Put the feedback and tickets admin areas behind the shared identity #13

Merged
Paddy merged 2 commits from feature/admin-auth-cutover into master 2026-09-06 19:06:30 +00:00
2 changed files with 18 additions and 1 deletions
Showing only changes of commit 9811610d55 - Show all commits
+13 -1
View File
@@ -11,7 +11,19 @@ These items were identified during a security review on 2026-05-02 and conscious
`sessionId` and `sessionKey` are currently read from query parameters, which means they appear in server access logs, browser history, proxy logs, and `Referer` headers.
**Fix:** Move to request headers (`X-Session-Id` / `X-Session-Key`) or the request body. Requires a corresponding frontend update.
**Fix (updated 2026-09-06):** Move the calendar onto the shared admin identity -
`requireAppAccess('calendar')` against the better-auth session cookie, per
`docs/calendar-auth-migration.md`. That closes this item outright rather than moving the
credential to a safer place, and it is now the cheaper of the two: the feedback and tickets
modules made the same move on 2026-09-06 for one line each.
~~Move to request headers (`X-Session-Id` / `X-Session-Key`) or the request body.~~ No longer
the recommendation. Nothing on the server reads those two headers any more - the calendar's
query parameters are the last legacy credential path in the API - so this would build a second
mechanism just as the first is being retired. They survive only in the CORS `allowedHeaders`
list, and only until both frontends are redeployed.
Either fix requires a corresponding frontend update.
> Note: the shared calendar `password` parameter in query params is intentional (iCal clients don't support headers) and is acceptable for the current setup.
+5
View File
@@ -102,6 +102,11 @@ export const describeAdminBinding = (
expect(res.locals.admin).toMatchObject({id: 'u1', email: 'a@nachklang.art', displayName: 'Anna Admin'});
});
// Weaker than it looks and kept deliberately: neither module imports
// checkSession any more, so this cannot fail today. It is a tripwire for
// the change that would matter - someone reintroducing a header-session
// fallback "just for the calendar users who have not been invited yet",
// which is exactly the shortcut the cutover exists to close.
it('never falls back to a calendar header session', async () => {
m.getSession.mockResolvedValue(null);