fix(auth): allow /lunch/pick public access for accountless external attendees
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m30s
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m30s
The external dish-picker page is reached via a signed token by attendees who
have no account. The middleware authorized() callback redirected any non
allowlisted path to /login, which is a dead end for accountless users — so the
picker shipped in 8d4f0ba was unreachable in prod (307 → /login). Add
/lunch/pick to publicPaths; data stays gated by token verification in tRPC.
Adds a regression test asserting the path is public and a protected path is not.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -58,6 +58,7 @@ export const authConfig: NextAuthConfig = {
|
|||||||
'/forgot-password',
|
'/forgot-password',
|
||||||
'/reset-password',
|
'/reset-password',
|
||||||
'/apply',
|
'/apply',
|
||||||
|
'/lunch/pick', // external attendees pick a dish via signed token (no account)
|
||||||
'/api/auth',
|
'/api/auth',
|
||||||
'/api/trpc', // tRPC handles its own auth via procedures
|
'/api/trpc', // tRPC handles its own auth via procedures
|
||||||
]
|
]
|
||||||
|
|||||||
25
tests/unit/auth-public-paths.test.ts
Normal file
25
tests/unit/auth-public-paths.test.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* The external lunch dish-pick page is reached by attendees with NO account, via
|
||||||
|
* a signed token link. It MUST be in the middleware public-path allowlist, or the
|
||||||
|
* auth middleware redirects them to /login (a dead end for accountless users).
|
||||||
|
*/
|
||||||
|
import { describe, it, expect } from 'vitest'
|
||||||
|
import { authConfig } from '@/lib/auth.config'
|
||||||
|
|
||||||
|
function authorized(pathname: string, auth: unknown) {
|
||||||
|
const fn = authConfig.callbacks!.authorized!
|
||||||
|
return fn({
|
||||||
|
auth: auth as never,
|
||||||
|
request: { nextUrl: new URL(`http://localhost${pathname}`) } as never,
|
||||||
|
} as never)
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('middleware public paths', () => {
|
||||||
|
it('allows the external lunch pick page without a session', () => {
|
||||||
|
expect(authorized('/lunch/pick/some.signed.token', null)).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('blocks a protected page without a session', () => {
|
||||||
|
expect(authorized('/admin/logistics', null)).toBe(false)
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user