diff --git a/packages/backend/src/mfm/from-html.ts b/packages/backend/src/mfm/from-html.ts index 9b4346d2c..ffec44376 100644 --- a/packages/backend/src/mfm/from-html.ts +++ b/packages/backend/src/mfm/from-html.ts @@ -6,7 +6,7 @@ import { getSubjectHostFromUriAndUsernameCached } from "@/remote/resolve-user.js const urlRegex = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+/; const urlRegexFull = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+$/; -export async function fromHtml(html: string, hashtagNames?: string[], basicMentionResolve: boolean = false): Promise { +export async function fromHtml(html: string, hashtagNames?: string[]): Promise { // some AP servers like Pixelfed use br tags as well as newlines html = html.replace(/\r?\n/gi, "\n"); @@ -73,9 +73,7 @@ export async function fromHtml(html: string, hashtagNames?: string[], basicMenti if (part.length === 2 && href) { //#region ホスト名部分が省略されているので復元する - const acct = basicMentionResolve - ? `${txt}@${new URL(href.value).hostname}` - : `${txt}@${await getSubjectHostFromUriAndUsernameCached(href.value, txt)}`; + const acct = `${txt}@${await getSubjectHostFromUriAndUsernameCached(href.value, txt)}`; text += acct; //#endregion } else if (part.length === 3) { diff --git a/packages/backend/src/remote/resolve-user.ts b/packages/backend/src/remote/resolve-user.ts index 2f0c6008e..b60106e28 100644 --- a/packages/backend/src/remote/resolve-user.ts +++ b/packages/backend/src/remote/resolve-user.ts @@ -190,9 +190,16 @@ export async function getSubjectHostFromUri(uri: string): Promise } export async function getSubjectHostFromUriAndUsernameCached(uri: string, username: string): Promise { - const hostname = new URL(uri).hostname; + const url = new URL(uri); + const hostname = url.hostname; 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(/^\/@(?[a-zA-Z0-9_]+|$)@(?[a-zA-Z0-9-.]+\.[a-zA-Z0-9-]+)$/) + if (match && match.groups?.host) { + return match.groups.host; + } + if (hostname === config.hostname) { // user is local, return local account domain return config.domain; diff --git a/packages/backend/test/mfm.ts b/packages/backend/test/mfm.ts index 5c9250048..5a42e420d 100644 --- a/packages/backend/test/mfm.ts +++ b/packages/backend/test/mfm.ts @@ -109,11 +109,7 @@ describe("fromHtml", () => { it("mention", async () => { assert.deepStrictEqual( - await fromHtml( - '

a @user d

', - undefined, - false - ), + await fromHtml('

a @user d

'), "a @user@joiniceshrimp.org d", ); });