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:
@@ -17,7 +17,9 @@ const AnalyticsManager = require('../Analytics/AnalyticsManager')
|
||||
const UserPrimaryEmailCheckHandler = require('../User/UserPrimaryEmailCheckHandler')
|
||||
const UserAuditLogHandler = require('./UserAuditLogHandler')
|
||||
const { RateLimiter } = require('../../infrastructure/RateLimiter')
|
||||
const Features = require('../../infrastructure/Features')
|
||||
const tsscmp = require('tsscmp')
|
||||
const Modules = require('../../infrastructure/Modules')
|
||||
|
||||
const AUDIT_LOG_TOKEN_PREFIX_LENGTH = 10
|
||||
|
||||
@@ -208,9 +210,7 @@ async function addWithConfirmationCode(req, res) {
|
||||
confirmCodeExpiresTimestamp,
|
||||
}
|
||||
|
||||
return res.json({
|
||||
redir: '/user/emails/confirm-secondary',
|
||||
})
|
||||
return res.sendStatus(200)
|
||||
} catch (err) {
|
||||
if (err.name === 'EmailExistsError') {
|
||||
return res.status(409).json({
|
||||
@@ -418,6 +418,45 @@ async function resendSecondaryEmailConfirmationCode(req, res) {
|
||||
}
|
||||
}
|
||||
|
||||
async function confirmSecondaryEmailPage(req, res) {
|
||||
const userId = SessionManager.getLoggedInUserId(req.session)
|
||||
|
||||
if (!req.session.pendingSecondaryEmail) {
|
||||
const redirectURL =
|
||||
AuthenticationController.getRedirectFromSession(req) || '/project'
|
||||
return res.redirect(redirectURL)
|
||||
}
|
||||
|
||||
AnalyticsManager.recordEventForUser(
|
||||
userId,
|
||||
'confirm-secondary-email-page-displayed'
|
||||
)
|
||||
|
||||
res.render('user/confirmSecondaryEmail', {
|
||||
email: req.session.pendingSecondaryEmail.email,
|
||||
})
|
||||
}
|
||||
|
||||
async function addSecondaryEmailPage(req, res) {
|
||||
const userId = SessionManager.getLoggedInUserId(req.session)
|
||||
|
||||
const confirmedEmails =
|
||||
await UserGetter.promises.getUserConfirmedEmails(userId)
|
||||
|
||||
if (confirmedEmails.length >= 2) {
|
||||
const redirectURL =
|
||||
AuthenticationController.getRedirectFromSession(req) || '/project'
|
||||
return res.redirect(redirectURL)
|
||||
}
|
||||
|
||||
AnalyticsManager.recordEventForUser(
|
||||
userId,
|
||||
'add-secondary-email-page-displayed'
|
||||
)
|
||||
|
||||
res.render('user/addSecondaryEmail')
|
||||
}
|
||||
|
||||
async function primaryEmailCheckPage(req, res) {
|
||||
const userId = SessionManager.getLoggedInUserId(req.session)
|
||||
const user = await UserGetter.promises.getUser(userId, {
|
||||
@@ -443,10 +482,35 @@ async function primaryEmailCheck(req, res) {
|
||||
await UserUpdater.promises.updateUser(userId, {
|
||||
$set: { lastPrimaryEmailCheck: new Date() },
|
||||
})
|
||||
|
||||
AnalyticsManager.recordEventForUserInBackground(
|
||||
userId,
|
||||
'primary-email-check-done'
|
||||
)
|
||||
|
||||
// We want to redirect to prompt a user to add a secondary email if their primary
|
||||
// is an institutional email and they dont' already have a secondary.
|
||||
if (Features.hasFeature('saas') && req.capabilitySet.has('add-affiliation')) {
|
||||
const confirmedEmails =
|
||||
await UserGetter.promises.getUserConfirmedEmails(userId)
|
||||
|
||||
if (confirmedEmails.length < 2) {
|
||||
const { email: primaryEmail } = SessionManager.getSessionUser(req.session)
|
||||
const primaryEmailDomain = EmailHelper.getDomain(primaryEmail)
|
||||
|
||||
const institution = (
|
||||
await Modules.promises.hooks.fire(
|
||||
'getInstitutionViaDomain',
|
||||
primaryEmailDomain
|
||||
)
|
||||
)?.[0]
|
||||
|
||||
if (institution) {
|
||||
return AsyncFormHelper.redirect(req, res, '/user/emails/add-secondary')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AsyncFormHelper.redirect(req, res, '/project')
|
||||
}
|
||||
|
||||
@@ -558,6 +622,10 @@ const UserEmailsController = {
|
||||
|
||||
sendReconfirmation,
|
||||
|
||||
addSecondaryEmailPage: expressify(addSecondaryEmailPage),
|
||||
|
||||
confirmSecondaryEmailPage: expressify(confirmSecondaryEmailPage),
|
||||
|
||||
primaryEmailCheckPage: expressify(primaryEmailCheckPage),
|
||||
|
||||
primaryEmailCheck: expressify(primaryEmailCheck),
|
||||
|
||||
@@ -79,6 +79,18 @@ async function getUserFullEmails(userId) {
|
||||
)
|
||||
}
|
||||
|
||||
async function getUserConfirmedEmails(userId) {
|
||||
const user = await UserGetter.promises.getUser(userId, {
|
||||
emails: 1,
|
||||
})
|
||||
|
||||
if (!user) {
|
||||
throw new Error('User not Found')
|
||||
}
|
||||
|
||||
return user.emails.filter(email => !!email.confirmedAt)
|
||||
}
|
||||
|
||||
async function getSsoUsersAtInstitution(institutionId, projection) {
|
||||
if (!projection) {
|
||||
throw new Error('missing projection')
|
||||
@@ -124,6 +136,8 @@ const UserGetter = {
|
||||
|
||||
getUserFullEmails: callbackify(getUserFullEmails),
|
||||
|
||||
getUserConfirmedEmails: callbackify(getUserConfirmedEmails),
|
||||
|
||||
getUserByMainEmail(email, projection, callback) {
|
||||
email = email.trim()
|
||||
if (arguments.length === 2) {
|
||||
|
||||
@@ -336,6 +336,7 @@ function initialize(webRouter, privateApiRouter, publicApiRouter) {
|
||||
webRouter.post(
|
||||
'/user/emails/primary-email-check',
|
||||
AuthenticationController.requireLogin(),
|
||||
PermissionsController.useCapabilities(),
|
||||
UserEmailsController.primaryEmailCheck
|
||||
)
|
||||
|
||||
@@ -348,6 +349,7 @@ function initialize(webRouter, privateApiRouter, publicApiRouter) {
|
||||
CaptchaMiddleware.validateCaptcha('addEmail'),
|
||||
UserEmailsController.add
|
||||
)
|
||||
|
||||
webRouter.post(
|
||||
'/user/emails/delete',
|
||||
AuthenticationController.requireLogin(),
|
||||
@@ -366,29 +368,21 @@ function initialize(webRouter, privateApiRouter, publicApiRouter) {
|
||||
RateLimiterMiddleware.rateLimit(rateLimiters.endorseEmail),
|
||||
UserEmailsController.endorse
|
||||
)
|
||||
}
|
||||
|
||||
webRouter.post(
|
||||
'/user/emails/secondary',
|
||||
if (Features.hasFeature('saas')) {
|
||||
webRouter.get(
|
||||
'/user/emails/add-secondary',
|
||||
AuthenticationController.requireLogin(),
|
||||
PermissionsController.requirePermission('add-secondary-email'),
|
||||
RateLimiterMiddleware.rateLimit(rateLimiters.addEmail),
|
||||
UserEmailsController.addWithConfirmationCode
|
||||
UserEmailsController.addSecondaryEmailPage
|
||||
)
|
||||
|
||||
webRouter.post(
|
||||
webRouter.get(
|
||||
'/user/emails/confirm-secondary',
|
||||
AuthenticationController.requireLogin(),
|
||||
PermissionsController.requirePermission('add-secondary-email'),
|
||||
RateLimiterMiddleware.rateLimit(rateLimiters.checkEmailConfirmationCode),
|
||||
UserEmailsController.checkSecondaryEmailConfirmationCode
|
||||
)
|
||||
|
||||
webRouter.post(
|
||||
'/user/emails/resend-secondary-confirmation',
|
||||
AuthenticationController.requireLogin(),
|
||||
PermissionsController.requirePermission('add-secondary-email'),
|
||||
RateLimiterMiddleware.rateLimit(rateLimiters.resendConfirmationCode),
|
||||
UserEmailsController.resendSecondaryEmailConfirmationCode
|
||||
UserEmailsController.confirmSecondaryEmailPage
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user