my-fullstack-ai-platform/lib/supabase/proxy.ts

86 lines
2.7 KiB
TypeScript
Raw Normal View History

2026-04-04 20:00:53 +00:00
import { createServerClient } from "@supabase/ssr";
import { NextResponse, type NextRequest } from "next/server";
import { hasEnvVars } from "../utils";
export async function updateSession(request: NextRequest) {
let supabaseResponse = NextResponse.next({
request,
});
if (!hasEnvVars) {
return supabaseResponse;
}
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!,
{
cookies: {
getAll() {
return request.cookies.getAll();
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value }) =>
request.cookies.set(name, value),
);
supabaseResponse = NextResponse.next({
request,
});
cookiesToSet.forEach(({ name, value, options }) =>
supabaseResponse.cookies.set(name, value, options),
);
},
},
},
);
const { data } = await supabase.auth.getClaims();
const user = data?.claims;
// Paths that do not require auth OR do not enforce organization check
const isAuthPath = request.nextUrl.pathname.startsWith("/auth") || request.nextUrl.pathname.startsWith("/login");
const isApiPath = request.nextUrl.pathname.startsWith("/api");
// The sign up callback or standard paths like favicon Next.js ignores, but just in case
const isPublicResource = request.nextUrl.pathname.startsWith("/_next") || request.nextUrl.pathname.includes(".");
if (isPublicResource) {
return supabaseResponse;
}
if (!user && !isAuthPath && !isApiPath) {
// potentially respond by redirecting the user to the login page
2026-04-04 20:00:53 +00:00
const url = request.nextUrl.clone();
url.pathname = "/auth/login";
return NextResponse.redirect(url);
}
if (user && !isAuthPath && !isApiPath) {
// Logged in, check if they are going to an app route
// Fetch profile to see if they have an organization
const { data: profile } = await supabase
.from('profiles')
.select('organization_id')
.eq('id', user.sub)
.single();
const hasOrg = !!profile?.organization_id;
const isOnboarding = request.nextUrl.pathname.startsWith("/onboarding");
if (!hasOrg && !isOnboarding) {
// Force user to onboarding if they have no organization
const url = request.nextUrl.clone();
url.pathname = "/onboarding";
return NextResponse.redirect(url);
}
if (hasOrg && isOnboarding) {
// If they already have an organization, they shouldn't be in onboarding
const url = request.nextUrl.clone();
url.pathname = "/dashboard";
return NextResponse.redirect(url);
}
}
2026-04-04 20:00:53 +00:00
return supabaseResponse;
}