Convert ~160 raw res.json()/res.status().json() calls across 32+ files
to use centralized helpers from src/utils/responses.js (ok, errorResponse,
successMessage, notFound, validationError, forbidden, unauthorized, conflict).
No behavior changes — response shapes are identical. Future schema changes
(e.g., requestId envelope) only need to update one module.
Fix error vs errorResponse signature mismatch in routes/health.js CA cert
endpoint where error(res, message, statusCode) was being called with
errorResponse(res, statusCode, message, extras) argument order.
Files changed: middleware.js, csrf-protection.js, error-handler.js,
license-manager.js, src/app.js, and 27 route files.
Test suite: 755 pass / 4 pre-existing failures (services credential tests).
Cross-platform hardening — removes all hardcoded /app/ paths from route files
and routes them through platform-paths.js so the app works the same way
regardless of Docker layout (single-file mount vs consolidated data dir).
Changes:
- platform-paths.js: add generatedCertsDir, pkiDir, containerUpdatesDir,
containerFrontendDir, containerAssetsDir, resolveAssetsPath()
- self-updater.js: UPDATE_URL/MIRROR_URL/CHANNEL env var overrides
- routes/ca.js: use platformPaths for cert paths and generated certs dir
- routes/services.js: use platformPaths.pkiRootCert
- routes/themes.js: derive THEMES_DIR from platformPaths.servicesFile
- routes/config/assets.js + backup.js: use resolveAssetsPath() fallback
- routes/services.js + src/app.js: use platformPaths.pkiRootCert
- server.js: HOST env var support, parse PORT as int
- src/app.js: GET /api/v1/version (public, no auth), global request timeout,
disable x-powered-by, trust proxy
- pylon/dashcaddy-pylon.js: PYLON_HOST env var, graceful shutdown on SIGTERM/SIGINT
A fresh user can now deploy with a custom Docker layout (e.g. /opt/dc/data/
as a single volume mount) and the app finds its files automatically, no env
var configuration required.
Server export now includes encryption key, themes, and all config files.
Client export bundles all DashCaddy localStorage keys (19 named + dynamic
widget keys) as browserState. Restore handles both server and browser
state in one operation. Legacy v1.0 import format still supported.
Removed redundant Export/Import toolbar buttons — Backup modal is now
the single entry point.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Full codebase including API server (32 modules + routes), dashboard frontend,
DashCA certificate distribution, installer script, and deployment skills.