Skip to content

Commit

Permalink
fix: #11808, reduce zeal of middleware.registrationComplete
Browse files Browse the repository at this point in the history
Now will judiciously check whether the target category or topic is restricted to verified users before redirecting unverified users to the email confirmation interstitial
  • Loading branch information
julianlam committed Sep 26, 2023
1 parent e0b29ba commit 74902e4
Showing 1 changed file with 47 additions and 12 deletions.
59 changes: 47 additions & 12 deletions src/middleware/user.js
Expand Up @@ -8,7 +8,10 @@ const util = require('util');

const meta = require('../meta');
const user = require('../user');
const groups = require('../groups');
const topics = require('../topics');
const privileges = require('../privileges');
const privilegeHelpers = require('../privileges/helpers');
const plugins = require('../plugins');
const helpers = require('./helpers');
const auth = require('../routes/authentication');
Expand Down Expand Up @@ -239,18 +242,12 @@ module.exports = function (middleware) {
*/
const path = req.path.startsWith('/api/') ? req.path.replace('/api', '') : req.path;

if (req.uid > 0 && !(path.endsWith('/edit/email') || path.startsWith('/confirm/'))) {
const [confirmed, isAdmin] = await Promise.all([
user.getUserField(req.uid, 'email:confirmed'),
user.isAdministrator(req.uid),
]);
if (meta.config.requireEmailAddress && !confirmed && !isAdmin) {
req.session.registration = {
...req.session.registration,
uid: req.uid,
updateEmail: true,
};
}
if (meta.config.requireEmailAddress && await requiresEmailConfirmation(req)) {
req.session.registration = {
...req.session.registration,
uid: req.uid,
updateEmail: true,
};
}

if (!req.session.hasOwnProperty('registration')) {
Expand All @@ -269,4 +266,42 @@ module.exports = function (middleware) {

controllers.helpers.redirect(res, '/register/complete');
};

async function requiresEmailConfirmation(req) {
/**
* N.B. THIS IS NOT AN AUTHENTICATION MECHANISM
*
* It merely decides whether or not the accessed category is restricted to
* verified users only, and renders a decision (Boolean) based on whether
* the calling user is verified or not.
*/
if (req.uid <= 0) {
return false;
}

// Extract tid or cid
const [confirmed, isAdmin] = await Promise.all([
groups.isMember(req.uid, 'verified-users'),
user.isAdministrator(req.uid),
]);
if (confirmed || isAdmin) {
return false;
}

let cid;
if (req.params.hasOwnProperty('category_id')) {
cid = req.params.category_id;
} else if (req.params.hasOwnProperty('topic_id')) {
cid = await topics.getTopicField(req.params.topic_id, 'cid');
} else {
return false; // not a category or topic url, no check required
}

const [registeredAllowed, verifiedAllowed] = await Promise.all([
privilegeHelpers.isAllowedTo(['read'], 'registered-users', cid),
privilegeHelpers.isAllowedTo(['read'], 'verified-users', cid),
]);

return !registeredAllowed.pop() && verifiedAllowed.pop();
}
};

0 comments on commit 74902e4

Please sign in to comment.