Compare commits

...
4 Commits
Author SHA1 Message Date
Hermes 77a94d55d2 DC-083: mark license-manager.js done in backlog
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s
2026-08-12 16:11:26 -07:00
Hermes a468e0f480 [grade=B] DC-083: comprehensive license-manager.js test coverage (77 tests, revenue path)
Added __tests__/license-manager.test.js with 77 tests covering the entire
src/managers/license-manager.js module (534 LOC) — the revenue validation
path that was previously untested by any dedicated test file.

Coverage includes:
- load(): credential-store primary, config-backup fallback, no-license,
  credential-store error → config recovery, re-store after restore
- activate(): real crypto round-trip for all durations (30/90/180/365),
  already-activated idempotency, invalid format, missing code, offline
  HMAC validation failure, LIFETIME rejection (prod) + acceptance (dev),
  credential-store save failure, config write, lowercase normalization,
  whitespace trimming
- activate() online path: server success, server unreachable → offline
  fallback, server explicit rejection (no fallback)
- deactivate(): success, no-active-license, credential delete, config clear
- getStatus(): free tier, active premium, expired, lifetime, code masking
- hasFeature(): no-activation, active, expired, specific-feature, default
- isPro()/isExpired()/daysRemaining(): all branches (no-activation, active,
  expired, lifetime, missing expiresAt)
- getMachineFingerprint(): stable 16-char hex
- requirePremium() middleware: next() on available, 403 on unavailable,
  upgrade URL, unknown feature
- loadSecret(): file-exists, file-missing, read-error (deterministic fs mock)
- _validateOffline(): with-secret valid, forged HMAC mismatch, no-secret
  structural-only, malformed code, unsupported version (forged v2 payload)
- _updateConfig(): creates config, preserves fields, clears on deactivation,
  nonexistent-directory tolerance
- _maskCode(): standard, short, empty
- Full lifecycle: activate→status→deactivate→status, load-after-activate
  restore, freshly-minted-code validation

Unlike license-tier-enforcement.test.js (which stubs _validateOffline),
these tests exercise the REAL crypto flow end-to-end: generateCode(TEST_SECRET)
→ activate(code) → _validateOffline(code) → verifyCode(secret, code) →
credential store. Uses jest.isolateModules for online tests so the module-
level LICENSE_SERVER_URL const is re-read per test.

Codex grade: B (urn:ump:vwial6vhrzzmsvpfjdxnk53hvol3wna3o2zwmneqjcquxfgdersq)
Full suite: 1738/1738 pass (was 1661, +77 new). Zero new ESLint warnings on src/.
2026-08-12 16:11:15 -07:00
Hermes 43d9c0e1d0 DC-083: claim license-manager.js coverage for Hermes
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s
2026-08-12 15:56:53 -07:00
Hermes 96a6e8ac6a DC-106: auto-claim (autonomous build pick tick)
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s
2026-08-12 15:24:45 -07:00
2 changed files with 1493 additions and 1 deletions
+3 -1
View File
@@ -145,9 +145,10 @@
- **impact:** Any execSync with interpolation is a potential RCE. This is the same class of bug P0-2 already fixed — finish the job. - **impact:** Any execSync with interpolation is a potential RCE. This is the same class of bug P0-2 already fixed — finish the job.
### DC-083: 30 source files have zero test coverage ### DC-083: 30 source files have zero test coverage
- **status:** partial (coverage 65pct->75pct) - **status:** partial (license-manager.js done; 29 files remain — claimed by hermes 2026-08-12)
- **details:** The test gap scan found 30 source files with NO corresponding test file, including critical paths: `license-manager.js` (534 lines, the entire revenue validation path), `config-schema.js`, `middleware.js` (the auth/rate-limit/CORS stack), `startup-validator.js`, all 7 DNS provider modules (`technitium.js`, `cloudflare.js`, `rfc2136.js`, `manual.js`, `base.js`, `registry.js`, `email.js`), `docker-maintenance.js`, `config/migrations.js`, `event-workers.js`, `keychain-manager.js`, `event-store.js`, `host-registry.js`. Fix: prioritize license-manager.js (revenue path) and middleware.js (security stack) first, then work through the rest. Effort: ~8 hr (can be done incrementally, 2-3 files per PR). - **details:** The test gap scan found 30 source files with NO corresponding test file, including critical paths: `license-manager.js` (534 lines, the entire revenue validation path), `config-schema.js`, `middleware.js` (the auth/rate-limit/CORS stack), `startup-validator.js`, all 7 DNS provider modules (`technitium.js`, `cloudflare.js`, `rfc2136.js`, `manual.js`, `base.js`, `registry.js`, `email.js`), `docker-maintenance.js`, `config/migrations.js`, `event-workers.js`, `keychain-manager.js`, `event-store.js`, `host-registry.js`. Fix: prioritize license-manager.js (revenue path) and middleware.js (security stack) first, then work through the rest. Effort: ~8 hr (can be done incrementally, 2-3 files per PR).
- **impact:** license-manager.js validates Pro licenses — an untested bug there could silently break activation for every paying customer. - **impact:** license-manager.js validates Pro licenses — an untested bug there could silently break activation for every paying customer.
- **result:** license-manager.js (534 LOC) — the entire revenue validation path — now has dedicated test coverage via `__tests__/license-manager.test.js` (77 tests, codex-graded B). Tests exercise the REAL crypto flow end-to-end: `generateCode(TEST_SECRET)``activate(code)``_validateOffline(code)``verifyCode(secret, code)` → credential store + config persistence. Unlike `license-tier-enforcement.test.js` (which stubs `_validateOffline`), these tests validate actual HMAC signatures, forge version-2 payloads, test online validation paths via `jest.isolateModules`, and cover every public+private method including load/deactivate/getStatus/hasFeature/isPro/isExpired/daysRemaining/getMachineFingerprint/requirePremium/loadSecret/_validateOffline/_updateConfig/_maskCode. Full lifecycle integration tests verify activate→status→deactivate→status and load-after-activate restore across simulated restarts. Full suite: 1738/1738 pass (was 1661, +77 new). Zero new ESLint warnings. 29 files remain uncovered (next priority: middleware.js security stack).
### DC-084: No .dockerignore — test files and .git leak into Docker image ### DC-084: No .dockerignore — test files and .git leak into Docker image
- **status:** already done (.dockerignore) - **status:** already done (.dockerignore)
@@ -278,6 +279,7 @@
### DC-106: Caddyfile-as-code — visual reverse proxy builder ### DC-106: Caddyfile-as-code — visual reverse proxy builder
- **status:** pending - **status:** pending
- **status:** in-progress (auto-claimed at 20260812T222443Z)
- **details:** Instead of editing Caddyfile text, provide a visual builder: "I want requests to blog.yourdomain.com to go to container X on port 80, with authentication, rate limiting, and compression." Generate the Caddyfile block from the form. Show a live preview of the generated config. Apply via Caddy admin API. This eliminates the need to learn Caddyfile syntax entirely. Effort: ~3 hr. - **details:** Instead of editing Caddyfile text, provide a visual builder: "I want requests to blog.yourdomain.com to go to container X on port 80, with authentication, rate limiting, and compression." Generate the Caddyfile block from the form. Show a live preview of the generated config. Apply via Caddy admin API. This eliminates the need to learn Caddyfile syntax entirely. Effort: ~3 hr.
- **impact:** Caddyfile syntax is the #1 technical barrier. A visual builder makes reverse proxy configuration accessible to non-sysadmins. - **impact:** Caddyfile syntax is the #1 technical barrier. A visual builder makes reverse proxy configuration accessible to non-sysadmins.
File diff suppressed because it is too large Load Diff