[backend] Parse incorrectly formatted mentions in from-html

This commit is contained in:
Laura Hausmann 2023-10-14 16:10:30 +02:00
parent c02747116d
commit 72f048a24d
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
3 changed files with 11 additions and 10 deletions

View file

@ -6,7 +6,7 @@ import { getSubjectHostFromUriAndUsernameCached } from "@/remote/resolve-user.js
const urlRegex = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+/; const urlRegex = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+/;
const urlRegexFull = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+$/; const urlRegexFull = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+$/;
export async function fromHtml(html: string, hashtagNames?: string[], basicMentionResolve: boolean = false): Promise<string> { export async function fromHtml(html: string, hashtagNames?: string[]): Promise<string> {
// some AP servers like Pixelfed use br tags as well as newlines // some AP servers like Pixelfed use br tags as well as newlines
html = html.replace(/<br\s?\/?>\r?\n/gi, "\n"); html = html.replace(/<br\s?\/?>\r?\n/gi, "\n");
@ -73,9 +73,7 @@ export async function fromHtml(html: string, hashtagNames?: string[], basicMenti
if (part.length === 2 && href) { if (part.length === 2 && href) {
//#region ホスト名部分が省略されているので復元する //#region ホスト名部分が省略されているので復元する
const acct = basicMentionResolve const acct = `${txt}@${await getSubjectHostFromUriAndUsernameCached(href.value, txt)}`;
? `${txt}@${new URL(href.value).hostname}`
: `${txt}@${await getSubjectHostFromUriAndUsernameCached(href.value, txt)}`;
text += acct; text += acct;
//#endregion //#endregion
} else if (part.length === 3) { } else if (part.length === 3) {

View file

@ -190,9 +190,16 @@ export async function getSubjectHostFromUri(uri: string): Promise<string | null>
} }
export async function getSubjectHostFromUriAndUsernameCached(uri: string, username: string): Promise<string | null> { export async function getSubjectHostFromUriAndUsernameCached(uri: string, username: string): Promise<string | null> {
const hostname = new URL(uri).hostname; const url = new URL(uri);
const hostname = url.hostname;
username = username.substring(1); // remove leading @ from username username = username.substring(1); // remove leading @ from username
// This resolves invalid mentions with the URL format https://host.tld/@user@otherhost.tld
const match = url.pathname.match(/^\/@(?<user>[a-zA-Z0-9_]+|$)@(?<host>[a-zA-Z0-9-.]+\.[a-zA-Z0-9-]+)$/)
if (match && match.groups?.host) {
return match.groups.host;
}
if (hostname === config.hostname) { if (hostname === config.hostname) {
// user is local, return local account domain // user is local, return local account domain
return config.domain; return config.domain;

View file

@ -109,11 +109,7 @@ describe("fromHtml", () => {
it("mention", async () => { it("mention", async () => {
assert.deepStrictEqual( assert.deepStrictEqual(
await fromHtml( await fromHtml('<p>a <a href="https://joiniceshrimp.org/@user" class="u-url mention">@user</a> d</p>'),
'<p>a <a href="https://joiniceshrimp.org/@user" class="u-url mention">@user</a> d</p>',
undefined,
false
),
"a @user@joiniceshrimp.org d", "a @user@joiniceshrimp.org d",
); );
}); });