mirror of
https://github.com/overleaf/overleaf.git
synced 2025-03-22 02:04:31 +00:00
Merge pull request #3096 from overleaf/jel-security-alert-primary-email
Send security alert email when primary email changed GitOrigin-RevId: a01f38a2478dc280261b9a43ef1a01751d4601fb
This commit is contained in:
parent
3babf23444
commit
bbf3132a16
3 changed files with 76 additions and 8 deletions
services/web
|
@ -125,13 +125,20 @@ const UserEmailsController = {
|
||||||
initiatorId: userId,
|
initiatorId: userId,
|
||||||
ipAddress: req.ip
|
ipAddress: req.ip
|
||||||
}
|
}
|
||||||
UserUpdater.setDefaultEmailAddress(userId, email, false, auditLog, err => {
|
UserUpdater.setDefaultEmailAddress(
|
||||||
if (err) {
|
userId,
|
||||||
return UserEmailsController._handleEmailError(err, req, res, next)
|
email,
|
||||||
|
false,
|
||||||
|
auditLog,
|
||||||
|
true,
|
||||||
|
err => {
|
||||||
|
if (err) {
|
||||||
|
return UserEmailsController._handleEmailError(err, req, res, next)
|
||||||
|
}
|
||||||
|
AuthenticationController.setInSessionUser(req, { email: email })
|
||||||
|
res.sendStatus(200)
|
||||||
}
|
}
|
||||||
AuthenticationController.setInSessionUser(req, { email: email })
|
)
|
||||||
res.sendStatus(200)
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
endorse(req, res, next) {
|
endorse(req, res, next) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ const {
|
||||||
} = require('../Institutions/InstitutionsAPI')
|
} = require('../Institutions/InstitutionsAPI')
|
||||||
const Features = require('../../infrastructure/Features')
|
const Features = require('../../infrastructure/Features')
|
||||||
const FeaturesUpdater = require('../Subscription/FeaturesUpdater')
|
const FeaturesUpdater = require('../Subscription/FeaturesUpdater')
|
||||||
|
const EmailHandler = require('../Email/EmailHandler')
|
||||||
const EmailHelper = require('../Helpers/EmailHelper')
|
const EmailHelper = require('../Helpers/EmailHelper')
|
||||||
const Errors = require('../Errors/Errors')
|
const Errors = require('../Errors/Errors')
|
||||||
const NewsletterManager = require('../Newsletter/NewsletterManager')
|
const NewsletterManager = require('../Newsletter/NewsletterManager')
|
||||||
|
@ -23,7 +24,8 @@ async function setDefaultEmailAddress(
|
||||||
userId,
|
userId,
|
||||||
email,
|
email,
|
||||||
allowUnconfirmed,
|
allowUnconfirmed,
|
||||||
auditLog
|
auditLog,
|
||||||
|
sendSecurityAlert
|
||||||
) {
|
) {
|
||||||
email = EmailHelper.parseEmail(email)
|
email = EmailHelper.parseEmail(email)
|
||||||
if (email == null) {
|
if (email == null) {
|
||||||
|
@ -67,6 +69,25 @@ async function setDefaultEmailAddress(
|
||||||
throw new Error('email update error')
|
throw new Error('email update error')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sendSecurityAlert) {
|
||||||
|
// send email to both old and new primary email
|
||||||
|
const emailOptions = {
|
||||||
|
actionDescribed: `the primary email address on your account was changed to ${email}`,
|
||||||
|
action: 'change of primary email address'
|
||||||
|
}
|
||||||
|
const toOld = Object.assign({}, emailOptions, { to: oldEmail })
|
||||||
|
const toNew = Object.assign({}, emailOptions, { to: email })
|
||||||
|
try {
|
||||||
|
await EmailHandler.promises.sendEmail('securityAlert', toOld)
|
||||||
|
await EmailHandler.promises.sendEmail('securityAlert', toNew)
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(
|
||||||
|
{ err: error, userId },
|
||||||
|
'could not send security alert email when primary email changed'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await NewsletterManager.promises.changeEmail(user, email)
|
await NewsletterManager.promises.changeEmail(user, email)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -155,6 +176,7 @@ const UserUpdater = {
|
||||||
newEmail,
|
newEmail,
|
||||||
true,
|
true,
|
||||||
auditLog,
|
auditLog,
|
||||||
|
true,
|
||||||
cb
|
cb
|
||||||
),
|
),
|
||||||
cb => UserUpdater.removeEmailAddress(userId, oldEmail, cb)
|
cb => UserUpdater.removeEmailAddress(userId, oldEmail, cb)
|
||||||
|
|
|
@ -59,6 +59,11 @@ describe('UserUpdater', function() {
|
||||||
addAffiliation: this.addAffiliation,
|
addAffiliation: this.addAffiliation,
|
||||||
removeAffiliation: this.removeAffiliation
|
removeAffiliation: this.removeAffiliation
|
||||||
},
|
},
|
||||||
|
'../Email/EmailHandler': (this.EmailHandler = {
|
||||||
|
promises: {
|
||||||
|
sendEmail: sinon.stub()
|
||||||
|
}
|
||||||
|
}),
|
||||||
'../../infrastructure/Features': (this.Features = {
|
'../../infrastructure/Features': (this.Features = {
|
||||||
hasFeature: sinon.stub().returns(false)
|
hasFeature: sinon.stub().returns(false)
|
||||||
}),
|
}),
|
||||||
|
@ -151,7 +156,13 @@ describe('UserUpdater', function() {
|
||||||
.calledWith(this.stubbedUser._id, this.newEmail)
|
.calledWith(this.stubbedUser._id, this.newEmail)
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
this.UserUpdater.setDefaultEmailAddress
|
this.UserUpdater.setDefaultEmailAddress
|
||||||
.calledWith(this.stubbedUser._id, this.newEmail, true)
|
.calledWith(
|
||||||
|
this.stubbedUser._id,
|
||||||
|
this.newEmail,
|
||||||
|
true,
|
||||||
|
this.auditLog,
|
||||||
|
true
|
||||||
|
)
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
this.UserUpdater.removeEmailAddress
|
this.UserUpdater.removeEmailAddress
|
||||||
.calledWith(this.stubbedUser._id, this.stubbedUser.email)
|
.calledWith(this.stubbedUser._id, this.stubbedUser.email)
|
||||||
|
@ -562,6 +573,34 @@ describe('UserUpdater', function() {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('security alert', function() {
|
||||||
|
it('should be sent to old and new email when sendSecurityAlert=true', function(done) {
|
||||||
|
// this.UserGetter.promises.getUser.resolves(this.stubbedUser)
|
||||||
|
this.UserUpdater.promises.updateUser = sinon.stub().resolves({ n: 1 })
|
||||||
|
|
||||||
|
this.UserUpdater.setDefaultEmailAddress(
|
||||||
|
this.stubbedUser._id,
|
||||||
|
this.newEmail,
|
||||||
|
false,
|
||||||
|
this.auditLog,
|
||||||
|
true,
|
||||||
|
error => {
|
||||||
|
expect(error).to.not.exist
|
||||||
|
this.EmailHandler.promises.sendEmail.callCount.should.equal(2)
|
||||||
|
const toOldEmailAlert = this.EmailHandler.promises.sendEmail
|
||||||
|
.firstCall
|
||||||
|
expect(toOldEmailAlert.args[0]).to.equal('securityAlert')
|
||||||
|
const toNewEmailAlert = this.EmailHandler.promises.sendEmail
|
||||||
|
.lastCall
|
||||||
|
expect(toOldEmailAlert.args[1].to).to.equal(this.stubbedUser.email)
|
||||||
|
expect(toNewEmailAlert.args[0]).to.equal('securityAlert')
|
||||||
|
expect(toNewEmailAlert.args[1].to).to.equal(this.newEmail)
|
||||||
|
done()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('confirmEmail', function() {
|
describe('confirmEmail', function() {
|
||||||
|
|
Loading…
Reference in a new issue