refactor: remove calls to getUserDataByUserSlug for most account routes, since it is populated via middleware now

This commit is contained in:
Julian Lam
2023-01-24 21:35:09 -05:00
parent 839d05bc95
commit 44ea9da022
9 changed files with 141 additions and 149 deletions

View File

@@ -7,7 +7,7 @@ const plugins = require('../../plugins');
const blocksController = module.exports;
blocksController.getBlocks = async function (req, res, next) {
blocksController.getBlocks = async function (req, res) {
const page = parseInt(req.query.page, 10) || 1;
const resultsPerPage = 50;
const start = Math.max(0, page - 1) * resultsPerPage;

View File

@@ -4,40 +4,47 @@ const user = require('../../user');
const meta = require('../../meta');
const helpers = require('../helpers');
const groups = require('../../groups');
const accountHelpers = require('./helpers');
const privileges = require('../../privileges');
const accountHelpers = require('./helpers');
const file = require('../../file');
const editController = module.exports;
editController.get = async function (req, res, next) {
const [userData, canUseSignature] = await Promise.all([
editController.get = async function (req, res) {
const [{
username,
userslug,
isSelf,
reputation,
groups: _groups,
groupTitleArray,
allowMultipleBadges,
}, canUseSignature] = await Promise.all([
accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, req.query),
privileges.global.can('signature', req.uid),
]);
if (!userData) {
return next();
}
userData.maximumSignatureLength = meta.config.maximumSignatureLength;
userData.maximumAboutMeLength = meta.config.maximumAboutMeLength;
userData.maximumProfileImageSize = meta.config.maximumProfileImageSize;
userData.allowMultipleBadges = meta.config.allowMultipleBadges === 1;
userData.allowAccountDelete = meta.config.allowAccountDelete === 1;
userData.allowWebsite = !userData.isSelf || !!meta.config['reputation:disabled'] || userData.reputation >= meta.config['min:rep:website'];
userData.allowAboutMe = !userData.isSelf || !!meta.config['reputation:disabled'] || userData.reputation >= meta.config['min:rep:aboutme'];
userData.allowSignature = canUseSignature && (!userData.isSelf || !!meta.config['reputation:disabled'] || userData.reputation >= meta.config['min:rep:signature']);
userData.profileImageDimension = meta.config.profileImageDimension;
userData.defaultAvatar = user.getDefaultAvatar();
userData.groups = userData.groups.filter(g => g && g.userTitleEnabled && !groups.isPrivilegeGroup(g.name) && g.name !== 'registered-users');
const payload = {};
payload.maximumSignatureLength = meta.config.maximumSignatureLength;
payload.maximumAboutMeLength = meta.config.maximumAboutMeLength;
payload.maximumProfileImageSize = meta.config.maximumProfileImageSize;
payload.allowMultipleBadges = meta.config.allowMultipleBadges === 1;
payload.allowAccountDelete = meta.config.allowAccountDelete === 1;
payload.allowWebsite = !isSelf || !!meta.config['reputation:disabled'] || reputation >= meta.config['min:rep:website'];
payload.allowAboutMe = !isSelf || !!meta.config['reputation:disabled'] || reputation >= meta.config['min:rep:aboutme'];
payload.allowSignature = canUseSignature && (!isSelf || !!meta.config['reputation:disabled'] || reputation >= meta.config['min:rep:signature']);
payload.profileImageDimension = meta.config.profileImageDimension;
payload.defaultAvatar = user.getDefaultAvatar();
if (!userData.allowMultipleBadges) {
userData.groupTitle = userData.groupTitleArray[0];
payload.groups = _groups.filter(g => g && g.userTitleEnabled && !groups.isPrivilegeGroup(g.name) && g.name !== 'registered-users');
if (!allowMultipleBadges) {
payload.groupTitle = groupTitleArray[0];
}
userData.groups.sort((a, b) => {
const i1 = userData.groupTitleArray.indexOf(a.name);
const i2 = userData.groupTitleArray.indexOf(b.name);
payload.groups.sort((a, b) => {
const i1 = groupTitleArray.indexOf(a.name);
const i2 = groupTitleArray.indexOf(b.name);
if (i1 === -1) {
return 1;
} else if (i2 === -1) {
@@ -45,24 +52,25 @@ editController.get = async function (req, res, next) {
}
return i1 - i2;
});
userData.groups.forEach((group) => {
payload.groups.forEach((group) => {
group.userTitle = group.userTitle || group.displayName;
group.selected = userData.groupTitleArray.includes(group.name);
group.selected = groupTitleArray.includes(group.name);
});
userData.groupSelectSize = Math.min(10, Math.max(5, userData.groups.length + 1));
payload.groupSelectSize = Math.min(10, Math.max(5, payload.groups.length + 1));
userData.title = `[[pages:account/edit, ${userData.username}]]`;
userData.breadcrumbs = helpers.buildBreadcrumbs([
payload.title = `[[pages:account/edit, ${username}]]`;
payload.breadcrumbs = helpers.buildBreadcrumbs([
{
text: userData.username,
url: `/user/${userData.userslug}`,
text: username,
url: `/user/${userslug}`,
},
{
text: '[[user:edit]]',
},
]);
userData.editButtons = [];
res.render('account/edit', userData);
payload.editButtons = [];
res.render('account/edit', payload);
};
editController.password = async function (req, res, next) {
@@ -95,46 +103,39 @@ editController.email = async function (req, res, next) {
helpers.redirect(res, '/register/complete');
};
async function renderRoute(name, req, res, next) {
const userData = await getUserData(req, next);
if (!userData) {
return next();
}
if (meta.config[`${name}:disableEdit`] && !userData.isAdmin) {
async function renderRoute(name, req, res) {
const [isAdmin, { username, userslug }, hasPassword] = await Promise.all([
privileges.admin.can('admin:users', res.locals.uid),
user.getUserFields(res.locals.uid, ['username', 'userslug']),
user.hasPassword(res.locals.uid),
]);
if (meta.config[`${name}:disableEdit`] && !isAdmin) {
return helpers.notAllowed(req, res);
}
const payload = { hasPassword };
if (name === 'password') {
userData.minimumPasswordLength = meta.config.minimumPasswordLength;
userData.minimumPasswordStrength = meta.config.minimumPasswordStrength;
payload.minimumPasswordLength = meta.config.minimumPasswordLength;
payload.minimumPasswordStrength = meta.config.minimumPasswordStrength;
}
userData.title = `[[pages:account/edit/${name}, ${userData.username}]]`;
userData.breadcrumbs = helpers.buildBreadcrumbs([
payload.title = `[[pages:account/edit/${name}, ${username}]]`;
payload.breadcrumbs = helpers.buildBreadcrumbs([
{
text: userData.username,
url: `/user/${userData.userslug}`,
text: username,
url: `/user/${userslug}`,
},
{
text: '[[user:edit]]',
url: `/user/${userData.userslug}/edit`,
url: `/user/${userslug}/edit`,
},
{
text: `[[user:${name}]]`,
},
]);
res.render(`account/edit/${name}`, userData);
}
async function getUserData(req) {
const userData = await accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, req.query);
if (!userData) {
return null;
}
userData.hasPassword = await user.hasPassword(userData.uid);
return userData;
res.render(`account/edit/${name}`, payload);
}
editController.uploadPicture = async function (req, res, next) {

View File

@@ -2,7 +2,6 @@
const user = require('../../user');
const helpers = require('../helpers');
const accountHelpers = require('./helpers');
const pagination = require('../../pagination');
const followController = module.exports;
@@ -15,27 +14,25 @@ followController.getFollowers = async function (req, res, next) {
await getFollow('account/followers', 'followers', req, res, next);
};
async function getFollow(tpl, name, req, res, next) {
const userData = await accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, req.query);
if (!userData) {
return next();
}
async function getFollow(tpl, name, req, res) {
const { username, userslug, followerCount, followingCount } = await user.getUserFields(res.locals.uid, ['username', 'userslug']);
const page = parseInt(req.query.page, 10) || 1;
const resultsPerPage = 50;
const start = Math.max(0, page - 1) * resultsPerPage;
const stop = start + resultsPerPage - 1;
userData.title = `[[pages:${tpl}, ${userData.username}]]`;
const payload = {};
payload.title = `[[pages:${tpl}, ${username}]]`;
const method = name === 'following' ? 'getFollowing' : 'getFollowers';
userData.users = await user[method](userData.uid, start, stop);
payload.users = await user[method](res.locals.uid, start, stop);
const count = name === 'following' ? userData.followingCount : userData.followerCount;
const count = name === 'following' ? followingCount : followerCount;
const pageCount = Math.ceil(count / resultsPerPage);
userData.pagination = pagination.create(page, pageCount);
payload.pagination = pagination.create(page, pageCount);
userData.breadcrumbs = helpers.buildBreadcrumbs([{ text: userData.username, url: `/user/${userData.userslug}` }, { text: `[[user:${name}]]` }]);
payload.breadcrumbs = helpers.buildBreadcrumbs([{ text: username, url: `/user/${userslug}` }, { text: `[[user:${name}]]` }]);
res.render(tpl, userData);
res.render(tpl, payload);
}

View File

@@ -1,25 +1,25 @@
'use strict';
const user = require('../../user');
const groups = require('../../groups');
const helpers = require('../helpers');
const accountHelpers = require('./helpers');
const groupsController = module.exports;
groupsController.get = async function (req, res, next) {
const userData = await accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, req.query);
if (!userData) {
return next();
}
let groupsData = await groups.getUserGroups([userData.uid]);
groupsController.get = async function (req, res) {
const { username, userslug } = await user.getUserFields(res.locals.uid, ['username', 'userslug']);
const payload = {};
let groupsData = await groups.getUserGroups([res.locals.uid]);
groupsData = groupsData[0];
const groupNames = groupsData.filter(Boolean).map(group => group.name);
const members = await groups.getMemberUsers(groupNames, 0, 3);
groupsData.forEach((group, index) => {
group.members = members[index];
});
userData.groups = groupsData;
userData.title = `[[pages:account/groups, ${userData.username}]]`;
userData.breadcrumbs = helpers.buildBreadcrumbs([{ text: userData.username, url: `/user/${userData.userslug}` }, { text: '[[global:header.groups]]' }]);
res.render('account/groups', userData);
payload.groups = groupsData;
payload.title = `[[pages:account/groups, ${username}]]`;
payload.breadcrumbs = helpers.buildBreadcrumbs([{ text: username, url: `/user/${userslug}` }, { text: '[[global:header.groups]]' }]);
res.render('account/groups', payload);
};

View File

@@ -3,52 +3,53 @@
const db = require('../../database');
const user = require('../../user');
const helpers = require('../helpers');
const accountHelpers = require('./helpers');
const pagination = require('../../pagination');
const infoController = module.exports;
infoController.get = async function (req, res, next) {
const userData = await accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, req.query);
if (!userData) {
return next();
}
infoController.get = async function (req, res) {
const page = Math.max(1, req.query.page || 1);
const itemsPerPage = 10;
const start = (page - 1) * itemsPerPage;
const stop = start + itemsPerPage - 1;
const [{ username, userslug }, isPrivileged] = await Promise.all([
user.getUserFields(res.locals.uid, ['username', 'userslug']),
user.isPrivileged(res.locals.uid),
]);
const [history, sessions, usernames, emails, notes] = await Promise.all([
user.getModerationHistory(userData.uid),
user.auth.getSessions(userData.uid, req.sessionID),
user.getHistory(`user:${userData.uid}:usernames`),
user.getHistory(`user:${userData.uid}:emails`),
getNotes(userData, start, stop),
user.getModerationHistory(res.locals.uid),
user.auth.getSessions(res.locals.uid, req.sessionID),
user.getHistory(`user:${res.locals.uid}:usernames`),
user.getHistory(`user:${res.locals.uid}:emails`),
getNotes({ uid: res.locals.uid, isPrivileged }, start, stop),
]);
userData.history = history;
userData.sessions = sessions;
userData.usernames = usernames;
userData.emails = emails;
const payload = {};
if (userData.isAdminOrGlobalModeratorOrModerator) {
userData.moderationNotes = notes.notes;
payload.history = history;
payload.sessions = sessions;
payload.usernames = usernames;
payload.emails = emails;
if (isPrivileged) {
payload.moderationNotes = notes.notes;
const pageCount = Math.ceil(notes.count / itemsPerPage);
userData.pagination = pagination.create(page, pageCount, req.query);
payload.pagination = pagination.create(page, pageCount, req.query);
}
userData.title = '[[pages:account/info]]';
userData.breadcrumbs = helpers.buildBreadcrumbs([{ text: userData.username, url: `/user/${userData.userslug}` }, { text: '[[user:account_info]]' }]);
payload.title = '[[pages:account/info]]';
payload.breadcrumbs = helpers.buildBreadcrumbs([{ text: username, url: `/user/${userslug}` }, { text: '[[user:account_info]]' }]);
res.render('account/info', userData);
res.render('account/info', payload);
};
async function getNotes(userData, start, stop) {
if (!userData.isAdminOrGlobalModeratorOrModerator) {
async function getNotes({ uid, isPrivileged }, start, stop) {
if (!isPrivileged) {
return;
}
const [notes, count] = await Promise.all([
user.getModerationNotes(userData.uid, start, stop),
db.sortedSetCard(`uid:${userData.uid}:moderation:notes`),
user.getModerationNotes(uid, start, stop),
db.sortedSetCard(`uid:${uid}:moderation:notes`),
]);
return { notes: notes, count: count };
}

View File

@@ -8,7 +8,6 @@ const categories = require('../../categories');
const privileges = require('../../privileges');
const pagination = require('../../pagination');
const helpers = require('../helpers');
const accountHelpers = require('./helpers');
const plugins = require('../../plugins');
const utils = require('../../utils');
@@ -174,28 +173,25 @@ postsController.getTopics = async function (req, res, next) {
await getPostsFromUserSet('account/topics', req, res, next);
};
async function getPostsFromUserSet(template, req, res, next) {
async function getPostsFromUserSet(template, req, res) {
const data = templateToData[template];
const page = Math.max(1, parseInt(req.query.page, 10) || 1);
const [userData, settings] = await Promise.all([
accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, req.query),
const [{ username, userslug }, settings] = await Promise.all([
user.getUserFields(res.locals.uid, ['username', 'userslug']),
user.getSettings(req.uid),
]);
if (!userData) {
return next();
}
const itemsPerPage = data.type === 'topics' ? settings.topicsPerPage : settings.postsPerPage;
const start = (page - 1) * itemsPerPage;
const stop = start + itemsPerPage - 1;
const sets = await data.getSets(req.uid, userData);
const sets = await data.getSets(req.uid, { uid: res.locals.uid, username, userslug });
let result;
if (plugins.hooks.hasListeners('filter:account.getPostsFromUserSet')) {
result = await plugins.hooks.fire('filter:account.getPostsFromUserSet', {
req: req,
template: template,
userData: userData,
userData: { uid: res.locals.uid, username, userslug },
settings: settings,
data: data,
start: start,
@@ -210,29 +206,31 @@ async function getPostsFromUserSet(template, req, res, next) {
});
}
const { itemCount, itemData } = result;
userData[data.type] = itemData[data.type];
userData.nextStart = itemData.nextStart;
const payload = {};
payload[data.type] = itemData[data.type];
payload.nextStart = itemData.nextStart;
const pageCount = Math.ceil(itemCount / itemsPerPage);
userData.pagination = pagination.create(page, pageCount, req.query);
payload.pagination = pagination.create(page, pageCount, req.query);
userData.noItemsFoundKey = data.noItemsFoundKey;
userData.title = `[[pages:${template}, ${userData.username}]]`;
userData.breadcrumbs = helpers.buildBreadcrumbs([{ text: userData.username, url: `/user/${userData.userslug}` }, { text: data.crumb }]);
userData.showSort = template === 'account/watched';
payload.noItemsFoundKey = data.noItemsFoundKey;
payload.title = `[[pages:${template}, ${username}]]`;
payload.breadcrumbs = helpers.buildBreadcrumbs([{ text: username, url: `/user/${userslug}` }, { text: data.crumb }]);
payload.showSort = template === 'account/watched';
const baseUrl = (req.baseUrl + req.path.replace(/^\/api/, ''));
userData.sortOptions = [
payload.sortOptions = [
{ url: `${baseUrl}?sort=votes`, name: '[[global:votes]]' },
{ url: `${baseUrl}?sort=posts`, name: '[[global:posts]]' },
{ url: `${baseUrl}?sort=views`, name: '[[global:views]]' },
{ url: `${baseUrl}?sort=lastpost`, name: '[[global:lastpost]]' },
{ url: `${baseUrl}?sort=firstpost`, name: '[[global:firstpost]]' },
];
userData.sortOptions.forEach((option) => {
payload.sortOptions.forEach((option) => {
option.selected = option.url.includes(`sort=${req.query.sort}`);
});
res.render(template, userData);
res.render(template, payload);
}
async function getItemData(sets, data, req, start, stop) {

View File

@@ -2,19 +2,17 @@
const user = require('../../user');
const helpers = require('../helpers');
const accountHelpers = require('./helpers');
const sessionController = module.exports;
sessionController.get = async function (req, res, next) {
const userData = await accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, req.query);
if (!userData) {
return next();
}
sessionController.get = async function (req, res) {
const { username, userslug } = await user.getUserFields(res.locals.uid, ['username', 'userslug']);
userData.sessions = await user.auth.getSessions(userData.uid, req.sessionID);
userData.title = '[[pages:account/sessions]]';
userData.breadcrumbs = helpers.buildBreadcrumbs([{ text: userData.username, url: `/user/${userData.userslug}` }, { text: '[[pages:account/sessions]]' }]);
const payload = {
sessions: await user.auth.getSessions(res.locals.uid, req.sessionID),
title: '[[pages:account/sessions]]',
breadcrumbs: helpers.buildBreadcrumbs([{ text: username, url: `/user/${userslug}` }, { text: '[[pages:account/sessions]]' }]),
};
res.render('account/sessions', userData);
res.render('account/sessions', payload);
};

View File

@@ -6,35 +6,33 @@ const nconf = require('nconf');
const db = require('../../database');
const helpers = require('../helpers');
const user = require('../../user');
const meta = require('../../meta');
const pagination = require('../../pagination');
const accountHelpers = require('./helpers');
const uploadsController = module.exports;
uploadsController.get = async function (req, res, next) {
const userData = await accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, req.query);
if (!userData) {
return next();
}
uploadsController.get = async function (req, res) {
const { username, userslug } = await user.getUserFields(res.locals.uid, ['username', 'userslug']);
const page = Math.max(1, parseInt(req.query.page, 10) || 1);
const itemsPerPage = 25;
const start = (page - 1) * itemsPerPage;
const stop = start + itemsPerPage - 1;
const [itemCount, uploadNames] = await Promise.all([
db.sortedSetCard(`uid:${userData.uid}:uploads`),
db.getSortedSetRevRange(`uid:${userData.uid}:uploads`, start, stop),
db.sortedSetCard(`uid:${res.locals.uid}:uploads`),
db.getSortedSetRevRange(`uid:${res.locals.uid}:uploads`, start, stop),
]);
userData.uploads = uploadNames.map(uploadName => ({
const payload = {};
payload.uploads = uploadNames.map(uploadName => ({
name: uploadName,
url: path.resolve(nconf.get('upload_url'), uploadName),
}));
const pageCount = Math.ceil(itemCount / itemsPerPage);
userData.pagination = pagination.create(page, pageCount, req.query);
userData.privateUploads = meta.config.privateUploads === 1;
userData.title = `[[pages:account/uploads, ${userData.username}]]`;
userData.breadcrumbs = helpers.buildBreadcrumbs([{ text: userData.username, url: `/user/${userData.userslug}` }, { text: '[[global:uploads]]' }]);
res.render('account/uploads', userData);
payload.pagination = pagination.create(page, pageCount, req.query);
payload.privateUploads = meta.config.privateUploads === 1;
payload.title = `[[pages:account/uploads, ${username}]]`;
payload.breadcrumbs = helpers.buildBreadcrumbs([{ text: username, url: `/user/${userslug}` }, { text: '[[global:uploads]]' }]);
res.render('account/uploads', payload);
};

View File

@@ -1,6 +1,5 @@
'use strict';
const db = require('../../database');
const user = require('../../user');
const topics = require('../../topics');