fix(config): lazy-evaluate paths, fix TOCTOU, segment-boundary cloud detection

- Convert 4 module-level constants to lazy-evaluated functions to avoid
  import-time caching: openrouter-catalog, aggregator, disk-cache, auth-middleware
- Fix symlink-checks.ts to use ccsDir parameter instead of homedir/.ccs,
  remove unused homedir parameter from checkSettingsSymlinks()
- Replace TOCTOU existsSync+statSync with single statSync in try/catch
  for --config-dir validation in ccs.ts
- Switch detectCloudSyncPath from substring to path-segment-boundary matching
  to prevent false positives (e.g., megauser != MEGA, Dropbox-api != Dropbox)
- Add test for false-positive protection
This commit is contained in:
Tam Nhu Tran
2026-02-11 11:24:34 +07:00
parent 60d6bbd027
commit d5abc7d691
9 changed files with 55 additions and 36 deletions
+7 -5
View File
@@ -8,7 +8,9 @@ import * as path from 'path';
import { getCcsDir } from '../../utils/config-manager';
const OPENROUTER_API_URL = 'https://openrouter.ai/api/v1/models';
const CACHE_FILE = path.join(getCcsDir(), 'openrouter-models-cache.json');
function getCacheFile() {
return path.join(getCcsDir(), 'openrouter-models-cache.json');
}
const CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
export interface OpenRouterModel {
@@ -30,8 +32,8 @@ interface CacheData {
/** Check if cached data is valid */
function getCachedModels(): OpenRouterModel[] | null {
try {
if (!fs.existsSync(CACHE_FILE)) return null;
const data = JSON.parse(fs.readFileSync(CACHE_FILE, 'utf8')) as CacheData;
if (!fs.existsSync(getCacheFile())) return null;
const data = JSON.parse(fs.readFileSync(getCacheFile(), 'utf8')) as CacheData;
if (Date.now() - data.fetchedAt > CACHE_TTL_MS) return null;
return data.models;
} catch {
@@ -42,10 +44,10 @@ function getCachedModels(): OpenRouterModel[] | null {
/** Save models to cache */
function setCachedModels(models: OpenRouterModel[]): void {
try {
const dir = path.dirname(CACHE_FILE);
const dir = path.dirname(getCacheFile());
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
fs.writeFileSync(
CACHE_FILE,
getCacheFile(),
JSON.stringify({
models,
fetchedAt: Date.now(),