import { render } from "@react-email/render"; import { TRPCError } from "@trpc/server"; import ContattoAdminEmail, { type ContattoAdmin_NewMail, } from "emails/contatto"; import EmailContattoInteressato, { type ContattoInteressato_NewMail, } from "emails/email-interessato"; import type { PagamentoConferma_NewMail } from "emails/pagamento-conferma"; import PagamentoConferma from "emails/pagamento-conferma"; import type { PagamentoErrore_NewMail } from "emails/pagamento-errore"; import PagamentoErrore from "emails/pagamento-errore"; import type { PagamentoRicezione_NewMail } from "emails/pagamento-ricezione"; import PagamentoRicezione from "emails/pagamento-ricezione"; import type { PwResetLink_NewMail } from "emails/pw-reset-link"; import PwResetLink from "emails/pw-reset-link"; import type { Recesso_NewMail } from "emails/recesso"; import Recesso from "emails/recesso"; import type { RegistrazioneAvvenuta_NewMail } from "emails/registrazione-avvenuta"; import RegistrazioneAvvenuta from "emails/registrazione-avvenuta"; import { createTransport } from "nodemailer"; import { htmlToText } from "nodemailer-html-to-text"; import { env } from "~/env.mjs"; import type { JSX } from "react"; import VerificaEmail, { type VerificaEmail_NewMail, } from "emails/VerificaEmail"; import OnboardingServizio, { type OnboardingServizio_NewMail, } from "emails/onboarding-servizio"; import type { ContattoAnnuncio_NewMail } from "emails/contatto_annuncio"; import ContattoAnnuncioEmail from "emails/contatto_annuncio"; import type { UsersId } from "~/schemas/public/Users"; import { StoreEmail } from "~/server/services/email.service"; import type { Generic_NewMail } from "emails/gereric-email"; import Generic from "emails/gereric-email"; import { GetFlagValueHandler } from "~/server/controllers/flags.controller"; import { db } from "~/server/db"; type MailerProps = { to: string; subject: string; html: string; }; const mailer = async ({ to, subject, html }: MailerProps) => { const smtpTransport = createTransport({ host: "smtps.aruba.it", logger: false, debug: false, secure: true, port: 465, auth: { user: env.ARUBA_USER, pass: env.ARUBA_PASS, }, tls: { minVersion: "TLSv1", ciphers: "HIGH:MEDIUM:!aNULL:!eNULL:@STRENGTH:!DH:!kEDH", }, }); smtpTransport.use("compile", htmlToText()); const message = { from: env.ARUBA_USER, to: to, subject: subject, html: html, }; smtpTransport.sendMail(message, (err, info) => { if (err) { throw new Error(err.message); } return info; }); }; type base_NewMailProps = { userId?: UsersId; to: string; subject: string; }; export type NewMailProps = base_NewMailProps & MailsTemplates; export type MailsTemplates = | ContattoAdmin_NewMail | ContattoAnnuncio_NewMail | ContattoInteressato_NewMail | PagamentoConferma_NewMail | PagamentoErrore_NewMail | PagamentoRicezione_NewMail | PwResetLink_NewMail | Recesso_NewMail | RegistrazioneAvvenuta_NewMail | VerificaEmail_NewMail | OnboardingServizio_NewMail | Generic_NewMail; export const genMail = async ({ ...mail }: MailsTemplates) => { let mailComponent: JSX.Element | null = null; let title = ""; switch (mail.mailType) { case "contattoAdminEmail": mailComponent = ContattoAdminEmail({ ...mail.props, }); title = "Contatto amministratore"; break; case "contattoAnnuncioEmail": mailComponent = ContattoAnnuncioEmail({ ...mail.props, }); title = "Contatto annuncio"; break; case "emailContattoInteressato": mailComponent = EmailContattoInteressato({ ...mail.props, }); title = "Contatto interessato"; break; case "pagamentoConferma": mailComponent = PagamentoConferma({ ...mail.props, }); title = "Conferma pagamento"; break; case "pagamentoErrore": mailComponent = PagamentoErrore(); title = "Errore pagamento"; break; case "pagamentoRicezione": mailComponent = PagamentoRicezione(); title = "Ricezione pagamento"; break; case "pwResetLink": mailComponent = PwResetLink({ ...mail.props, }); title = "Reset password"; break; case "recesso": mailComponent = Recesso(); title = "Recesso"; break; case "registrazioneAvvenuta": mailComponent = RegistrazioneAvvenuta(); title = "Registrazione avvenuta"; break; case "verificaEmail": mailComponent = VerificaEmail({ ...mail.props, }); title = "Verifica email"; break; case "onboardingServizio": mailComponent = OnboardingServizio({ ...mail.props, }); title = "Onboarding Servizio"; break; case "generic": mailComponent = Generic({ ...mail.props, }); title = mail.props.title || "Email Generica"; break; } if (mailComponent === null) { throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: "Errore nella creazione dell'email", }); } return { html: await render(mailComponent), title }; }; export const NewMail = async ({ userId, to, subject, ...mail }: NewMailProps) => { const emailFlag = await GetFlagValueHandler({ db: db, id: "EMAIL_OFF", }); if (emailFlag === "true") { console.warn( `Email sending is disabled to:${to} subj:${subject} msgType: ${mail.mailType}`, ); return { success: true, message: `Email sending is disabled to:${to} subj:${subject} msgType: ${mail.mailType}`, }; } try { const { html } = await genMail({ ...mail }); await mailer({ to: to, subject: subject, html, }); if (userId) { // Store the email in the database if userId is provided await StoreEmail({ userId, data: mail }); } } catch (e) { throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: "Errore nell'invio dell'email: " + (e as Error).message, }); } };