AttachmentViewer.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. 'use strict';
  2. const common = require('../common');
  3. describe('AttachmentViewer', function () {
  4. describe('setAttachment, showAttachment, removeAttachment, hideAttachment, hideAttachmentPreview, hasAttachment, getAttachment & moveAttachmentTo', function () {
  5. this.timeout(30000);
  6. jsc.property(
  7. 'displays & hides data as requested',
  8. common.jscMimeTypes(),
  9. 'string',
  10. 'string',
  11. 'string',
  12. 'string',
  13. function (mimeType, rawdata, filename, prefix, postfix) {
  14. let clean = jsdom(),
  15. data = 'data:' + mimeType + ';base64,' + common.btoa(rawdata),
  16. mimePrefix = mimeType.substring(0, 6),
  17. previewSupported = (
  18. mimePrefix === 'image/' ||
  19. mimePrefix === 'audio/' ||
  20. mimePrefix === 'video/' ||
  21. mimeType.match(/\/pdf/i)
  22. ),
  23. results = [],
  24. result = '';
  25. // text node of attachment will truncate at null byte
  26. if (filename === '\u0000') {
  27. filename = '';
  28. }
  29. prefix = prefix.replace(/%(s|d)/g, '%%');
  30. postfix = postfix.replace(/%(s|d)/g, '%%').replace(/<|>/g, '');
  31. $('body').html(
  32. '<div id="attachmentPreview" class="col-md-12 text-center hidden"></div>' +
  33. '<div id="attachment" class="hidden"></div>' +
  34. '<div id="templates">' +
  35. '<div id="attachmenttemplate" role="alert" class="attachment hidden alert alert-info">' +
  36. '<span class="glyphicon glyphicon-download-alt" aria-hidden="true"></span>' +
  37. '<a class="alert-link">Download attachment</a>' +
  38. '</div>' +
  39. '</div>'
  40. );
  41. // mock createObjectURL for jsDOM
  42. if (typeof window.URL.createObjectURL === 'undefined') {
  43. Object.defineProperty(
  44. window.URL,
  45. 'createObjectURL',
  46. {value: function(blob) {
  47. return 'blob:' + location.origin + '/1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed';
  48. }}
  49. )
  50. }
  51. $.PrivateBin.AttachmentViewer.init();
  52. $.PrivateBin.Model.init();
  53. results.push(
  54. !$.PrivateBin.AttachmentViewer.hasAttachment() &&
  55. $('#attachment').hasClass('hidden') &&
  56. $('#attachment').children().length === 0 &&
  57. $('#attachmenttemplate').hasClass('hidden') &&
  58. $('#attachmentPreview').hasClass('hidden')
  59. );
  60. global.atob = common.atob;
  61. if (filename.length) {
  62. $.PrivateBin.AttachmentViewer.setAttachment(data, filename);
  63. } else {
  64. $.PrivateBin.AttachmentViewer.setAttachment(data);
  65. }
  66. // // beyond this point we will get the blob URL instead of the data
  67. data = window.URL.createObjectURL(data);
  68. const attachment = $.PrivateBin.AttachmentViewer.getAttachments();
  69. results.push(
  70. $.PrivateBin.AttachmentViewer.hasAttachment() &&
  71. $('#attachment').hasClass('hidden') &&
  72. $('#attachment').children().length > 0 &&
  73. $('#attachmentPreview').hasClass('hidden') &&
  74. attachment[0][0] === data &&
  75. attachment[0][1] === filename
  76. );
  77. $.PrivateBin.AttachmentViewer.showAttachment();
  78. results.push(
  79. !$('#attachment').hasClass('hidden') &&
  80. $('#attachment').children().length > 0 &&
  81. (previewSupported ? !$('#attachmentPreview').hasClass('hidden') : $('#attachmentPreview').hasClass('hidden'))
  82. );
  83. $.PrivateBin.AttachmentViewer.hideAttachment();
  84. results.push(
  85. $('#attachment').hasClass('hidden') &&
  86. (previewSupported ? !$('#attachmentPreview').hasClass('hidden') : $('#attachmentPreview').hasClass('hidden'))
  87. );
  88. if (previewSupported) {
  89. $.PrivateBin.AttachmentViewer.hideAttachmentPreview();
  90. results.push($('#attachmentPreview').hasClass('hidden'));
  91. }
  92. $.PrivateBin.AttachmentViewer.showAttachment();
  93. results.push(
  94. !$('#attachment').hasClass('hidden') &&
  95. (previewSupported ? !$('#attachmentPreview').hasClass('hidden') : $('#attachmentPreview').hasClass('hidden'))
  96. );
  97. let element = $('<div>');
  98. $.PrivateBin.AttachmentViewer.moveAttachmentTo(element, attachment[0], prefix + '%s' + postfix);
  99. // messageIDs with links get a relaxed treatment
  100. if (prefix.indexOf('<a') === -1 && postfix.indexOf('<a') === -1) {
  101. result = $('<textarea>').text((prefix + filename + postfix)).text();
  102. } else {
  103. result = DOMPurify.sanitize(
  104. prefix + $.PrivateBin.Helper.htmlEntities(filename) + postfix, {
  105. ALLOWED_TAGS: ['a', 'i', 'span'],
  106. ALLOWED_ATTR: ['href', 'id']
  107. }
  108. );
  109. }
  110. if (filename.length) {
  111. results.push(
  112. element.find('a')[0].href === data &&
  113. element.find('a')[0].getAttribute('download') === filename &&
  114. element.find('a')[0].text === result
  115. );
  116. } else {
  117. results.push(element.find('a')[0].href === data);
  118. }
  119. $.PrivateBin.AttachmentViewer.removeAttachment();
  120. results.push(
  121. $('#attachment').hasClass('hidden') &&
  122. $('#attachment').children().length === 0 &&
  123. $('#attachmentPreview').hasClass('hidden')
  124. );
  125. clean();
  126. return results.every(element => element);
  127. }
  128. );
  129. });
  130. });