feat(rbac): enforce admin access checks and document permission model
This commit is contained in:
37
apps/admin/src/middleware.ts
Normal file
37
apps/admin/src/middleware.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { type NextRequest, NextResponse } from "next/server"
|
||||
|
||||
import { canAccessRoute, getRequiredPermission, resolveRoleFromRequest } from "@/lib/access"
|
||||
|
||||
export function middleware(request: NextRequest) {
|
||||
const { pathname } = request.nextUrl
|
||||
|
||||
const role = resolveRoleFromRequest(request)
|
||||
|
||||
if (!role) {
|
||||
const unauthorizedUrl = request.nextUrl.clone()
|
||||
unauthorizedUrl.pathname = "/unauthorized"
|
||||
unauthorizedUrl.searchParams.set("reason", "missing-role")
|
||||
|
||||
return NextResponse.redirect(unauthorizedUrl)
|
||||
}
|
||||
|
||||
if (!canAccessRoute(role, pathname)) {
|
||||
const unauthorizedUrl = request.nextUrl.clone()
|
||||
unauthorizedUrl.pathname = "/unauthorized"
|
||||
|
||||
const required = getRequiredPermission(pathname)
|
||||
unauthorizedUrl.searchParams.set("required", required.permission)
|
||||
unauthorizedUrl.searchParams.set("scope", required.scope)
|
||||
|
||||
return NextResponse.redirect(unauthorizedUrl)
|
||||
}
|
||||
|
||||
const response = NextResponse.next()
|
||||
response.headers.set("x-cms-role", role)
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
export const config = {
|
||||
matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
|
||||
}
|
||||
Reference in New Issue
Block a user