import crypto from "node:crypto"; import { TRPCError } from "@trpc/server"; import type { UsersId } from "~/schemas/public/Users"; import { db } from "~/server/db"; import { NewMail } from "../services/mailer"; const INVITE_EXPIRY_HOURS = 48; export async function createInviteToken(email: string) { // Generate a secure random token const token = crypto.randomBytes(32).toString("hex"); const expiresAt = new Date(Date.now() + INVITE_EXPIRY_HOURS * 60 * 60 * 1000); try { // Store in database await db .insertInto("user_invites") .values({ email, token, expires_at: expiresAt, }) .execute(); } catch (e) { console.error("Error creating invite token:", e); throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Errore durante la creazione del token di invito.: ${(e as Error).message}`, }); } return token; } export async function verifyInviteToken(token: string) { try { const invite = await db .selectFrom("user_invites") .selectAll() .where("token", "=", token) .where("expires_at", ">", new Date()) .executeTakeFirst(); if (!invite) { return null; } return invite; } catch (e) { console.error("Error verifying invite token:", e); throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Errore durante la verifica del token di invito.: ${(e as Error).message}`, }); } } export async function consumeInviteToken(token: string) { try { await db.deleteFrom("user_invites").where("token", "=", token).execute(); } catch (e) { console.error("Error consuming invite token:", e); throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Errore durante il consumo del token di invito.: ${(e as Error).message}`, }); } } export const sendInvitoEmail = async ({ userId, email, inviteUrl, nome, }: { userId: UsersId; email: string; inviteUrl: string; nome: string; }) => { try { await NewMail({ template: { mailType: "invito", props: { inviteUrl, nome, }, }, mail: { subject: "Procedi ora su Infoalloggi.it", to: email, }, userId, }); return true; } catch (e) { throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Error sending email: ${(e as Error).message}`, }); } };