123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- // @flow
-
- import Logger from 'jitsi-meet-logger';
-
- import { openConnection } from '../../../connection';
- import {
- openAuthDialog,
- openLoginDialog } from '../../../react/features/authentication/actions.web';
- import { WaitForOwnerDialog } from '../../../react/features/authentication/components';
- import {
- isTokenAuthEnabled,
- getTokenAuthUrl
- } from '../../../react/features/authentication/functions';
- import { getReplaceParticipant } from '../../../react/features/base/config/functions';
- import { isDialogOpen } from '../../../react/features/base/dialog';
- import { setJWT } from '../../../react/features/base/jwt';
- import UIUtil from '../util/UIUtil';
-
- import LoginDialog from './LoginDialog';
-
-
- let externalAuthWindow;
- declare var APP: Object;
-
- const logger = Logger.getLogger(__filename);
-
-
- /**
- * Authenticate using external service or just focus
- * external auth window if there is one already.
- *
- * @param {JitsiConference} room
- * @param {string} [lockPassword] password to use if the conference is locked
- */
- function doExternalAuth(room, lockPassword) {
- const config = APP.store.getState()['features/base/config'];
-
- if (externalAuthWindow) {
- externalAuthWindow.focus();
-
- return;
- }
-
- if (room.isJoined()) {
- let getUrl;
-
- if (isTokenAuthEnabled(config)) {
- getUrl = Promise.resolve(getTokenAuthUrl(config)(room.getName(), true));
- initJWTTokenListener(room);
- } else {
- getUrl = room.getExternalAuthUrl(true);
- }
- getUrl.then(url => {
- externalAuthWindow = LoginDialog.showExternalAuthDialog(
- url,
- () => {
- externalAuthWindow = null;
- if (!isTokenAuthEnabled(config)) {
- room.join(lockPassword);
- }
- }
- );
- });
- } else if (isTokenAuthEnabled(config)) {
- redirectToTokenAuthService(room.getName());
- } else {
- room.getExternalAuthUrl().then(UIUtil.redirect);
- }
- }
-
- /**
- * Redirect the user to the token authentication service for the login to be
- * performed. Once complete it is expected that the service will bring the user
- * back with "?jwt={the JWT token}" query parameter added.
- * @param {string} [roomName] the name of the conference room.
- */
- export function redirectToTokenAuthService(roomName: string) {
- const config = APP.store.getState()['features/base/config'];
-
- // FIXME: This method will not preserve the other URL params that were
- // originally passed.
- UIUtil.redirect(getTokenAuthUrl(config)(roomName, false));
- }
-
- /**
- * Initializes 'message' listener that will wait for a JWT token to be received
- * from the token authentication service opened in a popup window.
- * @param room the name of the conference room.
- */
- function initJWTTokenListener(room) {
- /**
- *
- */
- function listener({ data, source }) {
- if (externalAuthWindow !== source) {
- logger.warn('Ignored message not coming '
- + 'from external authnetication window');
-
- return;
- }
-
- let jwt;
-
- if (data && (jwt = data.jwtToken)) {
- logger.info('Received JSON Web Token (JWT):', jwt);
-
- APP.store.dispatch(setJWT(jwt));
-
- const roomName = room.getName();
-
- openConnection({
- retry: false,
- roomName
- }).then(connection => {
- // Start new connection
- const newRoom = connection.initJitsiConference(
- roomName, APP.conference._getConferenceOptions());
-
- // Authenticate from the new connection to get
- // the session-ID from the focus, which will then be used
- // to upgrade current connection's user role
-
- newRoom.room.moderator.authenticate()
- .then(() => {
- connection.disconnect();
-
- // At this point we'll have session-ID stored in
- // the settings. It will be used in the call below
- // to upgrade user's role
- room.room.moderator.authenticate()
- .then(() => {
- logger.info('User role upgrade done !');
- // eslint-disable-line no-use-before-define
- unregister();
- })
- .catch((err, errCode) => {
- logger.error('Authentication failed: ',
- err, errCode);
- unregister();
- });
- })
- .catch((error, code) => {
- unregister();
- connection.disconnect();
- logger.error(
- 'Authentication failed on the new connection',
- error, code);
- });
- }, err => {
- unregister();
- logger.error('Failed to open new connection', err);
- });
- }
- }
-
- /**
- *
- */
- function unregister() {
- window.removeEventListener('message', listener);
- }
-
- if (window.addEventListener) {
- window.addEventListener('message', listener, false);
- }
- }
-
- /**
- * Authenticate for the conference.
- * Uses external service for auth if conference supports that.
- * @param {JitsiConference} room
- * @param {string} [lockPassword] password to use if the conference is locked
- */
- function authenticate(room: Object, lockPassword: string) {
- const config = APP.store.getState()['features/base/config'];
-
- if (isTokenAuthEnabled(config) || room.isExternalAuthEnabled()) {
- doExternalAuth(room, lockPassword);
- } else {
- APP.store.dispatch(openLoginDialog());
- }
- }
-
- /**
- * Notify user that authentication is required to create the conference.
- * @param {JitsiConference} room
- * @param {string} [lockPassword] password to use if the conference is locked
- */
- function requireAuth(room: Object, lockPassword: string) {
- if (!isDialogOpen(APP.store, WaitForOwnerDialog)) {
- return;
- }
-
- APP.store.dispatch(
- openAuthDialog(
- room.getName(), authenticate.bind(null, room, lockPassword))
- );
- }
-
- /**
- * De-authenticate local user.
- *
- * @param {JitsiConference} room
- * @param {string} [lockPassword] password to use if the conference is locked
- * @returns {Promise}
- */
- function logout(room: Object) {
- return new Promise(resolve => {
- room.room.moderator.logout(resolve);
- }).then(url => {
- // de-authenticate conference on the fly
- if (room.isJoined()) {
- const replaceParticipant = getReplaceParticipant(APP.store.getState());
-
- room.join(null, replaceParticipant);
- }
-
- return url;
- });
- }
-
- export default {
- authenticate,
- logout,
- requireAuth
- };
|