Skip to content

Custom argument parameter decorator #629

@etylermoss

Description

@etylermoss

I find using regular method & parameter decorators rather hacky when trying to work with arguments as they are disconnected.

For instance in my code below, I need to check that the supplied user_id is permitted to be deleted by the user who made the request (gotten from context).

/** @typegraphql Delete a user from the application.
 */
@UserAccessControl('DELETE', 'user_id')
@Mutation(_returns => User, {nullable: true})
deleteUser(@Arg('user_id') user_id: string): User {
	const user = this.userSvc.getUserByID(user_id);
	return this.userSvc.deleteUser(user_id) ? user : null;
}

The problem is that the AccessControl decorator doesn't enforce that 'user_id' be a specified parameter, it just happens to be so, and I later have to check whether the property exists on the args object in the resolver function. 'user_id' could be anything on either AccessControl or Arg.

It would be nice to have a way to define custom decorators that behave like Arg, i.e they add the parameter to the schema (in contrast to regular parameter decorators). This would allow the above to become just deleteUser(@UserAccessControl('DELETE', 'user_id') user_id: string), where UserAccessControl is something analogous to:

const UserAccessControl = (requiredLevel, name, options): ParameterDecorator => {
  return createArgParamDecorator(name, async ({context}, argValue) => {
    const userLevel = getUserLevelForUser(context.req.user_id, argValue); // Use DI / Container.get() etc.
    if (userLevel < requiredLevel) {
      throw new ForbiddenError();
    }
    return argValue; // this means the requesting user is permitted to perform 'DELETE' level operations on the user_id argValue
  }, options);
}

I've created an implementation and example of this feature here (missing tests):
etylermoss@14c2a23

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions