mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-08-31 19:51:36 +08:00
refactor: 💡 refact recovery code
This commit is contained in:
parent
2eeb376d24
commit
77f62b94cc
@ -126,9 +126,9 @@ interface TOTPStatus {
|
||||
|
||||
interface RecoveryKeysResponse {
|
||||
success: boolean;
|
||||
recoveryCodes?: string;
|
||||
recoveryCodes?: string[];
|
||||
keysExist?: boolean;
|
||||
usedRecoveryCodes?: string;
|
||||
usedRecoveryCodes?: string[];
|
||||
}
|
||||
|
||||
export default class MultiFactorAuthenticationOptions extends OptionsWidget {
|
||||
@ -231,6 +231,7 @@ export default class MultiFactorAuthenticationOptions extends OptionsWidget {
|
||||
}
|
||||
|
||||
const usedResult = await server.get<RecoveryKeysResponse>("totp_recovery/used");
|
||||
|
||||
if (usedResult.usedRecoveryCodes) {
|
||||
this.keyFiller(usedResult.usedRecoveryCodes);
|
||||
this.$generateRecoveryCodeButton.text(t("multi_factor_authentication.recovery_keys_regenerate"));
|
||||
@ -239,14 +240,19 @@ export default class MultiFactorAuthenticationOptions extends OptionsWidget {
|
||||
}
|
||||
}
|
||||
|
||||
private keyFiller(values: string) {
|
||||
const keys = values.split(',').slice(0, 8);
|
||||
|
||||
private keyFiller(values: string[]) {
|
||||
this.fillKeys("");
|
||||
|
||||
keys.forEach((key, index) => {
|
||||
if (index < 8 && key && typeof key === 'string') {
|
||||
this.$recoveryKeys[index].text(key.trim());
|
||||
values.forEach((key, index) => {
|
||||
if (typeof key === 'string') {
|
||||
const date = new Date(key.replace(/\//g, '-'));
|
||||
if (isNaN(date.getTime())) {
|
||||
this.$recoveryKeys[index].text(key);
|
||||
} else {
|
||||
this.$recoveryKeys[index].text(t("multi_factor_authentication.recovery_keys_used", { date: key.replace(/\//g, '-') }));
|
||||
}
|
||||
} else {
|
||||
this.$recoveryKeys[index].text(t("multi_factor_authentication.recovery_keys_unused", { index: key }));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1322,6 +1322,8 @@
|
||||
"recovery_keys_no_key_set": "未设置恢复代码",
|
||||
"recovery_keys_generate": "生成恢复代码",
|
||||
"recovery_keys_regenerate": "重新生成恢复代码",
|
||||
"recovery_keys_used": "已使用: {{date}}",
|
||||
"recovery_keys_unused": "恢复代码 {{index}} 未使用",
|
||||
"oauth_title": "OAuth/OpenID 认证",
|
||||
"oauth_description": "OpenID 是一种标准化方式,允许您使用其他服务(如 Google)的账户登录网站,以验证您的身份。请参阅这些 <a href=\"https://developers.google.com/identity/openid-connect/openid-connect\">指南</a> 通过 Google 设置 OpenID 服务。",
|
||||
"oauth_description_warning": "要启用 OAuth/OpenID,您需要设置 config.ini 文件中的 OAuth/OpenID 基础 URL、客户端 ID 和客户端密钥,并重新启动应用程序。",
|
||||
|
@ -1333,6 +1333,8 @@
|
||||
"recovery_keys_no_key_set": "No recovery codes set",
|
||||
"recovery_keys_generate": "Generate Recovery Codes",
|
||||
"recovery_keys_regenerate": "Regenerate Recovery Codes",
|
||||
"recovery_keys_used": "Used: {{date}}",
|
||||
"recovery_keys_unused": "Recovery code {{index}} is unused",
|
||||
"oauth_title": "OAuth/OpenID",
|
||||
"oauth_description": "OpenID is a standardized way to let you log into websites using an account from another service, like Google, to verify your identity. Follow these <a href=\"https://developers.google.com/identity/openid-connect/openid-connect\">instructions</a> to setup an OpenID service through Google.",
|
||||
"oauth_description_warning": "To enable OAuth/OpenID, you need to set the OAuth/OpenID base URL, client ID and client secret in the config.ini file and restart the application.",
|
||||
|
@ -3,7 +3,7 @@ import type { Request } from 'express';
|
||||
import { randomBytes } from 'crypto';
|
||||
|
||||
function setRecoveryCodes(req: Request) {
|
||||
const success = recovery_codes.setRecoveryCodes(req.body.recoveryCodes);
|
||||
const success = recovery_codes.setRecoveryCodes(req.body.recoveryCodes.join(','));
|
||||
return { success: success, message: 'Recovery codes set!' };
|
||||
}
|
||||
|
||||
@ -31,15 +31,28 @@ function generateRecoveryCodes() {
|
||||
randomBytes(16).toString('base64')
|
||||
];
|
||||
|
||||
recovery_codes.setRecoveryCodes(recoveryKeys.toString());
|
||||
recovery_codes.setRecoveryCodes(recoveryKeys.join(','));
|
||||
|
||||
return { success: true, recoveryCodes: recoveryKeys.toString() };
|
||||
return { success: true, recoveryCodes: recoveryKeys };
|
||||
}
|
||||
|
||||
function getUsedRecoveryCodes() {
|
||||
if (!recovery_codes.isRecoveryCodeSet()) {
|
||||
return []
|
||||
}
|
||||
|
||||
const dateRegex = RegExp(/^\d{4}\/\d{2}\/\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/gm);
|
||||
const recoveryCodes = recovery_codes.getRecoveryCodes();
|
||||
const usedStatus: string[] = [];
|
||||
|
||||
recoveryCodes.forEach((recoveryKey: string) => {
|
||||
if (dateRegex.test(recoveryKey)) usedStatus.push(recoveryKey);
|
||||
else usedStatus.push(recoveryCodes.indexOf(recoveryKey));
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
usedRecoveryCodes: recovery_codes.getUsedRecoveryCodes().toString()
|
||||
usedRecoveryCodes: usedStatus
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
import sql from '../sql.js';
|
||||
import optionService from '../options.js';
|
||||
import crypto from 'crypto';
|
||||
@ -26,7 +24,7 @@ function setRecoveryCodes(recoveryCodes: string) {
|
||||
|
||||
function getRecoveryCodes() {
|
||||
if (!isRecoveryCodeSet()) {
|
||||
return Array(8).fill("Keys not set")
|
||||
return []
|
||||
}
|
||||
|
||||
return sql.transactional(() => {
|
||||
@ -67,25 +65,9 @@ function verifyRecoveryCode(recoveryCodeGuess: string) {
|
||||
return loginSuccess;
|
||||
}
|
||||
|
||||
function getUsedRecoveryCodes() {
|
||||
if (!isRecoveryCodeSet()) {
|
||||
return Array(8).fill("Recovery code not set")
|
||||
}
|
||||
|
||||
const dateRegex = RegExp(/^\d{4}\/\d{2}\/\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/gm);
|
||||
const recoveryCodes = getRecoveryCodes();
|
||||
const usedStatus: string[] = [];
|
||||
|
||||
recoveryCodes.forEach((recoveryKey: string) => {
|
||||
if (dateRegex.test(recoveryKey)) usedStatus.push('Used: ' + recoveryKey);
|
||||
else usedStatus.push('Recovery code ' + recoveryCodes.indexOf(recoveryKey) + ' is unused');
|
||||
});
|
||||
return usedStatus;
|
||||
}
|
||||
|
||||
export default {
|
||||
setRecoveryCodes,
|
||||
getRecoveryCodes,
|
||||
verifyRecoveryCode,
|
||||
getUsedRecoveryCodes,
|
||||
isRecoveryCodeSet
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user