import { createServerClient } from "@supabase/ssr"; import { NextRequest, NextResponse } from "next/server"; import { legacyRecoveryToken } from "./shared/legacy-recovery"; import { restrictionPageAllowed } from "./shared/account-controls"; export async function proxy(request: NextRequest) { const recoveryToken = legacyRecoveryToken(request.nextUrl.pathname); if (recoveryToken) { const destination = request.nextUrl.clone(); destination.pathname = "/auth/callback"; destination.search = ""; destination.searchParams.set("legacy_recovery_token", recoveryToken); return NextResponse.redirect(destination); } let response = NextResponse.next({ request }); // Developer requests authenticate with their own opaque key, never browser cookies. if ( request.nextUrl.pathname.startsWith("/api/dev/v1/") || request.nextUrl.pathname === "/api/dev/openapi.json" ) return response; if (!process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY) return response; const client = createServerClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY, { cookies: { getAll: () => request.cookies.getAll(), setAll: (values) => { values.forEach(({ name, value }) => request.cookies.set(name, value)); response = NextResponse.next({ request }); values.forEach(({ name, value, options }) => response.cookies.set(name, value, options), ); }, }, }, ); const { data: { user }, } = await client.auth.getUser(); const path = request.nextUrl.pathname; if (user && !path.startsWith("/api/") && !restrictionPageAllowed(path)) { const { data, error } = await client .from("profiles") .select("account_status") .eq("id", user.id) .maybeSingle(); if (error) return new NextResponse( "Account access could not be verified. Please try again.", { status: 503, headers: { "Cache-Control": "no-store" } }, ); if (data && data.account_status !== "active") { const destination = new URL("/ban/appeal", request.url); const redirect = NextResponse.redirect(destination); response.cookies .getAll() .forEach((cookie) => redirect.cookies.set(cookie)); redirect.headers.set("Cache-Control", "private, no-store"); return redirect; } } return response; } export const config = { matcher: [ "/((?!_next/static|_next/image|favicon.ico|\\.well-known/workflow/|tools/|desktop/|fonts/|images/|media/|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|ttf|woff|woff2|jar)$).*)", ], };