diff --git a/graph/mutators/settings.js b/graph/mutators/settings.js index f725d791d..59613ae6f 100644 --- a/graph/mutators/settings.js +++ b/graph/mutators/settings.js @@ -2,20 +2,16 @@ const errors = require('../../errors'); const { UPDATE_SETTINGS, - UPDATE_WORDLIST, } = require('../../perms/constants'); const SettingsService = require('../../services/settings'); const update = async (ctx, settings) => SettingsService.update(settings); -const updateWordlist = async (ctx, wordlist) => SettingsService.updateWordlist(wordlist); - module.exports = (ctx) => { let mutators = { Settings: { update: () => Promise.reject(errors.ErrNotAuthorized), - updateWordlist: () => Promise.reject(errors.ErrNotAuthorized) } }; @@ -23,10 +19,6 @@ module.exports = (ctx) => { if (ctx.user.can(UPDATE_SETTINGS)) { mutators.Settings.update = (id, settings) => update(ctx, id, settings); } - - if (ctx.user.can(UPDATE_WORDLIST)) { - mutators.Settings.updateWordlist = (id, status) => updateWordlist(ctx, id, status); - } } return mutators; diff --git a/graph/resolvers/root_mutation.js b/graph/resolvers/root_mutation.js index 17235a59e..c3bf6b7e9 100644 --- a/graph/resolvers/root_mutation.js +++ b/graph/resolvers/root_mutation.js @@ -61,9 +61,6 @@ const RootMutation = { updateSettings: async (_, {input: settings}, {mutators: {Settings}}) => { await Settings.update(settings); }, - updateWordlist: async (_, {input: wordlist}, {mutators: {Settings}}) => { - await Settings.updateWordlist(wordlist); - }, createToken: async (_, {input}, {mutators: {Token}}) => ({ token: await Token.create(input), }), diff --git a/graph/typeDefs.graphql b/graph/typeDefs.graphql index 338ce82ea..3fbc1cec3 100644 --- a/graph/typeDefs.graphql +++ b/graph/typeDefs.graphql @@ -1250,14 +1250,6 @@ input UpdateDomainsInput { whitelist: [String!] } -# UpdateWordlistResponse contains any errors that were rendered as a result -# of the mutation. -type UpdateWordlistResponse implements Response { - - # An array of errors relating to the mutation that occurred. - errors: [UserError!] -} - # CreateTokenInput contains the input to create the token. input CreateTokenInput { @@ -1342,10 +1334,6 @@ type RootMutation { # Mutation is restricted. updateSettings(input: UpdateSettingsInput!): UpdateSettingsResponse - # updateWordlist will update the given Wordlist. - # Mutation is restricted. - updateWordlist(input: UpdateWordlistInput!): UpdateWordlistResponse - # Ignore comments by another user ignoreUser(id: ID!): IgnoreUserResponse diff --git a/perms/constants.js b/perms/constants.js index 070fe80bf..4c85f9c26 100644 --- a/perms/constants.js +++ b/perms/constants.js @@ -19,7 +19,6 @@ module.exports = { UPDATE_ASSET_SETTINGS: 'UPDATE_ASSET_SETTINGS', UPDATE_ASSET_STATUS: 'UPDATE_ASSET_STATUS', UPDATE_SETTINGS: 'UPDATE_SETTINGS', - UPDATE_WORDLIST: 'UPDATE_WORDLIST', // queries SEARCH_ASSETS: 'SEARCH_ASSETS', diff --git a/perms/mutationReducer.js b/perms/mutationReducer.js index 2e8718ed1..c44035372 100644 --- a/perms/mutationReducer.js +++ b/perms/mutationReducer.js @@ -19,7 +19,6 @@ module.exports = (user, perm) => { case types.SET_COMMENT_STATUS: case types.UPDATE_CONFIG: case types.UPDATE_SETTINGS: - case types.UPDATE_WORDLIST: case types.UPDATE_ASSET_SETTINGS: case types.UPDATE_ASSET_STATUS: return check(user, ['ADMIN', 'MODERATOR']); diff --git a/services/settings.js b/services/settings.js index 4b5680b30..b11b86d91 100644 --- a/services/settings.js +++ b/services/settings.js @@ -6,7 +6,7 @@ function dotizeRecurse(result, object, path = '') { const newPath = path ? `${path}.${key}` : key; if (typeof object[key] === 'object' && !Array.isArray(object[key])) { dotizeRecurse(result, object[key], newPath); - return; + continue; } result[newPath] = object[key]; } @@ -68,19 +68,6 @@ module.exports = class SettingsService { }); } - /** - * updateWordlist will update the wordlists. - * - * @param {Object} wordlist the Wordlist object - */ - static updateWordlist(wordlist) { - return SettingModel.findOneAndUpdate(selector, { - $set: { - wordlist, - }, - }); - } - /** * This is run once when the app starts to ensure settings are populated. */ diff --git a/test/server/graph/mutations/updateSettings.js b/test/server/graph/mutations/updateSettings.js index c1ec678d6..553a2be65 100644 --- a/test/server/graph/mutations/updateSettings.js +++ b/test/server/graph/mutations/updateSettings.js @@ -4,10 +4,12 @@ const schema = require('../../../../graph/schema'); const Context = require('../../../../graph/context'); const UserModel = require('../../../../models/user'); const SettingsService = require('../../../../services/settings'); +const isEqual = require('lodash/isEqual'); const {expect} = require('chai'); describe('graph.mutations.updateSettings', () => { + beforeEach(async () => { await SettingsService.init(); }); @@ -71,4 +73,86 @@ describe('graph.mutations.updateSettings', () => { }); }); }); + + describe('nested objects', () => { + const user = new UserModel({roles: ['ADMIN']}); + const ctx = new Context({user}); + + it('should handle nested objects', async () => { + const initSettings = { + wordlist: { + banned: ['fuck'], + suspect: ['idiot', 'nazis'], + }, + domains: { + whitelist: ['localhost:3000'], + }, + }; + + let res = await graphql(schema, QUERY, {}, ctx, { + settings: initSettings, + }); + if (res.errors) { + console.error(res.errors); + } + + if (res.data.updateSettings && res.data.updateSettings.errors) { + console.error(res.data.updateSettings.errors); + } + + expect(res.errors).to.be.empty; + expect(res.data.updateSettings).to.be.null; + + let retrievedSettings = await SettingsService.retrieve(); + Object.keys(initSettings).forEach((key) => { + Object.keys(initSettings[key]).forEach((nestedKey) => { + expect(retrievedSettings).to.have.property(key); + expect(retrievedSettings[key]).to.have.property(nestedKey); + expect(isEqual(retrievedSettings[key][nestedKey], initSettings[key][nestedKey])).to.be.true; + }); + }); + + const change = { + wordlist: { + suspect: ['idiot'], + }, + domains: { + whitelist: ['coralproject.org'], + }, + }; + + const changedSettings = Object.assign({}, initSettings, { + wordlist: { + suspect: change.wordlist.suspect, + }, + domains: { + whitelist: change.domains.whitelist, + } + }); + + res = await graphql(schema, QUERY, {}, ctx, { + settings: change, + }); + + if (res.errors) { + console.error(res.errors); + } + + if (res.data.updateSettings && res.data.updateSettings.errors) { + console.error(res.data.updateSettings.errors); + } + + expect(res.errors).to.be.empty; + expect(res.data.updateSettings).to.be.null; + + retrievedSettings = await SettingsService.retrieve(); + Object.keys(changedSettings).forEach((key) => { + Object.keys(changedSettings[key]).forEach((nestedKey) => { + expect(retrievedSettings).to.have.property(key); + expect(retrievedSettings[key]).to.have.property(nestedKey); + expect(isEqual(retrievedSettings[key][nestedKey], changedSettings[key][nestedKey])).to.be.true; + }); + }); + }); + }); }); diff --git a/test/server/graph/mutations/updateWordlist.js b/test/server/graph/mutations/updateWordlist.js deleted file mode 100644 index 3a392a074..000000000 --- a/test/server/graph/mutations/updateWordlist.js +++ /dev/null @@ -1,82 +0,0 @@ -const {graphql} = require('graphql'); - -const schema = require('../../../../graph/schema'); -const Context = require('../../../../graph/context'); -const UserModel = require('../../../../models/user'); -const SettingsService = require('../../../../services/settings'); - -const {expect} = require('chai'); - -describe('graph.mutations.updateWordlist', () => { - beforeEach(async () => { - await SettingsService.init(); - }); - - const QUERY = ` - mutation UpdateWordlist($wordlist: UpdateWordlistInput!) { - updateWordlist(input: $wordlist) { - errors { - translation_key - } - } - } -`; - - describe('context with different user roles', () => { - - [ - {error: 'NOT_AUTHORIZED'}, - {error: 'NOT_AUTHORIZED', roles: []}, - {roles: ['ADMIN']}, - {roles: ['ADMIN', 'MODERATOR']}, - {roles: ['MODERATOR']}, - ].forEach(({roles, error}) => { - it(roles && roles.length > 0 ? roles.join(', ') : '', async () => { - let user; - if (roles != null) { - user = new UserModel({roles}); - } - const ctx = new Context({user}); - - const wordlist = { - banned: [ - 'happy', - ], - suspect: [ - 'sad', - ], - }; - - const res = await graphql(schema, QUERY, {}, ctx, { - wordlist, - }); - if (res.errors) { - console.error(res.errors); - } - expect(res.errors).to.be.empty; - - if (error) { - expect(res.data.updateWordlist.errors).to.not.be.empty; - expect(res.data.updateWordlist.errors[0]).to.have.property('translation_key', error); - - const {wordlist: retrievedWordlist} = await SettingsService.retrieve(); - expect(retrievedWordlist).to.have.property('banned'); - expect(retrievedWordlist.banned).to.have.members([]); - expect(retrievedWordlist).to.have.property('suspect'); - expect(retrievedWordlist.suspect).to.have.members([]); - } else { - if (res.data.updateWordlist && res.data.updateWordlist.errors) { - console.error(res.data.updateWordlist.errors); - } - expect(res.data.updateWordlist).to.be.null; - - const {wordlist: retrievedWordlist} = await SettingsService.retrieve(); - expect(retrievedWordlist).to.have.property('banned'); - expect(retrievedWordlist.banned).to.have.members(wordlist.banned); - expect(retrievedWordlist).to.have.property('suspect'); - expect(retrievedWordlist.suspect).to.have.members(wordlist.suspect); - } - }); - }); - }); -});