UserEmailsTests.coffee 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. expect = require("chai").expect
  2. async = require("async")
  3. User = require "./helpers/User"
  4. request = require "./helpers/request"
  5. settings = require "settings-sharelatex"
  6. {db, ObjectId} = require("../../../app/js/infrastructure/mongojs")
  7. describe "UserEmails", ->
  8. beforeEach (done) ->
  9. @timeout(20000)
  10. @user = new User()
  11. @user.login done
  12. describe 'confirming an email', ->
  13. it 'should confirm the email', (done) ->
  14. token = null
  15. async.series [
  16. (cb) =>
  17. @user.request {
  18. method: 'POST',
  19. url: '/user/emails',
  20. json:
  21. email: 'newly-added-email@example.com'
  22. }, (error, response, body) =>
  23. return done(error) if error?
  24. expect(response.statusCode).to.equal 204
  25. cb()
  26. (cb) =>
  27. @user.request { url: '/user/emails', json: true }, (error, response, body) ->
  28. expect(response.statusCode).to.equal 200
  29. expect(body[0].confirmedAt).to.not.exist
  30. expect(body[1].confirmedAt).to.not.exist
  31. cb()
  32. (cb) =>
  33. db.tokens.find {
  34. use: 'email_confirmation',
  35. 'data.user_id': @user._id,
  36. usedAt: { $exists: false }
  37. }, (error, tokens) =>
  38. # There should only be one confirmation token at the moment
  39. expect(tokens.length).to.equal 1
  40. expect(tokens[0].data.email).to.equal 'newly-added-email@example.com'
  41. expect(tokens[0].data.user_id).to.equal @user._id
  42. token = tokens[0].token
  43. cb()
  44. (cb) =>
  45. @user.request {
  46. method: 'POST',
  47. url: '/user/emails/confirm',
  48. json:
  49. token: token
  50. }, (error, response, body) =>
  51. return done(error) if error?
  52. expect(response.statusCode).to.equal 200
  53. cb()
  54. (cb) =>
  55. @user.request { url: '/user/emails', json: true }, (error, response, body) ->
  56. expect(response.statusCode).to.equal 200
  57. expect(body[0].confirmedAt).to.not.exist
  58. expect(body[1].confirmedAt).to.exist
  59. cb()
  60. (cb) =>
  61. db.tokens.find {
  62. use: 'email_confirmation',
  63. 'data.user_id': @user._id,
  64. usedAt: { $exists: false }
  65. }, (error, tokens) =>
  66. # Token should be deleted after use
  67. expect(tokens.length).to.equal 0
  68. cb()
  69. ], done
  70. it 'should not allow confirmation of the email if the user has changed', (done) ->
  71. token1 = null
  72. token2 = null
  73. @user2 = new User()
  74. @email = 'duplicate-email@example.com'
  75. async.series [
  76. (cb) => @user2.login cb
  77. (cb) =>
  78. # Create email for first user
  79. @user.request {
  80. method: 'POST',
  81. url: '/user/emails',
  82. json: {@email}
  83. }, cb
  84. (cb) =>
  85. db.tokens.find {
  86. use: 'email_confirmation',
  87. 'data.user_id': @user._id,
  88. usedAt: { $exists: false }
  89. }, (error, tokens) =>
  90. # There should only be one confirmation token at the moment
  91. expect(tokens.length).to.equal 1
  92. expect(tokens[0].data.email).to.equal @email
  93. expect(tokens[0].data.user_id).to.equal @user._id
  94. token1 = tokens[0].token
  95. cb()
  96. (cb) =>
  97. # Delete the email from the first user
  98. @user.request {
  99. method: 'DELETE',
  100. url: '/user/emails',
  101. json: {@email}
  102. }, cb
  103. (cb) =>
  104. # Create email for second user
  105. @user2.request {
  106. method: 'POST',
  107. url: '/user/emails',
  108. json: {@email}
  109. }, cb
  110. (cb) =>
  111. # Original confirmation token should no longer work
  112. @user.request {
  113. method: 'POST',
  114. url: '/user/emails/confirm',
  115. json:
  116. token: token1
  117. }, (error, response, body) =>
  118. return done(error) if error?
  119. expect(response.statusCode).to.equal 404
  120. cb()
  121. (cb) =>
  122. db.tokens.find {
  123. use: 'email_confirmation',
  124. 'data.user_id': @user2._id,
  125. usedAt: { $exists: false }
  126. }, (error, tokens) =>
  127. # The first token has been used, so this should be token2 now
  128. expect(tokens.length).to.equal 1
  129. expect(tokens[0].data.email).to.equal @email
  130. expect(tokens[0].data.user_id).to.equal @user2._id
  131. token2 = tokens[0].token
  132. cb()
  133. (cb) =>
  134. # Second user should be able to confirm the email
  135. @user2.request {
  136. method: 'POST',
  137. url: '/user/emails/confirm',
  138. json:
  139. token: token2
  140. }, (error, response, body) =>
  141. return done(error) if error?
  142. expect(response.statusCode).to.equal 200
  143. cb()
  144. (cb) =>
  145. @user2.request { url: '/user/emails', json: true }, (error, response, body) ->
  146. expect(response.statusCode).to.equal 200
  147. expect(body[0].confirmedAt).to.not.exist
  148. expect(body[1].confirmedAt).to.exist
  149. cb()
  150. ], done
  151. describe "with an expired token", ->
  152. it 'should not confirm the email', (done) ->
  153. token = null
  154. async.series [
  155. (cb) =>
  156. @user.request {
  157. method: 'POST',
  158. url: '/user/emails',
  159. json:
  160. email: @email = 'expired-token-email@example.com'
  161. }, (error, response, body) =>
  162. return done(error) if error?
  163. expect(response.statusCode).to.equal 204
  164. cb()
  165. (cb) =>
  166. db.tokens.find {
  167. use: 'email_confirmation',
  168. 'data.user_id': @user._id,
  169. usedAt: { $exists: false }
  170. }, (error, tokens) =>
  171. # There should only be one confirmation token at the moment
  172. expect(tokens.length).to.equal 1
  173. expect(tokens[0].data.email).to.equal @email
  174. expect(tokens[0].data.user_id).to.equal @user._id
  175. token = tokens[0].token
  176. cb()
  177. (cb) =>
  178. db.tokens.update {
  179. token: token
  180. }, {
  181. $set: {
  182. expiresAt: new Date(Date.now() - 1000000)
  183. }
  184. }, cb
  185. (cb) =>
  186. @user.request {
  187. method: 'POST',
  188. url: '/user/emails/confirm',
  189. json:
  190. token: token
  191. }, (error, response, body) =>
  192. return done(error) if error?
  193. expect(response.statusCode).to.equal 404
  194. cb()
  195. ], done