| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 | const graphHelper = require('../../helpers/graph')const safeRegex = require('safe-regex')const _ = require('lodash')const gql = require('graphql')/* global WIKI */module.exports = {  Query: {    async groups () { return {} }  },  Mutation: {    async groups () { return {} }  },  GroupQuery: {    /**     * FETCH ALL GROUPS     */    async list () {      return WIKI.models.groups.query().select(        'groups.*',        WIKI.models.groups.relatedQuery('users').count().as('userCount')      )    },    /**     * FETCH A SINGLE GROUP     */    async single(obj, args) {      return WIKI.models.groups.query().findById(args.id)    }  },  GroupMutation: {    /**     * ASSIGN USER TO GROUP     */    async assignUser (obj, args, { req }) {      // Check for guest user      if (args.userId === 2) {        throw new gql.GraphQLError('Cannot assign the Guest user to a group.')      }      // Check for valid group      const grp = await WIKI.models.groups.query().findById(args.groupId)      if (!grp) {        throw new gql.GraphQLError('Invalid Group ID')      }      // Check assigned permissions for write:groups      if (        WIKI.auth.checkExclusiveAccess(req.user, ['write:groups'], ['manage:groups', 'manage:system']) &&        grp.permissions.some(p => {          const resType = _.last(p.split(':'))          return ['users', 'groups', 'navigation', 'theme', 'api', 'system'].includes(resType)        })      ) {        throw new gql.GraphQLError('You are not authorized to assign a user to this elevated group.')      }      // Check for valid user      const usr = await WIKI.models.users.query().findById(args.userId)      if (!usr) {        throw new gql.GraphQLError('Invalid User ID')      }      // Check for existing relation      const relExist = await WIKI.models.knex('userGroups').where({        userId: args.userId,        groupId: args.groupId      }).first()      if (relExist) {        throw new gql.GraphQLError('User is already assigned to group.')      }      // Assign user to group      await grp.$relatedQuery('users').relate(usr.id)      // Revoke tokens for this user      WIKI.auth.revokeUserTokens({ id: usr.id, kind: 'u' })      WIKI.events.outbound.emit('addAuthRevoke', { id: usr.id, kind: 'u' })      return {        responseResult: graphHelper.generateSuccess('User has been assigned to group.')      }    },    /**     * CREATE NEW GROUP     */    async create (obj, args, { req }) {      const group = await WIKI.models.groups.query().insertAndFetch({        name: args.name,        permissions: JSON.stringify(WIKI.data.groups.defaultPermissions),        pageRules: JSON.stringify(WIKI.data.groups.defaultPageRules),        isSystem: false      })      await WIKI.auth.reloadGroups()      WIKI.events.outbound.emit('reloadGroups')      return {        responseResult: graphHelper.generateSuccess('Group created successfully.'),        group      }    },    /**     * DELETE GROUP     */    async delete (obj, args) {      if (args.id === 1 || args.id === 2) {        throw new gql.GraphQLError('Cannot delete this group.')      }      await WIKI.models.groups.query().deleteById(args.id)      WIKI.auth.revokeUserTokens({ id: args.id, kind: 'g' })      WIKI.events.outbound.emit('addAuthRevoke', { id: args.id, kind: 'g' })      await WIKI.auth.reloadGroups()      WIKI.events.outbound.emit('reloadGroups')      return {        responseResult: graphHelper.generateSuccess('Group has been deleted.')      }    },    /**     * UNASSIGN USER FROM GROUP     */    async unassignUser (obj, args) {      if (args.userId === 2) {        throw new gql.GraphQLError('Cannot unassign Guest user')      }      if (args.userId === 1 && args.groupId === 1) {        throw new gql.GraphQLError('Cannot unassign Administrator user from Administrators group.')      }      const grp = await WIKI.models.groups.query().findById(args.groupId)      if (!grp) {        throw new gql.GraphQLError('Invalid Group ID')      }      const usr = await WIKI.models.users.query().findById(args.userId)      if (!usr) {        throw new gql.GraphQLError('Invalid User ID')      }      await grp.$relatedQuery('users').unrelate().where('userId', usr.id)      WIKI.auth.revokeUserTokens({ id: usr.id, kind: 'u' })      WIKI.events.outbound.emit('addAuthRevoke', { id: usr.id, kind: 'u' })      return {        responseResult: graphHelper.generateSuccess('User has been unassigned from group.')      }    },    /**     * UPDATE GROUP     */    async update (obj, args, { req }) {      // Check for unsafe regex page rules      if (_.some(args.pageRules, pr => {        return pr.match === 'REGEX' && !safeRegex(pr.path)      })) {        throw new gql.GraphQLError('Some Page Rules contains unsafe or exponential time regex.')      }      // Set default redirect on login value      if (_.isEmpty(args.redirectOnLogin)) {        args.redirectOnLogin = '/'      }      // Check assigned permissions for write:groups      if (        WIKI.auth.checkExclusiveAccess(req.user, ['write:groups'], ['manage:groups', 'manage:system']) &&        args.permissions.some(p => {          const resType = _.last(p.split(':'))          return ['users', 'groups', 'navigation', 'theme', 'api', 'system'].includes(resType)        })      ) {        throw new gql.GraphQLError('You are not authorized to manage this group or assign these permissions.')      }      // Update group      await WIKI.models.groups.query().patch({        name: args.name,        redirectOnLogin: args.redirectOnLogin,        permissions: JSON.stringify(args.permissions),        pageRules: JSON.stringify(args.pageRules)      }).where('id', args.id)      // Revoke tokens for this group      WIKI.auth.revokeUserTokens({ id: args.id, kind: 'g' })      WIKI.events.outbound.emit('addAuthRevoke', { id: args.id, kind: 'g' })      // Reload group permissions      await WIKI.auth.reloadGroups()      WIKI.events.outbound.emit('reloadGroups')      return {        responseResult: graphHelper.generateSuccess('Group has been updated.')      }    }  },  Group: {    users (grp) {      return grp.$relatedQuery('users')    }  }}
 |