修复底层配置服务混乱的问题

This commit is contained in:
cc
2026-04-29 23:59:56 +08:00
parent 7469337aeb
commit 1fc710ccef
10 changed files with 131 additions and 196 deletions

View File

@@ -1,14 +1,13 @@
import { dirname, join } from 'path'
import { join } from 'path'
import { app, safeStorage } from 'electron'
import crypto from 'crypto'
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs'
import Store from 'electron-store'
import { expandHomePath } from '../utils/pathUtils'
import { getElectronSafeStorage, getPathFallback, isWorkerRuntime } from './electronRuntime'
// 加密前缀标记
const SAFE_PREFIX = 'safe:' // safeStorage 加密(普通模式)
const isSafeStorageAvailable = (): boolean => {
try {
const safeStorage = getElectronSafeStorage()
return typeof safeStorage?.isEncryptionAvailable === 'function' && safeStorage.isEncryptionAvailable()
} catch {
return false
@@ -113,68 +112,6 @@ interface ConfigSchema {
aiInsightDebugLogEnabled: boolean
}
interface ConfigStoreLike<T extends Record<string, any>> {
get<K extends keyof T>(key: K): T[K]
set<K extends keyof T>(key: K, value: T[K]): void
clear(): void
store: T
}
function cloneJson<T>(value: T): T {
return JSON.parse(JSON.stringify(value))
}
class JsonConfigStore<T extends Record<string, any>> implements ConfigStoreLike<T> {
private readonly filePath: string
private readonly defaults: T
private data: T
constructor(options: { name: string; defaults: T; cwd?: string }) {
const baseDir = options.cwd || getPathFallback('userData')
mkdirSync(baseDir, { recursive: true })
this.filePath = join(baseDir, `${options.name}.json`)
this.defaults = cloneJson(options.defaults)
this.data = cloneJson(options.defaults)
this.load()
}
get store(): T {
return this.data
}
private load(): void {
try {
if (!existsSync(this.filePath)) return
const raw = readFileSync(this.filePath, 'utf8')
const parsed = JSON.parse(raw)
if (parsed && typeof parsed === 'object') {
this.data = { ...cloneJson(this.defaults), ...parsed }
}
} catch {
this.data = cloneJson(this.defaults)
}
}
private persist(): void {
mkdirSync(dirname(this.filePath), { recursive: true })
writeFileSync(this.filePath, JSON.stringify(this.data), 'utf8')
}
get<K extends keyof T>(key: K): T[K] {
return this.data[key]
}
set<K extends keyof T>(key: K, value: T[K]): void {
this.data[key] = value
this.persist()
}
clear(): void {
this.data = cloneJson(this.defaults)
this.persist()
}
}
// 需要 safeStorage 加密的字段(普通模式)
const ENCRYPTED_STRING_KEYS: Set<string> = new Set([
'decryptKey',
@@ -194,7 +131,7 @@ const LOCKABLE_NUMBER_KEYS: Set<string> = new Set(['imageXorKey'])
export class ConfigService {
private static instance: ConfigService
private store!: ConfigStoreLike<ConfigSchema>
private store!: Store<ConfigSchema>
// 锁定模式运行时状态
private unlockedKeys: Map<string, any> = new Map()
@@ -288,17 +225,36 @@ export class ConfigService {
aiInsightDebugLogEnabled: false
}
const cwd = String(process.env.WEFLOW_CONFIG_CWD || process.env.WEFLOW_USER_DATA_PATH || '').trim()
this.store = new JsonConfigStore<ConfigSchema>({
const storeOptions: any = {
name: 'WeFlow-config',
defaults,
cwd: cwd || undefined
})
if (!isWorkerRuntime()) {
this.migrateAuthFields()
this.migrateAiConfig()
projectName: String(process.env.WEFLOW_PROJECT_NAME || 'WeFlow').trim() || 'WeFlow'
}
const runningInWorker = process.env.WEFLOW_WORKER === '1'
if (runningInWorker) {
const cwd = String(process.env.WEFLOW_CONFIG_CWD || process.env.WEFLOW_USER_DATA_PATH || '').trim()
if (cwd) {
storeOptions.cwd = cwd
}
}
try {
this.store = new Store<ConfigSchema>(storeOptions)
} catch (error) {
const message = String((error as Error)?.message || error || '')
if (message.includes('projectName')) {
const fallbackOptions = {
...storeOptions,
projectName: 'WeFlow',
cwd: storeOptions.cwd || process.env.WEFLOW_CONFIG_CWD || process.env.WEFLOW_USER_DATA_PATH || process.cwd()
}
this.store = new Store<ConfigSchema>(fallbackOptions)
} else {
throw error
}
}
this.migrateAuthFields()
this.migrateAiConfig()
}
// === 状态查询 ===
@@ -400,8 +356,6 @@ export class ConfigService {
if (!plaintext) return ''
if (plaintext.startsWith(SAFE_PREFIX)) return plaintext
if (!isSafeStorageAvailable()) return plaintext
const safeStorage = getElectronSafeStorage()
if (!safeStorage) return plaintext
const encrypted = safeStorage.encryptString(plaintext)
return SAFE_PREFIX + encrypted.toString('base64')
}
@@ -410,8 +364,6 @@ export class ConfigService {
if (!stored) return ''
if (!stored.startsWith(SAFE_PREFIX)) return stored
if (!isSafeStorageAvailable()) return ''
const safeStorage = getElectronSafeStorage()
if (!safeStorage) return ''
try {
const buf = Buffer.from(stored.slice(SAFE_PREFIX.length), 'base64')
return safeStorage.decryptString(buf)
@@ -879,7 +831,7 @@ export class ConfigService {
if (workerUserDataPath) {
return workerUserDataPath
}
return getPathFallback('userData')
return app?.getPath?.('userData') || process.cwd()
}
getCacheBasePath(): string {