fix(auth): fail closed without JWT secret - #961
Open
nasalehj wants to merge 1 commit into
Open
Conversation
|
@nasalehj Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
nasalehj
force-pushed
the
fix/issue-814-auth-secret-fail-closed
branch
from
August 26, 2026 13:41
0867bfd to
78b6fef
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #814
Protected-route middleware no longer verifies cookies with a committed fallback secret. Missing or blank
AUTH_SECRETnow follows the existing invalid-token redirect path, while configured secrets preserve the existing JWT verification and cookie-clearing behavior. Startup validation and environment documentation now require a server-side secret of at least 32 characters.Why
Previously, any deployment with
AUTH_SECRETunset accepted tokens signed with a public repository string, turning a missing configuration into an authentication bypass. The middleware now fails closed per request, and validation surfaces the configuration error before deployment.What was built
middleware.tsjwtVerify; preserves protected routes, clock tolerance, redirects, and invalid-cookie deletion.scripts/validate-env.jsAUTH_SECRETas a trimmed string with at least 32 characters in development and the general environment schema..env.exampleAUTH_SECRETconfiguration without including a usable value.__tests__/middleware.test.tstests/helpers/middlewareJwtTestHelper.tsjosepackage directly.jest.config.cjs__tests__directory in Jest discovery so middleware coverage runs through the standard test command.The tests use a local deterministic signing/verifying helper only to exercise middleware control flow under the current Jest environment; production middleware continues to use
jose.Integration changes outside
src/scripts/validate-env.js— rejects missing, empty, and shortAUTH_SECRETvalues before deployment..env.example— documents the required server-side secret.jest.config.cjs— makes the existing root middleware test discoverable by Jest.tests/helpers/middlewareJwtTestHelper.ts— added test-only cryptographic fixture support; it is not imported by production code.Acceptance criteria coverage
middleware.ts,__tests__/middleware.test.ts— 8/8 focused tests pass, including valid, missing, and blank secret cases)middleware.tsand repository search — no occurrence remains in production middleware)__tests__/middleware.test.ts— explicit legacy-secret and missing-secret tests)eslint-plugin-jsdoc; focused middleware tests pass.Deliberately deferred
Test plan
npx prettier --check __tests__/middleware.test.ts tests/helpers/middlewareJwtTestHelper.ts middleware.ts scripts/validate-env.js— all matched files pass.npm test -- --runInBand __tests__/middleware.test.ts— 8/8 passing.AUTH_SECRET=test-secret-with-at-least-32-characters npm run validate:env— passes.AUTH_SECRET= npm run validate:env— exits 1 withAUTH_SECRET: Invalid value.npm run typecheck— fails on pre-existing syntax errors in unrelated files includingsrc/app/compare/page.tsx,src/components/ComparisonBar.tsx,src/components/PropertyCard.tsx,src/components/TransactionConfirmation.tsx,src/lib/toast.ts, andsrc/stories/ResponsiveContainerExample.stories.ts; the baseline also reports an existingsrc/components/CartSidebar.tsxsyntax error.npm test -- --runInBand— 63/141 suites passing; 985/1152 tests passing. Failures are existing repository issues including incomplete viem mocks, Vitest/CommonJS incompatibilities, malformed unrelated source/tests, and unrelated component assertions.npm run lint— cannot start becauseeslint-plugin-jsdocis not installed.npm run build— stops at the same pre-existing typecheck failures.Env vars / Notes
AUTH_SECRETmust be supplied through the deployment secret manager or local uncommitted environment file and must contain at least 32 non-whitespace characters. No migration or API contract changes are included.