"use client"; /** * OAuthButtons — "Continue with Google / Facebook" row used above both * LoginForm and SignUpForm. Clicking a button performs a top-level * navigation to the BFF's /oauth//start endpoint, which kicks off * the Authorization Code flow. The BFF handles the round-trip and 302s back * to ${frontend}${next} with the session cookie already set. * * Top-level navigation (not fetch) is intentional: cross-origin redirects * to Google / Facebook can't happen from XHR, and we need the BFF to set * the cookie before the browser lands back on the frontend. */ import { useMemo } from "react"; const BFF_BASE = process.env.NEXT_PUBLIC_BFF_URL || "http://localhost:8080"; type Props = { /** Frontend path to land on after the round-trip. Defaults to /u/me. */ next?: string; /** Whether to render a divider with "or continue with email" below. */ showDivider?: boolean; }; export function OAuthButtons({ next, showDivider = true }: Props) { const startUrl = useMemo( () => (provider: "google" | "facebook") => { const u = new URL(`${BFF_BASE}/api/v1/auth/oauth/${provider}/start`); if (next) u.searchParams.set("next", next); return u.toString(); }, [next], ); return (
Google Facebook
{showDivider ? (
or
) : null}
); } function GoogleIcon({ className }: { className?: string }) { return ( ); } function FacebookIcon({ className }: { className?: string }) { return ( ); }