mirror of
https://github.com/overleaf/overleaf.git
synced 2025-04-08 21:20:45 +00:00
Merge pull request #2184 from overleaf/jel-unlink-institution-and-email-notifications
Unlink institution login and send email link/unlink notifications GitOrigin-RevId: d0fe96804d69e3c332c2b866fad5af026b5e2f8f
This commit is contained in:
parent
ea0270dbdd
commit
d8e6535691
3 changed files with 97 additions and 20 deletions
services/web
app/src/Features
test/unit/src/User
|
@ -487,7 +487,7 @@ templates.emailThirdPartyIdentifierLinked = NoCTAEmailTemplate({
|
|||
},
|
||||
message(opts) {
|
||||
let message = `We're contacting you to notify you that your ${opts.provider}
|
||||
account is now linked to your ${settings.appName} account`
|
||||
account is now linked to your ${settings.appName} account.`
|
||||
return message
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
const EmailHandler = require('../Email/EmailHandler')
|
||||
const Errors = require('../Errors/Errors')
|
||||
const logger = require('logger-sharelatex')
|
||||
const OError = require('@overleaf/o-error')
|
||||
|
@ -77,39 +78,82 @@ async function _addInstitutionEmail(userId, email, providerId) {
|
|||
}
|
||||
}
|
||||
|
||||
async function _sendLinkedEmail(userId, providerName) {
|
||||
const user = await UserGetter.promises.getUser(userId, { email: 1 })
|
||||
const emailOptions = {
|
||||
to: user.email,
|
||||
provider: providerName
|
||||
}
|
||||
EmailHandler.sendEmail(
|
||||
'emailThirdPartyIdentifierLinked',
|
||||
emailOptions,
|
||||
error => {
|
||||
if (error != null) {
|
||||
logger.warn(error)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function _sendUnlinkedEmail(primaryEmail, providerName) {
|
||||
const emailOptions = {
|
||||
to: primaryEmail,
|
||||
provider: providerName
|
||||
}
|
||||
EmailHandler.sendEmail(
|
||||
'emailThirdPartyIdentifierUnlinked',
|
||||
emailOptions,
|
||||
error => {
|
||||
if (error != null) {
|
||||
logger.warn(error)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async function getUser(providerId, externalUserId) {
|
||||
if (providerId == null || externalUserId == null) {
|
||||
throw new Error('invalid arguments')
|
||||
}
|
||||
try {
|
||||
const query = _getUserQuery(providerId, externalUserId)
|
||||
let user = await User.findOne(query).exec()
|
||||
if (!user) {
|
||||
throw new Errors.SAMLUserNotFoundError()
|
||||
}
|
||||
return user
|
||||
} catch (error) {
|
||||
throw error
|
||||
const query = _getUserQuery(providerId, externalUserId)
|
||||
let user = await User.findOne(query).exec()
|
||||
if (!user) {
|
||||
throw new Errors.SAMLUserNotFoundError()
|
||||
}
|
||||
return user
|
||||
}
|
||||
|
||||
async function linkAccounts(
|
||||
userId,
|
||||
externalUserId,
|
||||
institutionEmail,
|
||||
providerId
|
||||
providerId,
|
||||
providerName
|
||||
) {
|
||||
try {
|
||||
await _addIdentifier(userId, externalUserId, providerId)
|
||||
await _addInstitutionEmail(userId, institutionEmail, providerId)
|
||||
} catch (error) {
|
||||
throw error
|
||||
await _addIdentifier(userId, externalUserId, providerId)
|
||||
await _addInstitutionEmail(userId, institutionEmail, providerId)
|
||||
await _sendLinkedEmail(userId, providerName)
|
||||
}
|
||||
|
||||
async function unlinkAccounts(userId, primaryEmail, providerId, providerName) {
|
||||
const query = {
|
||||
_id: userId
|
||||
}
|
||||
const update = {
|
||||
$pull: {
|
||||
samlIdentifiers: {
|
||||
providerId
|
||||
}
|
||||
}
|
||||
}
|
||||
await User.update(query, update).exec()
|
||||
_sendUnlinkedEmail(primaryEmail, providerName)
|
||||
}
|
||||
|
||||
const SAMLIdentityManager = {
|
||||
getUser,
|
||||
linkAccounts
|
||||
linkAccounts,
|
||||
unlinkAccounts
|
||||
}
|
||||
|
||||
module.exports = SAMLIdentityManager
|
||||
|
|
|
@ -12,20 +12,39 @@ describe('SAMLIdentityManager', function() {
|
|||
SAMLUserNotFoundError: sinon.stub()
|
||||
}
|
||||
this.user = {
|
||||
_id: 'user-id'
|
||||
_id: 'user-id',
|
||||
email: 'dev@overleaf.com',
|
||||
emails: [
|
||||
{ email: 'dev@overleaf.com' },
|
||||
{ email: 'team@overleaf.com', samlProviderId: '1' }
|
||||
],
|
||||
samlIdentifiers: [{ providerId: '1' }]
|
||||
}
|
||||
this.userWithoutInstitutionEmail = {
|
||||
_id: 'user-id',
|
||||
emails: [{ email: 'dev@overleaf.com' }]
|
||||
}
|
||||
this.institution = {
|
||||
name: 'Overleaf University'
|
||||
}
|
||||
this.SAMLIdentityManager = SandboxedModule.require(modulePath, {
|
||||
requires: {
|
||||
'../Email/EmailHandler': (this.EmailHandler = {
|
||||
sendEmail: sinon.stub().yields()
|
||||
}),
|
||||
'../Errors/Errors': this.Errors,
|
||||
'../../models/User': {
|
||||
User: (this.User = {
|
||||
findOne: sinon.stub()
|
||||
findOne: sinon.stub(this.user),
|
||||
update: sinon.stub().returns({
|
||||
exec: sinon.stub().resolves()
|
||||
})
|
||||
})
|
||||
},
|
||||
'../User/UserGetter': (this.UserGetter = {
|
||||
getUser: sinon.stub(),
|
||||
promises: {
|
||||
getUser: sinon.stub().resolves()
|
||||
getUser: sinon.stub().resolves(this.user)
|
||||
}
|
||||
}),
|
||||
'../User/UserUpdater': (this.UserUpdater = {
|
||||
|
@ -58,4 +77,18 @@ describe('SAMLIdentityManager', function() {
|
|||
}
|
||||
})
|
||||
})
|
||||
describe('unlinkAccounts', function() {
|
||||
it('should send an email notification email', function() {
|
||||
this.SAMLIdentityManager.unlinkAccounts(
|
||||
this.user._id,
|
||||
this.user.email,
|
||||
'1',
|
||||
'Overleaf University',
|
||||
() => {
|
||||
expect(this.User.update).to.have.been.called
|
||||
expect(this.EmailHandler.sendEmail).to.have.been.called
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Add table
Reference in a new issue