171 lines
5.7 KiB
JavaScript
171 lines
5.7 KiB
JavaScript
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;
|