Package Exports
- @joindeed/prisma-auth
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@joindeed/prisma-auth) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
This is a mere PoC!!! Not production-ready! API will change!
What?: declarative authorisation middleware that operates on Prisma level (and not graphql resolver level).
Why?: because imperatively crafting auth rules is dangerous, especially in GraphQL+Prisma world, if we automatically expose the whole schema with Pal.js, nexus-prisma or similar tool.
Theory
So we support two types of authorisation definitions:
1. individual field level
model User {
/// @Auth(read:[Owner,Admin])
email String
}2. model level
/// @Auth(read: [Owner,Admin])
model Purchases {...}Model level read permissions should be enforced in these scenarios:
- custom resolver that returns a single entity of given type
- custom resolver that returns a list of entities of given type. In this case we should actually enforce authorisation at Prisma query level (using the auto-generated
whereclause) - relation resolver that returns a single entity of given type
- relation resolver that returns a list of entities of given type. This one is not yet handled
Usage
Define auth annotations as Prisma comments (see above, not tripple slash)
Define role matchers per each Prisma model in this fashion:
const roles = {
Purchases: {
Owner: {
matcher: (ctx, record) => isAuthenticated(ctx) && ctx.currentUser?.id === record?.userId,
queryConstraint: (ctx) =>
isAuthenticated(ctx) && {
userId: ctx.currentUser?.id,
},
},
},
}matcher is used to restrict access to individual records.
queryConstraint is used to generate a where clause for Prisma which should be used to restrict list fields.
- Configure your GraphQL schema to use the middleware
import { applyMiddleware } from 'graphql-middleware'
import { makeAuthorizationMiddlewares } from '@joindeed/prisma-auth'
const server = new ApolloServer({
schema: applyMiddleware(schema, ...makeAuthorizationMiddlewares(roles)),
...
})
Get in touch if you have ideas how all of this could have been done better!
TODO:
- enforce authorisation on relation resolver that returns a list of entities
- write proper readme
- update/delete/create operation support
Credit
This package has been proudly developed by the Deed team!
Check us out, we may be hiring!