zenstackhq / zenstack

Fullstack TypeScript toolkit that enhances Prisma ORM with flexible Authorization layer for RBAC/ABAC/PBAC/ReBAC, offering auto-generated type-safe APIs and frontend hooks.
https://zenstack.dev
MIT License
2.07k stars 88 forks source link

Incorrect error response when a policy rejection occurs (in REST API flavor context) #449

Closed Azzerty23 closed 1 year ago

Azzerty23 commented 1 year ago

Description and expected behavior I expect to receive a 403 error response indicating a lack of permission.

Screenshots Capture d’écran 2023-06-02 à 15 16 59

Environment (please complete the following information):

Additional context Response detail: Cannot read properties of undefined (reading 'PrismaClientKnownRequestError')\nTypeError: Cannot read properties of undefined (reading 'PrismaClientKnownRequestError')\n at prismaClientKnownRequestError (/Users/augustin/Documents/Dev/Test/zenstack-rest-turbo/apps/express-api/dist/index.js:15890:50)\n at PolicyUtil.deniedByPolicy (/Users/augustin/Documents/Dev/Test/zenstack-rest-turbo/apps/express-api/dist/index.js:24086:58)\n at PolicyProxyHandler. (/Users/augustin/Documents/Dev/Test/zenstack-rest-turbo/apps/express-api/dist/index.js:24460:30)\n at Generator.next ()\n at fulfilled (/Users/augustin/Documents/Dev/Test/zenstack-rest-turbo/apps/express-api/dist/index.js:24200:28)\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Azzerty23 commented 1 year ago

It seems to be an issue on my side since it's working fine in dev mode...

ymc9 commented 1 year ago

Got it. @Azzerty23 let me know in case you find something suspicious on ZenStack side.

Azzerty23 commented 1 year ago

Hi @ymc9, I have identified the source of my issue and found a way to resolve it by modifying how the ZenStack runtime loads the Prisma module. You can find the relevant code here: https://github.com/zenstackhq/zenstack/blob/afa23882422d0fdf772d9a23e4cc157399b19a99/packages/runtime/src/enhancements/utils.ts#LL65C13-L65C45. By replacing this line with: return require('@prisma/client/runtime');, everything works as expected.

=> When I build the project with esbuild, require(loadPath).Prisma; returns undefined... hence my problem.

However, I don't understand one thing : const loadPath = path.dirname(prisma._engineConfig.datamodelPath); returns my dist/ folder. So what does .Prisma refer to in require(loadPath).Prisma;? Am I supposed to have a Prisma folder in my dist/ directory?

Is it possible to fix this by checking that require(loadPath).Prisma; does not return undefined? I can create a pull request for that if the solution is acceptable to you.

For more context, here is a demo repository with the build script (inside apps/express-api folder): https://github.com/Azzerty23/zenstack-rest-turbo.

ymc9 commented 1 year ago

Hey @Azzerty23 , thanks a lot for digging into this issue!

The reason why I chose to load from prisma._engineConfig.datamodelPath first is to be more resilient and support cases where Prisma client is generated to non-standard locations (so not loadable from @prisma/client/runtime). But I don't know why it ends up undefined ... Let me check your repro and understand it.

Yes, checking if require(loadPath).Prisma is undefined and fallback to loading from @prisma/client/runtime makes good sense. If you already have the code ready in a fork, sending a PR (merge to dev branch) would be great!

Thank you!

ymc9 commented 1 year ago

Fixed by #461

ymc9 commented 1 year ago

Hi @Azzerty23 , I've merged the change and published a new version. Welcome to the contributors team!

Azzerty23 commented 1 year ago

Thank you very much :D