2021-03-24 14:09:40 +00:00
|
|
|
// @flow
|
2015-12-17 15:31:11 +00:00
|
|
|
|
2021-11-10 10:11:29 +00:00
|
|
|
import Logger from '@jitsi/logger';
|
2020-05-20 10:57:03 +00:00
|
|
|
|
2017-04-21 10:00:50 +00:00
|
|
|
import { openConnection } from '../../../connection';
|
2021-04-22 15:05:14 +00:00
|
|
|
import {
|
|
|
|
openAuthDialog,
|
|
|
|
openLoginDialog } from '../../../react/features/authentication/actions.web';
|
2022-04-06 02:13:39 +00:00
|
|
|
import {
|
|
|
|
LoginDialog,
|
|
|
|
WaitForOwnerDialog
|
|
|
|
} from '../../../react/features/authentication/components';
|
2017-10-10 23:31:40 +00:00
|
|
|
import {
|
2022-09-27 07:10:28 +00:00
|
|
|
getTokenAuthUrl,
|
|
|
|
isTokenAuthEnabled
|
2021-03-24 14:09:40 +00:00
|
|
|
} from '../../../react/features/authentication/functions';
|
2021-06-16 11:08:18 +00:00
|
|
|
import { getReplaceParticipant } from '../../../react/features/base/config/functions';
|
2021-04-22 15:05:14 +00:00
|
|
|
import { isDialogOpen } from '../../../react/features/base/dialog';
|
2021-03-24 14:09:40 +00:00
|
|
|
import { setJWT } from '../../../react/features/base/jwt';
|
2016-01-06 22:39:13 +00:00
|
|
|
import UIUtil from '../util/UIUtil';
|
2017-04-21 10:00:50 +00:00
|
|
|
|
2022-04-06 02:13:39 +00:00
|
|
|
import ExternalLoginDialog from './LoginDialog';
|
2015-12-17 15:31:11 +00:00
|
|
|
|
2021-04-22 15:05:14 +00:00
|
|
|
|
2015-12-17 15:31:11 +00:00
|
|
|
let externalAuthWindow;
|
2021-03-24 14:09:40 +00:00
|
|
|
declare var APP: Object;
|
|
|
|
|
|
|
|
const logger = Logger.getLogger(__filename);
|
2015-12-17 15:31:11 +00:00
|
|
|
|
2016-07-11 11:46:11 +00:00
|
|
|
|
2016-01-15 14:59:35 +00:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2017-10-12 23:02:29 +00:00
|
|
|
function doExternalAuth(room, lockPassword) {
|
2021-03-24 14:09:40 +00:00
|
|
|
const config = APP.store.getState()['features/base/config'];
|
|
|
|
|
2015-12-17 15:31:11 +00:00
|
|
|
if (externalAuthWindow) {
|
|
|
|
externalAuthWindow.focus();
|
2017-10-12 23:02:29 +00:00
|
|
|
|
2015-12-17 15:31:11 +00:00
|
|
|
return;
|
|
|
|
}
|
2021-04-22 15:05:14 +00:00
|
|
|
|
2015-12-17 15:31:11 +00:00
|
|
|
if (room.isJoined()) {
|
2016-07-11 11:46:11 +00:00
|
|
|
let getUrl;
|
2017-10-12 23:02:29 +00:00
|
|
|
|
2021-03-24 14:09:40 +00:00
|
|
|
if (isTokenAuthEnabled(config)) {
|
|
|
|
getUrl = Promise.resolve(getTokenAuthUrl(config)(room.getName(), true));
|
2016-07-11 11:46:11 +00:00
|
|
|
initJWTTokenListener(room);
|
|
|
|
} else {
|
|
|
|
getUrl = room.getExternalAuthUrl(true);
|
|
|
|
}
|
2017-10-12 23:02:29 +00:00
|
|
|
getUrl.then(url => {
|
2022-04-06 02:13:39 +00:00
|
|
|
externalAuthWindow = ExternalLoginDialog.showExternalAuthDialog(
|
2015-12-17 15:31:11 +00:00
|
|
|
url,
|
2017-10-12 23:02:29 +00:00
|
|
|
() => {
|
2015-12-17 15:31:11 +00:00
|
|
|
externalAuthWindow = null;
|
2021-03-24 14:09:40 +00:00
|
|
|
if (!isTokenAuthEnabled(config)) {
|
2016-07-11 11:46:11 +00:00
|
|
|
room.join(lockPassword);
|
|
|
|
}
|
2015-12-17 15:31:11 +00:00
|
|
|
}
|
|
|
|
);
|
|
|
|
});
|
2021-03-24 14:09:40 +00:00
|
|
|
} else if (isTokenAuthEnabled(config)) {
|
2017-10-12 23:02:29 +00:00
|
|
|
redirectToTokenAuthService(room.getName());
|
2015-12-17 15:31:11 +00:00
|
|
|
} else {
|
2017-10-12 23:02:29 +00:00
|
|
|
room.getExternalAuthUrl().then(UIUtil.redirect);
|
2016-07-11 11:46:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Redirect the user to the token authentication service for the login to be
|
2021-03-16 14:56:54 +00:00
|
|
|
* performed. Once complete it is expected that the service will bring the user
|
2016-07-11 11:46:11 +00:00
|
|
|
* back with "?jwt={the JWT token}" query parameter added.
|
|
|
|
* @param {string} [roomName] the name of the conference room.
|
|
|
|
*/
|
2021-03-24 14:09:40 +00:00
|
|
|
export function redirectToTokenAuthService(roomName: string) {
|
|
|
|
const config = APP.store.getState()['features/base/config'];
|
|
|
|
|
2018-02-26 22:50:27 +00:00
|
|
|
// FIXME: This method will not preserve the other URL params that were
|
|
|
|
// originally passed.
|
2021-03-24 14:09:40 +00:00
|
|
|
UIUtil.redirect(getTokenAuthUrl(config)(roomName, false));
|
2016-07-11 11:46:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initializes 'message' listener that will wait for a JWT token to be received
|
|
|
|
* from the token authentication service opened in a popup window.
|
2021-03-16 14:56:54 +00:00
|
|
|
* @param room the name of the conference room.
|
2016-07-11 11:46:11 +00:00
|
|
|
*/
|
|
|
|
function initJWTTokenListener(room) {
|
2017-10-12 23:02:29 +00:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
function listener({ data, source }) {
|
2017-04-21 10:00:50 +00:00
|
|
|
if (externalAuthWindow !== source) {
|
2017-10-12 23:02:29 +00:00
|
|
|
logger.warn('Ignored message not coming '
|
|
|
|
+ 'from external authnetication window');
|
|
|
|
|
2016-07-11 11:46:11 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-04-21 10:00:50 +00:00
|
|
|
|
|
|
|
let jwt;
|
|
|
|
|
|
|
|
if (data && (jwt = data.jwtToken)) {
|
2017-10-12 23:02:29 +00:00
|
|
|
logger.info('Received JSON Web Token (JWT):', jwt);
|
2017-04-21 10:00:50 +00:00
|
|
|
|
|
|
|
APP.store.dispatch(setJWT(jwt));
|
|
|
|
|
2017-10-12 23:02:29 +00:00
|
|
|
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
|
2021-03-16 14:56:54 +00:00
|
|
|
// the session-ID from the focus, which will then be used
|
2017-10-12 23:02:29 +00:00
|
|
|
// to upgrade current connection's user role
|
|
|
|
|
|
|
|
newRoom.room.moderator.authenticate()
|
|
|
|
.then(() => {
|
|
|
|
connection.disconnect();
|
|
|
|
|
|
|
|
// At this point we'll have session-ID stored in
|
2021-03-16 14:56:54 +00:00
|
|
|
// the settings. It will be used in the call below
|
2017-10-12 23:02:29 +00:00
|
|
|
// 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) => {
|
2016-07-11 11:46:11 +00:00
|
|
|
unregister();
|
2017-10-12 23:02:29 +00:00
|
|
|
connection.disconnect();
|
|
|
|
logger.error(
|
|
|
|
'Authentication failed on the new connection',
|
|
|
|
error, code);
|
2016-07-11 11:46:11 +00:00
|
|
|
});
|
2017-10-12 23:02:29 +00:00
|
|
|
}, err => {
|
|
|
|
unregister();
|
|
|
|
logger.error('Failed to open new connection', err);
|
|
|
|
});
|
2016-07-11 11:46:11 +00:00
|
|
|
}
|
2017-10-12 23:02:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
function unregister() {
|
|
|
|
window.removeEventListener('message', listener);
|
|
|
|
}
|
|
|
|
|
2016-07-11 11:46:11 +00:00
|
|
|
if (window.addEventListener) {
|
2017-10-12 23:02:29 +00:00
|
|
|
window.addEventListener('message', listener, false);
|
2015-12-17 15:31:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-15 14:59:35 +00:00
|
|
|
/**
|
2021-04-22 15:05:14 +00:00
|
|
|
* Authenticate for the conference.
|
2016-01-15 14:59:35 +00:00
|
|
|
* Uses external service for auth if conference supports that.
|
|
|
|
* @param {JitsiConference} room
|
|
|
|
* @param {string} [lockPassword] password to use if the conference is locked
|
|
|
|
*/
|
2021-04-22 15:05:14 +00:00
|
|
|
function authenticate(room: Object, lockPassword: string) {
|
2021-03-24 14:09:40 +00:00
|
|
|
const config = APP.store.getState()['features/base/config'];
|
|
|
|
|
|
|
|
if (isTokenAuthEnabled(config) || room.isExternalAuthEnabled()) {
|
2015-12-17 15:31:11 +00:00
|
|
|
doExternalAuth(room, lockPassword);
|
2021-04-22 15:05:14 +00:00
|
|
|
} else {
|
|
|
|
APP.store.dispatch(openLoginDialog());
|
2015-12-17 15:31:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-22 15:05:14 +00:00
|
|
|
/**
|
|
|
|
* 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) {
|
2022-04-06 02:13:39 +00:00
|
|
|
if (isDialogOpen(APP.store, WaitForOwnerDialog) || isDialogOpen(APP.store, LoginDialog)) {
|
2021-04-22 15:05:14 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
APP.store.dispatch(
|
|
|
|
openAuthDialog(
|
|
|
|
room.getName(), authenticate.bind(null, room, lockPassword))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-02-25 13:52:15 +00:00
|
|
|
/**
|
|
|
|
* De-authenticate local user.
|
|
|
|
*
|
|
|
|
* @param {JitsiConference} room
|
|
|
|
* @param {string} [lockPassword] password to use if the conference is locked
|
|
|
|
* @returns {Promise}
|
|
|
|
*/
|
2021-03-24 14:09:40 +00:00
|
|
|
function logout(room: Object) {
|
2017-10-12 23:02:29 +00:00
|
|
|
return new Promise(resolve => {
|
2016-02-25 13:52:15 +00:00
|
|
|
room.room.moderator.logout(resolve);
|
2017-10-12 23:02:29 +00:00
|
|
|
}).then(url => {
|
2016-02-25 13:52:15 +00:00
|
|
|
// de-authenticate conference on the fly
|
|
|
|
if (room.isJoined()) {
|
2021-06-16 11:08:18 +00:00
|
|
|
const replaceParticipant = getReplaceParticipant(APP.store.getState());
|
2021-06-11 08:58:45 +00:00
|
|
|
|
|
|
|
room.join(null, replaceParticipant);
|
2016-02-25 13:52:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return url;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-12-17 15:31:11 +00:00
|
|
|
export default {
|
2021-04-22 15:05:14 +00:00
|
|
|
authenticate,
|
|
|
|
logout,
|
|
|
|
requireAuth
|
2015-12-17 15:31:11 +00:00
|
|
|
};
|