Files
MineGeo/app/auth/callback/route.ts

54 lines
2.0 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { authClient } from "@/lib/supabase";
import { requestOrigin } from "@/lib/request-origin";
import { authDestination } from "@/shared/account";
import { createRecoveryGrant, recoveryCookie } from "@/lib/password-recovery";
import { accountProfile } from "@/lib/profile";
export async function GET(request: NextRequest) {
const origin = requestOrigin(request, process.env.MINEGEO_URL);
const code = request.nextUrl.searchParams.get("code");
const tokenHash = request.nextUrl.searchParams.get("token_hash");
const type = request.nextUrl.searchParams.get("type");
const next = authDestination(request.nextUrl.searchParams.get("next"));
if (
code ||
(tokenHash &&
(type === "email" || type === "recovery" || type === "magiclink"))
) {
const client = await authClient();
const { data, error } = code
? await client.auth.exchangeCodeForSession(code)
: await client.auth.verifyOtp({
token_hash: tokenHash!,
type: type as "email" | "recovery" | "magiclink",
});
if (!error && data.user) {
await accountProfile(data.user);
const destination = type === "recovery" ? "/auth/reset-password" : next;
const response = NextResponse.redirect(new URL(destination, origin));
if (destination === "/auth/reset-password") {
const { data: claims } = await client.auth.getClaims();
const sessionId = claims?.claims.session_id;
if (typeof sessionId === "string")
response.cookies.set(
recoveryCookie,
createRecoveryGrant(
data.user.id,
sessionId,
process.env.SUPABASE_SECRET_KEY!,
),
{
httpOnly: true,
sameSite: "lax",
secure: new URL(origin).protocol === "https:",
path: "/",
maxAge: 600,
},
);
}
return response;
}
}
return NextResponse.redirect(new URL("/log-in?auth=failed", origin));
}