mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-12-19 13:10:16 +08:00
feat: 禁止默认密码
This commit is contained in:
parent
e4c1807f76
commit
e406dca7ae
@ -33,6 +33,14 @@ export default class WebUIManager {
|
||||
return data.data
|
||||
}
|
||||
|
||||
public static async changePasswordFromDefault(newToken: string) {
|
||||
const { data } = await serverRequest.post<ServerResponse<boolean>>(
|
||||
'/auth/update_token',
|
||||
{ newToken, fromDefault: true }
|
||||
)
|
||||
return data.data
|
||||
}
|
||||
|
||||
public static async checkUsingDefaultToken() {
|
||||
const { data } = await serverRequest.get<ServerResponse<boolean>>(
|
||||
'/auth/check_using_default_token'
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { Input } from '@heroui/input'
|
||||
import { useLocalStorage } from '@uidotdev/usehooks'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Controller, useForm } from 'react-hook-form'
|
||||
import toast from 'react-hot-toast'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
@ -11,6 +12,9 @@ import SaveButtons from '@/components/button/save_buttons'
|
||||
import WebUIManager from '@/controllers/webui_manager'
|
||||
|
||||
const ChangePasswordCard = () => {
|
||||
const [isDefaultToken, setIsDefaultToken] = useState<boolean>(false)
|
||||
const [isLoadingCheck, setIsLoadingCheck] = useState<boolean>(true)
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit: handleWebuiSubmit,
|
||||
@ -29,9 +33,32 @@ const ChangePasswordCard = () => {
|
||||
const navigate = useNavigate()
|
||||
const [_, setToken] = useLocalStorage(key.token, '')
|
||||
|
||||
// 检查是否使用默认密码
|
||||
useEffect(() => {
|
||||
const checkDefaultToken = async () => {
|
||||
try {
|
||||
const isDefault = await WebUIManager.checkUsingDefaultToken()
|
||||
setIsDefaultToken(isDefault)
|
||||
} catch (error) {
|
||||
console.error('检查默认密码状态失败:', error)
|
||||
} finally {
|
||||
setIsLoadingCheck(false)
|
||||
}
|
||||
}
|
||||
|
||||
checkDefaultToken()
|
||||
}, [])
|
||||
|
||||
const onSubmit = handleWebuiSubmit(async (data) => {
|
||||
try {
|
||||
if (isDefaultToken) {
|
||||
// 从默认密码更新
|
||||
await WebUIManager.changePasswordFromDefault(data.newToken)
|
||||
} else {
|
||||
// 正常密码更新
|
||||
await WebUIManager.changePassword(data.oldToken, data.newToken)
|
||||
}
|
||||
|
||||
toast.success('修改成功')
|
||||
setToken('')
|
||||
localStorage.removeItem(key.token)
|
||||
@ -42,9 +69,30 @@ const ChangePasswordCard = () => {
|
||||
}
|
||||
})
|
||||
|
||||
if (isLoadingCheck) {
|
||||
return (
|
||||
<>
|
||||
<title>修改密码 - NapCat WebUI</title>
|
||||
<div className="flex justify-center items-center h-32">
|
||||
<div className="text-center">加载中...</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<title>修改密码 - NapCat WebUI</title>
|
||||
|
||||
{isDefaultToken && (
|
||||
<div className="mb-4 p-3 bg-warning-50 border border-warning-200 rounded-lg">
|
||||
<p className="text-warning-700 text-sm">
|
||||
检测到您正在使用默认密码,为了安全起见,请立即设置新密码。
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!isDefaultToken && (
|
||||
<Controller
|
||||
control={control}
|
||||
name="oldToken"
|
||||
@ -57,18 +105,21 @@ const ChangePasswordCard = () => {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Controller
|
||||
control={control}
|
||||
name="newToken"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
{...field}
|
||||
label="新密码"
|
||||
placeholder="请输入新密码"
|
||||
label={isDefaultToken ? "设置新密码" : "新密码"}
|
||||
placeholder={isDefaultToken ? "请设置一个安全的新密码" : "请输入新密码"}
|
||||
type="password"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<SaveButtons
|
||||
onSubmit={onSubmit}
|
||||
reset={reset}
|
||||
|
||||
@ -25,7 +25,6 @@ export default function WebLoginPage() {
|
||||
const [tokenValue, setTokenValue] = useState<string>(token || '')
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false)
|
||||
const [, setLocalToken] = useLocalStorage<string>(key.token, '')
|
||||
|
||||
const onSubmit = async () => {
|
||||
if (!tokenValue) {
|
||||
toast.error('请输入token')
|
||||
|
||||
@ -93,11 +93,16 @@ export const checkHandler: RequestHandler = async (req, res) => {
|
||||
|
||||
// 修改密码(token)
|
||||
export const UpdateTokenHandler: RequestHandler = async (req, res) => {
|
||||
const { oldToken, newToken } = req.body;
|
||||
const { oldToken, newToken, fromDefault } = req.body;
|
||||
const authorization = req.headers.authorization;
|
||||
|
||||
if (isEmpty(oldToken) || isEmpty(newToken)) {
|
||||
return sendError(res, 'oldToken or newToken is empty');
|
||||
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');
|
||||
}
|
||||
|
||||
try {
|
||||
@ -108,7 +113,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 });
|
||||
} else {
|
||||
// 正常的密码更新流程
|
||||
await WebUiConfig.UpdateToken(oldToken, newToken);
|
||||
}
|
||||
|
||||
return sendSuccess(res, 'Token updated successfully');
|
||||
} catch (e: any) {
|
||||
return sendError(res, `Failed to update token: ${e.message}`);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user