FIX: Treat contact_url setting as a domain by default (#30225)

This commit makes the `contact_url` in the /about page behave as an absolute URL instead of a relative one if it doesn't explicitly start with a slash or a protocol. This prevents situation where, e.g., `www.example.com` is specified in the setting and the contact URL anchor tag ends up with a `href` that navigates to `<site address>/www.example.com` instead of just `www.example.com`. We prevent this by adding 2 leading slashes `//` to `contact_url` which makes the `href` resolves to the specified `contact_url` using the same protocol as the current site's.

Internal topic: t/143907.
This commit is contained in:
Osama Sayegh 2024-12-23 07:54:53 +03:00 committed by GitHub
parent 4cf2f5d98a
commit f6282145aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 67 additions and 8 deletions

View File

@ -149,8 +149,9 @@ export default class AboutPage extends Component {
const email = escape(this.args.model.contact_email || ""); const email = escape(this.args.model.contact_email || "");
if (url) { if (url) {
const href = this.contactURLHref;
return i18n("about.contact_info", { return i18n("about.contact_info", {
contact_info: `<a href='${url}' target='_blank'>${url}</a>`, contact_info: `<a href='${href}' target='_blank'>${url}</a>`,
}); });
} else if (email) { } else if (email) {
return i18n("about.contact_info", { return i18n("about.contact_info", {
@ -161,6 +162,20 @@ export default class AboutPage extends Component {
} }
} }
get contactURLHref() {
const url = escape(this.args.model.contact_url || "");
if (!url) {
return;
}
if (url.startsWith("/") || url.match(/^\w+:/)) {
return url;
}
return `//${url}`;
}
get siteAgeString() { get siteAgeString() {
const creationDate = new Date(this.args.model.site_creation_date); const creationDate = new Date(this.args.model.site_creation_date);
@ -278,7 +293,7 @@ export default class AboutPage extends Component {
<div class="about__right-side"> <div class="about__right-side">
<h3>{{i18n "about.contact"}}</h3> <h3>{{i18n "about.contact"}}</h3>
{{#if this.contactInfo}} {{#if this.contactInfo}}
<p>{{htmlSafe this.contactInfo}}</p> <p class="about__contact-info">{{htmlSafe this.contactInfo}}</p>
{{/if}} {{/if}}
<p>{{i18n "about.report_inappropriate_content"}}</p> <p>{{i18n "about.report_inappropriate_content"}}</p>
<h3>{{i18n "about.site_activity"}}</h3> <h3>{{i18n "about.site_activity"}}</h3>

View File

@ -11,12 +11,16 @@ function createModelObject({
moderators = [], moderators = [],
stats = {}, stats = {},
}) { }) {
return { const model = arguments[0] || {};
return Object.assign(
{
title, title,
admins, admins,
moderators, moderators,
stats, stats,
}; },
model
);
} }
module("Integration | Component | about-page", function (hooks) { module("Integration | Component | about-page", function (hooks) {
@ -98,4 +102,44 @@ module("Integration | Component | about-page", function (hooks) {
}) })
); );
}); });
test("contact URL", async function (assert) {
let model = createModelObject({
contact_url: "www.example.com",
});
await render(<template><AboutPage @model={{model}} /></template>);
assert
.dom(".about__contact-info a")
.hasAttribute(
"href",
"//www.example.com",
"appends a double slash if the value doesn't start with a slash or a protocol"
);
model.contact_url = "/u/somebody";
await render(<template><AboutPage @model={{model}} /></template>);
assert
.dom(".about__contact-info a")
.hasAttribute(
"href",
"/u/somebody",
"doesn't append a double slash if the value starts with a slash"
);
model.contact_url = "https://example.com";
await render(<template><AboutPage @model={{model}} /></template>);
assert
.dom(".about__contact-info a")
.hasAttribute(
"href",
"https://example.com",
"doesn't append a double slash if the value starts with a protocol"
);
});
}); });