attachments.js 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import { Meteor } from 'meteor/meteor';
  2. import { FilesCollection } from 'meteor/ostrio:files';
  3. import { createBucket } from './lib/grid/createBucket';
  4. import { createOnAfterUpload } from './lib/fsHooks/createOnAfterUpload';
  5. import { createInterceptDownload } from './lib/fsHooks/createInterceptDownload';
  6. import { createOnAfterRemove } from './lib/fsHooks/createOnAfterRemove';
  7. let attachmentBucket;
  8. if (Meteor.isServer) {
  9. attachmentBucket = createBucket('attachments');
  10. }
  11. const insertActivity = (fileObj, activityType) =>
  12. Activities.insert({
  13. userId: fileObj.userId,
  14. type: 'card',
  15. activityType,
  16. attachmentId: fileObj._id,
  17. // this preserves the name so that notifications can be meaningful after
  18. // this file is removed
  19. attachmentName: fileObj.name,
  20. boardId: fileObj.meta.boardId,
  21. cardId: fileObj.meta.cardId,
  22. listId: fileObj.meta.listId,
  23. swimlaneId: fileObj.meta.swimlaneId,
  24. });
  25. // XXX Enforce a schema for the Attachments FilesCollection
  26. // see: https://github.com/VeliovGroup/Meteor-Files/wiki/Schema
  27. Attachments = new FilesCollection({
  28. debug: false, // Change to `true` for debugging
  29. collectionName: 'attachments',
  30. allowClientCode: true,
  31. onAfterUpload: function onAfterUpload(fileRef) {
  32. createOnAfterUpload(attachmentBucket).call(this, fileRef);
  33. // If the attachment doesn't have a source field
  34. // or its source is different than import
  35. if (!fileRef.meta.source || fileRef.meta.source !== 'import') {
  36. // Add activity about adding the attachment
  37. insertActivity(fileRef, 'addAttachment');
  38. }
  39. },
  40. interceptDownload: createInterceptDownload(attachmentBucket),
  41. onAfterRemove: function onAfterRemove(files) {
  42. createOnAfterRemove(attachmentBucket).call(this, files);
  43. files.forEach(fileObj => {
  44. insertActivity(fileObj, 'deleteAttachment');
  45. });
  46. },
  47. // We authorize the attachment download either:
  48. // - if the board is public, everyone (even unconnected) can download it
  49. // - if the board is private, only board members can download it
  50. protected(fileObj) {
  51. const board = Boards.findOne(fileObj.meta.boardId);
  52. if (board.isPublic()) {
  53. return true;
  54. }
  55. return board.hasMember(this.userId);
  56. },
  57. });
  58. if (Meteor.isServer) {
  59. Attachments.allow({
  60. insert(userId, fileObj) {
  61. return allowIsBoardMember(userId, Boards.findOne(fileObj.boardId));
  62. },
  63. update(userId, fileObj) {
  64. return allowIsBoardMember(userId, Boards.findOne(fileObj.boardId));
  65. },
  66. remove(userId, fileObj) {
  67. return allowIsBoardMember(userId, Boards.findOne(fileObj.boardId));
  68. },
  69. fetch: ['meta'],
  70. });
  71. Meteor.startup(() => {
  72. Attachments.collection._ensureIndex({ cardId: 1 });
  73. });
  74. }
  75. export default Attachments;