fix(auth): centralize JWT secret + 24h TTL (Brief 1 of fix-auth-bypass) #6
No reviewers
Labels
No labels
agent-context-drift
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: rstillwell/deckhearth#6
Loading…
Reference in a new issue
No description provided.
Delete branch "brief/fix-auth-bypass/1-jwt-secret-helper"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Convoy
fix-auth-bypass/ Brief 1 of 5. Resolves AGENTS.md gotcha #3 (hardcodedJWT_SECRETdefault across 7 files). See.convoys/fix-auth-bypass.mdfor the full convoy plan.lib/auth-secret.jsis the single source of truth forJWT_SECRETand the canonicalJWT_TOKEN_TTL = '24h'. The module throws at import time ifprocess.env.JWT_SECRETis unset or empty — no silent fallback.pages/api/auth/login.jsandpages/api/auth/register.jsadditionally route token minting throughgenerateTokeninauth-utils.js(one canonical mint site), which dropped their inlinejwt.signandjsonwebtokenimport.auth-utils.generateToken('7d') andlogin.js/register.js('24h') is reconciled to 24h via the importedJWT_TOKEN_TTL. The'7d'was the drift — no UX impact, since the call path was always login→inline-24h.Files changed
lib/auth-secret.js(new, 12 lines)lib/permission-middleware.js(literal → import)pages/api/auth-utils.js(literal → import;'7d'→JWT_TOKEN_TTL)pages/api/auth/login.js(literal → import; inlinejwt.sign(...)→generateToken(...))pages/api/auth/register.js(same as login)pages/api/auth/verify.js(literal → import). The no-token admin-fetch branch is intentionally preserved here — Brief 2 removes it.pages/api/favorites.js(literal → import)pages/api/users/search.js(literal → import)Test plan
npm run buildexits 0npm run lintmatches baseline (128 problems / 81 errors / 47 warnings); zero new lint issues in the 8 in-scope filesJWT_SECRETset:import('./lib/auth-secret.js')→{ JWT_SECRET: string, JWT_TOKEN_TTL: '24h' }JWT_SECRETunset OR empty string: same import throws synchronously with descriptive error (reviewer reproduced both cases)grep "process.env.JWT_SECRET"returns exactly 1 hit (the helper itself)grep "your-secret-key-change-in-production"returns zero hitsexp - iat ≈ 86400(24h). UnsetJWT_SECRETin a side-deploy → confirm 500 on first auth call (i.e. fail-loud worked end-to-end on Vercel runtime).Pre-merge requirements
JWT_SECRETmust be set in Vercel project env for both Production and Preview before this merges, or the serverless functions will crash on cold start (R3 in convoy file).⚠️ Post-merge state — convoy is NOT complete after this PR
This PR alone does not close the auth bypass.
lib/permission-middleware.js::getUserFromRequeststill returns a hardcoded admin user when noBearertoken is present (intentional in this PR — that removal is Brief 2's job, which depends on this PR landing first).pages/api/auth/verify.jslikewise still has its no-token admin-fetch branch (WHERE email = 'admin@tcgvault.com').Do not advertise the convoy as complete or close the AGENTS.md gotcha #2 line item until Brief 2 also merges. This PR closes gotcha #3 only.
Out of scope (intentionally — see convoy plan)
lib/permission-middleware.js::getUserFromRequest→ Brief 2pages/api/auth/verify.js→ Brief 2/api/simple,/api/test-*,/api/setup-database) → Brief 3 (PR #7)Audit cohort
role-reviewercomplete — Approve-with-followups (no merge blockers; the M1 nit prompted the new "Post-merge state" section above)🤖 Pipeline metadata: convoy=fix-auth-bypass, brief=1, depends_on=[], audit=reviewer-only
The latest updates on your projects. Learn more about Vercel for GitHub.
Pipeline Health
Build + CI gates
Build runs on Vercel; this CI runs lint and schema-map drift only (no duplicate build).
Role reports
See individual comments above for details. This rollup updates automatically.