From 03f83c0eedf992c588dd5d87d44b7e7e642228ff Mon Sep 17 00:00:00 2001
From: Alan Guo Xiang Tan <gxtan1990@gmail.com>
Date: Fri, 23 Sep 2022 10:19:59 +0800
Subject: [PATCH] FIX: Respect site settings for sidebar users, groups and
 badges link (#18325)

The links should not be displayed when its associated site setting has
been disabled. This commit maintains parity with the old hamburger menu.
---
 .../sidebar/common/community-section.js       | 39 ++++++++--------
 .../sidebar/user/community-section.js         | 11 ++---
 .../sidebar/base-community-section-link.js    |  7 +++
 .../community-section/badges-section-link.js  |  4 ++
 .../community-section/groups-section-link.js  |  4 ++
 .../community-section/users-section-link.js   |  7 +++
 .../community-section/admin-section-link.js   |  4 ++
 ...idebar-anonymous-community-section-test.js | 14 +++++-
 .../sidebar-user-community-section-test.js    | 45 +++++++++++++++++++
 .../discourse/tests/helpers/site-settings.js  |  1 +
 10 files changed, 110 insertions(+), 26 deletions(-)

diff --git a/app/assets/javascripts/discourse/app/components/sidebar/common/community-section.js b/app/assets/javascripts/discourse/app/components/sidebar/common/community-section.js
index 64a74edf18c..2ef6f167147 100644
--- a/app/assets/javascripts/discourse/app/components/sidebar/common/community-section.js
+++ b/app/assets/javascripts/discourse/app/components/sidebar/common/community-section.js
@@ -23,27 +23,19 @@ export default class SidebarCommunitySection extends Component {
   constructor() {
     super(...arguments);
 
-    this.moreSectionLinks = [
+    this.moreSectionLinks = this.#initializeSectionLinks([
       ...this.defaultMoreSectionLinks,
       ...customSectionLinks,
-    ].map((sectionLinkClass) => {
-      return this.#initializeSectionLink(sectionLinkClass);
-    });
+    ]);
 
-    this.moreSecondarySectionLinks = [
+    this.moreSecondarySectionLinks = this.#initializeSectionLinks([
       ...this.defaultMoreSecondarySectionLinks,
       ...secondaryCustomSectionLinks,
-    ].map((sectionLinkClass) => {
-      return this.#initializeSectionLink(sectionLinkClass);
-    });
+    ]);
 
-    const mainSectionLinks = this.currentUser?.staff
-      ? [...this.defaultMainSectionLinks, ...this.defaultAdminMainSectionLinks]
-      : [...this.defaultMainSectionLinks];
-
-    this.sectionLinks = mainSectionLinks.map((sectionLinkClass) => {
-      return this.#initializeSectionLink(sectionLinkClass);
-    });
+    this.sectionLinks = this.#initializeSectionLinks(
+      this.defaultMainSectionLinks
+    );
 
     this.callbackId = this.topicTrackingState.onStateChange(() => {
       this.sectionLinks.forEach((sectionLink) => {
@@ -62,11 +54,6 @@ export default class SidebarCommunitySection extends Component {
     return [];
   }
 
-  // Override in child
-  get defaultAdminMainSectionLinks() {
-    return [];
-  }
-
   // Override in child
   get defaultMoreSectionLinks() {
     return [];
@@ -77,6 +64,18 @@ export default class SidebarCommunitySection extends Component {
     return [];
   }
 
+  #initializeSectionLinks(sectionLinkClasses) {
+    return sectionLinkClasses.reduce((links, sectionLinkClass) => {
+      const sectionLink = this.#initializeSectionLink(sectionLinkClass);
+
+      if (sectionLink.shouldDisplay) {
+        links.push(sectionLink);
+      }
+
+      return links;
+    }, []);
+  }
+
   #initializeSectionLink(sectionLinkClass) {
     return new sectionLinkClass({
       topicTrackingState: this.topicTrackingState,
diff --git a/app/assets/javascripts/discourse/app/components/sidebar/user/community-section.js b/app/assets/javascripts/discourse/app/components/sidebar/user/community-section.js
index 1ba644a618c..13f74a48383 100644
--- a/app/assets/javascripts/discourse/app/components/sidebar/user/community-section.js
+++ b/app/assets/javascripts/discourse/app/components/sidebar/user/community-section.js
@@ -32,11 +32,12 @@ export default class SidebarUserCommunitySection extends SidebarCommonCommunityS
   }
 
   get defaultMainSectionLinks() {
-    return [EverythingSectionLink, TrackedSectionLink, MyPostsSectionLink];
-  }
-
-  get defaultAdminMainSectionLinks() {
-    return [AdminSectionLink];
+    return [
+      EverythingSectionLink,
+      TrackedSectionLink,
+      MyPostsSectionLink,
+      AdminSectionLink,
+    ];
   }
 
   get defaultMoreSectionLinks() {
diff --git a/app/assets/javascripts/discourse/app/lib/sidebar/base-community-section-link.js b/app/assets/javascripts/discourse/app/lib/sidebar/base-community-section-link.js
index e41a3e91fb1..f3f5b2d891f 100644
--- a/app/assets/javascripts/discourse/app/lib/sidebar/base-community-section-link.js
+++ b/app/assets/javascripts/discourse/app/lib/sidebar/base-community-section-link.js
@@ -33,6 +33,13 @@ export default class BaseCommunitySectionLink {
     this._notImplemented();
   }
 
+  /**
+   * @returns {boolean} Whether the section link should be displayed. Defaults to true.
+   */
+  get shouldDisplay() {
+    return true;
+  }
+
   /**
    * @returns {string} Ember route
    */
diff --git a/app/assets/javascripts/discourse/app/lib/sidebar/common/community-section/badges-section-link.js b/app/assets/javascripts/discourse/app/lib/sidebar/common/community-section/badges-section-link.js
index b4504d514cf..8c6f19f5d05 100644
--- a/app/assets/javascripts/discourse/app/lib/sidebar/common/community-section/badges-section-link.js
+++ b/app/assets/javascripts/discourse/app/lib/sidebar/common/community-section/badges-section-link.js
@@ -18,4 +18,8 @@ export default class BadgesSectionLink extends BaseSectionLink {
   get text() {
     return I18n.t("sidebar.sections.community.links.badges.content");
   }
+
+  get shouldDisplay() {
+    return this.siteSettings.enable_badges;
+  }
 }
diff --git a/app/assets/javascripts/discourse/app/lib/sidebar/common/community-section/groups-section-link.js b/app/assets/javascripts/discourse/app/lib/sidebar/common/community-section/groups-section-link.js
index d6ad8b78cfd..6305865ea83 100644
--- a/app/assets/javascripts/discourse/app/lib/sidebar/common/community-section/groups-section-link.js
+++ b/app/assets/javascripts/discourse/app/lib/sidebar/common/community-section/groups-section-link.js
@@ -18,4 +18,8 @@ export default class GroupsSectionLink extends BaseSectionLink {
   get text() {
     return I18n.t("sidebar.sections.community.links.groups.content");
   }
+
+  get shouldDisplay() {
+    return this.siteSettings.enable_group_directory;
+  }
 }
diff --git a/app/assets/javascripts/discourse/app/lib/sidebar/common/community-section/users-section-link.js b/app/assets/javascripts/discourse/app/lib/sidebar/common/community-section/users-section-link.js
index 019eaddb2a6..8b6015f69f5 100644
--- a/app/assets/javascripts/discourse/app/lib/sidebar/common/community-section/users-section-link.js
+++ b/app/assets/javascripts/discourse/app/lib/sidebar/common/community-section/users-section-link.js
@@ -18,4 +18,11 @@ export default class UsersSectionLink extends BaseSectionLink {
   get text() {
     return I18n.t("sidebar.sections.community.links.users.content");
   }
+
+  get shouldDisplay() {
+    return (
+      this.siteSettings.enable_user_directory &&
+      (this.currentUser || !this.siteSettings.hide_user_profiles_from_public)
+    );
+  }
 }
diff --git a/app/assets/javascripts/discourse/app/lib/sidebar/user/community-section/admin-section-link.js b/app/assets/javascripts/discourse/app/lib/sidebar/user/community-section/admin-section-link.js
index 85b3d315fce..addbdd862d2 100644
--- a/app/assets/javascripts/discourse/app/lib/sidebar/user/community-section/admin-section-link.js
+++ b/app/assets/javascripts/discourse/app/lib/sidebar/user/community-section/admin-section-link.js
@@ -18,4 +18,8 @@ export default class AdminSectionLink extends BaseSectionLink {
   get text() {
     return I18n.t("sidebar.sections.community.links.admin.content");
   }
+
+  get shouldDisplay() {
+    return this.currentUser?.staff;
+  }
 }
diff --git a/app/assets/javascripts/discourse/tests/acceptance/sidebar-anonymous-community-section-test.js b/app/assets/javascripts/discourse/tests/acceptance/sidebar-anonymous-community-section-test.js
index f5dc01231b0..c01d2357d97 100644
--- a/app/assets/javascripts/discourse/tests/acceptance/sidebar-anonymous-community-section-test.js
+++ b/app/assets/javascripts/discourse/tests/acceptance/sidebar-anonymous-community-section-test.js
@@ -4,6 +4,7 @@ import { test } from "qunit";
 
 import {
   acceptance,
+  exists,
   query,
   queryAll,
 } from "discourse/tests/helpers/qunit-helpers";
@@ -72,7 +73,18 @@ acceptance("Sidebar - Anonymous user - Community Section", function (needs) {
     );
   });
 
-  test("groups  and badges section links are shown in more...", async function (assert) {
+  test("users section link is not shown when hide_user_profiles_from_public site setting is enabled", async function (assert) {
+    this.siteSettings.hide_user_profiles_from_public = true;
+
+    await visit("/");
+
+    assert.notOk(
+      exists(".sidebar-section-community .sidebar-section-link-users"),
+      "users section link is not shown in sidebar"
+    );
+  });
+
+  test("groups and badges section links are shown in more...", async function (assert) {
     await visit("/");
 
     await click(
diff --git a/app/assets/javascripts/discourse/tests/acceptance/sidebar-user-community-section-test.js b/app/assets/javascripts/discourse/tests/acceptance/sidebar-user-community-section-test.js
index 9c6e58d4afa..b424702c1db 100644
--- a/app/assets/javascripts/discourse/tests/acceptance/sidebar-user-community-section-test.js
+++ b/app/assets/javascripts/discourse/tests/acceptance/sidebar-user-community-section-test.js
@@ -229,6 +229,21 @@ acceptance("Sidebar - Logged on user - Community Section", function (needs) {
     );
   });
 
+  test("users section link is not shown when enable_user_directory site setting is disabled", async function (assert) {
+    this.siteSettings.enable_user_directory = false;
+
+    await visit("/");
+
+    await click(
+      ".sidebar-section-community .sidebar-more-section-links-details-summary"
+    );
+
+    assert.notOk(
+      exists(".sidebar-section-community .sidebar-section-link-users"),
+      "users section link is not displayed in sidebar"
+    );
+  });
+
   test("clicking on badges link", async function (assert) {
     await visit("/");
 
@@ -245,6 +260,21 @@ acceptance("Sidebar - Logged on user - Community Section", function (needs) {
     );
   });
 
+  test("badges section link is not shown when badges has been disabled", async function (assert) {
+    this.siteSettings.enable_badges = false;
+
+    await visit("/");
+
+    await click(
+      ".sidebar-section-community .sidebar-more-section-links-details-summary"
+    );
+
+    assert.notOk(
+      exists(".sidebar-section-community .sidebar-section-link-badges"),
+      "badges section link is not shown in sidebar"
+    );
+  });
+
   test("clicking on groups link", async function (assert) {
     await visit("/t/280");
 
@@ -292,6 +322,21 @@ acceptance("Sidebar - Logged on user - Community Section", function (needs) {
     );
   });
 
+  test("groups section link is not shown when enable_group_directory site setting has been disabled", async function (assert) {
+    this.siteSettings.enable_group_directory = false;
+
+    await visit("/");
+
+    await click(
+      ".sidebar-section-community .sidebar-more-section-links-details-summary"
+    );
+
+    assert.notOk(
+      exists(".sidebar-section-community .sidebar-section-link-groups"),
+      "groups section link is not shown in sidebar"
+    );
+  });
+
   test("navigating to about from sidebar", async function (assert) {
     await visit("/");
 
diff --git a/app/assets/javascripts/discourse/tests/helpers/site-settings.js b/app/assets/javascripts/discourse/tests/helpers/site-settings.js
index 91e33c8b6b0..95c591654ab 100644
--- a/app/assets/javascripts/discourse/tests/helpers/site-settings.js
+++ b/app/assets/javascripts/discourse/tests/helpers/site-settings.js
@@ -99,6 +99,7 @@ const ORIGINAL_SETTINGS = {
   secure_media: false,
   external_emoji_url: "",
   remove_muted_tags_from_latest: "always",
+  enable_group_directory: true,
 };
 
 let siteSettings = Object.assign({}, ORIGINAL_SETTINGS);