source: Klonkt/src/config/mailer.js@ 7990e00

main
Last change on this file since 7990e00 was ca507ef, checked in by roboburr <roboburr@…>, 3 months ago

feat: SMTP configurable via Admin → Settings (app_settings, env fallback) + test email

  • config/mailer.js: reads SMTP from app_settings (smtp_host/port/user/pass/from), with env as fallback; transport rebuilds automatically on change (no restart needed); mailerStatus() for the UI (without leaking the password).
  • admin-settings: POST /smtp (save; password only updated when a new value is given; clear) + POST /smtp/test (test email). GET includes smtp status.
  • admin-settings.ejs: Email (SMTP) card with host/port/user/pass/from + save/ clear + test-email button (only shown when configured).

Once SMTP is filled in, newsletter sending, show-notify and double opt-in work.

Co-Authored-By: Claude <noreply@…>

  • Property mode set to 100644
File size: 2.2 KB
RevLine 
[ca507ef]1// E-mail versturen (wachtwoord-reset, nieuwsbrief, notify). Optioneel: alleen actief
2// als SMTP is ingesteld — via Beheer → Instellingen (app_settings) OF env-vars.
[9e27d64]3//
[ca507ef]4// Config-bron (in deze volgorde): app_settings (ingesteld in de UI), anders env:
5// SMTP_HOST, SMTP_PORT (default 587), SMTP_USER, SMTP_PASS, SMTP_FROM (default = USER)
6// Niet ingesteld → versturen valt terug op CLI (reset-admin) / wordt overgeslagen.
[9e27d64]7
8import nodemailer from 'nodemailer';
[ca507ef]9import { getSetting } from '../services/SettingsService.js';
[9e27d64]10
[ca507ef]11function cfg() {
12 const host = getSetting('smtp_host', '') || process.env.SMTP_HOST || '';
13 const port = parseInt(getSetting('smtp_port', '') || process.env.SMTP_PORT || '587', 10) || 587;
14 const user = getSetting('smtp_user', '') || process.env.SMTP_USER || '';
15 const pass = getSetting('smtp_pass', '') || process.env.SMTP_PASS || '';
16 const from = getSetting('smtp_from', '') || process.env.SMTP_FROM || user;
17 return { host, port, user, pass, from };
18}
[9e27d64]19
20export function mailerConfigured() {
[ca507ef]21 const c = cfg();
22 return !!(c.host && c.user && c.pass);
23}
24
25// Status voor de UI (zonder het wachtwoord te lekken).
26export function mailerStatus() {
27 const c = cfg();
28 return {
29 configured: mailerConfigured(),
30 host: c.host,
31 port: c.port,
32 user: c.user,
33 from: c.from,
34 passSet: !!c.pass,
35 // bron: handig om te tonen dat env nog actief is
36 fromEnv: !getSetting('smtp_host', '') && !!process.env.SMTP_HOST,
37 };
[9e27d64]38}
39
[ca507ef]40// Transport cachen, maar herbouwen zodra de config wijzigt (UI-edit zonder herstart).
41let _transport = null, _key = null;
[9e27d64]42function transport() {
[ca507ef]43 const c = cfg();
44 const key = [c.host, c.port, c.user, c.pass].join('|');
45 if (!_transport || _key !== key) {
[9e27d64]46 _transport = nodemailer.createTransport({
[ca507ef]47 host: c.host,
48 port: c.port,
49 secure: c.port === 465, // 465 = impliciete TLS; 587 = STARTTLS
50 auth: { user: c.user, pass: c.pass },
[9e27d64]51 });
[ca507ef]52 _key = key;
[9e27d64]53 }
54 return _transport;
55}
56
57export async function sendMail({ to, subject, text, html }) {
58 if (!mailerConfigured()) throw new Error('SMTP niet geconfigureerd');
[ca507ef]59 const c = cfg();
60 return transport().sendMail({ from: c.from, to, subject, text, html });
[9e27d64]61}
Note: See TracBrowser for help on using the repository browser.