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.
This commit is contained in:
David Taylor 2021-06-14 15:12:57 +01:00 committed by GitHub
parent 178b294a62
commit c44650eec5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 37 deletions

View File

@ -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();
},
buildArgs() {
if (!this.user) {
@discourseComputed("user")
flair(user) {
if (!user) {
return;
}
return this.primaryGroupFlair(user) || this.automaticGroupFlair(user);
},
if (
this.user.primary_group_flair_url ||
this.user.primary_group_flair_bg_color
) {
primaryGroupFlair(user) {
if (user.primary_group_flair_url || user.primary_group_flair_bg_color) {
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,
};
} 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,
flairURL: user.primary_group_flair_url,
flairBgColor: user.primary_group_flair_bg_color,
flairColor: user.primary_group_flair_color,
groupName: user.primary_group_name,
};
}
},
automaticGroupFlair(user) {
const autoFlairAttrs = autoGroupFlairForUser(this.site, user);
if (autoFlairAttrs) {
return {
flairURL: autoFlairAttrs.primary_group_flair_url,
flairBgColor: autoFlairAttrs.primary_group_flair_bg_color,
flairColor: autoFlairAttrs.primary_group_flair_color,
groupName: autoFlairAttrs.primary_group_name,
};
}
},
});

View File

@ -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">

View File

@ -0,0 +1,7 @@
{{#if flair}}
{{avatar-flair
flairURL=flair.flairURL
flairBgColor=flair.flairBgColor
flairColor=flair.flairColor
groupName=flair.groupName}}
{{/if}}

View File

@ -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");
},
});
}
);