Skip to content

Commit

Permalink
Add NoIntrospectionFieldsRule
Browse files Browse the repository at this point in the history
  • Loading branch information
danielrearden committed Jun 1, 2020
1 parent 4f35752 commit a626231
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 0 deletions.
89 changes: 89 additions & 0 deletions src/validation/__tests__/NoIntrospectionFieldsRule-test.js
@@ -0,0 +1,89 @@
// @flow strict

import { describe, it } from 'mocha';

import { NoIntrospectionFieldsRule } from '../rules/NoIntrospectionFieldsRule';

import { expectValidationErrors } from './harness';

function expectErrors(queryStr) {
return expectValidationErrors(NoIntrospectionFieldsRule, queryStr);
}

function expectValid(queryStr) {
expectErrors(queryStr).to.deep.equal([]);
}

describe('Validate: No introspection fields', () => {
it('ignores valid fields including __typename', () => {
expectValid(`
{
dog {
__typename
name
}
}
`);
});

it('ignores valid fields to be aliased as __schema or __type', () => {
expectValid(`
{
__schema: dog
__type: cat
}
`);
});

it('reports error when __schema field is requested', () => {
expectErrors(`
{
__schema {
queryType {
name
}
}
}
`).to.deep.equal([
{
message:
'GraphQL introspection has been disabled, but the requested query contained the field "__schema".',
locations: [{ line: 3, column: 9 }],
},
]);
});

it('reports error when __type field is requested', () => {
expectErrors(`
{
__type(name: "Query") {
name
}
}
`).to.deep.equal([
{
message:
'GraphQL introspection has been disabled, but the requested query contained the field "__type".',
locations: [{ line: 3, column: 9 }],
},
]);
});

it('reports error when an introspection field is requested and aliased', () => {
expectErrors(`
{
s: __schema {
queryType {
name
}
}
}
`).to.deep.equal([
{
message:
'GraphQL introspection has been disabled, but the requested query contained the field "__schema".',
locations: [{ line: 3, column: 9 }],
},
]);
});
});
3 changes: 3 additions & 0 deletions src/validation/index.js
Expand Up @@ -94,3 +94,6 @@ export { UniqueEnumValueNamesRule } from './rules/UniqueEnumValueNamesRule';
export { UniqueFieldDefinitionNamesRule } from './rules/UniqueFieldDefinitionNamesRule';
export { UniqueDirectiveNamesRule } from './rules/UniqueDirectiveNamesRule';
export { PossibleTypeExtensionsRule } from './rules/PossibleTypeExtensionsRule';

// Optional rules not defined by the GraphQL Specification
export { NoIntrospectionFieldsRule } from './rules/NoIntrospectionFieldsRule';
13 changes: 13 additions & 0 deletions src/validation/rules/NoIntrospectionFieldsRule.d.ts
@@ -0,0 +1,13 @@
import { ASTVisitor } from '../../language/visitor';
import { ValidationContext } from '../ValidationContext';

/**
* No introspection fields
*
* A GraphQL document is only valid if all fields selected are not
* fields that return an introspection type. Note: This rule is not
* part of the Validation section of the GraphQL Specification.
*/
export function NoIntrospectionFieldsRule(
context: ValidationContext,
): ASTVisitor;
32 changes: 32 additions & 0 deletions src/validation/rules/NoIntrospectionFieldsRule.js
@@ -0,0 +1,32 @@
// @flow strict

import { GraphQLError } from '../../error/GraphQLError';

import { type FieldNode } from '../../language/ast';
import { type ASTVisitor } from '../../language/visitor';

import { type ValidationContext } from '../ValidationContext';

/**
* No introspection fields
*
* A GraphQL document is only valid if all fields selected are not
* fields that return an introspection type. Note: This rule is not
* part of the Validation section of the GraphQL Specification.
*/
export function NoIntrospectionFieldsRule(
context: ValidationContext,
): ASTVisitor {
return {
Field(node: FieldNode) {
if (node.name.value === '__schema' || node.name.value === '__type') {
context.reportError(
new GraphQLError(
`GraphQL introspection has been disabled, but the requested query contained the field "${node.name.value}".`,
node,
),
);
}
},
};
}

0 comments on commit a626231

Please sign in to comment.