From 1e6367a147dddb323799a3cd1947507c595d21db Mon Sep 17 00:00:00 2001 From: Anso Date: Wed, 25 Mar 2026 01:03:22 -0400 Subject: [PATCH] fix(env): resolve 404 when loading env files and CSP inline script violation (#134) The /envs endpoint now filters to only return env files that actually exist on disk, and absolute env_file paths from compose files (e.g. shared globals.env in a sibling directory) are no longer rejected. The inline theme-detection script is moved to an external file to comply with CSP. --- CHANGELOG.md | 7 +++++++ backend/src/index.ts | 27 +++++++++++++++++++-------- frontend/index.html | 13 +------------ frontend/public/theme-init.js | 10 ++++++++++ 4 files changed, 37 insertions(+), 20 deletions(-) create mode 100644 frontend/public/theme-init.js diff --git a/CHANGELOG.md b/CHANGELOG.md index ff83bfe9..8a415b93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Fixed + +* **env:** fix 404 when loading env files for stacks with `env_file` paths outside the stack directory (e.g. shared `globals.env`). The `/envs` endpoint now only returns files that exist on disk, and absolute `env_file` paths from compose files are no longer rejected. +* **csp:** fix Content Security Policy violation caused by inline theme-detection script. Moved to an external `theme-init.js` file so it is covered by `script-src 'self'`. + ## [0.2.2](https://github.com/AnsoCode/Sencho/compare/v0.2.1...v0.2.2) (2026-03-25) diff --git a/backend/src/index.ts b/backend/src/index.ts index 41dbb6dd..dedfd781 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -847,11 +847,6 @@ async function resolveAllEnvFilePaths(nodeId: number, stackName: string): Promis const addEnvPath = (rawPath: string) => { const resolved = path.resolve(stackDir, rawPath); - // Reject paths that escape the stack directory - if (!resolved.startsWith(path.resolve(stackDir) + path.sep) && resolved !== path.resolve(stackDir)) { - console.warn(`[Security] env_file path "${rawPath}" escapes stack directory — skipping`); - return; - } envFiles.add(resolved); }; @@ -866,15 +861,31 @@ async function resolveAllEnvFilePaths(nodeId: number, stackName: string): Promis } if (envFiles.size === 0) { - return [defaultEnvPath]; + envFiles.add(defaultEnvPath); } - return Array.from(envFiles); + // Filter to only include files that actually exist on disk + const existing: string[] = []; + for (const f of envFiles) { + try { + await fsService.access(f); + existing.push(f); + } catch { + // File does not exist — skip + } + } + return existing; } catch (error) { console.warn(`Could not parse compose.yaml for env_file resolution in stack "${stackName}":`, error); } - return [defaultEnvPath]; + // Fallback: return default only if it exists + try { + await fsService.access(defaultEnvPath); + return [defaultEnvPath]; + } catch { + return []; + } } app.get('/api/stacks/:stackName/envs', async (req: Request, res: Response) => { diff --git a/frontend/index.html b/frontend/index.html index 42884c56..bbed42c6 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -9,18 +9,7 @@ - + diff --git a/frontend/public/theme-init.js b/frontend/public/theme-init.js new file mode 100644 index 00000000..91e5f5f4 --- /dev/null +++ b/frontend/public/theme-init.js @@ -0,0 +1,10 @@ +(function () { + try { + var saved = localStorage.getItem('sencho-theme'); + if (saved === 'light') { + document.documentElement.classList.remove('dark'); + } else { + document.documentElement.classList.add('dark'); + } + } catch (e) { } +})();