Changeset ca507ef in Klonkt for src/config/mailer.js


Ignore:
Timestamp:
06/19/2026 08:29:28 AM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
7eb35ae
Parents:
977f65d
Message:

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@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/config/mailer.js

    r977f65d rca507ef  
    1 // E-mail versturen (wachtwoord-reset). Optioneel: alleen actief als de self-hoster
    2 // SMTP heeft ingesteld. Niet ingesteld? Dan valt de reset terug op de CLI
    3 // (`npm run reset-admin`) — zie README.
     1// E-mail versturen (wachtwoord-reset, nieuwsbrief, notify). Optioneel: alleen actief
     2// als SMTP is ingesteld — via Beheer → Instellingen (app_settings) OF env-vars.
    43//
    5 // Config via env:
    6 //   SMTP_HOST, SMTP_PORT (default 587), SMTP_USER, SMTP_PASS
    7 //   SMTP_FROM (afzender; default = SMTP_USER)
     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.
    87
    98import nodemailer from 'nodemailer';
     9import { getSetting } from '../services/SettingsService.js';
    1010
    11 const HOST = process.env.SMTP_HOST || '';
    12 const PORT = parseInt(process.env.SMTP_PORT || '587', 10);
    13 const USER = process.env.SMTP_USER || '';
    14 const PASS = process.env.SMTP_PASS || '';
    15 const FROM = process.env.SMTP_FROM || USER;
     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}
    1619
    1720export function mailerConfigured() {
    18   return !!(HOST && USER && PASS);
     21  const c = cfg();
     22  return !!(c.host && c.user && c.pass);
    1923}
    2024
    21 let _transport = null;
     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  };
     38}
     39
     40// Transport cachen, maar herbouwen zodra de config wijzigt (UI-edit zonder herstart).
     41let _transport = null, _key = null;
    2242function transport() {
    23   if (!_transport) {
     43  const c = cfg();
     44  const key = [c.host, c.port, c.user, c.pass].join('|');
     45  if (!_transport || _key !== key) {
    2446    _transport = nodemailer.createTransport({
    25       host: HOST,
    26       port: PORT,
    27       secure: PORT === 465, // 465 = impliciete TLS; 587 = STARTTLS
    28       auth: { user: USER, pass: PASS },
     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 },
    2951    });
     52    _key = key;
    3053  }
    3154  return _transport;
     
    3457export async function sendMail({ to, subject, text, html }) {
    3558  if (!mailerConfigured()) throw new Error('SMTP niet geconfigureerd');
    36   return transport().sendMail({ from: FROM, to, subject, text, html });
     59  const c = cfg();
     60  return transport().sendMail({ from: c.from, to, subject, text, html });
    3761}
Note: See TracChangeset for help on using the changeset viewer.