98 lines
3.2 KiB
JavaScript
98 lines
3.2 KiB
JavaScript
import { getDb } from '../models/db.js';
|
|
import bcrypt from 'bcryptjs';
|
|
|
|
function isAdmin(req, res, next) {
|
|
const userId = req.headers['x-user-id'];
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'Not authenticated' });
|
|
}
|
|
|
|
const db = getDb();
|
|
const user = db.prepare('SELECT username FROM users WHERE id = ?').get(userId);
|
|
|
|
if (!user || user.username !== 'admin') {
|
|
return res.status(403).json({ error: 'Admin access required' });
|
|
}
|
|
|
|
next();
|
|
}
|
|
|
|
export default function setupRoutes(app) {
|
|
// Get all users
|
|
app.get('/api/admin/users', isAdmin, (req, res) => {
|
|
const db = getDb();
|
|
const users = db.prepare('SELECT id, username, created_at FROM users ORDER BY created_at DESC').all();
|
|
res.json(users);
|
|
});
|
|
|
|
// Get all entries (admin view)
|
|
app.get('/api/admin/entries', isAdmin, (req, res) => {
|
|
const db = getDb();
|
|
const entries = db.prepare(`
|
|
SELECT e.*, u.username
|
|
FROM entries e
|
|
JOIN users u ON e.user_id = u.id
|
|
ORDER BY e.created_at DESC
|
|
LIMIT 100
|
|
`).all();
|
|
res.json(entries);
|
|
});
|
|
|
|
// Get stats
|
|
app.get('/api/admin/stats', isAdmin, (req, res) => {
|
|
const db = getDb();
|
|
|
|
const totalUsers = db.prepare('SELECT COUNT(*) as count FROM users').get().count;
|
|
const totalEntries = db.prepare('SELECT COUNT(*) as count FROM entries').get().count;
|
|
const todayEntries = db.prepare("SELECT COUNT(*) as count FROM entries WHERE date(created_at) = date('now')").get().count;
|
|
const topFoods = db.prepare(`SELECT name, COUNT(*) as count FROM entries GROUP BY name ORDER BY count DESC LIMIT 5`).all();
|
|
const todayCalories = db.prepare("SELECT COALESCE(SUM(calories), 0) as total FROM entries WHERE date(created_at) = date('now')").get().total;
|
|
|
|
res.json({ totalUsers, totalEntries, todayEntries, todayCalories, topFoods });
|
|
});
|
|
|
|
// Get activity log
|
|
app.get('/api/admin/activity', isAdmin, (req, res) => {
|
|
const db = getDb();
|
|
const limit = parseInt(req.query.limit) || 50;
|
|
const activity = db.prepare(`
|
|
SELECT al.*, u.username
|
|
FROM activity_log al
|
|
LEFT JOIN users u ON al.user_id = u.id
|
|
ORDER BY al.created_at DESC
|
|
LIMIT ?
|
|
`).all(limit);
|
|
res.json(activity);
|
|
});
|
|
|
|
// Delete user
|
|
app.delete('/api/admin/users/:id', isAdmin, (req, res) => {
|
|
const db = getDb();
|
|
const { id } = req.params;
|
|
const userId = req.headers['x-user-id'];
|
|
|
|
if (userId == id) {
|
|
return res.status(400).json({ error: 'Cannot delete yourself' });
|
|
}
|
|
|
|
db.prepare('DELETE FROM entries WHERE user_id = ?').run(id);
|
|
db.prepare('DELETE FROM activity_log WHERE user_id = ?').run(id);
|
|
db.prepare('DELETE FROM users WHERE id = ?').run(id);
|
|
|
|
res.json({ success: true });
|
|
});
|
|
|
|
// Reset password
|
|
app.post('/api/admin/users/:id/reset-password', isAdmin, (req, res) => {
|
|
const db = getDb();
|
|
const { id } = req.params;
|
|
const { password } = req.body;
|
|
|
|
const hash = bcrypt.hashSync(password, 10);
|
|
db.prepare('UPDATE users SET password = ? WHERE id = ?').run(hash, id);
|
|
db.prepare('INSERT INTO activity_log (user_id, action, details) VALUES (?, ?, ?)').run(id, 'password_reset', 'Password reset by admin');
|
|
|
|
res.json({ success: true });
|
|
});
|
|
}
|