Merge pull request #1055 from BeatC/incorrect-password-hint
Incorrect password hint
This commit is contained in:
commit
1f75683581
|
@ -126,4 +126,5 @@ $selectActiveItemBg: $defaultDarkColor;
|
||||||
$inputControlEmColor: #f29424;
|
$inputControlEmColor: #f29424;
|
||||||
//buttons
|
//buttons
|
||||||
$linkFontColor: #489afe;
|
$linkFontColor: #489afe;
|
||||||
$linkHoverFontColor: #287ade;
|
$linkHoverFontColor: #287ade;
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&__input {
|
&__input {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
@include transition(all .2s ease-in);
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
margin-bottom: inherit;
|
margin-bottom: inherit;
|
||||||
|
@ -28,6 +30,11 @@
|
||||||
&::selection {
|
&::selection {
|
||||||
background-color: $defaultDarkSelectionColor;
|
background-color: $defaultDarkSelectionColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
color: $errorColor;
|
||||||
|
border-color: $errorColor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__em {
|
&__em {
|
||||||
|
@ -41,6 +48,10 @@
|
||||||
span {
|
span {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&_error {
|
||||||
|
color: $errorColor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__container {
|
&__container {
|
||||||
|
|
|
@ -55,6 +55,7 @@ $hintFontSize: em(13, 14);
|
||||||
$linkFontColor: #3572b0;
|
$linkFontColor: #3572b0;
|
||||||
$linkHoverFontColor: darken(#3572b0, 10%);
|
$linkHoverFontColor: darken(#3572b0, 10%);
|
||||||
$dropdownColor: #333;
|
$dropdownColor: #333;
|
||||||
|
$errorColor: #c61600;
|
||||||
|
|
||||||
// Popover colors
|
// Popover colors
|
||||||
$popoverBg: #000;
|
$popoverBg: #000;
|
||||||
|
|
|
@ -199,6 +199,7 @@
|
||||||
"passwordError2": "This conversation isn't currently protected by a password. Only the owner of the conference can set a password.",
|
"passwordError2": "This conversation isn't currently protected by a password. Only the owner of the conference can set a password.",
|
||||||
"connectError": "Oops! Something went wrong and we couldn't connect to the conference.",
|
"connectError": "Oops! Something went wrong and we couldn't connect to the conference.",
|
||||||
"connectErrorWithMsg": "Oops! Something went wrong and we couldn't connect to the conference: __msg__",
|
"connectErrorWithMsg": "Oops! Something went wrong and we couldn't connect to the conference: __msg__",
|
||||||
|
"incorrectPassword": "Password is incorrect",
|
||||||
"connecting": "Connecting",
|
"connecting": "Connecting",
|
||||||
"copy": "Copy",
|
"copy": "Copy",
|
||||||
"error": "Error",
|
"error": "Error",
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
/* global APP, $ */
|
|
||||||
|
|
||||||
import UIUtil from '../util/UIUtil';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show dialog which asks for required conference password.
|
|
||||||
* @returns {Promise<string>} password or nothing if user canceled
|
|
||||||
*/
|
|
||||||
export default function askForPassword () {
|
|
||||||
let titleKey = "dialog.passwordRequired";
|
|
||||||
let msgString = `
|
|
||||||
<input name="lockKey" type="text"
|
|
||||||
data-i18n="[placeholder]dialog.password"
|
|
||||||
autofocus>`;
|
|
||||||
return new Promise(function (resolve, reject) {
|
|
||||||
APP.UI.messageHandler.openTwoButtonDialog({
|
|
||||||
titleKey,
|
|
||||||
msgString,
|
|
||||||
leftButtonKey: "dialog.Ok",
|
|
||||||
submitFunction: $.noop,
|
|
||||||
closeFunction: function (e, v, m, f) {
|
|
||||||
if (v && f.lockKey) {
|
|
||||||
resolve(UIUtil.escapeHtml(f.lockKey));
|
|
||||||
} else {
|
|
||||||
reject(APP.UI.messageHandler.CANCEL);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
focus: ':input:first'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -32,7 +32,7 @@ class Invite {
|
||||||
error);
|
error);
|
||||||
|
|
||||||
if (!locked) {
|
if (!locked) {
|
||||||
this.roomLocker.resetPassword();
|
this.getRoomLocker().resetPassword();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setLockedFromElsewhere(locked);
|
this.setLockedFromElsewhere(locked);
|
||||||
|
@ -46,14 +46,20 @@ class Invite {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.conference.on(ConferenceEvents.CONFERENCE_JOINED, () => {
|
||||||
|
let roomLocker = this.getRoomLocker();
|
||||||
|
roomLocker.hideRequirePasswordDialog();
|
||||||
|
});
|
||||||
|
|
||||||
APP.UI.addListener( UIEvents.INVITE_CLICKED,
|
APP.UI.addListener( UIEvents.INVITE_CLICKED,
|
||||||
() => { this.openLinkDialog(); });
|
() => { this.openLinkDialog(); });
|
||||||
|
|
||||||
APP.UI.addListener( UIEvents.PASSWORD_REQUIRED,
|
APP.UI.addListener( UIEvents.PASSWORD_REQUIRED,
|
||||||
() => {
|
() => {
|
||||||
|
let roomLocker = this.getRoomLocker();
|
||||||
this.setLockedFromElsewhere(true);
|
this.setLockedFromElsewhere(true);
|
||||||
this.roomLocker.requirePassword().then(() => {
|
roomLocker.requirePassword().then(() => {
|
||||||
let pass = this.roomLocker.password;
|
let pass = roomLocker.password;
|
||||||
// we received that password is required, but user is trying
|
// we received that password is required, but user is trying
|
||||||
// anyway to login without a password, mark room as not
|
// anyway to login without a password, mark room as not
|
||||||
// locked in case he succeeds (maybe someone removed the
|
// locked in case he succeeds (maybe someone removed the
|
||||||
|
@ -62,7 +68,7 @@ class Invite {
|
||||||
// will be marked as locked.
|
// will be marked as locked.
|
||||||
if (!pass)
|
if (!pass)
|
||||||
this.setLockedFromElsewhere(false);
|
this.setLockedFromElsewhere(false);
|
||||||
this.conference.join(this.roomLocker.password);
|
this.conference.join(pass);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -124,7 +130,7 @@ class Invite {
|
||||||
* @returns {String} password
|
* @returns {String} password
|
||||||
*/
|
*/
|
||||||
getPassword() {
|
getPassword() {
|
||||||
return this.roomLocker.password;
|
return this.getRoomLocker().password;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,7 +150,7 @@ class Invite {
|
||||||
*/
|
*/
|
||||||
setRoomUnlocked() {
|
setRoomUnlocked() {
|
||||||
if (this.isModerator) {
|
if (this.isModerator) {
|
||||||
this.roomLocker.lock().then(() => {
|
this.getRoomLocker().lock().then(() => {
|
||||||
APP.UI.emitEvent(UIEvents.TOGGLE_ROOM_LOCK);
|
APP.UI.emitEvent(UIEvents.TOGGLE_ROOM_LOCK);
|
||||||
this.updateView();
|
this.updateView();
|
||||||
});
|
});
|
||||||
|
@ -159,8 +165,8 @@ class Invite {
|
||||||
*/
|
*/
|
||||||
setRoomLocked(newPass) {
|
setRoomLocked(newPass) {
|
||||||
let isModerator = this.isModerator;
|
let isModerator = this.isModerator;
|
||||||
if (isModerator && (newPass || !this.roomLocker.isLocked)) {
|
if (isModerator && (newPass || !this.getRoomLocker().isLocked)) {
|
||||||
this.roomLocker.lock(newPass).then(() => {
|
this.getRoomLocker().lock(newPass).then(() => {
|
||||||
APP.UI.emitEvent(UIEvents.TOGGLE_ROOM_LOCK);
|
APP.UI.emitEvent(UIEvents.TOGGLE_ROOM_LOCK);
|
||||||
this.updateView();
|
this.updateView();
|
||||||
});
|
});
|
||||||
|
@ -182,7 +188,7 @@ class Invite {
|
||||||
* @returns {Boolean} isLocked
|
* @returns {Boolean} isLocked
|
||||||
*/
|
*/
|
||||||
isLocked() {
|
isLocked() {
|
||||||
return this.roomLocker.isLocked;
|
return this.getRoomLocker().isLocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -190,9 +196,10 @@ class Invite {
|
||||||
* @param isLocked
|
* @param isLocked
|
||||||
*/
|
*/
|
||||||
setLockedFromElsewhere(isLocked) {
|
setLockedFromElsewhere(isLocked) {
|
||||||
let oldLockState = this.roomLocker.isLocked;
|
let roomLocker = this.getRoomLocker();
|
||||||
|
let oldLockState = roomLocker.isLocked;
|
||||||
if (oldLockState !== isLocked) {
|
if (oldLockState !== isLocked) {
|
||||||
this.roomLocker.lockedElsewhere = isLocked;
|
roomLocker.lockedElsewhere = isLocked;
|
||||||
APP.UI.emitEvent(UIEvents.TOGGLE_ROOM_LOCK);
|
APP.UI.emitEvent(UIEvents.TOGGLE_ROOM_LOCK);
|
||||||
this.updateView();
|
this.updateView();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
/* global APP */
|
||||||
|
|
||||||
|
import UIUtil from '../util/UIUtil';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show dialog which asks for required conference password.
|
||||||
|
* @returns {Promise<string>} password or nothing if user canceled
|
||||||
|
*/
|
||||||
|
export default class RequirePasswordDialog {
|
||||||
|
constructor() {
|
||||||
|
this.titleKey = 'dialog.passwordRequired';
|
||||||
|
this.labelKey = 'dialog.passwordLabel';
|
||||||
|
this.errorKey = 'dialog.incorrectPassword';
|
||||||
|
this.errorId = 'passwordRequiredError';
|
||||||
|
this.inputId = 'passwordRequiredInput';
|
||||||
|
this.inputErrorClass = 'error';
|
||||||
|
this.isOpened = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registering dialog listeners
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_registerListeners() {
|
||||||
|
let el = document.getElementById(this.inputId);
|
||||||
|
el.addEventListener('keypress', this._hideError.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method returning dialog body
|
||||||
|
* @returns {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_getBodyMessage() {
|
||||||
|
return (
|
||||||
|
`<div class="input-control">
|
||||||
|
<label class="input-control__label"
|
||||||
|
data-i18n="${this.labelKey}"></label>
|
||||||
|
<input class="input-control__input" name="lockKey" type="text"
|
||||||
|
data-i18n="[placeholder]dialog.password"
|
||||||
|
autofocus id="${this.inputId}">
|
||||||
|
<p class="input-control__hint input-control__hint_error hide"
|
||||||
|
id="${this.errorId}"
|
||||||
|
data-i18n="${this.errorKey}"></p>
|
||||||
|
</div>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asking for a password
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
askForPassword() {
|
||||||
|
if (!this.isOpened) {
|
||||||
|
return this.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.resolve = resolve;
|
||||||
|
this.reject = reject;
|
||||||
|
this._showError();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the dialog
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
open() {
|
||||||
|
let { titleKey } = this;
|
||||||
|
let msgString = this._getBodyMessage();
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.resolve = resolve;
|
||||||
|
this.reject = reject;
|
||||||
|
let submitFunction = this._submitFunction.bind(this);
|
||||||
|
let closeFunction = this._closeFunction.bind(this);
|
||||||
|
|
||||||
|
this._dialog = APP.UI.messageHandler.openTwoButtonDialog({
|
||||||
|
titleKey,
|
||||||
|
msgString,
|
||||||
|
leftButtonKey: "dialog.Ok",
|
||||||
|
submitFunction,
|
||||||
|
closeFunction,
|
||||||
|
focus: ':input:first'
|
||||||
|
});
|
||||||
|
|
||||||
|
this._registerListeners();
|
||||||
|
this.isOpened = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submit dialog callback
|
||||||
|
* @param e - event
|
||||||
|
* @param v - value
|
||||||
|
* @param m - message
|
||||||
|
* @param f - form
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_submitFunction(e, v, m, f) {
|
||||||
|
e.preventDefault();
|
||||||
|
this._processInput(v, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processing input in dialog
|
||||||
|
* @param v - value
|
||||||
|
* @param f - form
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_processInput(v, f) {
|
||||||
|
if (v && f.lockKey) {
|
||||||
|
this.resolve(UIUtil.escapeHtml(f.lockKey));
|
||||||
|
} else {
|
||||||
|
this.reject(APP.UI.messageHandler.CANCEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close dialog callback
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_closeFunction(e, v, m, f) {
|
||||||
|
this._processInput(v, f);
|
||||||
|
this._hideError();
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method showing error hint
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_showError() {
|
||||||
|
let className = this.inputErrorClass;
|
||||||
|
let input = document.getElementById(this.inputId);
|
||||||
|
document.getElementById(this.errorId).classList.remove('hide');
|
||||||
|
input.classList.add(className);
|
||||||
|
input.select();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method hiding error hint
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_hideError() {
|
||||||
|
let className = this.inputErrorClass;
|
||||||
|
document.getElementById(this.errorId).classList.add('hide');
|
||||||
|
document.getElementById(this.inputId).classList.remove(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the dialog
|
||||||
|
*/
|
||||||
|
close() {
|
||||||
|
if (this._dialog) {
|
||||||
|
this._dialog.close();
|
||||||
|
}
|
||||||
|
this.isOpened = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/* global APP, JitsiMeetJS */
|
/* global APP, JitsiMeetJS */
|
||||||
import askForPassword from './AskForPassword';
|
import RequirePasswordDialog from './RequirePasswordDialog';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show notification that user cannot set password for the conference
|
* Show notification that user cannot set password for the conference
|
||||||
|
@ -31,7 +31,7 @@ const ConferenceErrors = JitsiMeetJS.errors.conference;
|
||||||
*/
|
*/
|
||||||
export default function createRoomLocker (room) {
|
export default function createRoomLocker (room) {
|
||||||
let password;
|
let password;
|
||||||
|
let requirePasswordDialog = new RequirePasswordDialog();
|
||||||
/**
|
/**
|
||||||
* If the room was locked from someone other than us, we indicate it with
|
* If the room was locked from someone other than us, we indicate it with
|
||||||
* this property in order to have correct roomLocker state of isLocked.
|
* this property in order to have correct roomLocker state of isLocked.
|
||||||
|
@ -104,7 +104,7 @@ export default function createRoomLocker (room) {
|
||||||
* Asks user for required conference password.
|
* Asks user for required conference password.
|
||||||
*/
|
*/
|
||||||
requirePassword () {
|
requirePassword () {
|
||||||
return askForPassword().then(
|
return requirePasswordDialog.askForPassword().then(
|
||||||
newPass => { password = newPass; }
|
newPass => { password = newPass; }
|
||||||
).catch(
|
).catch(
|
||||||
reason => {
|
reason => {
|
||||||
|
@ -116,6 +116,15 @@ export default function createRoomLocker (room) {
|
||||||
console.error(reason);
|
console.error(reason);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides require password dialog
|
||||||
|
*/
|
||||||
|
hideRequirePasswordDialog() {
|
||||||
|
if (requirePasswordDialog.isOpened) {
|
||||||
|
requirePasswordDialog.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global $, APP, toastr, Impromptu */
|
/* global $, APP, toastr */
|
||||||
|
|
||||||
import UIUtil from './UIUtil';
|
import UIUtil from './UIUtil';
|
||||||
import jitsiLocalStorage from '../../util/JitsiLocalStorage';
|
import jitsiLocalStorage from '../../util/JitsiLocalStorage';
|
||||||
|
@ -138,7 +138,7 @@ var messageHandler = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
APP.translation.translateElement(dialog, i18nOptions);
|
APP.translation.translateElement(dialog, i18nOptions);
|
||||||
return dialog;
|
return $.prompt.getApi();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Shows a message to the user with two buttons: first is given as a
|
* Shows a message to the user with two buttons: first is given as a
|
||||||
|
@ -242,7 +242,7 @@ var messageHandler = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
APP.translation.translateElement(twoButtonDialog);
|
APP.translation.translateElement(twoButtonDialog);
|
||||||
return twoButtonDialog;
|
return $.prompt.getApi();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -300,10 +300,10 @@ var messageHandler = {
|
||||||
args.closeText = '';
|
args.closeText = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
let dialog = new Impromptu(
|
let dialog = $.prompt(
|
||||||
msgString + generateDontShowCheckbox(dontShowAgain), args);
|
msgString + generateDontShowCheckbox(dontShowAgain), args);
|
||||||
APP.translation.translateElement(dialog.getPrompt());
|
APP.translation.translateElement(dialog);
|
||||||
return dialog;
|
return $.prompt.getApi();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -338,13 +338,6 @@ var messageHandler = {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes currently opened dialog.
|
|
||||||
*/
|
|
||||||
closeDialog: function () {
|
|
||||||
$.prompt.close();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows a dialog with different states to the user.
|
* Shows a dialog with different states to the user.
|
||||||
*
|
*
|
||||||
|
@ -367,9 +360,9 @@ var messageHandler = {
|
||||||
= this._getFormattedTitleString(currentState.titleKey);
|
= this._getFormattedTitleString(currentState.titleKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let dialog = new Impromptu(statesObject, options);
|
let dialog = $.prompt(statesObject, options);
|
||||||
APP.translation.translateElement(dialog.getPrompt(), translateOptions);
|
APP.translation.translateElement(dialog, translateOptions);
|
||||||
return dialog;
|
return $.prompt.getApi();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue