diff --git a/astrbot/dashboard/routes/auth.py b/astrbot/dashboard/routes/auth.py index 4ee0d57d4..70f9f6e2f 100644 --- a/astrbot/dashboard/routes/auth.py +++ b/astrbot/dashboard/routes/auth.py @@ -68,7 +68,11 @@ async def edit_account(self): Response().error("新用户名和新密码不能同时为空,你改了个寂寞").__dict__ ) + # Verify password confirmation if new_pwd: + confirm_pwd = post_data.get("confirm_password", None) + if confirm_pwd != new_pwd: + return Response().error("两次输入的新密码不一致,健忘症患者?").__dict__ self.config["dashboard"]["password"] = new_pwd if new_username: self.config["dashboard"]["username"] = new_username diff --git a/dashboard/src/i18n/locales/en-US/core/header.json b/dashboard/src/i18n/locales/en-US/core/header.json index df3255ec0..080c59b13 100644 --- a/dashboard/src/i18n/locales/en-US/core/header.json +++ b/dashboard/src/i18n/locales/en-US/core/header.json @@ -72,14 +72,17 @@ "form": { "currentPassword": "Current Password", "newPassword": "New Password", + "confirmPassword": "Confirm New Password", "newUsername": "New Username (Optional)", "passwordHint": "Password must be at least 8 characters", + "confirmPasswordHint": "Please enter new password again to confirm", "usernameHint": "Leave blank to keep current username", "defaultCredentials": "Default username and password are both astrbot" }, "validation": { "passwordRequired": "Please enter password", "passwordMinLength": "Password must be at least 8 characters", + "passwordMatch": "Passwords do not match", "usernameMinLength": "Username must be at least 3 characters" }, "actions": { diff --git a/dashboard/src/i18n/locales/zh-CN/core/header.json b/dashboard/src/i18n/locales/zh-CN/core/header.json index d21cb0f98..8b6b3dc1e 100644 --- a/dashboard/src/i18n/locales/zh-CN/core/header.json +++ b/dashboard/src/i18n/locales/zh-CN/core/header.json @@ -72,14 +72,17 @@ "form": { "currentPassword": "当前密码", "newPassword": "新密码", + "confirmPassword": "确认新密码", "newUsername": "新用户名 (可选)", "passwordHint": "密码长度至少 8 位", + "confirmPasswordHint": "请再次输入新密码以确认", "usernameHint": "留空表示不修改用户名", "defaultCredentials": "默认用户名和密码均为 astrbot" }, "validation": { "passwordRequired": "请输入密码", "passwordMinLength": "密码长度至少 8 位", + "passwordMatch": "两次输入的密码不一致", "usernameMinLength": "用户名长度至少3位" }, "actions": { @@ -90,4 +93,4 @@ "updateFailed": "修改失败,请重试" } } -} +} diff --git a/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue b/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue index 1bcd7f167..356d8344d 100644 --- a/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue +++ b/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue @@ -33,6 +33,7 @@ let aboutDialog = ref(false); const username = localStorage.getItem('user'); let password = ref(''); let newPassword = ref(''); +let confirmPassword = ref(''); let newUsername = ref(''); let status = ref(''); let updateStatus = ref('') @@ -89,6 +90,10 @@ const passwordRules = computed(() => [ (v: string) => !!v || t('core.header.accountDialog.validation.passwordRequired'), (v: string) => v.length >= 8 || t('core.header.accountDialog.validation.passwordMinLength') ]); +const confirmPasswordRules = computed(() => [ + (v: string) => !newPassword.value || !!v || t('core.header.accountDialog.validation.passwordRequired'), + (v: string) => !newPassword.value || v === newPassword.value || t('core.header.accountDialog.validation.passwordMatch') +]); const usernameRules = computed(() => [ (v: string) => !v || v.length >= 3 || t('core.header.accountDialog.validation.usernameMinLength') ]); @@ -96,6 +101,7 @@ const usernameRules = computed(() => [ // 显示密码相关 const showPassword = ref(false); const showNewPassword = ref(false); +const showConfirmPassword = ref(false); // 账户修改状态 const accountEditStatus = ref({ @@ -169,17 +175,14 @@ function accountEdit() { accountEditStatus.value.error = false; accountEditStatus.value.success = false; - // md5加密 - // @ts-ignore - if (password.value != '') { - password.value = md5(password.value); - } - if (newPassword.value != '') { - newPassword.value = md5(newPassword.value); - } + const passwordHash = password.value ? md5(password.value) : ''; + const newPasswordHash = newPassword.value ? md5(newPassword.value) : ''; + const confirmPasswordHash = confirmPassword.value ? md5(confirmPassword.value) : ''; + axios.post('/api/auth/account/edit', { - password: password.value, - new_password: newPassword.value, + password: passwordHash, + new_password: newPasswordHash, + confirm_password: confirmPasswordHash, new_username: newUsername.value ? newUsername.value : username }) .then((res) => { @@ -188,6 +191,7 @@ function accountEdit() { accountEditStatus.value.message = res.data.message; password.value = ''; newPassword.value = ''; + confirmPassword.value = ''; return; } accountEditStatus.value.success = true; @@ -204,6 +208,7 @@ function accountEdit() { accountEditStatus.value.message = typeof err === 'string' ? err : t('core.header.accountDialog.messages.updateFailed'); password.value = ''; newPassword.value = ''; + confirmPassword.value = ''; }) .finally(() => { accountEditStatus.value.loading = false; @@ -734,10 +739,16 @@ onMounted(async () => { + +