From 0bbb813e4b28169e5f6cca4820c9087046574097 Mon Sep 17 00:00:00 2001 From: Sam Thompson Date: Thu, 30 Jul 2020 18:43:18 -0700 Subject: [PATCH] feat: #8493, plugin helper for standardised link/button injection --- src/controllers/accounts/helpers.js | 132 +++++++++++----------------- src/controllers/helpers.js | 29 ++++++ src/plugins/hooks.js | 2 +- 3 files changed, 80 insertions(+), 83 deletions(-) diff --git a/src/controllers/accounts/helpers.js b/src/controllers/accounts/helpers.js index 817de9dd01..902b03594c 100644 --- a/src/controllers/accounts/helpers.js +++ b/src/controllers/accounts/helpers.js @@ -1,7 +1,6 @@ 'use strict'; const validator = require('validator'); -const winston = require('winston'); const nconf = require('nconf'); const user = require('../../user'); @@ -12,6 +11,7 @@ const utils = require('../../utils'); const privileges = require('../../privileges'); const translator = require('../../translator'); const messaging = require('../../messaging'); +const { buildLinks } = require('../helpers'); const helpers = module.exports; @@ -83,7 +83,55 @@ helpers.getUserDataByUserSlug = async function (userslug, callerUID) { userData['reputation:disabled'] = meta.config['reputation:disabled'] === 1; userData['downvote:disabled'] = meta.config['downvote:disabled'] === 1; userData['email:confirmed'] = !!userData['email:confirmed']; - userData.profile_links = filterLinks(results.profile_menu.links, { + + const profileMenuLinks = [{ + id: 'info', + route: 'info', + name: '[[user:account_info]]', + icon: 'fa-info', + visibility: { + self: false, + other: false, + moderator: false, + globalMod: false, + admin: true, + canViewInfo: true, + }, + }, { + id: 'sessions', + route: 'sessions', + name: '[[pages:account/sessions]]', + icon: 'fa-group', + visibility: { + self: true, + other: false, + moderator: false, + globalMod: false, + admin: false, + canViewInfo: false, + }, + }]; + + if (meta.config.gdpr_enabled) { + profileMenuLinks.push({ + id: 'consent', + route: 'consent', + name: '[[user:consent.title]]', + icon: 'fa-thumbs-o-up', + visibility: { + self: true, + other: false, + moderator: false, + globalMod: false, + admin: false, + canViewInfo: false, + }, + }); + } + + const { links } = await plugins.fireHook('filter:user.profileMenu', { uid, callerUID, links: profileMenuLinks }); + + userData.profile_links = await buildLinks('accounts/profile', links, { self: isSelf, other: !isSelf, moderator: isModerator, @@ -127,7 +175,6 @@ async function getAllData(uid, callerUID) { isModerator: user.isModeratorOfAnyCategory(callerUID), isFollowing: user.isFollowing(callerUID, uid), ips: user.getIPs(uid, 4), - profile_menu: getProfileMenu(uid, callerUID), groups: groups.getUserGroups([uid]), sso: plugins.fireHook('filter:auth.list', { uid: uid, associations: [] }), canEdit: privileges.users.canEdit(callerUID, uid), @@ -138,59 +185,6 @@ async function getAllData(uid, callerUID) { }); } -async function getProfileMenu(uid, callerUID) { - const links = [{ - id: 'info', - route: 'info', - name: '[[user:account_info]]', - icon: 'fa-info', - visibility: { - self: false, - other: false, - moderator: false, - globalMod: false, - admin: true, - canViewInfo: true, - }, - }, { - id: 'sessions', - route: 'sessions', - name: '[[pages:account/sessions]]', - icon: 'fa-group', - visibility: { - self: true, - other: false, - moderator: false, - globalMod: false, - admin: false, - canViewInfo: false, - }, - }]; - - if (meta.config.gdpr_enabled) { - links.push({ - id: 'consent', - route: 'consent', - name: '[[user:consent.title]]', - icon: 'fa-thumbs-o-up', - visibility: { - self: true, - other: false, - moderator: false, - globalMod: false, - admin: false, - canViewInfo: false, - }, - }); - } - - return await plugins.fireHook('filter:user.profileMenu', { - uid: uid, - callerUID: callerUID, - links: links, - }); -} - async function parseAboutMe(userData) { if (!userData.aboutme) { userData.aboutme = ''; @@ -202,30 +196,4 @@ async function parseAboutMe(userData) { userData.aboutmeParsed = translator.escape(parsed); } -function filterLinks(links, states) { - return links.filter(function (link, index) { - // "public" is the old property, if visibility is defined, discard `public` - if (link.hasOwnProperty('public') && !link.hasOwnProperty('visibility')) { - winston.warn('[account/profileMenu (' + link.id + ')] Use of the `.public` property is deprecated, use `visibility` now'); - return link && (link.public || states.self); - } - - // Default visibility - link.visibility = { self: true, - other: true, - moderator: true, - globalMod: true, - admin: true, - canViewInfo: true, - ...link.visibility }; - - var permit = Object.keys(states).some(function (state) { - return states[state] && link.visibility[state]; - }); - - links[index].public = permit; - return permit; - }); -} - require('../../promisify')(helpers); diff --git a/src/controllers/helpers.js b/src/controllers/helpers.js index 7ac17130f4..8464f2d123 100644 --- a/src/controllers/helpers.js +++ b/src/controllers/helpers.js @@ -1,5 +1,6 @@ 'use strict'; +const winston = require('winston'); const nconf = require('nconf'); const validator = require('validator'); const querystring = require('querystring'); @@ -218,6 +219,34 @@ helpers.buildTitle = function (pageTitle) { return title; }; +helpers.buildLinks = async function (event, links, states) { + const filtered = await plugins.fireHook(`filter:buildLinks.${event}`, { links, states }); + + return filtered.links.filter(function (link, index) { + // "public" is the old property, if visibility is defined, discard `public` + if (link.hasOwnProperty('public') && !link.hasOwnProperty('visibility')) { + winston.warn('[account/profileMenu (' + link.id + ')] Use of the `.public` property is deprecated, use `visibility` now'); + return link && (link.public || filtered.states.self); + } + + // Default visibility + link.visibility = { self: true, + other: true, + moderator: true, + globalMod: true, + admin: true, + canViewInfo: true, + ...link.visibility }; + + var permit = Object.keys(filtered.states).some(function (state) { + return filtered.states[state] && link.visibility[state]; + }); + + filtered.links[index].public = permit; + return permit; + }); +}; + helpers.getCategories = async function (set, uid, privilege, selectedCid) { const cids = await categories.getCidsByPrivilege(set, uid, privilege); return await getCategoryData(cids, uid, selectedCid); diff --git a/src/plugins/hooks.js b/src/plugins/hooks.js index e6d7067df9..e32d8ed78b 100644 --- a/src/plugins/hooks.js +++ b/src/plugins/hooks.js @@ -6,7 +6,7 @@ const utils = require('../utils'); module.exports = function (Plugins) { Plugins.deprecatedHooks = { - + 'filter:user.profileMenu': 'filter:buildLinks.accounts/profile', }; Plugins.internals = {