/** * /api/admin/smtp — Gestion de la configuration SMTP * Protégé par requireAuth + requireAdmin (appliqués dans server.js). */ import { Router } from 'express'; import { z } from 'zod'; import db from '../db/index.js'; import { HttpError } from '../middleware/errorHandler.js'; import { sendMail, buildEmailHtml, getSmtpConfig } from '../utils/mailer.js'; const router = Router(); // ── Helpers ───────────────────────────────────────────────────────────────── function ensureRow() { const exists = db.prepare('SELECT id FROM smtp_config WHERE id = 1').get(); if (!exists) { db.prepare(` INSERT INTO smtp_config (id, enabled, host, port, secure, email, username, password, allow_unauth, app_name, app_url, allow_registration, min_password_length) VALUES (1, 0, '', 587, 0, '', '', '', 0, 'Crowdlending Tracker', '', 1, 8) `).run(); } } // ── GET /admin/smtp ───────────────────────────────────────────────────────── router.get('/', (_req, res, next) => { try { ensureRow(); const row = db.prepare('SELECT * FROM smtp_config WHERE id = 1').get(); res.json({ enabled: !!row.enabled, host: row.host || '', port: row.port || 587, secure: !!row.secure, email: row.email || '', username: row.username || '', hasPassword: !!(row.password), allowUnauth: !!row.allow_unauth, appName: row.app_name || 'Crowdlending Tracker', appUrl: row.app_url || '', allowRegistration: row.allow_registration !== 0, minPasswordLength: row.min_password_length || 8, }); } catch (e) { next(e); } }); // ── PUT /admin/smtp ───────────────────────────────────────────────────────── const SmtpSchema = z.object({ enabled: z.boolean().optional(), host: z.string().optional(), port: z.number().int().min(1).max(65535).optional(), secure: z.boolean().optional(), email: z.string().optional(), username: z.string().optional(), password: z.string().optional(), allowUnauth: z.boolean().optional(), appName: z.string().max(100).optional(), appUrl: z.string().max(500).optional(), }); router.put('/', (req, res, next) => { try { ensureRow(); const body = SmtpSchema.parse(req.body); const row = db.prepare('SELECT * FROM smtp_config WHERE id = 1').get(); const updates = { enabled: body.enabled !== undefined ? (body.enabled ? 1 : 0) : row.enabled, host: body.host !== undefined ? body.host : row.host, port: body.port !== undefined ? body.port : row.port, secure: body.secure !== undefined ? (body.secure ? 1 : 0) : row.secure, email: body.email !== undefined ? body.email : row.email, username: body.username !== undefined ? body.username : row.username, password: body.password !== undefined ? body.password : row.password, allow_unauth: body.allowUnauth !== undefined ? (body.allowUnauth ? 1 : 0) : row.allow_unauth, app_name: body.appName !== undefined ? body.appName : row.app_name, app_url: body.appUrl !== undefined ? body.appUrl : row.app_url, }; db.prepare(` UPDATE smtp_config SET enabled=?, host=?, port=?, secure=?, email=?, username=?, password=?, allow_unauth=?, app_name=?, app_url=? WHERE id=1 `).run( updates.enabled, updates.host, updates.port, updates.secure, updates.email, updates.username, updates.password, updates.allow_unauth, updates.app_name, updates.app_url, ); res.json({ ok: true }); } catch (e) { next(e); } }); // ── POST /admin/smtp/test ─────────────────────────────────────────────────── router.post('/test', async (req, res, next) => { try { const { to } = z.object({ to: z.string().email() }).parse(req.body); const cfg = getSmtpConfig(); if (!cfg.host) throw new HttpError(400, 'Aucun serveur SMTP configuré.'); await sendMail({ to, subject: `Test SMTP — ${cfg.appName}`, html: buildEmailHtml({ title: 'Email de test', body: `
Si vous recevez cet email, votre configuration SMTP fonctionne correctement.
`, }), }); res.json({ ok: true, msg: `Email de test envoyé à ${to}.` }); } catch (e) { next(e); } }); // ── GET /admin/smtp/env ───────────────────────────────────────────────────── router.get('/env', (_req, res) => { res.json({ host: process.env.SMTP_HOST || '', port: parseInt(process.env.SMTP_PORT || '587', 10), email: process.env.SMTP_EMAIL || '', username: process.env.SMTP_USERNAME || '', appName: process.env.APP_NAME || '', appUrl: process.env.APP_URL || '', }); }); export default router;