mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-11 19:26:56 +00:00
fix(stacks): harden stack management with security, validation, and logging (#520)
* fix(stacks): harden stack management with security fixes, validation alignment, and logging Validate WebSocket stack names with isValidStackName() to close a path-traversal gap on the /api/stacks/:stackName/logs WS endpoint. Align POST /api/stacks to use the canonical validator (allows underscores). Replace error: any catch blocks with error: unknown + type narrowing. Add cache invalidation to PUT /api/stacks/:stackName/env. Rename DELETE param from :name to :stackName for consistency. Add standard [Stacks] lifecycle logs and diagnostic [Stacks:debug] logs gated behind the Developer Mode toggle (with 5s TTL cache). Extract shared isDebugEnabled() and getErrorMessage() utilities. Frontend: roll back optimistic status on API failure, guard unsaved changes when switching stacks, pre-check duplicate names in App Store. * docs(settings): update Developer Mode description to mention debug diagnostics
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Shared diagnostic logging gate.
|
||||
*
|
||||
* Reads `developer_mode` from the global settings, cached for a short
|
||||
* window so hot paths (per-request, per-log-line) do not hit SQLite
|
||||
* on every call.
|
||||
*/
|
||||
|
||||
let cachedValue = false;
|
||||
let cacheExpiry = 0;
|
||||
const CACHE_TTL_MS = 5_000;
|
||||
|
||||
export function isDebugEnabled(): boolean {
|
||||
const now = Date.now();
|
||||
if (now < cacheExpiry) return cachedValue;
|
||||
|
||||
try {
|
||||
// Dynamic require avoids circular-dependency issues when this
|
||||
// utility is imported from services that DatabaseService itself
|
||||
// depends on, and prevents SQLite side effects during tests.
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const { DatabaseService } = require('../services/DatabaseService');
|
||||
cachedValue = DatabaseService.getInstance().getGlobalSettings().developer_mode === '1';
|
||||
} catch {
|
||||
cachedValue = false;
|
||||
}
|
||||
|
||||
cacheExpiry = now + CACHE_TTL_MS;
|
||||
return cachedValue;
|
||||
}
|
||||
Reference in New Issue
Block a user