mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-29 20:19:22 +03:00
Drop 2FA, read #84
This commit is contained in:
parent
ca59c21602
commit
48fa1a1fdc
44 changed files with 119 additions and 1461 deletions
241
dev/App/User.js
241
dev/App/User.js
|
|
@ -79,7 +79,6 @@ import { AbstractApp } from 'App/Abstract';
|
|||
import { ComposePopupView } from 'View/Popup/Compose';
|
||||
import { FolderSystemPopupView } from 'View/Popup/FolderSystem';
|
||||
import { AskPopupView } from 'View/Popup/Ask';
|
||||
import { TwoFactorConfigurationPopupView } from 'View/Popup/TwoFactorConfiguration';
|
||||
|
||||
// Every 5 minutes
|
||||
const refreshFolders = 300000;
|
||||
|
|
@ -912,136 +911,124 @@ class AppUser extends AbstractApp {
|
|||
|
||||
rl.setWindowTitle();
|
||||
if (SettingsGet('Auth')) {
|
||||
if (
|
||||
Settings.capa(Capa.TwoFactor) &&
|
||||
Settings.capa(Capa.TwoFactorForce) &&
|
||||
SettingsGet('RequireTwoFactor')
|
||||
) {
|
||||
this.bootend();
|
||||
showScreenPopup(TwoFactorConfigurationPopupView, [true]);
|
||||
} else {
|
||||
rl.setWindowTitle(i18n('GLOBAL/LOADING'));
|
||||
rl.setWindowTitle(i18n('GLOBAL/LOADING'));
|
||||
|
||||
// require.ensure([], function() { // require code splitting
|
||||
this.foldersReload(value => {
|
||||
try {
|
||||
this.bootend();
|
||||
|
||||
this.foldersReload(value => {
|
||||
try {
|
||||
this.bootend();
|
||||
|
||||
if (value) {
|
||||
if (startupUrl) {
|
||||
rl.route.setHash(root(startupUrl), true);
|
||||
}
|
||||
|
||||
if (window.crypto && crypto.getRandomValues && Settings.capa(Capa.OpenPGP)) {
|
||||
const openpgpCallback = () => {
|
||||
if (!window.openpgp) {
|
||||
return false;
|
||||
}
|
||||
PgpUserStore.openpgp = openpgp;
|
||||
|
||||
if (window.Worker) {
|
||||
try {
|
||||
PgpUserStore.openpgp.initWorker({ path: openPgpWorkerJs() });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
PgpUserStore.openpgpKeyring = new openpgp.Keyring();
|
||||
PgpUserStore.capaOpenPGP(true);
|
||||
|
||||
this.reloadOpenPgpKeys();
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
if (!openpgpCallback()) {
|
||||
const script = createElement('script', {src:openPgpJs()});
|
||||
script.onload = openpgpCallback;
|
||||
script.onerror = () => console.error(script.src);
|
||||
doc.head.append(script);
|
||||
}
|
||||
} else {
|
||||
PgpUserStore.capaOpenPGP(false);
|
||||
}
|
||||
|
||||
startScreens([
|
||||
MailBoxUserScreen,
|
||||
Settings.capa(Capa.Settings) ? SettingsUserScreen : null
|
||||
// false ? AboutUserScreen : null
|
||||
]);
|
||||
|
||||
setInterval(() => {
|
||||
const cF = FolderUserStore.currentFolderFullNameRaw(),
|
||||
iF = getFolderInboxName();
|
||||
this.folderInformation(iF);
|
||||
if (iF !== cF) {
|
||||
this.folderInformation(cF);
|
||||
}
|
||||
this.folderInformationMultiply();
|
||||
}, refreshFolders);
|
||||
|
||||
// Every 15 minutes
|
||||
setInterval(this.quota, 900000);
|
||||
// Every 20 minutes
|
||||
setInterval(this.foldersReload, 1200000);
|
||||
|
||||
setTimeout(this.contactsSync, 10000);
|
||||
contactsSyncInterval = 5 <= contactsSyncInterval ? contactsSyncInterval : 20;
|
||||
contactsSyncInterval = 320 >= contactsSyncInterval ? contactsSyncInterval : 320;
|
||||
setInterval(this.contactsSync, contactsSyncInterval * 60000 + 5000);
|
||||
|
||||
this.accountsAndIdentities(true);
|
||||
|
||||
setTimeout(() => {
|
||||
const cF = FolderUserStore.currentFolderFullNameRaw();
|
||||
if (getFolderInboxName() !== cF) {
|
||||
this.folderInformation(cF);
|
||||
}
|
||||
this.folderInformationMultiply(true);
|
||||
}, 1000);
|
||||
|
||||
setTimeout(this.quota, 5000);
|
||||
setTimeout(() => Remote.appDelayStart(()=>{}), 35000);
|
||||
|
||||
// When auto-login is active
|
||||
if (
|
||||
!!SettingsGet('AccountSignMe') &&
|
||||
navigator.registerProtocolHandler &&
|
||||
Settings.capa(Capa.Composer)
|
||||
) {
|
||||
setTimeout(() => {
|
||||
try {
|
||||
navigator.registerProtocolHandler(
|
||||
'mailto',
|
||||
location.protocol + '//' + location.host + location.pathname + '?mailto&to=%s',
|
||||
(SettingsGet('Title') || 'SnappyMail')
|
||||
);
|
||||
} catch (e) {} // eslint-disable-line no-empty
|
||||
|
||||
if (SettingsGet('MailToEmail')) {
|
||||
mailToHelper(SettingsGet('MailToEmail'));
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
['touchstart','mousedown','mousemove','keydown'].forEach(
|
||||
t => doc.addEventListener(t, SettingsUserStore.delayLogout, {passive:true})
|
||||
);
|
||||
SettingsUserStore.delayLogout();
|
||||
|
||||
setTimeout(() => this.initVerticalLayoutResizer(), 1);
|
||||
} else {
|
||||
this.logout();
|
||||
if (value) {
|
||||
if (startupUrl) {
|
||||
rl.route.setHash(root(startupUrl), true);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
|
||||
// }); // require code splitting
|
||||
}
|
||||
if (window.crypto && crypto.getRandomValues && Settings.capa(Capa.OpenPGP)) {
|
||||
const openpgpCallback = () => {
|
||||
if (!window.openpgp) {
|
||||
return false;
|
||||
}
|
||||
PgpUserStore.openpgp = openpgp;
|
||||
|
||||
if (window.Worker) {
|
||||
try {
|
||||
PgpUserStore.openpgp.initWorker({ path: openPgpWorkerJs() });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
PgpUserStore.openpgpKeyring = new openpgp.Keyring();
|
||||
PgpUserStore.capaOpenPGP(true);
|
||||
|
||||
this.reloadOpenPgpKeys();
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
if (!openpgpCallback()) {
|
||||
const script = createElement('script', {src:openPgpJs()});
|
||||
script.onload = openpgpCallback;
|
||||
script.onerror = () => console.error(script.src);
|
||||
doc.head.append(script);
|
||||
}
|
||||
} else {
|
||||
PgpUserStore.capaOpenPGP(false);
|
||||
}
|
||||
|
||||
startScreens([
|
||||
MailBoxUserScreen,
|
||||
Settings.capa(Capa.Settings) ? SettingsUserScreen : null
|
||||
// false ? AboutUserScreen : null
|
||||
]);
|
||||
|
||||
setInterval(() => {
|
||||
const cF = FolderUserStore.currentFolderFullNameRaw(),
|
||||
iF = getFolderInboxName();
|
||||
this.folderInformation(iF);
|
||||
if (iF !== cF) {
|
||||
this.folderInformation(cF);
|
||||
}
|
||||
this.folderInformationMultiply();
|
||||
}, refreshFolders);
|
||||
|
||||
// Every 15 minutes
|
||||
setInterval(this.quota, 900000);
|
||||
// Every 20 minutes
|
||||
setInterval(this.foldersReload, 1200000);
|
||||
|
||||
setTimeout(this.contactsSync, 10000);
|
||||
contactsSyncInterval = 5 <= contactsSyncInterval ? contactsSyncInterval : 20;
|
||||
contactsSyncInterval = 320 >= contactsSyncInterval ? contactsSyncInterval : 320;
|
||||
setInterval(this.contactsSync, contactsSyncInterval * 60000 + 5000);
|
||||
|
||||
this.accountsAndIdentities(true);
|
||||
|
||||
setTimeout(() => {
|
||||
const cF = FolderUserStore.currentFolderFullNameRaw();
|
||||
if (getFolderInboxName() !== cF) {
|
||||
this.folderInformation(cF);
|
||||
}
|
||||
this.folderInformationMultiply(true);
|
||||
}, 1000);
|
||||
|
||||
setTimeout(this.quota, 5000);
|
||||
setTimeout(() => Remote.appDelayStart(()=>{}), 35000);
|
||||
|
||||
// When auto-login is active
|
||||
if (
|
||||
!!SettingsGet('AccountSignMe') &&
|
||||
navigator.registerProtocolHandler &&
|
||||
Settings.capa(Capa.Composer)
|
||||
) {
|
||||
setTimeout(() => {
|
||||
try {
|
||||
navigator.registerProtocolHandler(
|
||||
'mailto',
|
||||
location.protocol + '//' + location.host + location.pathname + '?mailto&to=%s',
|
||||
(SettingsGet('Title') || 'SnappyMail')
|
||||
);
|
||||
} catch (e) {} // eslint-disable-line no-empty
|
||||
|
||||
if (SettingsGet('MailToEmail')) {
|
||||
mailToHelper(SettingsGet('MailToEmail'));
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
['touchstart','mousedown','mousemove','keydown'].forEach(
|
||||
t => doc.addEventListener(t, SettingsUserStore.delayLogout, {passive:true})
|
||||
);
|
||||
SettingsUserStore.delayLogout();
|
||||
|
||||
setTimeout(() => this.initVerticalLayoutResizer(), 1);
|
||||
} else {
|
||||
this.logout();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
this.bootend();
|
||||
startScreens([LoginUserScreen]);
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@
|
|||
* @enum {string}
|
||||
*/
|
||||
export const Capa = {
|
||||
TwoFactor: 'TWO_FACTOR',
|
||||
TwoFactorForce: 'TWO_FACTOR_FORCE',
|
||||
OpenPGP: 'OPEN_PGP',
|
||||
Prefetch: 'PREFETCH',
|
||||
Composer: 'COMPOSER',
|
||||
|
|
@ -86,9 +84,6 @@ export const Notification = {
|
|||
DomainNotAllowed: 109,
|
||||
AccountNotAllowed: 110,
|
||||
|
||||
AccountTwoFactorAuthRequired: 120,
|
||||
AccountTwoFactorAuthError: 121,
|
||||
|
||||
ContactsSyncError: 140,
|
||||
|
||||
CantGetMessageList: 201,
|
||||
|
|
|
|||
|
|
@ -70,61 +70,6 @@ class RemoteUserFetch extends AbstractFetchRemote {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
getTwoFactor(fCallback) {
|
||||
this.defaultRequest(fCallback, 'GetTwoFactorInfo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
createTwoFactor(fCallback) {
|
||||
this.defaultRequest(fCallback, 'CreateTwoFactorSecret');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
clearTwoFactor(fCallback) {
|
||||
this.defaultRequest(fCallback, 'ClearTwoFactorInfo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
showTwoFactorSecret(fCallback) {
|
||||
this.defaultRequest(fCallback, 'ShowTwoFactorSecret');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sCode
|
||||
*/
|
||||
testTwoFactor(fCallback, sCode) {
|
||||
this.defaultRequest(fCallback, 'TestTwoFactorInfo', {
|
||||
Code: sCode
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {boolean} bEnable
|
||||
*/
|
||||
enableTwoFactor(fCallback, bEnable) {
|
||||
this.defaultRequest(fCallback, 'EnableTwoFactor', {
|
||||
Enable: bEnable ? 1 : 0
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
clearTwoFactorInfo(fCallback) {
|
||||
this.defaultRequest(fCallback, 'ClearTwoFactorInfo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ export class SettingsUserScreen extends AbstractSettingsScreen {
|
|||
settingsAddViewModel(FiltersUserSettings, 'SettingsFilters', 'SETTINGS_LABELS/LABEL_FILTERS_NAME', 'filters');
|
||||
}
|
||||
|
||||
if (Settings.capa(Capa.AutoLogout) || Settings.capa(Capa.TwoFactor)) {
|
||||
if (Settings.capa(Capa.AutoLogout)) {
|
||||
settingsAddViewModel(SecurityUserSettings, 'SettingsSecurity', 'SETTINGS_LABELS/LABEL_SECURITY_NAME', 'security');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,10 +16,6 @@ export class SecurityAdminSettings {
|
|||
verifySslCertificate: !!SettingsGet('VerifySslCertificate'),
|
||||
allowSelfSigned: !!SettingsGet('AllowSelfSigned'),
|
||||
|
||||
isTwoFactorDropperShown: false,
|
||||
twoFactorDropperUser: '',
|
||||
twoFactorDropperUserFocused: false,
|
||||
|
||||
adminLogin: SettingsGet('AdminLogin'),
|
||||
adminLoginError: false,
|
||||
adminPassword: '',
|
||||
|
|
@ -30,9 +26,7 @@ export class SecurityAdminSettings {
|
|||
adminPasswordUpdateError: false,
|
||||
adminPasswordUpdateSuccess: false,
|
||||
|
||||
capaOpenPGP: Settings.capa(Capa.OpenPGP),
|
||||
capaTwoFactorAuth: Settings.capa(Capa.TwoFactor),
|
||||
capaTwoFactorAuthForce: Settings.capa(Capa.TwoFactorForce)
|
||||
capaOpenPGP: Settings.capa(Capa.OpenPGP)
|
||||
});
|
||||
|
||||
addSubscribablesTo(this, {
|
||||
|
|
@ -60,18 +54,6 @@ export class SecurityAdminSettings {
|
|||
CapaOpenPGP: value ? 1 : 0
|
||||
}),
|
||||
|
||||
capaTwoFactorAuth: value => {
|
||||
value || this.capaTwoFactorAuthForce(false);
|
||||
Remote.saveAdminConfig(null, {
|
||||
CapaTwoFactorAuth: value ? 1 : 0
|
||||
});
|
||||
},
|
||||
|
||||
capaTwoFactorAuthForce: value =>
|
||||
Remote.saveAdminConfig(null, {
|
||||
CapaTwoFactorAuthForce: value ? 1 : 0
|
||||
}),
|
||||
|
||||
useLocalProxyForExternalImages: value =>
|
||||
Remote.saveAdminConfig(null, {
|
||||
UseLocalProxyForExternalImages: value ? 1 : 0
|
||||
|
|
@ -120,15 +102,6 @@ export class SecurityAdminSettings {
|
|||
return true;
|
||||
}
|
||||
|
||||
showTwoFactorDropper() {
|
||||
this.twoFactorDropperUser('');
|
||||
this.isTwoFactorDropperShown(true);
|
||||
|
||||
setTimeout(() => {
|
||||
this.twoFactorDropperUserFocused(true);
|
||||
}, 50);
|
||||
}
|
||||
|
||||
onNewAdminPasswordResponse(iError, data) {
|
||||
if (iError) {
|
||||
this.adminPasswordUpdateError(true);
|
||||
|
|
@ -147,9 +120,5 @@ export class SecurityAdminSettings {
|
|||
this.adminPassword('');
|
||||
this.adminPasswordNew('');
|
||||
this.adminPasswordNew2('');
|
||||
|
||||
this.isTwoFactorDropperShown(false);
|
||||
this.twoFactorDropperUser('');
|
||||
this.twoFactorDropperUserFocused(false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,12 +11,9 @@ import { SettingsUserStore } from 'Stores/User/Settings';
|
|||
|
||||
import Remote from 'Remote/User/Fetch';
|
||||
|
||||
import { TwoFactorConfigurationPopupView } from 'View/Popup/TwoFactorConfiguration';
|
||||
|
||||
export class SecurityUserSettings {
|
||||
constructor() {
|
||||
this.capaAutoLogout = Settings.capa(Capa.AutoLogout);
|
||||
this.capaTwoFactor = Settings.capa(Capa.TwoFactor);
|
||||
|
||||
this.autoLogout = SettingsUserStore.autoLogout;
|
||||
this.autoLogoutTrigger = ko.observable(SaveSettingsStep.Idle);
|
||||
|
|
@ -43,8 +40,4 @@ export class SecurityUserSettings {
|
|||
));
|
||||
}
|
||||
}
|
||||
|
||||
configureTwoFactor() {
|
||||
showScreenPopup(TwoFactorConfigurationPopupView);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@
|
|||
@import "Filter.less";
|
||||
@import "Template.less";
|
||||
@import "OpenPgpKey.less";
|
||||
@import "TwoFactor.less";
|
||||
@import "Identity.less";
|
||||
@import "AdvancedSearch.less";
|
||||
@import "Attachmnets.less";
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
.b-two-factor-content {
|
||||
|
||||
width: 750px;
|
||||
|
||||
.modal-body {
|
||||
min-height: 100px;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,193 +0,0 @@
|
|||
import { Capa } from 'Common/Enums';
|
||||
import { Settings } from 'Common/Globals';
|
||||
import { pString } from 'Common/Utils';
|
||||
import { i18n, trigger as translatorTrigger } from 'Common/Translator';
|
||||
|
||||
import Remote from 'Remote/User/Fetch';
|
||||
|
||||
import { showScreenPopup } from 'Knoin/Knoin';
|
||||
import { AbstractViewPopup } from 'Knoin/AbstractViews';
|
||||
|
||||
import { TwoFactorTestPopupView } from 'View/Popup/TwoFactorTest';
|
||||
|
||||
class TwoFactorConfigurationPopupView extends AbstractViewPopup {
|
||||
constructor() {
|
||||
super('TwoFactorConfiguration');
|
||||
|
||||
this.addObservables({
|
||||
lock: false,
|
||||
|
||||
processing: false,
|
||||
clearing: false,
|
||||
secreting: false,
|
||||
|
||||
viewUser: '',
|
||||
twoFactorStatus: false,
|
||||
|
||||
twoFactorTested: false,
|
||||
|
||||
viewSecret: '',
|
||||
viewBackupCodes: '',
|
||||
viewUrlTitle: '',
|
||||
viewUrl: '',
|
||||
|
||||
viewEnable_: false
|
||||
});
|
||||
|
||||
this.capaTwoFactor = Settings.capa(Capa.TwoFactor);
|
||||
|
||||
const fn = iError => iError && this.viewEnable_(false);
|
||||
this.addComputables({
|
||||
viewEnable: {
|
||||
read: this.viewEnable_,
|
||||
write: (value) => {
|
||||
value = !!value;
|
||||
if (value && this.twoFactorTested()) {
|
||||
this.viewEnable_(value);
|
||||
Remote.enableTwoFactor(fn, value);
|
||||
} else {
|
||||
if (!value) {
|
||||
this.viewEnable_(value);
|
||||
}
|
||||
Remote.enableTwoFactor(fn, false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
viewTwoFactorEnableTooltip: () => {
|
||||
translatorTrigger();
|
||||
return this.twoFactorTested() || this.viewEnable_()
|
||||
? ''
|
||||
: i18n('POPUPS_TWO_FACTOR_CFG/TWO_FACTOR_SECRET_TEST_BEFORE_DESC');
|
||||
},
|
||||
|
||||
viewTwoFactorStatus: () => {
|
||||
translatorTrigger();
|
||||
return i18n(
|
||||
this.twoFactorStatus()
|
||||
? 'POPUPS_TWO_FACTOR_CFG/TWO_FACTOR_SECRET_CONFIGURED_DESC'
|
||||
: 'POPUPS_TWO_FACTOR_CFG/TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC'
|
||||
);
|
||||
},
|
||||
|
||||
twoFactorAllowedEnable: () => this.viewEnable() || this.twoFactorTested()
|
||||
});
|
||||
|
||||
this.onResult = this.onResult.bind(this);
|
||||
this.onShowSecretResult = this.onShowSecretResult.bind(this);
|
||||
}
|
||||
|
||||
showSecret() {
|
||||
this.secreting(true);
|
||||
Remote.showTwoFactorSecret(this.onShowSecretResult);
|
||||
}
|
||||
|
||||
hideSecret() {
|
||||
this.viewSecret('');
|
||||
this.viewBackupCodes('');
|
||||
this.viewUrlTitle('');
|
||||
this.viewUrl('');
|
||||
}
|
||||
|
||||
createTwoFactor() {
|
||||
this.processing(true);
|
||||
Remote.createTwoFactor(this.onResult);
|
||||
}
|
||||
|
||||
logout() {
|
||||
rl.app.logout();
|
||||
}
|
||||
|
||||
testTwoFactor() {
|
||||
showScreenPopup(TwoFactorTestPopupView, [this.twoFactorTested]);
|
||||
}
|
||||
|
||||
clearTwoFactor() {
|
||||
this.viewSecret('');
|
||||
this.viewBackupCodes('');
|
||||
this.viewUrlTitle('');
|
||||
this.viewUrl('');
|
||||
|
||||
this.twoFactorTested(false);
|
||||
|
||||
this.clearing(true);
|
||||
Remote.clearTwoFactor(this.onResult);
|
||||
}
|
||||
|
||||
onShow(bLock) {
|
||||
this.lock(!!bLock);
|
||||
|
||||
this.viewSecret('');
|
||||
this.viewBackupCodes('');
|
||||
this.viewUrlTitle('');
|
||||
this.viewUrl('');
|
||||
}
|
||||
|
||||
onHide() {
|
||||
if (this.lock()) {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
getQr() {
|
||||
return (
|
||||
'otpauth://totp/' +
|
||||
encodeURIComponent(this.viewUser()) +
|
||||
'?secret=' +
|
||||
encodeURIComponent(this.viewSecret()) +
|
||||
'&issuer=' +
|
||||
encodeURIComponent('')
|
||||
);
|
||||
}
|
||||
|
||||
onResult(iError, oData) {
|
||||
this.processing(false);
|
||||
this.clearing(false);
|
||||
|
||||
if (iError) {
|
||||
this.viewUser('');
|
||||
this.viewEnable_(false);
|
||||
this.twoFactorStatus(false);
|
||||
this.twoFactorTested(false);
|
||||
|
||||
this.viewSecret('');
|
||||
this.viewBackupCodes('');
|
||||
this.viewUrlTitle('');
|
||||
this.viewUrl('');
|
||||
} else {
|
||||
this.viewUser(pString(oData.Result.User));
|
||||
this.viewEnable_(!!oData.Result.Enable);
|
||||
this.twoFactorStatus(!!oData.Result.IsSet);
|
||||
this.twoFactorTested(!!oData.Result.Tested);
|
||||
|
||||
this.viewSecret(pString(oData.Result.Secret));
|
||||
this.viewBackupCodes(pString(oData.Result.BackupCodes).replace(/[\s]+/g, ' '));
|
||||
|
||||
this.viewUrlTitle(pString(oData.Result.UrlTitle));
|
||||
this.viewUrl(qr.toDataURL({ level: 'M', size: 8, value: this.getQr() }));
|
||||
}
|
||||
}
|
||||
|
||||
onShowSecretResult(iError, data) {
|
||||
this.secreting(false);
|
||||
|
||||
if (iError) {
|
||||
this.viewSecret('');
|
||||
this.viewUrlTitle('');
|
||||
this.viewUrl('');
|
||||
} else {
|
||||
this.viewSecret(pString(data.Result.Secret));
|
||||
this.viewUrlTitle(pString(data.Result.UrlTitle));
|
||||
this.viewUrl(qr.toDataURL({ level: 'M', size: 6, value: this.getQr() }));
|
||||
}
|
||||
}
|
||||
|
||||
onBuild() {
|
||||
if (this.capaTwoFactor) {
|
||||
this.processing(true);
|
||||
Remote.getTwoFactor(this.onResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { TwoFactorConfigurationPopupView, TwoFactorConfigurationPopupView as default };
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
import Remote from 'Remote/User/Fetch';
|
||||
|
||||
import { decorateKoCommands } from 'Knoin/Knoin';
|
||||
import { AbstractViewPopup } from 'Knoin/AbstractViews';
|
||||
|
||||
class TwoFactorTestPopupView extends AbstractViewPopup {
|
||||
constructor() {
|
||||
super('TwoFactorTest');
|
||||
|
||||
this.addObservables({
|
||||
code: '',
|
||||
codeStatus: null,
|
||||
|
||||
testing: false
|
||||
});
|
||||
|
||||
this.koTestedTrigger = null;
|
||||
|
||||
decorateKoCommands(this, {
|
||||
testCodeCommand: self => self.code() && !self.testing()
|
||||
});
|
||||
}
|
||||
|
||||
testCodeCommand() {
|
||||
this.testing(true);
|
||||
Remote.testTwoFactor(iError => {
|
||||
this.testing(false);
|
||||
this.codeStatus(!iError);
|
||||
|
||||
if (this.koTestedTrigger && this.codeStatus()) {
|
||||
this.koTestedTrigger(true);
|
||||
}
|
||||
}, this.code());
|
||||
}
|
||||
|
||||
clearPopup() {
|
||||
this.code('');
|
||||
this.codeStatus(null);
|
||||
this.testing(false);
|
||||
|
||||
this.koTestedTrigger = null;
|
||||
}
|
||||
|
||||
onShow(koTestedTrigger) {
|
||||
this.clearPopup();
|
||||
|
||||
this.koTestedTrigger = koTestedTrigger;
|
||||
}
|
||||
}
|
||||
|
||||
export { TwoFactorTestPopupView, TwoFactorTestPopupView as default };
|
||||
|
|
@ -141,13 +141,6 @@ class LoginUserView extends AbstractViewCenter {
|
|||
}
|
||||
this.submitError(getNotification(iError, oData.ErrorMessage, Notification.UnknownNotification));
|
||||
this.submitErrorAddidional((oData && oData.ErrorMessageAdditional) || '');
|
||||
} else if (oData.TwoFactorAuth) {
|
||||
this.submitRequest(false);
|
||||
this.additionalCode('');
|
||||
this.additionalCodeVisibility(true);
|
||||
let input = this.querySelector('.inputAdditionalCode');
|
||||
input.required = true;
|
||||
setTimeout(() => input.focus(), 100);
|
||||
} else {
|
||||
rl.route.reload();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue