Midday / apps /dashboard /src /actions /verify-otp-action.ts
Jules
Final deployment with all fixes and verified content
c09f67c
"use server";
import { createClient } from "@midday/supabase/server";
import { addSeconds, addYears } from "date-fns";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import { z } from "zod";
import { Cookies } from "@/utils/constants";
import { actionClient } from "./safe-action";
export const verifyOtpAction = actionClient
.schema(
z.object({
token: z.string(),
email: z.string(),
redirectTo: z.string(),
}),
)
.action(async ({ parsedInput: { email, token, redirectTo } }) => {
const supabase = await createClient();
await supabase.auth.verifyOtp({
email,
token,
type: "email",
});
// Validate that the session was actually established (similar to OAuth callback)
const {
data: { session },
} = await supabase.auth.getSession();
if (!session) {
throw new Error("Failed to establish session after OTP verification");
}
const cookieStore = await cookies();
cookieStore.set(Cookies.PreferredSignInProvider, "otp", {
expires: addYears(new Date(), 1),
});
// Force primary database reads for subsequent requests after redirect.
// This prevents replication lag issues when the user record hasn't
// replicated to read replicas yet (same as the OAuth callback).
cookieStore.set(Cookies.ForcePrimary, "true", {
expires: addSeconds(new Date(), 30),
httpOnly: false, // Needs to be readable by client-side tRPC
sameSite: "lax",
});
redirect(redirectTo);
});