116 lines
4.6 KiB
JavaScript
116 lines
4.6 KiB
JavaScript
const express = require('express');
|
|
const { errorReportHelpers, logToFile } = require('../mariadb');
|
|
const { validateSession } = require('../sessionModel');
|
|
const router = express.Router();
|
|
|
|
// Middleware: require valid session (logged-in user)
|
|
const requireSession = async (req, res, next) => {
|
|
const sessionId = req.headers['x-session-id'] || (req.body && req.body.sessionId) || (req.query && req.query.sessionId);
|
|
if (!sessionId) return res.status(401).json({ error: 'Login required' });
|
|
const session = await validateSession(sessionId);
|
|
if (!session || !session.data || !session.data.playerName) {
|
|
return res.status(401).json({ error: 'Invalid or expired session' });
|
|
}
|
|
req.session = session;
|
|
req.sessionPlayerName = session.data.playerName;
|
|
next();
|
|
};
|
|
|
|
// POST /api/errors - Submit error report (requires login)
|
|
router.post('/', requireSession, async (req, res) => {
|
|
try {
|
|
const { title, description, category, pageUrl } = req.body;
|
|
if (!title || !description) {
|
|
return res.status(400).json({ error: 'Title and description are required' });
|
|
}
|
|
const id = await errorReportHelpers.create({
|
|
playerName: req.sessionPlayerName,
|
|
title,
|
|
description,
|
|
category: category || 'other',
|
|
pageUrl: pageUrl || ''
|
|
});
|
|
logToFile(`API: Error report #${id} created by ${req.sessionPlayerName}`);
|
|
res.json({ success: true, id });
|
|
} catch (error) {
|
|
logToFile('API: Error creating report', error);
|
|
res.status(500).json({ error: String(error) });
|
|
}
|
|
});
|
|
|
|
// GET /api/errors - List error reports (requires login, GM sees all, player sees their own)
|
|
router.get('/', requireSession, async (req, res) => {
|
|
try {
|
|
const isGM = req.sessionPlayerName && req.sessionPlayerName.toLowerCase() === 'gm';
|
|
const reports = isGM
|
|
? await errorReportHelpers.getAll()
|
|
: await errorReportHelpers.getByPlayer(req.sessionPlayerName);
|
|
res.json(reports);
|
|
} catch (error) {
|
|
logToFile('API: Error listing reports', error);
|
|
res.status(500).json({ error: String(error) });
|
|
}
|
|
});
|
|
|
|
// GET /api/errors/:id - Get one error report (requires login)
|
|
router.get('/:id', requireSession, async (req, res) => {
|
|
try {
|
|
const report = await errorReportHelpers.getById(parseInt(req.params.id));
|
|
if (!report) return res.status(404).json({ error: 'Not found' });
|
|
// Players can only see their own reports, GM sees all
|
|
const isGM = req.sessionPlayerName && req.sessionPlayerName.toLowerCase() === 'gm';
|
|
if (!isGM && report.player_name !== req.sessionPlayerName) {
|
|
return res.status(403).json({ error: 'Access denied' });
|
|
}
|
|
res.json(report);
|
|
} catch (error) {
|
|
logToFile('API: Error getting report', error);
|
|
res.status(500).json({ error: String(error) });
|
|
}
|
|
});
|
|
|
|
// PUT /api/errors/:id/resolve - Resolve error report (GM only)
|
|
router.put('/:id/resolve', requireSession, async (req, res) => {
|
|
try {
|
|
const isGM = req.sessionPlayerName && req.sessionPlayerName.toLowerCase() === 'gm';
|
|
if (!isGM) return res.status(403).json({ error: 'GM access required' });
|
|
const { note } = req.body;
|
|
await errorReportHelpers.resolve(parseInt(req.params.id), req.sessionPlayerName, note || '');
|
|
logToFile(`API: Error report #${req.params.id} resolved by ${req.sessionPlayerName}`);
|
|
res.json({ success: true });
|
|
} catch (error) {
|
|
logToFile('API: Error resolving report', error);
|
|
res.status(500).json({ error: String(error) });
|
|
}
|
|
});
|
|
|
|
// PUT /api/errors/:id/status - Update status (GM only)
|
|
router.put('/:id/status', requireSession, async (req, res) => {
|
|
try {
|
|
const isGM = req.sessionPlayerName && req.sessionPlayerName.toLowerCase() === 'gm';
|
|
if (!isGM) return res.status(403).json({ error: 'GM access required' });
|
|
const { status } = req.body;
|
|
await errorReportHelpers.updateStatus(parseInt(req.params.id), status);
|
|
res.json({ success: true });
|
|
} catch (error) {
|
|
logToFile('API: Error updating status', error);
|
|
res.status(500).json({ error: String(error) });
|
|
}
|
|
});
|
|
|
|
// DELETE /api/errors/:id - Delete error report (GM only)
|
|
router.delete('/:id', requireSession, async (req, res) => {
|
|
try {
|
|
const isGM = req.sessionPlayerName && req.sessionPlayerName.toLowerCase() === 'gm';
|
|
if (!isGM) return res.status(403).json({ error: 'GM access required' });
|
|
await errorReportHelpers.delete(parseInt(req.params.id));
|
|
logToFile(`API: Error report #${req.params.id} deleted by ${req.sessionPlayerName}`);
|
|
res.json({ success: true });
|
|
} catch (error) {
|
|
logToFile('API: Error deleting report', error);
|
|
res.status(500).json({ error: String(error) });
|
|
}
|
|
});
|
|
|
|
console.log('Error report routes registered');
|
|
module.exports = router; |