- src/context/caddy.js: Caddyfile manipulation, reload, config generation
- src/context/dns.js: DNS API wrapper with token management
- All context modules use factory pattern with explicit dependencies
- src/context/caddy.js: Caddyfile manipulation, reload, config generation
- Uses dependency injection (init() pattern) for siteConfig, log, fetchT
- Atomic mutex-based modifications with rollback on failure
- All Caddy operations now in one module
- src/utils/logger.js: Structured JSON logging
- src/context/docker.js: Docker API wrapper (pull, findContainer, getUsedPorts)
- All modules can now be imported directly instead of via ctx
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>
DNS server IDs (dns1, dns2, dns3) were hardcoded throughout the frontend
and backend. Now config.json's dnsServers object is the single source of
truth — adding or removing a DNS server in config automatically updates
the dashboard cards, credential modal, health checks, and probes.
- credentials.js: rebuild modal sections dynamically from SITE.dnsServers
- globals.js: add getPrimaryDnsId() helper for primary DNS lookups
- service-create.js, service-infrastructure.js: use dynamic DNS ID
- startup-validator.js: dynamic topCardServices from config
- middleware.js: add license endpoints to public routes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add url-resolver.js with single resolveServiceUrl() used by all 5 consumers
(probes, health routes, health checker auto-config)
- Health checker now does full sync (add/update/remove) instead of add-only,
and re-syncs automatically after every services.json mutation
- docker-maintenance and log-digest are now optional imports with try/catch,
preventing container crashes when these files are absent
- Add null guards in routes/logs.js for graceful 503 responses
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Mount Tailscale router at /tailscale prefix so all 10 routes resolve
to /api/tailscale/* as expected by middleware, audit logger, and
frontend. Previously 5 routes (status, config, check-connection,
devices, protect-service) resolved to /api/* instead, with config
colliding with the settings route. Strip redundant /tailscale/ prefix
from OAuth routes that were compensating for the missing mount prefix.
Increase default health check timeout from 10s to 20s to reduce false
positives on slower services.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Added automatic volume path translation in deployment (deploy.js)
- Updated FileBrowser template to use /opt/ instead of hard-coded E:/
- Migrated self-updater.js to use centralized platformPaths module
- Updated UI placeholders to use platform-neutral paths (/media/)
- All paths now automatically adapt to Windows or Linux at runtime via process.platform detection
Prevents Docker disk bloat by adding log rotation (10MB max, 3 files)
to all container creation and update paths, auto-pruning dangling
images after deploy/remove/update, and a daily maintenance module
that cleans build cache and warns on disk thresholds.
Saves a deployment manifest in services.json at deploy time so users
can restore all their apps after a Docker purge. Adds restore-all
and restore-single endpoints that recreate containers, Caddy config,
and DNS records from the saved manifests.
Adds an hourly log collector and daily digest generator that
summarizes errors, warnings, and events across all services into
a single human-readable report with guidance on where to investigate.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Changed hardcoded secure:true to req.secure || req.protocol === 'https'
- Allows CSRF cookies to work over HTTP on localhost
- Still enforces secure flag for HTTPS connections
- Enables OpenClaw programmatic API access
Server-side batched /api/v1/services/status endpoint replaces N
individual browser probes with a single API call (HEAD-first with
GET fallback, concurrency-limited, CA-aware HTTPS agent).
Frontend: clock reuses DOM instead of rebuilding innerHTML every
second with drift-correcting timer that pauses on hidden tabs.
Card animations use CSS transitionDelay + requestAnimationFrame.
Internet dot blink moved from JS intervals to CSS keyframes with
prefers-reduced-motion support. Service worker rewritten with
network-first navigation, stale-while-revalidate assets, and
navigation preload. Font faces drop TTF fallbacks, use font-display
swap.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix container-to-host path mapping in trigger.json (stagingDir
was using container path /app/updates/ instead of host path
/opt/dashcaddy/updates/)
- Fix download race condition: primary download's async unlink
could delete mirror download's file — use unlinkSync before retry
- Fix DASHCADDY_COMMIT build arg not passed to docker compose build
(was set as env var, now uses --build-arg)
- Remove MakeDirectory=yes from systemd path unit (was creating
trigger.json as directory instead of file)
- Remove unused 'tar' npm module import
- Add mirror fallback for tarball downloads (not just version checks)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- self-updater.js: polls for new versions, downloads/verifies tarballs,
triggers host-side rebuild via systemd path unit
- dashcaddy-update.sh + systemd units: host-side container rebuild with
automatic rollback on health check failure
- 7 new /api/v1/system/* endpoints for version info, update check/apply,
rollback, and update history
- Frontend: DashCaddy tab in Updates modal with version display,
changelog, update button, rollback, and notification dot
- install.sh: updater service installation, volume mounts, env vars
- build-release.sh + webhook-handler.js: release server pipeline
(Gitea webhook → build tarball → deploy to get.dashcaddy.net)
- Dockerfile: DASHCADDY_COMMIT build arg → VERSION file
- Version bump to 1.1.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Escape all innerHTML assignments with user/external data across 12 JS files
- Upgrade credential encryption: per-value IV, key moved to sessionStorage
- Fix open redirect in TOTP auth via proper URL hostname validation
- Remove sensitive DNS topology data from localStorage cache
- Add security regression test suite (51 tests)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- CSRF: HMAC-signed double-submit cookie (server-bound, not raw compare)
- Keychain: execFileSync with arg arrays to prevent command injection
- Caddy config: always use structured generation, never accept raw config
- Templates: replace {{GENERATED_SECRET}} with crypto.randomBytes
- Caddyfile removal: move regex inside ctx.caddy.modify() to fix TOCTOU race
- Credentials: proper-lockfile for all file operations, fix key rotation
to decrypt with old key before generating new key
- Service removal: filter by ID only, not AND with appTemplate
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Deploy endpoint: validate appId, config, and subdomain before use (prevents 500 crash on empty body)
- Container ops: return 404 instead of 500 for non-existent containers
- Update-subdomain: require oldSubdomain/newSubdomain fields (prevents false 200 with undefined values)
- Global error handler: catch-all that never leaks stack traces or internal paths
- API 404 catch-all: return JSON instead of HTML for unmatched /api/* routes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Apps can now be served at domain.com/appname/ instead of requiring
subdomain DNS records (appname.domain.com). Supports three subpath
modes per template: native (URL base env var), strip (handle_path),
and none (incompatible warning). Tested on Linux with deploy/removal
lifecycle verified.
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.