From 320f21c113401d630b15b9e52884af5f06f0e322 Mon Sep 17 00:00:00 2001 From: Hermes Date: Wed, 10 Jun 2026 19:05:07 -0700 Subject: [PATCH] fix: credential-manager and crypto-utils auto-resolve data directory paths The CREDENTIALS_FILE and ENCRYPTION_KEY_FILE env vars defaulted to __dirname/credentials.json and __dirname/.encryption-key, which works for the standard install (where individual files are mounted to /app/) but breaks for deployments using a consolidated data directory at /app/data/. Add resolveCredentialsFile() and resolveKeyFile() helpers that: 1. Honor explicit env var if set 2. Check /app/credentials.json and /app/data/credentials.json 3. Check /app/.encryption-key and /app/data/.encryption-key 4. Default to standard path for new installs This makes DashCaddy deployable with either pattern without requiring custom env var configuration, which is essential for general-public reproducibility. --- dashcaddy-api/credential-manager.js | 21 ++++++++++++++++++++- dashcaddy-api/crypto-utils.js | 22 ++++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/dashcaddy-api/credential-manager.js b/dashcaddy-api/credential-manager.js index 8acdeb1..56782e2 100644 --- a/dashcaddy-api/credential-manager.js +++ b/dashcaddy-api/credential-manager.js @@ -10,7 +10,26 @@ const lockfile = require('proper-lockfile'); const fs = require('fs'); const path = require('path'); -const CREDENTIALS_FILE = process.env.CREDENTIALS_FILE || path.join(__dirname, 'credentials.json'); +// Resolve credentials file path — supports both standard install (/app/credentials.json) +// and custom deployments with consolidated data directory (/app/data/credentials.json) +function resolveCredentialsFile() { + if (process.env.CREDENTIALS_FILE) { + return process.env.CREDENTIALS_FILE; + } + const candidates = [ + path.join(__dirname, 'credentials.json'), + path.join(__dirname, 'data', 'credentials.json'), + ]; + for (const candidate of candidates) { + if (fs.existsSync(candidate)) { + return candidate; + } + } + // No existing file — return standard path so first store() creates it there + return candidates[0]; +} + +const CREDENTIALS_FILE = resolveCredentialsFile(); class CredentialManager { constructor() { diff --git a/dashcaddy-api/crypto-utils.js b/dashcaddy-api/crypto-utils.js index 49fb7f9..3e76f25 100644 --- a/dashcaddy-api/crypto-utils.js +++ b/dashcaddy-api/crypto-utils.js @@ -15,8 +15,26 @@ const IV_LENGTH = 16; // 128 bits for GCM const AUTH_TAG_LENGTH = 16; const SALT_LENGTH = 32; -// Key file location (should be outside of mounted volumes for security) -const KEY_FILE = process.env.ENCRYPTION_KEY_FILE || path.join(__dirname, '.encryption-key'); +// Resolve encryption key file path — supports both standard install (/app/.encryption-key) +// and custom deployments with consolidated data directory (/app/data/.encryption-key) +function resolveKeyFile() { + if (process.env.ENCRYPTION_KEY_FILE) { + return process.env.ENCRYPTION_KEY_FILE; + } + const candidates = [ + path.join(__dirname, '.encryption-key'), + path.join(__dirname, 'data', '.encryption-key'), + ]; + for (const candidate of candidates) { + if (fs.existsSync(candidate)) { + return candidate; + } + } + // No existing file — return standard path so first load creates it there + return candidates[0]; +} + +const KEY_FILE = resolveKeyFile(); let encryptionKey = null;