From 7e27d979be202dc89b0a564a60a37d394a56bde2 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Tue, 18 Jul 2023 15:57:54 +0200 Subject: [PATCH 1/2] [mastodon-client] improve mention regexes --- packages/megalodon/src/misskey.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/megalodon/src/misskey.ts b/packages/megalodon/src/misskey.ts index faae6e56a..491375ad8 100644 --- a/packages/megalodon/src/misskey.ts +++ b/packages/megalodon/src/misskey.ts @@ -1522,11 +1522,11 @@ export default class Misskey implements MegalodonInterface { )) { if (m.acct == m.username) status.content = status.content.replace( - `@${m.acct}@${this.baseUrlToHost(this.baseUrl)}`, + new RegExp(`(?<=^|\\s|>)@${m.acct}@${this.baseUrlToHost(this.baseUrl)}(?=[^a-zA-Z0-9]|$)`, 'g'), `@${m.acct}`, ); status.content = status.content.replace( - `@${m.acct}`, + new RegExp(`(?<=^|\\s|>)@${m.acct}(?=[^a-zA-Z0-9]|$)`, 'g'), `@${m.acct}`, ); } @@ -1542,7 +1542,7 @@ export default class Misskey implements MegalodonInterface { if (text == undefined) return mentions; const mentionMatch = text.matchAll( - /(?<=^|\s)@(?.*?)(?:@(?.*?)|)(?=\s|$)/g, + /(?<=^|\s)@(?[a-zA-Z0-9_]+)(?:@(?[a-zA-Z0-9-.]+\.[a-zA-Z0-9-]+)|)(?=[^a-zA-Z0-9]|$)/g, ); for (const m of mentionMatch) { @@ -2963,7 +2963,7 @@ export default class Misskey implements MegalodonInterface { } try { - const match = q.match(/^@(?.*?)(?:@(?.*?)|)$/); + const match = q.match(/^@(?[a-zA-Z0-9_]+)(?:@(?[a-zA-Z0-9-.]+\.[a-zA-Z0-9-]+)|)$/); if (match) { const lookupQuery = { username: match.groups?.user, From 6810721608727e6938152254b991713ec68668b8 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Tue, 18 Jul 2023 17:08:13 +0200 Subject: [PATCH 2/2] [mastodon-client] fix mentions of remote local users without host --- packages/megalodon/src/misskey.ts | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/packages/megalodon/src/misskey.ts b/packages/megalodon/src/misskey.ts index 491375ad8..a3afff728 100644 --- a/packages/megalodon/src/misskey.ts +++ b/packages/megalodon/src/misskey.ts @@ -1514,19 +1514,35 @@ export default class Misskey implements MegalodonInterface { if (status.quote != null) status.quote = await this.addMentionsToStatus(status.quote, cache); + const idx = status.account.acct.indexOf('@'); + const origin = idx < 0 ? null : status.account.acct.substring(idx + 1); + status.mentions = ( - await this.getMentions(status.plain_content!, cache) + await this.getMentions(status.plain_content!, origin, cache) ).filter((p) => p != null); for (const m of status.mentions.filter( (value, index, array) => array.indexOf(value) === index, )) { - if (m.acct == m.username) + const regexFull = new RegExp(`(?<=^|\\s|>)@${m.acct}(?=[^a-zA-Z0-9]|$)`, 'gi'); + const regexLocalUser = new RegExp(`(?<=^|\\s|>)@${m.acct}@${this.baseUrlToHost(this.baseUrl)}(?=[^a-zA-Z0-9]|$)`, 'gi'); + const regexRemoteUser = new RegExp(`(?<=^|\\s|>)@${m.username}(?=[^a-zA-Z0-9@]|$)`, 'gi'); + + if (m.acct == m.username) { status.content = status.content.replace( - new RegExp(`(?<=^|\\s|>)@${m.acct}@${this.baseUrlToHost(this.baseUrl)}(?=[^a-zA-Z0-9]|$)`, 'g'), + regexLocalUser, `@${m.acct}`, ); + } + + else if (!status.content.match(regexFull)) { + status.content = status.content.replace( + regexRemoteUser, + `@${m.acct}`, + ); + } + status.content = status.content.replace( - new RegExp(`(?<=^|\\s|>)@${m.acct}(?=[^a-zA-Z0-9]|$)`, 'g'), + regexFull, `@${m.acct}`, ); } @@ -1535,6 +1551,7 @@ export default class Misskey implements MegalodonInterface { public async getMentions( text: string, + origin: string | null, cache: AccountCache, ): Promise { const mentions: Entity.Mention[] = []; @@ -1551,7 +1568,7 @@ export default class Misskey implements MegalodonInterface { const account = await this.getAccountByNameCached( m.groups.user, - m.groups.host, + m.groups.host ?? origin, cache, );