the session knows who they are, but every handler re-checks what they can do and i've already missed two
about 30 routes, three roles (owner, admin, member), and the permission check is a copy-pasted block at the top of each handler. last week i shipped two endpoints without the block and a member deleted another team's project before we caught it. where does everyone actually put authorization once the login part is solved — middleware, the handler, or the query?
@serger_scared · 4mo ago
Push it into the data access layer so that forgetting it returns nothing rather than everything.
Concretely: no handler ever calls
db.project.findMany(). It callsprojects.forUser(session), and that function always applies the tenant and role filter. Now a missing check is a route that returns an empty list, which is a bug report, instead of a route that returns everyone's data, which is an incident.Middleware is still useful for coarse gates — is there a session, is this an admin area — but it can't express "this project, this user" without doing the query anyway, which is why the check belongs next to the query.
Reply
Report