更新安全配置项目
This commit is contained in:
+147
-153
@@ -2,32 +2,30 @@ import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
export interface DBConfig {
|
||||
host: string;
|
||||
port: number;
|
||||
user: string;
|
||||
password: string;
|
||||
database: string;
|
||||
host: string;
|
||||
port: number;
|
||||
user: string;
|
||||
password: string;
|
||||
database: string;
|
||||
}
|
||||
|
||||
export interface AIConfig {
|
||||
apiKey: string;
|
||||
baseUrl: string;
|
||||
model: string;
|
||||
apiKey: string;
|
||||
baseUrl: string;
|
||||
model: string;
|
||||
}
|
||||
|
||||
export interface ExportConfig {
|
||||
// 未翻译文本的颜色 (hex)
|
||||
untranslatedColor: string;
|
||||
// 第二页是否显示表头
|
||||
secondPageHeader: boolean;
|
||||
// 页面方向: portrait | landscape
|
||||
orientation: "portrait" | "landscape";
|
||||
// 未翻译文本的颜色 (hex)
|
||||
untranslatedColor: string;
|
||||
// 页面方向: portrait | landscape
|
||||
orientation: "portrait" | "landscape";
|
||||
}
|
||||
|
||||
export interface AppConfig {
|
||||
db: DBConfig;
|
||||
ai: AIConfig;
|
||||
export: ExportConfig;
|
||||
db: DBConfig;
|
||||
ai: AIConfig;
|
||||
export: ExportConfig;
|
||||
}
|
||||
|
||||
// 配置文件路径(单一文件)
|
||||
@@ -37,29 +35,29 @@ const configPath = path.join(process.cwd(), "config.json");
|
||||
* 检查配置文件是否存在
|
||||
*/
|
||||
function configFileExists(): boolean {
|
||||
return fs.existsSync(configPath);
|
||||
return fs.existsSync(configPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取完整配置(仅从 config.json)
|
||||
*/
|
||||
function readConfigFile(): Partial<AppConfig> {
|
||||
try {
|
||||
if (configFileExists()) {
|
||||
const content = fs.readFileSync(configPath, "utf-8");
|
||||
return JSON.parse(content);
|
||||
try {
|
||||
if (configFileExists()) {
|
||||
const content = fs.readFileSync(configPath, "utf-8");
|
||||
return JSON.parse(content);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Config read error:", e);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Config read error:", e);
|
||||
}
|
||||
return {};
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入完整配置
|
||||
*/
|
||||
function writeConfigFile(config: AppConfig): void {
|
||||
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
|
||||
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,185 +65,181 @@ function writeConfigFile(config: AppConfig): void {
|
||||
* 从环境变量读取初始值写入 config.json
|
||||
*/
|
||||
function initConfigFromEnv(): AppConfig {
|
||||
const initialConfig: AppConfig = {
|
||||
db: {
|
||||
host: process.env.DB_HOST || "127.0.0.1",
|
||||
port: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 3306,
|
||||
user: process.env.DB_USER || "root",
|
||||
password: process.env.DB_PASSWORD || "",
|
||||
database: process.env.DB_NAME || "recipe_tools",
|
||||
},
|
||||
ai: {
|
||||
apiKey: process.env.AI_API_KEY || "",
|
||||
baseUrl: process.env.AI_BASE_URL || "https://api.openai.com/v1",
|
||||
model: process.env.AI_MODEL || "gpt-3.5-turbo",
|
||||
},
|
||||
export: {
|
||||
untranslatedColor: process.env.EXPORT_UNTRANSLATED_COLOR || "CC0000",
|
||||
secondPageHeader: process.env.EXPORT_SECOND_PAGE_HEADER === "true",
|
||||
orientation: (process.env.EXPORT_ORIENTATION as "portrait" | "landscape") || "landscape",
|
||||
},
|
||||
};
|
||||
const initialConfig: AppConfig = {
|
||||
db: {
|
||||
host: process.env.DB_HOST || "127.0.0.1",
|
||||
port: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 3306,
|
||||
user: process.env.DB_USER || "root",
|
||||
password: process.env.DB_PASSWORD || "",
|
||||
database: process.env.DB_NAME || "recipe_tools",
|
||||
},
|
||||
ai: {
|
||||
apiKey: process.env.AI_API_KEY || "",
|
||||
baseUrl: process.env.AI_BASE_URL || "https://api.openai.com/v1",
|
||||
model: process.env.AI_MODEL || "gpt-3.5-turbo",
|
||||
},
|
||||
export: {
|
||||
untranslatedColor: process.env.EXPORT_UNTRANSLATED_COLOR || "CC0000",
|
||||
orientation: (process.env.EXPORT_ORIENTATION as "portrait" | "landscape") || "landscape",
|
||||
},
|
||||
};
|
||||
|
||||
writeConfigFile(initialConfig);
|
||||
return initialConfig;
|
||||
writeConfigFile(initialConfig);
|
||||
return initialConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据库配置(仅从 config.json)
|
||||
*/
|
||||
export function getDBConfig(): DBConfig {
|
||||
// 如果配置文件不存在,从环境变量初始化
|
||||
if (!configFileExists()) {
|
||||
return initConfigFromEnv().db;
|
||||
}
|
||||
// 如果配置文件不存在,从环境变量初始化
|
||||
if (!configFileExists()) {
|
||||
return initConfigFromEnv().db;
|
||||
}
|
||||
|
||||
const fileConfig = readConfigFile();
|
||||
const defaultConfig: DBConfig = {
|
||||
host: "127.0.0.1",
|
||||
port: 3306,
|
||||
user: "root",
|
||||
password: "",
|
||||
database: "recipe_tools",
|
||||
};
|
||||
|
||||
if (fileConfig.db) {
|
||||
return {
|
||||
host: fileConfig.db.host || defaultConfig.host,
|
||||
port: fileConfig.db.port || defaultConfig.port,
|
||||
user: fileConfig.db.user || defaultConfig.user,
|
||||
password: fileConfig.db.password ?? defaultConfig.password,
|
||||
database: fileConfig.db.database || defaultConfig.database,
|
||||
const fileConfig = readConfigFile();
|
||||
const defaultConfig: DBConfig = {
|
||||
host: "127.0.0.1",
|
||||
port: 3306,
|
||||
user: "root",
|
||||
password: "",
|
||||
database: "recipe_tools",
|
||||
};
|
||||
}
|
||||
|
||||
return defaultConfig;
|
||||
if (fileConfig.db) {
|
||||
return {
|
||||
host: fileConfig.db.host || defaultConfig.host,
|
||||
port: fileConfig.db.port || defaultConfig.port,
|
||||
user: fileConfig.db.user || defaultConfig.user,
|
||||
password: fileConfig.db.password ?? defaultConfig.password,
|
||||
database: fileConfig.db.database || defaultConfig.database,
|
||||
};
|
||||
}
|
||||
|
||||
return defaultConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取AI翻译配置(仅从 config.json)
|
||||
*/
|
||||
export function getAIConfig(): AIConfig {
|
||||
// 如果配置文件不存在,从环境变量初始化
|
||||
if (!configFileExists()) {
|
||||
return initConfigFromEnv().ai;
|
||||
}
|
||||
// 如果配置文件不存在,从环境变量初始化
|
||||
if (!configFileExists()) {
|
||||
return initConfigFromEnv().ai;
|
||||
}
|
||||
|
||||
const fileConfig = readConfigFile();
|
||||
const defaultConfig: AIConfig = {
|
||||
apiKey: "",
|
||||
baseUrl: "https://api.openai.com/v1",
|
||||
model: "gpt-3.5-turbo",
|
||||
};
|
||||
|
||||
if (fileConfig.ai) {
|
||||
return {
|
||||
apiKey: fileConfig.ai.apiKey ?? defaultConfig.apiKey,
|
||||
baseUrl: fileConfig.ai.baseUrl || defaultConfig.baseUrl,
|
||||
model: fileConfig.ai.model || defaultConfig.model,
|
||||
const fileConfig = readConfigFile();
|
||||
const defaultConfig: AIConfig = {
|
||||
apiKey: "",
|
||||
baseUrl: "https://api.openai.com/v1",
|
||||
model: "gpt-3.5-turbo",
|
||||
};
|
||||
}
|
||||
|
||||
return defaultConfig;
|
||||
if (fileConfig.ai) {
|
||||
return {
|
||||
apiKey: fileConfig.ai.apiKey ?? defaultConfig.apiKey,
|
||||
baseUrl: fileConfig.ai.baseUrl || defaultConfig.baseUrl,
|
||||
model: fileConfig.ai.model || defaultConfig.model,
|
||||
};
|
||||
}
|
||||
|
||||
return defaultConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取导出配置(仅从 config.json)
|
||||
*/
|
||||
export function getExportConfig(): ExportConfig {
|
||||
// 如果配置文件不存在,从环境变量初始化
|
||||
if (!configFileExists()) {
|
||||
return initConfigFromEnv().export;
|
||||
}
|
||||
// 如果配置文件不存在,从环境变量初始化
|
||||
if (!configFileExists()) {
|
||||
return initConfigFromEnv().export;
|
||||
}
|
||||
|
||||
const fileConfig = readConfigFile();
|
||||
const defaultConfig: ExportConfig = {
|
||||
untranslatedColor: "CC0000",
|
||||
secondPageHeader: false,
|
||||
orientation: "landscape",
|
||||
};
|
||||
|
||||
if (fileConfig.export) {
|
||||
return {
|
||||
untranslatedColor: fileConfig.export.untranslatedColor || defaultConfig.untranslatedColor,
|
||||
secondPageHeader: fileConfig.export.secondPageHeader ?? defaultConfig.secondPageHeader,
|
||||
orientation: fileConfig.export.orientation || defaultConfig.orientation,
|
||||
const fileConfig = readConfigFile();
|
||||
const defaultConfig: ExportConfig = {
|
||||
untranslatedColor: "CC0000",
|
||||
orientation: "landscape",
|
||||
};
|
||||
}
|
||||
|
||||
return defaultConfig;
|
||||
if (fileConfig.export) {
|
||||
return {
|
||||
untranslatedColor: fileConfig.export.untranslatedColor || defaultConfig.untranslatedColor,
|
||||
orientation: fileConfig.export.orientation || defaultConfig.orientation,
|
||||
};
|
||||
}
|
||||
|
||||
return defaultConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取完整配置
|
||||
*/
|
||||
export function getAllConfig(): AppConfig {
|
||||
// 如果配置文件不存在,从环境变量初始化
|
||||
if (!configFileExists()) {
|
||||
return initConfigFromEnv();
|
||||
}
|
||||
// 如果配置文件不存在,从环境变量初始化
|
||||
if (!configFileExists()) {
|
||||
return initConfigFromEnv();
|
||||
}
|
||||
|
||||
return {
|
||||
db: getDBConfig(),
|
||||
ai: getAIConfig(),
|
||||
export: getExportConfig(),
|
||||
};
|
||||
return {
|
||||
db: getDBConfig(),
|
||||
ai: getAIConfig(),
|
||||
export: getExportConfig(),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存AI翻译配置
|
||||
*/
|
||||
export function saveAIConfig(config: Partial<AIConfig>): AIConfig {
|
||||
// 确保配置文件存在
|
||||
if (!configFileExists()) {
|
||||
initConfigFromEnv();
|
||||
}
|
||||
// 确保配置文件存在
|
||||
if (!configFileExists()) {
|
||||
initConfigFromEnv();
|
||||
}
|
||||
|
||||
const current = getAIConfig();
|
||||
const current = getAIConfig();
|
||||
|
||||
const newConfig: AIConfig = {
|
||||
apiKey: config.apiKey ?? current.apiKey,
|
||||
baseUrl: config.baseUrl ?? current.baseUrl,
|
||||
model: config.model ?? current.model,
|
||||
};
|
||||
const newConfig: AIConfig = {
|
||||
apiKey: config.apiKey ?? current.apiKey,
|
||||
baseUrl: config.baseUrl ?? current.baseUrl,
|
||||
model: config.model ?? current.model,
|
||||
};
|
||||
|
||||
// 读取现有配置,更新 ai 部分
|
||||
const fileConfig = readConfigFile();
|
||||
const updatedConfig: AppConfig = {
|
||||
db: fileConfig.db ?? { host: "127.0.0.1", port: 3306, user: "root", password: "", database: "recipe_tools" },
|
||||
export: fileConfig.export ?? { untranslatedColor: "CC0000", secondPageHeader: false, orientation: "landscape" },
|
||||
ai: newConfig,
|
||||
};
|
||||
writeConfigFile(updatedConfig);
|
||||
// 读取现有配置,更新 ai 部分
|
||||
const fileConfig = readConfigFile();
|
||||
const updatedConfig: AppConfig = {
|
||||
db: fileConfig.db ?? {host: "127.0.0.1", port: 3306, user: "root", password: "", database: "recipe_tools"},
|
||||
export: fileConfig.export ?? {untranslatedColor: "CC0000", orientation: "landscape"},
|
||||
ai: newConfig,
|
||||
};
|
||||
writeConfigFile(updatedConfig);
|
||||
|
||||
return newConfig;
|
||||
return newConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存导出配置
|
||||
*/
|
||||
export function saveExportConfig(config: Partial<ExportConfig>): ExportConfig {
|
||||
// 确保配置文件存在
|
||||
if (!configFileExists()) {
|
||||
initConfigFromEnv();
|
||||
}
|
||||
// 确保配置文件存在
|
||||
if (!configFileExists()) {
|
||||
initConfigFromEnv();
|
||||
}
|
||||
|
||||
const current = getExportConfig();
|
||||
const current = getExportConfig();
|
||||
|
||||
const newConfig: ExportConfig = {
|
||||
untranslatedColor: config.untranslatedColor ?? current.untranslatedColor,
|
||||
secondPageHeader: config.secondPageHeader ?? current.secondPageHeader,
|
||||
orientation: config.orientation ?? current.orientation,
|
||||
};
|
||||
const newConfig: ExportConfig = {
|
||||
untranslatedColor: config.untranslatedColor ?? current.untranslatedColor,
|
||||
orientation: config.orientation ?? current.orientation,
|
||||
};
|
||||
|
||||
// 读取现有配置,更新 export 部分
|
||||
const fileConfig = readConfigFile();
|
||||
const updatedConfig: AppConfig = {
|
||||
db: fileConfig.db ?? { host: "127.0.0.1", port: 3306, user: "root", password: "", database: "recipe_tools" },
|
||||
ai: fileConfig.ai ?? { apiKey: "", baseUrl: "https://api.openai.com/v1", model: "gpt-3.5-turbo" },
|
||||
export: newConfig,
|
||||
};
|
||||
writeConfigFile(updatedConfig);
|
||||
// 读取现有配置,更新 export 部分
|
||||
const fileConfig = readConfigFile();
|
||||
const updatedConfig: AppConfig = {
|
||||
db: fileConfig.db ?? {host: "127.0.0.1", port: 3306, user: "root", password: "", database: "recipe_tools"},
|
||||
ai: fileConfig.ai ?? {apiKey: "", baseUrl: "https://api.openai.com/v1", model: "gpt-3.5-turbo"},
|
||||
export: newConfig,
|
||||
};
|
||||
writeConfigFile(updatedConfig);
|
||||
|
||||
return newConfig;
|
||||
return newConfig;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user