obsidian-visualiser/server/tasks/mail.ts

122 lines
3.5 KiB
TypeScript

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<string, { component: any, subject: string }> = {
"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
{
to: string[];
template: string;
data: Record<string, any>;
}
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: false },
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 defineTask({
meta: {
name: 'mail',
description: ''
},
run: async ({ payload, context }) => {
try {
if(payload.type !== 'mail')
{
throw new Error(`Données inconnues`);
}
const mailPayload = payload.data as MailPayload;
const template = templates[mailPayload.template];
console.log(mailPayload);
if(!template)
{
throw new Error(`Modèle de mail ${mailPayload.template} inconnu`);
}
console.time('Generating HTML');
const mail: Mail.Options = {
from: 'd[any] - Ne pas répondre <no-reply@peaceultime.com>',
to: mailPayload.to,
html: await render(template.component, mailPayload.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<string, any>): Promise<string>
{
const app = createSSRApp({
render(){
return h(base, null, { default: () => h(component, data, { default: () => null }) });
}
});
const html = await renderToString(app);
return (`<html><body><div>${html}</div></body></html>`);
}