/** * Verify user email with token from URL * Public procedure - no authentication required * * Flow: * 1. Find token in email_verifications table * 2. Check if token is expired * 3. Update user's email_verified_at timestamp * 4. Delete the verification record */ import { ORPCError } from "@orpc/server"; import { os } from "../base.js"; export const verifyEmail = os.auth.verifyEmail.handler( async ({ input, context }) => { const { token } = input; // Find the verification record const verification = await context.db .selectFrom("email_verifications") .select(["id", "user_id", "expires_at"]) .where("token", "=", token) .executeTakeFirst(); if (!verification) { throw new ORPCError("BAD_REQUEST", { message: "Invalid or expired token", }); } // Check if token is expired if (new Date() > verification.expires_at) { // Clean up expired token await context.db .deleteFrom("email_verifications") .where("id", "=", verification.id) .execute(); throw new ORPCError("BAD_REQUEST", { message: "Invalid or expired token", }); } // Update user's email_verified_at await context.db .updateTable("users") .set({ email_verified_at: new Date() }) .where("id", "=", verification.user_id) .execute(); // Delete the verification record await context.db .deleteFrom("email_verifications") .where("id", "=", verification.id) .execute(); return { success: true }; }, );