Merge branch 'develop' into develop
commit
d606acf1e4
|
|
@ -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%",
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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) =>
|
||||||
({
|
({
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
|
|
|
||||||
|
|
@ -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'
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ const styles = (theme) =>
|
||||||
},
|
},
|
||||||
divider :
|
divider :
|
||||||
{
|
{
|
||||||
marginLeft : theme.spacing(3),
|
marginLeft : theme.spacing(3)
|
||||||
},
|
},
|
||||||
show :
|
show :
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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'
|
||||||
|
|
|
||||||
|
|
@ -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": "注销",
|
||||||
|
|
|
||||||
|
|
@ -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í",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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": "Αποσύνδεση",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) =>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue