mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #17730 from overleaf/rh-acct-delete-email
[web] Send email notification on account deletion GitOrigin-RevId: 03c0effba0ee3b829f5b4fe377fe67d05776ba3f
This commit is contained in:
parent
8bde496da4
commit
bf7a18db8b
3 changed files with 53 additions and 2 deletions
|
@ -527,8 +527,8 @@ templates.groupSSOReauthenticate = ctaTemplate({
|
|||
return [
|
||||
`Hi,
|
||||
<div>
|
||||
Single sign-on for your Overleaf group has been updated.
|
||||
This means you need to reauthenticate your Overleaf account with your group’s SSO provider.
|
||||
Single sign-on for your Overleaf group has been updated.
|
||||
This means you need to reauthenticate your Overleaf account with your group’s SSO provider.
|
||||
</div>
|
||||
`,
|
||||
]
|
||||
|
@ -786,6 +786,31 @@ templates.userOnboardingEmail = NoCTAEmailTemplate({
|
|||
},
|
||||
})
|
||||
|
||||
templates.deletedAccount = NoCTAEmailTemplate({
|
||||
subject() {
|
||||
return 'Overleaf security note: account deletion confirmation'
|
||||
},
|
||||
title() {
|
||||
return 'Account deleted'
|
||||
},
|
||||
message(opts, isPlainText) {
|
||||
const dateFormatted = moment().format('dddd D MMMM YYYY')
|
||||
const timeFormatted = moment().format('HH:mm')
|
||||
const helpLink = EmailMessageHelper.displayLink(
|
||||
'quick guide',
|
||||
`${settings.siteUrl}/learn/how-to/Keeping_your_account_secure`,
|
||||
isPlainText
|
||||
)
|
||||
|
||||
return [
|
||||
`We are writing to let you know that your ${settings.appName} account was deleted on ${dateFormatted} at ${timeFormatted} GMT.`,
|
||||
`If this was you, you're all set and can ignore this email.`,
|
||||
`If you did not take this action, please get in touch with our support team at ${settings.adminEmail} to report this as potentially suspicious activity on your account.`,
|
||||
`For tips on keeping your ${settings.appName} account secure, read our ${helpLink}.`,
|
||||
]
|
||||
},
|
||||
})
|
||||
|
||||
templates.securityAlert = NoCTAEmailTemplate({
|
||||
subject(opts) {
|
||||
return `Overleaf security note: ${opts.action}`
|
||||
|
|
|
@ -16,6 +16,7 @@ const InstitutionsAPI = require('../Institutions/InstitutionsAPI')
|
|||
const Modules = require('../../infrastructure/Modules')
|
||||
const Errors = require('../Errors/Errors')
|
||||
const OnboardingDataCollectionManager = require('../OnboardingDataCollection/OnboardingDataCollectionManager')
|
||||
const EmailHandler = require('../Email/EmailHandler')
|
||||
|
||||
module.exports = {
|
||||
deleteUser: callbackify(deleteUser),
|
||||
|
@ -48,6 +49,7 @@ async function deleteUser(userId, options) {
|
|||
await Modules.promises.hooks.fire('deleteUser', userId)
|
||||
await _createDeletedUser(user, options)
|
||||
await ProjectDeleter.promises.deleteUsersProjects(user._id)
|
||||
await _sendDeleteEmail(user)
|
||||
await deleteMongoUser(user._id)
|
||||
} catch (error) {
|
||||
logger.warn({ error, userId }, 'something went wrong deleting the user')
|
||||
|
@ -110,6 +112,13 @@ async function ensureCanDeleteUser(user) {
|
|||
}
|
||||
}
|
||||
|
||||
async function _sendDeleteEmail(user) {
|
||||
const emailOptions = {
|
||||
to: user.email,
|
||||
}
|
||||
await EmailHandler.promises.sendEmail('deletedAccount', emailOptions)
|
||||
}
|
||||
|
||||
async function _createDeletedUser(user, options) {
|
||||
await DeletedUser.updateOne(
|
||||
{ 'deleterData.deletedUserId': user._id },
|
||||
|
|
|
@ -100,6 +100,12 @@ describe('UserDeleter', function () {
|
|||
deleteOnboardingDataCollection: sinon.stub().resolves(),
|
||||
}
|
||||
|
||||
this.EmailHandler = {
|
||||
promises: {
|
||||
sendEmail: sinon.stub().resolves(),
|
||||
},
|
||||
}
|
||||
|
||||
this.UserDeleter = SandboxedModule.require(modulePath, {
|
||||
requires: {
|
||||
'../../models/User': { User },
|
||||
|
@ -119,6 +125,7 @@ describe('UserDeleter', function () {
|
|||
'../../infrastructure/Modules': this.Modules,
|
||||
'../OnboardingDataCollection/OnboardingDataCollectionManager':
|
||||
this.OnboardingDataCollectionManager,
|
||||
'../Email/EmailHandler': this.EmailHandler,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
@ -251,6 +258,16 @@ describe('UserDeleter', function () {
|
|||
await this.UserDeleter.promises.deleteUser(this.userId, {})
|
||||
this.DeletedUserMock.verify()
|
||||
})
|
||||
|
||||
it('should email the user', async function () {
|
||||
await this.UserDeleter.promises.deleteUser(this.userId, {})
|
||||
const emailOptions = {
|
||||
to: 'bob@bob.com',
|
||||
}
|
||||
expect(
|
||||
this.EmailHandler.promises.sendEmail
|
||||
).to.have.been.calledWith('deletedAccount', emailOptions)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when unsubscribing from mailchimp fails', function () {
|
||||
|
|
Loading…
Reference in a new issue