From 9968268975601df4b21f941325b080384ca8e26a Mon Sep 17 00:00:00 2001 From: Peifan Li Date: Sat, 3 Jan 2026 11:23:03 -0500 Subject: [PATCH] feat: Add allowResetPassword setting and UI components --- backend/src/services/passwordService.ts | 7 ++++++ backend/src/types/settings.ts | 1 + .../components/Settings/SecuritySettings.tsx | 16 +++++++++++++ frontend/src/pages/LoginPage.tsx | 23 +++++++++++-------- frontend/src/types.ts | 1 + frontend/src/utils/locales/ar.ts | 2 ++ frontend/src/utils/locales/de.ts | 2 ++ frontend/src/utils/locales/en.ts | 2 ++ frontend/src/utils/locales/es.ts | 2 ++ frontend/src/utils/locales/fr.ts | 2 ++ frontend/src/utils/locales/ja.ts | 2 ++ frontend/src/utils/locales/ko.ts | 2 ++ frontend/src/utils/locales/pt.ts | 2 ++ frontend/src/utils/locales/ru.ts | 2 ++ frontend/src/utils/locales/zh.ts | 2 ++ 15 files changed, 58 insertions(+), 10 deletions(-) diff --git a/backend/src/services/passwordService.ts b/backend/src/services/passwordService.ts index 4f6a190..1333c21 100644 --- a/backend/src/services/passwordService.ts +++ b/backend/src/services/passwordService.ts @@ -117,6 +117,13 @@ export async function resetPassword(): Promise { const settings = storageService.getSettings(); const mergedSettings = { ...defaultSettings, ...settings }; + // Check if password reset is allowed (defaults to true for backward compatibility) + const allowResetPassword = mergedSettings.allowResetPassword !== false; + + if (!allowResetPassword) { + throw new Error("Password reset is not allowed. The allowResetPassword setting is disabled."); + } + // Check if password login is allowed (defaults to true for backward compatibility) const passwordLoginAllowed = mergedSettings.passwordLoginAllowed !== false; diff --git a/backend/src/types/settings.ts b/backend/src/types/settings.ts index 5b53082..0d70b6d 100644 --- a/backend/src/types/settings.ts +++ b/backend/src/types/settings.ts @@ -2,6 +2,7 @@ export interface Settings { loginEnabled: boolean; password?: string; passwordLoginAllowed?: boolean; + allowResetPassword?: boolean; defaultAutoPlay: boolean; defaultAutoLoop: boolean; maxConcurrentDownloads: number; diff --git a/frontend/src/components/Settings/SecuritySettings.tsx b/frontend/src/components/Settings/SecuritySettings.tsx index 5300c85..dcddfdc 100644 --- a/frontend/src/components/Settings/SecuritySettings.tsx +++ b/frontend/src/components/Settings/SecuritySettings.tsx @@ -162,6 +162,22 @@ const SecuritySettings: React.FC = ({ settings, onChange + onChange('allowResetPassword', e.target.checked)} + disabled={!settings.loginEnabled} + /> + } + label={t('allowResetPassword') || 'Allow Reset Password'} + /> + + + {t('allowResetPasswordHelper') || 'When disabled, the reset password button will not be shown on the login page and the reset password API will be blocked.'} + + + {settings.passwordLoginAllowed !== false && ( { }); const passwordLoginAllowed = settingsData?.passwordLoginAllowed !== false; + const allowResetPassword = settingsData?.allowResetPassword !== false; // Update website name when settings are loaded useEffect(() => { @@ -426,16 +427,18 @@ const LoginPage: React.FC = () => { : (t('loginWithPasskey') || 'Login with Passkey')} )} - + {allowResetPassword && ( + + )} 0 || (error && waitTime === 0) ? 'auto' : 0, mt: 2 }}> {waitTime > 0 && ( diff --git a/frontend/src/types.ts b/frontend/src/types.ts index f6bce3b..2f6c530 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -60,6 +60,7 @@ export interface Settings { password?: string; isPasswordSet?: boolean; passwordLoginAllowed?: boolean; + allowResetPassword?: boolean; defaultAutoPlay: boolean; defaultAutoLoop: boolean; maxConcurrentDownloads: number; diff --git a/frontend/src/utils/locales/ar.ts b/frontend/src/utils/locales/ar.ts index b0ee436..8430de1 100644 --- a/frontend/src/utils/locales/ar.ts +++ b/frontend/src/utils/locales/ar.ts @@ -54,6 +54,8 @@ export const ar = { enableLogin: "تفعيل حماية تسجيل الدخول", allowPasswordLogin: "السماح بتسجيل الدخول بكلمة المرور", allowPasswordLoginHelper: "عند التعطيل، لن يكون تسجيل الدخول بكلمة المرور متاحًا. يجب أن يكون لديك مفتاح وصول واحد على الأقل لتعطيل تسجيل الدخول بكلمة المرور.", + allowResetPassword: "السماح بإعادة تعيين كلمة المرور", + allowResetPasswordHelper: "عند التعطيل، لن يتم عرض زر إعادة تعيين كلمة المرور في صفحة تسجيل الدخول وستتم حظر واجهة برمجة تطبيقات إعادة تعيين كلمة المرور.", password: "كلمة المرور", enterPassword: "أدخل كلمة المرور", togglePasswordVisibility: "تبديل رؤية كلمة المرور", diff --git a/frontend/src/utils/locales/de.ts b/frontend/src/utils/locales/de.ts index fc28c11..93a13d9 100644 --- a/frontend/src/utils/locales/de.ts +++ b/frontend/src/utils/locales/de.ts @@ -53,6 +53,8 @@ export const de = { enableLogin: "Anmeldeschutz aktivieren", allowPasswordLogin: "Passwort-Anmeldung zulassen", allowPasswordLoginHelper: "Wenn deaktiviert, ist die Passwort-Anmeldung nicht verfügbar. Sie müssen mindestens einen Passkey haben, um die Passwort-Anmeldung zu deaktivieren.", + allowResetPassword: "Passwort zurücksetzen zulassen", + allowResetPasswordHelper: "Wenn deaktiviert, wird die Schaltfläche zum Zurücksetzen des Passworts auf der Anmeldeseite nicht angezeigt und die API zum Zurücksetzen des Passworts wird blockiert.", password: "Passwort", enterPassword: "Passwort eingeben", togglePasswordVisibility: "Passwort sichtbar machen", diff --git a/frontend/src/utils/locales/en.ts b/frontend/src/utils/locales/en.ts index d78b416..347f99b 100644 --- a/frontend/src/utils/locales/en.ts +++ b/frontend/src/utils/locales/en.ts @@ -54,6 +54,8 @@ export const en = { enableLogin: "Enable Login Protection", allowPasswordLogin: "Allow Password Login", allowPasswordLoginHelper: "When disabled, password login is not available. You must have at least one passkey to disable password login.", + allowResetPassword: "Allow Reset Password", + allowResetPasswordHelper: "When disabled, the reset password button will not be shown on the login page and the reset password API will be blocked.", password: "Password", enterPassword: "Enter Password", togglePasswordVisibility: "Toggle password visibility", diff --git a/frontend/src/utils/locales/es.ts b/frontend/src/utils/locales/es.ts index 4df5f30..dd437c2 100644 --- a/frontend/src/utils/locales/es.ts +++ b/frontend/src/utils/locales/es.ts @@ -64,6 +64,8 @@ export const es = { enableLogin: "Habilitar Protección de Inicio de Sesión", allowPasswordLogin: "Permitir Inicio de Sesión con Contraseña", allowPasswordLoginHelper: "Cuando está deshabilitado, el inicio de sesión con contraseña no está disponible. Debe tener al menos una clave de acceso para deshabilitar el inicio de sesión con contraseña.", + allowResetPassword: "Permitir Restablecer Contraseña", + allowResetPasswordHelper: "Cuando está deshabilitado, el botón de restablecer contraseña no se mostrará en la página de inicio de sesión y la API de restablecer contraseña será bloqueada.", password: "Contraseña", enterPassword: "Introducir contraseña", togglePasswordVisibility: "Alternar visibilidad de contraseña", diff --git a/frontend/src/utils/locales/fr.ts b/frontend/src/utils/locales/fr.ts index 6ba48df..55de638 100644 --- a/frontend/src/utils/locales/fr.ts +++ b/frontend/src/utils/locales/fr.ts @@ -57,6 +57,8 @@ export const fr = { enableLogin: "Activer la protection par connexion", allowPasswordLogin: "Autoriser la connexion par mot de passe", allowPasswordLoginHelper: "Lorsqu'elle est désactivée, la connexion par mot de passe n'est pas disponible. Vous devez avoir au moins une clé d'accès pour désactiver la connexion par mot de passe.", + allowResetPassword: "Autoriser la réinitialisation du mot de passe", + allowResetPasswordHelper: "Lorsqu'elle est désactivée, le bouton de réinitialisation du mot de passe ne sera pas affiché sur la page de connexion et l'API de réinitialisation du mot de passe sera bloquée.", password: "Mot de passe", enterPassword: "Entrez le mot de passe", togglePasswordVisibility: "Afficher/Masquer le mot de passe", diff --git a/frontend/src/utils/locales/ja.ts b/frontend/src/utils/locales/ja.ts index 5539f1f..ab0ca6a 100644 --- a/frontend/src/utils/locales/ja.ts +++ b/frontend/src/utils/locales/ja.ts @@ -56,6 +56,8 @@ export const ja = { enableLogin: "ログイン保護を有効にする", allowPasswordLogin: "パスワードログインを許可", allowPasswordLoginHelper: "無効にすると、パスワードログインは利用できません。パスワードログインを無効にするには、少なくとも1つのパスキーが必要です。", + allowResetPassword: "パスワードリセットを許可", + allowResetPasswordHelper: "無効にすると、ログインページにパスワードリセットボタンが表示されず、パスワードリセットAPIがブロックされます。", password: "パスワード", enterPassword: "パスワードを入力", togglePasswordVisibility: "パスワードの表示切り替え", diff --git a/frontend/src/utils/locales/ko.ts b/frontend/src/utils/locales/ko.ts index a4d99b1..46b5448 100644 --- a/frontend/src/utils/locales/ko.ts +++ b/frontend/src/utils/locales/ko.ts @@ -56,6 +56,8 @@ export const ko = { enableLogin: "로그인 보호 활성화", allowPasswordLogin: "비밀번호 로그인 허용", allowPasswordLoginHelper: "비활성화되면 비밀번호 로그인을 사용할 수 없습니다. 비밀번호 로그인을 비활성화하려면 최소한 하나의 패스키가 있어야 합니다.", + allowResetPassword: "비밀번호 재설정 허용", + allowResetPasswordHelper: "비활성화되면 로그인 페이지에 비밀번호 재설정 버튼이 표시되지 않고 비밀번호 재설정 API가 차단됩니다.", password: "비밀번호", enterPassword: "비밀번호 입력", togglePasswordVisibility: "비밀번호 표시 전환", diff --git a/frontend/src/utils/locales/pt.ts b/frontend/src/utils/locales/pt.ts index a0bdc47..5cdd238 100644 --- a/frontend/src/utils/locales/pt.ts +++ b/frontend/src/utils/locales/pt.ts @@ -57,6 +57,8 @@ export const pt = { enableLogin: "Ativar Proteção de Login", allowPasswordLogin: "Permitir Login com Senha", allowPasswordLoginHelper: "Quando desabilitado, o login com senha não está disponível. Você deve ter pelo menos uma chave de acesso para desabilitar o login com senha.", + allowResetPassword: "Permitir Redefinir Senha", + allowResetPasswordHelper: "Quando desabilitado, o botão de redefinir senha não será exibido na página de login e a API de redefinir senha será bloqueada.", password: "Senha", enterPassword: "Digite a senha", togglePasswordVisibility: "Alternar visibilidade da senha", diff --git a/frontend/src/utils/locales/ru.ts b/frontend/src/utils/locales/ru.ts index ef16af4..0cce6c8 100644 --- a/frontend/src/utils/locales/ru.ts +++ b/frontend/src/utils/locales/ru.ts @@ -66,6 +66,8 @@ export const ru = { enableLogin: "Включить защиту входа", allowPasswordLogin: "Разрешить вход по паролю", allowPasswordLoginHelper: "При отключении вход по паролю недоступен. Для отключения входа по паролю необходимо иметь хотя бы один ключ доступа.", + allowResetPassword: "Разрешить сброс пароля", + allowResetPasswordHelper: "При отключении кнопка сброса пароля не будет отображаться на странице входа, а API сброса пароля будет заблокирована.", password: "Пароль", enterPassword: "Введите пароль", togglePasswordVisibility: "Показать/скрыть пароль", diff --git a/frontend/src/utils/locales/zh.ts b/frontend/src/utils/locales/zh.ts index 11fdf0e..e799e67 100644 --- a/frontend/src/utils/locales/zh.ts +++ b/frontend/src/utils/locales/zh.ts @@ -54,6 +54,8 @@ export const zh = { enableLogin: "启用登录保护", allowPasswordLogin: "允许密码登录", allowPasswordLoginHelper: "禁用后,密码登录将不可用。要禁用密码登录,您必须至少有一个通行密钥。", + allowResetPassword: "允许重置密码", + allowResetPasswordHelper: "禁用后,登录页面将不显示重置密码按钮,并且重置密码 API 将被阻止。", password: "密码", enterPassword: "输入密码", togglePasswordVisibility: "切换密码可见性",