Merge branch 'develop' into develop

auto_join_3.3
Stefan Otto 2020-03-30 12:49:46 +02:00 committed by GitHub
commit d606acf1e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 347 additions and 160 deletions

View File

@ -46,7 +46,8 @@
"test": "react-scripts test", "test": "react-scripts test",
"eject": "react-scripts eject", "eject": "react-scripts eject",
"electron": "electron --no-sandbox .", "electron": "electron --no-sandbox .",
"dev": "nf start -p 3000" "dev": "nf start -p 3000",
"lint": "eslint -c .eslintrc.json --ext .js src"
}, },
"browserslist": [ "browserslist": [
">0.2%", ">0.2%",

View File

@ -231,7 +231,7 @@ export default class RoomClient
this._hark = null; this._hark = null;
// Local MediaStream for hark // Local MediaStream for hark
this._harkStream = null this._harkStream = null;
// Local webcam mediasoup Producer. // Local webcam mediasoup Producer.
this._webcamProducer = null; this._webcamProducer = null;
@ -1162,21 +1162,30 @@ export default class RoomClient
...VIDEO_CONSTRAINS[resolution] ...VIDEO_CONSTRAINS[resolution]
} }
}); });
if (stream){
if (stream)
{
const track = stream.getVideoTracks()[0]; const track = stream.getVideoTracks()[0];
if (track) {
if (track)
{
await this._webcamProducer.replaceTrack({ track }); await this._webcamProducer.replaceTrack({ track });
store.dispatch( store.dispatch(
producerActions.setProducerTrack(this._webcamProducer.id, track)); producerActions.setProducerTrack(this._webcamProducer.id, track));
} else { }
logger.warn('getVideoTracks Error: First Video Track is null') else
{
logger.warn('getVideoTracks Error: First Video Track is null');
} }
} else {
logger.warn ('getUserMedia Error: Stream is null!')
} }
else
{
logger.warn('getUserMedia Error: Stream is null!');
}
store.dispatch(settingsActions.setSelectedWebcamDevice(deviceId)); store.dispatch(settingsActions.setSelectedWebcamDevice(deviceId));
await this._updateWebcams(); await this._updateWebcams();
@ -1586,6 +1595,50 @@ export default class RoomClient
}) })
})); }));
if (this._screenSharingProducer)
{
this._screenSharingProducer.close();
store.dispatch(
producerActions.removeProducer(this._screenSharingProducer.id));
this._screenSharingProducer = null;
}
if (this._webcamProducer)
{
this._webcamProducer.close();
store.dispatch(
producerActions.removeProducer(this._webcamProducer.id));
this._webcamProducer = null;
}
if (this._micProducer)
{
this._micProducer.close();
store.dispatch(
producerActions.removeProducer(this._micProducer.id));
this._micProducer = null;
}
if (this._sendTransport)
{
this._sendTransport.close();
this._sendTransport = null;
}
if (this._recvTransport)
{
this._recvTransport.close();
this._recvTransport = null;
}
store.dispatch(roomActions.setRoomState('connecting')); store.dispatch(roomActions.setRoomState('connecting'));
}); });
@ -1788,6 +1841,13 @@ export default class RoomClient
break; break;
} }
case 'roomBack':
{
await this._joinRoom({ joinVideo });
break;
}
case 'lockRoom': case 'lockRoom':
{ {
store.dispatch( store.dispatch(
@ -2340,7 +2400,7 @@ export default class RoomClient
dtlsParameters, dtlsParameters,
iceServers : this._turnServers, iceServers : this._turnServers,
// TODO: Fix for issue #72 // TODO: Fix for issue #72
iceTransportPolicy : this._device.flag === 'firefox' ? 'relay' : undefined, iceTransportPolicy : this._device.flag === 'firefox' && this._turnServers ? 'relay' : undefined,
proprietaryConstraints : PC_PROPRIETARY_CONSTRAINTS proprietaryConstraints : PC_PROPRIETARY_CONSTRAINTS
}); });
@ -2404,7 +2464,7 @@ export default class RoomClient
dtlsParameters, dtlsParameters,
iceServers : this._turnServers, iceServers : this._turnServers,
// TODO: Fix for issue #72 // TODO: Fix for issue #72
iceTransportPolicy : this._device.flag === 'firefox' ? 'relay' : undefined iceTransportPolicy : this._device.flag === 'firefox' && this._turnServers ? 'relay' : undefined
}); });
this._recvTransport.on( this._recvTransport.on(
@ -2477,7 +2537,11 @@ export default class RoomClient
{ {
if (this._mediasoupDevice.canProduce('audio')) if (this._mediasoupDevice.canProduce('audio'))
if (!this._muted) if (!this._muted)
this.enableMic(); {
await this.enableMic();
if (peers.length > 4)
this.muteMic();
}
if (joinVideo && this._mediasoupDevice.canProduce('video')) if (joinVideo && this._mediasoupDevice.canProduce('video'))
this.enableWebcam(); this.enableWebcam();

View File

@ -35,12 +35,10 @@ export const setConsumerPreferredLayers = (consumerId, spatialLayer, temporalLay
}); });
export const setConsumerPriority = (consumerId, priority) => export const setConsumerPriority = (consumerId, priority) =>
{ ({
return {
type : 'SET_CONSUMER_PRIORITY', type : 'SET_CONSUMER_PRIORITY',
payload : { consumerId, priority } payload : { consumerId, priority }
}; });
};
export const setConsumerTrack = (consumerId, track) => export const setConsumerTrack = (consumerId, track) =>
({ ({

View File

@ -38,7 +38,7 @@ export const setMediaCapabilities = ({
canSendWebcam, canSendWebcam,
canShareScreen, canShareScreen,
canShareFiles canShareFiles
}) => }) =>
({ ({
type : 'SET_MEDIA_CAPABILITIES', type : 'SET_MEDIA_CAPABILITIES',
payload : { canSendMic, canSendWebcam, canShareScreen, canShareFiles } payload : { canSendMic, canSendWebcam, canShareScreen, canShareFiles }
@ -92,7 +92,7 @@ export const setDisplayNameInProgress = (flag) =>
payload : { flag } payload : { flag }
}); });
export const setIsSpeaking = (flag) => export const setIsSpeaking = (flag) =>
({ ({
type : 'SET_IS_SPEAKING', type : 'SET_IS_SPEAKING',
payload : { flag } payload : { flag }

View File

@ -46,7 +46,6 @@ export const setPeerPicture = (peerId, picture) =>
payload : { peerId, picture } payload : { peerId, picture }
}); });
export const addPeerRole = (peerId, role) => export const addPeerRole = (peerId, role) =>
({ ({
type : 'ADD_PEER_ROLE', type : 'ADD_PEER_ROLE',

View File

@ -178,7 +178,8 @@ const ChooseRoom = ({
<CookieConsent buttonText={intl.formatMessage({ <CookieConsent buttonText={intl.formatMessage({
id : 'room.consentUnderstand', id : 'room.consentUnderstand',
defaultMessage : 'I understand' defaultMessage : 'I understand'
})}> })}
>
<FormattedMessage <FormattedMessage
id='room.cookieConsent' id='room.cookieConsent'
defaultMessage='This website uses cookies to enhance the user experience' defaultMessage='This website uses cookies to enhance the user experience'

View File

@ -78,14 +78,10 @@ const styles = (theme) =>
alignItems : 'flex-end', alignItems : 'flex-end',
padding : theme.spacing(1), padding : theme.spacing(1),
zIndex : 21, zIndex : 21,
opacity : 0, opacity : 1,
transition : 'opacity 0.3s', transition : 'opacity 0.3s',
touchAction : 'none', touchAction : 'none',
pointerEvents : 'none', pointerEvents : 'none',
'&.hover' :
{
opacity : 1
},
'& p' : '& p' :
{ {
position : 'absolute', position : 'absolute',
@ -95,14 +91,20 @@ const styles = (theme) =>
transform : 'translate(-50%, -50%)', transform : 'translate(-50%, -50%)',
color : 'rgba(255, 255, 255, 0.5)', color : 'rgba(255, 255, 255, 0.5)',
fontSize : '7em', fontSize : '7em',
margin : 0 margin : 0,
opacity : 0,
transition : 'opacity 0.1s ease-in-out',
'&.hover' :
{
opacity : 1
}
} }
}, },
ptt : ptt :
{ {
position : 'absolute', position : 'absolute',
float : 'left', float : 'left',
bottom : '10%', top : '10%',
left : '50%', left : '50%',
transform : 'translate(-50%, 0%)', transform : 'translate(-50%, 0%)',
color : 'rgba(255, 255, 255, 0.7)', color : 'rgba(255, 255, 255, 0.7)',
@ -113,8 +115,10 @@ const styles = (theme) =>
borderRadius : '20px', borderRadius : '20px',
textAlign : 'center', textAlign : 'center',
opacity : 0, opacity : 0,
transition : 'opacity 1s ease',
'&.enabled' : '&.enabled' :
{ {
transition : 'opacity 0.1s',
opacity : 1 opacity : 1
} }
} }
@ -292,7 +296,7 @@ const Me = (props) =>
> >
<div className={classnames(classes.viewContainer)} style={style}> <div className={classnames(classes.viewContainer)} style={style}>
<div <div
className={classnames(classes.controls, 'hover')} className={classnames(classes.controls)}
onMouseOver={() => setHover(true)} onMouseOver={() => setHover(true)}
onMouseOut={() => setHover(false)} onMouseOut={() => setHover(false)}
onTouchStart={() => onTouchStart={() =>
@ -313,7 +317,7 @@ const Me = (props) =>
}, 2000); }, 2000);
}} }}
> >
<p className={classnames(hover ? 'hover' : null)}> <p className={classnames(hover && 'hover')}>
<FormattedMessage <FormattedMessage
id='room.me' id='room.me'
defaultMessage='ME' defaultMessage='ME'
@ -323,7 +327,7 @@ const Me = (props) =>
<div className={classnames(classes.ptt, (micState ==='muted' && me.isSpeaking) ? 'enabled' : null)} > <div className={classnames(classes.ptt, (micState ==='muted' && me.isSpeaking) ? 'enabled' : null)} >
<FormattedMessage <FormattedMessage
id='me.mutedPTT' id='me.mutedPTT'
defaultMessage='You are muted: hold SPACE-BAR to speak!' defaultMessage='You are muted, hold down SPACE-BAR to talk'
/> />
</div> </div>

View File

@ -47,7 +47,7 @@ const styles = (theme) =>
}, },
divider : divider :
{ {
marginLeft : theme.spacing(3), marginLeft : theme.spacing(3)
}, },
show : show :
{ {

View File

@ -339,7 +339,8 @@ const JoinDialog = ({
<CookieConsent buttonText={intl.formatMessage({ <CookieConsent buttonText={intl.formatMessage({
id : 'room.consentUnderstand', id : 'room.consentUnderstand',
defaultMessage : 'I understand' defaultMessage : 'I understand'
})}> })}
>
<FormattedMessage <FormattedMessage
id='room.cookieConsent' id='room.cookieConsent'
defaultMessage='This website uses cookies to enhance the user experience' defaultMessage='This website uses cookies to enhance the user experience'

View File

@ -151,8 +151,8 @@ const ListPeer = (props) =>
id : 'tooltip.muteScreenSharing', id : 'tooltip.muteScreenSharing',
defaultMessage : 'Mute participant share' defaultMessage : 'Mute participant share'
})} })}
color={ screenVisible ? 'primary' : 'secondary'} color={screenVisible ? 'primary' : 'secondary'}
disabled={ peer.peerScreenInProgress } disabled={peer.peerScreenInProgress}
onClick={() => onClick={() =>
{ {
screenVisible ? screenVisible ?
@ -172,8 +172,8 @@ const ListPeer = (props) =>
id : 'tooltip.muteParticipant', id : 'tooltip.muteParticipant',
defaultMessage : 'Mute participant' defaultMessage : 'Mute participant'
})} })}
color={ micEnabled ? 'primary' : 'secondary'} color={micEnabled ? 'primary' : 'secondary'}
disabled={ peer.peerAudioInProgress } disabled={peer.peerAudioInProgress}
onClick={() => onClick={() =>
{ {
micEnabled ? micEnabled ?
@ -193,7 +193,7 @@ const ListPeer = (props) =>
id : 'tooltip.kickParticipant', id : 'tooltip.kickParticipant',
defaultMessage : 'Kick out participant' defaultMessage : 'Kick out participant'
})} })}
disabled={ peer.peerKickInProgress } disabled={peer.peerKickInProgress}
onClick={() => onClick={() =>
{ {
roomClient.kickPeer(peer.id); roomClient.kickPeer(peer.id);

View File

@ -159,13 +159,13 @@ class Room extends React.PureComponent
<CookieConsent <CookieConsent
buttonText={ buttonText={
<FormattedMessage <FormattedMessage
id = 'room.consentUnderstand' id='room.consentUnderstand'
defaultMessage = 'I understand' defaultMessage='I understand'
/> />
} }
> >
<FormattedMessage <FormattedMessage
id = 'room.cookieConsent' id='room.cookieConsent'
defaultMessage='This website uses cookies to enhance the user experience' defaultMessage='This website uses cookies to enhance the user experience'
/> />
</CookieConsent> </CookieConsent>

View File

@ -52,6 +52,9 @@
"room.muteAll": null, "room.muteAll": null,
"room.stopAllVideo": null, "room.stopAllVideo": null,
"room.closeMeeting": null, "room.closeMeeting": null,
"room.speechUnsupported": null,
"me.mutedPTT": null,
"tooltip.login": "登录", "tooltip.login": "登录",
"tooltip.logout": "注销", "tooltip.logout": "注销",

View File

@ -48,6 +48,12 @@
"room.spotlights": "Aktivní Účastníci", "room.spotlights": "Aktivní Účastníci",
"room.passive": "Pasivní Účastníci", "room.passive": "Pasivní Účastníci",
"room.videoPaused": "Toto video bylo pozastaveno", "room.videoPaused": "Toto video bylo pozastaveno",
"room.muteAll": null,
"room.stopAllVideo": null,
"room.closeMeeting": null,
"room.speechUnsupported": null,
"me.mutedPTT": null,
"tooltip.login": "Přihlášení", "tooltip.login": "Přihlášení",
"tooltip.logout": "Odhlášení", "tooltip.logout": "Odhlášení",

View File

@ -52,6 +52,9 @@
"room.muteAll": "Alle stummschalten", "room.muteAll": "Alle stummschalten",
"room.stopAllVideo": "Alle Videos stoppen", "room.stopAllVideo": "Alle Videos stoppen",
"room.closeMeeting": "Meeting schließen", "room.closeMeeting": "Meeting schließen",
"room.speechUnsupported": "Dein Browser unterstützt keine Spracherkennung",
"me.mutedPTT": "Du bist stummgeschalted, Halte die SPACE-Taste um zu sprechen",
"tooltip.login": "Anmelden", "tooltip.login": "Anmelden",
"tooltip.logout": "Abmelden", "tooltip.logout": "Abmelden",

View File

@ -52,6 +52,9 @@
"room.muteAll": null, "room.muteAll": null,
"room.stopAllVideo": null, "room.stopAllVideo": null,
"room.closeMeeting": null, "room.closeMeeting": null,
"room.speechUnsupported": null,
"me.mutedPTT": null,
"tooltip.login": "Log ind", "tooltip.login": "Log ind",
"tooltip.logout": "Log ud", "tooltip.logout": "Log ud",

View File

@ -52,6 +52,9 @@
"room.muteAll": null, "room.muteAll": null,
"room.stopAllVideo": null, "room.stopAllVideo": null,
"room.closeMeeting": null, "room.closeMeeting": null,
"room.speechUnsupported": null,
"me.mutedPTT": null,
"tooltip.login": "Σύνδεση", "tooltip.login": "Σύνδεση",
"tooltip.logout": "Αποσύνδεση", "tooltip.logout": "Αποσύνδεση",

View File

@ -52,6 +52,9 @@
"room.muteAll": "Mute all", "room.muteAll": "Mute all",
"room.stopAllVideo": "Stop all video", "room.stopAllVideo": "Stop all video",
"room.closeMeeting": "Close meeting", "room.closeMeeting": "Close meeting",
"room.speechUnsupported": "Your browser does not support speech recognition",
"me.mutedPTT": "You are muted, hold down SPACE-BAR to talk",
"tooltip.login": "Log in", "tooltip.login": "Log in",
"tooltip.logout": "Log out", "tooltip.logout": "Log out",

View File

@ -52,6 +52,9 @@
"room.muteAll": null, "room.muteAll": null,
"room.stopAllVideo": null, "room.stopAllVideo": null,
"room.closeMeeting": null, "room.closeMeeting": null,
"room.speechUnsupported": null,
"me.mutedPTT": null,
"tooltip.login": "Entrar", "tooltip.login": "Entrar",
"tooltip.logout": "Salir", "tooltip.logout": "Salir",

View File

@ -52,6 +52,9 @@
"room.muteAll": null, "room.muteAll": null,
"room.stopAllVideo": null, "room.stopAllVideo": null,
"room.closeMeeting": null, "room.closeMeeting": null,
"room.speechUnsupported": null,
"me.mutedPTT": null,
"tooltip.login": "Connexion", "tooltip.login": "Connexion",
"tooltip.logout": "Déconnexion", "tooltip.logout": "Déconnexion",

View File

@ -52,6 +52,9 @@
"room.muteAll": null, "room.muteAll": null,
"room.stopAllVideo": null, "room.stopAllVideo": null,
"room.closeMeeting": null, "room.closeMeeting": null,
"room.speechUnsupported": null,
"me.mutedPTT": null,
"tooltip.login": "Prijava", "tooltip.login": "Prijava",
"tooltip.logout": "Odjava", "tooltip.logout": "Odjava",

View File

@ -52,6 +52,9 @@
"room.muteAll": null, "room.muteAll": null,
"room.stopAllVideo": null, "room.stopAllVideo": null,
"room.closeMeeting": null, "room.closeMeeting": null,
"room.speechUnsupported": null,
"me.mutedPTT": null,
"tooltip.login": "Belépés", "tooltip.login": "Belépés",
"tooltip.logout": "Kilépés", "tooltip.logout": "Kilépés",

View File

@ -49,6 +49,12 @@
"room.spotlights": "Partecipanti in Evidenza", "room.spotlights": "Partecipanti in Evidenza",
"room.passive": "Participanti Passivi", "room.passive": "Participanti Passivi",
"room.videoPaused": "Il video è in pausa", "room.videoPaused": "Il video è in pausa",
"room.muteAll": null,
"room.stopAllVideo": null,
"room.closeMeeting": null,
"room.speechUnsupported": null,
"me.mutedPTT": null,
"tooltip.login": "Log in", "tooltip.login": "Log in",
"tooltip.logout": "Log out", "tooltip.logout": "Log out",

View File

@ -52,6 +52,9 @@
"room.muteAll": "Demp alle", "room.muteAll": "Demp alle",
"room.stopAllVideo": "Stopp all video", "room.stopAllVideo": "Stopp all video",
"room.closeMeeting": "Avslutt møte", "room.closeMeeting": "Avslutt møte",
"room.speechUnsupported": "Din nettleser støtter ikke stemmegjenkjenning",
"me.mutedPTT": "Du er dempet, hold nede SPACE for å snakke",
"tooltip.login": "Logg in", "tooltip.login": "Logg in",
"tooltip.logout": "Logg ut", "tooltip.logout": "Logg ut",

View File

@ -52,6 +52,9 @@
"room.muteAll": null, "room.muteAll": null,
"room.stopAllVideo": null, "room.stopAllVideo": null,
"room.closeMeeting": null, "room.closeMeeting": null,
"room.speechUnsupported": null,
"me.mutedPTT": null,
"tooltip.login": "Zaloguj", "tooltip.login": "Zaloguj",
"tooltip.logout": "Wyloguj", "tooltip.logout": "Wyloguj",

View File

@ -52,6 +52,9 @@
"room.muteAll": null, "room.muteAll": null,
"room.stopAllVideo": null, "room.stopAllVideo": null,
"room.closeMeeting": null, "room.closeMeeting": null,
"room.speechUnsupported": null,
"me.mutedPTT": null,
"tooltip.login": "Entrar", "tooltip.login": "Entrar",
"tooltip.logout": "Sair", "tooltip.logout": "Sair",

View File

@ -52,6 +52,9 @@
"room.muteAll": null, "room.muteAll": null,
"room.stopAllVideo": null, "room.stopAllVideo": null,
"room.closeMeeting": null, "room.closeMeeting": null,
"room.speechUnsupported": null,
"me.mutedPTT": null,
"tooltip.login": "Intră în cont", "tooltip.login": "Intră în cont",
"tooltip.logout": "Deconectare", "tooltip.logout": "Deconectare",

View File

@ -64,6 +64,12 @@ module.exports =
// listeningRedirectPort disabled // listeningRedirectPort disabled
// use case: loadbalancer backend // use case: loadbalancer backend
httpOnly : false, httpOnly : false,
// WebServer/Express trust proxy config for httpOnly mode
// You can find more info:
// - https://expressjs.com/en/guide/behind-proxies.html
// - https://www.npmjs.com/package/proxy-addr
// use case: loadbalancer backend
trustProxy : '',
// This function will be called on successful login through oidc. // This function will be called on successful login through oidc.
// Use this function to map your oidc userinfo to the Peer object. // Use this function to map your oidc userinfo to the Peer object.
// The roomId is equal to the room name. // The roomId is equal to the room name.

View File

@ -26,8 +26,8 @@ class Lobby extends EventEmitter
// Close the peers. // Close the peers.
for (const peer in this._peers) for (const peer in this._peers)
{ {
if (!peer.closed) if (!this._peers[peer].closed)
peer.close(); this._peers[peer].close();
} }
this._peers = null; this._peers = null;

View File

@ -2,6 +2,8 @@ const EventEmitter = require('events').EventEmitter;
const axios = require('axios'); const axios = require('axios');
const Logger = require('./Logger'); const Logger = require('./Logger');
const Lobby = require('./Lobby'); const Lobby = require('./Lobby');
const { v4: uuidv4 } = require('uuid');
const jwt = require('jsonwebtoken');
const userRoles = require('../userRoles'); const userRoles = require('../userRoles');
const config = require('../config/config'); const config = require('../config/config');
@ -46,6 +48,8 @@ class Room extends EventEmitter
super(); super();
this.setMaxListeners(Infinity); this.setMaxListeners(Infinity);
this._uuid = uuidv4();
// Room ID. // Room ID.
this._roomId = roomId; this._roomId = roomId;
@ -107,8 +111,8 @@ class Room extends EventEmitter
// Close the peers. // Close the peers.
for (const peer in this._peers) for (const peer in this._peers)
{ {
if (!peer.closed) if (!this._peers[peer].closed)
peer.close(); this._peers[peer].close();
} }
this._peers = null; this._peers = null;
@ -120,22 +124,41 @@ class Room extends EventEmitter
this.emit('close'); this.emit('close');
} }
handlePeer(peer) verifyPeer({ id, token })
{ {
logger.info('handlePeer() [peer:"%s", roles:"%s"]', peer.id, peer.roles); try
{
const decoded = jwt.verify(token, this._uuid);
// Allow reconnections, remove old peer logger.info('verifyPeer() [decoded:"%o"]', decoded);
return decoded.id === id;
}
catch (err)
{
logger.warn('verifyPeer() | invalid token');
}
return false;
}
handlePeer({ peer, returning })
{
logger.info('handlePeer() [peer:"%s", roles:"%s", returning:"%s"]', peer.id, peer.roles, returning);
// Should not happen
if (this._peers[peer.id]) if (this._peers[peer.id])
{ {
logger.warn( logger.warn(
'handleConnection() | there is already a peer with same peerId [peer:"%s"]', 'handleConnection() | there is already a peer with same peerId [peer:"%s"]',
peer.id); peer.id);
this._peers[peer.id].close();
} }
// Returning user
if (returning)
this._peerJoining(peer, true);
// Always let ADMIN in, even if locked // Always let ADMIN in, even if locked
if (peer.roles.includes(userRoles.ADMIN)) else if (peer.roles.includes(userRoles.ADMIN))
this._peerJoining(peer); this._peerJoining(peer);
else if (this._locked) else if (this._locked)
this._parkPeer(peer); this._parkPeer(peer);
@ -332,7 +355,7 @@ class Room extends EventEmitter
} }
} }
async _peerJoining(peer) async _peerJoining(peer, returning = false)
{ {
peer.socket.join(this._roomId); peer.socket.join(this._roomId);
@ -343,6 +366,18 @@ class Room extends EventEmitter
this._handlePeer(peer); this._handlePeer(peer);
if (returning)
{
this._notification(peer.socket, 'roomBack');
}
else
{
const token = jwt.sign({ id: peer.id }, this._uuid, { noTimestamp: true });
peer.socket.handshake.session.token = token;
peer.socket.handshake.session.save();
let turnServers; let turnServers;
if ('turnAPIURI' in config) if ('turnAPIURI' in config)
@ -383,6 +418,7 @@ class Room extends EventEmitter
this._notification(peer.socket, 'roomReady', { turnServers }); this._notification(peer.socket, 'roomReady', { turnServers });
} }
}
_handlePeer(peer) _handlePeer(peer)
{ {

View File

@ -25,6 +25,7 @@
"express-socket.io-session": "^1.3.5", "express-socket.io-session": "^1.3.5",
"helmet": "^3.21.2", "helmet": "^3.21.2",
"ims-lti": "^3.0.2", "ims-lti": "^3.0.2",
"jsonwebtoken": "^8.5.1",
"mediasoup": "^3.5.5", "mediasoup": "^3.5.5",
"openid-client": "^3.7.3", "openid-client": "^3.7.3",
"passport": "^0.4.0", "passport": "^0.4.0",
@ -32,6 +33,7 @@
"pidusage": "^2.0.17", "pidusage": "^2.0.17",
"redis": "^2.8.0", "redis": "^2.8.0",
"socket.io": "^2.3.0", "socket.io": "^2.3.0",
"spdy": "^4.0.1" "spdy": "^4.0.1",
"uuid": "^7.0.2"
} }
} }

View File

@ -100,6 +100,10 @@ const session = expressSession({
} }
}); });
if (config.trustProxy) {
app.set('trust proxy', config.trustProxy);
}
app.use(session); app.use(session);
passport.serializeUser((user, done) => passport.serializeUser((user, done) =>
@ -464,8 +468,28 @@ async function runWebSocketServer()
queue.push(async () => queue.push(async () =>
{ {
const { token } = socket.handshake.session;
const room = await getOrCreateRoom({ roomId }); const room = await getOrCreateRoom({ roomId });
const peer = new Peer({ id: peerId, roomId, socket });
let peer = peers.get(peerId);
let returning = false;
if (peer && !token)
{ // Don't allow hijacking sessions
socket.disconnect(true);
return;
}
else if (token && room.verifyPeer({ id: peerId, token }))
{ // Returning user, remove if old peer exists
if (peer)
peer.close();
returning = true;
}
peer = new Peer({ id: peerId, roomId, socket });
peers.set(peerId, peer); peers.set(peerId, peer);
@ -495,7 +519,7 @@ async function runWebSocketServer()
} }
} }
room.handlePeer(peer); room.handlePeer({ peer, returning });
}) })
.catch((error) => .catch((error) =>
{ {