Engineering manualAPI route source
/api/auth/google
Exact current route handler: hosted-app/app/api/auth/google/route.js
Methods: GET. Input signals: query parameters. Literal response-status signals: 503.
Source: hosted-app/app/api/auth/google/route.js. Imports: ../../../../lib/public-origin.mjs, ../../../../lib/supabase-rest.mjs, next/server, node:crypto. Exact source is shown for inspection; its presence does not prove authentication, validation or live behavior.
All API routes · API and execution contract
import { NextResponse } from "next/server";
import { createHash, randomBytes } from "node:crypto";
import { supabaseConfigFromEnv } from "../../../../lib/supabase-rest.mjs";
import { publicOriginFor } from "../../../../lib/public-origin.mjs";
export const runtime = "nodejs";
export const dynamic = "force-dynamic";
const safeNextPath = (value) => /^\/[^/\\]/.test(String(value || "")) ? String(value) : "/";
const PKCE_COOKIE = "brand-studio.oauth_pkce";
const base64Url = (value) => Buffer.from(value).toString("base64url");
export async function GET(request) {
const { supabaseUrl } = supabaseConfigFromEnv(process.env);
if (!supabaseUrl) {
return NextResponse.json({ status: "refused", reason: "supabase_not_configured" }, { status: 503 });
}
const requestUrl = new URL(request.url);
const callback = new URL("/auth/callback", publicOriginFor(request));
callback.searchParams.set("next", safeNextPath(requestUrl.searchParams.get("next")));
const verifier = base64Url(randomBytes(48));
const challenge = base64Url(createHash("sha256").update(verifier).digest());
const authorize = new URL(`${supabaseUrl}/auth/v1/authorize`);
authorize.searchParams.set("provider", "google");
authorize.searchParams.set("redirect_to", callback.toString());
authorize.searchParams.set("code_challenge", challenge);
authorize.searchParams.set("code_challenge_method", "s256");
const response = NextResponse.redirect(authorize);
response.cookies.set(PKCE_COOKIE, verifier, {
httpOnly: true,
secure: requestUrl.protocol === "https:",
sameSite: "lax",
path: "/api/auth/google/exchange",
maxAge: 10 * 60
});
return response;
}