notification-setting.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. const loggerFactory = require('@alias/logger');
  2. // eslint-disable-next-line no-unused-vars
  3. const logger = loggerFactory('growi:routes:apiv3:notification-setting');
  4. const express = require('express');
  5. const router = express.Router();
  6. const { body } = require('express-validator/check');
  7. const ErrorV3 = require('../../models/vo/error-apiv3');
  8. const validator = {
  9. slackConfiguration: [
  10. body('webhookUrl').isString().trim(),
  11. body('isIncomingWebhookPrioritized').isBoolean(),
  12. body('slackToken').isString().trim(),
  13. ],
  14. userNotification: [
  15. body('pathPattern').isString().trim(),
  16. body('channel').isString().trim(),
  17. ],
  18. };
  19. /**
  20. * @swagger
  21. * tags:
  22. * name: NotificationSetting
  23. */
  24. /**
  25. * @swagger
  26. *
  27. * components:
  28. * schemas:
  29. * SlackConfigurationParams:
  30. * type: object
  31. * properties:
  32. * webhookUrl:
  33. * type: string
  34. * description: incoming webhooks url
  35. * isIncomingWebhookPrioritized:
  36. * type: boolean
  37. * description: use incoming webhooks even if Slack App settings are enabled
  38. * slackToken:
  39. * type: string
  40. * description: OAuth access token
  41. * UserNotificationParams:
  42. * type: object
  43. * properties:
  44. * pathPattern:
  45. * type: string
  46. * description: path name of wiki
  47. * channel:
  48. * type: string
  49. * description: slack channel name without '#'
  50. */
  51. module.exports = (crowi) => {
  52. const loginRequiredStrictly = require('../../middleware/login-required')(crowi);
  53. const adminRequired = require('../../middleware/admin-required')(crowi);
  54. const csrf = require('../../middleware/csrf')(crowi);
  55. const UpdatePost = crowi.model('UpdatePost');
  56. const GlobalNotificationSetting = crowi.model('GlobalNotificationSetting');
  57. const { ApiV3FormValidator } = crowi.middlewares;
  58. /**
  59. * @swagger
  60. *
  61. * /_api/v3/notification-setting/:
  62. * get:
  63. * tags: [NotificationSetting]
  64. * description: Get notification paramators
  65. * responses:
  66. * 200:
  67. * description: params of notification
  68. * content:
  69. * application/json:
  70. * schema:
  71. * properties:
  72. * notificationParams:
  73. * type: object
  74. * description: notification params
  75. */
  76. router.get('/', loginRequiredStrictly, adminRequired, async(req, res) => {
  77. const notificationParams = {
  78. webhookUrl: await crowi.configManager.getConfig('notification', 'slack:incomingWebhookUrl'),
  79. isIncomingWebhookPrioritized: await crowi.configManager.getConfig('notification', 'slack:isIncomingWebhookPrioritized'),
  80. slackToken: await crowi.configManager.getConfig('notification', 'slack:token'),
  81. userNotifications: await UpdatePost.findAll(),
  82. globalNotifications: await GlobalNotificationSetting.findAll(),
  83. };
  84. return res.apiv3({ notificationParams });
  85. });
  86. /**
  87. * @swagger
  88. *
  89. * /_api/v3/notification-setting/slack-configuration:
  90. * put:
  91. * tags: [NotificationSetting]
  92. * description: Update slack configuration setting
  93. * requestBody:
  94. * required: true
  95. * content:
  96. * application/json:
  97. * schema:
  98. * $ref: '#/components/schemas/SlackConfigurationParams'
  99. * responses:
  100. * 200:
  101. * description: Succeeded to update slack configuration setting
  102. * content:
  103. * application/json:
  104. * schema:
  105. * $ref: '#/components/schemas/SlackConfigurationParams'
  106. */
  107. router.put('/slack-configuration', loginRequiredStrictly, adminRequired, csrf, validator.slackConfiguration, ApiV3FormValidator, async(req, res) => {
  108. const requestParams = {
  109. 'slack:incomingWebhookUrl': req.body.webhookUrl,
  110. 'slack:isIncomingWebhookPrioritized': req.body.isIncomingWebhookPrioritized,
  111. 'slack:token': req.body.slackToken,
  112. };
  113. try {
  114. await crowi.configManager.updateConfigsInTheSameNamespace('notification', requestParams);
  115. const responseParams = {
  116. webhookUrl: await crowi.configManager.getConfig('notification', 'slack:incomingWebhookUrl'),
  117. isIncomingWebhookPrioritized: await crowi.configManager.getConfig('notification', 'slack:isIncomingWebhookPrioritized'),
  118. slackToken: await crowi.configManager.getConfig('notification', 'slack:token'),
  119. };
  120. await crowi.setupSlack();
  121. return res.apiv3({ responseParams });
  122. }
  123. catch (err) {
  124. const msg = 'Error occurred in updating slack configuration';
  125. logger.error('Error', err);
  126. return res.apiv3Err(new ErrorV3(msg, 'update-slackConfiguration-failed'));
  127. }
  128. });
  129. /**
  130. * @swagger
  131. *
  132. * /_api/v3/notification-setting/user-notification:
  133. * post:
  134. * tags: [NotificationSetting]
  135. * description: add user notification setting
  136. * requestBody:
  137. * required: true
  138. * content:
  139. * application/json:
  140. * schema:
  141. * $ref: '#/components/schemas/UserNotificationParams'
  142. * responses:
  143. * 200:
  144. * description: Succeeded to add user notification setting
  145. * content:
  146. * application/json:
  147. * schema:
  148. * properties:
  149. * createdUser:
  150. * type: object
  151. * description: user who set notification
  152. * userNotifications:
  153. * type: object
  154. * description: user trigger notifications for updated
  155. */
  156. router.post('/user-notification', loginRequiredStrictly, adminRequired, csrf, validator.userNotification, ApiV3FormValidator, async(req, res) => {
  157. const { pathPattern, channel } = req.body;
  158. const UpdatePost = crowi.model('UpdatePost');
  159. try {
  160. logger.info('notification.add', pathPattern, channel);
  161. const responseParams = {
  162. createdUser: await UpdatePost.create(pathPattern, channel, req.user),
  163. userNotifications: await UpdatePost.findAll(),
  164. };
  165. return res.apiv3({ responseParams });
  166. }
  167. catch (err) {
  168. const msg = 'Error occurred in updating user notification';
  169. logger.error('Error', err);
  170. return res.apiv3Err(new ErrorV3(msg, 'update-userNotification-failed'));
  171. }
  172. });
  173. /**
  174. * @swagger
  175. *
  176. * /_api/v3/notification-setting/global-notification/{id}/enabled:
  177. * put:
  178. * tags: [NotificationSetting]
  179. * description: toggle enabled global notification
  180. * parameters:
  181. * - name: id
  182. * in: path
  183. * required: true
  184. * description: notification id for updated
  185. * schema:
  186. * type: string
  187. * requestBody:
  188. * required: true
  189. * content:
  190. * application/json:
  191. * schema:
  192. * properties:
  193. * isEnabled:
  194. * type: boolean
  195. * description: is notification enabled
  196. * responses:
  197. * 200:
  198. * description: Succeeded to delete global notification pattern
  199. * content:
  200. * application/json:
  201. * schema:
  202. * properties:
  203. * deletedNotificaton:
  204. * type: object
  205. * description: notification id for updated
  206. */
  207. router.put('/global-notification/:id/enabled', loginRequiredStrictly, adminRequired, csrf, async(req, res) => {
  208. const { id } = req.params;
  209. const { isEnabled } = req.body;
  210. try {
  211. if (isEnabled) {
  212. await GlobalNotificationSetting.enable(id);
  213. }
  214. else {
  215. await GlobalNotificationSetting.disable(id);
  216. }
  217. return res.apiv3({ id });
  218. }
  219. catch (err) {
  220. const msg = 'Error occurred in toggle of global notification';
  221. logger.error('Error', err);
  222. return res.apiv3Err(new ErrorV3(msg, 'toggle-globalNotification-failed'));
  223. }
  224. });
  225. /**
  226. * @swagger
  227. *
  228. * /_api/v3/notification-setting/global-notification/{id}:
  229. * delete:
  230. * tags: [NotificationSetting]
  231. * description: delete global notification pattern
  232. * parameters:
  233. * - name: id
  234. * in: path
  235. * required: true
  236. * description: id of global notification
  237. * schema:
  238. * type: string
  239. * responses:
  240. * 200:
  241. * description: Succeeded to delete global notification pattern
  242. * content:
  243. * application/json:
  244. * schema:
  245. * properties:
  246. * deletedNotificaton:
  247. * type: object
  248. * description: deleted notification
  249. */
  250. router.delete('/global-notification/:id', loginRequiredStrictly, adminRequired, csrf, async(req, res) => {
  251. const { id } = req.params;
  252. try {
  253. const deletedNotificaton = await GlobalNotificationSetting.findOneAndRemove({ _id: id });
  254. return res.apiv3(deletedNotificaton);
  255. }
  256. catch (err) {
  257. const msg = 'Error occurred in delete global notification';
  258. logger.error('Error', err);
  259. return res.apiv3Err(new ErrorV3(msg, 'delete-globalNotification-failed'));
  260. }
  261. });
  262. return router;
  263. };