mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
reCaptcha at admin login
https://github.com/the-djmaze/snappymail/issues/222#issuecomment-1036211212
This commit is contained in:
parent
fecc9f96eb
commit
2fea7b92e1
4 changed files with 25 additions and 23 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { fireEvent } from 'Common/Globals';
|
||||||
import { getNotification } from 'Common/Translator';
|
import { getNotification } from 'Common/Translator';
|
||||||
|
|
||||||
import Remote from 'Remote/Admin/Fetch';
|
import Remote from 'Remote/Admin/Fetch';
|
||||||
|
|
@ -5,7 +6,7 @@ import Remote from 'Remote/Admin/Fetch';
|
||||||
import { decorateKoCommands } from 'Knoin/Knoin';
|
import { decorateKoCommands } from 'Knoin/Knoin';
|
||||||
import { AbstractViewLogin } from 'Knoin/AbstractViews';
|
import { AbstractViewLogin } from 'Knoin/AbstractViews';
|
||||||
|
|
||||||
class LoginAdminView extends AbstractViewLogin {
|
export class LoginAdminView extends AbstractViewLogin {
|
||||||
constructor() {
|
constructor() {
|
||||||
super('AdminLogin');
|
super('AdminLogin');
|
||||||
|
|
||||||
|
|
@ -32,12 +33,12 @@ class LoginAdminView extends AbstractViewLogin {
|
||||||
}
|
}
|
||||||
|
|
||||||
submitCommand(self, event) {
|
submitCommand(self, event) {
|
||||||
const valid = event.target.form.reportValidity(),
|
let form = event.target.form,
|
||||||
name = this.login().trim(),
|
data = new FormData(form),
|
||||||
pass = this.password();
|
valid = form.reportValidity() && fireEvent('sm-admin-login', data);
|
||||||
|
|
||||||
this.loginError(!name);
|
this.loginError(!this.login());
|
||||||
this.passwordError(!pass);
|
this.passwordError(!this.password());
|
||||||
this.formError(!valid);
|
this.formError(!valid);
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
|
@ -45,21 +46,21 @@ class LoginAdminView extends AbstractViewLogin {
|
||||||
|
|
||||||
Remote.request('AdminLogin',
|
Remote.request('AdminLogin',
|
||||||
(iError, oData) => {
|
(iError, oData) => {
|
||||||
|
fireEvent('sm-admin-login-response', {
|
||||||
|
error: iError,
|
||||||
|
data: oData
|
||||||
|
});
|
||||||
if (iError) {
|
if (iError) {
|
||||||
this.submitRequest(false);
|
this.submitRequest(false);
|
||||||
this.submitError(getNotification(iError));
|
this.submitError(getNotification(iError));
|
||||||
} else {
|
} else {
|
||||||
rl.setData(oData.Result);
|
rl.setData(oData.Result);
|
||||||
}
|
}
|
||||||
}, {
|
},
|
||||||
Login: name,
|
data
|
||||||
Password: pass,
|
);
|
||||||
TOTP: this.totp()
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { LoginAdminView };
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ const SignMeOff = 0,
|
||||||
SignMeUnused = 2;
|
SignMeUnused = 2;
|
||||||
|
|
||||||
|
|
||||||
class LoginUserView extends AbstractViewLogin {
|
export class LoginUserView extends AbstractViewLogin {
|
||||||
constructor() {
|
constructor() {
|
||||||
super('Login');
|
super('Login');
|
||||||
|
|
||||||
|
|
@ -161,5 +161,3 @@ class LoginUserView extends AbstractViewLogin {
|
||||||
showScreenPopup(LanguagesPopupView, [this.language, this.languages(), LanguageStore.userLanguage()]);
|
showScreenPopup(LanguagesPopupView, [this.language, this.languages(), LanguageStore.userLanguage()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { LoginUserView };
|
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,16 @@
|
||||||
(rl => {
|
(rl => {
|
||||||
|
|
||||||
rl && addEventListener('rl-view-model', e => {
|
rl && addEventListener('rl-view-model', e => {
|
||||||
if (e.detail && 'Login' === e.detail.viewModelTemplateID
|
const id = e.detail.viewModelTemplateID;
|
||||||
|
if (e.detail && ('AdminLogin' === id || 'Login' === id)
|
||||||
&& rl.pluginSettingsGet('recaptcha', 'show_captcha_on_login')) {
|
&& rl.pluginSettingsGet('recaptcha', 'show_captcha_on_login')) {
|
||||||
let
|
let
|
||||||
nId = null,
|
nId = null,
|
||||||
script;
|
script;
|
||||||
|
|
||||||
const
|
const
|
||||||
|
mode = 'Login' === id ? 'user' : 'admin',
|
||||||
|
|
||||||
doc = document,
|
doc = document,
|
||||||
|
|
||||||
container = e.detail.viewModelDom.querySelector('#plugin-Login-BottomControlGroup'),
|
container = e.detail.viewModelDom.querySelector('#plugin-Login-BottomControlGroup'),
|
||||||
|
|
@ -42,15 +45,15 @@
|
||||||
|
|
||||||
StartRecaptcha();
|
StartRecaptcha();
|
||||||
|
|
||||||
addEventListener('sm-user-login', e => {
|
addEventListener(`sm-${mode}-login`, e => {
|
||||||
if (null !== nId && window.grecaptcha) {
|
if (null !== nId && window.grecaptcha) {
|
||||||
e.detail.set('RecaptchaResponse', window.grecaptcha.getResponse(nId));
|
e.detail.set('RecaptchaResponse', window.grecaptcha.getResponse(nId));
|
||||||
} else {
|
} else {
|
||||||
e.preventDefault()
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
addEventListener('sm-user-login-response', e => {
|
addEventListener(`sm-${mode}-login-response`, e => {
|
||||||
if (e.detail.error) {
|
if (e.detail.error) {
|
||||||
if (null !== nId && window.grecaptcha) {
|
if (null !== nId && window.grecaptcha) {
|
||||||
window.grecaptcha.reset(nId);
|
window.grecaptcha.reset(nId);
|
||||||
|
|
|
||||||
|
|
@ -5,21 +5,21 @@
|
||||||
<form action="#/" data-bind="submit: submitForm, css: {'errorAnimated': formError, 'submitting': submitRequest()}">
|
<form action="#/" data-bind="submit: submitForm, css: {'errorAnimated': formError, 'submitting': submitRequest()}">
|
||||||
<div class="controls" data-bind="css: {'error': loginError}">
|
<div class="controls" data-bind="css: {'error': loginError}">
|
||||||
<span class="fontastic">👤</span>
|
<span class="fontastic">👤</span>
|
||||||
<input required="" type="text" class="input-block-level"
|
<input name="Login" required="" type="text" class="input-block-level"
|
||||||
autofocus="" autocomplete="username" autocorrect="off" autocapitalize="off" spellcheck="false"
|
autofocus="" autocomplete="username" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||||
data-bind="textInput: login, disable: submitRequest"
|
data-bind="textInput: login, disable: submitRequest"
|
||||||
data-i18n="[placeholder]LOGIN/LABEL_LOGIN" />
|
data-i18n="[placeholder]LOGIN/LABEL_LOGIN" />
|
||||||
</div>
|
</div>
|
||||||
<div class="controls" data-bind="css: {'error': passwordError}">
|
<div class="controls" data-bind="css: {'error': passwordError}">
|
||||||
<span class="fontastic">🔑</span>
|
<span class="fontastic">🔑</span>
|
||||||
<input required="" type="password" class="input-block-level"
|
<input name="Password" required="" type="password" class="input-block-level"
|
||||||
autocomplete="current-password" autocorrect="off" autocapitalize="off" spellcheck="false"
|
autocomplete="current-password" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||||
data-bind="textInput: password, disable: submitRequest"
|
data-bind="textInput: password, disable: submitRequest"
|
||||||
data-i18n="[placeholder]LOGIN/LABEL_PASSWORD" />
|
data-i18n="[placeholder]LOGIN/LABEL_PASSWORD" />
|
||||||
</div>
|
</div>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<span class="fontastic">⏱</span>
|
<span class="fontastic">⏱</span>
|
||||||
<input type="text" pattern="[0-9]*" inputmode="numeric" class="input-block-level"
|
<input name="TOTP" type="text" pattern="[0-9]*" inputmode="numeric" class="input-block-level"
|
||||||
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||||
data-bind="textInput: totp, disable: submitRequest"
|
data-bind="textInput: totp, disable: submitRequest"
|
||||||
data-i18n="[placeholder]LOGIN/LABEL_TOTP" />
|
data-i18n="[placeholder]LOGIN/LABEL_TOTP" />
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue