Repository Public
1// Auteur : Simon-Pierre Boucher — contact@spboucher.ai2// Clic sur le lien magique : le jeton prouve la possession de la boîte3// courriel → session ouverte, adresse marquée vérifiée.4import { NextRequest, NextResponse } from "next/server";5import {6 consumeAuthToken,7 findUserById,8 markEmailVerified,9 touchLastLogin,10} from "@/lib/db";11import {12 BASE_URL,13 mintSessionToken,14 SESSION_COOKIE,15 sessionCookieOptions,16 safeNext,17} from "@/lib/auth";1819export async function GET(req: NextRequest) {20 const token = req.nextUrl.searchParams.get("token") ?? "";21 const row = token ? consumeAuthToken(token, "magic-link") : undefined;22 if (!row?.user_id || !findUserById(row.user_id))23 return NextResponse.redirect(24 new URL("/connexion?error=jeton-invalide", BASE_URL),25 );2627 markEmailVerified(row.user_id);28 touchLastLogin(row.user_id);2930 let next = "/compte";31 try {32 next = safeNext((JSON.parse(row.payload ?? "{}") as { next?: string }).next);33 } catch {34 /* payload absent */35 }36 const res = NextResponse.redirect(new URL(next, BASE_URL));37 res.cookies.set(38 SESSION_COOKIE,39 await mintSessionToken(row.user_id),40 sessionCookieOptions,41 );42 return res;43}44