task-d.7.11
This commit is contained in:
112
src/proxy.ts
112
src/proxy.ts
@@ -1,56 +1,89 @@
|
||||
import { auth } from "@/auth";
|
||||
import { NextResponse } from "next/server";
|
||||
import { auth } from '@/auth';
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
const protectedApiPrefixes = [
|
||||
"/api/products",
|
||||
"/api/organizations",
|
||||
"/api/users",
|
||||
];
|
||||
const superAdminOnlyRoutes = ["/dashboard/workspaces"];
|
||||
const organizationAdminRoutes = [
|
||||
"/dashboard/users",
|
||||
"/dashboard/workspaces/team",
|
||||
];
|
||||
const protectedApiPrefixes = ['/api/products', '/api/organizations', '/api/users'];
|
||||
const superAdminOnlyRoutes = ['/dashboard/workspaces', '/dashboard/administration/setup'];
|
||||
const organizationAdminRoutes = ['/dashboard/users', '/dashboard/workspaces/team'];
|
||||
|
||||
export default auth((req) => {
|
||||
const pathname = req.nextUrl.pathname;
|
||||
const isDashboardRoute = pathname.startsWith("/dashboard/crm");
|
||||
const isProtectedApiRoute = protectedApiPrefixes.some((prefix) =>
|
||||
pathname.startsWith(prefix),
|
||||
interface BootstrapStatusResponse {
|
||||
initialized: boolean;
|
||||
}
|
||||
|
||||
function isBootstrapAllowedPath(pathname: string) {
|
||||
return (
|
||||
pathname === '/administration/setup' ||
|
||||
pathname.startsWith('/api/setup/bootstrap/') ||
|
||||
pathname === '/api/setup/templates'
|
||||
);
|
||||
}
|
||||
|
||||
async function getBootstrapInitialized(origin: string): Promise<boolean | null> {
|
||||
try {
|
||||
const response = await fetch(new URL('/api/setup/bootstrap/status', origin), {
|
||||
cache: 'no-store',
|
||||
headers: {
|
||||
'x-setup-proxy-check': '1'
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) return null;
|
||||
|
||||
const payload = (await response.json()) as BootstrapStatusResponse;
|
||||
return payload.initialized;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export default auth(async (req) => {
|
||||
const pathname = req.nextUrl.pathname;
|
||||
const bootstrapAllowedPath = isBootstrapAllowedPath(pathname);
|
||||
|
||||
if (bootstrapAllowedPath) {
|
||||
return NextResponse.next();
|
||||
}
|
||||
|
||||
const isInitialized = await getBootstrapInitialized(req.nextUrl.origin);
|
||||
|
||||
if (isInitialized === false) {
|
||||
if (pathname.startsWith('/api/')) {
|
||||
return NextResponse.json(
|
||||
{ message: 'System setup is required before this API is available.', redirectTo: '/administration/setup' },
|
||||
{ status: 503 }
|
||||
);
|
||||
}
|
||||
|
||||
return NextResponse.redirect(new URL('/administration/setup', req.nextUrl.origin));
|
||||
}
|
||||
|
||||
const isDashboardRoute = pathname.startsWith('/dashboard');
|
||||
const isProtectedApiRoute = protectedApiPrefixes.some((prefix) => pathname.startsWith(prefix));
|
||||
const user = req.auth?.user;
|
||||
const isSignedIn = !!user;
|
||||
const isSuperAdmin = user?.systemRole === "super_admin";
|
||||
const isSignedIn = Boolean(user);
|
||||
const isSuperAdmin = user?.systemRole === 'super_admin';
|
||||
const isOrganizationAdmin =
|
||||
isSuperAdmin ||
|
||||
(user?.activeOrganizationId &&
|
||||
(user.activeMembershipRole === "admin" ||
|
||||
user.activePermissions?.includes("users:manage")));
|
||||
Boolean(
|
||||
user?.activeOrganizationId &&
|
||||
(user.activeMembershipRole === 'admin' || user.activePermissions?.includes('users:manage'))
|
||||
);
|
||||
|
||||
if (!isSignedIn && (isDashboardRoute || isProtectedApiRoute)) {
|
||||
if (isProtectedApiRoute) {
|
||||
return NextResponse.json({ message: "Unauthorized" }, { status: 401 });
|
||||
return NextResponse.json({ message: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
const signInUrl = new URL("/auth/sign-in", req.nextUrl.origin);
|
||||
signInUrl.searchParams.set("callbackUrl", pathname);
|
||||
const signInUrl = new URL('/auth/sign-in', req.nextUrl.origin);
|
||||
signInUrl.searchParams.set('callbackUrl', `${pathname}${req.nextUrl.search}`);
|
||||
return NextResponse.redirect(signInUrl);
|
||||
}
|
||||
|
||||
if (
|
||||
isSignedIn &&
|
||||
superAdminOnlyRoutes.some((prefix) => pathname.startsWith(prefix)) &&
|
||||
!isSuperAdmin
|
||||
) {
|
||||
return NextResponse.redirect(new URL("/dashboard", req.nextUrl.origin));
|
||||
if (isSignedIn && superAdminOnlyRoutes.some((prefix) => pathname.startsWith(prefix)) && !isSuperAdmin) {
|
||||
return NextResponse.redirect(new URL('/dashboard', req.nextUrl.origin));
|
||||
}
|
||||
|
||||
if (
|
||||
isSignedIn &&
|
||||
organizationAdminRoutes.some((prefix) => pathname.startsWith(prefix)) &&
|
||||
!isOrganizationAdmin
|
||||
) {
|
||||
return NextResponse.redirect(new URL("/dashboard", req.nextUrl.origin));
|
||||
if (isSignedIn && organizationAdminRoutes.some((prefix) => pathname.startsWith(prefix)) && !isOrganizationAdmin) {
|
||||
return NextResponse.redirect(new URL('/dashboard', req.nextUrl.origin));
|
||||
}
|
||||
|
||||
return NextResponse.next();
|
||||
@@ -58,7 +91,6 @@ export default auth((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)(.*)",
|
||||
],
|
||||
'/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)'
|
||||
]
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user