Files
carmanagement/apps/dashboard/src/middleware.ts
T
2026-06-10 00:40:19 -04:00

82 lines
2.9 KiB
TypeScript

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
const PUBLIC_DASHBOARD_PREFIXES = ['/dashboard/sign-in', '/dashboard/forgot-password']
const MARKETPLACE_URL = process.env.NEXT_PUBLIC_MARKETPLACE_URL ?? 'http://localhost:3000'
function rejectInternalSubrequest(req: NextRequest): NextResponse | null {
if (!req.headers.has('x-middleware-subrequest')) return null
return new NextResponse('Unsupported internal request header', { status: 400 })
}
function dedupeDashboardPath(pathname: string): string {
return pathname.replace(/^\/dashboard\/dashboard(?=\/|$)/, '/dashboard')
}
function isInternalHost(host: string | null): boolean {
if (!host) return false
const hostname = host.split(':')[0]?.toLowerCase()
return ['host.docker.internal', 'dashboard', 'admin', 'api', 'marketplace'].includes(hostname)
}
function isProtectedRoute(req: NextRequest) {
const { pathname } = req.nextUrl
if (PUBLIC_DASHBOARD_PREFIXES.some((p) => pathname === p || pathname.startsWith(p + '/'))) return false
return pathname === '/dashboard' || pathname.startsWith('/dashboard/')
}
function localJwtMiddleware(req: NextRequest): NextResponse {
const token = req.cookies.get('employee_session')?.value
if (token && req.nextUrl.pathname === '/dashboard/sign-in') {
const dashboardUrl = req.nextUrl.clone()
dashboardUrl.pathname = '/dashboard'
dashboardUrl.search = ''
return NextResponse.redirect(dashboardUrl)
}
if (!isProtectedRoute(req)) return NextResponse.next()
if (!token) {
const forwardedHost = req.headers.get('x-forwarded-host')
const forwardedProto = req.headers.get('x-forwarded-proto')
const marketplaceOrigin = new URL(MARKETPLACE_URL)
const signInUrl = req.nextUrl.clone()
if (forwardedHost && !isInternalHost(forwardedHost)) {
signInUrl.host = forwardedHost
signInUrl.protocol = (forwardedProto ?? 'http') + ':'
} else if (isInternalHost(signInUrl.host)) {
signInUrl.host = marketplaceOrigin.host
signInUrl.protocol = marketplaceOrigin.protocol
}
const isMarketplaceHost = signInUrl.host === marketplaceOrigin.host
signInUrl.pathname = isMarketplaceHost ? '/' : '/dashboard/sign-in'
signInUrl.searchParams.set('redirect', req.nextUrl.pathname)
return NextResponse.redirect(signInUrl)
}
return NextResponse.next()
}
export default function middleware(req: NextRequest) {
const rejected = rejectInternalSubrequest(req)
if (rejected) return rejected
const dedupedPath = dedupeDashboardPath(req.nextUrl.pathname)
if (dedupedPath !== req.nextUrl.pathname) {
const redirectUrl = req.nextUrl.clone()
redirectUrl.pathname = dedupedPath
return NextResponse.redirect(redirectUrl)
}
return localJwtMiddleware(req)
}
export const config = {
matcher: [
'/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
'/(api|trpc)(.*)',
],
}