Commit Graph
249 Commits
Author SHA1 Message Date
Krystie ef855e3fd7 build: bump SW cache to dashcaddy-shell-f6673e7190
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
Forces clients to pull the rebuilt core.js bundle that includes
totp-recovery.js.
2026-06-18 19:57:38 -07:00
Krystie 3dff49cdc5 feat(status): TOTP recovery UI - panel, backup download, always-visible Import
- status/js/totp-recovery.js: NEW. Wires up recovery panel on the TOTP
  gate. Pastes Base32 -> /api/v1/totp/setup -> /verify-setup -> session.
  Exposes window._refreshRecoveryLink() called by totp-auth.js.
- status/js/totp-auth.js: showTotpOverlay() now calls
  _refreshRecoveryLink() so the recovery link hides when TOTP is healthy
  and appears when it's broken.
- status/js/totp-settings.js: removed setupSection.style.display='none'
  so 'Import existing secret' is always visible; added 'Download backup
  file' button after setup that exports the Base32 + recovery
  instructions as JSON.
- status/index.html: added 'Lost access? Recover with saved Base32
  key ->' link to the TOTP overlay plus the recovery panel itself;
  added title tooltip to the auth card reminding users to save the
  Base32 on first setup.
- status/build.js: include JS('totp-recovery.js') in the core bundle
  after totp-auth.js (since recovery registers a hook auth calls).
2026-06-18 19:56:52 -07:00
Krystie d230b39948 feat(totp): 4-part defense against permanent lockout
- credential-manager.js: add diagnose(key) method that distinguishes
  ok | missing | unreadable | corrupt instead of silently returning null
- crypto-utils.js: silent fallback to .encryption-key.bak when primary
  can't decrypt existing credentials; first-run bootstrap writes .bak;
  rotateKey() backs up old key before swap
- routes/auth/totp.js: new public /api/v1/totp/recovery-info endpoint
  returns {status, isSetUp, hint} so UI can show meaningful errors
- middleware.js: add /totp/recovery-info to PUBLIC_ROUTES so the
  locked-out user can read the diagnostic without being logged in
2026-06-18 19:56:45 -07:00
Hermes 7bbd969fa2 fix: rebuild bundle with widget, restore TOTP across container recreate, integrate auto-updater changes
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
Three logical changes grouped:

1. Widget bundle rebuild + sami-files logo (from previous session)
   - status/dist/{init,core,features,onboarding}.js rebuilt from latest source
   - status/sw.js cache bumped to dashcaddy-shell-594ec75648 to force SW refresh
   - status/assets/sami-files.png added (Sami Files service card logo)

2. status/build.js: include monitoring-widgets.js in bundle
   - The original build.js was missing monitoring-widgets.js from its JS()
     bundle list — that's why the System Overview widget never showed up
     in the live init.js until we ran the live /var/www/dashcaddy-status/
     build.js. Now consistent.

3. dashcaddy-api/scripts/dashcaddy-update.sh restart_container(): preserve
   TOTP secret across container recreates
   - Was only setting SERVICES_FILE; container fell back to image-local
     /app/credentials.json + /app/.encryption-key (auto-generated fresh
     every recreate), which broke TOTP for the bind-mounted secret at
     /app/data/credentials.json
   - Added CREDENTIALS_FILE + ENCRYPTION_KEY_FILE env vars pointing at
     /app/data/ so the container reads from the bind-mounted host data dir
   - See skill: software-development/dashcaddy/references/totp-and-system-overview-pitfalls.md §9

4. Auto-updater integration (pulled from upstream release):
   - dashcaddy-api/VERSION: dev → c64bbe2
   - dashcaddy-api/health-checker.js, middleware.js, package.json,
     routes/backups.js, src/app.js: new release code (bundled workflows,
     /api/auth/ → /api/v1/ back-compat rewrite, backup storage limits)
2026-06-18 19:23:30 -07:00
Hermes 4f377970d7 chore: ignore runtime data + scratch files, remove dead root routes/
Working tree accumulated 172 untracked/modified files from the auto-updater:
- 19 secret/runtime files in dashcaddy-api/data/ that should never be tracked
- 199 byte-identical duplicates of tracked files dumped at root by an
  outdated rsync/cp step
- 6 scratch debug scripts (cm_check.js, login_test.js, full_test.js, ...)
- 7 .bak-* files from start.sh and dashcaddy-update.sh rollback branches
- Root-level routes/ directory: dead code, container COPYs dashcaddy-api/routes/

.gitignore now ignores:
  - dashcaddy-api/data/          (runtime: credentials, secrets, history)
  - start.sh.bak*, scripts/*.bak* (auto-updater rollback backups)
  - updates/                      (auto-updater runtime state)
  - cm_check*.js, *_test.js       (scratch debug scripts)

Removed dead code:
  - routes/openclaw.js            (replaced by dashcaddy-api/routes/openclaw.js)

Recreated runtime scripts that were deleted with their duplicates:
  - start.sh                      (canonical container-start, 47-line full config)
  - scripts/dashcaddy-update.sh was already untracked; fixed the tracked
    dashcaddy-api/scripts/dashcaddy-update.sh instead (see next commit)

Net change: 172 → 17 files in working tree.
2026-06-18 19:23:02 -07:00
Hermes 7f0d43943c feat: restore monitoring widget + add sami-files template
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
- Recreate status/js/monitoring-widgets.js with robust services count
  (reads from window.APPS, #cards DOM, then live fetch as fallback)
- Add sami-files service to data/services.json (Sami Files card)
- Add sami-files template to app-templates.js under 'Files' category
  with full systemd deployment docs and Caddy snippet
- Bundle monitoring-widgets.js into init.js
2026-06-18 18:52:48 -07:00
Hermes 7bc2a207f3 DC-005: Fix all 138 broken test paths after src/ refactor
After the DC-005 module reorganization (41 files moved into src/ subdirs),
138 test suites failed because the refactor script's path-rewrite logic
missed three categories:

1. Files inside src/ doing 'require("./src/...")' — should be 'require("../...")'
2. Files in src/X/Y/ doing 'require("../../../src/...")' — should be 'require("../../...")'
3. Test files in __tests__/ with leftover 'require("../../../src/...")' paths

Root cause: the original refactor script ran before all files were moved,
so it computed relative paths against stale filesystem state.

Result:
- 30/30 test suites pass
- 879/879 tests pass (was: 18/30 suites, 614/687 tests)

Also fixed:
- routes/apps/restore.js: wrong responses import path
- routes/*/*.js: '../../src/utilities/X' → '../src/utilities/X' (depth 2 routes)
2026-06-13 12:16:56 -07:00
Hermes 9468dfc0eb DC-005/DC-006: claim as in-progress (krystie) 2026-06-13 11:56:58 -07:00
Hermes 6025f68b22 DC-004: Fix all 19 ESLint warnings (zero remaining)
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
Removed unused imports (path, validateStartupConfig, platformPaths),
renamed unused destructures (_timeout, _logEntry), replaced nested
ternaries with lookup tables, added eslint-disable comments on
require-await functions that are intentionally async for API stability,
and extracted helper functions to reduce max-depth and complexity in
app.js, dns.js, provider-dns.js, and site.js. All 879 tests pass.
2026-06-13 11:53:18 -07:00
Hermes f96e903710 DC-007: Add smoke tests for 7 untested modules
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
2026-06-13 11:38:51 -07:00
Hermes 5b1d631870 DC-004 (partial): 19→15 ESLint warnings — fixed logging.js & http.js
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
Fixed:
- src/utils/logging.js: removed unused path import, split nested ternary, renamed unused logEntry → _logEntry
- src/utils/http.js: renamed unused timeout destructure → _timeout, split both nested ternaries in getSetCookie (replace_all accidentally renamed one _httpFetch, restored)

Remaining 15 warnings:
- 4 require-await (async functions kept for API consistency — add eslint-disable comments)
- 4 max-depth nesting
- 2 complexity (loadSiteConfig, getProviderConfig)
- 1 unused platformPaths in config/migrations.js
- 1 in logging.js (ternary not detected as fixed — needs review)
- 1 in http.js (same)

All 759 tests still pass.
2026-06-13 11:22:07 -07:00
Hermes e32f11b83e DC-003: Move stale debug test scripts to scripts/legacy/
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
comprehensive-test.js and test-security-fixes.js are 875 lines of
ad-hoc security test scripts (not Jest tests). They have zero references
in code or docs. Moved to scripts/legacy/ to declutter repo root
without losing the content. All 759 Jest tests still pass.
2026-06-13 11:15:12 -07:00
Hermes 4c60ed1ccf DC-002: Sync root VERSION with package.json + keep them in sync via release.sh
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
- Updated root VERSION file from 1.13.0 → 1.13.4 to match package.json.
- scripts/release.sh now writes both files on every release bump, and
  stages VERSION alongside package.json in the release commit.
- This prevents the drift that caused the stale VERSION in the first place.
2026-06-13 11:13:54 -07:00
Hermes d12a9a3cfa DC-001: mark done, claim DC-002
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
2026-06-13 11:12:37 -07:00
Hermes 2580c65074 DC-001: Fix 4 failing services.routes tests - add /services/ prefix to credential routes
The 3 credential endpoints (POST/DELETE/GET /:serviceId/credentials) were missing
the /services/ path segment, causing 404s when tests called /api/services/<id>/credentials.

Fixed routes now match the URL pattern used by the live frontend
(/api/v1/services/<id>/credentials) and the test suite.

All 759 tests pass.
2026-06-13 11:12:14 -07:00
Hermes 8e703d9c4c DC-001: claim for Hermes
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
2026-06-13 05:26:57 -07:00
Hermes 8ef5e4a9a4 Add shared BACKLOG.md for Hermes+Krystie collaborative improvements
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
2026-06-13 05:22:59 -07:00
Hermes 53680c4c74 v1.13.4: Standardize all route responses to use response helpers
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
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).
v1.13.4
2026-06-11 00:48:13 -07:00
Hermes 2d394d882d Standardize response shapes and fix dead fetchT timeout keys
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
Three small cleanups for v1.14.0:

1. /caddy/cas now uses standard success envelope
   Was: { status: 'success', data: { cas: caList } }
   Now: { success: true, cas: caList }
   Updated frontend service-infrastructure.js to match.

2. /api/health/ca now uses standard envelope + meaningful HTTP codes
   Was: { status, message, daysUntilExpiration } with 200 on every error
   Now: { success, caStatus, message|error, daysUntilExpiration }
        with 200 / 404 / 500 as appropriate
   caStatus field preserves the original 'healthy'/'warning'/'critical'/'error'
   semantic so any future consumer of the CA-health state still has it.
   Tests updated to match.

3. Dead timeout: keys in fetchT opts are now a warning, not a silent strip
   src/utils/http.js:41 used to do  without telling
   anyone. Callers that wrote fetchT(url, { timeout: 5000 }) got the default
   5s timeout with no indication that their explicit value was ignored.
   Now it logs a warning naming the call site, then strips the key.
   Fixed 4 call sites that had stale timeout: keys:
   - src/context/caddy.js
   - src/context/dns.js
   - src/context/provider-dns.js
   - routes/dns.js (2 places)
v1.13.3
2026-06-10 21:52:33 -07:00
Hermes 11cfb8c26a Consolidate response helpers and error logger to single modules
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
Two cleanups in one pass for the v1.14.0 'works on any platform' theme:

1. Response helpers — merged src/utils/responses.js and the root-level
   response-helpers.js into a single module at src/utils/responses.js.
   The old module had a richer set (created, noContent, validationError,
   unauthorized, forbidden, notFound, conflict) and is now re-exported
   from the new location. Updated 15 routes to import from
   src/utils/responses and deleted the root response-helpers.js.

2. Error logger — error-handler.js now uses the unified
   src/utils/logging.js#logError (same one src/app.js uses), so all errors
   go to one log file with one rotation policy. Removed the dead
   asyncHandler export (the real one is in src/utils/async-handler.js
   and is used everywhere). Deleted the legacy error-logger.js.

Both are invisible to users — same HTTP response shapes, same log file
path, same error format. Internal-only refactor.
v1.13.2
2026-06-10 21:37:55 -07:00
Hermes caa09dcebe Bump to v1.13.1 - fix /health/ready res.status bug
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
The readiness probe was using asyncHandler directly, but this codebase's
asyncHandler has signature (logError, fn, context) — first arg is the logger.
Switched to boundAsyncHandler which is what every other route in src/app.js
uses. Verified working on both DNS2 (Docker) and Contabo (systemd).

8 new tests in __tests__/health-endpoints.test.js verify both endpoints.
v1.13.1
2026-06-10 21:12:37 -07:00
Hermes 264de9644c Fix /health/ready res.status bug + add comprehensive health endpoint tests
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
The readiness probe was crashing with 'res.status is not a function' because
asyncHandler(async (req, res) => {...}, 'health-ready') was called directly,
but asyncHandler's signature is (logError, fn, context) — first arg is the
logger, not the handler. The fix uses boundAsyncHandler like all other routes
in the file do.

Added 8 unit tests for both /health/live and /health/ready:
- live always 200 (liveness ≠ readiness)
- ready returns 503 when config/services/docker fail
- no 'res.status is not a function' crash when dependencies fail
- all 4 check keys present in response

Also added MONITORING_PUBLIC env var (defaults true) and the new health
endpoints to PUBLIC_ROUTES so k8s probes can hit them without auth.
2026-06-10 20:35:27 -07:00
Hermes e40cb35011 Add MONITORING_PUBLIC env var to gate monitoring endpoints behind auth
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
By default /api/v1/monitoring/stats and /api/v1/health-checks/status are
public (current behavior, dashboard needs them pre-login). Users deploying
DashCaddy on the open internet can now set:

  MONITORING_PUBLIC=false

...or add 'monitoring: { public: false }' to config.json to require auth.
This prevents anonymous disclosure of CPU/memory/disk data.

The check uses env var first, then config.json, then defaults to true
(preserves current behavior for existing users).
2026-06-10 20:13:53 -07:00
Hermes 7485772427 Bump to v1.13.0 - config migration system
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
v1.13.0
2026-06-10 20:06:46 -07:00
Hermes e5d7da6edd Add config migration system
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
When config.json schema changes between versions, register a migration
function in src/config/migrations.js. On startup, loadSiteConfig() detects
the stored version, runs all migrations forward, and writes the result back.
Users never see the migration — it runs silently and the rest of the app
only ever sees the current schema.

Includes:
- v0 → v1: normalize dns from string to object
- v1 → v2: add dns.provider field (default 'technitium')
- Forward compat: configs from future versions left untouched
- Idempotent: re-running on already-migrated config is a no-op
- Safe: no user data is removed during migration

21 unit tests covering edge cases: null input, forward compat, corrupt
JSON, missing parent dirs, idempotency, full migration chain.
2026-06-10 20:06:09 -07:00
Hermes 28f0fa3c10 Add /api/v1/version to PUBLIC_ROUTES
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
2026-06-10 19:55:19 -07:00
Hermes eee32c1eae Fix missing platform-paths import in routes/services.js
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
2026-06-10 19:47:52 -07:00
Hermes 37a3282f98 Bump to v1.12.0 - cross-platform standardization
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
v1.12.0
2026-06-10 19:36:30 -07:00
Hermes 1fbe65f524 Standardize paths, add version endpoint, request timeouts, HOST env var, graceful shutdown
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
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.
2026-06-10 19:36:05 -07:00
Hermes 320f21c113 fix: credential-manager and crypto-utils auto-resolve data directory paths
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
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.
2026-06-10 19:05:07 -07:00
Hermes 5c76c3df97 fix: System Overview widget - expose monitoring/health endpoints publicly + fix data formats
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
- Add /api/v1/monitoring/stats and /api/v1/health-checks/status to PUBLIC_ROUTES
  so the frontend widget can fetch without auth
- Transform monitoring stats response from nested {cpu:{percent}} to flat
  {cpu: number, memory: number, memoryUsage: number} for the widget
- Add summary {healthy, unhealthy, total} to health-checks/status response
2026-06-10 18:24:30 -07:00
Hermes 260575c6bd fix: wrap createContainer with user-friendly DC-201 error for missing images
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
2026-06-10 17:39:37 -07:00
Hermes e361d9a328 fix: increase pull timeout to 300s, add missing environment:{} to portainer + uptime-kuma templates
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
v1.11.0
2026-06-10 17:05:28 -07:00
Hermes aa25bcc053 fix: always expose DC-prefixed errors to users in safeErrorMessage
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
2026-06-10 17:02:13 -07:00
Hermes bda08b592e fix: idempotent Caddy subpath config, increase Docker pull timeout to 120s, extend health check to 60s
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
- helpers.js: treat 'No changes to apply' as success (config already exists = idempotent)
- constants.js: Docker pull timeout 30s → 120s (large images need more time)
- deploy.js: health check 40s → 60s (some apps like filebrowser are slow to start)
2026-06-10 16:43:34 -07:00
Hermes 0e408974a0 fix: harden deploy error handling - guard against undefined errors, safeErrorMessage null check
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
- deploy.js: wrap logError/notification in try/catch so they never mask the original deploy error
- deploy.js: use optional chaining for error.message access
- logging.js: safeErrorMessage handles null/undefined error gracefully
2026-06-10 16:39:14 -07:00
Hermes f4b35dcc30 fix: correct apps route mount paths - mount all sub-routers at /apps prefix to match frontend API calls
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
2026-06-10 16:28:41 -07:00
Hermes 1c0d765182 fix: app route path nesting (deploy/remove/templates), server.js fetchT import, lifetime license expiry, workflows path prefix
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
- routes/apps/index.js: mount sub-routers at '/' to avoid double-nesting (was /deploy/deploy, now /deploy)
- server.js: add fetchT import for workflow engine init
- license-manager.js: fix isExpired() for lifetime licenses (null expiresAt → always expired)
- src/app.js: add '/workflows' path prefix to prevent requirePremium gating all routes
- app-templates.js: fix 10 templates missing volumes/healthCheck
- routes/apps/index.js: add e.stack to error logging for better debugging
2026-06-10 16:20:51 -07:00
Hermes 2cd62208ac fix: workflows route mounted without path prefix — blocked all API on free tier; fix 10 app templates missing fields 2026-06-10 15:40:00 -07:00
Hermes 7557a6364a ops: add host-side update script to repo, include dns-providers/ in backup/deploy/restore paths
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
2026-06-10 15:18:48 -07:00
Hermes 54c4b049a8 fix: include dns-providers/ in Docker image build 2026-06-10 15:11:14 -07:00
Hermes 2de72ed506 feat: DNS provider abstraction — Technitium, Cloudflare, RFC 2136, Manual
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
- dns-providers/: adapter base class + registry with auto-discovery
- technitium.js: wraps existing Technitium API calls into adapter interface
- cloudflare.js: Cloudflare API v4 adapter (zones, records, credentials)
- rfc2136.js: RFC 2136 dynamic DNS via nsupdate (BIND, PowerDNS, etc.)
- manual.js: no-op adapter for external DNS management with instructions
- provider-dns.js: provider-aware DNS context, resolves active adapter from config
- Universal helper methods: universalCreateRecord/Delete/ResolveRecord
- All 7 route files updated to use universal methods instead of raw dns.call()
- Setup wizard: provider dropdown (Technitium, Cloudflare, RFC 2136, Manual)
- DNS template selector: added Cloudflare and External/Manual options
- Config schema: validates dns.provider field
- Capability gating on Technitium-specific endpoints (logs, restart, update)
- Backward compatible: no provider set = auto-detect (technitium if dns.ip exists)
2026-06-10 15:06:41 -07:00
Hermes 0aa1c3d077 fix: correct module imports for SSLMonitor and DNSPropagationChecker
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
2026-06-10 14:45:34 -07:00
Hermes 954be9e868 feat: auto-restart policies, SSL monitoring, DNS propagation, dependency tracking, config drift detection
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
v1.9.0
2026-06-10 14:43:46 -07:00
Hermes afcccf811e release: 1.8.0 — service categories, monitoring widgets, update UX, fail2ban watchdog
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
v1.8.0
2026-06-10 12:52:13 -07:00
hermes 0aa7244cf4 infra: Samihost fail2ban watchdog (auto-unban trusted IPs, drift guard, cap at 200)
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
2026-06-10 11:28:42 -07:00
Hermes 1d8919532b feat: service categories end-to-end + monitoring widgets on main dashboard
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
Service categories (described in README roadmap, never wired):
- Backend: POST /services now persists category/containerId/port/ip/tailscaleOnly
- Backend: POST /services/update accepts category for in-place changes
- Frontend: category <select> in add-service modal (local + external)
- Frontend: category <select> in edit-service modal with current value
- Frontend: All Categories dropdown in service filter bar (auto-populated
  from both API categories and any categories present on rendered cards)
- Frontend: colored category badge (icon + name) on service cards
- Frontend: filter auto-refreshes after buildGrid

Monitoring on main dashboard (replaces orphaned monitoring-dashboard.html):
- New monitoring-widgets.js embeds a 5-card System Overview panel above
  the filter bar: Services, Containers Up, Avg CPU, Avg Memory, Health
- Pulls /api/v1/monitoring/stats + /api/v1/health-checks/status
- Auto-refreshes on DC.POLL.STATS (5s), color-coded bars (warn >=65%, bad >=85%)

Build:
- Added monitoring-widgets.js to init.js bundle in build.js
- Rebuilt dist/ bundles (core.js, features.js, init.js)
- sw.js cache version bumped automatically
- CSP hash regenerated
2026-06-10 01:49:27 -07:00
Krystie 9ab947a394 feat: enforceStorageLimit - prune oldest backups when maxStorageBytes exceeded 2026-05-28 15:14:59 -07:00
Krystie ad9400490d Merge: resolve conflict in routes/backups.js, keep storage-info + maxStorageBytes 2026-05-28 15:00:41 -07:00
Hermes ea9bdf9598 Backup data/ dir before update, restore on rollback
- Add backup_data_dir() and restore_data_dir() using rsync
- Data backed up to backups/{version}/data-backup/ alongside code
- restore_data_dir() called in all three rollback paths (build fail, restart fail, health check fail)
- Add restart_container() that does rm + run to apply new env vars
- Handle action=rollback explicitly (no new version deployment)
- Uses standalone docker build instead of compose for reliability
- Add start.sh at /opt/dashcaddy/start.sh for reboot survival
2026-05-28 02:34:27 -07:00