attachments.js 2.7 KB

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