Maj Section Général
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* /api/admin/general — Paramètres généraux de l'application
|
||||
* Protégé par requireAuth + requireAdmin (appliqués dans server.js).
|
||||
*
|
||||
* GET / — retourne les 4 champs généraux
|
||||
* PATCH / — met à jour un ou plusieurs champs
|
||||
*
|
||||
* Route publique complémentaire : /api/app-info (server.js) expose
|
||||
* allowRegistration et minPasswordLength sans auth.
|
||||
*/
|
||||
|
||||
import { Router } from 'express';
|
||||
import { z } from 'zod';
|
||||
import db from '../db/index.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
router.get('/', (_req, res, next) => {
|
||||
try {
|
||||
ensureRow();
|
||||
const row = db.prepare('SELECT app_name, app_url, allow_registration, min_password_length FROM smtp_config WHERE id = 1').get();
|
||||
res.json({
|
||||
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); }
|
||||
});
|
||||
|
||||
const PatchSchema = z.object({
|
||||
appName: z.string().min(1).max(100).optional(),
|
||||
appUrl: z.string().max(500).optional(),
|
||||
allowRegistration: z.boolean().optional(),
|
||||
minPasswordLength: z.number().int().min(6).max(64).optional(),
|
||||
});
|
||||
|
||||
router.patch('/', (req, res, next) => {
|
||||
try {
|
||||
ensureRow();
|
||||
const body = PatchSchema.parse(req.body);
|
||||
const row = db.prepare('SELECT app_name, app_url, allow_registration, min_password_length FROM smtp_config WHERE id = 1').get();
|
||||
|
||||
db.prepare(`
|
||||
UPDATE smtp_config SET
|
||||
app_name = ?,
|
||||
app_url = ?,
|
||||
allow_registration = ?,
|
||||
min_password_length = ?
|
||||
WHERE id = 1
|
||||
`).run(
|
||||
body.appName !== undefined ? body.appName : (row.app_name || 'Crowdlending Tracker'),
|
||||
body.appUrl !== undefined ? body.appUrl : (row.app_url || ''),
|
||||
body.allowRegistration !== undefined ? (body.allowRegistration ? 1 : 0) : (row.allow_registration !== 0 ? 1 : 0),
|
||||
body.minPasswordLength !== undefined ? body.minPasswordLength : (row.min_password_length || 8),
|
||||
);
|
||||
|
||||
res.json({ ok: true });
|
||||
} catch (e) { next(e); }
|
||||
});
|
||||
|
||||
export default router;
|
||||
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* /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: `<p>Si vous recevez cet email, votre configuration SMTP fonctionne correctement.</p>`,
|
||||
}),
|
||||
});
|
||||
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;
|
||||
Reference in New Issue
Block a user