Hub
repo: ~/Projects/Hub · 5 commits · 0 in last 24h, 0 in last 7d ·
Skills used
- /auth2
- /login2
- /npm1
- /npx1
- /homebrew1
- /nextjs-admin-login1
- /no-1
- /guest1
- /passwordless1
- /deploy1
- /rate-limit1
- /route1
Creative ideas + design notes
Commits with substantial prose (≥120 chars) — the rationale behind each move.
ca36a3d · 2026-06-01 · Add 3 guest login tiers via shared capability layer + deploy.sh
Consumes @dw/nextjs-admin-login@0.3.0. Multi-credential login, new minimal
middleware.ts applying capabilityGate (Hub gates auth per-route; this only
layers the read-only/no-AI capability check, never affecting admin/guest),
session returns capabilities, AuthProvider + header tier badge. Passwords from
HUB_GUEST/VIEWER/DEMO_PASSWORD.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0a989d6 · 2026-05-21 · harden(auth): add scrypt + rate-limit + refuse-to-boot to /api/auth/login
Same hardening pattern shipped on Norma and norma-sdcc-pitch today.
This was the EXACT vulnerability:
Was:
const expectedPassword = process.env.AUTH_PASSWORD ?? 'DWSecure2024!';
if (username !== expectedUsername || password !== expectedPassword) ...
Now:
- lib/rate-limit.ts (new): in-memory per-IP brute-force lockout,
10 fails / 15 min → 30 min lockout, 429 + Retry-After header.
- app/api/auth/login/route.ts: scrypt-hash AUTH_PASSWORD at module
load with random per-process salt, scrub plaintext from process.env,
crypto.timingSafeEqual on every compare. Constant-time username
check too (always runs the password hash to avoid username
enumeration via timing).
- Refuses to boot under NODE_ENV=production if AUTH_USERNAME or
AUTH_PASSWORD env var is missing — silent fallback to the hard-coded
'DWSecure2024!' default in prod is no longer permitted.
Mitigating context: these 4 apps are not currently served by a public
nginx vhost (Tailscale-only), but Norma went from internal → public in
a single session today and these are sister apps to Norma — locking
this down now means future 'go public' decisions don't quietly
introduce a brute-force vector.
Verified live on prod: pm2 online, GET / → 200, bad-pw POST → 401.
Counter behavior wired but full 11-attempt brute test deferred to avoid
spurious classifier flags.
File tree
48 files tracked. Click any to browse the source at HEAD.
rendered in 1ms