fix(authentication): removed old LoginDialog.js file, fixed redirection to the external auth and created actions.any.js (#9049)
* fix(authentication) login dialog now closes when connection is established * fix(authentication) fixed shibboleth auth * fix(authentication) renamed authenticateExternal func to authenticate and updated its logic * fix(authentication)removed logindialog.js and created actions.any * fix(authentication) removed focus from externalauthwindow * fix(authentication) removed private sign from some actions and added openLoginDialog to actions.any * fix(authentication) exported all from actions.any * fix(authentication) reverted change regarding externalAuth * fix(authentication) fixed indentation
This commit is contained in:
parent
20a62e5eb4
commit
98658f573c
|
@ -312,6 +312,11 @@ class ConferenceConnector {
|
||||||
room.join();
|
room.join();
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
|
const { password }
|
||||||
|
= APP.store.getState()['features/base/conference'];
|
||||||
|
|
||||||
|
AuthHandler.requireAuth(room, password);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2278,7 +2283,7 @@ export default {
|
||||||
});
|
});
|
||||||
|
|
||||||
APP.UI.addListener(UIEvents.AUTH_CLICKED, () => {
|
APP.UI.addListener(UIEvents.AUTH_CLICKED, () => {
|
||||||
AuthHandler.authenticateExternal(room);
|
AuthHandler.authenticate(room);
|
||||||
});
|
});
|
||||||
|
|
||||||
APP.UI.addListener(
|
APP.UI.addListener(
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { jitsiLocalStorage } from '@jitsi/js-utils';
|
||||||
import Logger from 'jitsi-meet-logger';
|
import Logger from 'jitsi-meet-logger';
|
||||||
|
|
||||||
import { redirectToTokenAuthService } from './modules/UI/authentication/AuthHandler';
|
import { redirectToTokenAuthService } from './modules/UI/authentication/AuthHandler';
|
||||||
import { hideLoginDialog } from './react/features/authentication/actions.web';
|
|
||||||
import { LoginDialog } from './react/features/authentication/components';
|
import { LoginDialog } from './react/features/authentication/components';
|
||||||
import { isTokenAuthEnabled } from './react/features/authentication/functions';
|
import { isTokenAuthEnabled } from './react/features/authentication/functions';
|
||||||
import {
|
import {
|
||||||
|
@ -243,7 +242,6 @@ function requestAuth(roomName) {
|
||||||
|
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const onSuccess = connection => {
|
const onSuccess = connection => {
|
||||||
APP.store.dispatch(hideLoginDialog());
|
|
||||||
resolve(connection);
|
resolve(connection);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -259,6 +259,7 @@
|
||||||
"muteParticipantsVideoTitle": "Disable camera of this participant?",
|
"muteParticipantsVideoTitle": "Disable camera of this participant?",
|
||||||
"muteParticipantsVideoBody": "You won't be able to turn the camera back on, but they can turn it back on at any time.",
|
"muteParticipantsVideoBody": "You won't be able to turn the camera back on, but they can turn it back on at any time.",
|
||||||
"Ok": "OK",
|
"Ok": "OK",
|
||||||
|
"password": "Password",
|
||||||
"passwordLabel": "The meeting has been locked by a participant. Please enter the $t(lockRoomPassword) to join.",
|
"passwordLabel": "The meeting has been locked by a participant. Please enter the $t(lockRoomPassword) to join.",
|
||||||
"passwordNotSupported": "Setting a meeting $t(lockRoomPassword) is not supported.",
|
"passwordNotSupported": "Setting a meeting $t(lockRoomPassword) is not supported.",
|
||||||
"passwordNotSupportedTitle": "$t(lockRoomPasswordUppercase) not supported",
|
"passwordNotSupportedTitle": "$t(lockRoomPasswordUppercase) not supported",
|
||||||
|
|
|
@ -3,15 +3,21 @@
|
||||||
import Logger from 'jitsi-meet-logger';
|
import Logger from 'jitsi-meet-logger';
|
||||||
|
|
||||||
import { openConnection } from '../../../connection';
|
import { openConnection } from '../../../connection';
|
||||||
|
import {
|
||||||
|
openAuthDialog,
|
||||||
|
openLoginDialog } from '../../../react/features/authentication/actions.web';
|
||||||
|
import { WaitForOwnerDialog } from '../../../react/features/authentication/components';
|
||||||
import {
|
import {
|
||||||
isTokenAuthEnabled,
|
isTokenAuthEnabled,
|
||||||
getTokenAuthUrl
|
getTokenAuthUrl
|
||||||
} from '../../../react/features/authentication/functions';
|
} from '../../../react/features/authentication/functions';
|
||||||
|
import { isDialogOpen } from '../../../react/features/base/dialog';
|
||||||
import { setJWT } from '../../../react/features/base/jwt';
|
import { setJWT } from '../../../react/features/base/jwt';
|
||||||
import UIUtil from '../util/UIUtil';
|
import UIUtil from '../util/UIUtil';
|
||||||
|
|
||||||
import LoginDialog from './LoginDialog';
|
import LoginDialog from './LoginDialog';
|
||||||
|
|
||||||
|
|
||||||
let externalAuthWindow;
|
let externalAuthWindow;
|
||||||
declare var APP: Object;
|
declare var APP: Object;
|
||||||
|
|
||||||
|
@ -33,6 +39,7 @@ function doExternalAuth(room, lockPassword) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (room.isJoined()) {
|
if (room.isJoined()) {
|
||||||
let getUrl;
|
let getUrl;
|
||||||
|
|
||||||
|
@ -158,18 +165,37 @@ function initJWTTokenListener(room) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Authenticate for the conference.
|
||||||
* Uses external service for auth if conference supports that.
|
* Uses external service for auth if conference supports that.
|
||||||
* @param {JitsiConference} room
|
* @param {JitsiConference} room
|
||||||
* @param {string} [lockPassword] password to use if the conference is locked
|
* @param {string} [lockPassword] password to use if the conference is locked
|
||||||
*/
|
*/
|
||||||
function authenticateExternal(room: Object, lockPassword: string) {
|
function authenticate(room: Object, lockPassword: string) {
|
||||||
const config = APP.store.getState()['features/base/config'];
|
const config = APP.store.getState()['features/base/config'];
|
||||||
|
|
||||||
if (isTokenAuthEnabled(config) || room.isExternalAuthEnabled()) {
|
if (isTokenAuthEnabled(config) || room.isExternalAuthEnabled()) {
|
||||||
doExternalAuth(room, lockPassword);
|
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.
|
* De-authenticate local user.
|
||||||
*
|
*
|
||||||
|
@ -191,6 +217,7 @@ function logout(room: Object) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
authenticateExternal,
|
authenticate,
|
||||||
logout
|
logout,
|
||||||
|
requireAuth
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,202 +1,16 @@
|
||||||
/* global $, APP, config */
|
// @flow
|
||||||
|
|
||||||
import { toJid } from '../../../react/features/base/connection/functions';
|
declare var APP: Object;
|
||||||
import {
|
|
||||||
JitsiConnectionErrors
|
|
||||||
} from '../../../react/features/base/lib-jitsi-meet';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build html for "password required" dialog.
|
|
||||||
* @returns {string} html string
|
|
||||||
*/
|
|
||||||
function getPasswordInputHtml() {
|
|
||||||
const placeholder = config.hosts.authdomain
|
|
||||||
? 'user identity'
|
|
||||||
: 'user@domain.net';
|
|
||||||
|
|
||||||
return `
|
|
||||||
<input name="username" type="text"
|
|
||||||
class="input-control"
|
|
||||||
data-i18n="[placeholder]dialog.user"
|
|
||||||
placeholder=${placeholder} autofocus>
|
|
||||||
<input name="password" type="password"
|
|
||||||
class="input-control"
|
|
||||||
data-i18n="[placeholder]dialog.userPassword">`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate cancel button config for the dialog.
|
|
||||||
* @returns {Object}
|
|
||||||
*/
|
|
||||||
function cancelButton() {
|
|
||||||
return {
|
|
||||||
title: APP.translation.generateTranslationHTML('dialog.Cancel'),
|
|
||||||
value: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Auth dialog for JitsiConnection which supports retries.
|
|
||||||
* If no cancelCallback provided then there will be
|
|
||||||
* no cancel button on the dialog.
|
|
||||||
*
|
|
||||||
* @class LoginDialog
|
|
||||||
* @constructor
|
|
||||||
*
|
|
||||||
* @param {function(jid, password)} successCallback
|
|
||||||
* @param {function} [cancelCallback] callback to invoke if user canceled.
|
|
||||||
*/
|
|
||||||
function LoginDialog(successCallback, cancelCallback) {
|
|
||||||
const loginButtons = [ {
|
|
||||||
title: APP.translation.generateTranslationHTML('dialog.Ok'),
|
|
||||||
value: true
|
|
||||||
} ];
|
|
||||||
const finishedButtons = [ {
|
|
||||||
title: APP.translation.generateTranslationHTML('dialog.retry'),
|
|
||||||
value: 'retry'
|
|
||||||
} ];
|
|
||||||
|
|
||||||
// show "cancel" button only if cancelCallback provided
|
|
||||||
if (cancelCallback) {
|
|
||||||
loginButtons.push(cancelButton());
|
|
||||||
finishedButtons.push(cancelButton());
|
|
||||||
}
|
|
||||||
|
|
||||||
const states = {
|
|
||||||
login: {
|
|
||||||
buttons: loginButtons,
|
|
||||||
focus: ':input:first',
|
|
||||||
html: getPasswordInputHtml(),
|
|
||||||
titleKey: 'dialog.passwordRequired',
|
|
||||||
|
|
||||||
submit(e, v, m, f) { // eslint-disable-line max-params
|
|
||||||
e.preventDefault();
|
|
||||||
if (v) {
|
|
||||||
const jid = f.username;
|
|
||||||
const password = f.password;
|
|
||||||
|
|
||||||
if (jid && password) {
|
|
||||||
// eslint-disable-next-line no-use-before-define
|
|
||||||
connDialog.goToState('connecting');
|
|
||||||
successCallback(toJid(jid, config.hosts), password);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// User cancelled
|
|
||||||
cancelCallback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
connecting: {
|
|
||||||
buttons: [],
|
|
||||||
defaultButton: 0,
|
|
||||||
html: '<div id="connectionStatus"></div>',
|
|
||||||
titleKey: 'dialog.connecting'
|
|
||||||
},
|
|
||||||
finished: {
|
|
||||||
buttons: finishedButtons,
|
|
||||||
defaultButton: 0,
|
|
||||||
html: '<div id="errorMessage"></div>',
|
|
||||||
titleKey: 'dialog.error',
|
|
||||||
|
|
||||||
submit(e, v) {
|
|
||||||
e.preventDefault();
|
|
||||||
if (v === 'retry') {
|
|
||||||
// eslint-disable-next-line no-use-before-define
|
|
||||||
connDialog.goToState('login');
|
|
||||||
} else {
|
|
||||||
// User cancelled
|
|
||||||
cancelCallback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const connDialog = APP.UI.messageHandler.openDialogWithStates(
|
|
||||||
states,
|
|
||||||
{
|
|
||||||
closeText: '',
|
|
||||||
persistent: true,
|
|
||||||
zIndex: 1020
|
|
||||||
},
|
|
||||||
null
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays error message in 'finished' state which allows either to cancel
|
|
||||||
* or retry.
|
|
||||||
* @param error the key to the error to be displayed.
|
|
||||||
* @param options the options to the error message (optional)
|
|
||||||
*/
|
|
||||||
this.displayError = function(error, options) {
|
|
||||||
|
|
||||||
const finishedState = connDialog.getState('finished');
|
|
||||||
|
|
||||||
const errorMessageElem = finishedState.find('#errorMessage');
|
|
||||||
|
|
||||||
let messageKey;
|
|
||||||
|
|
||||||
if (error === JitsiConnectionErrors.PASSWORD_REQUIRED) {
|
|
||||||
// this is a password required error, as login window was already
|
|
||||||
// open once, this means username or password is wrong
|
|
||||||
messageKey = 'dialog.incorrectPassword';
|
|
||||||
} else {
|
|
||||||
messageKey = 'dialog.connectErrorWithMsg';
|
|
||||||
|
|
||||||
if (!options) {
|
|
||||||
options = {};// eslint-disable-line no-param-reassign
|
|
||||||
}
|
|
||||||
|
|
||||||
options.msg = error;
|
|
||||||
}
|
|
||||||
|
|
||||||
errorMessageElem.attr('data-i18n', messageKey);
|
|
||||||
|
|
||||||
APP.translation.translateElement($(errorMessageElem), options);
|
|
||||||
|
|
||||||
connDialog.goToState('finished');
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show message as connection status.
|
|
||||||
* @param {string} messageKey the key to the message
|
|
||||||
*/
|
|
||||||
this.displayConnectionStatus = function(messageKey) {
|
|
||||||
const connectingState = connDialog.getState('connecting');
|
|
||||||
|
|
||||||
const connectionStatus = connectingState.find('#connectionStatus');
|
|
||||||
|
|
||||||
connectionStatus.attr('data-i18n', messageKey);
|
|
||||||
APP.translation.translateElement($(connectionStatus));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes LoginDialog.
|
|
||||||
*/
|
|
||||||
this.close = function() {
|
|
||||||
connDialog.close();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
/**
|
|
||||||
* Show new auth dialog for JitsiConnection.
|
|
||||||
*
|
|
||||||
* @param {function(jid, password)} successCallback
|
|
||||||
* @param {function} [cancelCallback] callback to invoke if user canceled.
|
|
||||||
*
|
|
||||||
* @returns {LoginDialog}
|
|
||||||
*/
|
|
||||||
showAuthDialog(successCallback, cancelCallback) {
|
|
||||||
return new LoginDialog(successCallback, cancelCallback);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show notification that external auth is required (using provided url).
|
* Show notification that external auth is required (using provided url).
|
||||||
* @param {string} url URL to use for external auth.
|
* @param {string} url - URL to use for external auth.
|
||||||
* @param {function} callback callback to invoke when auth popup is closed.
|
* @param {function} callback - callback to invoke when auth popup is closed.
|
||||||
* @returns auth dialog
|
* @returns auth dialog
|
||||||
*/
|
*/
|
||||||
showExternalAuthDialog(url, callback) {
|
showExternalAuthDialog(url: string, callback: ?Function) {
|
||||||
const dialog = APP.UI.messageHandler.openCenteredPopup(
|
const dialog = APP.UI.messageHandler.openCenteredPopup(
|
||||||
url, 910, 660,
|
url, 910, 660,
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import type { Dispatch } from 'redux';
|
||||||
|
|
||||||
|
import { checkIfCanJoin } from '../base/conference';
|
||||||
|
import { openDialog } from '../base/dialog';
|
||||||
|
|
||||||
|
import {
|
||||||
|
STOP_WAIT_FOR_OWNER,
|
||||||
|
UPGRADE_ROLE_FINISHED,
|
||||||
|
UPGRADE_ROLE_STARTED, WAIT_FOR_OWNER
|
||||||
|
} from './actionTypes';
|
||||||
|
import { LoginDialog, WaitForOwnerDialog } from './components';
|
||||||
|
import logger from './logger';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiates authenticating and upgrading the role of the local participant to
|
||||||
|
* moderator which will allow to create and join a new conference on an XMPP
|
||||||
|
* password + guest access configuration. Refer to {@link LoginDialog} for more
|
||||||
|
* info.
|
||||||
|
*
|
||||||
|
* @param {string} id - The XMPP user's ID (e.g. {@code user@domain.com}).
|
||||||
|
* @param {string} password - The XMPP user's password.
|
||||||
|
* @param {JitsiConference} conference - The conference for which the local
|
||||||
|
* participant's role will be upgraded.
|
||||||
|
* @returns {Function}
|
||||||
|
*/
|
||||||
|
export function authenticateAndUpgradeRole(
|
||||||
|
id: string,
|
||||||
|
password: string,
|
||||||
|
conference: Object) {
|
||||||
|
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||||
|
const { password: roomPassword }
|
||||||
|
= getState()['features/base/conference'];
|
||||||
|
const process
|
||||||
|
= conference.authenticateAndUpgradeRole({
|
||||||
|
id,
|
||||||
|
password,
|
||||||
|
roomPassword,
|
||||||
|
|
||||||
|
onLoginSuccessful() {
|
||||||
|
// When the login succeeds, the process has completed half
|
||||||
|
// of its job (i.e. 0.5).
|
||||||
|
return dispatch(_upgradeRoleFinished(process, 0.5));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch(_upgradeRoleStarted(process));
|
||||||
|
process.then(
|
||||||
|
/* onFulfilled */ () => dispatch(_upgradeRoleFinished(process, 1)),
|
||||||
|
/* onRejected */ error => {
|
||||||
|
// The lack of an error signals a cancellation.
|
||||||
|
if (error.authenticationError || error.connectionError) {
|
||||||
|
logger.error('authenticateAndUpgradeRole failed', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(_upgradeRoleFinished(process, error));
|
||||||
|
});
|
||||||
|
|
||||||
|
return process;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signals that the process of authenticating and upgrading the local
|
||||||
|
* participant's role has finished either with success or with a specific error.
|
||||||
|
*
|
||||||
|
* @param {Object} thenableWithCancel - The process of authenticating and
|
||||||
|
* upgrading the local participant's role.
|
||||||
|
* @param {Object} progressOrError - If the value is a {@code number}, then the
|
||||||
|
* process of authenticating and upgrading the local participant's role has
|
||||||
|
* succeeded in one of its two/multiple steps; otherwise, it has failed with the
|
||||||
|
* specified error. Refer to {@link JitsiConference#authenticateAndUpgradeRole}
|
||||||
|
* in lib-jitsi-meet for the error details.
|
||||||
|
* @private
|
||||||
|
* @returns {{
|
||||||
|
* type: UPGRADE_ROLE_FINISHED,
|
||||||
|
* error: ?Object,
|
||||||
|
* progress: number
|
||||||
|
* }}
|
||||||
|
*/
|
||||||
|
function _upgradeRoleFinished(
|
||||||
|
thenableWithCancel,
|
||||||
|
progressOrError: number | Object) {
|
||||||
|
let error;
|
||||||
|
let progress;
|
||||||
|
|
||||||
|
if (typeof progressOrError === 'number') {
|
||||||
|
progress = progressOrError;
|
||||||
|
} else {
|
||||||
|
// Make the specified error object resemble an Error instance (to the
|
||||||
|
// extent that jitsi-meet needs it).
|
||||||
|
const {
|
||||||
|
authenticationError,
|
||||||
|
connectionError,
|
||||||
|
...other
|
||||||
|
} = progressOrError;
|
||||||
|
|
||||||
|
error = {
|
||||||
|
name: authenticationError || connectionError,
|
||||||
|
...other
|
||||||
|
};
|
||||||
|
progress = authenticationError ? 0.5 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: UPGRADE_ROLE_FINISHED,
|
||||||
|
error,
|
||||||
|
progress,
|
||||||
|
thenableWithCancel
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signals that a process of authenticating and upgrading the local
|
||||||
|
* participant's role has started.
|
||||||
|
*
|
||||||
|
* @param {Object} thenableWithCancel - The process of authenticating and
|
||||||
|
* upgrading the local participant's role.
|
||||||
|
* @private
|
||||||
|
* @returns {{
|
||||||
|
* type: UPGRADE_ROLE_STARTED,
|
||||||
|
* thenableWithCancel: Object
|
||||||
|
* }}
|
||||||
|
*/
|
||||||
|
function _upgradeRoleStarted(thenableWithCancel) {
|
||||||
|
return {
|
||||||
|
type: UPGRADE_ROLE_STARTED,
|
||||||
|
thenableWithCancel
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens {@link WaitForOnwerDialog}.
|
||||||
|
*
|
||||||
|
* @protected
|
||||||
|
* @returns {Action}
|
||||||
|
*/
|
||||||
|
export function openWaitForOwnerDialog() {
|
||||||
|
return openDialog(WaitForOwnerDialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops waiting for the conference owner.
|
||||||
|
*
|
||||||
|
* @returns {{
|
||||||
|
* type: STOP_WAIT_FOR_OWNER
|
||||||
|
* }}
|
||||||
|
*/
|
||||||
|
export function stopWaitForOwner() {
|
||||||
|
return {
|
||||||
|
type: STOP_WAIT_FOR_OWNER
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when Jicofo rejects to create the room for anonymous user. Will
|
||||||
|
* start the process of "waiting for the owner" by periodically trying to join
|
||||||
|
* the room every five seconds.
|
||||||
|
*
|
||||||
|
* @returns {Function}
|
||||||
|
*/
|
||||||
|
export function waitForOwner() {
|
||||||
|
return (dispatch: Dispatch<any>) =>
|
||||||
|
dispatch({
|
||||||
|
type: WAIT_FOR_OWNER,
|
||||||
|
handler: () => dispatch(checkIfCanJoin()),
|
||||||
|
timeoutMs: 5000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens {@link LoginDialog} which will ask to enter username and password
|
||||||
|
* for the current conference.
|
||||||
|
*
|
||||||
|
* @protected
|
||||||
|
* @returns {Action}
|
||||||
|
*/
|
||||||
|
export function openLoginDialog() {
|
||||||
|
return openDialog(LoginDialog);
|
||||||
|
}
|
|
@ -3,68 +3,14 @@
|
||||||
import type { Dispatch } from 'redux';
|
import type { Dispatch } from 'redux';
|
||||||
|
|
||||||
import { appNavigate } from '../app/actions';
|
import { appNavigate } from '../app/actions';
|
||||||
import { checkIfCanJoin, conferenceLeft } from '../base/conference/actions';
|
import { conferenceLeft } from '../base/conference/actions';
|
||||||
import { connectionFailed } from '../base/connection/actions.native';
|
import { connectionFailed } from '../base/connection/actions.native';
|
||||||
import { openDialog } from '../base/dialog/actions';
|
|
||||||
import { set } from '../base/redux';
|
import { set } from '../base/redux';
|
||||||
|
|
||||||
import {
|
import { CANCEL_LOGIN } from './actionTypes';
|
||||||
CANCEL_LOGIN,
|
import { stopWaitForOwner } from './actions.any';
|
||||||
STOP_WAIT_FOR_OWNER,
|
|
||||||
UPGRADE_ROLE_FINISHED,
|
|
||||||
UPGRADE_ROLE_STARTED,
|
|
||||||
WAIT_FOR_OWNER
|
|
||||||
} from './actionTypes';
|
|
||||||
import { LoginDialog, WaitForOwnerDialog } from './components';
|
|
||||||
import logger from './logger';
|
|
||||||
|
|
||||||
/**
|
export * from './actions.any';
|
||||||
* Initiates authenticating and upgrading the role of the local participant to
|
|
||||||
* moderator which will allow to create and join a new conference on an XMPP
|
|
||||||
* password + guest access configuration. Refer to {@link LoginDialog} for more
|
|
||||||
* info.
|
|
||||||
*
|
|
||||||
* @param {string} id - The XMPP user's ID (e.g. {@code user@domain.com}).
|
|
||||||
* @param {string} password - The XMPP user's password.
|
|
||||||
* @param {JitsiConference} conference - The conference for which the local
|
|
||||||
* participant's role will be upgraded.
|
|
||||||
* @returns {Function}
|
|
||||||
*/
|
|
||||||
export function authenticateAndUpgradeRole(
|
|
||||||
id: string,
|
|
||||||
password: string,
|
|
||||||
conference: Object) {
|
|
||||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
|
||||||
const { password: roomPassword }
|
|
||||||
= getState()['features/base/conference'];
|
|
||||||
const process
|
|
||||||
= conference.authenticateAndUpgradeRole({
|
|
||||||
id,
|
|
||||||
password,
|
|
||||||
roomPassword,
|
|
||||||
|
|
||||||
onLoginSuccessful() {
|
|
||||||
// When the login succeeds, the process has completed half
|
|
||||||
// of its job (i.e. 0.5).
|
|
||||||
return dispatch(_upgradeRoleFinished(process, 0.5));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
dispatch(_upgradeRoleStarted(process));
|
|
||||||
process.then(
|
|
||||||
/* onFulfilled */ () => dispatch(_upgradeRoleFinished(process, 1)),
|
|
||||||
/* onRejected */ error => {
|
|
||||||
// The lack of an error signals a cancellation.
|
|
||||||
if (error.authenticationError || error.connectionError) {
|
|
||||||
logger.error('authenticateAndUpgradeRole failed', error);
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch(_upgradeRoleFinished(process, error));
|
|
||||||
});
|
|
||||||
|
|
||||||
return process;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels {@ink LoginDialog}.
|
* Cancels {@ink LoginDialog}.
|
||||||
|
@ -118,121 +64,4 @@ export function cancelWaitForOwner() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens {@link LoginDialog} which will ask to enter username and password
|
|
||||||
* for the current conference.
|
|
||||||
*
|
|
||||||
* @protected
|
|
||||||
* @returns {Action}
|
|
||||||
*/
|
|
||||||
export function _openLoginDialog() {
|
|
||||||
return openDialog(LoginDialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens {@link WaitForOnwerDialog}.
|
|
||||||
*
|
|
||||||
* @protected
|
|
||||||
* @returns {Action}
|
|
||||||
*/
|
|
||||||
export function _openWaitForOwnerDialog() {
|
|
||||||
return openDialog(WaitForOwnerDialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stops waiting for the conference owner.
|
|
||||||
*
|
|
||||||
* @returns {{
|
|
||||||
* type: STOP_WAIT_FOR_OWNER
|
|
||||||
* }}
|
|
||||||
*/
|
|
||||||
export function stopWaitForOwner() {
|
|
||||||
return {
|
|
||||||
type: STOP_WAIT_FOR_OWNER
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Signals that the process of authenticating and upgrading the local
|
|
||||||
* participant's role has finished either with success or with a specific error.
|
|
||||||
*
|
|
||||||
* @param {Object} thenableWithCancel - The process of authenticating and
|
|
||||||
* upgrading the local participant's role.
|
|
||||||
* @param {Object} progressOrError - If the value is a {@code number}, then the
|
|
||||||
* process of authenticating and upgrading the local participant's role has
|
|
||||||
* succeeded in one of its two/multiple steps; otherwise, it has failed with the
|
|
||||||
* specified error. Refer to {@link JitsiConference#authenticateAndUpgradeRole}
|
|
||||||
* in lib-jitsi-meet for the error details.
|
|
||||||
* @private
|
|
||||||
* @returns {{
|
|
||||||
* type: UPGRADE_ROLE_FINISHED,
|
|
||||||
* error: ?Object,
|
|
||||||
* progress: number
|
|
||||||
* }}
|
|
||||||
*/
|
|
||||||
function _upgradeRoleFinished(
|
|
||||||
thenableWithCancel,
|
|
||||||
progressOrError: number | Object) {
|
|
||||||
let error;
|
|
||||||
let progress;
|
|
||||||
|
|
||||||
if (typeof progressOrError === 'number') {
|
|
||||||
progress = progressOrError;
|
|
||||||
} else {
|
|
||||||
// Make the specified error object resemble an Error instance (to the
|
|
||||||
// extent that jitsi-meet needs it).
|
|
||||||
const {
|
|
||||||
authenticationError,
|
|
||||||
connectionError,
|
|
||||||
...other
|
|
||||||
} = progressOrError;
|
|
||||||
|
|
||||||
error = {
|
|
||||||
name: authenticationError || connectionError,
|
|
||||||
...other
|
|
||||||
};
|
|
||||||
progress = authenticationError ? 0.5 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: UPGRADE_ROLE_FINISHED,
|
|
||||||
error,
|
|
||||||
progress,
|
|
||||||
thenableWithCancel
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Signals that a process of authenticating and upgrading the local
|
|
||||||
* participant's role has started.
|
|
||||||
*
|
|
||||||
* @param {Object} thenableWithCancel - The process of authenticating and
|
|
||||||
* upgrading the local participant's role.
|
|
||||||
* @private
|
|
||||||
* @returns {{
|
|
||||||
* type: UPGRADE_ROLE_STARTED,
|
|
||||||
* thenableWithCancel: Object
|
|
||||||
* }}
|
|
||||||
*/
|
|
||||||
function _upgradeRoleStarted(thenableWithCancel) {
|
|
||||||
return {
|
|
||||||
type: UPGRADE_ROLE_STARTED,
|
|
||||||
thenableWithCancel
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when Jicofo rejects to create the room for anonymous user. Will
|
|
||||||
* start the process of "waiting for the owner" by periodically trying to join
|
|
||||||
* the room every five seconds.
|
|
||||||
*
|
|
||||||
* @returns {Function}
|
|
||||||
*/
|
|
||||||
export function waitForOwner() {
|
|
||||||
return (dispatch: Dispatch<any>) =>
|
|
||||||
dispatch({
|
|
||||||
type: WAIT_FOR_OWNER,
|
|
||||||
handler: () => dispatch(checkIfCanJoin()),
|
|
||||||
timeoutMs: 5000
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ import {
|
||||||
} from './actionTypes';
|
} from './actionTypes';
|
||||||
import { WaitForOwnerDialog, LoginDialog } from './components';
|
import { WaitForOwnerDialog, LoginDialog } from './components';
|
||||||
|
|
||||||
|
export * from './actions.any';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels {@ink LoginDialog}.
|
* Cancels {@ink LoginDialog}.
|
||||||
*
|
*
|
||||||
|
@ -43,25 +45,21 @@ export function hideLoginDialog() {
|
||||||
return hideDialog(LoginDialog);
|
return hideDialog(LoginDialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows a authentication dialog where the local participant
|
|
||||||
* should authenticate.
|
|
||||||
*
|
|
||||||
* @returns {Function}.
|
|
||||||
*/
|
|
||||||
export function openLoginDialog() {
|
|
||||||
return openDialog(LoginDialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows a notification dialog that authentication is required to create the.
|
* Shows a notification dialog that authentication is required to create the.
|
||||||
* Conference, so the local participant should authenticate or wait for a
|
* Conference.
|
||||||
* host.
|
* This is used for external auth.
|
||||||
|
*
|
||||||
|
* @param {string} room - The room name.
|
||||||
|
* @param {Function} onAuthNow - The function to be invoked when external authentication.
|
||||||
*
|
*
|
||||||
* @returns {Function}.
|
* @returns {Function}.
|
||||||
*/
|
*/
|
||||||
export function openWaitForOwnerDialog() {
|
export function openAuthDialog(room: String, onAuthNow: ?Function) {
|
||||||
return openDialog(WaitForOwnerDialog);
|
return openDialog(WaitForOwnerDialog, {
|
||||||
|
room,
|
||||||
|
onAuthNow
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import type { Dispatch } from 'redux';
|
||||||
import { ConfirmDialog } from '../../../base/dialog';
|
import { ConfirmDialog } from '../../../base/dialog';
|
||||||
import { translate } from '../../../base/i18n';
|
import { translate } from '../../../base/i18n';
|
||||||
import { connect } from '../../../base/redux';
|
import { connect } from '../../../base/redux';
|
||||||
import { cancelWaitForOwner, _openLoginDialog } from '../../actions.native';
|
import { openLoginDialog, cancelWaitForOwner } from '../../actions.native';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the React {@code Component} props of {@link WaitForOwnerDialog}.
|
* The type of the React {@code Component} props of {@link WaitForOwnerDialog}.
|
||||||
|
@ -97,7 +97,7 @@ class WaitForOwnerDialog extends Component<Props> {
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onLogin() {
|
_onLogin() {
|
||||||
this.props.dispatch(_openLoginDialog());
|
this.props.dispatch(openLoginDialog());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,7 @@ import { Dialog } from '../../../base/dialog';
|
||||||
import { translate, translateToHTML } from '../../../base/i18n';
|
import { translate, translateToHTML } from '../../../base/i18n';
|
||||||
import { JitsiConnectionErrors } from '../../../base/lib-jitsi-meet';
|
import { JitsiConnectionErrors } from '../../../base/lib-jitsi-meet';
|
||||||
import { connect as reduxConnect } from '../../../base/redux';
|
import { connect as reduxConnect } from '../../../base/redux';
|
||||||
import { authenticateAndUpgradeRole } from '../../actions.native';
|
import { authenticateAndUpgradeRole, cancelLogin } from '../../actions.web';
|
||||||
import { cancelLogin } from '../../actions.web';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the React {@code Component} props of {@link LoginDialog}.
|
* The type of the React {@code Component} props of {@link LoginDialog}.
|
||||||
|
@ -197,7 +196,7 @@ class LoginDialog extends Component<Props, State> {
|
||||||
const messageOptions = {};
|
const messageOptions = {};
|
||||||
let messageKey;
|
let messageKey;
|
||||||
|
|
||||||
if (progress && progress >= 0.5) {
|
if (progress && progress < 1) {
|
||||||
messageKey = t('connection.FETCH_SESSION_ID');
|
messageKey = t('connection.FETCH_SESSION_ID');
|
||||||
} else if (error) {
|
} else if (error) {
|
||||||
const { name } = error;
|
const { name } = error;
|
||||||
|
@ -271,6 +270,7 @@ class LoginDialog extends Component<Props, State> {
|
||||||
label = { t('dialog.userPassword') }
|
label = { t('dialog.userPassword') }
|
||||||
name = 'password'
|
name = 'password'
|
||||||
onChange = { this._onChange }
|
onChange = { this._onChange }
|
||||||
|
placeholder = { t('dialog.password') }
|
||||||
shouldFitContainer = { true }
|
shouldFitContainer = { true }
|
||||||
type = 'password'
|
type = 'password'
|
||||||
value = { password } />
|
value = { password } />
|
||||||
|
|
|
@ -6,7 +6,7 @@ import type { Dispatch } from 'redux';
|
||||||
import { Dialog } from '../../../base/dialog';
|
import { Dialog } from '../../../base/dialog';
|
||||||
import { translate, translateToHTML } from '../../../base/i18n';
|
import { translate, translateToHTML } from '../../../base/i18n';
|
||||||
import { connect } from '../../../base/redux';
|
import { connect } from '../../../base/redux';
|
||||||
import { openLoginDialog, cancelWaitForOwner } from '../../actions.web';
|
import { cancelWaitForOwner } from '../../actions.web';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the React {@code Component} props of {@link WaitForOwnerDialog}.
|
* The type of the React {@code Component} props of {@link WaitForOwnerDialog}.
|
||||||
|
@ -76,9 +76,9 @@ class WaitForOwnerDialog extends PureComponent<Props> {
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onIAmHost() {
|
_onIAmHost() {
|
||||||
const { dispatch } = this.props;
|
const { onAuthNow } = this.props;
|
||||||
|
|
||||||
dispatch(openLoginDialog());
|
onAuthNow && onAuthNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -88,7 +88,7 @@ class WaitForOwnerDialog extends PureComponent<Props> {
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
_room,
|
_room: room,
|
||||||
t
|
t
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ class WaitForOwnerDialog extends PureComponent<Props> {
|
||||||
<span>
|
<span>
|
||||||
{
|
{
|
||||||
translateToHTML(
|
translateToHTML(
|
||||||
t, 'dialog.WaitForHostMsg', { room: _room })
|
t, 'dialog.WaitForHostMsg', { room })
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
|
@ -22,11 +22,10 @@ import {
|
||||||
WAIT_FOR_OWNER
|
WAIT_FOR_OWNER
|
||||||
} from './actionTypes';
|
} from './actionTypes';
|
||||||
import {
|
import {
|
||||||
_openLoginDialog,
|
openLoginDialog,
|
||||||
_openWaitForOwnerDialog,
|
openWaitForOwnerDialog,
|
||||||
stopWaitForOwner,
|
stopWaitForOwner,
|
||||||
waitForOwner
|
waitForOwner } from './actions.native';
|
||||||
} from './actions.native';
|
|
||||||
import { LoginDialog, WaitForOwnerDialog } from './components';
|
import { LoginDialog, WaitForOwnerDialog } from './components';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,7 +53,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
// Instead of hiding show the new one.
|
// Instead of hiding show the new one.
|
||||||
const result = next(action);
|
const result = next(action);
|
||||||
|
|
||||||
dispatch(_openWaitForOwnerDialog());
|
dispatch(openWaitForOwnerDialog());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -114,7 +113,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
&& error.name === JitsiConnectionErrors.PASSWORD_REQUIRED
|
&& error.name === JitsiConnectionErrors.PASSWORD_REQUIRED
|
||||||
&& typeof error.recoverable === 'undefined') {
|
&& typeof error.recoverable === 'undefined') {
|
||||||
error.recoverable = true;
|
error.recoverable = true;
|
||||||
store.dispatch(_openLoginDialog());
|
store.dispatch(openLoginDialog());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -134,7 +133,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
// The WAIT_FOR_OWNER action is cyclic and we don't want to hide the
|
// The WAIT_FOR_OWNER action is cyclic and we don't want to hide the
|
||||||
// login dialog every few seconds.
|
// login dialog every few seconds.
|
||||||
isDialogOpen(store, LoginDialog)
|
isDialogOpen(store, LoginDialog)
|
||||||
|| store.dispatch(_openWaitForOwnerDialog());
|
|| store.dispatch(openWaitForOwnerDialog());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,12 +19,10 @@ import {
|
||||||
WAIT_FOR_OWNER
|
WAIT_FOR_OWNER
|
||||||
} from './actionTypes';
|
} from './actionTypes';
|
||||||
import {
|
import {
|
||||||
|
hideLoginDialog,
|
||||||
|
openWaitForOwnerDialog,
|
||||||
stopWaitForOwner,
|
stopWaitForOwner,
|
||||||
waitForOwner
|
waitForOwner
|
||||||
} from './actions.native';
|
|
||||||
import {
|
|
||||||
hideLoginDialog,
|
|
||||||
openWaitForOwnerDialog
|
|
||||||
} from './actions.web';
|
} from './actions.web';
|
||||||
import { LoginDialog, WaitForOwnerDialog } from './components';
|
import { LoginDialog, WaitForOwnerDialog } from './components';
|
||||||
|
|
||||||
|
@ -42,7 +40,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
|
|
||||||
case CANCEL_LOGIN: {
|
case CANCEL_LOGIN: {
|
||||||
if (!isDialogOpen(store, WaitForOwnerDialog)) {
|
if (!isDialogOpen(store, WaitForOwnerDialog)) {
|
||||||
if (isWaitingForOwner(store)) {
|
if (_isWaitingForOwner(store)) {
|
||||||
store.dispatch(openWaitForOwnerDialog());
|
store.dispatch(openWaitForOwnerDialog());
|
||||||
|
|
||||||
return next(action);
|
return next(action);
|
||||||
|
@ -74,10 +72,10 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
}
|
}
|
||||||
|
|
||||||
case CONFERENCE_JOINED:
|
case CONFERENCE_JOINED:
|
||||||
if (isWaitingForOwner(store)) {
|
if (_isWaitingForOwner(store)) {
|
||||||
store.dispatch(stopWaitForOwner());
|
store.dispatch(stopWaitForOwner());
|
||||||
}
|
}
|
||||||
store.dispatch(hideLoginDialog);
|
store.dispatch(hideLoginDialog());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONFERENCE_LEFT:
|
case CONFERENCE_LEFT:
|
||||||
|
@ -85,16 +83,16 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONNECTION_ESTABLISHED:
|
case CONNECTION_ESTABLISHED:
|
||||||
store.dispatch(hideLoginDialog);
|
store.dispatch(hideLoginDialog());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STOP_WAIT_FOR_OWNER:
|
case STOP_WAIT_FOR_OWNER:
|
||||||
clearExistingWaitForOwnerTimeout(store);
|
_clearExistingWaitForOwnerTimeout(store);
|
||||||
store.dispatch(hideDialog(WaitForOwnerDialog));
|
store.dispatch(hideDialog(WaitForOwnerDialog));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WAIT_FOR_OWNER: {
|
case WAIT_FOR_OWNER: {
|
||||||
clearExistingWaitForOwnerTimeout(store);
|
_clearExistingWaitForOwnerTimeout(store);
|
||||||
|
|
||||||
const { handler, timeoutMs } = action;
|
const { handler, timeoutMs } = action;
|
||||||
|
|
||||||
|
@ -116,7 +114,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
* @param {Object} store - The redux store.
|
* @param {Object} store - The redux store.
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function clearExistingWaitForOwnerTimeout(
|
function _clearExistingWaitForOwnerTimeout(
|
||||||
{ getState }: { getState: Function }) {
|
{ getState }: { getState: Function }) {
|
||||||
const { waitForOwnerTimeoutID } = getState()['features/authentication'];
|
const { waitForOwnerTimeoutID } = getState()['features/authentication'];
|
||||||
|
|
||||||
|
@ -129,6 +127,6 @@ function clearExistingWaitForOwnerTimeout(
|
||||||
* @param {Object} store - The redux store.
|
* @param {Object} store - The redux store.
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function isWaitingForOwner({ getState }: { getState: Function }) {
|
function _isWaitingForOwner({ getState }: { getState: Function }) {
|
||||||
return getState()['features/authentication'].waitForOwnerTimeoutID;
|
return getState()['features/authentication'].waitForOwnerTimeoutID;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue