From 2015777fd1f872deaac8030dc8fec2f7af398b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 17 Feb 2026 19:07:28 -0500 Subject: [PATCH] fix: when registering through an invite, prepopulate the email field on /register/complete with the email --- src/controllers/authentication.js | 10 +++++++--- src/controllers/index.js | 1 + src/user/interstitials.js | 2 ++ src/user/invite.js | 11 +++++++---- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/controllers/authentication.js b/src/controllers/authentication.js index f948e053b5..3c5b337801 100644 --- a/src/controllers/authentication.js +++ b/src/controllers/authentication.js @@ -32,12 +32,12 @@ async function registerAndLoginUser(req, res, userData) { if (deferRegistration) { userData.register = true; req.session.registration = userData; - + const next = `${nconf.get('relative_path')}/register/complete`; if (req.body?.noscript === 'true') { - res.redirect(`${nconf.get('relative_path')}/register/complete`); + res.redirect(next); return; } - res.json({ next: `${nconf.get('relative_path')}/register/complete` }); + res.json({ next }); return; } @@ -71,6 +71,7 @@ async function registerAndLoginUser(req, res, userData) { return complete; } +// POST /register authenticationController.register = async function (req, res) { const registrationType = meta.config.registrationType || 'normal'; @@ -109,6 +110,7 @@ authenticationController.register = async function (req, res) { } }; +// POST /register/complete authenticationController.registerComplete = async function (req, res) { try { // For the interstitials that respond, execute the callback with the form body @@ -185,6 +187,7 @@ authenticationController.registerComplete = async function (req, res) { } }; +// POST /register/abort authenticationController.registerAbort = async (req, res) => { if (req.uid && req.session.registration) { // Email is the only cancelable interstitial @@ -204,6 +207,7 @@ authenticationController.registerAbort = async (req, res) => { }); }; +// POST /login authenticationController.login = async (req, res, next) => { let { strategy } = await plugins.hooks.fire('filter:login.override', { req, strategy: 'local' }); if (!passport._strategy(strategy)) { diff --git a/src/controllers/index.js b/src/controllers/index.js index 879774c17f..0336db8d1d 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -192,6 +192,7 @@ Controllers.register = async function (req, res, next) { } }; +// GET /register/complete Controllers.registerInterstitial = async function (req, res, next) { if (!req.session.hasOwnProperty('registration')) { return res.redirect(`${nconf.get('relative_path')}/register`); diff --git a/src/user/interstitials.js b/src/user/interstitials.js index 672af70d80..1558899497 100644 --- a/src/user/interstitials.js +++ b/src/user/interstitials.js @@ -36,6 +36,8 @@ Interstitials.email = async (data) => { let email; if (data.userData.uid) { email = await user.getUserField(data.userData.uid, 'email'); + } else if (data.userData.token) { + email = await user.getEmailFromToken(data.userData.token); } data.interstitials.push({ diff --git a/src/user/invite.js b/src/user/invite.js index 344e09fd6b..fd308af56c 100644 --- a/src/user/invite.js +++ b/src/user/invite.js @@ -78,6 +78,11 @@ module.exports = function (User) { return email && email === enteredEmail; }; + User.getEmailFromToken = async function (token) { + if (!token) return null; + return await db.getObjectField(`invitation:token:${token}`, 'email'); + }; + User.confirmIfInviteEmailIsUsed = async function (token, enteredEmail, uid) { if (!enteredEmail) { return; @@ -100,11 +105,9 @@ module.exports = function (User) { return; } - if (!groupsToJoin || groupsToJoin.length < 1) { - return; + if (Array.isArray(groupsToJoin) && groupsToJoin.length) { + await groups.join(groupsToJoin, uid); } - - await groups.join(groupsToJoin, uid); }; User.deleteInvitation = async function (invitedBy, email) {