Index: src/config/mailer.js
===================================================================
--- src/config/mailer.js	(revision 977f65dcbd1516c5c9fc5ede25fb4f04159c5872)
+++ src/config/mailer.js	(revision ca507ef52c838114528326fef0f84d202c7147f7)
@@ -1,31 +1,54 @@
-// E-mail versturen (wachtwoord-reset). Optioneel: alleen actief als de self-hoster
-// SMTP heeft ingesteld. Niet ingesteld? Dan valt de reset terug op de CLI
-// (`npm run reset-admin`) — zie README.
+// E-mail versturen (wachtwoord-reset, nieuwsbrief, notify). Optioneel: alleen actief
+// als SMTP is ingesteld — via Beheer → Instellingen (app_settings) OF env-vars.
 //
-// Config via env:
-//   SMTP_HOST, SMTP_PORT (default 587), SMTP_USER, SMTP_PASS
-//   SMTP_FROM (afzender; default = SMTP_USER)
+// Config-bron (in deze volgorde): app_settings (ingesteld in de UI), anders env:
+//   SMTP_HOST, SMTP_PORT (default 587), SMTP_USER, SMTP_PASS, SMTP_FROM (default = USER)
+// Niet ingesteld → versturen valt terug op CLI (reset-admin) / wordt overgeslagen.
 
 import nodemailer from 'nodemailer';
+import { getSetting } from '../services/SettingsService.js';
 
-const HOST = process.env.SMTP_HOST || '';
-const PORT = parseInt(process.env.SMTP_PORT || '587', 10);
-const USER = process.env.SMTP_USER || '';
-const PASS = process.env.SMTP_PASS || '';
-const FROM = process.env.SMTP_FROM || USER;
+function cfg() {
+  const host = getSetting('smtp_host', '') || process.env.SMTP_HOST || '';
+  const port = parseInt(getSetting('smtp_port', '') || process.env.SMTP_PORT || '587', 10) || 587;
+  const user = getSetting('smtp_user', '') || process.env.SMTP_USER || '';
+  const pass = getSetting('smtp_pass', '') || process.env.SMTP_PASS || '';
+  const from = getSetting('smtp_from', '') || process.env.SMTP_FROM || user;
+  return { host, port, user, pass, from };
+}
 
 export function mailerConfigured() {
-  return !!(HOST && USER && PASS);
+  const c = cfg();
+  return !!(c.host && c.user && c.pass);
 }
 
-let _transport = null;
+// Status voor de UI (zonder het wachtwoord te lekken).
+export function mailerStatus() {
+  const c = cfg();
+  return {
+    configured: mailerConfigured(),
+    host: c.host,
+    port: c.port,
+    user: c.user,
+    from: c.from,
+    passSet: !!c.pass,
+    // bron: handig om te tonen dat env nog actief is
+    fromEnv: !getSetting('smtp_host', '') && !!process.env.SMTP_HOST,
+  };
+}
+
+// Transport cachen, maar herbouwen zodra de config wijzigt (UI-edit zonder herstart).
+let _transport = null, _key = null;
 function transport() {
-  if (!_transport) {
+  const c = cfg();
+  const key = [c.host, c.port, c.user, c.pass].join('|');
+  if (!_transport || _key !== key) {
     _transport = nodemailer.createTransport({
-      host: HOST,
-      port: PORT,
-      secure: PORT === 465, // 465 = impliciete TLS; 587 = STARTTLS
-      auth: { user: USER, pass: PASS },
+      host: c.host,
+      port: c.port,
+      secure: c.port === 465, // 465 = impliciete TLS; 587 = STARTTLS
+      auth: { user: c.user, pass: c.pass },
     });
+    _key = key;
   }
   return _transport;
@@ -34,4 +57,5 @@
 export async function sendMail({ to, subject, text, html }) {
   if (!mailerConfigured()) throw new Error('SMTP niet geconfigureerd');
-  return transport().sendMail({ from: FROM, to, subject, text, html });
+  const c = cfg();
+  return transport().sendMail({ from: c.from, to, subject, text, html });
 }
Index: src/routes/admin-settings.js
===================================================================
--- src/routes/admin-settings.js	(revision 977f65dcbd1516c5c9fc5ede25fb4f04159c5872)
+++ src/routes/admin-settings.js	(revision ca507ef52c838114528326fef0f84d202c7147f7)
@@ -22,4 +22,5 @@
 import { requireGod } from '../middleware/auth.js';
 import { getTenancy, setTenancy, getSetting, setSetting } from '../services/SettingsService.js';
+import { mailerStatus, sendMail } from '../config/mailer.js';
 import { entitlementStatus, premiumUnlocked } from '../services/PatreonService.js';
 import { googleConfigured, redirectUri, currentClientId, clientSecretSet } from '../config/google.js';
@@ -83,4 +84,5 @@
       secretSet: clientSecretSet(),
     },
+    smtp: mailerStatus(),
     success: req.query.success || null,
     error: req.query.error || null,
@@ -151,3 +153,39 @@
 });
 
+// ── SMTP / e-mail-instellingen ────────────────────────────────────
+router.post('/smtp', requireGod, (req, res) => {
+  const b = req.body || {};
+  if (b.clear === '1') {
+    ['smtp_host', 'smtp_port', 'smtp_user', 'smtp_pass', 'smtp_from'].forEach((k) => setSetting(k, ''));
+    return res.redirect('/admin/settings?success=' + encodeURIComponent('SMTP-instellingen gewist'));
+  }
+  setSetting('smtp_host', (b.smtp_host || '').toString().trim());
+  setSetting('smtp_port', (b.smtp_port || '').toString().trim());
+  setSetting('smtp_user', (b.smtp_user || '').toString().trim());
+  setSetting('smtp_from', (b.smtp_from || '').toString().trim());
+  // Wachtwoord alleen overschrijven als er een nieuwe waarde is ingevoerd.
+  const pass = (b.smtp_pass || '').toString();
+  if (pass) setSetting('smtp_pass', pass);
+  res.redirect('/admin/settings?success=' + encodeURIComponent('SMTP-instellingen opgeslagen'));
+});
+
+// Testmail sturen naar een opgegeven adres (of de ingelogde gebruiker).
+router.post('/smtp/test', requireGod, async (req, res) => {
+  const to = ((req.body && req.body.to) || (req.session.user && req.session.user.email) || '').toString().trim();
+  if (!to || to.indexOf('@') === -1) {
+    return res.redirect('/admin/settings?error=' + encodeURIComponent('Geef een geldig test-e-mailadres op.'));
+  }
+  try {
+    await sendMail({
+      to,
+      subject: 'Klonkt — SMTP-test',
+      text: 'Gelukt! Je SMTP-instellingen werken. Dit is een testbericht van je Klonkt-site.',
+      html: '<p>Gelukt! Je <strong>SMTP-instellingen werken</strong>. Dit is een testbericht van je Klonkt-site.</p>',
+    });
+    res.redirect('/admin/settings?success=' + encodeURIComponent('Testmail verstuurd naar ' + to));
+  } catch (e) {
+    res.redirect('/admin/settings?error=' + encodeURIComponent('Testmail mislukt: ' + (e.message || e)));
+  }
+});
+
 export default router;
Index: src/views/pages/admin-settings.ejs
===================================================================
--- src/views/pages/admin-settings.ejs	(revision 977f65dcbd1516c5c9fc5ede25fb4f04159c5872)
+++ src/views/pages/admin-settings.ejs	(revision ca507ef52c838114528326fef0f84d202c7147f7)
@@ -110,4 +110,44 @@
     <% if (typeof premiumEnabled !== 'undefined' && premiumEnabled && !(premium && premium.premium)) { %>
       <p class="set-help" style="margin-top:.7rem; color:var(--accent)">Premium-laag staat aan zonder Patreon — de Google-knop blijft verborgen tot premium ontgrendeld is.</p>
+    <% } %>
+  </section>
+
+  <%# E-mail / SMTP — nodig voor nieuwsbrief versturen, notify-mails en wachtwoord-reset. %>
+  <section class="set-card" style="margin-top:1rem">
+    <h2>E-mail (SMTP)</h2>
+    <p class="set-help">Nodig om de <strong>nieuwsbrief te versturen</strong>, <strong>show-notify</strong>-mails te sturen en wachtwoord-reset per mail te laten werken. Vul de gegevens van je mailprovider in (bv. je hostingmail, Gmail-app-wachtwoord, Brevo, Mailgun…).
+      <% if (smtp && smtp.configured) { %><br><strong>Status: ingesteld&nbsp;✓</strong><% if (smtp.fromEnv) { %> <small>(via .env)</small><% } %><% } else { %><br>Nog niet ingesteld — versturen werkt nog niet.<% } %></p>
+
+    <form method="post" action="/admin/settings/smtp" class="set-form">
+      <label><span>SMTP-host</span>
+        <input type="text" name="smtp_host" value="<%= smtp ? smtp.host : '' %>" placeholder="smtp.jouwprovider.nl" autocomplete="off">
+      </label>
+      <label><span>Poort <small style="font-weight:400">— 587 (STARTTLS) of 465 (SSL)</small></span>
+        <input type="text" name="smtp_port" value="<%= (smtp && smtp.port) ? smtp.port : '' %>" placeholder="587" autocomplete="off" inputmode="numeric">
+      </label>
+      <label><span>Gebruikersnaam</span>
+        <input type="text" name="smtp_user" value="<%= smtp ? smtp.user : '' %>" placeholder="jij@jouwprovider.nl" autocomplete="off">
+      </label>
+      <label><span>Wachtwoord <% if (smtp && smtp.passSet) { %><small style="font-weight:400">— ingesteld; leeg laten = ongewijzigd</small><% } %></span>
+        <input type="password" name="smtp_pass" placeholder="<%= (smtp && smtp.passSet) ? '•••••••• (ingesteld)' : 'app-wachtwoord' %>" autocomplete="off">
+      </label>
+      <label><span>Afzender <small style="font-weight:400">— optioneel; standaard = gebruikersnaam</small></span>
+        <input type="text" name="smtp_from" value="<%= smtp ? smtp.from : '' %>" placeholder="Jouw Naam &lt;jij@jouwprovider.nl&gt;" autocomplete="off">
+      </label>
+      <div class="set-actions">
+        <button type="submit" class="btn btn-primary">SMTP opslaan</button>
+        <% if (smtp && (smtp.host || smtp.passSet)) { %>
+          <button type="submit" name="clear" value="1" class="btn" formnovalidate>Wissen</button>
+        <% } %>
+      </div>
+    </form>
+
+    <% if (smtp && smtp.configured) { %>
+      <form method="post" action="/admin/settings/smtp/test" class="set-form" style="margin-top:.8rem">
+        <label><span>Testmail sturen naar</span>
+          <input type="email" name="to" placeholder="jij@email.nl" autocomplete="off">
+        </label>
+        <div class="set-actions"><button type="submit" class="btn">✉ Testmail sturen</button></div>
+      </form>
     <% } %>
   </section>
