infoalloggi-monorepo/apps/infoalloggi/src/server/controllers/invites.controller.ts

102 lines
2.2 KiB
TypeScript
Raw Normal View History

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}`,
});
}
};