Problem
The request hook refreshes the Discord role and authorizes /admin using the value returned by refreshDiscordRole, but it does not update event.locals.user.role. Every admin action separately checks the stale locals.user object with isAdmin(locals.user).
A user whose stored role changes from user to admin during the hook therefore passes the page guard but receives 403 from actions such as tile creation, verification, and activity purge until they start a new session.
Reproduction
- Sign in while the stored role is
user.
- Grant the user the configured Discord admin role.
- Request an admin page. The hook refreshes the database role and allows the page.
- Submit an admin action in that same session. The action sees
locals.user.role === 'user' and rejects it.
Suggested fix
After a successful role refresh, assign the refreshed role to event.locals.user.role, or have the actions use an authoritative role check that reads or refreshes the current database role.
Affected code
src/hooks.server.ts
src/lib/server/admin.ts
- all admin actions that call
isAdmin(locals.user)
Problem
The request hook refreshes the Discord role and authorizes
/adminusing the value returned byrefreshDiscordRole, but it does not updateevent.locals.user.role. Every admin action separately checks the stalelocals.userobject withisAdmin(locals.user).A user whose stored role changes from
usertoadminduring the hook therefore passes the page guard but receives 403 from actions such as tile creation, verification, and activity purge until they start a new session.Reproduction
user.locals.user.role === 'user'and rejects it.Suggested fix
After a successful role refresh, assign the refreshed role to
event.locals.user.role, or have the actions use an authoritative role check that reads or refreshes the current database role.Affected code
src/hooks.server.tssrc/lib/server/admin.tsisAdmin(locals.user)