generate-permissions.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import { stitchSchemas, ValidationLevel } from '@graphql-tools/stitch';
  2. import { GraphQLEnumType, GraphQLSchema } from 'graphql';
  3. import { GraphQLEnumValueConfigMap } from 'graphql/type/definition';
  4. import { getAllPermissionsMetadata } from '../../common/constants';
  5. import { PermissionDefinition } from '../../common/permission-definition';
  6. const PERMISSION_DESCRIPTION = `@description
  7. Permissions for administrators and customers. Used to control access to
  8. GraphQL resolvers via the {@link Allow} decorator.
  9. ## Understanding Permission.Owner
  10. \`Permission.Owner\` is a special permission which is used in some Vendure resolvers to indicate that that resolver should only
  11. be accessible to the "owner" of that resource.
  12. For example, the Shop API \`activeCustomer\` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
  13. based on the activeUserId of the current session. As a result, the resolver code looks like this:
  14. @example
  15. \`\`\`TypeScript
  16. \\@Query()
  17. \\@Allow(Permission.Owner)
  18. async activeCustomer(\\@Ctx() ctx: RequestContext): Promise<Customer | undefined> {
  19. const userId = ctx.activeUserId;
  20. if (userId) {
  21. return this.customerService.findOneByUserId(ctx, userId);
  22. }
  23. }
  24. \`\`\`
  25. Here we can see that the "ownership" must be enforced by custom logic inside the resolver. Since "ownership" cannot be defined generally
  26. nor statically encoded at build-time, any resolvers using \`Permission.Owner\` **must** include logic to enforce that only the owner
  27. of the resource has access. If not, then it is the equivalent of using \`Permission.Public\`.
  28. @docsCategory common`;
  29. /**
  30. * Generates the `Permission` GraphQL enum based on the default & custom permission definitions.
  31. */
  32. export function generatePermissionEnum(
  33. schema: GraphQLSchema,
  34. customPermissions: PermissionDefinition[],
  35. ): GraphQLSchema {
  36. const allPermissionsMetadata = getAllPermissionsMetadata(customPermissions);
  37. const values: GraphQLEnumValueConfigMap = {};
  38. let i = 0;
  39. for (const entry of allPermissionsMetadata) {
  40. values[entry.name] = {
  41. value: i,
  42. description: entry.description,
  43. };
  44. i++;
  45. }
  46. const permissionsEnum = new GraphQLEnumType({
  47. name: 'Permission',
  48. description: PERMISSION_DESCRIPTION,
  49. values,
  50. });
  51. return stitchSchemas({
  52. subschemas: [schema],
  53. types: [permissionsEnum],
  54. typeMergingOptions: { validationSettings: { validationLevel: ValidationLevel.Off } },
  55. });
  56. }