diff --git a/src/app/api/change-password/route.ts b/src/app/api/change-password/route.ts index c9534f8fae..6aba321bd6 100644 --- a/src/app/api/change-password/route.ts +++ b/src/app/api/change-password/route.ts @@ -22,22 +22,21 @@ export async function POST(request: NextRequest) { try { const body = await request.json(); - const { newPassword } = body; - - // 获取认证信息 + const { newPassword, oldPassword } = body; const authInfo = getAuthInfoFromCookie(request); if (!authInfo || !authInfo.username) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } - - // 验证新密码 - if (!newPassword || typeof newPassword !== 'string') { - return NextResponse.json({ error: '新密码不得为空' }, { status: 400 }); + if (!oldPassword || typeof oldPassword !== 'string') { + return NextResponse.json({ error: '旧密码不得为空' }, { status: 400 }); + } + if (!newPassword || typeof newPassword !== 'string' || newPassword.trim().length < 6) { + return NextResponse.json({ error: '新密码长度至少为6位' }, { status: 400 }); + } + if (oldPassword === newPassword) { + return NextResponse.json({ error: '新密码不能与旧密码相同' }, { status: 400 }); } - const username = authInfo.username; - - // 不允许站长修改密码(站长用户名等于 process.env.USERNAME) if (username === process.env.USERNAME) { return NextResponse.json( { error: '站长不能通过此接口修改密码' }, @@ -45,7 +44,10 @@ export async function POST(request: NextRequest) { ); } - // 修改密码 + const valid = await db.verifyUser(username, oldPassword); + if (!valid) { + return NextResponse.json({ error: '旧密码错误' }, { status: 401 }); + } await db.changePassword(username, newPassword); return NextResponse.json({ ok: true }); diff --git a/src/components/UserMenu.tsx b/src/components/UserMenu.tsx index 8889562390..59c5e1e5b7 100644 --- a/src/components/UserMenu.tsx +++ b/src/components/UserMenu.tsx @@ -97,7 +97,7 @@ export const UserMenu: React.FC = () => { { value: 'custom', label: '自定义代理' }, ]; - // 修改密码相关状态 + const [oldPassword, setOldPassword] = useState(''); const [newPassword, setNewPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [passwordLoading, setPasswordLoading] = useState(false); @@ -277,6 +277,7 @@ export const UserMenu: React.FC = () => { const handleChangePassword = () => { setIsOpen(false); setIsChangePasswordOpen(true); + setOldPassword(''); setNewPassword(''); setConfirmPassword(''); setPasswordError(''); @@ -284,6 +285,7 @@ export const UserMenu: React.FC = () => { const handleCloseChangePassword = () => { setIsChangePasswordOpen(false); + setOldPassword(''); setNewPassword(''); setConfirmPassword(''); setPasswordError(''); @@ -291,20 +293,23 @@ export const UserMenu: React.FC = () => { const handleSubmitChangePassword = async () => { setPasswordError(''); - - // 验证密码 - if (!newPassword) { - setPasswordError('新密码不得为空'); + if (!oldPassword) { + setPasswordError('旧密码不得为空'); + return; + } + if (!newPassword || newPassword.trim().length < 6) { + setPasswordError('新密码长度至少为6位'); + return; + } + if (oldPassword === newPassword) { + setPasswordError('新密码不能与旧密码相同'); return; } - if (newPassword !== confirmPassword) { setPasswordError('两次输入的密码不一致'); return; } - setPasswordLoading(true); - try { const response = await fetch('/api/change-password', { method: 'POST', @@ -312,18 +317,15 @@ export const UserMenu: React.FC = () => { 'Content-Type': 'application/json', }, body: JSON.stringify({ + oldPassword, newPassword, }), }); - const data = await response.json(); - if (!response.ok) { setPasswordError(data.error || '修改密码失败'); return; } - - // 修改成功,关闭弹窗并登出 setIsChangePasswordOpen(false); await handleLogout(); } catch (error) { @@ -1021,9 +1023,20 @@ export const UserMenu: React.FC = () => { - {/* 表单 */}
- {/* 新密码输入 */} +
+ + setOldPassword(e.target.value)} + disabled={passwordLoading} + /> +
- - {/* 确认密码输入 */}
- {/* 错误信息 */} {passwordError && (
{passwordError}
)}
- - {/* 操作按钮 */}