From c0431e3dc2681916502b72a5f5afcd86f134852b Mon Sep 17 00:00:00 2001 From: bietiaop <1527109126@qq.com> Date: Wed, 29 Jan 2025 20:40:23 +0800 Subject: [PATCH] feat(webui_api): update token --- src/webui/src/api/Auth.ts | 16 +++++++++++++ src/webui/src/helper/config.ts | 41 +++++++++++++++++++++++++++++----- src/webui/src/router/auth.ts | 4 +++- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/webui/src/api/Auth.ts b/src/webui/src/api/Auth.ts index 370261a7..b29f743c 100644 --- a/src/webui/src/api/Auth.ts +++ b/src/webui/src/api/Auth.ts @@ -62,3 +62,19 @@ export const checkHandler: RequestHandler = async (req, res) => { return sendError(res, 'Authorization Faild'); } }; + +// 修改密码(token) +export const UpdateTokenHandler: RequestHandler = async (req, res) => { + const { oldToken, newToken } = req.body; + + if (isEmpty(oldToken) || isEmpty(newToken)) { + return sendError(res, 'oldToken or newToken is empty'); + } + + try { + await WebUiConfig.UpdateToken(oldToken, newToken); + return sendSuccess(res, 'Token updated successfully'); + } catch (e: any) { + return sendError(res, `Failed to update token: ${e.message}`); + } +}; diff --git a/src/webui/src/helper/config.ts b/src/webui/src/helper/config.ts index 2ad61b47..9f1f08b1 100644 --- a/src/webui/src/helper/config.ts +++ b/src/webui/src/helper/config.ts @@ -68,7 +68,15 @@ export class WebUiConfigWrapper { WebUiConfigData: WebUiConfigType | undefined = undefined; private applyDefaults(obj: Partial, defaults: T): T { - return { ...defaults, ...obj }; + const result = { ...defaults } as T; + for (const key in obj) { + if (obj[key] && typeof obj[key] === 'object' && !Array.isArray(obj[key])) { + result[key] = this.applyDefaults(obj[key], defaults[key]); + } else if (obj[key] !== undefined) { + result[key] = obj[key] as T[Extract]; + } + } + return result; } async GetWebUIConfig(): Promise { @@ -99,10 +107,8 @@ export class WebUiConfigWrapper { } const fileContent = await fs.readFile(configPath, 'utf-8'); - // 更新配置字段后新增字段可能会缺失,同步一下 const parsedConfig = this.applyDefaults(JSON.parse(fileContent) as Partial, defaultconfig); - // 配置已经被操作过了,还是回写一下吧,不然新配置不会出现在配置文件里 if ( await fs .access(configPath, constants.W_OK) @@ -113,9 +119,7 @@ export class WebUiConfigWrapper { } else { console.warn(`文件: ${configPath} 没有写入权限, 配置的更改部分可能会在重启后还原.`); } - // 不希望回写的配置放后面 - // 查询主机地址是否可用 const [host_err, host] = await tryUseHost(parsedConfig.host) .then((data) => [null, data]) .catch((err) => [err, null]); @@ -124,7 +128,6 @@ export class WebUiConfigWrapper { parsedConfig.port = 0; // 设置为0,禁用WebUI } else { parsedConfig.host = host; - // 修正端口占用情况 const [port_err, port] = await tryUsePort(parsedConfig.port, parsedConfig.host) .then((data) => [null, data]) .catch((err) => [err, null]); @@ -143,6 +146,32 @@ export class WebUiConfigWrapper { return defaultconfig; // 理论上这行代码到不了,到了只能返回默认配置了 } + async UpdateWebUIConfig(newConfig: Partial): Promise { + const configPath = resolve(webUiPathWrapper.configPath, './webui.json'); + const currentConfig = await this.GetWebUIConfig(); + const updatedConfig = this.applyDefaults(newConfig, currentConfig); + + if ( + await fs + .access(configPath, constants.W_OK) + .then(() => true) + .catch(() => false) + ) { + await fs.writeFile(configPath, JSON.stringify(updatedConfig, null, 4)); + this.WebUiConfigData = updatedConfig; + } else { + console.warn(`文件: ${configPath} 没有写入权限, 配置的更改部分可能会在重启后还原.`); + } + } + + async UpdateToken(oldToken: string, newToken: string): Promise { + const currentConfig = await this.GetWebUIConfig(); + if (currentConfig.token !== oldToken) { + throw new Error('旧 token 不匹配'); + } + await this.UpdateWebUIConfig({ token: newToken }); + } + // 获取日志文件夹路径 public static async GetLogsPath(): Promise { return resolve(webUiPathWrapper.logsPath); diff --git a/src/webui/src/router/auth.ts b/src/webui/src/router/auth.ts index 45d32dd2..4ab3a89b 100644 --- a/src/webui/src/router/auth.ts +++ b/src/webui/src/router/auth.ts @@ -1,6 +1,6 @@ import { Router } from 'express'; -import { checkHandler, LoginHandler, LogoutHandler } from '@webapi/api/Auth'; +import { checkHandler, LoginHandler, LogoutHandler, UpdateTokenHandler } from '@webapi/api/Auth'; const router = Router(); // router:登录 @@ -9,5 +9,7 @@ router.post('/login', LoginHandler); router.post('/check', checkHandler); // router:注销 router.post('/logout', LogoutHandler); +// router:更新token +router.post('/update_token', UpdateTokenHandler); export { router as AuthRouter };