Open
Description
Background
One of the traps that ZenStack users frequently fall into is not providing all the fields needed in the user context object when calling enhance
. Today, ZenStack doesn't do anything special when dealing with auth()
expressions in access policy rules. It just translates it to the user context you provided.
const db = enhance(prisma, { user: { id: userId } });
model Post {
...
@@allow('all', auth().role == 'ADMIN') // <- this won't work
}
You're responsible for making sure all fields accessed from auth()
are available.
It caused two problems:
- When you forget to do that, you get unexpected authorization results.
- There's no typing guarantee. The
auth()
call is resolved to theUser
model (or a model marked@@auth
), which causes the illusion that it at least has all non-optional fields of the model. It's not the case if you don't provide those fields.
Proposed Solution
- Make
enhance()
automatically analyze what fields are accessed fromauth()
and do a database fetch for the missing ones. - This means its signature needs to be changed to return a
Promise
. - Or, we can make the feature opt-in and introduce an overloaded version of
enhance()
that enables the auto-fetching and returns aPromise
, and keep the original one unchanged (thus no breaking changes).