diff --git a/public/language/en-GB/admin/manage/user-custom-fields.json b/public/language/en-GB/admin/manage/user-custom-fields.json index 2471e2e8f1..dab10670d2 100644 --- a/public/language/en-GB/admin/manage/user-custom-fields.json +++ b/public/language/en-GB/admin/manage/user-custom-fields.json @@ -20,5 +20,9 @@ "minimum-reputation": "Minimum reputation", "minimum-reputation-help": "If a user has less than this value they won't be able to use this field", "delete-field-confirm-x": "Do you really want to delete custom field \"%1\"?", - "custom-fields-saved": "Custom fields saved" + "custom-fields-saved": "Custom fields saved", + "visibility": "Visibility", + "visibility-all": "Everyone can see the field", + "visibility-loggedin": "Only logged in users can see the field", + "visibility-privileged": "Only privileged users like admins & moderators can see the field" } \ No newline at end of file diff --git a/public/src/admin/manage/users/custom-fields.js b/public/src/admin/manage/users/custom-fields.js index 631f06ea63..a7b0b65ca2 100644 --- a/public/src/admin/manage/users/custom-fields.js +++ b/public/src/admin/manage/users/custom-fields.js @@ -51,6 +51,7 @@ define('admin/manage/user/custom-fields', [ icon: el.attr('data-icon'), type: el.attr('data-type'), 'select-options': el.attr('data-select-options'), + visibility: el.attr('data-visibility'), 'min:rep': el.attr('data-min-rep'), }; } diff --git a/src/controllers/accounts/edit.js b/src/controllers/accounts/edit.js index 2326361fdc..61a13399a0 100644 --- a/src/controllers/accounts/edit.js +++ b/src/controllers/accounts/edit.js @@ -29,7 +29,7 @@ editController.get = async function (req, res, next) { const [canUseSignature, canManageUsers, customUserFields] = await Promise.all([ privileges.global.can('signature', req.uid), privileges.admin.can('admin:users', req.uid), - accountHelpers.getCustomUserFields(userData), + accountHelpers.getCustomUserFields(req.uid, userData), ]); userData.customUserFields = customUserFields; diff --git a/src/controllers/accounts/helpers.js b/src/controllers/accounts/helpers.js index 72ef70b9bd..2bf00215ae 100644 --- a/src/controllers/accounts/helpers.js +++ b/src/controllers/accounts/helpers.js @@ -129,13 +129,26 @@ helpers.getUserDataByUserSlug = async function (userslug, callerUID, query = {}) return hookData.userData; }; -helpers.getCustomUserFields = async function (userData) { +helpers.getCustomUserFields = async function (callerUID, userData) { const keys = await db.getSortedSetRange('user-custom-fields', 0, -1); const allFields = (await db.getObjects(keys.map(k => `user-custom-field:${k}`))).filter(Boolean); + const isSelf = String(callerUID) === String(userData.uid); + const [isAdmin, isModOfAny] = await Promise.all([ + privileges.users.isAdministrator(callerUID), + user.isModeratorOfAnyCategory(callerUID), + ]); + const fields = allFields.filter((field) => { + const visibilityCheck = isAdmin || isModOfAny || isSelf || field.visibility === 'all' || + ( + field.visibility === 'loggedin' && + String(callerUID) !== '0' && + String(callerUID) !== '-1' + ); const minRep = field['min:rep'] || 0; - return userData.reputation >= minRep || meta.config['reputation:disabled']; + const repCheck = userData.reputation >= minRep || meta.config['reputation:disabled']; + return visibilityCheck && repCheck; }); fields.forEach((f) => { diff --git a/src/controllers/accounts/profile.js b/src/controllers/accounts/profile.js index f99b1f9fcd..e24415794d 100644 --- a/src/controllers/accounts/profile.js +++ b/src/controllers/accounts/profile.js @@ -25,7 +25,7 @@ profileController.get = async function (req, res, next) { const [latestPosts, bestPosts, customUserFields] = await Promise.all([ getLatestPosts(req.uid, userData), getBestPosts(req.uid, userData), - accountHelpers.getCustomUserFields(userData), + accountHelpers.getCustomUserFields(req.uid, userData), posts.parseSignature(userData, req.uid), ]); userData.customUserFields = customUserFields; diff --git a/src/controllers/admin/users.js b/src/controllers/admin/users.js index db1be70157..4ea3ebb9e5 100644 --- a/src/controllers/admin/users.js +++ b/src/controllers/admin/users.js @@ -310,6 +310,7 @@ usersController.customFields = async function (req, res) { field.selectOptionsFormatted = field['select-options'].trim().split('\n').join(', '); } field['min:rep'] = field['min:rep'] || 0; + field.visibility = field.visibility || 'all'; }); res.render('admin/manage/users/custom-fields', { fields: fields }); }; diff --git a/src/views/admin/manage/users/custom-fields.tpl b/src/views/admin/manage/users/custom-fields.tpl index f3eb010987..b16a0bd754 100644 --- a/src/views/admin/manage/users/custom-fields.tpl +++ b/src/views/admin/manage/users/custom-fields.tpl @@ -21,13 +21,14 @@