Georg Wagner
08/04/2021, 12:10 PMRyan
08/04/2021, 12:19 PMGeorg Wagner
08/04/2021, 1:08 PMmutation createProductMutation {
createProduct(data: {
name: "test50",
orders:{
create: {
customer: {
connect: {
id: "81c9cb84-6b9e-4b61-b067-33d83d813043"
}
}
}
}
}) {
id
}
}
So this should throw an authorization error, and not create.
So my idea was to write some generic code, which hooks in all mutations which exist.
But I know only a way to do it for this specific case. By using graphql directives. I created a directive "CreateOnlyByActiveUser".
@TypeGraphQL.Mutation(_returns => Product, {
nullable: false
})
@Directive('@CreateOnlyByActiveUser')
async createProduct(@TypeGraphQL.Ctx() ctx: any, @TypeGraphQL.Args() args: CreateProductArgs): Promise<Product> {
return getPrismaFromContext(ctx).product.create(args);
}
So when the mutation is executed I am hooking in the resolver of that mutation and this code is executed. It works actually, but only for the above mentioned mutation, because the path is explicit bound to our example.
field.resolve = async function (...args) {
// this code is executed when mutation createProduct is executed
const [, inputArgs, context, info] = args;
if (inputArgs.data.orders.create[0].customer.connect.id !== context.user.id) {
console.log('You are not allowed to see');
throw new AuthenticationError(
`Only the active user is allowed to see create an order`,
);
} else {
return resolve.apply(this, args);
}
};
Imagine if I would not use connect in the end, but also create. Or maybe I am using only the lower level mutation createOrder.
mutation createProductMutation {
createOrder(data: {
customer: {
connect: {
id: "81c9cb84-6b9e-4b61-b067-33d83d813043"
}
},
product:{
connect: {
id: "23214214"
}
}
}) {
id
}
}
Then I cannot reuse that directive, I have to adapt the path.
My idea is to use a unique magic field name of "id" in object type "User" like "MAGIC_ID". Then my directive could search in the input args and validate it.
But such design is bad and error prone. When working with authorization, we shouldn't work error-prone. So I was wondering whether there is a more elegant solution.Ryan
08/04/2021, 1:15 PMid
in args
. Something like this.Ryan
08/04/2021, 1:16 PMGeorg Wagner
08/04/2021, 1:24 PMRyan
08/04/2021, 1:27 PMJoey
08/05/2021, 4:33 PM