Merge pull request #3492 from overleaf/jel-calc-notification-period
Flag emails in affiliation notification period GitOrigin-RevId: d2d4868ba3a49e69b85a3bdca16d12276ac5c006
This commit is contained in:
@@ -2,6 +2,7 @@ const { ObjectId } = require('mongodb')
|
||||
const should = require('chai').should()
|
||||
const SandboxedModule = require('sandboxed-module')
|
||||
const assert = require('assert')
|
||||
const moment = require('moment')
|
||||
const path = require('path')
|
||||
const sinon = require('sinon')
|
||||
const modulePath = path.join(
|
||||
@@ -41,7 +42,6 @@ describe('UserGetter', function() {
|
||||
},
|
||||
ObjectId
|
||||
}
|
||||
const settings = { apis: { v1: { url: 'v1.url', user: '', pass: '' } } }
|
||||
this.getUserAffiliations = sinon.stub().resolves([])
|
||||
|
||||
this.UserGetter = SandboxedModule.require(modulePath, {
|
||||
@@ -57,7 +57,9 @@ describe('UserGetter', function() {
|
||||
'@overleaf/metrics': {
|
||||
timeAsyncMethod: sinon.stub()
|
||||
},
|
||||
'settings-sharelatex': settings,
|
||||
'settings-sharelatex': (this.settings = {
|
||||
reconfirmNotificationDays: 14
|
||||
}),
|
||||
'../Institutions/InstitutionsAPI': {
|
||||
promises: {
|
||||
getUserAffiliations: this.getUserAffiliations
|
||||
@@ -192,7 +194,8 @@ describe('UserGetter', function() {
|
||||
inferred: affiliationsData[0].inferred,
|
||||
department: affiliationsData[0].department,
|
||||
role: affiliationsData[0].role,
|
||||
licence: affiliationsData[0].licence
|
||||
licence: affiliationsData[0].licence,
|
||||
inReconfirmNotificationPeriod: false
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -262,6 +265,528 @@ describe('UserGetter', function() {
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
describe('affiliation reconfirmation', function() {
|
||||
const institutionNonSSO = {
|
||||
id: 1,
|
||||
name: 'University Name',
|
||||
commonsAccount: true,
|
||||
isUniversity: true,
|
||||
confirmed: true,
|
||||
ssoBeta: false,
|
||||
ssoEnabled: false,
|
||||
maxConfirmationMonths: 12
|
||||
}
|
||||
const institutionSSO = {
|
||||
id: 2,
|
||||
name: 'SSO University Name',
|
||||
isUniversity: true,
|
||||
confirmed: true,
|
||||
ssoBeta: false,
|
||||
ssoEnabled: true,
|
||||
maxConfirmationMonths: 12
|
||||
}
|
||||
describe('non-SSO institutions', function() {
|
||||
const email1 = 'leonard@example-affiliation.com'
|
||||
const email2 = 'mccoy@example-affiliation.com'
|
||||
const affiliationsData = [
|
||||
{
|
||||
email: email1,
|
||||
role: 'Prof',
|
||||
department: 'Medicine',
|
||||
inferred: false,
|
||||
licence: 'pro_plus',
|
||||
institution: institutionNonSSO
|
||||
},
|
||||
{
|
||||
email: email2,
|
||||
role: 'Prof',
|
||||
department: 'Medicine',
|
||||
inferred: false,
|
||||
licence: 'pro_plus',
|
||||
institution: institutionNonSSO
|
||||
}
|
||||
]
|
||||
it('should flag inReconfirmNotificationPeriod for all affiliations in period', function(done) {
|
||||
const user = {
|
||||
_id: '12390i',
|
||||
email: email1,
|
||||
emails: [
|
||||
{
|
||||
email: email1,
|
||||
reversedHostname: 'moc.noitailiffa-elpmaxe',
|
||||
confirmedAt: moment()
|
||||
.subtract(
|
||||
institutionNonSSO.maxConfirmationMonths + 2,
|
||||
'months'
|
||||
)
|
||||
.toDate(),
|
||||
default: true
|
||||
},
|
||||
{
|
||||
email: email2,
|
||||
reversedHostname: 'moc.noitailiffa-elpmaxe',
|
||||
confirmedAt: moment()
|
||||
.subtract(
|
||||
institutionNonSSO.maxConfirmationMonths + 1,
|
||||
'months'
|
||||
)
|
||||
.toDate()
|
||||
}
|
||||
]
|
||||
}
|
||||
this.getUserAffiliations.resolves(affiliationsData)
|
||||
this.UserGetter.promises.getUser = sinon.stub().resolves(user)
|
||||
this.UserGetter.getUserFullEmails(
|
||||
this.fakeUser._id,
|
||||
(error, fullEmails) => {
|
||||
expect(error).to.not.exist
|
||||
expect(
|
||||
fullEmails[0].affiliation.inReconfirmNotificationPeriod
|
||||
).to.equal(true)
|
||||
expect(
|
||||
fullEmails[1].affiliation.inReconfirmNotificationPeriod
|
||||
).to.equal(true)
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
it('should not flag affiliations outside of notification period', function(done) {
|
||||
const aboutToBeWithinPeriod = moment()
|
||||
.subtract(institutionNonSSO.maxConfirmationMonths, 'months')
|
||||
.add(15, 'days')
|
||||
.toDate() // expires in 15 days
|
||||
const user = {
|
||||
_id: '12390i',
|
||||
email: email1,
|
||||
emails: [
|
||||
{
|
||||
email: email1,
|
||||
reversedHostname: 'moc.noitailiffa-elpmaxe',
|
||||
confirmedAt: new Date(),
|
||||
default: true
|
||||
},
|
||||
{
|
||||
email: email2,
|
||||
reversedHostname: 'moc.noitailiffa-elpmaxe',
|
||||
confirmedAt: aboutToBeWithinPeriod
|
||||
}
|
||||
]
|
||||
}
|
||||
this.getUserAffiliations.resolves(affiliationsData)
|
||||
this.UserGetter.promises.getUser = sinon.stub().resolves(user)
|
||||
this.UserGetter.getUserFullEmails(
|
||||
this.fakeUser._id,
|
||||
(error, fullEmails) => {
|
||||
expect(error).to.not.exist
|
||||
expect(
|
||||
fullEmails[0].affiliation.inReconfirmNotificationPeriod
|
||||
).to.equal(false)
|
||||
expect(
|
||||
fullEmails[1].affiliation.inReconfirmNotificationPeriod
|
||||
).to.equal(false)
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('SSO institutions', function() {
|
||||
it('should flag only linked email, if in notification period', function(done) {
|
||||
const email1 = 'email1@sso.bar'
|
||||
const email2 = 'email2@sso.bar'
|
||||
const email3 = 'email3@sso.bar'
|
||||
|
||||
const affiliationsData = [
|
||||
{
|
||||
email: email1,
|
||||
role: 'Prof',
|
||||
department: 'Maths',
|
||||
inferred: false,
|
||||
licence: 'pro_plus',
|
||||
institution: institutionSSO
|
||||
},
|
||||
{
|
||||
email: email2,
|
||||
role: 'Prof',
|
||||
department: 'Maths',
|
||||
inferred: false,
|
||||
licence: 'pro_plus',
|
||||
institution: institutionSSO
|
||||
},
|
||||
{
|
||||
email: email3,
|
||||
role: 'Prof',
|
||||
department: 'Maths',
|
||||
inferred: false,
|
||||
licence: 'pro_plus',
|
||||
institution: institutionSSO
|
||||
}
|
||||
]
|
||||
|
||||
const user = {
|
||||
_id: '12390i',
|
||||
email: email1,
|
||||
emails: [
|
||||
{
|
||||
email: email1,
|
||||
reversedHostname: 'rab.oss',
|
||||
confirmedAt: new Date('2019-09-24'),
|
||||
reconfirmedAt: new Date('2019-09-24'),
|
||||
default: true
|
||||
},
|
||||
{
|
||||
email: email2,
|
||||
reversedHostname: 'rab.oss',
|
||||
confirmedAt: new Date('2019-09-24'),
|
||||
reconfirmedAt: new Date('2019-09-24'),
|
||||
samlProviderId: institutionSSO.id
|
||||
},
|
||||
{
|
||||
email: email3,
|
||||
reversedHostname: 'rab.oss',
|
||||
confirmedAt: new Date('2019-09-24'),
|
||||
reconfirmedAt: new Date('2019-09-24')
|
||||
}
|
||||
],
|
||||
samlIdentifiers: [
|
||||
{
|
||||
providerId: institutionSSO.id,
|
||||
externalUserId: 'abc123'
|
||||
}
|
||||
]
|
||||
}
|
||||
this.getUserAffiliations.resolves(affiliationsData)
|
||||
this.UserGetter.promises.getUser = sinon.stub().resolves(user)
|
||||
this.UserGetter.getUserFullEmails(
|
||||
this.fakeUser._id,
|
||||
(error, fullEmails) => {
|
||||
expect(error).to.not.exist
|
||||
expect(
|
||||
fullEmails[0].affiliation.inReconfirmNotificationPeriod
|
||||
).to.equal(false)
|
||||
expect(
|
||||
fullEmails[1].affiliation.inReconfirmNotificationPeriod
|
||||
).to.equal(true)
|
||||
expect(
|
||||
fullEmails[2].affiliation.inReconfirmNotificationPeriod
|
||||
).to.equal(false)
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('multiple institution affiliations', function() {
|
||||
it('should flag each institution', function(done) {
|
||||
const email1 = 'email1@sso.bar'
|
||||
const email2 = 'email2@sso.bar'
|
||||
const email3 = 'email3@foo.bar'
|
||||
const email4 = 'email4@foo.bar'
|
||||
|
||||
const affiliationsData = [
|
||||
{
|
||||
email: email1,
|
||||
role: 'Prof',
|
||||
department: 'Maths',
|
||||
inferred: false,
|
||||
licence: 'pro_plus',
|
||||
institution: institutionSSO
|
||||
},
|
||||
{
|
||||
email: email2,
|
||||
role: 'Prof',
|
||||
department: 'Maths',
|
||||
inferred: false,
|
||||
licence: 'pro_plus',
|
||||
institution: institutionSSO
|
||||
},
|
||||
{
|
||||
email: email3,
|
||||
role: 'Prof',
|
||||
department: 'Maths',
|
||||
inferred: false,
|
||||
licence: 'pro_plus',
|
||||
institution: institutionNonSSO
|
||||
},
|
||||
{
|
||||
email: email4,
|
||||
role: 'Prof',
|
||||
department: 'Maths',
|
||||
inferred: false,
|
||||
licence: 'pro_plus',
|
||||
institution: institutionNonSSO
|
||||
}
|
||||
]
|
||||
const user = {
|
||||
_id: '12390i',
|
||||
email: email1,
|
||||
emails: [
|
||||
{
|
||||
email: email1,
|
||||
reversedHostname: 'rab.oss',
|
||||
confirmedAt: '2019-09-24T20:25:08.503Z',
|
||||
default: true
|
||||
},
|
||||
{
|
||||
email: email2,
|
||||
reversedHostname: 'rab.oss',
|
||||
confirmedAt: new Date('2019-09-24T20:25:08.503Z'),
|
||||
samlProviderId: institutionSSO.id
|
||||
},
|
||||
{
|
||||
email: email3,
|
||||
reversedHostname: 'rab.oof',
|
||||
confirmedAt: new Date('2019-10-24T20:25:08.503Z')
|
||||
},
|
||||
{
|
||||
email: email4,
|
||||
reversedHostname: 'rab.oof',
|
||||
confirmedAt: new Date('2019-09-24T20:25:08.503Z')
|
||||
}
|
||||
],
|
||||
samlIdentifiers: [
|
||||
{
|
||||
providerId: institutionSSO.id,
|
||||
externalUserId: 'abc123'
|
||||
}
|
||||
]
|
||||
}
|
||||
this.getUserAffiliations.resolves(affiliationsData)
|
||||
this.UserGetter.promises.getUser = sinon.stub().resolves(user)
|
||||
this.UserGetter.getUserFullEmails(
|
||||
this.fakeUser._id,
|
||||
(error, fullEmails) => {
|
||||
expect(error).to.not.exist
|
||||
expect(
|
||||
fullEmails[0].affiliation.inReconfirmNotificationPeriod
|
||||
).to.to.equal(false)
|
||||
expect(
|
||||
fullEmails[1].affiliation.inReconfirmNotificationPeriod
|
||||
).to.equal(true)
|
||||
expect(
|
||||
fullEmails[2].affiliation.inReconfirmNotificationPeriod
|
||||
).to.equal(true)
|
||||
expect(
|
||||
fullEmails[3].affiliation.inReconfirmNotificationPeriod
|
||||
).to.equal(true)
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('reconfirmedAt', function() {
|
||||
it('only use confirmedAt when no reconfirmedAt', function(done) {
|
||||
const email1 = 'email1@foo.bar'
|
||||
const email2 = 'email2@foo.bar'
|
||||
const email3 = 'email3@foo.bar'
|
||||
|
||||
const affiliationsData = [
|
||||
{
|
||||
email: email1,
|
||||
role: 'Prof',
|
||||
department: 'Maths',
|
||||
inferred: false,
|
||||
licence: 'pro_plus',
|
||||
institution: institutionNonSSO
|
||||
},
|
||||
{
|
||||
email: email2,
|
||||
role: 'Prof',
|
||||
department: 'Maths',
|
||||
inferred: false,
|
||||
licence: 'pro_plus',
|
||||
institution: institutionNonSSO
|
||||
},
|
||||
{
|
||||
email: email3,
|
||||
role: 'Prof',
|
||||
department: 'Maths',
|
||||
inferred: false,
|
||||
licence: 'pro_plus',
|
||||
institution: institutionNonSSO
|
||||
}
|
||||
]
|
||||
const user = {
|
||||
_id: '12390i',
|
||||
email: email1,
|
||||
emails: [
|
||||
{
|
||||
email: email1,
|
||||
reversedHostname: 'rab.oof',
|
||||
confirmedAt: moment().subtract(
|
||||
institutionSSO.maxConfirmationMonths * 2,
|
||||
'months'
|
||||
),
|
||||
reconfirmedAt: moment().subtract(
|
||||
institutionSSO.maxConfirmationMonths * 3,
|
||||
'months'
|
||||
),
|
||||
default: true
|
||||
},
|
||||
{
|
||||
email: email2,
|
||||
reversedHostname: 'rab.oof',
|
||||
confirmedAt: moment().subtract(
|
||||
institutionSSO.maxConfirmationMonths * 3,
|
||||
'months'
|
||||
),
|
||||
reconfirmedAt: moment().subtract(
|
||||
institutionSSO.maxConfirmationMonths * 2,
|
||||
'months'
|
||||
)
|
||||
},
|
||||
{
|
||||
email: email3,
|
||||
reversedHostname: 'rab.oof',
|
||||
confirmedAt: moment().subtract(
|
||||
institutionSSO.maxConfirmationMonths * 4,
|
||||
'months'
|
||||
),
|
||||
reconfirmedAt: moment().subtract(
|
||||
institutionSSO.maxConfirmationMonths * 4,
|
||||
'months'
|
||||
)
|
||||
}
|
||||
]
|
||||
}
|
||||
this.getUserAffiliations.resolves(affiliationsData)
|
||||
this.UserGetter.promises.getUser = sinon.stub().resolves(user)
|
||||
this.UserGetter.getUserFullEmails(
|
||||
this.fakeUser._id,
|
||||
(error, fullEmails) => {
|
||||
expect(error).to.not.exist
|
||||
expect(
|
||||
fullEmails[0].affiliation.inReconfirmNotificationPeriod
|
||||
).to.equal(true)
|
||||
expect(
|
||||
fullEmails[1].affiliation.inReconfirmNotificationPeriod
|
||||
).to.equal(true)
|
||||
expect(
|
||||
fullEmails[2].affiliation.inReconfirmNotificationPeriod
|
||||
).to.equal(true)
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('before reconfirmation period expires and within reconfirmation notification period', function() {
|
||||
const email = 'leonard@example-affiliation.com'
|
||||
it('should flag the email', function(done) {
|
||||
const confirmedAt = moment()
|
||||
.subtract(institutionNonSSO.maxConfirmationMonths, 'months')
|
||||
.subtract(14, 'days')
|
||||
.toDate() // expires in 14 days
|
||||
const affiliationsData = [
|
||||
{
|
||||
email,
|
||||
role: 'Prof',
|
||||
department: 'Medicine',
|
||||
inferred: false,
|
||||
licence: 'pro_plus',
|
||||
institution: institutionNonSSO
|
||||
}
|
||||
]
|
||||
const user = {
|
||||
_id: '12390i',
|
||||
email,
|
||||
emails: [
|
||||
{
|
||||
email,
|
||||
confirmedAt,
|
||||
default: true
|
||||
}
|
||||
]
|
||||
}
|
||||
this.getUserAffiliations.resolves(affiliationsData)
|
||||
this.UserGetter.promises.getUser = sinon.stub().resolves(user)
|
||||
this.UserGetter.getUserFullEmails(
|
||||
this.fakeUser._id,
|
||||
(error, fullEmails) => {
|
||||
expect(error).to.not.exist
|
||||
expect(
|
||||
fullEmails[0].affiliation.inReconfirmNotificationPeriod
|
||||
).to.equal(true)
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when no Settings.reconfirmNotificationDays', function() {
|
||||
it('should always return inReconfirmNotificationPeriod:false', function(done) {
|
||||
const email1 = 'email1@sso.bar'
|
||||
const email2 = 'email2@foo.bar'
|
||||
const email3 = 'email3@foo.bar'
|
||||
const confirmedAtAboutToExpire = moment()
|
||||
.subtract(institutionNonSSO.maxConfirmationMonths, 'months')
|
||||
.subtract(14, 'days')
|
||||
.toDate() // expires in 14 days
|
||||
|
||||
const affiliationsData = [
|
||||
{
|
||||
email: email1,
|
||||
institution: institutionSSO
|
||||
},
|
||||
{
|
||||
email: email2,
|
||||
institution: institutionNonSSO
|
||||
},
|
||||
{
|
||||
email: email3,
|
||||
institution: institutionNonSSO
|
||||
}
|
||||
]
|
||||
const user = {
|
||||
_id: '12390i',
|
||||
email: email1,
|
||||
emails: [
|
||||
{
|
||||
email: email1,
|
||||
confirmedAt: confirmedAtAboutToExpire,
|
||||
default: true,
|
||||
samlProviderId: institutionSSO.id
|
||||
},
|
||||
{
|
||||
email: email2,
|
||||
confirmedAt: new Date('2019-09-24T20:25:08.503Z')
|
||||
},
|
||||
{
|
||||
email: email3,
|
||||
confirmedAt: new Date('2019-10-24T20:25:08.503Z')
|
||||
}
|
||||
],
|
||||
samlIdentifiers: [
|
||||
{
|
||||
providerId: institutionSSO.id,
|
||||
externalUserId: 'abc123'
|
||||
}
|
||||
]
|
||||
}
|
||||
this.settings.reconfirmNotificationDays = undefined
|
||||
this.getUserAffiliations.resolves(affiliationsData)
|
||||
this.UserGetter.promises.getUser = sinon.stub().resolves(user)
|
||||
this.UserGetter.getUserFullEmails(
|
||||
this.fakeUser._id,
|
||||
(error, fullEmails) => {
|
||||
expect(error).to.not.exist
|
||||
expect(
|
||||
fullEmails[0].affiliation.inReconfirmNotificationPeriod
|
||||
).to.to.equal(false)
|
||||
expect(
|
||||
fullEmails[1].affiliation.inReconfirmNotificationPeriod
|
||||
).to.equal(false)
|
||||
expect(
|
||||
fullEmails[2].affiliation.inReconfirmNotificationPeriod
|
||||
).to.equal(false)
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('getUserbyMainEmail', function() {
|
||||
|
||||
Reference in New Issue
Block a user