From 78239ac9071167fdf243c55ae4bc9a2c0b0d89aa Mon Sep 17 00:00:00 2001 From: Antoine Cormouls Date: Fri, 17 Jul 2020 18:50:41 +0200 Subject: [PATCH] Merge pull request from GHSA-236h-rqv8-8q73 * Fix graphql viewer breach * fix * remove comment --- spec/ParseGraphQLServer.spec.js | 330 +++++++++++++++----------- src/GraphQL/loaders/usersMutations.js | 32 ++- src/GraphQL/loaders/usersQueries.js | 45 ++-- 3 files changed, 226 insertions(+), 181 deletions(-) diff --git a/spec/ParseGraphQLServer.spec.js b/spec/ParseGraphQLServer.spec.js index b805cabe96..c1f23bc733 100644 --- a/spec/ParseGraphQLServer.spec.js +++ b/spec/ParseGraphQLServer.spec.js @@ -170,7 +170,7 @@ describe('ParseGraphQLServer', () => { new ParseGraphQLServer(parseServer, { graphQLPath: 'somepath', }).applyGraphQL({ - use: (path) => { + use: path => { useCount++; expect(path).toEqual('somepath'); }, @@ -208,7 +208,7 @@ describe('ParseGraphQLServer', () => { graphQLPath: 'graphQL', playgroundPath: 'somepath', }).applyPlayground({ - get: (path) => { + get: path => { useCount++; expect(path).toEqual('somepath'); }, @@ -436,9 +436,7 @@ describe('ParseGraphQLServer', () => { parseGraphQLServer.applyGraphQL(expressApp); parseGraphQLServer.applyPlayground(expressApp); parseGraphQLServer.createSubscriptions(httpServer); - await new Promise((resolve) => - httpServer.listen({ port: 13377 }, resolve) - ); + await new Promise(resolve => httpServer.listen({ port: 13377 }, resolve)); const subscriptionClient = new SubscriptionClient( 'ws://localhost:13377/subscriptions', @@ -506,7 +504,7 @@ describe('ParseGraphQLServer', () => { let checked = false; const apolloClient = new ApolloClient({ link: new ApolloLink((operation, forward) => { - return forward(operation).map((response) => { + return forward(operation).map(response => { const context = operation.getContext(); const { response: { headers }, @@ -541,7 +539,7 @@ describe('ParseGraphQLServer', () => { it('should handle Parse headers', async () => { let checked = false; const originalGetGraphQLOptions = parseGraphQLServer._getGraphQLOptions; - parseGraphQLServer._getGraphQLOptions = async (req) => { + parseGraphQLServer._getGraphQLOptions = async req => { expect(req.info).toBeDefined(); expect(req.config).toBeDefined(); expect(req.auth).toBeDefined(); @@ -643,7 +641,7 @@ describe('ParseGraphQLServer', () => { }) ).data['__type']; expect(fileType.kind).toEqual('OBJECT'); - expect(fileType.fields.map((field) => field.name).sort()).toEqual([ + expect(fileType.fields.map(field => field.name).sort()).toEqual([ 'name', 'url', ]); @@ -665,7 +663,7 @@ describe('ParseGraphQLServer', () => { }) ).data['__type']; expect(classType.kind).toEqual('INTERFACE'); - expect(classType.fields.map((field) => field.name).sort()).toEqual([ + expect(classType.fields.map(field => field.name).sort()).toEqual([ 'ACL', 'createdAt', 'objectId', @@ -690,7 +688,7 @@ describe('ParseGraphQLServer', () => { ).data['__type']; expect(readPreferenceType.kind).toEqual('ENUM'); expect( - readPreferenceType.enumValues.map((value) => value.name).sort() + readPreferenceType.enumValues.map(value => value.name).sort() ).toEqual([ 'NEAREST', 'PRIMARY', @@ -731,7 +729,7 @@ describe('ParseGraphQLServer', () => { } `, }) - ).data['__schema'].types.map((type) => type.name); + ).data['__schema'].types.map(type => type.name); const expectedTypes = [ 'ParseObject', @@ -741,7 +739,7 @@ describe('ParseGraphQLServer', () => { 'Upload', ]; expect( - expectedTypes.every((type) => schemaTypes.indexOf(type) !== -1) + expectedTypes.every(type => schemaTypes.indexOf(type) !== -1) ).toBeTruthy(JSON.stringify(schemaTypes.types)); }); }); @@ -768,7 +766,7 @@ describe('ParseGraphQLServer', () => { } `, }) - ).data['__schema'].types.map((type) => type.name); + ).data['__schema'].types.map(type => type.name); expect(schemaTypes).toContain('Node'); }); @@ -786,7 +784,7 @@ describe('ParseGraphQLServer', () => { } `, }) - ).data['__type'].fields.map((field) => field.name); + ).data['__type'].fields.map(field => field.name); expect(queryFields).toContain('node'); }); @@ -804,7 +802,7 @@ describe('ParseGraphQLServer', () => { } `, }) - ).data['__type'].fields.map((field) => field.name); + ).data['__type'].fields.map(field => field.name); expect(userFields).toContain('id'); expect(userFields).toContain('objectId'); @@ -824,7 +822,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].inputFields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(createFileInputFields).toEqual(['clientMutationId', 'upload']); @@ -844,7 +842,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].fields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(createFilePayloadFields).toEqual([ @@ -869,7 +867,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].inputFields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(callFunctionInputFields).toEqual([ @@ -895,7 +893,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].fields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(callFunctionPayloadFields).toEqual([ @@ -918,7 +916,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].inputFields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(inputFields).toEqual(['clientMutationId', 'fields']); @@ -938,7 +936,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].fields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(payloadFields).toEqual(['clientMutationId', 'viewer']); @@ -958,7 +956,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].inputFields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(inputFields).toEqual([ @@ -982,7 +980,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].fields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(payloadFields).toEqual(['clientMutationId', 'viewer']); @@ -1002,7 +1000,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].inputFields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(inputFields).toEqual(['clientMutationId']); @@ -1022,7 +1020,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].fields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(payloadFields).toEqual(['clientMutationId', 'viewer']); @@ -1042,7 +1040,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].inputFields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(inputFields).toEqual([ @@ -1066,7 +1064,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].fields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(payloadFields).toEqual(['class', 'clientMutationId']); @@ -1086,7 +1084,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].inputFields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(inputFields).toEqual([ @@ -1110,7 +1108,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].fields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(payloadFields).toEqual(['class', 'clientMutationId']); @@ -1130,7 +1128,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].inputFields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(inputFields).toEqual(['clientMutationId', 'name']); @@ -1150,7 +1148,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].fields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(payloadFields).toEqual(['class', 'clientMutationId']); @@ -1175,7 +1173,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].inputFields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(createObjectInputFields).toEqual([ @@ -1203,7 +1201,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].fields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(createObjectPayloadFields).toEqual([ @@ -1231,7 +1229,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].inputFields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(createObjectInputFields).toEqual([ @@ -1260,7 +1258,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].fields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(createObjectPayloadFields).toEqual([ @@ -1288,7 +1286,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].inputFields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(createObjectInputFields).toEqual(['clientMutationId', 'id']); @@ -1313,7 +1311,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type'].fields - .map((field) => field.name) + .map(field => field.name) .sort(); expect(createObjectPayloadFields).toEqual([ @@ -1339,7 +1337,7 @@ describe('ParseGraphQLServer', () => { } `, }) - ).data['__schema'].types.map((type) => type.name); + ).data['__schema'].types.map(type => type.name); const expectedTypes = [ 'Role', @@ -1354,7 +1352,7 @@ describe('ParseGraphQLServer', () => { 'UpdateUserFieldsInput', ]; expect( - expectedTypes.every((type) => schemaTypes.indexOf(type) !== -1) + expectedTypes.every(type => schemaTypes.indexOf(type) !== -1) ).toBeTruthy(JSON.stringify(schemaTypes)); }); @@ -1373,7 +1371,7 @@ describe('ParseGraphQLServer', () => { `, }) ).data['__type']; - const possibleTypes = objectType.possibleTypes.map((o) => o.name); + const possibleTypes = objectType.possibleTypes.map(o => o.name); expect(possibleTypes).toContain('User'); expect(possibleTypes).toContain('Role'); expect(possibleTypes).toContain('Element'); @@ -1397,7 +1395,7 @@ describe('ParseGraphQLServer', () => { } `, }) - ).data['__type'].fields.map((field) => field.name); + ).data['__type'].fields.map(field => field.name); expect(userFields.indexOf('foo') !== -1).toBeTruthy(); }); @@ -1414,7 +1412,7 @@ describe('ParseGraphQLServer', () => { } `, }) - ).data['__type'].fields.map((field) => field.name); + ).data['__type'].fields.map(field => field.name); expect(userFields.includes('password')).toBeFalsy(); }); }); @@ -1896,13 +1894,13 @@ describe('ParseGraphQLServer', () => { `, }); expect( - __type.inputFields.find((o) => o.name === 'price').type.kind + __type.inputFields.find(o => o.name === 'price').type.kind ).toEqual('SCALAR'); expect( - __type.inputFields.find((o) => o.name === 'engine').type.kind + __type.inputFields.find(o => o.name === 'engine').type.kind ).toEqual('NON_NULL'); expect( - __type.inputFields.find((o) => o.name === 'doors').type.kind + __type.inputFields.find(o => o.name === 'doors').type.kind ).toEqual('NON_NULL'); const { @@ -1922,13 +1920,13 @@ describe('ParseGraphQLServer', () => { `, }); expect( - __type2.fields.find((o) => o.name === 'price').type.kind + __type2.fields.find(o => o.name === 'price').type.kind ).toEqual('SCALAR'); expect( - __type2.fields.find((o) => o.name === 'engine').type.kind + __type2.fields.find(o => o.name === 'engine').type.kind ).toEqual('NON_NULL'); expect( - __type2.fields.find((o) => o.name === 'doors').type.kind + __type2.fields.find(o => o.name === 'doors').type.kind ).toEqual('NON_NULL'); }); @@ -2787,7 +2785,7 @@ describe('ParseGraphQLServer', () => { ).toEqual(2); expect( findSecondaryObjectsResult.data.secondaryObjects.edges - .map((value) => value.node.someField) + .map(value => value.node.someField) .sort() ).toEqual(['some value 22', 'some value 44']); expect( @@ -2954,7 +2952,7 @@ describe('ParseGraphQLServer', () => { ).toEqual('some value 22'); expect( createPrimaryObjectResult.data.createPrimaryObject.primaryObject.relationField.edges - .map((value) => value.node.someField) + .map(value => value.node.someField) .sort() ).toEqual(['some value 22', 'some value 44']); expect( @@ -3193,7 +3191,7 @@ describe('ParseGraphQLServer', () => { }, }, }); - const classes = Object.keys(result.data).map((fieldName) => ({ + const classes = Object.keys(result.data).map(fieldName => ({ clientMutationId: result.data[fieldName].clientMutationId, class: { name: result.data[fieldName].class.name, @@ -3358,9 +3356,9 @@ describe('ParseGraphQLServer', () => { }, }); findResult.data.classes = findResult.data.classes - .filter((schemaClass) => !schemaClass.name.startsWith('_')) + .filter(schemaClass => !schemaClass.name.startsWith('_')) .sort((a, b) => (a.name > b.name ? 1 : -1)); - findResult.data.classes.forEach((schemaClass) => { + findResult.data.classes.forEach(schemaClass => { schemaClass.schemaFields = schemaClass.schemaFields.sort((a, b) => a.name > b.name ? 1 : -1 ); @@ -4277,10 +4275,10 @@ describe('ParseGraphQLServer', () => { expect(result.manyRelations.length).toEqual(2); const customerSubObject = result.manyRelations.find( - (o) => o.objectId === obj1.id + o => o.objectId === obj1.id ); const someClassSubObject = result.manyRelations.find( - (o) => o.objectId === obj2.id + o => o.objectId === obj2.id ); expect(customerSubObject).toBeDefined(); @@ -4289,7 +4287,7 @@ describe('ParseGraphQLServer', () => { 'imCustomerOne' ); const formatedArrayField = customerSubObject.arrayField.map( - (elem) => elem.value + elem => elem.value ); expect(formatedArrayField).toEqual(arrayField); expect(someClassSubObject.someClassField).toEqual( @@ -4445,7 +4443,7 @@ describe('ParseGraphQLServer', () => { await Promise.all( objects .slice(0, 3) - .map((obj) => + .map(obj => expectAsync( getObject(obj.className, obj.id) ).toBeRejectedWith(jasmine.stringMatching('Object not found')) @@ -4456,7 +4454,7 @@ describe('ParseGraphQLServer', () => { .someField ).toEqual('someValue4'); await Promise.all( - objects.map(async (obj) => + objects.map(async obj => expect( ( await getObject(obj.className, obj.id, { @@ -4467,7 +4465,7 @@ describe('ParseGraphQLServer', () => { ) ); await Promise.all( - objects.map(async (obj) => + objects.map(async obj => expect( ( await getObject(obj.className, obj.id, { @@ -4478,7 +4476,7 @@ describe('ParseGraphQLServer', () => { ) ); await Promise.all( - objects.map(async (obj) => + objects.map(async obj => expect( ( await getObject(obj.className, obj.id, { @@ -4494,7 +4492,7 @@ describe('ParseGraphQLServer', () => { }) ).toBeRejectedWith(jasmine.stringMatching('Object not found')); await Promise.all( - [object1, object3, object4].map(async (obj) => + [object1, object3, object4].map(async obj => expect( ( await getObject(obj.className, obj.id, { @@ -4505,7 +4503,7 @@ describe('ParseGraphQLServer', () => { ) ); await Promise.all( - objects.slice(0, 3).map((obj) => + objects.slice(0, 3).map(obj => expectAsync( getObject(obj.className, obj.id, { 'X-Parse-Session-Token': user4.getSessionToken(), @@ -4521,7 +4519,7 @@ describe('ParseGraphQLServer', () => { ).data.get.someField ).toEqual('someValue4'); await Promise.all( - objects.slice(0, 2).map((obj) => + objects.slice(0, 2).map(obj => expectAsync( getObject(obj.className, obj.id, { 'X-Parse-Session-Token': user5.getSessionToken(), @@ -4646,7 +4644,7 @@ describe('ParseGraphQLServer', () => { ).toBeDefined(); }); - it('should respect protectedFields', async (done) => { + it('should respect protectedFields', async done => { await prepareData(); await parseGraphQLServer.parseGraphQLSchema.databaseController.schemaCache.clear(); @@ -4762,7 +4760,7 @@ describe('ParseGraphQLServer', () => { let foundUserClassReadPreference = false; databaseAdapter.database.serverConfig.cursor.calls .all() - .forEach((call) => { + .forEach(call => { if ( call.args[0].ns.collection.indexOf('GraphQLClass') >= 0 ) { @@ -4826,7 +4824,7 @@ describe('ParseGraphQLServer', () => { let foundUserClassReadPreference = false; databaseAdapter.database.serverConfig.cursor.calls .all() - .forEach((call) => { + .forEach(call => { if (call.args[0].ns.collection.indexOf('GraphQLClass') >= 0) { foundGraphQLClassReadPreference = true; expect(call.args[0].options.readPreference.mode).toBe( @@ -4886,7 +4884,7 @@ describe('ParseGraphQLServer', () => { let foundUserClassReadPreference = false; databaseAdapter.database.serverConfig.cursor.calls .all() - .forEach((call) => { + .forEach(call => { if (call.args[0].ns.collection.indexOf('GraphQLClass') >= 0) { foundGraphQLClassReadPreference = true; expect(call.args[0].options.readPreference.mode).toBe( @@ -4936,7 +4934,7 @@ describe('ParseGraphQLServer', () => { expect(result.data.customers.edges.length).toEqual(2); - result.data.customers.edges.forEach((resultObj) => { + result.data.customers.edges.forEach(resultObj => { const obj = resultObj.node.objectId === obj1.id ? obj1 : obj2; expect(resultObj.node.objectId).toEqual(obj.id); expect(resultObj.node.someField).toEqual(obj.get('someField')); @@ -4977,12 +4975,12 @@ describe('ParseGraphQLServer', () => { expect( (await findObjects('GraphQLClass')).data.find.edges.map( - (object) => object.node.someField + object => object.node.someField ) ).toEqual([]); expect( (await findObjects('PublicClass')).data.find.edges.map( - (object) => object.node.someField + object => object.node.someField ) ).toEqual(['someValue4']); expect( @@ -4991,7 +4989,7 @@ describe('ParseGraphQLServer', () => { 'X-Parse-Master-Key': 'test', }) ).data.find.edges - .map((object) => object.node.someField) + .map(object => object.node.someField) .sort() ).toEqual(['someValue1', 'someValue2', 'someValue3']); expect( @@ -4999,7 +4997,7 @@ describe('ParseGraphQLServer', () => { await findObjects('PublicClass', { 'X-Parse-Master-Key': 'test', }) - ).data.find.edges.map((object) => object.node.someField) + ).data.find.edges.map(object => object.node.someField) ).toEqual(['someValue4']); expect( ( @@ -5007,7 +5005,7 @@ describe('ParseGraphQLServer', () => { 'X-Parse-Session-Token': user1.getSessionToken(), }) ).data.find.edges - .map((object) => object.node.someField) + .map(object => object.node.someField) .sort() ).toEqual(['someValue1', 'someValue2', 'someValue3']); expect( @@ -5015,7 +5013,7 @@ describe('ParseGraphQLServer', () => { await findObjects('PublicClass', { 'X-Parse-Session-Token': user1.getSessionToken(), }) - ).data.find.edges.map((object) => object.node.someField) + ).data.find.edges.map(object => object.node.someField) ).toEqual(['someValue4']); expect( ( @@ -5023,7 +5021,7 @@ describe('ParseGraphQLServer', () => { 'X-Parse-Session-Token': user2.getSessionToken(), }) ).data.find.edges - .map((object) => object.node.someField) + .map(object => object.node.someField) .sort() ).toEqual(['someValue1', 'someValue2', 'someValue3']); expect( @@ -5032,7 +5030,7 @@ describe('ParseGraphQLServer', () => { 'X-Parse-Session-Token': user3.getSessionToken(), }) ).data.find.edges - .map((object) => object.node.someField) + .map(object => object.node.someField) .sort() ).toEqual(['someValue1', 'someValue3']); expect( @@ -5040,14 +5038,14 @@ describe('ParseGraphQLServer', () => { await findObjects('GraphQLClass', { 'X-Parse-Session-Token': user4.getSessionToken(), }) - ).data.find.edges.map((object) => object.node.someField) + ).data.find.edges.map(object => object.node.someField) ).toEqual([]); expect( ( await findObjects('GraphQLClass', { 'X-Parse-Session-Token': user5.getSessionToken(), }) - ).data.find.edges.map((object) => object.node.someField) + ).data.find.edges.map(object => object.node.someField) ).toEqual(['someValue3']); }); @@ -5100,7 +5098,7 @@ describe('ParseGraphQLServer', () => { expect( result.data.graphQLClasses.edges - .map((object) => object.node.someField) + .map(object => object.node.someField) .sort() ).toEqual(['someValue1', 'someValue3']); }); @@ -5178,7 +5176,7 @@ describe('ParseGraphQLServer', () => { expect( result.data.graphQLClasses.edges - .map((object) => object.node.someField) + .map(object => object.node.someField) .sort() ).toEqual(['someValue1', 'someValue2']); }); @@ -5345,7 +5343,7 @@ describe('ParseGraphQLServer', () => { }); expect( - result.data.find.edges.map((obj) => obj.node.someField) + result.data.find.edges.map(obj => obj.node.someField) ).toEqual(['someValue14', 'someValue17']); }); @@ -5416,7 +5414,7 @@ describe('ParseGraphQLServer', () => { let result = await find(); expect( - result.data.someClasses.edges.map((edge) => edge.node.numberField) + result.data.someClasses.edges.map(edge => edge.node.numberField) ).toEqual(numberArray(0, 99)); expect(result.data.someClasses.count).toEqual(100); expect(result.data.someClasses.pageInfo.hasPreviousPage).toEqual( @@ -5432,7 +5430,7 @@ describe('ParseGraphQLServer', () => { result = await find({ first: 10 }); expect( - result.data.someClasses.edges.map((edge) => edge.node.numberField) + result.data.someClasses.edges.map(edge => edge.node.numberField) ).toEqual(numberArray(0, 9)); expect(result.data.someClasses.count).toEqual(100); expect(result.data.someClasses.pageInfo.hasPreviousPage).toEqual( @@ -5451,7 +5449,7 @@ describe('ParseGraphQLServer', () => { after: result.data.someClasses.pageInfo.endCursor, }); expect( - result.data.someClasses.edges.map((edge) => edge.node.numberField) + result.data.someClasses.edges.map(edge => edge.node.numberField) ).toEqual(numberArray(10, 19)); expect(result.data.someClasses.count).toEqual(100); expect(result.data.someClasses.pageInfo.hasPreviousPage).toEqual( @@ -5467,7 +5465,7 @@ describe('ParseGraphQLServer', () => { result = await find({ last: 10 }); expect( - result.data.someClasses.edges.map((edge) => edge.node.numberField) + result.data.someClasses.edges.map(edge => edge.node.numberField) ).toEqual(numberArray(90, 99)); expect(result.data.someClasses.count).toEqual(100); expect(result.data.someClasses.pageInfo.hasPreviousPage).toEqual( @@ -5486,7 +5484,7 @@ describe('ParseGraphQLServer', () => { before: result.data.someClasses.pageInfo.startCursor, }); expect( - result.data.someClasses.edges.map((edge) => edge.node.numberField) + result.data.someClasses.edges.map(edge => edge.node.numberField) ).toEqual(numberArray(80, 89)); expect(result.data.someClasses.count).toEqual(100); expect(result.data.someClasses.pageInfo.hasPreviousPage).toEqual( @@ -5820,7 +5818,7 @@ describe('ParseGraphQLServer', () => { let foundUserClassReadPreference = false; databaseAdapter.database.serverConfig.cursor.calls .all() - .forEach((call) => { + .forEach(call => { if (call.args[0].ns.collection.indexOf('GraphQLClass') >= 0) { foundGraphQLClassReadPreference = true; expect(call.args[0].options.readPreference.mode).toBe( @@ -5877,7 +5875,7 @@ describe('ParseGraphQLServer', () => { let foundUserClassReadPreference = false; databaseAdapter.database.serverConfig.cursor.calls .all() - .forEach((call) => { + .forEach(call => { if (call.args[0].ns.collection.indexOf('GraphQLClass') >= 0) { foundGraphQLClassReadPreference = true; expect(call.args[0].options.readPreference.mode).toBe( @@ -5937,7 +5935,7 @@ describe('ParseGraphQLServer', () => { let foundUserClassReadPreference = false; databaseAdapter.database.serverConfig.cursor.calls .all() - .forEach((call) => { + .forEach(call => { if (call.args[0].ns.collection.indexOf('GraphQLClass') >= 0) { foundGraphQLClassReadPreference = true; expect(call.args[0].options.readPreference.mode).toBe( @@ -6008,7 +6006,7 @@ describe('ParseGraphQLServer', () => { let foundUserClassReadPreference = false; databaseAdapter.database.serverConfig.cursor.calls .all() - .forEach((call) => { + .forEach(call => { if ( call.args[0].ns.collection.indexOf('GraphQLClass') >= 0 ) { @@ -6067,7 +6065,7 @@ describe('ParseGraphQLServer', () => { } expect( - result.data.graphQLClasses.edges.map((edge) => edge.node.objectId) + result.data.graphQLClasses.edges.map(edge => edge.node.objectId) ).toEqual([object3.id, object1.id, object2.id]); }); @@ -6120,7 +6118,7 @@ describe('ParseGraphQLServer', () => { expect( result.data.parentClass.graphQLClasses.edges.map( - (edge) => edge.node.objectId + edge => edge.node.objectId ) ).toEqual([object3.id, object1.id, object2.id]); } @@ -6384,7 +6382,7 @@ describe('ParseGraphQLServer', () => { } await Promise.all( - objects.slice(0, 3).map(async (obj) => { + objects.slice(0, 3).map(async obj => { const originalFieldValue = obj.get('someField'); await expectAsync( updateObject(obj.className, obj.id, { @@ -6405,7 +6403,7 @@ describe('ParseGraphQLServer', () => { await object4.fetch({ useMasterKey: true }); expect(object4.get('someField')).toEqual('changedValue1'); await Promise.all( - objects.map(async (obj) => { + objects.map(async obj => { expect( ( await updateObject( @@ -6421,7 +6419,7 @@ describe('ParseGraphQLServer', () => { }) ); await Promise.all( - objects.map(async (obj) => { + objects.map(async obj => { expect( ( await updateObject( @@ -6437,7 +6435,7 @@ describe('ParseGraphQLServer', () => { }) ); await Promise.all( - objects.map(async (obj) => { + objects.map(async obj => { expect( ( await updateObject( @@ -6453,7 +6451,7 @@ describe('ParseGraphQLServer', () => { }) ); await Promise.all( - [object1, object3, object4].map(async (obj) => { + [object1, object3, object4].map(async obj => { expect( ( await updateObject( @@ -6480,7 +6478,7 @@ describe('ParseGraphQLServer', () => { await object2.fetch({ useMasterKey: true }); expect(object2.get('someField')).toEqual(originalFieldValue); await Promise.all( - objects.slice(0, 3).map(async (obj) => { + objects.slice(0, 3).map(async obj => { const originalFieldValue = obj.get('someField'); await expectAsync( updateObject( @@ -6507,7 +6505,7 @@ describe('ParseGraphQLServer', () => { await object4.fetch({ useMasterKey: true }); expect(object4.get('someField')).toEqual('changedValue6'); await Promise.all( - objects.slice(0, 2).map(async (obj) => { + objects.slice(0, 2).map(async obj => { const originalFieldValue = obj.get('someField'); await expectAsync( updateObject( @@ -6583,7 +6581,7 @@ describe('ParseGraphQLServer', () => { } await Promise.all( - objects.slice(0, 3).map(async (obj) => { + objects.slice(0, 3).map(async obj => { const originalFieldValue = obj.get('someField'); await expectAsync( updateObject(obj.className, obj.id, { @@ -6607,7 +6605,7 @@ describe('ParseGraphQLServer', () => { await object4.fetch({ useMasterKey: true }); expect(object4.get('someField')).toEqual('changedValue1'); await Promise.all( - objects.map(async (obj) => { + objects.map(async obj => { expect( ( await updateObject( @@ -6626,7 +6624,7 @@ describe('ParseGraphQLServer', () => { }) ); await Promise.all( - objects.map(async (obj) => { + objects.map(async obj => { expect( ( await updateObject( @@ -6645,7 +6643,7 @@ describe('ParseGraphQLServer', () => { }) ); await Promise.all( - objects.map(async (obj) => { + objects.map(async obj => { expect( ( await updateObject( @@ -6664,7 +6662,7 @@ describe('ParseGraphQLServer', () => { }) ); await Promise.all( - [object1, object3, object4].map(async (obj) => { + [object1, object3, object4].map(async obj => { expect( ( await updateObject( @@ -6694,7 +6692,7 @@ describe('ParseGraphQLServer', () => { await object2.fetch({ useMasterKey: true }); expect(object2.get('someField')).toEqual(originalFieldValue); await Promise.all( - objects.slice(0, 3).map(async (obj) => { + objects.slice(0, 3).map(async obj => { const originalFieldValue = obj.get('someField'); await expectAsync( updateObject( @@ -6724,7 +6722,7 @@ describe('ParseGraphQLServer', () => { await object4.fetch({ useMasterKey: true }); expect(object4.get('someField')).toEqual('changedValue6'); await Promise.all( - objects.slice(0, 2).map(async (obj) => { + objects.slice(0, 2).map(async obj => { const originalFieldValue = obj.get('someField'); await expectAsync( updateObject( @@ -6851,7 +6849,7 @@ describe('ParseGraphQLServer', () => { } await Promise.all( - objects.slice(0, 3).map(async (obj) => { + objects.slice(0, 3).map(async obj => { const originalFieldValue = obj.get('someField'); await expectAsync( deleteObject(obj.className, obj.id) @@ -6861,7 +6859,7 @@ describe('ParseGraphQLServer', () => { }) ); await Promise.all( - objects.slice(0, 3).map(async (obj) => { + objects.slice(0, 3).map(async obj => { const originalFieldValue = obj.get('someField'); await expectAsync( deleteObject(obj.className, obj.id, { @@ -6952,7 +6950,7 @@ describe('ParseGraphQLServer', () => { } await Promise.all( - objects.slice(0, 3).map(async (obj) => { + objects.slice(0, 3).map(async obj => { const originalFieldValue = obj.get('someField'); await expectAsync( deleteObject(obj.className, obj.id) @@ -6962,7 +6960,7 @@ describe('ParseGraphQLServer', () => { }) ); await Promise.all( - objects.slice(0, 3).map(async (obj) => { + objects.slice(0, 3).map(async obj => { const originalFieldValue = obj.get('someField'); await expectAsync( deleteObject(obj.className, obj.id, { @@ -7185,6 +7183,56 @@ describe('ParseGraphQLServer', () => { expect(resultFoo).toBeDefined(); expect(resultFoo.bar).toEqual('hello'); }); + it('should return logged user and do not by pass pointer security', async () => { + const masterKeyOnlyACL = new Parse.ACL(); + masterKeyOnlyACL.setPublicReadAccess(false); + masterKeyOnlyACL.setPublicWriteAccess(false); + const foo = new Parse.Object('Foo'); + foo.setACL(masterKeyOnlyACL); + foo.set('bar', 'hello'); + await foo.save(null, { useMasterKey: true }); + const userName = 'userx1', + password = 'user1', + email = 'emailUserx1@parse.com'; + + const user = new Parse.User(); + user.setUsername(userName); + user.setPassword(password); + user.setEmail(email); + user.set('userFoo', foo); + await user.signUp(); + + await parseGraphQLServer.parseGraphQLSchema.databaseController.schemaCache.clear(); + + const session = await Parse.Session.current(); + const result = await apolloClient.query({ + query: gql` + query GetCurrentUser { + viewer { + sessionToken + user { + id + objectId + userFoo { + bar + } + } + } + } + `, + context: { + headers: { + 'X-Parse-Session-Token': session.getSessionToken(), + }, + }, + }); + + const sessionToken = result.data.viewer.sessionToken; + const { objectId, userFoo: resultFoo } = result.data.viewer.user; + expect(objectId).toEqual(user.id); + expect(sessionToken).toBeDefined(); + expect(resultFoo).toEqual(null); + }); }); describe('Users Mutations', () => { @@ -7635,8 +7683,8 @@ describe('ParseGraphQLServer', () => { } }); - it('should accept different params', (done) => { - Parse.Cloud.define('hello', async (req) => { + it('should accept different params', done => { + Parse.Cloud.define('hello', async req => { expect(req.params.date instanceof Date).toBe(true); expect(req.params.date.getTime()).toBe(1463907600000); expect(req.params.dateList[0] instanceof Date).toBe(true); @@ -7772,7 +7820,7 @@ describe('ParseGraphQLServer', () => { ).data['__type']; expect(functionEnum.kind).toEqual('ENUM'); expect( - functionEnum.enumValues.map((value) => value.name).sort() + functionEnum.enumValues.map(value => value.name).sort() ).toEqual(['_underscored', 'a', 'b', 'contains1Number']); } catch (e) { handleError(e); @@ -7814,12 +7862,12 @@ describe('ParseGraphQLServer', () => { ).data['__type']; expect(functionEnum.kind).toEqual('ENUM'); expect( - functionEnum.enumValues.map((value) => value.name).sort() + functionEnum.enumValues.map(value => value.name).sort() ).toEqual(['a']); expect( parseGraphQLServer.parseGraphQLSchema.log.warn.calls .all() - .map((call) => call.args[0]) + .map(call => call.args[0]) .sort() ).toEqual([ 'Function 1NumberInTheBeggning could not be added to the auto schema because GraphQL names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/.', @@ -8715,13 +8763,13 @@ describe('ParseGraphQLServer', () => { expect(result.name).toEqual('imACountry2'); expect(result.companies.edges.length).toEqual(3); expect( - result.companies.edges.some((o) => o.node.objectId === company.id) + result.companies.edges.some(o => o.node.objectId === company.id) ).toBeTruthy(); expect( - result.companies.edges.some((o) => o.node.name === 'imACompany2') + result.companies.edges.some(o => o.node.name === 'imACompany2') ).toBeTruthy(); expect( - result.companies.edges.some((o) => o.node.name === 'imACompany3') + result.companies.edges.some(o => o.node.name === 'imACompany3') ).toBeTruthy(); } ); @@ -8806,16 +8854,16 @@ describe('ParseGraphQLServer', () => { expect(result.companies.edges.length).toEqual(2); expect( result.companies.edges.some( - (c) => + c => c.node.name === 'imACompany2' && - c.node.teams.edges.some((t) => t.node.name === 'imATeam2') + c.node.teams.edges.some(t => t.node.name === 'imATeam2') ) ).toBeTruthy(); expect( result.companies.edges.some( - (c) => + c => c.node.name === 'imACompany3' && - c.node.teams.edges.some((t) => t.node.name === 'imATeam3') + c.node.teams.edges.some(t => t.node.name === 'imATeam3') ) ).toBeTruthy(); }); @@ -8884,17 +8932,13 @@ describe('ParseGraphQLServer', () => { expect(result.objectId).toEqual(country.id); expect(result.companies.edges.length).toEqual(2); expect( - result.companies.edges.some( - (o) => o.node.objectId === company2.id - ) + result.companies.edges.some(o => o.node.objectId === company2.id) ).toBeTruthy(); expect( - result.companies.edges.some((o) => o.node.name === 'imACompany3') + result.companies.edges.some(o => o.node.name === 'imACompany3') ).toBeTruthy(); expect( - result.companies.edges.some( - (o) => o.node.objectId === company1.id - ) + result.companies.edges.some(o => o.node.objectId === company1.id) ).toBeFalsy(); } ); @@ -8966,7 +9010,7 @@ describe('ParseGraphQLServer', () => { expect(result.name).toEqual('imACountry2'); expect(result.companies.edges.length).toEqual(1); expect( - result.companies.edges.some((o) => o.node.name === 'imACompany2') + result.companies.edges.some(o => o.node.name === 'imACompany2') ).toBeTruthy(); } ); @@ -9017,10 +9061,10 @@ describe('ParseGraphQLServer', () => { expect(result1.objectId).toEqual(country.id); expect(result1.companies.edges.length).toEqual(2); expect( - result1.companies.edges.some((o) => o.node.objectId === company1.id) + result1.companies.edges.some(o => o.node.objectId === company1.id) ).toBeTruthy(); expect( - result1.companies.edges.some((o) => o.node.objectId === company2.id) + result1.companies.edges.some(o => o.node.objectId === company2.id) ).toBeTruthy(); // With where @@ -9762,12 +9806,12 @@ describe('ParseGraphQLServer', () => { const { edges } = someClasses; expect(edges.length).toEqual(2); expect( - edges.find((result) => result.node.id === create1.someClass.id) - .node.someField + edges.find(result => result.node.id === create1.someClass.id).node + .someField ).toEqual(someFieldValue); expect( - edges.find((result) => result.node.id === create2.someClass.id) - .node.someField + edges.find(result => result.node.id === create2.someClass.id).node + .someField ).toEqual(someFieldValue2); } catch (e) { handleError(e); @@ -9859,7 +9903,7 @@ describe('ParseGraphQLServer', () => { const { someField } = getResult.data.someClass; expect(Array.isArray(someField)).toBeTruthy(); - expect(someField.map((element) => element.value)).toEqual( + expect(someField.map(element => element.value)).toEqual( someFieldValue ); expect(getResult.data.someClasses.edges.length).toEqual(1); @@ -10276,7 +10320,7 @@ describe('ParseGraphQLServer', () => { [46, 47], [48, 49], [44, 45], - ].map((point) => ({ + ].map(point => ({ latitude: point[0], longitude: point[1], })); @@ -10356,7 +10400,7 @@ describe('ParseGraphQLServer', () => { 'object' ); expect(getResult.data.someClass.somePolygonField).toEqual( - somePolygonFieldValue.map((geoPoint) => ({ + somePolygonFieldValue.map(geoPoint => ({ ...geoPoint, __typename: 'GeoPoint', })) @@ -10672,7 +10716,7 @@ describe('ParseGraphQLServer', () => { `, }); parseGraphQLServer.applyGraphQL(expressApp); - await new Promise((resolve) => + await new Promise(resolve => httpServer.listen({ port: 13377 }, resolve) ); const httpLink = createUploadLink({ @@ -10797,7 +10841,7 @@ describe('ParseGraphQLServer', () => { fields: { nameUpperCase: { type: new GraphQLNonNull(GraphQLString), - resolve: (p) => p.name.toUpperCase(), + resolve: p => p.name.toUpperCase(), }, type: { type: TypeEnum }, language: { @@ -10858,7 +10902,7 @@ describe('ParseGraphQLServer', () => { }); parseGraphQLServer.applyGraphQL(expressApp); - await new Promise((resolve) => + await new Promise(resolve => httpServer.listen({ port: 13377 }, resolve) ); const httpLink = createUploadLink({ @@ -10992,7 +11036,7 @@ describe('ParseGraphQLServer', () => { }); parseGraphQLServer.applyGraphQL(expressApp); - await new Promise((resolve) => + await new Promise(resolve => httpServer.listen({ port: 13377 }, resolve) ); const httpLink = createUploadLink({ diff --git a/src/GraphQL/loaders/usersMutations.js b/src/GraphQL/loaders/usersMutations.js index 701929677e..09d66bd90e 100644 --- a/src/GraphQL/loaders/usersMutations.js +++ b/src/GraphQL/loaders/usersMutations.js @@ -41,7 +41,7 @@ const load = parseGraphQLSchema => { const { fields } = args; const { config, auth, info } = context; - const { sessionToken } = await objectsMutations.createObject( + const { sessionToken, objectId } = await objectsMutations.createObject( '_User', fields, config, @@ -49,15 +49,14 @@ const load = parseGraphQLSchema => { info ); - info.sessionToken = sessionToken; + context.info.sessionToken = sessionToken; return { viewer: await getUserFromSessionToken( - config, - info, + context, mutationInfo, 'viewer.user.', - true + objectId ), }; } catch (e) { @@ -120,7 +119,7 @@ const load = parseGraphQLSchema => { const { fields, authData } = args; const { config, auth, info } = context; - const { sessionToken } = await objectsMutations.createObject( + const { sessionToken, objectId } = await objectsMutations.createObject( '_User', { ...fields, authData }, config, @@ -128,15 +127,14 @@ const load = parseGraphQLSchema => { info ); - info.sessionToken = sessionToken; + context.info.sessionToken = sessionToken; return { viewer: await getUserFromSessionToken( - config, - info, + context, mutationInfo, 'viewer.user.', - true + objectId ), }; } catch (e) { @@ -183,7 +181,7 @@ const load = parseGraphQLSchema => { const { username, password } = args; const { config, auth, info } = context; - const { sessionToken } = ( + const { sessionToken, objectId } = ( await usersRouter.handleLogIn({ body: { username, @@ -196,15 +194,14 @@ const load = parseGraphQLSchema => { }) ).response; - info.sessionToken = sessionToken; + context.info.sessionToken = sessionToken; return { viewer: await getUserFromSessionToken( - config, - info, + context, mutationInfo, 'viewer.user.', - true + objectId ), }; } catch (e) { @@ -236,11 +233,10 @@ const load = parseGraphQLSchema => { const { config, auth, info } = context; const viewer = await getUserFromSessionToken( - config, - info, + context, mutationInfo, 'viewer.user.', - true + auth.user.id ); await usersRouter.handleLogOut({ diff --git a/src/GraphQL/loaders/usersQueries.js b/src/GraphQL/loaders/usersQueries.js index 6a1d3ea945..976d0b3b02 100644 --- a/src/GraphQL/loaders/usersQueries.js +++ b/src/GraphQL/loaders/usersQueries.js @@ -2,16 +2,16 @@ import { GraphQLNonNull } from 'graphql'; import getFieldNames from 'graphql-list-fields'; import Parse from 'parse/node'; import rest from '../../rest'; -import Auth from '../../Auth'; import { extractKeysAndInclude } from './parseClassTypes'; +import { Auth } from '../../Auth'; const getUserFromSessionToken = async ( - config, - info, + context, queryInfo, keysPrefix, - validatedToken + userId ) => { + const { info, config } = context; if (!info || !info.sessionToken) { throw new Parse.Error( Parse.Error.INVALID_SESSION_TOKEN, @@ -27,7 +27,7 @@ const getUserFromSessionToken = async ( const { keys } = keysAndInclude; let { include } = keysAndInclude; - if (validatedToken && !keys && !include) { + if (userId && !keys && !include) { return { sessionToken, }; @@ -35,40 +35,47 @@ const getUserFromSessionToken = async ( include = 'user'; } + if (userId) { + // We need to re create the auth context + // to avoid security breach if userId is provided + context.auth = new Auth({ + config, + isMaster: context.auth.isMaster, + user: { id: userId }, + }); + } + const options = {}; if (keys) { options.keys = keys .split(',') - .map(key => `user.${key}`) + .map(key => `${key}`) .join(','); } if (include) { options.include = include .split(',') - .map(included => `user.${included}`) + .map(included => `${included}`) .join(','); } const response = await rest.find( config, - Auth.master(config), - '_Session', - { sessionToken }, + context.auth, + '_User', + // Get the user it self from auth object + { objectId: context.auth.user.id }, options, info.clientVersion, - info.context, + info.context ); - if ( - !response.results || - response.results.length == 0 || - !response.results[0].user - ) { + if (!response.results || response.results.length == 0) { throw new Parse.Error( Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token' ); } else { - const user = response.results[0].user; + const user = response.results[0]; return { sessionToken, user, @@ -89,10 +96,8 @@ const load = parseGraphQLSchema => { type: new GraphQLNonNull(parseGraphQLSchema.viewerType), async resolve(_source, _args, context, queryInfo) { try { - const { config, info } = context; return await getUserFromSessionToken( - config, - info, + context, queryInfo, 'user.', false