diff --git a/app/assets/javascripts/discourse/app/components/header/user-dropdown/user-status-bubble.gjs b/app/assets/javascripts/discourse/app/components/header/user-dropdown/user-status-bubble.gjs
index dfe634b07b7..5398001248a 100644
--- a/app/assets/javascripts/discourse/app/components/header/user-dropdown/user-status-bubble.gjs
+++ b/app/assets/javascripts/discourse/app/components/header/user-dropdown/user-status-bubble.gjs
@@ -1,15 +1,19 @@
import { concat } from "@ember/helper";
import emoji from "discourse/helpers/emoji";
+import escape from "discourse-common/lib/escape";
import I18n from "discourse-i18n";
const title = (description, endsAt, timezone) => {
- let content = description;
+ let content = escape(description);
+
if (endsAt) {
const until = moment
.tz(endsAt, timezone)
.format(I18n.t("dates.long_date_without_year"));
+
content += `\n${I18n.t("until")} ${until}`;
}
+
return content;
};
diff --git a/app/assets/javascripts/discourse/tests/acceptance/user-status-test.js b/app/assets/javascripts/discourse/tests/acceptance/user-status-test.js
index 455514ef339..e2902238aeb 100644
--- a/app/assets/javascripts/discourse/tests/acceptance/user-status-test.js
+++ b/app/assets/javascripts/discourse/tests/acceptance/user-status-test.js
@@ -217,11 +217,18 @@ acceptance("User Status", function (needs) {
await visit("/");
await openUserStatusModal();
- await fillIn(".user-status-description", userStatus);
+ await fillIn(".user-status-description", "off to dentist");
await pickEmoji(userStatusEmoji);
await click("#tap_tile_one_hour");
await click(".btn-primary"); // save
+ assert.ok(
+ query(".user-status-background img").title.startsWith(
+ "off to dentist",
+ "title is properly escaped"
+ )
+ );
+
await click(".header-dropdown-toggle.current-user button");
await click("#user-menu-button-profile");