/** * Magic-link send + consume via first-party FDI proxy. * Briven emails open: {origin}/auth/verify?preAuthSessionId&linkCode&deviceId */ import { getBrivenAuthPublicKey, getBrivenProjectId, } from "@/lib/auth-config"; import { establishPortalSession, userIdFromEngineBody, } from "@/lib/portal-session"; function fdiHeaders(): Record { const projectId = getBrivenProjectId() ?? ""; const publicKey = getBrivenAuthPublicKey() ?? ""; const headers: Record = { "content-type": "application/json", accept: "application/json", rid: "passwordless", "fdi-version": "1.19", "st-auth-mode": "cookie", }; if (projectId.startsWith("p_")) { headers["x-briven-project-id"] = projectId; } if (publicKey.startsWith("pk_briven_auth_")) { headers.authorization = `Bearer ${publicKey}`; } return headers; } export async function sendMagicLinkEmail(input: { email: string; /** Where to go after verify succeeds */ redirectTo?: string; }): Promise<{ ok: true } | { ok: false; message: string }> { const email = input.email.trim().toLowerCase(); if (!email.includes("@")) { return { ok: false, message: "Enter a valid email." }; } if (typeof window !== "undefined" && input.redirectTo) { sessionStorage.setItem("krypco_magic_redirect", input.redirectTo); } const magicLinkBaseUrl = typeof window !== "undefined" ? `${window.location.origin}/auth/verify` : "https://krypco.eu/auth/verify"; try { const res = await fetch("/api/auth/signinup/code", { method: "POST", credentials: "include", headers: fdiHeaders(), body: JSON.stringify({ email, flowType: "MAGIC_LINK", magicLinkBaseUrl, }), }); const data = (await res.json().catch(() => ({}))) as Record< string, unknown >; if (!res.ok || data.status !== "OK") { return { ok: false, message: typeof data.message === "string" ? data.message : "Could not send magic link.", }; } return { ok: true }; } catch (e) { return { ok: false, message: e instanceof Error ? e.message : "network error", }; } } export async function consumeMagicLink(input: { preAuthSessionId: string; deviceId: string; linkCode: string; }): Promise< | { ok: true; userId: string } | { ok: false; message: string } > { try { const res = await fetch("/api/auth/signinup/code/consume", { method: "POST", credentials: "include", headers: fdiHeaders(), body: JSON.stringify({ preAuthSessionId: input.preAuthSessionId, deviceId: input.deviceId, linkCode: input.linkCode, }), }); const data = (await res.json().catch(() => ({}))) as Record< string, unknown >; if (res.ok && data.status === "OK") { const userId = userIdFromEngineBody(data) || "session"; await establishPortalSession({ userId }); return { ok: true, userId }; } return { ok: false, message: typeof data.message === "string" ? data.message : "This sign-in link is invalid or expired. Request a new one.", }; } catch (e) { return { ok: false, message: e instanceof Error ? e.message : "network error", }; } }