Closed kishan-getstarted closed 1 year ago
Will look into it
I tested it with this example https://github.com/zenstackhq/docs-tutorial-express
Here's what I did:
prisma/shield.ts
import { TRPCError } from "@trpc/server";
import { allow, deny, shield } from "trpc-shield";
import { Context } from "../server/context";
export const permissions = shield<Context>(
{
list: {
query: {
aggregate: allow,
findFirst: allow,
findMany: deny,
findUnique: allow,
groupBy: allow,
},
mutation: {
createOne: deny,
deleteMany: allow,
deleteOne: allow,
updateMany: allow,
updateOne: allow,
upsertOne: allow,
},
},
},
{
fallbackRule: allow,
fallbackError: new TRPCError({
code: "UNAUTHORIZED",
message: "Not allowed",
}),
}
);
server/routers/_app.ts
const permissionsMiddleware = t.middleware(permissions);
const errorWrappedProc = t.procedure
.use(permissionsMiddleware)
....
That's all you need for the shield to work.
Thanks for the example. I will check in upcoming week. Other thing I wanted to ask u is in the documentation it’s mentioned we can use namespace router. I have tried that with zenstack but it seems not to work.
Basically if I use trpc prisma generator it will give me all the routes I wanted for example I have 3 models
space, user, partner
they all will have router like FindMany, create, etc
how can I apply different rules in shield for each route..
one solution is to name each route differently but for that I need to go and manually change each router name (bcz I am using generator)
second solution is namespace router but its seems to not work.
can u provide some insight on that ?
appreciated your response buddy !!
Cheers 🥂
Namespacing works fine. Just make sure the shield that gets generated matches the procedure names that Zenstack produces. With prisma-trpc-generator
there's an option that let's you hide model name from procedure name(findMany instead of findManyUser); showModelNameInProcedure
.
But since Zenstack uses its own implementation of the library, you would need to modify the generated shield to match the one I sent above. Basically just group them by router name
Just show u the sample code below is the way I want this to be work
query: {
space: {
findMany: and(isAuthenticated, or(isAdmin, isEditor, isReader)),
}
},
mutation: {
space: {
create: and(isAuthenticated, or(isAdmin, isEditor)),
update: and(isAuthenticated, or(isAdmin, isEditor)),
}
}
The above is not working but when I do like
query: {
findMany: and(isAuthenticated, or(isAdmin, isEditor, isReader)),
},
mutation: {
create: and(isAuthenticated, or(isAdmin, isEditor)),
update: and(isAuthenticated, or(isAdmin, isEditor)),
},
Its working fine..
My router config
export function createRouter<Config extends BaseConfig>(router: RouterFactory<Config>, procedure: ProcBuilder<Config>) {
return router({
partner: createPartnerRouter<Config>(router, procedure),
space: createSpaceRouter<Config>(router, procedure),
}
);
}
Ohh my bad!! The namespace should be at the root level. It works fine. I am good to close this PR.
Thanks, buddy for the help.. Really appreciated
Feature request
is it possible to wrap the shield with zenstack ? check here: https://zenstack.dev/docs/guides/trpc