mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-03-03 09:10:25 +00:00
Set bypass defaults to disabled and simplify loading: napcat.json default bypass flags changed to false and code now reads bypass options without merging a prior "all enabled" default. Removed the progressive bypass-disable logic and related environment variable usage, and added a log when Napi2NativeLoader enables bypasses. Web UI/backend adjustments: default NapCat config is now generated from the AJV schema; the bypass settings UI defaults to false, adds an o3HookMode toggle, and submits o3HookMode as 0/1. UX fixes: extension tabs made horizontally scrollable with fixed tab sizing, and plugin uninstall flow updated to a single confirmation dialog with an optional checkbox to remove plugin config. Overall changes aim to use safer defaults, simplify crash/restart behavior, and improve configuration and UI clarity.
91 lines
2.8 KiB
TypeScript
91 lines
2.8 KiB
TypeScript
import { RequestHandler } from 'express';
|
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
import { resolve } from 'node:path';
|
|
import { webUiPathWrapper } from '@/napcat-webui-backend/index';
|
|
import { sendError, sendSuccess } from '@/napcat-webui-backend/src/utils/response';
|
|
import json5 from 'json5';
|
|
|
|
import Ajv from 'ajv';
|
|
import { NapcatConfigSchema } from '@/napcat-core/helper/config';
|
|
|
|
// 动态获取 NapCat 配置默认值
|
|
function getDefaultNapcatConfig (): Record<string, unknown> {
|
|
const ajv = new Ajv({ useDefaults: true, coerceTypes: true });
|
|
const validate = ajv.compile(NapcatConfigSchema);
|
|
const data = {};
|
|
validate(data);
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* 获取 napcat 配置文件路径
|
|
*/
|
|
function getNapcatConfigPath (): string {
|
|
return resolve(webUiPathWrapper.configPath, './napcat.json');
|
|
}
|
|
|
|
/**
|
|
* 读取 napcat 配置
|
|
*/
|
|
function readNapcatConfig (): Record<string, unknown> {
|
|
const configPath = getNapcatConfigPath();
|
|
try {
|
|
if (existsSync(configPath)) {
|
|
const content = readFileSync(configPath, 'utf-8');
|
|
return { ...getDefaultNapcatConfig(), ...json5.parse(content) };
|
|
}
|
|
} catch (_e) {
|
|
// 读取失败,使用默认值
|
|
}
|
|
return { ...getDefaultNapcatConfig() };
|
|
}
|
|
|
|
/**
|
|
* 写入 napcat 配置
|
|
*/
|
|
function writeNapcatConfig (config: Record<string, unknown>): void {
|
|
const configPath = resolve(webUiPathWrapper.configPath, './napcat.json');
|
|
mkdirSync(webUiPathWrapper.configPath, { recursive: true });
|
|
writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
}
|
|
|
|
// 获取 NapCat 配置
|
|
export const NapCatGetConfigHandler: RequestHandler = (_, res) => {
|
|
try {
|
|
const config = readNapcatConfig();
|
|
return sendSuccess(res, config);
|
|
} catch (e) {
|
|
return sendError(res, 'Config Get Error: ' + (e as Error).message);
|
|
}
|
|
};
|
|
|
|
// 设置 NapCat 配置
|
|
export const NapCatSetConfigHandler: RequestHandler = (req, res) => {
|
|
try {
|
|
const newConfig = req.body;
|
|
if (!newConfig || typeof newConfig !== 'object') {
|
|
return sendError(res, 'config is empty or invalid');
|
|
}
|
|
|
|
// 读取当前配置并合并
|
|
const currentConfig = readNapcatConfig();
|
|
const mergedConfig = { ...currentConfig, ...newConfig };
|
|
|
|
// 验证 bypass 字段
|
|
if (mergedConfig.bypass && typeof mergedConfig.bypass === 'object') {
|
|
const bypass = mergedConfig.bypass as Record<string, unknown>;
|
|
const validKeys = ['hook', 'window', 'module', 'process', 'container', 'js'];
|
|
for (const key of validKeys) {
|
|
if (key in bypass && typeof bypass[key] !== 'boolean') {
|
|
return sendError(res, `bypass.${key} must be boolean`);
|
|
}
|
|
}
|
|
}
|
|
|
|
writeNapcatConfig(mergedConfig);
|
|
return sendSuccess(res, null);
|
|
} catch (e) {
|
|
return sendError(res, 'Config Set Error: ' + (e as Error).message);
|
|
}
|
|
};
|