/* global $, APP, config */ import { toJid } from '../../../react/features/base/connection'; 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 ` `; } /** * 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: '
', titleKey: 'dialog.connecting' }, finished: { buttons: finishedButtons, defaultButton: 0, html: '', 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 { /** * 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). * @param {string} url URL to use for external auth. * @param {function} callback callback to invoke when auth popup is closed. * @returns auth dialog */ showExternalAuthDialog(url, callback) { const dialog = APP.UI.messageHandler.openCenteredPopup( url, 910, 660, // On closed callback ); if (!dialog) { APP.UI.messageHandler.showWarning({ descriptionKey: 'dialog.popupError', titleKey: 'dialog.popupErrorTitle' }); } return dialog; }, /** * Shows a notification that authentication is required to create the * conference, so the local participant should authenticate or wait for a * host. * * @param {string} room - The name of the conference. * @param {function} onAuthNow - The callback to invoke if the local * participant wants to authenticate. * @returns dialog */ showAuthRequiredDialog(room, onAuthNow) { const msg = APP.translation.generateTranslationHTML( '[html]dialog.WaitForHostMsg', { room } ); const buttonTxt = APP.translation.generateTranslationHTML( 'dialog.IamHost' ); const buttons = [ { title: buttonTxt, value: 'authNow' } ]; return APP.UI.messageHandler.openDialog( 'dialog.WaitingForHost', msg, true, buttons, (e, submitValue) => { // Do not close the dialog yet. e.preventDefault(); // Open login popup. if (submitValue === 'authNow') { onAuthNow(); } } ); } };