[mirotalksfu] - add check users from enpoint, improve rec, update dep
هذا الالتزام موجود في:
@@ -41,7 +41,7 @@ dependencies: {
|
|||||||
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
|
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
|
||||||
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
|
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
|
||||||
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
|
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
|
||||||
* @version 1.3.73
|
* @version 1.3.74
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -109,6 +109,9 @@ const jwtCfg = {
|
|||||||
const hostCfg = {
|
const hostCfg = {
|
||||||
protected: config.host.protected,
|
protected: config.host.protected,
|
||||||
user_auth: config.host.user_auth,
|
user_auth: config.host.user_auth,
|
||||||
|
users_from_db: config.host.users_from_db,
|
||||||
|
users_api_endpoint: config.host.users_api_endpoint,
|
||||||
|
users_api_secret_key: config.host.users_api_secret_key,
|
||||||
users: config.host.users,
|
users: config.host.users,
|
||||||
authenticated: !config.host.protected,
|
authenticated: !config.host.protected,
|
||||||
};
|
};
|
||||||
@@ -305,7 +308,7 @@ function startServer() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// no room name specified to join || direct join
|
// no room name specified to join || direct join
|
||||||
app.get('/join/', (req, res) => {
|
app.get('/join/', async (req, res) => {
|
||||||
if (Object.keys(req.query).length > 0) {
|
if (Object.keys(req.query).length > 0) {
|
||||||
log.debug('Direct Join', req.query);
|
log.debug('Direct Join', req.query);
|
||||||
|
|
||||||
@@ -326,7 +329,7 @@ function startServer() {
|
|||||||
const { username, password, presenter } = checkXSS(jwt.verify(token, jwtCfg.JWT_KEY));
|
const { username, password, presenter } = checkXSS(jwt.verify(token, jwtCfg.JWT_KEY));
|
||||||
peerUsername = username;
|
peerUsername = username;
|
||||||
peerPassword = password;
|
peerPassword = password;
|
||||||
isPeerValid = isAuthPeer(username, password);
|
isPeerValid = await isAuthPeer(username, password);
|
||||||
isPeerPresenter = presenter === '1' || presenter === 'true';
|
isPeerPresenter = presenter === '1' || presenter === 'true';
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error('Direct Join JWT error', { error: err.message, token: token });
|
log.error('Direct Join JWT error', { error: err.message, token: token });
|
||||||
@@ -419,13 +422,13 @@ function startServer() {
|
|||||||
// ####################################################
|
// ####################################################
|
||||||
|
|
||||||
// handle login on host protected
|
// handle login on host protected
|
||||||
app.post(['/login'], (req, res) => {
|
app.post(['/login'], async (req, res) => {
|
||||||
const ip = getIP(req);
|
const ip = getIP(req);
|
||||||
log.debug(`Request login to host from: ${ip}`, req.body);
|
log.debug(`Request login to host from: ${ip}`, req.body);
|
||||||
|
|
||||||
const { username, password } = checkXSS(req.body);
|
const { username, password } = checkXSS(req.body);
|
||||||
|
|
||||||
const isPeerValid = isAuthPeer(username, password);
|
const isPeerValid = await isAuthPeer(username, password);
|
||||||
|
|
||||||
if (hostCfg.protected && isPeerValid && !hostCfg.authenticated) {
|
if (hostCfg.protected && isPeerValid && !hostCfg.authenticated) {
|
||||||
const ip = getIP(req);
|
const ip = getIP(req);
|
||||||
@@ -1169,7 +1172,7 @@ function startServer() {
|
|||||||
try {
|
try {
|
||||||
const { username, password, presenter } = checkXSS(jwt.verify(peer_token, jwtCfg.JWT_KEY));
|
const { username, password, presenter } = checkXSS(jwt.verify(peer_token, jwtCfg.JWT_KEY));
|
||||||
|
|
||||||
const isPeerValid = isAuthPeer(username, password);
|
const isPeerValid = await isAuthPeer(username, password);
|
||||||
|
|
||||||
is_presenter = presenter === '1' || presenter === 'true';
|
is_presenter = presenter === '1' || presenter === 'true';
|
||||||
|
|
||||||
@@ -1699,8 +1702,24 @@ function startServer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAuthPeer(username, password) {
|
async function isAuthPeer(username, password) {
|
||||||
return hostCfg.users && hostCfg.users.some((user) => user.username === username && user.password === password);
|
if (hostCfg.users_from_db && hostCfg.users_api_endpoint) {
|
||||||
|
try {
|
||||||
|
const response = await axios.post(hostCfg.users_api_endpoint, {
|
||||||
|
email: username,
|
||||||
|
password: password,
|
||||||
|
api_secret_key: hostCfg.users_api_secret_key,
|
||||||
|
});
|
||||||
|
return response.data && response.data.message === true;
|
||||||
|
} catch (error) {
|
||||||
|
log.error('AXIOS isAuthPeer error', error.message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
hostCfg.users && hostCfg.users.some((user) => user.username === username && user.password === password)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getActiveRooms() {
|
function getActiveRooms() {
|
||||||
|
|||||||
@@ -57,10 +57,14 @@ module.exports = {
|
|||||||
/*
|
/*
|
||||||
Host Protection (default: false)
|
Host Protection (default: false)
|
||||||
To enhance host security, enable host protection - user auth and provide valid
|
To enhance host security, enable host protection - user auth and provide valid
|
||||||
usernames and passwords in the users array.
|
usernames and passwords in the users array or active users_from_db using users_api_endpoint for check.
|
||||||
*/
|
*/
|
||||||
protected: false,
|
protected: false,
|
||||||
user_auth: false,
|
user_auth: false,
|
||||||
|
users_from_db: false,
|
||||||
|
//users_api_endpoint: 'http://localhost:9000/api/v1/user/isAuth',
|
||||||
|
users_api_endpoint: 'https://webrtc.mirotalk.com/api/v1/user/isAuth',
|
||||||
|
users_api_secret_key: '91bbfac3-5e39-4583-9123-883b72be505c',
|
||||||
users: [
|
users: [
|
||||||
{
|
{
|
||||||
username: 'username',
|
username: 'username',
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mirotalksfu",
|
"name": "mirotalksfu",
|
||||||
"version": "1.3.73",
|
"version": "1.3.74",
|
||||||
"description": "WebRTC SFU browser-based video calls",
|
"description": "WebRTC SFU browser-based video calls",
|
||||||
"main": "Server.js",
|
"main": "Server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -38,8 +38,8 @@
|
|||||||
"author": "Miroslav Pejic",
|
"author": "Miroslav Pejic",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/integrations": "7.101.0",
|
"@sentry/integrations": "7.102.0",
|
||||||
"@sentry/node": "7.101.0",
|
"@sentry/node": "7.102.0",
|
||||||
"axios": "^1.6.7",
|
"axios": "^1.6.7",
|
||||||
"body-parser": "1.20.2",
|
"body-parser": "1.20.2",
|
||||||
"colors": "1.4.0",
|
"colors": "1.4.0",
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ if (location.href.substr(0, 5) !== 'https') location.href = 'https' + location.h
|
|||||||
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
|
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
|
||||||
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
|
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
|
||||||
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
|
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
|
||||||
* @version 1.3.73
|
* @version 1.3.74
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
|
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
|
||||||
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
|
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
|
||||||
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
|
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
|
||||||
* @version 1.3.73
|
* @version 1.3.74
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -4185,12 +4185,8 @@ class RoomClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async syncRecordingInCloud(data) {
|
async syncRecordingInCloud(data) {
|
||||||
const arrayBuffer = data;
|
const arrayBuffer = await data.arrayBuffer();
|
||||||
const chunkSize = rc.recSyncChunkSize;
|
const chunkSize = rc.recSyncChunkSize;
|
||||||
const fileReader = new FileReader();
|
|
||||||
fileReader.readAsArrayBuffer(arrayBuffer);
|
|
||||||
fileReader.onload = async (event) => {
|
|
||||||
const arrayBuffer = event.target.result;
|
|
||||||
const totalChunks = Math.ceil(arrayBuffer.byteLength / chunkSize);
|
const totalChunks = Math.ceil(arrayBuffer.byteLength / chunkSize);
|
||||||
for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
|
for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
|
||||||
const chunk = arrayBuffer.slice(chunkIndex * chunkSize, (chunkIndex + 1) * chunkSize);
|
const chunk = arrayBuffer.slice(chunkIndex * chunkSize, (chunkIndex + 1) * chunkSize);
|
||||||
@@ -4198,14 +4194,12 @@ class RoomClient {
|
|||||||
await axios.post('/recSync?fileName=' + rc.recServerFileName, chunk, {
|
await axios.post('/recSync?fileName=' + rc.recServerFileName, chunk, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/octet-stream',
|
'Content-Type': 'application/octet-stream',
|
||||||
'Content-Length': chunk.length,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error syncing chunk:', error.message);
|
console.error('Error syncing chunk:', error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMediaRecorderStop(evt) {
|
handleMediaRecorderStop(evt) {
|
||||||
|
|||||||
المرجع في مشكلة جديدة
حظر مستخدم