Merge pull request #18320 from overleaf/dp-add-secondary-prompt-ui

Add secondary email form V2 (with Captcha this time)

GitOrigin-RevId: b06216a2c9cb5b3b09305a17992eca506a0047f5
This commit is contained in:
David
2024-05-27 10:22:40 +00:00
committed by Copybot
parent 5aea030184
commit 635aae7b1f
22 changed files with 837 additions and 59 deletions
@@ -18,7 +18,7 @@ describe('Add secondary email address confirmation code email', function () {
}
beforeEach(async function () {
if (!Features.hasFeature('affiliations')) {
if (!Features.hasFeature('saas')) {
this.skip()
}
@@ -39,16 +39,15 @@ describe('Add secondary email address confirmation code email', function () {
})
afterEach(function () {
if (!Features.hasFeature('affiliations')) {
if (!Features.hasFeature('saas')) {
this.skip()
}
spy.restore()
})
it('should redirect to confirm secondary email page', function () {
it('should send email with confirmation code', function () {
expect(res.response.statusCode).to.equal(200)
expect(res.body.redir).to.equal('/user/emails/confirm-secondary')
expect(confirmCode.length).to.equal(6)
})
@@ -2,9 +2,16 @@ const UserHelper = require('./helpers/UserHelper')
const Settings = require('@overleaf/settings')
const { expect } = require('chai')
const Features = require('../../../app/src/infrastructure/Features')
const MockV1ApiClass = require('./mocks/MockV1Api')
const Subscription = require('./helpers/Subscription').promises
describe('PrimaryEmailCheck', function () {
let userHelper
let MockV1Api
before(function () {
MockV1Api = MockV1ApiClass.instance()
})
beforeEach(async function () {
userHelper = await UserHelper.createUser()
@@ -200,18 +207,109 @@ describe('PrimaryEmailCheck', function () {
await UserHelper.updateUser(userHelper.user._id, {
$set: { lastPrimaryEmailCheck: new Date(time) },
})
checkResponse = await userHelper.fetch(
'/user/emails/primary-email-check',
{ method: 'POST' }
)
})
it('should be redirected to the project list page', function () {
expect(checkResponse.status).to.equal(302)
expect(checkResponse.headers.get('location')).to.equal(
UserHelper.url('/project').toString()
)
describe('when the user has a secondary email address', function () {
before(async function () {
if (!Features.hasFeature('saas')) {
this.skip()
}
})
beforeEach(async function () {
await userHelper.confirmEmail(
userHelper.user._id,
userHelper.user.email
)
await userHelper.addEmailAndConfirm(
userHelper.user._id,
'secondary@overleaf.com'
)
checkResponse = await userHelper.fetch(
'/user/emails/primary-email-check',
{ method: 'POST' }
)
})
it('should be redirected to the project list page', function () {
expect(checkResponse.status).to.equal(302)
expect(checkResponse.headers.get('location')).to.equal(
UserHelper.url('/project').toString()
)
})
})
describe('when the user has an institutional email and no secondary', function () {
before(async function () {
if (!Features.hasFeature('saas')) {
this.skip()
}
if (!Features.hasFeature('saml')) {
this.skip()
}
})
beforeEach(async function () {
MockV1Api.createInstitution({
name: 'Exampe Institution',
hostname: 'example.com',
licence: 'pro_plus',
confirmed: true,
})
MockV1Api.addAffiliation(userHelper.user._id, userHelper.user.email)
})
it('should be redirected to the add secondary email page', async function () {
const response = await userHelper.fetch(
'/user/emails/primary-email-check',
{ method: 'POST' }
)
expect(response.status).to.equal(302)
expect(response.headers.get('location')).to.equal(
UserHelper.url('/user/emails/add-secondary').toString()
)
})
})
describe('when the user is a managed user', function () {
beforeEach(async function () {
const adminUser = await UserHelper.createUser()
this.subscription = new Subscription({
adminId: adminUser._id,
memberIds: [userHelper.user._id],
groupPlan: true,
planCode: 'group_professional_5_enterprise',
})
await this.subscription.ensureExists()
await this.subscription.enableManagedUsers()
})
it('should be redirected to the project list page', async function () {
const response = await userHelper.fetch(
'/user/emails/primary-email-check',
{ method: 'POST' }
)
expect(response.status).to.equal(302)
expect(response.headers.get('location')).to.equal(
UserHelper.url('/project').toString()
)
})
})
})
describe('when user has checked their primary email address', function () {
beforeEach(async function () {
const time = Date.now() - Settings.primary_email_check_expiration * 2
await UserHelper.updateUser(userHelper.user._id, {
$set: { lastPrimaryEmailCheck: new Date(time) },
})
await userHelper.fetch('/user/emails/primary-email-check', {
method: 'POST',
})
})
it("shouldn't be redirected from project list to the primary email check page any longer", async function () {
@@ -301,8 +301,8 @@ describe('UserEmailsController', function () {
it('sends an email confirmation', function (done) {
this.UserEmailsController.addWithConfirmationCode(this.req, {
json: ({ redir }) => {
redir.should.equal('/user/emails/confirm-secondary')
sendStatus: code => {
code.should.equal(200)
assertCalledWith(
this.UserEmailsConfirmationHandler.promises.sendConfirmationCode,
this.newEmail,
@@ -1008,6 +1008,45 @@ describe('UserGetter', function () {
})
})
describe('getUserConfirmedEmails', function () {
beforeEach(function () {
this.fakeUser = {
emails: [
{
email: 'email1@foo.bar',
reversedHostname: 'rab.oof',
confirmedAt: new Date(),
},
{ email: 'email2@foo.bar', reversedHostname: 'rab.oof' },
{
email: 'email3@foo.bar',
reversedHostname: 'rab.oof',
confirmedAt: new Date(),
},
],
}
this.UserGetter.promises.getUser = sinon.stub().resolves(this.fakeUser)
})
it('should get user', async function () {
const projection = { emails: 1 }
await this.UserGetter.promises.getUserConfirmedEmails(this.fakeUser._id)
this.UserGetter.promises.getUser
.calledWith(this.fakeUser._id, projection)
.should.equal(true)
})
it('should return only confirmed emails', async function () {
const confirmedEmails =
await this.UserGetter.promises.getUserConfirmedEmails(this.fakeUser._id)
expect(confirmedEmails.length).to.equal(2)
expect(confirmedEmails[0].email).to.equal('email1@foo.bar')
expect(confirmedEmails[1].email).to.equal('email3@foo.bar')
})
})
describe('getUserbyMainEmail', function () {
it('query user by main email', function (done) {
const email = 'hello@world.com'