Handle v1 response when email is already in use

This commit is contained in:
James Allen 2018-07-16 17:25:52 +01:00
parent d0f77abc70
commit ca97698724
5 changed files with 76 additions and 5 deletions

View file

@ -75,6 +75,13 @@ UnconfirmedEmailError = (message) ->
return error
UnconfirmedEmailError.prototype.__proto___ = Error.prototype
EmailExistsError = (message) ->
error = new Error(message)
error.name = "EmailExistsError"
error.__proto__ = EmailExistsError.prototype
return error
EmailExistsError.prototype.__proto___ = Error.prototype
module.exports = Errors =
NotFoundError: NotFoundError
ServiceNotConfiguredError: ServiceNotConfiguredError
@ -87,3 +94,4 @@ module.exports = Errors =
ProjectHistoryDisabledError: ProjectHistoryDisabledError
V1ConnectionError: V1ConnectionError
UnconfirmedEmailError: UnconfirmedEmailError
EmailExistsError: EmailExistsError

View file

@ -51,6 +51,11 @@ module.exports = UserEmailsController =
if error?
if error instanceof Errors.UnconfirmedEmailError
return res.sendStatus 409
else if error instanceof Errors.EmailExistsError
return res.status(409).json {
error:
message: "The email '#{email}' is already in use by another account"
}
else
return next(error)
else

View file

@ -142,7 +142,9 @@ module.exports = UserUpdater =
if error?
error = new Errors.V1ConnectionError('No V1 connection') if error.code == 'ECONNREFUSED'
return callback(error)
if 200 <= response.statusCode < 300
if response.statusCode == 409 # Conflict
return callback(new Errors.EmailExistsError('email exists in v1'))
else if 200 <= response.statusCode < 300
return callback()
else
return callback new Error("non-success code from v1: #{response.statusCode}")

View file

@ -304,7 +304,7 @@ describe "UserEmails", ->
], done
describe 'setting a default email', ->
it 'should update confirmed emails', (done) ->
it 'should update confirmed emails for users not in v1', (done) ->
token = null
async.series [
(cb) =>
@ -384,7 +384,7 @@ describe "UserEmails", ->
cb()
], done
it 'should update the email in v2', (done) ->
it 'should update the email in v1 if confirmed', (done) ->
token = null
async.series [
(cb) =>
@ -430,3 +430,53 @@ describe "UserEmails", ->
MockV1Api.updateEmail.calledWith(42, 'new-confirmed-default-in-v1@example.com')
).to.equal true
done()
it 'should return an error if the email exists in v1', (done) ->
MockV1Api.existingEmails.push 'exists-in-v1@example.com'
async.series [
(cb) =>
db.users.update {
_id: ObjectId(@user._id)
}, {
$set: {
'overleaf.id': 42
}
}, cb
(cb) =>
@user.request {
method: 'POST',
url: '/user/emails',
json:
email: 'exists-in-v1@example.com'
}, (error, response, body) =>
return done(error) if error?
expect(response.statusCode).to.equal 204
cb()
(cb) =>
# Mark the email as confirmed
db.users.update {
'emails.email': 'exists-in-v1@example.com'
}, {
$set: {
'emails.$.confirmedAt': new Date()
}
}, cb
(cb) =>
@user.request {
method: 'POST',
url: '/user/emails/default',
json:
email: 'exists-in-v1@example.com'
}, (error, response, body) =>
return done(error) if error?
expect(response.statusCode).to.equal 409
expect(body.error).to.deep.equal {
message: "The email 'exists-in-v1@example.com' is already in use by another account"
}
cb()
(cb) =>
@user.request { url: '/user/emails', json: true }, (error, response, body) ->
expect(body[0].default).to.equal true
expect(body[1].default).to.equal false
cb()
], done

View file

@ -30,6 +30,8 @@ module.exports = MockV1Api =
updateEmail: sinon.stub()
existingEmails: []
setAffiliations: (affiliations) -> @affiliations = affiliations
run: () ->
@ -67,8 +69,12 @@ module.exports = MockV1Api =
res.json []
app.put '/api/v1/sharelatex/users/:id/email', (req, res, next) =>
@updateEmail parseInt(req.params.id), req.body.email
res.sendStatus 200
{ email } = req.body
if email in @existingEmails
return res.sendStatus 409
else
@updateEmail parseInt(req.params.id), email
return res.sendStatus 200
app.listen 5000, (error) ->
throw error if error?