const express = require('express'); const router = express.Router(); const { db } = require('../db'); const { v4: uuidv4 } = require('uuid'); function requireAuth(req, res, next) { if (req.session && req.session.authenticated) { return next(); } res.redirect('/admin/login'); } router.get('/login', (req, res) => { if (req.session && req.session.authenticated) { return res.redirect('/admin'); } res.render('admin/login', { error: null }); }); router.post('/login', (req, res) => { const { username, password } = req.body; const adminUser = process.env.ADMIN_USERNAME || 'admin'; const adminPass = process.env.ADMIN_PASSWORD || 'changeme123'; if (username === adminUser && password === adminPass) { console.log("[DEBUG] Connexion OK") req.session.authenticated = true; req.session.username = username; return req.session.save((err) => { if (err) { console.error('Session save error:', err); } return res.redirect('/admin'); }); } res.render('admin/login', { error: 'Identifiants incorrects' }); }); router.get('/logout', (req, res) => { req.session.destroy(() => { res.redirect('/admin/login'); }); }); router.use(requireAuth); router.get('/', (req, res) => { const status = req.query.status || 'all'; const language = req.query.language || 'all'; // Filtre langue identique au site public (repli sur la langue de la source) const languageExpr = `COALESCE(language, source_language, 'fr')`; const conditions = []; const params = []; if (status !== 'all') { conditions.push(`status = ?`); params.push(status); } if (language !== 'all') { conditions.push(`${languageExpr} = ?`); params.push(language); } const where = conditions.length > 0 ? ` WHERE ${conditions.join(' AND ')}` : ''; const articles = db .prepare(`SELECT * FROM articles${where} ORDER BY datetime(created_at) DESC`) .all(...params); // Stats (filtrées sur la langue sélectionnée) const stats = {}; ['pending', 'published', 'hidden', 'rejected'].forEach(s => { const statParams = [s]; let statQuery = `SELECT COUNT(*) as c FROM articles WHERE status = ?`; if (language !== 'all') { statQuery += ` AND ${languageExpr} = ?`; statParams.push(language); } stats[s] = db.prepare(statQuery).get(...statParams).c; }); let totalQuery = `SELECT COUNT(*) as c FROM articles`; const totalParams = []; if (language !== 'all') { totalQuery += ` WHERE ${languageExpr} = ?`; totalParams.push(language); } stats.total = db.prepare(totalQuery).get(...totalParams).c; // Langues disponibles dans l'ensemble des articles const languages = db .prepare(`SELECT ${languageExpr} as lang, COUNT(*) as c FROM articles GROUP BY lang ORDER BY c DESC, lang`) .all(); res.render('admin/dashboard', { articles, status, stats, languages, language }); }); router.post('/article/:id/validate', (req, res) => { const { id } = req.params; const { categories, summary } = req.body; try { const categoriesJson = categories ? JSON.stringify(categories.split(',').map(c => c.trim()).filter(Boolean)) : null; db.prepare(`UPDATE articles SET status='published', categories=COALESCE(?, categories), summary=COALESCE(?, summary), updated_at=datetime('now') WHERE id=?`) .run(categoriesJson, summary || null, id); db.prepare(`INSERT INTO activity_log (action, article_id, details) VALUES ('validate', ?, 'Article publié')`).run(id); res.redirect(req.get('referer') || '/admin'); } catch(e) { console.error(e); res.redirect('/admin'); } }); router.post('/article/:id/hide', (req, res) => { const { id } = req.params; db.prepare(`UPDATE articles SET status='hidden', updated_at=datetime('now') WHERE id=?`).run(id); db.prepare(`INSERT INTO activity_log (action, article_id, details) VALUES ('hide', ?, 'Article masqué')`).run(id); res.redirect(req.get('referer') || '/admin'); }); router.post('/article/:id/reject', (req, res) => { const { id } = req.params; db.prepare(`UPDATE articles SET status='rejected', updated_at=datetime('now') WHERE id=?`).run(id); db.prepare(`INSERT INTO activity_log (action, article_id, details) VALUES ('reject', ?, 'Article rejeté')`).run(id); res.redirect(req.get('referer') || '/admin'); }); router.post('/article/:id/publish', (req, res) => { const { id } = req.params; db.prepare(`UPDATE articles SET status='published', updated_at=datetime('now') WHERE id=?`).run(id); db.prepare(`INSERT INTO activity_log (action, article_id, details) VALUES ('publish', ?, 'Article republié')`).run(id); res.redirect(req.get('referer') || '/admin'); }); router.post('/article/:id/delete', (req, res) => { const { id } = req.params; db.prepare(`DELETE FROM articles WHERE id=?`).run(id); db.prepare(`INSERT INTO activity_log (action, article_id, details) VALUES ('delete', ?, 'Article supprimé')`).run(id); res.redirect(req.get('referer') || '/admin'); }); router.post('/collect', (req, res) => { const { collect } = require('../../collector/index'); collect().then(() => { db.prepare(`INSERT INTO activity_log (action, details) VALUES ('collect', 'Collecte manuelle déclenchée')`).run(); res.redirect('/admin?status=pending'); }).catch(err => { console.error(err); res.redirect('/admin'); }); }); router.get('/sources', (req, res) => { const sourcesPath = require('path').join(__dirname, '..', '..', 'config', 'sources.json'); const sources = JSON.parse(require('fs').readFileSync(sourcesPath, 'utf8')); res.render('admin/sources', { sources }); }); router.get('/log', (req, res) => { const logs = db.prepare(`SELECT * FROM activity_log ORDER BY datetime(created_at) DESC LIMIT 100`).all(); res.render('admin/log', { logs }); }); module.exports = router;