@@ -729,10 +729,134 @@ describe('ParseGraphQLServer', () => {
729729 } )
730730 expect ( introspection . data ) . toBeDefined ( ) ;
731731 } ) ;
732+
733+ it ( 'should block __type introspection without master key' , async ( ) => {
734+ try {
735+ await apolloClient . query ( {
736+ query : gql `
737+ query TypeIntrospection {
738+ __type(name: "User") {
739+ name
740+ kind
741+ }
742+ }
743+ ` ,
744+ } ) ;
745+
746+ fail ( 'should have thrown an error' ) ;
747+ } catch ( e ) {
748+ expect ( e . message ) . toEqual ( 'Response not successful: Received status code 403' ) ;
749+ expect ( e . networkError . result . errors [ 0 ] . message ) . toEqual ( 'Introspection is not allowed' ) ;
750+ }
751+ } ) ;
752+
753+ it ( 'should block aliased __type introspection without master key' , async ( ) => {
754+ try {
755+ await apolloClient . query ( {
756+ query : gql `
757+ query AliasedTypeIntrospection {
758+ myAlias: __type(name: "User") {
759+ name
760+ kind
761+ }
762+ }
763+ ` ,
764+ } ) ;
765+
766+ fail ( 'should have thrown an error' ) ;
767+ } catch ( e ) {
768+ expect ( e . message ) . toEqual ( 'Response not successful: Received status code 403' ) ;
769+ expect ( e . networkError . result . errors [ 0 ] . message ) . toEqual ( 'Introspection is not allowed' ) ;
770+ }
771+ } ) ;
772+
773+ it ( 'should allow __type introspection with master key' , async ( ) => {
774+ const introspection = await apolloClient . query ( {
775+ query : gql `
776+ query TypeIntrospection {
777+ __type(name: "User") {
778+ name
779+ kind
780+ }
781+ }
782+ ` ,
783+ context : {
784+ headers : {
785+ 'X-Parse-Master-Key' : 'test' ,
786+ } ,
787+ } ,
788+ } ) ;
789+ expect ( introspection . data ) . toBeDefined ( ) ;
790+ expect ( introspection . data . __type ) . toBeDefined ( ) ;
791+ expect ( introspection . errors ) . not . toBeDefined ( ) ;
792+ } ) ;
793+
794+ it ( 'should allow aliased __type introspection with master key' , async ( ) => {
795+ const introspection = await apolloClient . query ( {
796+ query : gql `
797+ query AliasedTypeIntrospection {
798+ myAlias: __type(name: "User") {
799+ name
800+ kind
801+ }
802+ }
803+ ` ,
804+ context : {
805+ headers : {
806+ 'X-Parse-Master-Key' : 'test' ,
807+ } ,
808+ } ,
809+ } ) ;
810+ expect ( introspection . data ) . toBeDefined ( ) ;
811+ expect ( introspection . data . myAlias ) . toBeDefined ( ) ;
812+ expect ( introspection . errors ) . not . toBeDefined ( ) ;
813+ } ) ;
814+
815+ it ( 'should allow __type introspection with maintenance key' , async ( ) => {
816+ const introspection = await apolloClient . query ( {
817+ query : gql `
818+ query TypeIntrospection {
819+ __type(name: "User") {
820+ name
821+ kind
822+ }
823+ }
824+ ` ,
825+ context : {
826+ headers : {
827+ 'X-Parse-Maintenance-Key' : 'test2' ,
828+ } ,
829+ } ,
830+ } ) ;
831+ expect ( introspection . data ) . toBeDefined ( ) ;
832+ expect ( introspection . data . __type ) . toBeDefined ( ) ;
833+ expect ( introspection . errors ) . not . toBeDefined ( ) ;
834+ } ) ;
835+
836+ it ( 'should allow __type introspection when public introspection is enabled' , async ( ) => {
837+ const parseServer = await reconfigureServer ( ) ;
838+ await createGQLFromParseServer ( parseServer , { graphQLPublicIntrospection : true } ) ;
839+
840+ const introspection = await apolloClient . query ( {
841+ query : gql `
842+ query TypeIntrospection {
843+ __type(name: "User") {
844+ name
845+ kind
846+ }
847+ }
848+ ` ,
849+ } ) ;
850+ expect ( introspection . data ) . toBeDefined ( ) ;
851+ expect ( introspection . data . __type ) . toBeDefined ( ) ;
852+ } ) ;
732853 } ) ;
733854
734855
735856 describe ( 'Default Types' , ( ) => {
857+ beforeEach ( async ( ) => {
858+ await createGQLFromParseServer ( parseServer , { graphQLPublicIntrospection : true } ) ;
859+ } ) ;
736860 it ( 'should have Object scalar type' , async ( ) => {
737861 const objectType = (
738862 await apolloClient . query ( {
@@ -892,6 +1016,10 @@ describe('ParseGraphQLServer', () => {
8921016 } ) ;
8931017
8941018 describe ( 'Relay Specific Types' , ( ) => {
1019+ beforeEach ( async ( ) => {
1020+ await createGQLFromParseServer ( parseServer , { graphQLPublicIntrospection : true } ) ;
1021+ } ) ;
1022+
8951023 let clearCache ;
8961024 beforeEach ( async ( ) => {
8971025 if ( ! clearCache ) {
@@ -1435,6 +1563,9 @@ describe('ParseGraphQLServer', () => {
14351563 } ) ;
14361564
14371565 describe ( 'Parse Class Types' , ( ) => {
1566+ beforeEach ( async ( ) => {
1567+ await createGQLFromParseServer ( parseServer , { graphQLPublicIntrospection : true } ) ;
1568+ } ) ;
14381569 it ( 'should have all expected types' , async ( ) => {
14391570 await parseServer . config . databaseController . loadSchema ( ) ;
14401571
@@ -1546,6 +1677,7 @@ describe('ParseGraphQLServer', () => {
15461677 beforeEach ( async ( ) => {
15471678 await parseGraphQLServer . setGraphQLConfig ( { } ) ;
15481679 await resetGraphQLCache ( ) ;
1680+ await createGQLFromParseServer ( parseServer , { graphQLPublicIntrospection : true } ) ;
15491681 } ) ;
15501682
15511683 it_id ( 'd6a23a2f-ca18-4b15-bc73-3e636f99e6bc' ) ( it ) ( 'should only include types in the enabledForClasses list' , async ( ) => {
@@ -6695,7 +6827,7 @@ describe('ParseGraphQLServer', () => {
66956827 ) ;
66966828 expect (
66976829 ( await deleteObject ( object4 . className , object4 . id ) ) . data . delete [
6698- object4 . className . charAt ( 0 ) . toLowerCase ( ) + object4 . className . slice ( 1 )
6830+ object4 . className . charAt ( 0 ) . toLowerCase ( ) + object4 . className . slice ( 1 )
66996831 ]
67006832 ) . toEqual ( { objectId : object4 . id , __typename : 'PublicClass' } ) ;
67016833 await expectAsync ( object4 . fetch ( { useMasterKey : true } ) ) . toBeRejectedWith (
@@ -7832,6 +7964,9 @@ describe('ParseGraphQLServer', () => {
78327964 } ) ;
78337965
78347966 describe ( 'Functions Mutations' , ( ) => {
7967+ beforeEach ( async ( ) => {
7968+ await createGQLFromParseServer ( parseServer , { graphQLPublicIntrospection : true } ) ;
7969+ } ) ;
78357970 it ( 'can be called' , async ( ) => {
78367971 try {
78377972 const clientMutationId = uuidv4 ( ) ;
@@ -11299,25 +11434,25 @@ describe('ParseGraphQLServer', () => {
1129911434 } ,
1130011435 } ) ;
1130111436 const SomeClassType = new GraphQLObjectType ( {
11302- name : 'SomeClass' ,
11303- fields : {
11304- nameUpperCase : {
11305- type : new GraphQLNonNull ( GraphQLString ) ,
11306- resolve : p => p . name . toUpperCase ( ) ,
11307- } ,
11308- type : { type : TypeEnum } ,
11309- language : {
11310- type : new GraphQLEnumType ( {
11311- name : 'LanguageEnum' ,
11312- values : {
11313- fr : { value : 'fr' } ,
11314- en : { value : 'en' } ,
11315- } ,
11316- } ) ,
11317- resolve : ( ) => 'fr' ,
11318- } ,
11437+ name : 'SomeClass' ,
11438+ fields : {
11439+ nameUpperCase : {
11440+ type : new GraphQLNonNull ( GraphQLString ) ,
11441+ resolve : p => p . name . toUpperCase ( ) ,
11442+ } ,
11443+ type : { type : TypeEnum } ,
11444+ language : {
11445+ type : new GraphQLEnumType ( {
11446+ name : 'LanguageEnum' ,
11447+ values : {
11448+ fr : { value : 'fr' } ,
11449+ en : { value : 'en' } ,
11450+ } ,
11451+ } ) ,
11452+ resolve : ( ) => 'fr' ,
1131911453 } ,
11320- } ) ,
11454+ } ,
11455+ } ) ,
1132111456 parseGraphQLServer = new ParseGraphQLServer ( parseServer , {
1132211457 graphQLPath : '/graphql' ,
1132311458 graphQLCustomTypeDefs : new GraphQLSchema ( {
0 commit comments