CsrfTests.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /* eslint-disable
  2. max-len,
  3. no-return-assign,
  4. no-unused-vars,
  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. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  12. */
  13. const { assert } = require('chai')
  14. const sinon = require('sinon')
  15. const chai = require('chai')
  16. const should = chai.should()
  17. const { expect } = chai
  18. const modulePath = '../../../../app/src/infrastructure/Csrf.js'
  19. const SandboxedModule = require('sandboxed-module')
  20. describe('Csrf', function() {
  21. beforeEach(function() {
  22. this.csurf_csrf = sinon
  23. .stub()
  24. .callsArgWith(2, (this.err = { code: 'EBADCSRFTOKEN' }))
  25. this.Csrf = SandboxedModule.require(modulePath, {
  26. globals: {
  27. console: console
  28. },
  29. requires: {
  30. csurf: sinon.stub().returns(this.csurf_csrf)
  31. }
  32. })
  33. this.csrf = new this.Csrf()
  34. this.next = sinon.stub()
  35. this.path = '/foo/bar'
  36. this.req = {
  37. path: this.path,
  38. method: 'POST'
  39. }
  40. return (this.res = {})
  41. })
  42. describe('the middleware', function() {
  43. describe('when there are no excluded routes', function() {
  44. it('passes the csrf error on', function() {
  45. this.csrf.middleware(this.req, this.res, this.next)
  46. return expect(this.next.calledWith(this.err)).to.equal(true)
  47. })
  48. })
  49. describe('when the route is excluded', function() {
  50. it('does not pass the csrf error on', function() {
  51. this.csrf.disableDefaultCsrfProtection(this.path, 'POST')
  52. this.csrf.middleware(this.req, this.res, this.next)
  53. return expect(this.next.calledWith(this.err)).to.equal(false)
  54. })
  55. })
  56. describe('when there is a partial route match', function() {
  57. it('passes the csrf error on when the match is too short', function() {
  58. this.csrf.disableDefaultCsrfProtection('/foo', 'POST')
  59. this.csrf.middleware(this.req, this.res, this.next)
  60. return expect(this.next.calledWith(this.err)).to.equal(true)
  61. })
  62. it('passes the csrf error on when the match is too long', function() {
  63. this.csrf.disableDefaultCsrfProtection('/foo/bar/baz', 'POST')
  64. this.csrf.middleware(this.req, this.res, this.next)
  65. return expect(this.next.calledWith(this.err)).to.equal(true)
  66. })
  67. })
  68. describe('when there are multiple exclusions', function() {
  69. it('does not pass the csrf error on when the match is present', function() {
  70. this.csrf.disableDefaultCsrfProtection(this.path, 'POST')
  71. this.csrf.disableDefaultCsrfProtection('/test', 'POST')
  72. this.csrf.disableDefaultCsrfProtection('/a/b/c', 'POST')
  73. this.csrf.middleware(this.req, this.res, this.next)
  74. return expect(this.next.calledWith(this.err)).to.equal(false)
  75. })
  76. it('passes the csrf error on when the match is not present', function() {
  77. this.csrf.disableDefaultCsrfProtection('/url', 'POST')
  78. this.csrf.disableDefaultCsrfProtection('/test', 'POST')
  79. this.csrf.disableDefaultCsrfProtection('/a/b/c', 'POST')
  80. this.csrf.middleware(this.req, this.res, this.next)
  81. return expect(this.next.calledWith(this.err)).to.equal(true)
  82. })
  83. })
  84. describe('when the method does not match', function() {
  85. it('passes the csrf error on', function() {
  86. this.csrf.disableDefaultCsrfProtection(this.path, 'POST')
  87. this.req.method = 'GET'
  88. this.csrf.middleware(this.req, this.res, this.next)
  89. return expect(this.next.calledWith(this.err)).to.equal(true)
  90. })
  91. })
  92. describe('when the route is excluded, but the error is not a bad-csrf-token error', function() {
  93. it('passes the error on', function() {
  94. let err
  95. this.Csrf = SandboxedModule.require(modulePath, {
  96. globals: {
  97. console: console
  98. },
  99. requires: {
  100. csurf: (this.csurf = sinon
  101. .stub()
  102. .returns(
  103. (this.csurf_csrf = sinon
  104. .stub()
  105. .callsArgWith(2, (err = { code: 'EOTHER' })))
  106. ))
  107. }
  108. })
  109. this.csrf = new this.Csrf()
  110. this.csrf.disableDefaultCsrfProtection(this.path, 'POST')
  111. this.csrf.middleware(this.req, this.res, this.next)
  112. expect(this.next.calledWith(err)).to.equal(true)
  113. return expect(this.next.calledWith(this.err)).to.equal(false)
  114. })
  115. })
  116. })
  117. describe('validateRequest', function() {
  118. describe('when the request is invalid', function() {
  119. it('calls the callback with error', function() {
  120. this.cb = sinon.stub()
  121. this.Csrf.validateRequest(this.req, this.cb)
  122. return expect(this.cb.calledWith(this.err)).to.equal(true)
  123. })
  124. })
  125. describe('when the request is valid', function() {
  126. it('calls the callback without an error', function() {
  127. this.Csrf = SandboxedModule.require(modulePath, {
  128. globals: {
  129. console: console
  130. },
  131. requires: {
  132. csurf: (this.csurf = sinon
  133. .stub()
  134. .returns((this.csurf_csrf = sinon.stub().callsArg(2))))
  135. }
  136. })
  137. this.cb = sinon.stub()
  138. this.Csrf.validateRequest(this.req, this.cb)
  139. return expect(this.cb.calledWith()).to.equal(true)
  140. })
  141. })
  142. })
  143. describe('validateToken', function() {
  144. describe('when the request is invalid', function() {
  145. it('calls the callback with `false`', function() {
  146. this.cb = sinon.stub()
  147. this.Csrf.validateToken('token', {}, this.cb)
  148. expect(this.cb.calledWith(this.err)).to.equal(true)
  149. })
  150. })
  151. describe('when the request is valid', function() {
  152. it('calls the callback with `true`', function() {
  153. this.Csrf = SandboxedModule.require(modulePath, {
  154. globals: {
  155. console: console
  156. },
  157. requires: {
  158. csurf: (this.csurf = sinon
  159. .stub()
  160. .returns((this.csurf_csrf = sinon.stub().callsArg(2))))
  161. }
  162. })
  163. this.cb = sinon.stub()
  164. this.Csrf.validateToken('goodtoken', {}, this.cb)
  165. return expect(this.cb.calledWith()).to.equal(true)
  166. })
  167. })
  168. describe('when there is no token', function() {
  169. it('calls the callback with an error', function() {
  170. this.Csrf = SandboxedModule.require(modulePath, {
  171. globals: {
  172. console: console
  173. },
  174. requires: {
  175. csurf: (this.csurf = sinon
  176. .stub()
  177. .returns((this.csurf_csrf = sinon.stub().callsArg(2))))
  178. }
  179. })
  180. this.cb = sinon.stub()
  181. this.Csrf.validateToken(null, {}, error => {
  182. expect(error).to.exist
  183. })
  184. })
  185. })
  186. })
  187. })