integrations.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. Integrations = new Mongo.Collection('integrations');
  2. /**
  3. * Integration with third-party applications
  4. */
  5. Integrations.attachSchema(new SimpleSchema({
  6. enabled: {
  7. /**
  8. * is the integration enabled?
  9. */
  10. type: Boolean,
  11. defaultValue: true,
  12. },
  13. title: {
  14. /**
  15. * name of the integration
  16. */
  17. type: String,
  18. optional: true,
  19. },
  20. type: {
  21. /**
  22. * type of the integratation (Default to 'outgoing-webhooks')
  23. */
  24. type: String,
  25. defaultValue: 'outgoing-webhooks',
  26. },
  27. activities: {
  28. /**
  29. * activities the integration gets triggered (list)
  30. */
  31. type: [String],
  32. defaultValue: ['all'],
  33. },
  34. url: { // URL validation regex (https://mathiasbynens.be/demo/url-regex)
  35. /**
  36. * URL validation regex (https://mathiasbynens.be/demo/url-regex)
  37. */
  38. type: String,
  39. },
  40. token: {
  41. /**
  42. * token of the integration
  43. */
  44. type: String,
  45. optional: true,
  46. },
  47. boardId: {
  48. /**
  49. * Board ID of the integration
  50. */
  51. type: String,
  52. },
  53. createdAt: {
  54. /**
  55. * Creation date of the integration
  56. */
  57. type: Date,
  58. denyUpdate: false,
  59. autoValue() { // eslint-disable-line consistent-return
  60. if (this.isInsert) {
  61. return new Date();
  62. } else {
  63. this.unset();
  64. }
  65. },
  66. },
  67. userId: {
  68. /**
  69. * user ID who created the interation
  70. */
  71. type: String,
  72. },
  73. }));
  74. Integrations.allow({
  75. insert(userId, doc) {
  76. return allowIsBoardAdmin(userId, Boards.findOne(doc.boardId));
  77. },
  78. update(userId, doc) {
  79. return allowIsBoardAdmin(userId, Boards.findOne(doc.boardId));
  80. },
  81. remove(userId, doc) {
  82. return allowIsBoardAdmin(userId, Boards.findOne(doc.boardId));
  83. },
  84. fetch: ['boardId'],
  85. });
  86. //INTEGRATIONS REST API
  87. if (Meteor.isServer) {
  88. /**
  89. * @operation get_all_integrations
  90. * @summary Get all integrations in board
  91. *
  92. * @param {string} boardId the board ID
  93. * @return_type [Integrations]
  94. */
  95. JsonRoutes.add('GET', '/api/boards/:boardId/integrations', function(req, res) {
  96. try {
  97. const paramBoardId = req.params.boardId;
  98. Authentication.checkBoardAccess(req.userId, paramBoardId);
  99. const data = Integrations.find({ boardId: paramBoardId }, { fields: { token: 0 } }).map(function(doc) {
  100. return doc;
  101. });
  102. JsonRoutes.sendResult(res, {code: 200, data});
  103. }
  104. catch (error) {
  105. JsonRoutes.sendResult(res, {
  106. code: 200,
  107. data: error,
  108. });
  109. }
  110. });
  111. /**
  112. * @operation get_integration
  113. * @summary Get a single integration in board
  114. *
  115. * @param {string} boardId the board ID
  116. * @param {string} intId the integration ID
  117. * @return_type Integrations
  118. */
  119. JsonRoutes.add('GET', '/api/boards/:boardId/integrations/:intId', function(req, res) {
  120. try {
  121. const paramBoardId = req.params.boardId;
  122. const paramIntId = req.params.intId;
  123. Authentication.checkBoardAccess(req.userId, paramBoardId);
  124. JsonRoutes.sendResult(res, {
  125. code: 200,
  126. data: Integrations.findOne({ _id: paramIntId, boardId: paramBoardId }, { fields: { token: 0 } }),
  127. });
  128. }
  129. catch (error) {
  130. JsonRoutes.sendResult(res, {
  131. code: 200,
  132. data: error,
  133. });
  134. }
  135. });
  136. /**
  137. * @operation new_integration
  138. * @summary Create a new integration
  139. *
  140. * @param {string} boardId the board ID
  141. * @param {string} url the URL of the integration
  142. * @return_type {_id: string}
  143. */
  144. JsonRoutes.add('POST', '/api/boards/:boardId/integrations', function(req, res) {
  145. try {
  146. const paramBoardId = req.params.boardId;
  147. Authentication.checkBoardAccess(req.userId, paramBoardId);
  148. const id = Integrations.insert({
  149. userId: req.userId,
  150. boardId: paramBoardId,
  151. url: req.body.url,
  152. });
  153. JsonRoutes.sendResult(res, {
  154. code: 200,
  155. data: {
  156. _id: id,
  157. },
  158. });
  159. }
  160. catch (error) {
  161. JsonRoutes.sendResult(res, {
  162. code: 200,
  163. data: error,
  164. });
  165. }
  166. });
  167. /**
  168. * @operation edit_integration
  169. * @summary Edit integration data
  170. *
  171. * @param {string} boardId the board ID
  172. * @param {string} intId the integration ID
  173. * @param {string} [enabled] is the integration enabled?
  174. * @param {string} [title] new name of the integration
  175. * @param {string} [url] new URL of the integration
  176. * @param {string} [token] new token of the integration
  177. * @param {string} [activities] new list of activities of the integration
  178. * @return_type {_id: string}
  179. */
  180. JsonRoutes.add('PUT', '/api/boards/:boardId/integrations/:intId', function (req, res) {
  181. try {
  182. const paramBoardId = req.params.boardId;
  183. const paramIntId = req.params.intId;
  184. Authentication.checkBoardAccess(req.userId, paramBoardId);
  185. if (req.body.hasOwnProperty('enabled')) {
  186. const newEnabled = req.body.enabled;
  187. Integrations.direct.update({_id: paramIntId, boardId: paramBoardId},
  188. {$set: {enabled: newEnabled}});
  189. }
  190. if (req.body.hasOwnProperty('title')) {
  191. const newTitle = req.body.title;
  192. Integrations.direct.update({_id: paramIntId, boardId: paramBoardId},
  193. {$set: {title: newTitle}});
  194. }
  195. if (req.body.hasOwnProperty('url')) {
  196. const newUrl = req.body.url;
  197. Integrations.direct.update({_id: paramIntId, boardId: paramBoardId},
  198. {$set: {url: newUrl}});
  199. }
  200. if (req.body.hasOwnProperty('token')) {
  201. const newToken = req.body.token;
  202. Integrations.direct.update({_id: paramIntId, boardId: paramBoardId},
  203. {$set: {token: newToken}});
  204. }
  205. if (req.body.hasOwnProperty('activities')) {
  206. const newActivities = req.body.activities;
  207. Integrations.direct.update({_id: paramIntId, boardId: paramBoardId},
  208. {$set: {activities: newActivities}});
  209. }
  210. JsonRoutes.sendResult(res, {
  211. code: 200,
  212. data: {
  213. _id: paramIntId,
  214. },
  215. });
  216. }
  217. catch (error) {
  218. JsonRoutes.sendResult(res, {
  219. code: 200,
  220. data: error,
  221. });
  222. }
  223. });
  224. /**
  225. * @operation delete_integration_activities
  226. * @summary Delete subscribed activities
  227. *
  228. * @param {string} boardId the board ID
  229. * @param {string} intId the integration ID
  230. * @param {string} newActivities the activities to remove from the integration
  231. * @return_type Integrations
  232. */
  233. JsonRoutes.add('DELETE', '/api/boards/:boardId/integrations/:intId/activities', function (req, res) {
  234. try {
  235. const paramBoardId = req.params.boardId;
  236. const paramIntId = req.params.intId;
  237. const newActivities = req.body.activities;
  238. Authentication.checkBoardAccess(req.userId, paramBoardId);
  239. Integrations.direct.update({_id: paramIntId, boardId: paramBoardId},
  240. {$pullAll: {activities: newActivities}});
  241. JsonRoutes.sendResult(res, {
  242. code: 200,
  243. data: Integrations.findOne({_id: paramIntId, boardId: paramBoardId}, { fields: {_id: 1, activities: 1}}),
  244. });
  245. }
  246. catch (error) {
  247. JsonRoutes.sendResult(res, {
  248. code: 200,
  249. data: error,
  250. });
  251. }
  252. });
  253. /**
  254. * @operation new_integration_activities
  255. * @summary Add subscribed activities
  256. *
  257. * @param {string} boardId the board ID
  258. * @param {string} intId the integration ID
  259. * @param {string} newActivities the activities to add to the integration
  260. * @return_type Integrations
  261. */
  262. JsonRoutes.add('POST', '/api/boards/:boardId/integrations/:intId/activities', function (req, res) {
  263. try {
  264. const paramBoardId = req.params.boardId;
  265. const paramIntId = req.params.intId;
  266. const newActivities = req.body.activities;
  267. Authentication.checkBoardAccess(req.userId, paramBoardId);
  268. Integrations.direct.update({_id: paramIntId, boardId: paramBoardId},
  269. {$addToSet: {activities: { $each: newActivities}}});
  270. JsonRoutes.sendResult(res, {
  271. code: 200,
  272. data: Integrations.findOne({_id: paramIntId, boardId: paramBoardId}, { fields: {_id: 1, activities: 1}}),
  273. });
  274. }
  275. catch (error) {
  276. JsonRoutes.sendResult(res, {
  277. code: 200,
  278. data: error,
  279. });
  280. }
  281. });
  282. /**
  283. * @operation delete_integration
  284. * @summary Delete integration
  285. *
  286. * @param {string} boardId the board ID
  287. * @param {string} intId the integration ID
  288. * @return_type {_id: string}
  289. */
  290. JsonRoutes.add('DELETE', '/api/boards/:boardId/integrations/:intId', function (req, res) {
  291. try {
  292. const paramBoardId = req.params.boardId;
  293. const paramIntId = req.params.intId;
  294. Authentication.checkBoardAccess(req.userId, paramBoardId);
  295. Integrations.direct.remove({_id: paramIntId, boardId: paramBoardId});
  296. JsonRoutes.sendResult(res, {
  297. code: 200,
  298. data: {
  299. _id: paramIntId,
  300. },
  301. });
  302. }
  303. catch (error) {
  304. JsonRoutes.sendResult(res, {
  305. code: 200,
  306. data: error,
  307. });
  308. }
  309. });
  310. }