feat: add demo space auth bypass in middleware
Skip EncryptID token check for demo subdomains when ENCRYPTID_DEMO_SPACES env var is set. Uses isDemoRequest() from @encryptid/sdk v0.2.0. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f4629a48c2
commit
63164a00ad
|
|
@ -1,5 +1,6 @@
|
||||||
import { NextResponse } from 'next/server'
|
import { NextResponse } from 'next/server'
|
||||||
import type { NextRequest } from 'next/server'
|
import type { NextRequest } from 'next/server'
|
||||||
|
import { isDemoRequest } from '@encryptid/sdk/server/nextjs'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Middleware to protect /space routes.
|
* Middleware to protect /space routes.
|
||||||
|
|
@ -9,15 +10,18 @@ import type { NextRequest } from 'next/server'
|
||||||
* requests — if no encryptid_token cookie is present on /space, redirect to
|
* requests — if no encryptid_token cookie is present on /space, redirect to
|
||||||
* the home page with a login hint.
|
* the home page with a login hint.
|
||||||
*
|
*
|
||||||
* Note: Since rfunds uses client-side Zustand persistence (localStorage),
|
* Demo spaces (ENCRYPTID_DEMO_SPACES env var) bypass auth.
|
||||||
* the primary auth gate is in the SpacePage component itself. This middleware
|
|
||||||
* serves as an additional layer for direct URL access.
|
|
||||||
*/
|
*/
|
||||||
export function middleware(request: NextRequest) {
|
export function middleware(request: NextRequest) {
|
||||||
const { pathname } = request.nextUrl
|
const { pathname } = request.nextUrl
|
||||||
|
|
||||||
// Only protect /space routes (not /tbff which is a public demo)
|
// Only protect /space routes (not /tbff which is a public demo)
|
||||||
if (pathname.startsWith('/space')) {
|
if (pathname.startsWith('/space')) {
|
||||||
|
// Demo spaces get anonymous access — SDK provides synthetic claims
|
||||||
|
if (isDemoRequest(request)) {
|
||||||
|
return NextResponse.next()
|
||||||
|
}
|
||||||
|
|
||||||
// Check for auth token in cookie (set by client after login)
|
// Check for auth token in cookie (set by client after login)
|
||||||
const token = request.cookies.get('encryptid_token')?.value
|
const token = request.cookies.get('encryptid_token')?.value
|
||||||
|
|
||||||
|
|
@ -26,9 +30,6 @@ export function middleware(request: NextRequest) {
|
||||||
const bearerToken = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : null
|
const bearerToken = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : null
|
||||||
|
|
||||||
if (!token && !bearerToken) {
|
if (!token && !bearerToken) {
|
||||||
// No auth — redirect to home with login hint
|
|
||||||
// The client-side auth store is the primary gate, but this catches
|
|
||||||
// direct navigation before hydration
|
|
||||||
const url = request.nextUrl.clone()
|
const url = request.nextUrl.clone()
|
||||||
url.pathname = '/'
|
url.pathname = '/'
|
||||||
url.searchParams.set('login', 'required')
|
url.searchParams.set('login', 'required')
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue