2
0

attachments.js 2.6 KB

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