diff --git a/dev/Settings/Admin/Security.js b/dev/Settings/Admin/Security.js index a1ba65b6f..3cc9f4d5e 100644 --- a/dev/Settings/Admin/Security.js +++ b/dev/Settings/Admin/Security.js @@ -21,28 +21,47 @@ export class AdminSettingsSecurity extends AbstractViewSettings { adminPasswordNew: '', adminPasswordNew2: '', adminPasswordNewError: false, - adminTOTP: SettingsGet('AdminTOTP'), + adminTOTP: '', - adminPasswordUpdateError: false, - adminPasswordUpdateSuccess: false, + saveError: false, + saveSuccess: false, + + viewQRCode: '', capaOpenPGP: SettingsCapa('OpenPGP') }); const reset = () => { - this.adminPasswordUpdateError(false); - this.adminPasswordUpdateSuccess(false); + this.saveError(false); + this.saveSuccess(false); this.adminPasswordNewError(false); }; addSubscribablesTo(this, { adminPassword: () => { - this.adminPasswordUpdateError(false); - this.adminPasswordUpdateSuccess(false); + this.saveError(false); + this.saveSuccess(false); }, adminLogin: () => this.adminLoginError(false), + adminTOTP: value => { + let l = value.length; + if (16 <= l && 0 == value.length * 5 % 8) { + Remote.request('AdminQRCode', (iError, data) => { + if (!iError) { + console.dir({data:data}); + this.viewQRCode(data.Result); + } + }, { + 'username': this.adminLogin(), + 'TOTP': this.adminTOTP() + }); + } else { + this.viewQRCode(''); + } + }, + adminPasswordNew: reset, adminPasswordNew2: reset, @@ -50,6 +69,8 @@ export class AdminSettingsSecurity extends AbstractViewSettings { capaOpenPGP: value => Remote.saveSetting('CapaOpenPGP', value) }); + this.adminTOTP(SettingsGet('AdminTOTP')); + decorateKoCommands(this, { saveNewAdminPasswordCommand: self => self.adminLogin().trim() && self.adminPassword() }); @@ -66,18 +87,18 @@ export class AdminSettingsSecurity extends AbstractViewSettings { return false; } - this.adminPasswordUpdateError(false); - this.adminPasswordUpdateSuccess(false); + this.saveError(false); + this.saveSuccess(false); Remote.request('AdminPasswordUpdate', (iError, data) => { if (iError) { - this.adminPasswordUpdateError(true); + this.saveError(true); } else { this.adminPassword(''); this.adminPasswordNew(''); this.adminPasswordNew2(''); - this.adminPasswordUpdateSuccess(true); + this.saveSuccess(true); this.weakPassword(!!data.Result.Weak); } diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php b/snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php index e26f0cd59..0e5a2f927 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php @@ -668,6 +668,19 @@ class ActionsAdmin extends Actions return $this->DefaultResponse(__FUNCTION__, true); } + public function DoAdminQRCode() : array + { + $user = (string) $this->GetActionParam('username', ''); + $secret = (string) $this->GetActionParam('TOTP', ''); + $issuer = \rawurlencode(\RainLoop\API::Config()->Get('webmail', 'title', 'SnappyMail')); + $QR = \SnappyMail\QRCode::getMinimumQRCode( + "otpauth://totp/{$issuer}:{$user}?secret={$secret}&issuer={$issuer}", +// "otpauth://totp/{$user}?secret={$secret}", + \SnappyMail\QRCode::ERROR_CORRECT_LEVEL_M + ); + return $this->DefaultResponse(__FUNCTION__, $QR->__toString()); + } + private function setAdminAuthToken(string $sToken) : void { Utils::SetCookie(static::$AUTH_ADMIN_TOKEN_KEY, $sToken, 0); diff --git a/snappymail/v/0.0.0/app/templates/Views/Admin/AdminSettingsSecurity.html b/snappymail/v/0.0.0/app/templates/Views/Admin/AdminSettingsSecurity.html index 12c8b05ac..8583e4640 100644 --- a/snappymail/v/0.0.0/app/templates/Views/Admin/AdminSettingsSecurity.html +++ b/snappymail/v/0.0.0/app/templates/Views/Admin/AdminSettingsSecurity.html @@ -49,7 +49,11 @@ data-bind="textInput: adminTOTP">
- +

+	
+
+