import { TRPCError } from "@trpc/server"; import { z } from "zod"; import { env } from "~/env"; import { usersId } from "~/schemas/public/Users"; import { adminProcedure, createTRPCRouter, publicProcedure, } from "~/server/api/trpc"; import { createInviteToken, InviteAcceptance, InviteVerification, sendInvitoEmail, } from "~/server/controllers/invites.controller"; import { db } from "~/server/db"; import { findUser_byEmail, getUser } from "~/server/services/user.service"; export const inviteRouter = createTRPCRouter({ // Admin sends invite sendInvite: adminProcedure .input( z.object({ id: usersId, }), ) .mutation(async ({ input }) => { try { const user = await getUser({ userId: input.id, db }); const token = await createInviteToken(user.email); const inviteUrl = `${env.BASE_URL}/auth/accetta-invito/${token}?e=${btoa(user.email)}`; await sendInvitoEmail({ userId: input.id, email: user.email, nome: user.nome, //password: user.password, inviteUrl, }); return { success: true }; } catch (e) { console.error("Error in sendInvite:", e); throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: "Errore durante l'invio dell'invito: " + (e instanceof Error ? e.message : "Unknown error"), }); } }), requestNewInvite: publicProcedure .input(z.object({ email: z.email() })) .mutation(async ({ input }) => { try { const user = await findUser_byEmail({ email: input.email }); if (!user) { // For security, we don't reveal whether the email exists or not return { success: true }; } const token = await createInviteToken(user.email); const inviteUrl = `${env.BASE_URL}/auth/accetta-invito/${token}?e=${btoa(user.email)}`; await sendInvitoEmail({ userId: user.id, email: user.email, nome: user.nome, //password: user.password, inviteUrl, }); return { success: true }; } catch (e) { console.error("Error in requestNewInvite:", e); throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: "Errore durante la richiesta di un nuovo invito: " + (e instanceof Error ? e.message : "Unknown error"), }); } }), // Verify invite token (public - user clicking the link) verifyInvite: publicProcedure .input(z.object({ token: z.string(), email: z.string().nullable() })) .query(async ({ input }) => { return await InviteVerification(input.token, input.email); }), // Accept invite and set password acceptInvite: publicProcedure .input( z.object({ email: z.email(), token: z.string(), password: z.string().min(8), }), ) .mutation(async ({ input, ctx }) => { return await InviteAcceptance( ctx, input.token, input.email, input.password, ); }), });