group.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. const graphHelper = require('../../helpers/graph')
  2. const safeRegex = require('safe-regex')
  3. const _ = require('lodash')
  4. const { v4: uuid } = require('uuid')
  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 Error('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 Error('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 Error('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 Error('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 Error('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. operation: 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. rules: JSON.stringify(WIKI.data.groups.defaultRules.map(r => ({
  78. id: uuid(),
  79. ...r
  80. }))),
  81. isSystem: false
  82. })
  83. await WIKI.auth.reloadGroups()
  84. WIKI.events.outbound.emit('reloadGroups')
  85. return {
  86. operation: graphHelper.generateSuccess('Group created successfully.'),
  87. group
  88. }
  89. },
  90. /**
  91. * DELETE GROUP
  92. */
  93. async deleteGroup (obj, args) {
  94. if (args.id === 1 || args.id === 2) {
  95. throw new Error('Cannot delete this group.')
  96. }
  97. await WIKI.models.groups.query().deleteById(args.id)
  98. WIKI.auth.revokeUserTokens({ id: args.id, kind: 'g' })
  99. WIKI.events.outbound.emit('addAuthRevoke', { id: args.id, kind: 'g' })
  100. await WIKI.auth.reloadGroups()
  101. WIKI.events.outbound.emit('reloadGroups')
  102. return {
  103. operation: graphHelper.generateSuccess('Group has been deleted.')
  104. }
  105. },
  106. /**
  107. * UNASSIGN USER FROM GROUP
  108. */
  109. async unassignUserFromGroup (obj, args) {
  110. if (args.userId === 2) {
  111. throw new Error('Cannot unassign Guest user')
  112. }
  113. if (args.userId === 1 && args.groupId === 1) {
  114. throw new Error('Cannot unassign Administrator user from Administrators group.')
  115. }
  116. const grp = await WIKI.models.groups.query().findById(args.groupId)
  117. if (!grp) {
  118. throw new Error('Invalid Group ID')
  119. }
  120. const usr = await WIKI.models.users.query().findById(args.userId)
  121. if (!usr) {
  122. throw new Error('Invalid User ID')
  123. }
  124. await grp.$relatedQuery('users').unrelate().where('userId', usr.id)
  125. WIKI.auth.revokeUserTokens({ id: usr.id, kind: 'u' })
  126. WIKI.events.outbound.emit('addAuthRevoke', { id: usr.id, kind: 'u' })
  127. return {
  128. operation: graphHelper.generateSuccess('User has been unassigned from group.')
  129. }
  130. },
  131. /**
  132. * UPDATE GROUP
  133. */
  134. async updateGroup (obj, args, { req }) {
  135. // Check for unsafe regex page rules
  136. if (_.some(args.pageRules, pr => {
  137. return pr.match === 'REGEX' && !safeRegex(pr.path)
  138. })) {
  139. throw new Error('Some Page Rules contains unsafe or exponential time regex.')
  140. }
  141. // Set default redirect on login value
  142. if (_.isEmpty(args.redirectOnLogin)) {
  143. args.redirectOnLogin = '/'
  144. }
  145. // Check assigned permissions for write:groups
  146. if (
  147. WIKI.auth.checkExclusiveAccess(req.user, ['write:groups'], ['manage:groups', 'manage:system']) &&
  148. args.permissions.some(p => {
  149. const resType = _.last(p.split(':'))
  150. return ['users', 'groups', 'navigation', 'theme', 'api', 'system'].includes(resType)
  151. })
  152. ) {
  153. throw new Error('You are not authorized to manage this group or assign these permissions.')
  154. }
  155. // Check assigned permissions for manage:groups
  156. if (
  157. WIKI.auth.checkExclusiveAccess(req.user, ['manage:groups'], ['manage:system']) &&
  158. args.permissions.some(p => _.last(p.split(':')) === 'system')
  159. ) {
  160. throw new Error('You are not authorized to manage this group or assign the manage:system permissions.')
  161. }
  162. // Update group
  163. await WIKI.models.groups.query().patch({
  164. name: args.name,
  165. redirectOnLogin: args.redirectOnLogin,
  166. permissions: JSON.stringify(args.permissions),
  167. pageRules: JSON.stringify(args.pageRules)
  168. }).where('id', args.id)
  169. // Revoke tokens for this group
  170. WIKI.auth.revokeUserTokens({ id: args.id, kind: 'g' })
  171. WIKI.events.outbound.emit('addAuthRevoke', { id: args.id, kind: 'g' })
  172. // Reload group permissions
  173. await WIKI.auth.reloadGroups()
  174. WIKI.events.outbound.emit('reloadGroups')
  175. return {
  176. operation: graphHelper.generateSuccess('Group has been updated.')
  177. }
  178. }
  179. },
  180. Group: {
  181. users (grp) {
  182. return grp.$relatedQuery('users')
  183. }
  184. }
  185. }