diff --git a/services/web/app/src/Features/Authentication/AuthenticationController.js b/services/web/app/src/Features/Authentication/AuthenticationController.js index 0df10e07159..a139611302f 100644 --- a/services/web/app/src/Features/Authentication/AuthenticationController.js +++ b/services/web/app/src/Features/Authentication/AuthenticationController.js @@ -663,8 +663,16 @@ function _loginAsyncHandlers(req, user, anonymousAnalyticsId, isNewUser) { return (user._login_req_ip = req.ip) } +AuthenticationController.createSessionForUser = function (user, req, callback) { + const anonymousAnalyticsId = req.session.analyticsId + const isNewUser = req.session.justRegistered || false + _loginAsyncHandlers(req, user, anonymousAnalyticsId, isNewUser) + _afterLoginSessionSetup(req, user, callback) +} + AuthenticationController.promises = { finishLogin: AuthenticationController._finishLoginAsync, + createSessionForUser: promisify(AuthenticationController.createSessionForUser), } module.exports = AuthenticationController diff --git a/services/web/app/src/Features/User/UserController.js b/services/web/app/src/Features/User/UserController.js index 3c1818979f0..f0e07a9721a 100644 --- a/services/web/app/src/Features/User/UserController.js +++ b/services/web/app/src/Features/User/UserController.js @@ -23,6 +23,8 @@ const { } = require('../../infrastructure/RequestContentTypeDetection') const Modules = require('../../infrastructure/Modules') const OneTimeTokenHandler = require('../Security/OneTimeTokenHandler') +const EmailHelper = require('../Helpers/EmailHelper') +const AuthenticationController = require('../Authentication/AuthenticationController') async function _sendSecurityAlertClearedSessions(user) { const emailOptions = { @@ -173,6 +175,34 @@ async function clearSessions(req, res, next) { res.sendStatus(201) } +async function createSession(req, res) { + const email = EmailHelper.parseEmail(req.body?.email) + if (!email) { + return res.status(400).json({ error: 'invalid_email' }) + } + + const user = await UserGetter.promises.getUserByAnyEmail(email) + + if (!user) { + return res.sendStatus(404) + } + + if (user.suspended) { + return res.status(403).json({ error: 'account_suspended' }) + } + + await AuthenticationController.promises.createSessionForUser(user, req) + + return res.status(201).json({ + user: { + id: user._id.toString(), + email: user.email, + first_name: user.first_name, + last_name: user.last_name, + }, + }) +} + async function ensureAffiliation(user) { if (!Features.hasFeature('affiliations')) { return @@ -500,6 +530,7 @@ async function expireDeletedUsersAfterDuration(req, res, next) { module.exports = { clearSessions: expressify(clearSessions), + createSession: expressify(createSession), changePassword: expressify(changePassword), tryDeleteUser: expressify(tryDeleteUser), subscribe: expressify(subscribe), diff --git a/services/web/app/src/router.mjs b/services/web/app/src/router.mjs index 42a041248f4..d7ef91791b8 100644 --- a/services/web/app/src/router.mjs +++ b/services/web/app/src/router.mjs @@ -496,6 +496,12 @@ async function initialize(webRouter, privateApiRouter, publicApiRouter) { UserInfoController.getPersonalInfo ) + privateApiRouter.post( + '/internal/create-user-session', + AuthenticationController.requirePrivateApiAuth(), + UserController.createSession + ) + webRouter.get( '/user/reconfirm', UserPagesController.renderReconfirmAccountPage