FIX: Do not render user-avatar-flair element when user has no flair (#13369)

FIX: Do not render user-avatar-flair element when user has no flair (#13369)

Rendering an empty flair element with the css background-image: url(); causes the browser to attempt an image request against the current document URL. Making duplicate requests for the document URL can cause some unusual race conditions, especially related to cookies. If this user-avatar-flair element was present on the site homepage (e.g. if categories+latest is the homepage), then it can prevent the signup flow from working correctly.

This commit updates the user-avatar-flair component to be a transparent wrapper around the avatar-flair component. If the user has no flair, no avatar-flair element will be rendered. This avoids the background-image: url(); situation, and fixes the auth flow.

This commit also removes the duplicate avatar flair rendering from the latest-topic-list-item component. This wasn’t particularly obvious, since the duplicate flairs were being rendered directly on top of each other.

diff --git a/app/assets/javascripts/discourse/app/components/user-avatar-flair.js b/app/assets/javascripts/discourse/app/components/user-avatar-flair.js
index faf7492..35def72 100644
--- a/app/assets/javascripts/discourse/app/components/user-avatar-flair.js
+++ b/app/assets/javascripts/discourse/app/components/user-avatar-flair.js
@@ -1,41 +1,38 @@
-import MountWidget from "discourse/components/mount-widget";
-import { observes } from "discourse-common/utils/decorators";
+import Component from "@ember/component";
 import autoGroupFlairForUser from "discourse/lib/avatar-flair";
+import discourseComputed from "discourse-common/utils/decorators";
 
-export default MountWidget.extend({
-  widget: "avatar-flair",
+export default Component.extend({
+  tagName: "",
 
-  @observes("user")
-  _rerender() {
-    this.queueRerender();
+  @discourseComputed("user")
+  flair(user) {
+    if (!user) {
+      return;
+    }
+    return this.primaryGroupFlair(user) || this.automaticGroupFlair(user);
   },
 
-  buildArgs() {
-    if (!this.user) {
-      return;
+  primaryGroupFlair(user) {
+    if (user.primary_group_flair_url || user.primary_group_flair_bg_color) {
+      return {
+        flairURL: user.primary_group_flair_url,
+        flairBgColor: user.primary_group_flair_bg_color,
+        flairColor: user.primary_group_flair_color,
+        groupName: user.primary_group_name,
+      };
     }
+  },
 
-    if (
-      this.user.primary_group_flair_url ||
-      this.user.primary_group_flair_bg_color
-    ) {
+  automaticGroupFlair(user) {
+    const autoFlairAttrs = autoGroupFlairForUser(this.site, user);
+    if (autoFlairAttrs) {
       return {
-        primary_group_flair_url: this.user.primary_group_flair_url,
-        primary_group_flair_bg_color: this.user.primary_group_flair_bg_color,
-        primary_group_flair_color: this.user.primary_group_flair_color,
-        primary_group_name: this.user.primary_group_name,
+        flairURL: autoFlairAttrs.primary_group_flair_url,
+        flairBgColor: autoFlairAttrs.primary_group_flair_bg_color,
+        flairColor: autoFlairAttrs.primary_group_flair_color,
+        groupName: autoFlairAttrs.primary_group_name,
       };
-    } else {
-      const autoFlairAttrs = autoGroupFlairForUser(this.site, this.user);
-      if (autoFlairAttrs) {
-        return {
-          primary_group_flair_url: autoFlairAttrs.primary_group_flair_url,
-          primary_group_flair_bg_color:
-            autoFlairAttrs.primary_group_flair_bg_color,
-          primary_group_flair_color: autoFlairAttrs.primary_group_flair_color,
-          primary_group_name: autoFlairAttrs.primary_group_name,
-        };
-      }
     }
   },
 });
diff --git a/app/assets/javascripts/discourse/app/templates/components/latest-topic-list-item.hbs b/app/assets/javascripts/discourse/app/templates/components/latest-topic-list-item.hbs
index 754d9fd..6d11717 100644
--- a/app/assets/javascripts/discourse/app/templates/components/latest-topic-list-item.hbs
+++ b/app/assets/javascripts/discourse/app/templates/components/latest-topic-list-item.hbs
@@ -3,13 +3,6 @@
     {{avatar topic.lastPosterUser imageSize="large"}}
   {{/user-link}}
   {{user-avatar-flair user=topic.lastPosterUser}}
-  {{#if topic.lastPosterGroup}}
-    {{avatar-flair
-      flairURL=topic.lastPosterGroup.flair_url
-      flairBgColor=topic.lastPosterGroup.flair_bg_color
-      flairColor=topic.lastPosterGroup.flair_color
-      groupName=topic.lastPosterGroup.name}}
-  {{/if}}
 </div>
 <div class="main-link">
   <div class="top-row">
diff --git a/app/assets/javascripts/discourse/app/templates/components/user-avatar-flair.hbs b/app/assets/javascripts/discourse/app/templates/components/user-avatar-flair.hbs
new file mode 100644
index 0000000..f802da5
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/templates/components/user-avatar-flair.hbs
@@ -0,0 +1,7 @@
+{{#if flair}}
+  {{avatar-flair
+    flairURL=flair.flairURL
+    flairBgColor=flair.flairBgColor
+    flairColor=flair.flairColor
+    groupName=flair.groupName}}
+{{/if}}
diff --git a/app/assets/javascripts/discourse/tests/integration/components/user-avatar-flair-test.js b/app/assets/javascripts/discourse/tests/integration/components/user-avatar-flair-test.js
index 8190008..70f22db 100644
--- a/app/assets/javascripts/discourse/tests/integration/components/user-avatar-flair-test.js
+++ b/app/assets/javascripts/discourse/tests/integration/components/user-avatar-flair-test.js
@@ -175,5 +175,23 @@ discourseModule(
         );
       },
     });
+
+    componentTest("user-avatar-flair for user with no flairs", {
+      template: hbs`{{user-avatar-flair user=args}}`,
+      beforeEach() {
+        resetFlair();
+        this.set("args", {
+          admin: false,
+          moderator: false,
+          trust_level: 1,
+        });
+      },
+      afterEach() {
+        resetFlair();
+      },
+      test(assert) {
+        assert.ok(!exists(".avatar-flair"), "it does not render a flair");
+      },
+    });
   }
 );

GitHub sha: c44650eec5a489af395d26875e042be49147c086

This commit appears in #13369 which was approved by nlalonde. It was merged by davidtaylorhq.