SecurityHeadersTests.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /* eslint-disable
  2. n/handle-callback-err,
  3. max-len,
  4. no-return-assign,
  5. */
  6. // TODO: This file was created by bulk-decaffeinate.
  7. // Fix any style issues and re-enable lint.
  8. /*
  9. * decaffeinate suggestions:
  10. * DS102: Remove unnecessary code created because of implicit returns
  11. * DS207: Consider shorter variations of null checks
  12. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  13. */
  14. const { assert } = require('chai')
  15. const async = require('async')
  16. const User = require('./helpers/User')
  17. const request = require('./helpers/request')
  18. const ProjectGetter = require('../../../app/src/Features/Project/ProjectGetter')
  19. const assertHasCommonHeaders = function (response) {
  20. const { headers } = response
  21. assert.include(headers, {
  22. 'x-download-options': 'noopen',
  23. 'x-xss-protection': '0',
  24. 'cross-origin-resource-policy': 'same-origin',
  25. 'cross-origin-opener-policy': 'same-origin-allow-popups',
  26. 'x-content-type-options': 'nosniff',
  27. 'x-permitted-cross-domain-policies': 'none',
  28. 'referrer-policy': 'origin-when-cross-origin',
  29. })
  30. assert.isUndefined(headers['cross-origin-embedder-policy'])
  31. }
  32. const assertHasCacheHeaders = function (response) {
  33. assert.include(response.headers, {
  34. 'surrogate-control': 'no-store',
  35. 'cache-control': 'no-store, no-cache, must-revalidate, proxy-revalidate',
  36. pragma: 'no-cache',
  37. expires: '0',
  38. })
  39. }
  40. const assertHasNoCacheHeaders = function (response) {
  41. assert.doesNotHaveAnyKeys(response.headers, [
  42. 'surrogate-control',
  43. 'cache-control',
  44. 'pragma',
  45. 'expires',
  46. ])
  47. }
  48. const assertHasAssetCachingHeaders = function (response) {
  49. assert.equal(response.headers['cache-control'], 'public, max-age=31536000')
  50. }
  51. describe('SecurityHeaders', function () {
  52. beforeEach(function () {
  53. return (this.user = new User())
  54. })
  55. it('should not have x-powered-by header', function (done) {
  56. return request.get('/', (err, res, body) => {
  57. assert.isUndefined(res.headers['x-powered-by'])
  58. return done()
  59. })
  60. })
  61. it('should have all common headers', function (done) {
  62. return request.get('/', (err, res, body) => {
  63. assertHasCommonHeaders(res)
  64. return done()
  65. })
  66. })
  67. it('should not have cache headers on public pages', function (done) {
  68. return request.get('/', (err, res, body) => {
  69. assertHasNoCacheHeaders(res)
  70. return done()
  71. })
  72. })
  73. it('should have caching headers on static assets', function (done) {
  74. request.get('/favicon.ico', (err, res) => {
  75. assertHasAssetCachingHeaders(res)
  76. done(err)
  77. })
  78. })
  79. it('should have cache headers when user is logged in', function (done) {
  80. return async.series(
  81. [
  82. cb => this.user.login(cb),
  83. cb => this.user.request.get('/', cb),
  84. cb => this.user.logout(cb),
  85. ],
  86. (err, results) => {
  87. const mainResponse = results[1][0]
  88. assertHasCacheHeaders(mainResponse)
  89. return done()
  90. }
  91. )
  92. })
  93. it('should have cache headers on project page when user is logged out', function (done) {
  94. return async.series(
  95. [
  96. cb => this.user.login(cb),
  97. cb =>
  98. this.user.createProject('public-project', (error, projectId) => {
  99. if (error != null) {
  100. return done(error)
  101. }
  102. this.project_id = projectId
  103. return this.user.makePublic(this.project_id, 'readAndWrite', cb)
  104. }),
  105. cb => this.user.logout(cb),
  106. cb => request.get(`/project/${this.project_id}`, cb),
  107. ],
  108. (err, res) => {
  109. const mainResponse = res[3][0]
  110. assertHasCacheHeaders(mainResponse)
  111. return done()
  112. }
  113. )
  114. })
  115. it('should have private cache headers on project file', function (done) {
  116. return async.series(
  117. [
  118. cb => this.user.login(cb),
  119. cb =>
  120. this.user.createProject(
  121. 'public-project',
  122. (error, projectId, folderId) => {
  123. if (error != null) {
  124. return done(error)
  125. }
  126. this.project_id = projectId
  127. return this.user.makePublic(this.project_id, 'readAndWrite', cb)
  128. }
  129. ),
  130. cb =>
  131. ProjectGetter.getProject(this.project_id, (error, project) => {
  132. if (error) {
  133. return cb(error)
  134. }
  135. this.root_folder_id = project.rootFolder[0]._id.toString()
  136. cb()
  137. }),
  138. cb => {
  139. return this.user.uploadFileInProject(
  140. this.project_id,
  141. this.root_folder_id,
  142. '2pixel.png',
  143. '1pixel.png',
  144. 'image/png',
  145. (error, fileId) => {
  146. if (error) {
  147. return cb(error)
  148. }
  149. this.file_id = fileId
  150. cb()
  151. }
  152. )
  153. },
  154. cb =>
  155. request.get(`/project/${this.project_id}/file/${this.file_id}`, cb),
  156. cb => this.user.logout(cb),
  157. ],
  158. (err, results) => {
  159. const res = results[4][0]
  160. assert.include(res.headers, {
  161. 'cache-control': 'private, max-age=3600',
  162. })
  163. assert.doesNotHaveAnyKeys(res.headers, [
  164. 'surrogate-control',
  165. 'pragma',
  166. 'expires',
  167. ])
  168. return done()
  169. }
  170. )
  171. })
  172. it('should have caching headers on static assets when user is logged in', function (done) {
  173. async.series(
  174. [
  175. cb => this.user.login(cb),
  176. cb => this.user.request.get('/favicon.ico', cb),
  177. cb => this.user.logout(cb),
  178. ],
  179. (err, results) => {
  180. const res = results[1][0]
  181. assertHasAssetCachingHeaders(res)
  182. done()
  183. }
  184. )
  185. })
  186. })