users.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. const loggerFactory = require('@alias/logger');
  2. const logger = loggerFactory('growi:routes:apiv3:user-group');
  3. const express = require('express');
  4. const router = express.Router();
  5. const { body } = require('express-validator/check');
  6. const { isEmail } = require('validator');
  7. const validator = {};
  8. /**
  9. * @swagger
  10. * tags:
  11. * name: Users
  12. */
  13. module.exports = (crowi) => {
  14. const loginRequiredStrictly = require('../../middleware/login-required')(crowi);
  15. const adminRequired = require('../../middleware/admin-required')(crowi);
  16. const csrf = require('../../middleware/csrf')(crowi);
  17. const {
  18. ErrorV3,
  19. User,
  20. Page,
  21. ExternalAccount,
  22. } = crowi.models;
  23. const { ApiV3FormValidator } = crowi.middlewares;
  24. /**
  25. * @swagger
  26. *
  27. * paths:
  28. * /_api/v3/users:
  29. * get:
  30. * tags: [Users]
  31. * description: Get users
  32. * responses:
  33. * 200:
  34. * description: users are fetched
  35. * content:
  36. * application/json:
  37. * schema:
  38. * properties:
  39. * users:
  40. * type: object
  41. * description: a result of `Users.find`
  42. */
  43. router.get('/', loginRequiredStrictly, adminRequired, async(req, res) => {
  44. try {
  45. const page = parseInt(req.query.page) || 1;
  46. const result = await User.findUsersWithPagination({ page });
  47. const { docs: users, total: totalUsers, limit: pagingLimit } = result;
  48. return res.apiv3({ users, totalUsers, pagingLimit });
  49. }
  50. catch (err) {
  51. const msg = 'Error occurred in fetching user group list';
  52. logger.error('Error', err);
  53. return res.apiv3Err(new ErrorV3(msg, 'user-group-list-fetch-failed'));
  54. }
  55. });
  56. validator.inviteEmail = [
  57. // isEmail prevents line breaks, so use isString
  58. body('shapedEmailList').custom((value) => {
  59. const array = value.filter((value) => { return isEmail(value) });
  60. if (array.length === 0) {
  61. throw new Error('At least one valid email address is required');
  62. }
  63. return array;
  64. }),
  65. ];
  66. /**
  67. * @swagger
  68. *
  69. * paths:
  70. * /_api/v3/users/invite:
  71. * post:
  72. * tags: [Users]
  73. * description: Create new users and send Emails
  74. * parameters:
  75. * - name: shapedEmailList
  76. * in: query
  77. * description: Invitation emailList
  78. * schema:
  79. * type: object
  80. * - name: sendEmail
  81. * in: query
  82. * description: Whether to send mail
  83. * schema:
  84. * type: boolean
  85. * responses:
  86. * 200:
  87. * description: Inviting user success
  88. * content:
  89. * application/json:
  90. * schema:
  91. * properties:
  92. * createdUserList:
  93. * type: object
  94. * description: Users successfully created
  95. * existingEmailList:
  96. * type: object
  97. * description: Users email that already exists
  98. */
  99. router.post('/invite', loginRequiredStrictly, adminRequired, csrf, validator.inviteEmail, ApiV3FormValidator, async(req, res) => {
  100. try {
  101. const emailList = await User.createUsersByInvitation(req.body.shapedEmailList, req.body.sendEmail);
  102. return res.apiv3({ emailList });
  103. }
  104. catch (err) {
  105. logger.error('Error', err);
  106. return res.apiv3Err(new ErrorV3(err));
  107. }
  108. });
  109. /**
  110. * @swagger
  111. *
  112. * paths:
  113. * /_api/v3/users/{id}/activate:
  114. * put:
  115. * tags: [Users]
  116. * description: Activate user
  117. * parameters:
  118. * - name: id
  119. * in: path
  120. * required: true
  121. * description: id of activate user
  122. * schema:
  123. * type: string
  124. * responses:
  125. * 200:
  126. * description: Activationg user success
  127. * content:
  128. * application/json:
  129. * schema:
  130. * properties:
  131. * userData:
  132. * type: object
  133. * description: data of activate user
  134. */
  135. router.put('/:id/activate', loginRequiredStrictly, adminRequired, csrf, async(req, res) => {
  136. // check user upper limit
  137. const isUserCountExceedsUpperLimit = await User.isUserCountExceedsUpperLimit();
  138. if (isUserCountExceedsUpperLimit) {
  139. const msg = 'Unable to activate because user has reached limit';
  140. logger.error('Error', msg);
  141. return res.apiv3Err(new ErrorV3(msg));
  142. }
  143. const { id } = req.params;
  144. try {
  145. const userData = await User.findById(id);
  146. await userData.statusActivate();
  147. return res.apiv3({ userData });
  148. }
  149. catch (err) {
  150. logger.error('Error', err);
  151. return res.apiv3Err(new ErrorV3(err));
  152. }
  153. });
  154. /**
  155. * @swagger
  156. *
  157. * paths:
  158. * /_api/v3/users/{id}/deactivate:
  159. * put:
  160. * tags: [Users]
  161. * description: Deactivate user
  162. * parameters:
  163. * - name: id
  164. * in: path
  165. * required: true
  166. * description: id of deactivate user
  167. * schema:
  168. * type: string
  169. * responses:
  170. * 200:
  171. * description: Deactivationg user success
  172. * content:
  173. * application/json:
  174. * schema:
  175. * properties:
  176. * userData:
  177. * type: object
  178. * description: data of deactivate user
  179. */
  180. router.put('/:id/deactivate', loginRequiredStrictly, adminRequired, csrf, async(req, res) => {
  181. const { id } = req.params;
  182. try {
  183. const userData = await User.findById(id);
  184. await userData.statusSuspend();
  185. return res.apiv3({ userData });
  186. }
  187. catch (err) {
  188. logger.error('Error', err);
  189. return res.apiv3Err(new ErrorV3(err));
  190. }
  191. });
  192. /**
  193. * @swagger
  194. *
  195. * paths:
  196. * /_api/v3/users/{id}/remove:
  197. * delete:
  198. * tags: [Users]
  199. * description: Delete user
  200. * parameters:
  201. * - name: id
  202. * in: path
  203. * required: true
  204. * description: id of delete user
  205. * schema:
  206. * type: string
  207. * responses:
  208. * 200:
  209. * description: Deleting user success
  210. * content:
  211. * application/json:
  212. * schema:
  213. * properties:
  214. * userData:
  215. * type: object
  216. * description: data of delete user
  217. */
  218. router.delete('/:id/remove', loginRequiredStrictly, adminRequired, csrf, async(req, res) => {
  219. const { id } = req.params;
  220. try {
  221. const userData = await User.findById(id);
  222. await userData.statusDelete();
  223. await ExternalAccount.remove({ user: userData });
  224. await Page.removeByPath(`/user/${userData.username}`);
  225. return res.apiv3({ userData });
  226. }
  227. catch (err) {
  228. logger.error('Error', err);
  229. return res.apiv3Err(new ErrorV3(err));
  230. }
  231. });
  232. return router;
  233. };