- health.js: replace magic number 5000 with TIMEOUTS.HTTP_DEFAULT (twice)
- services.js: replace magic number 5000 with TIMEOUTS.HTTP_DEFAULT
Both files already import TIMEOUTS from constants but weren't using it.
- monitoring.js: Added log dependency, replaced console.log with log.warn
- themes.js: Added log dependency, replaced console.error with log.error
- src/app.js: Pass log to monitoringRoutes and themesRoutes
This fixes error messages being lost to stdout instead of proper log files.
- Container exec/shell via WebSocket + xterm.js (subtle >_ button on cards)
- Live dashboard updates via SSE (resource alerts, health changes, update notices)
- Docker Compose import with YAML parsing, preview, and dependency-ordered deploy
- Volume & network management modal with disk usage overview
- CPU/memory resource limits on deploy and live update
- Email SMTP notifications (nodemailer) alongside Discord/Telegram/ntfy
- Scheduled auto-update scheduler with maintenance windows (daily/weekly/monthly)
New deps: ws, js-yaml, nodemailer
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Phase 2.1 refactor wrapped success() responses as { success, data: {...} }
but the frontend expects flat responses like { success, license: {...} }.
This caused license to show FREE TIER and broke other API consumers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
These endpoints must be accessible without TOTP auth for the dashboard
to load site config (TLD, DNS servers, custom logo) and service status
(bulk probe results). Without them, the dashboard shows all services
as OFF and loses custom branding after any session expiry.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
100 requests/15min was far too low for a dashboard with auto-refresh
polling every 10-30 seconds, causing 429s on TOTP config, site config,
license status and other endpoints after ~3 minutes of normal use.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
License status, services list, config, and license feature checks
were being rate-limited (429) after ~14 minutes of dashboard polling,
causing the license to show FREE TIER and services to fail loading.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove redundant ctx shim that conflicted with function parameter
- Use destructured notification/safeErrorMessage directly
- Add pylon, customLogoDark, customLogoLight to known config keys
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The lightweight probe endpoint used by the dashboard for live status
checks had no Pylon integration. When DNS2 (Singapore) tried to probe
home network services directly, all probes timed out with 502. Now
falls back to the configured Pylon relay before the domain fallback.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The modular refactor changed function signatures to destructured deps but
left internal ctx.* references intact, causing "ctx is not defined" errors
on /api/config, /api/logo, and many other endpoints. Also implements
loadTotpConfig and saveTotpConfig which were left as stubs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add missing fetchT dep to session-handlers.js (fixes ctx is not
defined error that broke jellyfin/emby/plex/syncthing SSO)
- Replace all ctx.fetchT calls with direct fetchT usage
- Remove server-old.js (69K monolith backup) from tracking
- Remove AI-generated doc artifacts from repo root
- Update .gitignore to prevent re-adding these files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolve conflict in server.js by accepting the remote's modular
refactor (1960 lines → 230 lines). Local Phase 1/2 changes
(logger swap, unused import) are superseded by the new structure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Create src/config/paths.js for all file paths and env vars
- Create src/config/site.js for site configuration loading
- Create src/config/index.js as unified config export
- Prepare for server.js modularization (Phase 2.1)
Part of deslopification roadmap: break 1997-line server.js into layers
- Consolidated all error classes into single errors.js
- Removed duplicate error definitions (NotFoundError, etc.)
- Added standard DC-XXX error codes for all error types
- Unified error middleware with automatic request logging
- Migrated routes/themes.js to throw-based error pattern
- Updated routes/services.js to use ConflictError
- Cleaner server.js error handler registration
- 40% less error handling boilerplate in routes
- Consistent error response format across all endpoints
- Replaced god object ctx with explicit dependency injection
- Added JSDoc documenting required dependencies (8 deps vs 50+)
- Updated response calls to use response-helpers (success/error)
- Self-documenting: you can see exactly what this route needs
- Health checks, pylon relay, CA cert validation all preserved
- Replaced god object ctx with explicit dependency injection
- Added JSDoc documenting all required dependencies
- Updated response calls to use response-helpers (success/error)
- Maintained all existing functionality
- Self-documenting: you can see exactly what this route needs
- Easier testing: mock only what's actually used (14 deps vs 50+ ctx properties)
- serviceUrl() now checks service.url before falling back to buildServiceUrl(id)
- Service update no longer overwrites ID with the new subdomain
- Accept "localhost" as valid IP in service update validation
- Find services by ID or URL match when updating
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The dashboard uses /api/v1/services/status (not /api/health/services)
for live status cards. This endpoint was missing pylon relay fallback,
so services unreachable from the Docker container showed as OFF even
when the pylon was running. Also adds Windows VBS startup wrapper for
pylon persistence across reboots.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DashCaddy Pylon is a lightweight probe agent that runs on remote
networks to relay health checks for services the main DashCaddy
instance can't reach directly (e.g., .sami domains, LAN IPs).
- Standalone zero-dependency Node.js script (pylon/dashcaddy-pylon.js)
- Optional API key auth, HEAD→GET fallback, batch probe support
- Health routes now try direct check first, fall back to pylon relay
- New endpoints: /health/probe (act as pylon), /health/pylon (status)
- Config: add "pylon": { "url": "...", "key": "..." } to config.json
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>