[mirotalk] - add possibility to password protect the room
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
- Is `100% Free` - `Open Source` - `Self Hosted`
|
||||
- No download, plug-in, or login required, entirely browser-based
|
||||
- Unlimited number of conference rooms without call time limitation
|
||||
- Possibility to Lock/Unlock the Room for the meeting
|
||||
- Possibility to Password protect the Room for the meeting
|
||||
- Desktop and Mobile compatible
|
||||
- Optimized Room URL Sharing (share it to your participants, wait for them to join)
|
||||
- Webcam Streaming (Front - Rear for mobile)
|
||||
|
||||
+42
-22
@@ -383,6 +383,7 @@ io.sockets.on('connect', (socket) => {
|
||||
log.debug('[' + socket.id + '] join ', config);
|
||||
|
||||
let channel = config.channel;
|
||||
let channel_password = config.channel_password;
|
||||
let peer_name = config.peer_name;
|
||||
let peer_video = config.peer_video;
|
||||
let peer_audio = config.peer_audio;
|
||||
@@ -400,7 +401,7 @@ io.sockets.on('connect', (socket) => {
|
||||
if (!(channel in peers)) peers[channel] = {};
|
||||
|
||||
// room locked by the participants can't join
|
||||
if (peers[channel]['Locked'] === true) {
|
||||
if (peers[channel]['lock'] === true && peers[channel]['password'] != channel_password) {
|
||||
log.debug('[' + socket.id + '] [Warning] Room Is Locked', channel);
|
||||
socket.emit('roomIsLocked');
|
||||
return;
|
||||
@@ -461,16 +462,12 @@ io.sockets.on('connect', (socket) => {
|
||||
|
||||
delete socket.channels[channel];
|
||||
delete channels[channel][socket.id];
|
||||
delete peers[channel][socket.id];
|
||||
delete peers[channel][socket.id]; // delete peer data from the room
|
||||
|
||||
switch (Object.keys(peers[channel]).length) {
|
||||
case 0:
|
||||
// last peer disconnected from the room without room status set, delete room data
|
||||
delete peers[channel];
|
||||
break;
|
||||
case 1:
|
||||
// last peer disconnected from the room having room status set, delete room data
|
||||
if ('Locked' in peers[channel]) delete peers[channel];
|
||||
case 0: // last peer disconnected from the room without room lock & password set
|
||||
case 2: // last peer disconnected from the room having room lock & password set
|
||||
delete peers[channel]; // clean lock and password value from the room
|
||||
break;
|
||||
}
|
||||
log.debug('connected peers grp by roomId', peers);
|
||||
@@ -517,21 +514,44 @@ io.sockets.on('connect', (socket) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* Refresh Room Status (Locked/Unlocked)
|
||||
* Handle Room action
|
||||
*/
|
||||
socket.on('roomStatus', (config) => {
|
||||
socket.on('roomAction', (config) => {
|
||||
//log.debug('[' + socket.id + '] Room action:', config);
|
||||
let room_is_locked = false;
|
||||
let room_id = config.room_id;
|
||||
let room_locked = config.room_locked;
|
||||
let peer_name = config.peer_name;
|
||||
|
||||
peers[room_id]['Locked'] = room_locked;
|
||||
|
||||
log.debug('[' + socket.id + '] emit roomStatus' + ' to [room_id: ' + room_id + ' locked: ' + room_locked + ']');
|
||||
|
||||
sendToRoom(room_id, socket.id, 'roomStatus', {
|
||||
peer_name: peer_name,
|
||||
room_locked: room_locked,
|
||||
});
|
||||
let password = config.password;
|
||||
let action = config.action;
|
||||
//
|
||||
switch (action) {
|
||||
case 'lock':
|
||||
peers[room_id]['lock'] = true;
|
||||
peers[room_id]['password'] = password;
|
||||
sendToRoom(room_id, socket.id, 'roomAction', {
|
||||
peer_name: peer_name,
|
||||
action: action,
|
||||
});
|
||||
room_is_locked = true;
|
||||
break;
|
||||
case 'unlock':
|
||||
peers[room_id]['lock'] = false;
|
||||
peers[room_id]['password'] = password;
|
||||
sendToRoom(room_id, socket.id, 'roomAction', {
|
||||
peer_name: peer_name,
|
||||
action: action,
|
||||
});
|
||||
break;
|
||||
case 'checkPassword':
|
||||
let config = {
|
||||
peer_name: peer_name,
|
||||
action: action,
|
||||
password: password === peers[room_id]['password'] ? 'OK' : 'KO',
|
||||
};
|
||||
sendToPeer(socket.id, sockets, 'roomAction', config);
|
||||
break;
|
||||
}
|
||||
log.debug('[' + socket.id + '] Room ' + room_id, { locked: room_is_locked, password: password });
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -573,7 +593,7 @@ io.sockets.on('connect', (socket) => {
|
||||
let status = config.status;
|
||||
|
||||
for (let peer_id in peers[room_id]) {
|
||||
if (peers[room_id][peer_id]['peer_name'] == peer_name) {
|
||||
if (peers[room_id][peer_id]['peer_name'] === peer_name) {
|
||||
switch (element) {
|
||||
case 'video':
|
||||
peers[room_id][peer_id]['peer_video'] = status;
|
||||
|
||||
@@ -607,7 +607,8 @@ emoji-picker {
|
||||
#myPeerNameSetBtn,
|
||||
#muteEveryoneBtn,
|
||||
#hideEveryoneBtn,
|
||||
#lockUnlockRoomBtn,
|
||||
#lockRoomBtn,
|
||||
#unlockRoomBtn,
|
||||
#speechRecognitionStart,
|
||||
#speechRecognitionStop {
|
||||
font-size: 0.9rem;
|
||||
@@ -618,7 +619,8 @@ emoji-picker {
|
||||
}
|
||||
|
||||
#myPeerNameSetBtn:hover,
|
||||
#lockUnlockRoomBtn:hover,
|
||||
#lockRoomBtn:hover,
|
||||
#unlockRoomBtn:hover,
|
||||
#speechRecognitionStart:hover,
|
||||
#speechRecognitionStop:hover {
|
||||
color: var(--hover-color);
|
||||
|
||||
+141
-38
@@ -68,6 +68,8 @@ const chatInputEmoji = {
|
||||
':+1:': '\uD83D\uDC4D',
|
||||
}; // https://github.com/wooorm/gemoji/blob/main/support.md
|
||||
|
||||
let thisRoomPassword = null;
|
||||
|
||||
let myPeerId; // socket.id
|
||||
|
||||
// video cam - screen max frame rate
|
||||
@@ -238,7 +240,8 @@ let wbPop = [];
|
||||
// room actions btns
|
||||
let muteEveryoneBtn;
|
||||
let hideEveryoneBtn;
|
||||
let lockUnlockRoomBtn;
|
||||
let lockRoomBtn;
|
||||
let unlockRoomBtn;
|
||||
// file transfer settings
|
||||
let fileToSend;
|
||||
let fileReader;
|
||||
@@ -387,7 +390,8 @@ function getHtmlElementsById() {
|
||||
// room actions buttons
|
||||
muteEveryoneBtn = getId('muteEveryoneBtn');
|
||||
hideEveryoneBtn = getId('hideEveryoneBtn');
|
||||
lockUnlockRoomBtn = getId('lockUnlockRoomBtn');
|
||||
lockRoomBtn = getId('lockRoomBtn');
|
||||
unlockRoomBtn = getId('unlockRoomBtn');
|
||||
// file send progress
|
||||
sendFileDiv = getId('sendFileDiv');
|
||||
sendFileInfo = getId('sendFileInfo');
|
||||
@@ -639,10 +643,10 @@ function initClientPeer() {
|
||||
|
||||
// on receiving data from signaling server...
|
||||
signalingSocket.on('connect', handleConnect);
|
||||
signalingSocket.on('serverInfo', handleServerInfo);
|
||||
signalingSocket.on('roomIsLocked', handleRoomLocked);
|
||||
signalingSocket.on('roomStatus', handleRoomStatus);
|
||||
signalingSocket.on('roomIsLocked', handleUnlockTheRoom);
|
||||
signalingSocket.on('roomAction', handleRoomAction);
|
||||
signalingSocket.on('addPeer', handleAddPeer);
|
||||
signalingSocket.on('serverInfo', handleServerInfo);
|
||||
signalingSocket.on('sessionDescription', handleSessionDescription);
|
||||
signalingSocket.on('iceCandidate', handleIceCandidate);
|
||||
signalingSocket.on('peerName', handlePeerName);
|
||||
@@ -795,12 +799,13 @@ function whoAreYouJoin() {
|
||||
}
|
||||
|
||||
/**
|
||||
* join to chennel and send some peer info
|
||||
* join to channel and send some peer info
|
||||
*/
|
||||
function joinToChannel() {
|
||||
console.log('join to channel', roomId);
|
||||
sendToServer('join', {
|
||||
channel: roomId,
|
||||
channel_password: thisRoomPassword,
|
||||
peer_info: peerInfo,
|
||||
peer_geo: peerGeo,
|
||||
peer_name: myPeerName,
|
||||
@@ -2467,8 +2472,11 @@ function setupMySettings() {
|
||||
hideEveryoneBtn.addEventListener('click', (e) => {
|
||||
disableAllPeers('video');
|
||||
});
|
||||
lockUnlockRoomBtn.addEventListener('click', (e) => {
|
||||
lockUnlockRoom();
|
||||
lockRoomBtn.addEventListener('click', (e) => {
|
||||
handleRoomAction({ action: 'lock' }, true);
|
||||
});
|
||||
unlockRoomBtn.addEventListener('click', (e) => {
|
||||
handleRoomAction({ action: 'unlock' }, true);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4309,59 +4317,100 @@ function disablePeer(peer_id, element) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock Unlock the room from unauthorized access
|
||||
* Handle Room action
|
||||
* @param {object} config data
|
||||
* @param {boolean} emit data to signaling server
|
||||
*/
|
||||
function lockUnlockRoom() {
|
||||
getId('lockUnlockRoomIco').className = roomLocked ? 'fas fa-lock-open' : 'fas fa-lock';
|
||||
function handleRoomAction(config, emit = false) {
|
||||
if (emit) {
|
||||
let thisConfig = {
|
||||
room_id: roomId,
|
||||
peer_name: myPeerName,
|
||||
action: config.action,
|
||||
password: null,
|
||||
};
|
||||
switch (config.action) {
|
||||
case 'lock':
|
||||
playSound('newMessage');
|
||||
|
||||
if (roomLocked) {
|
||||
roomLocked = false;
|
||||
emitRoomStatus();
|
||||
Swal.fire({
|
||||
allowOutsideClick: false,
|
||||
allowEscapeKey: false,
|
||||
showDenyButton: true,
|
||||
background: swalBackground,
|
||||
imageUrl: roomLockedImg,
|
||||
input: 'text',
|
||||
inputPlaceholder: 'Set Room password',
|
||||
confirmButtonText: `OK`,
|
||||
denyButtonText: `Cancel`,
|
||||
showClass: {
|
||||
popup: 'animate__animated animate__fadeInDown',
|
||||
},
|
||||
hideClass: {
|
||||
popup: 'animate__animated animate__fadeOutUp',
|
||||
},
|
||||
inputValidator: (pwd) => {
|
||||
if (!pwd) return 'Please enter the Room password';
|
||||
thisRoomPassword = pwd;
|
||||
},
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
thisConfig.password = thisRoomPassword;
|
||||
sendToServer('roomAction', thisConfig);
|
||||
handleRoomStatus(thisConfig);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'unlock':
|
||||
sendToServer('roomAction', thisConfig);
|
||||
handleRoomStatus(thisConfig);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
roomLocked = true;
|
||||
emitRoomStatus();
|
||||
playSound('locked');
|
||||
// data coming from signaling server
|
||||
handleRoomStatus(config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh Room Status (Locked/Unlocked)
|
||||
*/
|
||||
function emitRoomStatus() {
|
||||
let rStatus = roomLocked ? '🔒 LOCKED the room, no one can access!' : '🔓 UNLOCKED the room';
|
||||
userLog('toast', rStatus);
|
||||
|
||||
sendToServer('roomStatus', {
|
||||
room_id: roomId,
|
||||
room_locked: roomLocked,
|
||||
peer_name: myPeerName,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Room Status (Lock - Unlock)
|
||||
* Handle room status
|
||||
* @param {object} config data
|
||||
*/
|
||||
function handleRoomStatus(config) {
|
||||
let action = config.action;
|
||||
let peer_name = config.peer_name;
|
||||
let room_locked = config.room_locked;
|
||||
roomLocked = room_locked;
|
||||
lockUnlockRoomBtn.className = roomLocked ? 'fas fa-lock' : 'fas fa-lock-open';
|
||||
userLog('toast', peer_name + ' set room is locked to ' + roomLocked);
|
||||
switch (action) {
|
||||
case 'lock':
|
||||
playSound('locked');
|
||||
userLog('toast', peer_name + ' has 🔒 LOCKED the room by password', 'top-end');
|
||||
hide(lockRoomBtn);
|
||||
show(unlockRoomBtn);
|
||||
break;
|
||||
case 'unlock':
|
||||
userLog('toast', peer_name + ' has 🔓 UNLOCKED the room', 'top-end');
|
||||
hide(unlockRoomBtn);
|
||||
show(lockRoomBtn);
|
||||
break;
|
||||
case 'checkPassword':
|
||||
let password = config.password;
|
||||
password == 'OK' ? joinToChannel() : handleRoomLocked();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Room is Locked can't access...
|
||||
* Room is locked you provide a wrong password, can't access!
|
||||
*/
|
||||
function handleRoomLocked() {
|
||||
playSound('kickedOut');
|
||||
|
||||
console.log('Room is Locked, try with another one');
|
||||
Swal.fire({
|
||||
allowOutsideClick: false,
|
||||
background: swalBackground,
|
||||
position: 'center',
|
||||
imageUrl: roomLockedImg,
|
||||
title: 'Oops, Room Locked',
|
||||
title: 'Oops, Wrong Room Password',
|
||||
text: 'The room is locked, try with another one.',
|
||||
showDenyButton: false,
|
||||
confirmButtonText: `Ok`,
|
||||
@@ -4376,6 +4425,44 @@ function handleRoomLocked() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to unlock the room by providing a valid password
|
||||
*/
|
||||
function handleUnlockTheRoom() {
|
||||
playSound('alert');
|
||||
|
||||
Swal.fire({
|
||||
allowOutsideClick: false,
|
||||
allowEscapeKey: false,
|
||||
background: swalBackground,
|
||||
imageUrl: roomLockedImg,
|
||||
title: 'Oops, Room is Locked',
|
||||
input: 'text',
|
||||
inputPlaceholder: 'Enter the Room password',
|
||||
confirmButtonText: `OK`,
|
||||
showClass: {
|
||||
popup: 'animate__animated animate__fadeInDown',
|
||||
},
|
||||
hideClass: {
|
||||
popup: 'animate__animated animate__fadeOutUp',
|
||||
},
|
||||
inputValidator: (pwd) => {
|
||||
if (!pwd) return 'Please enter the Room password';
|
||||
thisRoomPassword = pwd;
|
||||
},
|
||||
}).then(() => {
|
||||
let config = {
|
||||
room_id: roomId,
|
||||
peer_name: myPeerName,
|
||||
action: 'checkPassword',
|
||||
password: thisRoomPassword,
|
||||
};
|
||||
sendToServer('roomAction', config);
|
||||
hide(lockRoomBtn);
|
||||
show(unlockRoomBtn);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle whiteboard toogle
|
||||
*/
|
||||
@@ -5677,3 +5764,19 @@ function getSl(selector) {
|
||||
function getEcN(className) {
|
||||
return document.getElementsByClassName(className);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide elemnt
|
||||
* @param {object} elem
|
||||
*/
|
||||
function hide(elem) {
|
||||
elem.className = 'hidden';
|
||||
}
|
||||
|
||||
/**
|
||||
* Show elemnt
|
||||
* @param {object} elem
|
||||
*/
|
||||
function show(elem) {
|
||||
elem.className = '';
|
||||
}
|
||||
|
||||
@@ -282,9 +282,8 @@ access to use this app.
|
||||
<button id="hideEveryoneBtn"><i class="fas fa-video"></i> Hide everyone</button>
|
||||
<br /><br />
|
||||
<label>Security</label><br />
|
||||
<button id="lockUnlockRoomBtn">
|
||||
<i id="lockUnlockRoomIco" class="fas fa-lock-open"></i> Lock/unlock room
|
||||
</button>
|
||||
<button id="lockRoomBtn"><i class="fas fa-lock-open"></i> Lock room</button>
|
||||
<button id="unlockRoomBtn" class="hidden"><i class="fas fa-lock"></i> Unlock room</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user