import nodemailer from 'nodemailer'; import { createSSRApp, h } from 'vue'; import { renderToString } from 'vue/server-renderer'; import base from '../components/mail/base.vue'; import Registration from '../components/mail/registration.vue'; import ResetPassword from '../components/mail/reset-password.vue'; const config = useRuntimeConfig(); const [domain, selector, dkim] = config.mail.dkim.split(":"); export const templates: Record = { "registration": { component: Registration, subject: 'Bienvenue sur d[any] 😎' }, "reset-password": { component: ResetPassword, subject: 'Réinitialisation de votre mot de passe' }, }; import type Mail from 'nodemailer/lib/mailer'; interface MailPayload { type: 'mail' to: string[] template: string data: Record } const transport = nodemailer.createTransport({ //@ts-ignore pool: true, host: config.mail.host, port: config.mail.port, secure: config.mail.port === "465", auth: { user: config.mail.user, pass: config.mail.passwd, }, tls: { rejectUnauthorized: config.mail.port !== "465" }, dkim: { domainName: domain, keySelector: selector, privateKey: dkim, }, proxy: config.mail.proxy, }); if(process.env.NODE_ENV === 'production') { transport.verify((error) => { if(error) { console.log('Mail server cannot be reached'); console.error(error); } else console.log("Mail server is reachable and ready to communicate"); }); } export default async function(e: TaskEvent) { try { if(e.payload.type !== 'mail') { throw new Error(`Données inconnues`); } const payload = e.payload as MailPayload; const template = templates[payload.template]; if(!template) { throw new Error(`Modèle de mail ${payload.template} inconnu`); } console.time('Generating HTML'); const mail: Mail.Options = { from: 'd[any] - Ne pas répondre ', to: payload.to, html: await render(template.component, payload.data), subject: template.subject, textEncoding: 'quoted-printable', }; console.timeEnd('Generating HTML'); if(mail.html === '') return { result: false, error: new Error("Invalid content") }; console.time('Sending Mail'); const status = await transport.sendMail(mail); console.timeEnd('Sending Mail'); if(status.rejected.length > 0) { return { result: false, error: status.response, details: status.rejectedErrors }; } return { result: true }; } catch(e) { console.error(e); return { result: false, error: e }; } } async function render(component: any, data: Record): Promise { const app = createSSRApp({ render(){ return h(base, null, { default: () => h(component, data, { default: () => null }) }); } }); const html = await renderToString(app); return (`
${html}
`); }