@@ -50,6 +50,7 @@ describe('ParseGraphQLServer', () => {
5050
5151 beforeEach ( async ( ) => {
5252 parseServer = await global . reconfigureServer ( {
53+ maintenanceKey : 'test2' ,
5354 maxUploadSize : '1kb' ,
5455 } ) ;
5556 parseGraphQLServer = new ParseGraphQLServer ( parseServer , {
@@ -88,8 +89,8 @@ describe('ParseGraphQLServer', () => {
8889
8990 it ( 'should initialize parseGraphQLSchema with a log controller' , async ( ) => {
9091 const loggerAdapter = {
91- log : ( ) => { } ,
92- error : ( ) => { } ,
92+ log : ( ) => { } ,
93+ error : ( ) => { } ,
9394 } ;
9495 const parseServer = await global . reconfigureServer ( {
9596 loggerAdapter,
@@ -124,10 +125,10 @@ describe('ParseGraphQLServer', () => {
124125 info : new Object ( ) ,
125126 config : new Object ( ) ,
126127 auth : new Object ( ) ,
127- get : ( ) => { } ,
128+ get : ( ) => { } ,
128129 } ;
129130 const res = {
130- set : ( ) => { } ,
131+ set : ( ) => { } ,
131132 } ;
132133
133134 it_id ( '0696675e-060f-414f-bc77-9d57f31807f5' ) ( it ) ( 'should return schema and context with req\'s info, config and auth' , async ( ) => {
@@ -431,7 +432,7 @@ describe('ParseGraphQLServer', () => {
431432 objects . push ( object1 , object2 , object3 , object4 ) ;
432433 }
433434
434- async function createGQLFromParseServer ( _parseServer ) {
435+ async function createGQLFromParseServer ( _parseServer , parseGraphQLServerOptions ) {
435436 if ( parseLiveQueryServer ) {
436437 await parseLiveQueryServer . server . close ( ) ;
437438 }
@@ -448,6 +449,7 @@ describe('ParseGraphQLServer', () => {
448449 graphQLPath : '/graphql' ,
449450 playgroundPath : '/playground' ,
450451 subscriptionsPath : '/subscriptions' ,
452+ ...parseGraphQLServerOptions ,
451453 } ) ;
452454 parseGraphQLServer . applyGraphQL ( expressApp ) ;
453455 parseGraphQLServer . applyPlayground ( expressApp ) ;
@@ -456,7 +458,7 @@ describe('ParseGraphQLServer', () => {
456458 }
457459
458460 beforeEach ( async ( ) => {
459- await createGQLFromParseServer ( parseServer ) ;
461+ await createGQLFromParseServer ( parseServer ) ;
460462
461463 const subscriptionClient = new SubscriptionClient (
462464 'ws://localhost:13377/subscriptions' ,
@@ -488,8 +490,8 @@ describe('ParseGraphQLServer', () => {
488490 } ,
489491 } ,
490492 } ) ;
491- spyOn ( console , 'warn' ) . and . callFake ( ( ) => { } ) ;
492- spyOn ( console , 'error' ) . and . callFake ( ( ) => { } ) ;
493+ spyOn ( console , 'warn' ) . and . callFake ( ( ) => { } ) ;
494+ spyOn ( console , 'error' ) . and . callFake ( ( ) => { } ) ;
493495 } ) ;
494496
495497 afterEach ( async ( ) => {
@@ -605,6 +607,96 @@ describe('ParseGraphQLServer', () => {
605607 ] ) ;
606608 } ;
607609
610+ describe ( 'Introspection' , ( ) => {
611+ it ( 'should have public introspection disabled by default without master key' , async ( ) => {
612+
613+ try {
614+ await apolloClient . query ( {
615+ query : gql `
616+ query Introspection {
617+ __schema {
618+ types {
619+ name
620+ }
621+ }
622+ }
623+ ` ,
624+ } )
625+
626+ fail ( 'should have thrown an error' ) ;
627+
628+ } catch ( e ) {
629+ expect ( e . message ) . toEqual ( 'Response not successful: Received status code 403' ) ;
630+ expect ( e . networkError . result . errors [ 0 ] . message ) . toEqual ( 'Introspection is not allowed' ) ;
631+ }
632+ } ) ;
633+
634+ it ( 'should always work with master key' , async ( ) => {
635+ const introspection =
636+ await apolloClient . query ( {
637+ query : gql `
638+ query Introspection {
639+ __schema {
640+ types {
641+ name
642+ }
643+ }
644+ }
645+ ` ,
646+ context : {
647+ headers : {
648+ 'X-Parse-Master-Key' : 'test' ,
649+ } ,
650+ }
651+ } , )
652+ expect ( introspection . data ) . toBeDefined ( ) ;
653+ expect ( introspection . errors ) . not . toBeDefined ( ) ;
654+ } ) ;
655+
656+ it ( 'should always work with maintenance key' , async ( ) => {
657+ const introspection =
658+ await apolloClient . query ( {
659+ query : gql `
660+ query Introspection {
661+ __schema {
662+ types {
663+ name
664+ }
665+ }
666+ }
667+ ` ,
668+ context : {
669+ headers : {
670+ 'X-Parse-Maintenance-Key' : 'test2' ,
671+ } ,
672+ }
673+ } , )
674+ expect ( introspection . data ) . toBeDefined ( ) ;
675+ expect ( introspection . errors ) . not . toBeDefined ( ) ;
676+ } ) ;
677+
678+ it ( 'should have public introspection enabled if enabled' , async ( ) => {
679+
680+ const parseServer = await reconfigureServer ( ) ;
681+ await createGQLFromParseServer ( parseServer , { graphQLPublicIntrospection : true } ) ;
682+
683+ const introspection =
684+ await apolloClient . query ( {
685+ query : gql `
686+ query Introspection {
687+ __schema {
688+ types {
689+ name
690+ }
691+ }
692+ }
693+ ` ,
694+ } )
695+ expect ( introspection . data ) . toBeDefined ( ) ;
696+ } ) ;
697+ } ) ;
698+
699+
608700 describe ( 'Default Types' , ( ) => {
609701 it ( 'should have Object scalar type' , async ( ) => {
610702 const objectType = (
@@ -749,6 +841,11 @@ describe('ParseGraphQLServer', () => {
749841 }
750842 }
751843 ` ,
844+ context : {
845+ headers : {
846+ 'X-Parse-Master-Key' : 'test' ,
847+ } ,
848+ }
752849 } )
753850 ) . data [ '__schema' ] . types . map ( type => type . name ) ;
754851
@@ -780,6 +877,11 @@ describe('ParseGraphQLServer', () => {
780877 }
781878 }
782879 ` ,
880+ context : {
881+ headers : {
882+ 'X-Parse-Master-Key' : 'test' ,
883+ } ,
884+ }
783885 } )
784886 ) . data [ '__schema' ] . types . map ( type => type . name ) ;
785887
@@ -864,7 +966,7 @@ describe('ParseGraphQLServer', () => {
864966 } ) ;
865967
866968 it ( 'should have clientMutationId in call function input' , async ( ) => {
867- Parse . Cloud . define ( 'hello' , ( ) => { } ) ;
969+ Parse . Cloud . define ( 'hello' , ( ) => { } ) ;
868970
869971 const callFunctionInputFields = (
870972 await apolloClient . query ( {
@@ -886,7 +988,7 @@ describe('ParseGraphQLServer', () => {
886988 } ) ;
887989
888990 it ( 'should have clientMutationId in call function payload' , async ( ) => {
889- Parse . Cloud . define ( 'hello' , ( ) => { } ) ;
991+ Parse . Cloud . define ( 'hello' , ( ) => { } ) ;
890992
891993 const callFunctionPayloadFields = (
892994 await apolloClient . query ( {
@@ -1312,6 +1414,11 @@ describe('ParseGraphQLServer', () => {
13121414 }
13131415 }
13141416 ` ,
1417+ context : {
1418+ headers : {
1419+ 'X-Parse-Master-Key' : 'test' ,
1420+ } ,
1421+ }
13151422 } )
13161423 ) . data [ '__schema' ] . types . map ( type => type . name ) ;
13171424
@@ -6553,7 +6660,7 @@ describe('ParseGraphQLServer', () => {
65536660 ) ;
65546661 expect (
65556662 ( await deleteObject ( object4 . className , object4 . id ) ) . data . delete [
6556- object4 . className . charAt ( 0 ) . toLowerCase ( ) + object4 . className . slice ( 1 )
6663+ object4 . className . charAt ( 0 ) . toLowerCase ( ) + object4 . className . slice ( 1 )
65576664 ]
65586665 ) . toEqual ( { objectId : object4 . id , __typename : 'PublicClass' } ) ;
65596666 await expectAsync ( object4 . fetch ( { useMasterKey : true } ) ) . toBeRejectedWith (
@@ -7447,9 +7554,9 @@ describe('ParseGraphQLServer', () => {
74477554 it ( 'should send reset password' , async ( ) => {
74487555 const clientMutationId = uuidv4 ( ) ;
74497556 const emailAdapter = {
7450- sendVerificationEmail : ( ) => { } ,
7557+ sendVerificationEmail : ( ) => { } ,
74517558 sendPasswordResetEmail : ( ) => Promise . resolve ( ) ,
7452- sendMail : ( ) => { } ,
7559+ sendMail : ( ) => { } ,
74537560 } ;
74547561 parseServer = await global . reconfigureServer ( {
74557562 appName : 'test' ,
@@ -7488,11 +7595,11 @@ describe('ParseGraphQLServer', () => {
74887595 const clientMutationId = uuidv4 ( ) ;
74897596 let resetPasswordToken ;
74907597 const emailAdapter = {
7491- sendVerificationEmail : ( ) => { } ,
7598+ sendVerificationEmail : ( ) => { } ,
74927599 sendPasswordResetEmail : ( { link } ) => {
74937600 resetPasswordToken = link . split ( 'token=' ) [ 1 ] . split ( '&' ) [ 0 ] ;
74947601 } ,
7495- sendMail : ( ) => { } ,
7602+ sendMail : ( ) => { } ,
74967603 } ;
74977604 parseServer = await global . reconfigureServer ( {
74987605 appName : 'test' ,
@@ -7558,9 +7665,9 @@ describe('ParseGraphQLServer', () => {
75587665 it ( 'should send verification email again' , async ( ) => {
75597666 const clientMutationId = uuidv4 ( ) ;
75607667 const emailAdapter = {
7561- sendVerificationEmail : ( ) => { } ,
7668+ sendVerificationEmail : ( ) => { } ,
75627669 sendPasswordResetEmail : ( ) => Promise . resolve ( ) ,
7563- sendMail : ( ) => { } ,
7670+ sendMail : ( ) => { } ,
75647671 } ;
75657672 parseServer = await global . reconfigureServer ( {
75667673 appName : 'test' ,
@@ -11157,25 +11264,25 @@ describe('ParseGraphQLServer', () => {
1115711264 } ,
1115811265 } ) ;
1115911266 const SomeClassType = new GraphQLObjectType ( {
11160- name : 'SomeClass' ,
11161- fields : {
11162- nameUpperCase : {
11163- type : new GraphQLNonNull ( GraphQLString ) ,
11164- resolve : p => p . name . toUpperCase ( ) ,
11165- } ,
11166- type : { type : TypeEnum } ,
11167- language : {
11168- type : new GraphQLEnumType ( {
11169- name : 'LanguageEnum' ,
11170- values : {
11171- fr : { value : 'fr' } ,
11172- en : { value : 'en' } ,
11173- } ,
11174- } ) ,
11175- resolve : ( ) => 'fr' ,
11176- } ,
11267+ name : 'SomeClass' ,
11268+ fields : {
11269+ nameUpperCase : {
11270+ type : new GraphQLNonNull ( GraphQLString ) ,
11271+ resolve : p => p . name . toUpperCase ( ) ,
1117711272 } ,
11178- } ) ,
11273+ type : { type : TypeEnum } ,
11274+ language : {
11275+ type : new GraphQLEnumType ( {
11276+ name : 'LanguageEnum' ,
11277+ values : {
11278+ fr : { value : 'fr' } ,
11279+ en : { value : 'en' } ,
11280+ } ,
11281+ } ) ,
11282+ resolve : ( ) => 'fr' ,
11283+ } ,
11284+ } ,
11285+ } ) ,
1117911286 parseGraphQLServer = new ParseGraphQLServer ( parseServer , {
1118011287 graphQLPath : '/graphql' ,
1118111288 graphQLCustomTypeDefs : new GraphQLSchema ( {
0 commit comments