A.7 — Move admin gate above the GET dispatch in /api/form
What's wrong
server/api/form/index.ts calls requireAdminSession() at line 484, but the entire if (method === 'GET') { ... } block is dispatched and returned before that line is reached. So all GET actions are anonymous: listFormGroups, listForms, getFormGroupSubmissions, resolveFormGroupRangeByDate, getOnlyActiveFormsinGroup.
getFormGroupSubmissions is the worst — it returns {studentName, studentId, formId, formTitle, submissionDate} for every submission in the group.
Why it matters
Same FERPA-style data leak as A.6 but for the entire admin surface. GET /api/form?action=getFormGroupSubmissions&formGroupId=1 (with id enumeration) yields the full roster of children, the forms they completed, and the timestamps.
How to fix
Move the auth call to the top of the handler, before the method/action dispatch:
export default defineEventHandler(async (event) => {
const method = event.node.req.method ?? 'GET'
const body = method === 'GET' ? null : ((await readBody(event).catch(() => null)) as Record<string, unknown> | null)
const action = getAction(event, body)
const { admin } = await requireAdmin(event) // <-- here, not at line 484
// ... rest unchanged
})
Alternatively, split into per-method/action files (see Group H — H.4 file naming).
Files
server/api/form/index.ts (lines 324-484)
Severity
C (Critical).
Acceptance
A.7 — Move admin gate above the GET dispatch in
/api/formWhat's wrong
server/api/form/index.tscallsrequireAdminSession()at line 484, but the entireif (method === 'GET') { ... }block is dispatched and returned before that line is reached. So all GET actions are anonymous:listFormGroups,listForms,getFormGroupSubmissions,resolveFormGroupRangeByDate,getOnlyActiveFormsinGroup.getFormGroupSubmissionsis the worst — it returns{studentName, studentId, formId, formTitle, submissionDate}for every submission in the group.Why it matters
Same FERPA-style data leak as A.6 but for the entire admin surface.
GET /api/form?action=getFormGroupSubmissions&formGroupId=1(with id enumeration) yields the full roster of children, the forms they completed, and the timestamps.How to fix
Move the auth call to the top of the handler, before the method/action dispatch:
Alternatively, split into per-method/action files (see Group H — H.4 file naming).
Files
server/api/form/index.ts(lines 324-484)Severity
C (Critical).
Acceptance