group.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. const graphHelper = require('../../helpers/graph')
  2. const safeRegex = require('safe-regex')
  3. const _ = require('lodash')
  4. const gql = require('graphql')
  5. /* global WIKI */
  6. module.exports = {
  7. Query: {
  8. /**
  9. * FETCH ALL GROUPS
  10. */
  11. async groups () {
  12. return WIKI.models.groups.query().select(
  13. 'groups.*',
  14. WIKI.models.groups.relatedQuery('users').count().as('userCount')
  15. )
  16. },
  17. /**
  18. * FETCH A SINGLE GROUP
  19. */
  20. async groupById(obj, args) {
  21. return WIKI.models.groups.query().findById(args.id)
  22. }
  23. },
  24. Mutation: {
  25. /**
  26. * ASSIGN USER TO GROUP
  27. */
  28. async assignUserToGroup (obj, args, { req }) {
  29. // Check for guest user
  30. if (args.userId === 2) {
  31. throw new gql.GraphQLError('Cannot assign the Guest user to a group.')
  32. }
  33. // Check for valid group
  34. const grp = await WIKI.models.groups.query().findById(args.groupId)
  35. if (!grp) {
  36. throw new gql.GraphQLError('Invalid Group ID')
  37. }
  38. // Check assigned permissions for write:groups
  39. if (
  40. WIKI.auth.checkExclusiveAccess(req.user, ['write:groups'], ['manage:groups', 'manage:system']) &&
  41. grp.permissions.some(p => {
  42. const resType = _.last(p.split(':'))
  43. return ['users', 'groups', 'navigation', 'theme', 'api', 'system'].includes(resType)
  44. })
  45. ) {
  46. throw new gql.GraphQLError('You are not authorized to assign a user to this elevated group.')
  47. }
  48. // Check for valid user
  49. const usr = await WIKI.models.users.query().findById(args.userId)
  50. if (!usr) {
  51. throw new gql.GraphQLError('Invalid User ID')
  52. }
  53. // Check for existing relation
  54. const relExist = await WIKI.models.knex('userGroups').where({
  55. userId: args.userId,
  56. groupId: args.groupId
  57. }).first()
  58. if (relExist) {
  59. throw new gql.GraphQLError('User is already assigned to group.')
  60. }
  61. // Assign user to group
  62. await grp.$relatedQuery('users').relate(usr.id)
  63. // Revoke tokens for this user
  64. WIKI.auth.revokeUserTokens({ id: usr.id, kind: 'u' })
  65. WIKI.events.outbound.emit('addAuthRevoke', { id: usr.id, kind: 'u' })
  66. return {
  67. responseResult: graphHelper.generateSuccess('User has been assigned to group.')
  68. }
  69. },
  70. /**
  71. * CREATE NEW GROUP
  72. */
  73. async createGroup (obj, args, { req }) {
  74. const group = await WIKI.models.groups.query().insertAndFetch({
  75. name: args.name,
  76. permissions: JSON.stringify(WIKI.data.groups.defaultPermissions),
  77. pageRules: JSON.stringify(WIKI.data.groups.defaultPageRules),
  78. isSystem: false
  79. })
  80. await WIKI.auth.reloadGroups()
  81. WIKI.events.outbound.emit('reloadGroups')
  82. return {
  83. responseResult: graphHelper.generateSuccess('Group created successfully.'),
  84. group
  85. }
  86. },
  87. /**
  88. * DELETE GROUP
  89. */
  90. async deleteGroup (obj, args) {
  91. if (args.id === 1 || args.id === 2) {
  92. throw new gql.GraphQLError('Cannot delete this group.')
  93. }
  94. await WIKI.models.groups.query().deleteById(args.id)
  95. WIKI.auth.revokeUserTokens({ id: args.id, kind: 'g' })
  96. WIKI.events.outbound.emit('addAuthRevoke', { id: args.id, kind: 'g' })
  97. await WIKI.auth.reloadGroups()
  98. WIKI.events.outbound.emit('reloadGroups')
  99. return {
  100. responseResult: graphHelper.generateSuccess('Group has been deleted.')
  101. }
  102. },
  103. /**
  104. * UNASSIGN USER FROM GROUP
  105. */
  106. async unassignUserFromGroup (obj, args) {
  107. if (args.userId === 2) {
  108. throw new gql.GraphQLError('Cannot unassign Guest user')
  109. }
  110. if (args.userId === 1 && args.groupId === 1) {
  111. throw new gql.GraphQLError('Cannot unassign Administrator user from Administrators group.')
  112. }
  113. const grp = await WIKI.models.groups.query().findById(args.groupId)
  114. if (!grp) {
  115. throw new gql.GraphQLError('Invalid Group ID')
  116. }
  117. const usr = await WIKI.models.users.query().findById(args.userId)
  118. if (!usr) {
  119. throw new gql.GraphQLError('Invalid User ID')
  120. }
  121. await grp.$relatedQuery('users').unrelate().where('userId', usr.id)
  122. WIKI.auth.revokeUserTokens({ id: usr.id, kind: 'u' })
  123. WIKI.events.outbound.emit('addAuthRevoke', { id: usr.id, kind: 'u' })
  124. return {
  125. responseResult: graphHelper.generateSuccess('User has been unassigned from group.')
  126. }
  127. },
  128. /**
  129. * UPDATE GROUP
  130. */
  131. async updateGroup (obj, args, { req }) {
  132. // Check for unsafe regex page rules
  133. if (_.some(args.pageRules, pr => {
  134. return pr.match === 'REGEX' && !safeRegex(pr.path)
  135. })) {
  136. throw new gql.GraphQLError('Some Page Rules contains unsafe or exponential time regex.')
  137. }
  138. // Set default redirect on login value
  139. if (_.isEmpty(args.redirectOnLogin)) {
  140. args.redirectOnLogin = '/'
  141. }
  142. // Check assigned permissions for write:groups
  143. if (
  144. WIKI.auth.checkExclusiveAccess(req.user, ['write:groups'], ['manage:groups', 'manage:system']) &&
  145. args.permissions.some(p => {
  146. const resType = _.last(p.split(':'))
  147. return ['users', 'groups', 'navigation', 'theme', 'api', 'system'].includes(resType)
  148. })
  149. ) {
  150. throw new gql.GraphQLError('You are not authorized to manage this group or assign these permissions.')
  151. }
  152. // Check assigned permissions for manage:groups
  153. if (
  154. WIKI.auth.checkExclusiveAccess(req.user, ['manage:groups'], ['manage:system']) &&
  155. args.permissions.some(p => _.last(p.split(':')) === 'system')
  156. ) {
  157. throw new gql.GraphQLError('You are not authorized to manage this group or assign the manage:system permissions.')
  158. }
  159. // Update group
  160. await WIKI.models.groups.query().patch({
  161. name: args.name,
  162. redirectOnLogin: args.redirectOnLogin,
  163. permissions: JSON.stringify(args.permissions),
  164. pageRules: JSON.stringify(args.pageRules)
  165. }).where('id', args.id)
  166. // Revoke tokens for this group
  167. WIKI.auth.revokeUserTokens({ id: args.id, kind: 'g' })
  168. WIKI.events.outbound.emit('addAuthRevoke', { id: args.id, kind: 'g' })
  169. // Reload group permissions
  170. await WIKI.auth.reloadGroups()
  171. WIKI.events.outbound.emit('reloadGroups')
  172. return {
  173. responseResult: graphHelper.generateSuccess('Group has been updated.')
  174. }
  175. }
  176. },
  177. Group: {
  178. users (grp) {
  179. return grp.$relatedQuery('users')
  180. }
  181. }
  182. }