UserEmailsTests.coffee 5.7 KB

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