From 473942ab907f626796ac0a13625d7a4393e7c3ed Mon Sep 17 00:00:00 2001 From: coratgerl <73360179+coratgerl@users.noreply.github.com> Date: Sun, 23 Nov 2025 20:59:23 +0100 Subject: [PATCH 1/4] feat: more --- spec/ParseGraphQLServer.spec.js | 27 +++++++++++ src/GraphQL/loaders/configQueries.js | 49 ++++++++++++++++++++ src/GraphQL/loaders/defaultGraphQLQueries.js | 2 + 3 files changed, 78 insertions(+) create mode 100644 src/GraphQL/loaders/configQueries.js diff --git a/spec/ParseGraphQLServer.spec.js b/spec/ParseGraphQLServer.spec.js index aa57e973ef..2f869b74c2 100644 --- a/spec/ParseGraphQLServer.spec.js +++ b/spec/ParseGraphQLServer.spec.js @@ -7080,6 +7080,33 @@ describe('ParseGraphQLServer', () => { }); }); + describe("Config Queries", () => { + fit("should return the config value for a specific parameter", async () => { + const query = gql` + query ConfigValue($paramName: String!) { + configValue(paramName: $paramName) { + value + source + } + } + `; + + const result = await apolloClient.query({ + query, + variables: { paramName: 'publicParam' }, + context: { + headers: { + 'X-Parse-Master-Key': 'test', + }, + }, + }); + + expect(result.errors).toBeUndefined(); + expect(result.data.configValue.value).toEqual('publicValue'); + expect(result.data.configValue.source).toEqual('params'); + }) + }) + describe('Users Queries', () => { it('should return current logged user', async () => { const userName = 'user1', diff --git a/src/GraphQL/loaders/configQueries.js b/src/GraphQL/loaders/configQueries.js new file mode 100644 index 0000000000..7c22ebf02a --- /dev/null +++ b/src/GraphQL/loaders/configQueries.js @@ -0,0 +1,49 @@ +import { GraphQLNonNull, GraphQLString } from 'graphql'; +import Parse from 'parse/node'; +import { createSanitizedError } from '../../Error'; +import { GlobalConfigRouter } from '../../Routers/GlobalConfigRouter'; + +const getConfigValue = async (context, paramName) => { + const { config, auth } = context; + + if (!auth.isMaster) { + throw createSanitizedError( + Parse.Error.OPERATION_FORBIDDEN, + 'Master Key is required to access GlobalConfig.' + ); + } + + const globalConfig = await GlobalConfigRouter.getGlobalConfig(config, auth); + const { params, masterKeyOnly } = globalConfig; + + // Vérifie si le paramètre existe dans params ou masterKeyOnly + if (params && params[paramName] !== undefined) { + return { value: params[paramName], source: 'params' }; + } else if (masterKeyOnly && masterKeyOnly[paramName] !== undefined) { + return { value: masterKeyOnly[paramName], source: 'masterKeyOnly' }; + } else { + throw createSanitizedError( + Parse.Error.INVALID_QUERY, + `Parameter "${paramName}" not found in GlobalConfig.` + ); + } +}; + +const load = (parseGraphQLSchema) => { + parseGraphQLSchema.addGraphQLQuery('configValue', { + description: 'Returns the value of a specific parameter from GlobalConfig.', + args: { + paramName: { type: new GraphQLNonNull(GraphQLString) }, + }, + type: new GraphQLNonNull(parseGraphQLSchema.configValueType), + async resolve(_source, args, context) { + try { + return getConfigValue(context, args.paramName); + } catch (e) { + parseGraphQLSchema.handleError(e); + } + }, + }); +}; + +export { load, getConfig, getConfigValue }; diff --git a/src/GraphQL/loaders/defaultGraphQLQueries.js b/src/GraphQL/loaders/defaultGraphQLQueries.js index 535cf62430..e98e02147b 100644 --- a/src/GraphQL/loaders/defaultGraphQLQueries.js +++ b/src/GraphQL/loaders/defaultGraphQLQueries.js @@ -1,6 +1,7 @@ import { GraphQLNonNull, GraphQLBoolean } from 'graphql'; import * as usersQueries from './usersQueries'; import * as schemaQueries from './schemaQueries'; +import * as configQueries from './configQueries'; const load = parseGraphQLSchema => { parseGraphQLSchema.addGraphQLQuery( @@ -16,6 +17,7 @@ const load = parseGraphQLSchema => { usersQueries.load(parseGraphQLSchema); schemaQueries.load(parseGraphQLSchema); + configQueries.load(parseGraphQLSchema); }; export { load }; From e92b88f1b0b70538c7cceec302852a97ff0ddef8 Mon Sep 17 00:00:00 2001 From: Lucas Coratger <73360179+coratgerl@users.noreply.github.com> Date: Sat, 29 Nov 2025 11:41:08 +0100 Subject: [PATCH 2/4] feat: add query and mutation to use Parse.Config --- spec/ParseGraphQLServer.spec.js | 261 +++++++++++++++++- src/GraphQL/ParseGraphQLSchema.js | 4 +- src/GraphQL/loaders/configMutations.js | 76 +++++ src/GraphQL/loaders/configQueries.js | 48 ++-- .../loaders/defaultGraphQLMutations.js | 2 + 5 files changed, 367 insertions(+), 24 deletions(-) create mode 100644 src/GraphQL/loaders/configMutations.js diff --git a/spec/ParseGraphQLServer.spec.js b/spec/ParseGraphQLServer.spec.js index 2f869b74c2..f0267518b0 100644 --- a/spec/ParseGraphQLServer.spec.js +++ b/spec/ParseGraphQLServer.spec.js @@ -7081,12 +7081,21 @@ describe('ParseGraphQLServer', () => { }); describe("Config Queries", () => { - fit("should return the config value for a specific parameter", async () => { + beforeEach(async () => { + // Setup initial config data + await Parse.Config.save( + { publicParam: 'publicValue', privateParam: 'privateValue' }, + { privateParam: true }, + { useMasterKey: true } + ); + }); + + it("should return the config value for a specific parameter", async () => { const query = gql` - query ConfigValue($paramName: String!) { + query configValue($paramName: String!) { configValue(paramName: $paramName) { value - source + isMasterKeyOnly } } `; @@ -7103,8 +7112,250 @@ describe('ParseGraphQLServer', () => { expect(result.errors).toBeUndefined(); expect(result.data.configValue.value).toEqual('publicValue'); - expect(result.data.configValue.source).toEqual('params'); - }) + expect(result.data.configValue.isMasterKeyOnly).toEqual(false); + }); + + it("should return null for non-existent parameter", async () => { + const query = gql` + query configValue($paramName: String!) { + configValue(paramName: $paramName) { + value + isMasterKeyOnly + } + } + `; + + const result = await apolloClient.query({ + query, + variables: { paramName: 'nonExistentParam' }, + context: { + headers: { + 'X-Parse-Master-Key': 'test', + }, + }, + }); + + expect(result.errors).toBeUndefined(); + expect(result.data.configValue.value).toBeNull(); + expect(result.data.configValue.isMasterKeyOnly).toBeNull(); + }); + }); + + describe("Config Mutations", () => { + it("should update a config value using mutation and retrieve it with query", async () => { + const mutation = gql` + mutation updateConfigValue($input: UpdateConfigValueInput!) { + updateConfigValue(input: $input) { + clientMutationId + configValue { + value + isMasterKeyOnly + } + } + } + `; + + const query = gql` + query configValue($paramName: String!) { + configValue(paramName: $paramName) { + value + isMasterKeyOnly + } + } + `; + + const mutationResult = await apolloClient.mutate({ + mutation, + variables: { + input: { + clientMutationId: 'test-mutation-id', + paramName: 'testParam', + value: 'testValue', + isMasterKeyOnly: false, + }, + }, + context: { + headers: { + 'X-Parse-Master-Key': 'test', + }, + }, + }); + + expect(mutationResult.errors).toBeUndefined(); + expect(mutationResult.data.updateConfigValue.configValue.value).toEqual('testValue'); + expect(mutationResult.data.updateConfigValue.configValue.isMasterKeyOnly).toEqual(false); + + const queryResult = await apolloClient.query({ + query, + variables: { paramName: 'testParam' }, + context: { + headers: { + 'X-Parse-Master-Key': 'test', + }, + }, + }); + + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data.configValue.value).toEqual('testValue'); + expect(queryResult.data.configValue.isMasterKeyOnly).toEqual(false); + }); + + it("should update a config value with isMasterKeyOnly set to true", async () => { + const mutation = gql` + mutation updateConfigValue($input: UpdateConfigValueInput!) { + updateConfigValue(input: $input) { + clientMutationId + configValue { + value + isMasterKeyOnly + } + } + } + `; + + const query = gql` + query configValue($paramName: String!) { + configValue(paramName: $paramName) { + value + isMasterKeyOnly + } + } + `; + + const mutationResult = await apolloClient.mutate({ + mutation, + variables: { + input: { + clientMutationId: 'test-mutation-id-2', + paramName: 'privateTestParam', + value: 'privateValue', + isMasterKeyOnly: true, + }, + }, + context: { + headers: { + 'X-Parse-Master-Key': 'test', + }, + }, + }); + + expect(mutationResult.errors).toBeUndefined(); + expect(mutationResult.data.updateConfigValue.configValue.value).toEqual('privateValue'); + expect(mutationResult.data.updateConfigValue.configValue.isMasterKeyOnly).toEqual(true); + + const queryResult = await apolloClient.query({ + query, + variables: { paramName: 'privateTestParam' }, + context: { + headers: { + 'X-Parse-Master-Key': 'test', + }, + }, + }); + + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data.configValue.value).toEqual('privateValue'); + expect(queryResult.data.configValue.isMasterKeyOnly).toEqual(true); + }); + + it("should update an existing config value", async () => { + await Parse.Config.save( + { existingParam: 'initialValue' }, + {}, + { useMasterKey: true } + ); + + const mutation = gql` + mutation updateConfigValue($input: UpdateConfigValueInput!) { + updateConfigValue(input: $input) { + clientMutationId + configValue { + value + isMasterKeyOnly + } + } + } + `; + + const query = gql` + query configValue($paramName: String!) { + configValue(paramName: $paramName) { + value + isMasterKeyOnly + } + } + `; + + const mutationResult = await apolloClient.mutate({ + mutation, + variables: { + input: { + clientMutationId: 'test-mutation-id-3', + paramName: 'existingParam', + value: 'updatedValue', + isMasterKeyOnly: false, + }, + }, + context: { + headers: { + 'X-Parse-Master-Key': 'test', + }, + }, + }); + + expect(mutationResult.errors).toBeUndefined(); + expect(mutationResult.data.updateConfigValue.configValue.value).toEqual('updatedValue'); + + const queryResult = await apolloClient.query({ + query, + variables: { paramName: 'existingParam' }, + context: { + headers: { + 'X-Parse-Master-Key': 'test', + }, + }, + }); + + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data.configValue.value).toEqual('updatedValue'); + }); + + it("should require master key to update config", async () => { + const mutation = gql` + mutation updateConfigValue($input: UpdateConfigValueInput!) { + updateConfigValue(input: $input) { + clientMutationId + configValue { + value + isMasterKeyOnly + } + } + } + `; + + try { + await apolloClient.mutate({ + mutation, + variables: { + input: { + clientMutationId: 'test-mutation-id-4', + paramName: 'testParam', + value: 'testValue', + isMasterKeyOnly: false, + }, + }, + context: { + headers: { + 'X-Parse-Application-Id': 'test', + }, + }, + }); + fail('Should have thrown an error'); + } catch (error) { + expect(error.graphQLErrors).toBeDefined(); + expect(error.graphQLErrors[0].message).toContain('Permission denied'); + } + }); }) describe('Users Queries', () => { diff --git a/src/GraphQL/ParseGraphQLSchema.js b/src/GraphQL/ParseGraphQLSchema.js index 154e774897..831fa07161 100644 --- a/src/GraphQL/ParseGraphQLSchema.js +++ b/src/GraphQL/ParseGraphQLSchema.js @@ -49,7 +49,7 @@ const RESERVED_GRAPHQL_TYPE_NAMES = [ 'DeleteClassPayload', 'PageInfo', ]; -const RESERVED_GRAPHQL_QUERY_NAMES = ['health', 'viewer', 'class', 'classes']; +const RESERVED_GRAPHQL_QUERY_NAMES = ['health', 'viewer', 'class', 'classes', 'configValue']; const RESERVED_GRAPHQL_MUTATION_NAMES = [ 'signUp', 'logIn', @@ -59,6 +59,7 @@ const RESERVED_GRAPHQL_MUTATION_NAMES = [ 'createClass', 'updateClass', 'deleteClass', + 'updateConfigValue', ]; class ParseGraphQLSchema { @@ -118,6 +119,7 @@ class ParseGraphQLSchema { this.functionNamesString = functionNamesString; this.parseClassTypes = {}; this.viewerType = null; + this.configValueType = null; this.graphQLAutoSchema = null; this.graphQLSchema = null; this.graphQLTypes = []; diff --git a/src/GraphQL/loaders/configMutations.js b/src/GraphQL/loaders/configMutations.js new file mode 100644 index 0000000000..22fa1d45ad --- /dev/null +++ b/src/GraphQL/loaders/configMutations.js @@ -0,0 +1,76 @@ +import { GraphQLNonNull, GraphQLString, GraphQLBoolean } from 'graphql'; +import { mutationWithClientMutationId } from 'graphql-relay'; +import Parse from 'parse/node'; +import { createSanitizedError } from '../../Error'; +import GlobalConfigRouter from '../../Routers/GlobalConfigRouter'; + +const globalConfigRouter = new GlobalConfigRouter(); + +const updateConfigValue = async (context, paramName, value, isMasterKeyOnly = false) => { + const { config, auth } = context; + + if (!auth.isMaster) { + throw createSanitizedError( + Parse.Error.OPERATION_FORBIDDEN, + 'Master Key is required to update GlobalConfig.' + ); + } + + await globalConfigRouter.updateGlobalConfig({ + body: { + params: { [paramName]: value }, + masterKeyOnly: { [paramName]: isMasterKeyOnly }, + }, + config, + auth, + context, + }); + + return { value, isMasterKeyOnly }; +}; + +const load = parseGraphQLSchema => { + const updateConfigValueMutation = mutationWithClientMutationId({ + name: 'UpdateConfigValue', + description: 'Updates the value of a specific parameter in GlobalConfig.', + inputFields: { + paramName: { + description: 'The name of the parameter to set.', + type: new GraphQLNonNull(GraphQLString), + }, + value: { + description: 'The value to set for the parameter.', + type: new GraphQLNonNull(GraphQLString), + }, + isMasterKeyOnly: { + description: 'Whether this parameter should only be accessible with master key.', + type: GraphQLBoolean, + defaultValue: false, + }, + }, + outputFields: { + configValue: { + description: 'The updated config value.', + type: new GraphQLNonNull(parseGraphQLSchema.configValueType), + }, + }, + mutateAndGetPayload: async (args, context) => { + try { + const { paramName, value, isMasterKeyOnly } = args; + const result = await updateConfigValue(context, paramName, value, isMasterKeyOnly); + return { + configValue: result, + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + }, + }); + + parseGraphQLSchema.addGraphQLType(updateConfigValueMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(updateConfigValueMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('updateConfigValue', updateConfigValueMutation, true, true); +}; + +export { load, updateConfigValue }; + diff --git a/src/GraphQL/loaders/configQueries.js b/src/GraphQL/loaders/configQueries.js index 7c22ebf02a..c67ab09db6 100644 --- a/src/GraphQL/loaders/configQueries.js +++ b/src/GraphQL/loaders/configQueries.js @@ -1,9 +1,8 @@ -import { GraphQLNonNull, GraphQLString } from 'graphql'; +import { GraphQLNonNull, GraphQLString, GraphQLBoolean, GraphQLObjectType } from 'graphql'; import Parse from 'parse/node'; import { createSanitizedError } from '../../Error'; -import { GlobalConfigRouter } from '../../Routers/GlobalConfigRouter'; -const getConfigValue = async (context, paramName) => { +const configValue = async (context, paramName) => { const { config, auth } = context; if (!auth.isMaster) { @@ -13,23 +12,36 @@ const getConfigValue = async (context, paramName) => { ); } - const globalConfig = await GlobalConfigRouter.getGlobalConfig(config, auth); - const { params, masterKeyOnly } = globalConfig; + const results = await config.database.find('_GlobalConfig', { objectId: '1' }, { limit: 1 }); - // Vérifie si le paramètre existe dans params ou masterKeyOnly - if (params && params[paramName] !== undefined) { - return { value: params[paramName], source: 'params' }; - } else if (masterKeyOnly && masterKeyOnly[paramName] !== undefined) { - return { value: masterKeyOnly[paramName], source: 'masterKeyOnly' }; - } else { - throw createSanitizedError( - Parse.Error.INVALID_QUERY, - `Parameter "${paramName}" not found in GlobalConfig.` - ); + if (results.length !== 1) { + return { value: null, isMasterKeyOnly: null }; + } + + const globalConfig = results[0]; + const params = globalConfig.params || {}; + const masterKeyOnly = globalConfig.masterKeyOnly || {}; + + if (params && params[paramName] !== undefined && masterKeyOnly && masterKeyOnly[paramName] !== undefined) { + return { value: params[paramName], isMasterKeyOnly: masterKeyOnly[paramName] }; } + + return { value: null, isMasterKeyOnly: null }; }; const load = (parseGraphQLSchema) => { + if (!parseGraphQLSchema.configValueType) { + const configValueType = new GraphQLObjectType({ + name: 'ConfigValue', + fields: { + value: { type: GraphQLString }, + isMasterKeyOnly: { type: GraphQLBoolean }, + }, + }); + parseGraphQLSchema.addGraphQLType(configValueType, true, true); + parseGraphQLSchema.configValueType = configValueType; + } + parseGraphQLSchema.addGraphQLQuery('configValue', { description: 'Returns the value of a specific parameter from GlobalConfig.', args: { @@ -38,12 +50,12 @@ const load = (parseGraphQLSchema) => { type: new GraphQLNonNull(parseGraphQLSchema.configValueType), async resolve(_source, args, context) { try { - return getConfigValue(context, args.paramName); + return configValue(context, args.paramName); } catch (e) { parseGraphQLSchema.handleError(e); } }, - }); + }, false, true); }; -export { load, getConfig, getConfigValue }; +export { load, configValue }; diff --git a/src/GraphQL/loaders/defaultGraphQLMutations.js b/src/GraphQL/loaders/defaultGraphQLMutations.js index 4d997a4822..46f513fb8e 100644 --- a/src/GraphQL/loaders/defaultGraphQLMutations.js +++ b/src/GraphQL/loaders/defaultGraphQLMutations.js @@ -2,12 +2,14 @@ import * as filesMutations from './filesMutations'; import * as usersMutations from './usersMutations'; import * as functionsMutations from './functionsMutations'; import * as schemaMutations from './schemaMutations'; +import * as configMutations from './configMutations'; const load = parseGraphQLSchema => { filesMutations.load(parseGraphQLSchema); usersMutations.load(parseGraphQLSchema); functionsMutations.load(parseGraphQLSchema); schemaMutations.load(parseGraphQLSchema); + configMutations.load(parseGraphQLSchema); }; export { load }; From a6c2bf21aeac75a661f7fa9e153bd2c9cdc6733b Mon Sep 17 00:00:00 2001 From: Lucas Coratger <73360179+coratgerl@users.noreply.github.com> Date: Sat, 29 Nov 2025 11:55:23 +0100 Subject: [PATCH 3/4] fix: feedbacks --- src/GraphQL/loaders/configQueries.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/GraphQL/loaders/configQueries.js b/src/GraphQL/loaders/configQueries.js index c67ab09db6..7b126645d1 100644 --- a/src/GraphQL/loaders/configQueries.js +++ b/src/GraphQL/loaders/configQueries.js @@ -22,8 +22,8 @@ const configValue = async (context, paramName) => { const params = globalConfig.params || {}; const masterKeyOnly = globalConfig.masterKeyOnly || {}; - if (params && params[paramName] !== undefined && masterKeyOnly && masterKeyOnly[paramName] !== undefined) { - return { value: params[paramName], isMasterKeyOnly: masterKeyOnly[paramName] }; + if (params[paramName] !== undefined) { + return { value: params[paramName], isMasterKeyOnly: masterKeyOnly[paramName] ?? null }; } return { value: null, isMasterKeyOnly: null }; @@ -50,7 +50,7 @@ const load = (parseGraphQLSchema) => { type: new GraphQLNonNull(parseGraphQLSchema.configValueType), async resolve(_source, args, context) { try { - return configValue(context, args.paramName); + return await configValue(context, args.paramName); } catch (e) { parseGraphQLSchema.handleError(e); } From d8d0d798fbd882b9067da4bc153f0ce2c713d376 Mon Sep 17 00:00:00 2001 From: Lucas Coratger <73360179+coratgerl@users.noreply.github.com> Date: Tue, 2 Dec 2025 18:03:37 +0100 Subject: [PATCH 4/4] fix: feedbacks --- spec/ParseGraphQLServer.spec.js | 72 +++++++++++++------------- src/GraphQL/ParseGraphQLSchema.js | 6 +-- src/GraphQL/loaders/configMutations.js | 22 ++++---- src/GraphQL/loaders/configQueries.js | 18 +++---- 4 files changed, 59 insertions(+), 59 deletions(-) diff --git a/spec/ParseGraphQLServer.spec.js b/spec/ParseGraphQLServer.spec.js index f0267518b0..a767f413b3 100644 --- a/spec/ParseGraphQLServer.spec.js +++ b/spec/ParseGraphQLServer.spec.js @@ -7092,8 +7092,8 @@ describe('ParseGraphQLServer', () => { it("should return the config value for a specific parameter", async () => { const query = gql` - query configValue($paramName: String!) { - configValue(paramName: $paramName) { + query cloudConfig($paramName: String!) { + cloudConfig(paramName: $paramName) { value isMasterKeyOnly } @@ -7111,14 +7111,14 @@ describe('ParseGraphQLServer', () => { }); expect(result.errors).toBeUndefined(); - expect(result.data.configValue.value).toEqual('publicValue'); - expect(result.data.configValue.isMasterKeyOnly).toEqual(false); + expect(result.data.cloudConfig.value).toEqual('publicValue'); + expect(result.data.cloudConfig.isMasterKeyOnly).toEqual(false); }); it("should return null for non-existent parameter", async () => { const query = gql` - query configValue($paramName: String!) { - configValue(paramName: $paramName) { + query cloudConfig($paramName: String!) { + cloudConfig(paramName: $paramName) { value isMasterKeyOnly } @@ -7136,18 +7136,18 @@ describe('ParseGraphQLServer', () => { }); expect(result.errors).toBeUndefined(); - expect(result.data.configValue.value).toBeNull(); - expect(result.data.configValue.isMasterKeyOnly).toBeNull(); + expect(result.data.cloudConfig.value).toBeNull(); + expect(result.data.cloudConfig.isMasterKeyOnly).toBeNull(); }); }); describe("Config Mutations", () => { it("should update a config value using mutation and retrieve it with query", async () => { const mutation = gql` - mutation updateConfigValue($input: UpdateConfigValueInput!) { - updateConfigValue(input: $input) { + mutation updateCloudConfig($input: UpdateCloudConfigInput!) { + updateCloudConfig(input: $input) { clientMutationId - configValue { + cloudConfig { value isMasterKeyOnly } @@ -7156,8 +7156,8 @@ describe('ParseGraphQLServer', () => { `; const query = gql` - query configValue($paramName: String!) { - configValue(paramName: $paramName) { + query cloudConfig($paramName: String!) { + cloudConfig(paramName: $paramName) { value isMasterKeyOnly } @@ -7182,8 +7182,8 @@ describe('ParseGraphQLServer', () => { }); expect(mutationResult.errors).toBeUndefined(); - expect(mutationResult.data.updateConfigValue.configValue.value).toEqual('testValue'); - expect(mutationResult.data.updateConfigValue.configValue.isMasterKeyOnly).toEqual(false); + expect(mutationResult.data.updateCloudConfig.cloudConfig.value).toEqual('testValue'); + expect(mutationResult.data.updateCloudConfig.cloudConfig.isMasterKeyOnly).toEqual(false); const queryResult = await apolloClient.query({ query, @@ -7196,16 +7196,16 @@ describe('ParseGraphQLServer', () => { }); expect(queryResult.errors).toBeUndefined(); - expect(queryResult.data.configValue.value).toEqual('testValue'); - expect(queryResult.data.configValue.isMasterKeyOnly).toEqual(false); + expect(queryResult.data.cloudConfig.value).toEqual('testValue'); + expect(queryResult.data.cloudConfig.isMasterKeyOnly).toEqual(false); }); it("should update a config value with isMasterKeyOnly set to true", async () => { const mutation = gql` - mutation updateConfigValue($input: UpdateConfigValueInput!) { - updateConfigValue(input: $input) { + mutation updateCloudConfig($input: UpdateCloudConfigInput!) { + updateCloudConfig(input: $input) { clientMutationId - configValue { + cloudConfig { value isMasterKeyOnly } @@ -7214,8 +7214,8 @@ describe('ParseGraphQLServer', () => { `; const query = gql` - query configValue($paramName: String!) { - configValue(paramName: $paramName) { + query cloudConfig($paramName: String!) { + cloudConfig(paramName: $paramName) { value isMasterKeyOnly } @@ -7240,8 +7240,8 @@ describe('ParseGraphQLServer', () => { }); expect(mutationResult.errors).toBeUndefined(); - expect(mutationResult.data.updateConfigValue.configValue.value).toEqual('privateValue'); - expect(mutationResult.data.updateConfigValue.configValue.isMasterKeyOnly).toEqual(true); + expect(mutationResult.data.updateCloudConfig.cloudConfig.value).toEqual('privateValue'); + expect(mutationResult.data.updateCloudConfig.cloudConfig.isMasterKeyOnly).toEqual(true); const queryResult = await apolloClient.query({ query, @@ -7254,8 +7254,8 @@ describe('ParseGraphQLServer', () => { }); expect(queryResult.errors).toBeUndefined(); - expect(queryResult.data.configValue.value).toEqual('privateValue'); - expect(queryResult.data.configValue.isMasterKeyOnly).toEqual(true); + expect(queryResult.data.cloudConfig.value).toEqual('privateValue'); + expect(queryResult.data.cloudConfig.isMasterKeyOnly).toEqual(true); }); it("should update an existing config value", async () => { @@ -7266,10 +7266,10 @@ describe('ParseGraphQLServer', () => { ); const mutation = gql` - mutation updateConfigValue($input: UpdateConfigValueInput!) { - updateConfigValue(input: $input) { + mutation updateCloudConfig($input: UpdateCloudConfigInput!) { + updateCloudConfig(input: $input) { clientMutationId - configValue { + cloudConfig { value isMasterKeyOnly } @@ -7278,8 +7278,8 @@ describe('ParseGraphQLServer', () => { `; const query = gql` - query configValue($paramName: String!) { - configValue(paramName: $paramName) { + query cloudConfig($paramName: String!) { + cloudConfig(paramName: $paramName) { value isMasterKeyOnly } @@ -7304,7 +7304,7 @@ describe('ParseGraphQLServer', () => { }); expect(mutationResult.errors).toBeUndefined(); - expect(mutationResult.data.updateConfigValue.configValue.value).toEqual('updatedValue'); + expect(mutationResult.data.updateCloudConfig.cloudConfig.value).toEqual('updatedValue'); const queryResult = await apolloClient.query({ query, @@ -7317,15 +7317,15 @@ describe('ParseGraphQLServer', () => { }); expect(queryResult.errors).toBeUndefined(); - expect(queryResult.data.configValue.value).toEqual('updatedValue'); + expect(queryResult.data.cloudConfig.value).toEqual('updatedValue'); }); it("should require master key to update config", async () => { const mutation = gql` - mutation updateConfigValue($input: UpdateConfigValueInput!) { - updateConfigValue(input: $input) { + mutation updateCloudConfig($input: UpdateCloudConfigInput!) { + updateCloudConfig(input: $input) { clientMutationId - configValue { + cloudConfig { value isMasterKeyOnly } diff --git a/src/GraphQL/ParseGraphQLSchema.js b/src/GraphQL/ParseGraphQLSchema.js index 831fa07161..5ecdd78de5 100644 --- a/src/GraphQL/ParseGraphQLSchema.js +++ b/src/GraphQL/ParseGraphQLSchema.js @@ -49,7 +49,7 @@ const RESERVED_GRAPHQL_TYPE_NAMES = [ 'DeleteClassPayload', 'PageInfo', ]; -const RESERVED_GRAPHQL_QUERY_NAMES = ['health', 'viewer', 'class', 'classes', 'configValue']; +const RESERVED_GRAPHQL_QUERY_NAMES = ['health', 'viewer', 'class', 'classes', 'cloudConfig']; const RESERVED_GRAPHQL_MUTATION_NAMES = [ 'signUp', 'logIn', @@ -59,7 +59,7 @@ const RESERVED_GRAPHQL_MUTATION_NAMES = [ 'createClass', 'updateClass', 'deleteClass', - 'updateConfigValue', + 'updateCloudConfig', ]; class ParseGraphQLSchema { @@ -119,7 +119,7 @@ class ParseGraphQLSchema { this.functionNamesString = functionNamesString; this.parseClassTypes = {}; this.viewerType = null; - this.configValueType = null; + this.cloudConfigType = null; this.graphQLAutoSchema = null; this.graphQLSchema = null; this.graphQLTypes = []; diff --git a/src/GraphQL/loaders/configMutations.js b/src/GraphQL/loaders/configMutations.js index 22fa1d45ad..c7c6176d68 100644 --- a/src/GraphQL/loaders/configMutations.js +++ b/src/GraphQL/loaders/configMutations.js @@ -6,7 +6,7 @@ import GlobalConfigRouter from '../../Routers/GlobalConfigRouter'; const globalConfigRouter = new GlobalConfigRouter(); -const updateConfigValue = async (context, paramName, value, isMasterKeyOnly = false) => { +const updateCloudConfig = async (context, paramName, value, isMasterKeyOnly = false) => { const { config, auth } = context; if (!auth.isMaster) { @@ -30,8 +30,8 @@ const updateConfigValue = async (context, paramName, value, isMasterKeyOnly = fa }; const load = parseGraphQLSchema => { - const updateConfigValueMutation = mutationWithClientMutationId({ - name: 'UpdateConfigValue', + const updateCloudConfigMutation = mutationWithClientMutationId({ + name: 'UpdateCloudConfig', description: 'Updates the value of a specific parameter in GlobalConfig.', inputFields: { paramName: { @@ -49,17 +49,17 @@ const load = parseGraphQLSchema => { }, }, outputFields: { - configValue: { + cloudConfig: { description: 'The updated config value.', - type: new GraphQLNonNull(parseGraphQLSchema.configValueType), + type: new GraphQLNonNull(parseGraphQLSchema.cloudConfigType), }, }, mutateAndGetPayload: async (args, context) => { try { const { paramName, value, isMasterKeyOnly } = args; - const result = await updateConfigValue(context, paramName, value, isMasterKeyOnly); + const result = await updateCloudConfig(context, paramName, value, isMasterKeyOnly); return { - configValue: result, + cloudConfig: result, }; } catch (e) { parseGraphQLSchema.handleError(e); @@ -67,10 +67,10 @@ const load = parseGraphQLSchema => { }, }); - parseGraphQLSchema.addGraphQLType(updateConfigValueMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(updateConfigValueMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('updateConfigValue', updateConfigValueMutation, true, true); + parseGraphQLSchema.addGraphQLType(updateCloudConfigMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(updateCloudConfigMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('updateCloudConfig', updateCloudConfigMutation, true, true); }; -export { load, updateConfigValue }; +export { load, updateCloudConfig }; diff --git a/src/GraphQL/loaders/configQueries.js b/src/GraphQL/loaders/configQueries.js index 7b126645d1..0320d68395 100644 --- a/src/GraphQL/loaders/configQueries.js +++ b/src/GraphQL/loaders/configQueries.js @@ -2,7 +2,7 @@ import { GraphQLNonNull, GraphQLString, GraphQLBoolean, GraphQLObjectType } from import Parse from 'parse/node'; import { createSanitizedError } from '../../Error'; -const configValue = async (context, paramName) => { +const cloudConfig = async (context, paramName) => { const { config, auth } = context; if (!auth.isMaster) { @@ -30,27 +30,27 @@ const configValue = async (context, paramName) => { }; const load = (parseGraphQLSchema) => { - if (!parseGraphQLSchema.configValueType) { - const configValueType = new GraphQLObjectType({ + if (!parseGraphQLSchema.cloudConfigType) { + const cloudConfigType = new GraphQLObjectType({ name: 'ConfigValue', fields: { value: { type: GraphQLString }, isMasterKeyOnly: { type: GraphQLBoolean }, }, }); - parseGraphQLSchema.addGraphQLType(configValueType, true, true); - parseGraphQLSchema.configValueType = configValueType; + parseGraphQLSchema.addGraphQLType(cloudConfigType, true, true); + parseGraphQLSchema.cloudConfigType = cloudConfigType; } - parseGraphQLSchema.addGraphQLQuery('configValue', { + parseGraphQLSchema.addGraphQLQuery('cloudConfig', { description: 'Returns the value of a specific parameter from GlobalConfig.', args: { paramName: { type: new GraphQLNonNull(GraphQLString) }, }, - type: new GraphQLNonNull(parseGraphQLSchema.configValueType), + type: new GraphQLNonNull(parseGraphQLSchema.cloudConfigType), async resolve(_source, args, context) { try { - return await configValue(context, args.paramName); + return await cloudConfig(context, args.paramName); } catch (e) { parseGraphQLSchema.handleError(e); } @@ -58,4 +58,4 @@ const load = (parseGraphQLSchema) => { }, false, true); }; -export { load, configValue }; +export { load, cloudConfig };