Added: ?admin TOTP show QR code

This commit is contained in:
the-djmaze 2022-08-29 12:17:08 +02:00
parent a80161a316
commit 3808852894
3 changed files with 50 additions and 12 deletions

View file

@ -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);
}

View file

@ -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);

View file

@ -49,7 +49,11 @@
data-bind="textInput: adminTOTP">
</div>
<div class="control-group">
<a class="btn" data-bind="command: saveNewAdminPasswordCommand, css: { 'btn-success': adminPasswordUpdateSuccess, 'btn-danger': adminPasswordUpdateError }"
<label></label>
<pre data-bind="text: viewQRCode" style="font-family:var(--fontMono);font-size:11px;letter-spacing:-1px;line-height:1;"></pre>
</div>
<div class="control-group">
<a class="btn" data-bind="command: saveNewAdminPasswordCommand, css: { 'btn-success': saveSuccess, 'btn-danger': saveError }"
data-icon="🔑" data-i18n="GLOBAL/SAVE"></a>
</div>
</div>