@envelop/operation-field-permissions 1.2.0 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/index.js +15 -10
  2. package/index.mjs +16 -11
  3. package/package.json +3 -3
package/index.js CHANGED
@@ -6,13 +6,10 @@ const core = require('@envelop/core');
6
6
  const extendedValidation = require('@envelop/extended-validation');
7
7
  const graphql = require('graphql');
8
8
 
9
- const getWrappedType = (graphqlType) => {
10
- if (graphqlType instanceof graphql.GraphQLList || graphqlType instanceof graphql.GraphQLNonNull) {
11
- return getWrappedType(graphqlType.ofType);
12
- }
13
- return graphqlType;
14
- };
15
9
  const OPERATION_PERMISSIONS_SYMBOL = Symbol('OPERATION_PERMISSIONS_SYMBOL');
10
+ /**
11
+ * Returns a set of type names that allow access to all fields in the type.
12
+ */
16
13
  const getWildcardTypes = (scope) => {
17
14
  const wildcardTypes = new Set();
18
15
  for (const item of scope) {
@@ -47,8 +44,8 @@ const OperationScopeRule = (options) => (context, executionArgs) => {
47
44
  Field(node) {
48
45
  const type = context.getType();
49
46
  if (type) {
50
- const wrappedType = getWrappedType(type);
51
- if (graphql.isIntrospectionType(wrappedType)) {
47
+ const namedType = graphql.getNamedType(type);
48
+ if (graphql.isIntrospectionType(namedType)) {
52
49
  return false;
53
50
  }
54
51
  }
@@ -57,15 +54,21 @@ const OperationScopeRule = (options) => (context, executionArgs) => {
57
54
  if (graphql.isIntrospectionType(parentType)) {
58
55
  return false;
59
56
  }
57
+ // We handle objects, interface and union permissions differently.
58
+ // When accessing an an object field, we check simply run the check.
60
59
  if (graphql.isObjectType(parentType)) {
61
60
  handleField(node, parentType);
62
61
  }
63
- else if (graphql.isUnionType(parentType)) {
62
+ // To allow a union case, every type in the union has to be allowed/
63
+ // If one of the types doesn't permit access we should throw a validation error.
64
+ if (graphql.isUnionType(parentType)) {
64
65
  for (const objectType of parentType.getTypes()) {
65
66
  handleField(node, objectType);
66
67
  }
67
68
  }
68
- else if (graphql.isInterfaceType(parentType)) {
69
+ // Same goes for interfaces. Every implementation should allow the access of the given
70
+ // field to pass the validation rule.
71
+ if (graphql.isInterfaceType(parentType)) {
69
72
  for (const objectType of executionArgs.schema.getImplementations(parentType).objects) {
70
73
  handleField(node, objectType);
71
74
  }
@@ -89,6 +92,8 @@ const useOperationFieldPermissions = (opts) => {
89
92
  }));
90
93
  addPlugin(core.useExtendContext(async (context) => {
91
94
  const permissions = await opts.getPermissions(context);
95
+ // Schema coordinates is a set of type-name field-name strings that
96
+ // describe the position of a field in the schema.
92
97
  const schemaCoordinates = toSet(permissions);
93
98
  const wildcardTypes = getWildcardTypes(schemaCoordinates);
94
99
  const scopeContext = {
package/index.mjs CHANGED
@@ -1,14 +1,11 @@
1
1
  import { useExtendContext } from '@envelop/core';
2
2
  import { useExtendedValidation } from '@envelop/extended-validation';
3
- import { isIntrospectionType, isObjectType, isUnionType, isInterfaceType, GraphQLList, GraphQLNonNull, GraphQLError } from 'graphql';
3
+ import { getNamedType, isIntrospectionType, isObjectType, isUnionType, isInterfaceType, GraphQLError } from 'graphql';
4
4
 
5
- const getWrappedType = (graphqlType) => {
6
- if (graphqlType instanceof GraphQLList || graphqlType instanceof GraphQLNonNull) {
7
- return getWrappedType(graphqlType.ofType);
8
- }
9
- return graphqlType;
10
- };
11
5
  const OPERATION_PERMISSIONS_SYMBOL = Symbol('OPERATION_PERMISSIONS_SYMBOL');
6
+ /**
7
+ * Returns a set of type names that allow access to all fields in the type.
8
+ */
12
9
  const getWildcardTypes = (scope) => {
13
10
  const wildcardTypes = new Set();
14
11
  for (const item of scope) {
@@ -43,8 +40,8 @@ const OperationScopeRule = (options) => (context, executionArgs) => {
43
40
  Field(node) {
44
41
  const type = context.getType();
45
42
  if (type) {
46
- const wrappedType = getWrappedType(type);
47
- if (isIntrospectionType(wrappedType)) {
43
+ const namedType = getNamedType(type);
44
+ if (isIntrospectionType(namedType)) {
48
45
  return false;
49
46
  }
50
47
  }
@@ -53,15 +50,21 @@ const OperationScopeRule = (options) => (context, executionArgs) => {
53
50
  if (isIntrospectionType(parentType)) {
54
51
  return false;
55
52
  }
53
+ // We handle objects, interface and union permissions differently.
54
+ // When accessing an an object field, we check simply run the check.
56
55
  if (isObjectType(parentType)) {
57
56
  handleField(node, parentType);
58
57
  }
59
- else if (isUnionType(parentType)) {
58
+ // To allow a union case, every type in the union has to be allowed/
59
+ // If one of the types doesn't permit access we should throw a validation error.
60
+ if (isUnionType(parentType)) {
60
61
  for (const objectType of parentType.getTypes()) {
61
62
  handleField(node, objectType);
62
63
  }
63
64
  }
64
- else if (isInterfaceType(parentType)) {
65
+ // Same goes for interfaces. Every implementation should allow the access of the given
66
+ // field to pass the validation rule.
67
+ if (isInterfaceType(parentType)) {
65
68
  for (const objectType of executionArgs.schema.getImplementations(parentType).objects) {
66
69
  handleField(node, objectType);
67
70
  }
@@ -85,6 +88,8 @@ const useOperationFieldPermissions = (opts) => {
85
88
  }));
86
89
  addPlugin(useExtendContext(async (context) => {
87
90
  const permissions = await opts.getPermissions(context);
91
+ // Schema coordinates is a set of type-name field-name strings that
92
+ // describe the position of a field in the schema.
88
93
  const schemaCoordinates = toSet(permissions);
89
94
  const wildcardTypes = getWildcardTypes(schemaCoordinates);
90
95
  const scopeContext = {
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@envelop/operation-field-permissions",
3
- "version": "1.2.0",
3
+ "version": "1.2.3",
4
4
  "sideEffects": false,
5
5
  "peerDependencies": {
6
+ "@envelop/core": "^1.6.1",
6
7
  "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
7
8
  },
8
9
  "dependencies": {
9
- "@envelop/core": "1.6.0",
10
- "@envelop/extended-validation": "1.3.0"
10
+ "@envelop/extended-validation": "^1.3.1"
11
11
  },
12
12
  "repository": {
13
13
  "type": "git",