64 lines
1.7 KiB
TypeScript
64 lines
1.7 KiB
TypeScript
|
|
import { NextRequest, NextResponse } from "next/server";
|
||
|
|
import { cookies } from "next/headers";
|
||
|
|
import {
|
||
|
|
type Provider,
|
||
|
|
PROVIDER_CONFIGS,
|
||
|
|
generateState,
|
||
|
|
buildAuthorizationUrl,
|
||
|
|
} from "@/lib/oauth";
|
||
|
|
|
||
|
|
const VALID_PROVIDERS = ["google", "apple", "github"];
|
||
|
|
|
||
|
|
export async function GET(
|
||
|
|
_req: NextRequest,
|
||
|
|
{ params }: { params: Promise<{ provider: string }> }
|
||
|
|
) {
|
||
|
|
const { provider } = await params;
|
||
|
|
|
||
|
|
if (!VALID_PROVIDERS.includes(provider)) {
|
||
|
|
return NextResponse.json(
|
||
|
|
{ error: `Unsupported provider. Must be one of: ${VALID_PROVIDERS.join(", ")}` },
|
||
|
|
{ status: 400 }
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
const config = PROVIDER_CONFIGS[provider as Provider];
|
||
|
|
const clientId = process.env[config.clientIdEnv];
|
||
|
|
|
||
|
|
if (!clientId) {
|
||
|
|
return NextResponse.json(
|
||
|
|
{
|
||
|
|
error: `${provider} OAuth is not configured. Missing ${config.clientIdEnv} environment variable.`,
|
||
|
|
},
|
||
|
|
{ status: 503 }
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Build the redirect URI — the callback URL for this provider
|
||
|
|
const url = new URL(_req.url);
|
||
|
|
const baseUrl = `${url.protocol}//${url.host}`;
|
||
|
|
const redirectUri = `${baseUrl}/mobile/api/auth/${provider}/callback`;
|
||
|
|
|
||
|
|
// Generate state for CSRF protection
|
||
|
|
const state = await generateState(provider as Provider);
|
||
|
|
|
||
|
|
// Store state in a cookie
|
||
|
|
const cookieStore = await cookies();
|
||
|
|
cookieStore.set("oauth_state", state, {
|
||
|
|
httpOnly: true,
|
||
|
|
secure: process.env.NODE_ENV === "production",
|
||
|
|
sameSite: "lax",
|
||
|
|
path: "/",
|
||
|
|
maxAge: 60 * 10, // 10 minutes
|
||
|
|
});
|
||
|
|
|
||
|
|
// Build the authorization URL and redirect
|
||
|
|
const authUrl = buildAuthorizationUrl(
|
||
|
|
provider as Provider,
|
||
|
|
state,
|
||
|
|
redirectUri
|
||
|
|
);
|
||
|
|
|
||
|
|
return NextResponse.redirect(authUrl);
|
||
|
|
}
|