fix(feedback): stop exposing done_by user id in API responses

Problem: GET /api/feedback (moderator-readable) returned the user id of
the admin who marked an entry done. Moderators don't need to triangulate
"which admin closed which ticket" — done_at alone is sufficient signal
that the entry has been triaged. Keeping the user id in the response
made it possible to cross-reference admins with the user list via a
second authenticated call.

Fix: the `feedback.done_by` column stays in the schema (server-side
audit trail is preserved) but the column is no longer SELECTed by the
list or update endpoints, and is no longer in the FeedbackEntry wire
type. Moderators see only the `done_at` timestamp.

Surfaced by /audit security (data exposure lens).
This commit is contained in:
Ole-Morten Duesund 2026-05-25 13:54:07 +02:00
commit fbe37109a4
2 changed files with 9 additions and 5 deletions

View file

@ -40,7 +40,7 @@ feedbackRoutes.post('/', requireAuth, async (c) => {
const entry: FeedbackEntry = {
id, kind: body.kind, body: trimmed, created_at: Date.now(),
done_at: null, done_by: null,
done_at: null,
};
return c.json(entry, 201);
});
@ -49,9 +49,11 @@ feedbackRoutes.get('/', requireAuth, (c) => {
const userId = c.get('userId');
if (!isModerator(userId)) return c.json({ error: 'forbidden' }, 403);
// done_by is intentionally NOT selected — it's stored for server-side audit
// but never returned via the API. See FeedbackEntry doc in shared/types.ts.
const rows = getDb()
.prepare(`
SELECT f.id, f.kind, f.body, f.created_at, f.done_at, f.done_by,
SELECT f.id, f.kind, f.body, f.created_at, f.done_at,
f.user_id, u.email AS user_email, u.display_name AS user_display
FROM feedback f
JOIN users u ON u.id = f.user_id
@ -85,7 +87,7 @@ feedbackRoutes.patch('/:id', requireAuth, async (c) => {
}
const row = db.prepare(`
SELECT f.id, f.kind, f.body, f.created_at, f.done_at, f.done_by,
SELECT f.id, f.kind, f.body, f.created_at, f.done_at,
f.user_id, u.email AS user_email, u.display_name AS user_display
FROM feedback f
JOIN users u ON u.id = f.user_id