diff --git a/components/base/Select.vue b/components/base/Select.vue index 3520675..35afcfd 100644 --- a/components/base/Select.vue +++ b/components/base/Select.vue @@ -1,6 +1,6 @@ diff --git a/nuxt.config.ts b/nuxt.config.ts index 1dd8c34..f07bf3a 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -1,4 +1,6 @@ // https://nuxt.com/docs/api/configuration/nuxt-config +import PluginVue from '@vitejs/plugin-vue'; + export default defineNuxtConfig({ compatibilityDate: '2024-04-03', modules: [ @@ -114,11 +116,20 @@ export default defineNuxtConfig({ path: '~/components', pathPrefix: false, }, + { + path: '~/server/components', + pathPrefix: true, + global: true, + }, ], nitro: { + preset: 'bun', experimental: { tasks: true, }, + rollupConfig: { + plugins: [ PluginVue() ], + }, }, runtimeConfig: { session: { diff --git a/pages/admin/index.vue b/pages/admin/index.vue index cba1ae3..9e4d728 100644 --- a/pages/admin/index.vue +++ b/pages/admin/index.vue @@ -1,8 +1,8 @@ \ No newline at end of file diff --git a/server/components/mail/revalidation.vue b/server/components/mail/revalidation.vue new file mode 100644 index 0000000..5198bcf --- /dev/null +++ b/server/components/mail/revalidation.vue @@ -0,0 +1,20 @@ + + + \ No newline at end of file diff --git a/server/tasks/mail.ts b/server/tasks/mail.ts index b0c3f57..897a76e 100644 --- a/server/tasks/mail.ts +++ b/server/tasks/mail.ts @@ -1,9 +1,34 @@ 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 revalidation from '../components/mail/revalidation.vue'; const config = useRuntimeConfig(); const [domain, selector, dkim] = config.mail.dkim.split(":"); +export const templates: Record = { + "registration": { component: registration, subject: 'Bienvenue sur d[any] 😎' }, + "revalidate-mail": { component: revalidation, subject: 'd[any]: Valider votre email' }, +}; + +import 'nitropack/types'; +import type Registration from '../components/mail/registration.vue'; +declare module 'nitropack/types' +{ + interface TaskPayload + { + type: 'mail' + to: string[] + template: string + data: Record + } +} + const transport = nodemailer.createTransport({ + //@ts-ignore pool: true, host: config.mail.host, port: config.mail.port, @@ -27,13 +52,35 @@ export default defineTask({ }, async run(e) { try { - const payload: { to: string[], message: string, subject: string } = e.payload; - const status = await transport.sendMail({ - from: 'Message automatique d[any] ', + if(e.payload.type !== 'mail') + { + throw new Error(`Données inconnues`); + } + + const payload = e.payload; + const template = templates[payload.template]; + + if(!template) + { + throw new Error(`Modèle de mail ${payload.template} inconnu`); + } + + const mail = { + from: 'd[any] - Ne pas répondre ', to: payload.to, - text: payload.message, - subject: payload.subject, - }); + html: await render(template.component, payload.data), + subject: template.subject, + attachments: [{ + filename: 'logo.svg', + path: '../../public/logo.dark.svg', + cid: 'logo.obsidian.peaceultime.com', + }] + }; + + if(mail.html === '') + return { result: false, error: new Error("Invalid content") }; + + const status = await transport.sendMail(mail); if(status.rejected.length > 0) { @@ -47,4 +94,15 @@ export default defineTask({ return { result: false, error: e }; } }, -}) \ No newline at end of file +}) + +async function render(component: any, data: Record): Promise +{ + const app = createSSRApp({ + render(){ + return h(base, null, { default: () => h(component, data, []) }); + } + }); + + return await renderToString(app); +} \ No newline at end of file