From d3013e32e16f244417a6240fbb92d2090c048e61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=B6=E7=91=BE?= <74231782+sj817@users.noreply.github.com> Date: Mon, 8 Sep 2025 22:35:36 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=A2=9E=E5=BC=BA=EF=BC=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=96=B0=E5=AF=86=E7=A0=81=E5=BC=BA=E5=BA=A6=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E5=92=8C=E6=97=A7=E5=AF=86=E7=A0=81=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dashboard/config/change_password.tsx | 52 +++++++++++++++- src/webui/src/api/Auth.ts | 61 +++++++++++-------- src/webui/src/router/auth.ts | 1 - 3 files changed, 84 insertions(+), 30 deletions(-) diff --git a/napcat.webui/src/pages/dashboard/config/change_password.tsx b/napcat.webui/src/pages/dashboard/config/change_password.tsx index f4afc4b0..d67ed01f 100644 --- a/napcat.webui/src/pages/dashboard/config/change_password.tsx +++ b/napcat.webui/src/pages/dashboard/config/change_password.tsx @@ -14,8 +14,9 @@ const ChangePasswordCard = () => { const { control, handleSubmit: handleWebuiSubmit, - formState: { isSubmitting }, - reset + formState: { isSubmitting, errors }, + reset, + watch } = useForm<{ oldToken: string newToken: string @@ -29,6 +30,9 @@ const ChangePasswordCard = () => { const navigate = useNavigate() const [_, setToken] = useLocalStorage(key.token, '') + // 监听旧密码的值 + const oldTokenValue = watch('oldToken') + const onSubmit = handleWebuiSubmit(async (data) => { try { // 使用正常密码更新流程 @@ -51,12 +55,24 @@ const ChangePasswordCard = () => { { + if (!value || value.trim().length === 0) { + return '旧密码不能为空' + } + return true + } + }} render={({ field }) => ( )} /> @@ -64,12 +80,42 @@ const ChangePasswordCard = () => { { + if (!value || value.trim().length === 0) { + return '新密码不能为空' + } + if (value.trim().length !== value.length) { + return '新密码不能包含前后空格' + } + if (value === oldTokenValue) { + return '新密码不能与旧密码相同' + } + // 检查是否包含字母 + if (!/[a-zA-Z]/.test(value)) { + return '新密码必须包含字母' + } + // 检查是否包含数字 + if (!/[0-9]/.test(value)) { + return '新密码必须包含数字' + } + return true + } + }} render={({ field }) => ( )} /> diff --git a/src/webui/src/api/Auth.ts b/src/webui/src/api/Auth.ts index bb450d99..54a8dfda 100644 --- a/src/webui/src/api/Auth.ts +++ b/src/webui/src/api/Auth.ts @@ -92,16 +92,36 @@ export const checkHandler: RequestHandler = async (req, res) => { // 修改密码(token) export const UpdateTokenHandler: RequestHandler = async (req, res) => { - const { oldToken, newToken, fromDefault } = req.body; + const { oldToken, newToken } = req.body; const authorization = req.headers.authorization; if (isEmpty(newToken)) { return sendError(res, 'newToken is empty'); } - // 如果不是从默认密码更新,则需要验证旧密码 - if (!fromDefault && isEmpty(oldToken)) { - return sendError(res, 'oldToken is required when not updating from default password'); + // 强制要求旧密码 + if (isEmpty(oldToken)) { + return sendError(res, 'oldToken is required'); + } + + // 检查新旧密码是否相同 + if (oldToken === newToken) { + return sendError(res, '新密码不能与旧密码相同'); + } + + // 检查新密码强度 + if (newToken.length < 6) { + return sendError(res, '新密码至少需要6个字符'); + } + + // 检查是否包含字母 + if (!/[a-zA-Z]/.test(newToken)) { + return sendError(res, '新密码必须包含字母'); + } + + // 检查是否包含数字 + if (!/[0-9]/.test(newToken)) { + return sendError(res, '新密码必须包含数字'); } try { @@ -112,29 +132,18 @@ export const UpdateTokenHandler: RequestHandler = async (req, res) => { AuthHelper.revokeCredential(Credential); } - if (fromDefault) { - // 从默认密码更新,直接设置新密码 - const currentConfig = await WebUiConfig.GetWebUIConfig(); - if (!currentConfig.defaultToken) { - return sendError(res, 'Current password is not default password'); - } - await WebUiConfig.UpdateWebUIConfig({ token: newToken, defaultToken: false }); - // 更新内存中的缓存token,使新密码立即生效 - setInitialWebUiToken(newToken); - } else { - // 正常的密码更新流程 - 使用启动时缓存的token进行验证 - const initialToken = getInitialWebUiToken(); - if (!initialToken) { - return sendError(res, 'Server token not initialized'); - } - if (initialToken !== oldToken) { - return sendError(res, '旧 token 不匹配'); - } - // 直接更新配置文件中的token,不需要通过WebUiConfig.UpdateToken方法 - await WebUiConfig.UpdateWebUIConfig({ token: newToken, defaultToken: false }); - // 更新内存中的缓存token,使新密码立即生效 - setInitialWebUiToken(newToken); + // 使用启动时缓存的token进行验证 + const initialToken = getInitialWebUiToken(); + if (!initialToken) { + return sendError(res, 'Server token not initialized'); } + if (initialToken !== oldToken) { + return sendError(res, '旧 token 不匹配'); + } + // 直接更新配置文件中的token,不需要通过WebUiConfig.UpdateToken方法 + await WebUiConfig.UpdateWebUIConfig({ token: newToken, defaultToken: false }); + // 更新内存中的缓存token,使新密码立即生效 + setInitialWebUiToken(newToken); return sendSuccess(res, 'Token updated successfully'); } catch (e: any) { diff --git a/src/webui/src/router/auth.ts b/src/webui/src/router/auth.ts index 9aea1b8d..1e1237fa 100644 --- a/src/webui/src/router/auth.ts +++ b/src/webui/src/router/auth.ts @@ -1,7 +1,6 @@ import { Router } from 'express'; import { - CheckDefaultTokenHandler, checkHandler, LoginHandler, LogoutHandler,