From 19e29c34654e2105ba78587a6e9feaf8c799b5d7 Mon Sep 17 00:00:00 2001 From: Francis Dinh Date: Thu, 8 Sep 2022 16:17:35 -0400 Subject: [PATCH 1/2] backend: move mentionedUsers query to mention handler The mentionedUsers query was being run on every post, regardless of whether a mention was in it or not. This resulted in an SQL query ending in `WHERE userId IN ()` which is not allowed in PostgreSQL. Reference: https://akkoma.dev/FoundKeyGang/FoundKey/issues/132 Changelog: Fixed --- packages/backend/src/mfm/to-html.ts | 37 ++++++++++++++--------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/packages/backend/src/mfm/to-html.ts b/packages/backend/src/mfm/to-html.ts index 117f8b278..9b72b98c6 100644 --- a/packages/backend/src/mfm/to-html.ts +++ b/packages/backend/src/mfm/to-html.ts @@ -14,23 +14,8 @@ export async function toHtml(mfmText: string, mentions?: string[]): Promise (handlers as any)[x.type](x))) targetElement.appendChild(child); - } - } - const handlers: { [K in mfm.MfmNode['type']]: (node: mfm.NodeType) => any } = { bold(node) { const el = doc.createElement('b'); @@ -117,8 +102,17 @@ export async function toHtml(mfmText: string, mentions?: string[]): Promise { const { username, host, acct } = node.props; + const ids = mentions ?? extractMentions(nodes); + const mentionedUsers = await UserProfiles.createQueryBuilder('user_profile') + .leftJoin('user_profile.user', 'user') + .select('user.username') + .addSelect('user.host') + // links should preferably use user friendly urls, only fall back to AP ids + .addSelect('COALESCE(user_profile.url, user.uri)', 'url') + .where('userId IN (:...ids)', { ids }) + .getMany(); const userInfo = mentionedUsers.find(user => user.user?.username === username && user.userHost === host); if (userInfo != null) { // Mastodon microformat: span.h-card > a.u-url.mention @@ -131,10 +125,9 @@ export async function toHtml(mfmText: string, mentions?: string[]): Promise 0) { + for (const child of children.map(x => (handlers as any)[x.type](x))) targetElement.appendChild(child); + } + } + appendChildren(nodes, doc.body); return `

${doc.body.innerHTML}

`; From 199622b41548110a2dee84983b93fe68388b20b8 Mon Sep 17 00:00:00 2001 From: Francis Dinh Date: Thu, 8 Sep 2022 17:45:03 -0400 Subject: [PATCH 2/2] add check if ids.length > 0 before executing query --- packages/backend/src/mfm/to-html.ts | 40 +++++++++++++++-------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/packages/backend/src/mfm/to-html.ts b/packages/backend/src/mfm/to-html.ts index 9b72b98c6..c32363574 100644 --- a/packages/backend/src/mfm/to-html.ts +++ b/packages/backend/src/mfm/to-html.ts @@ -105,26 +105,28 @@ export async function toHtml(mfmText: string, mentions?: string[]): Promise { const { username, host, acct } = node.props; const ids = mentions ?? extractMentions(nodes); - const mentionedUsers = await UserProfiles.createQueryBuilder('user_profile') - .leftJoin('user_profile.user', 'user') - .select('user.username') - .addSelect('user.host') - // links should preferably use user friendly urls, only fall back to AP ids - .addSelect('COALESCE(user_profile.url, user.uri)', 'url') - .where('userId IN (:...ids)', { ids }) - .getMany(); - const userInfo = mentionedUsers.find(user => user.user?.username === username && user.userHost === host); - if (userInfo != null) { - // Mastodon microformat: span.h-card > a.u-url.mention - const a = doc.createElement('a'); - a.href = userInfo.url ?? `${config.url}/${acct}`; - a.className = 'u-url mention'; - a.textContent = acct; + if (ids.length > 0) { + const mentionedUsers = await UserProfiles.createQueryBuilder('user_profile') + .leftJoin('user_profile.user', 'user') + .select('user.username') + .addSelect('user.host') + // links should preferably use user friendly urls, only fall back to AP ids + .addSelect('COALESCE(user_profile.url, user.uri)', 'url') + .where('"userId" IN (:...ids)', { ids }) + .getMany(); + const userInfo = mentionedUsers.find(user => user.user?.username === username && user.userHost === host); + if (userInfo != null) { + // Mastodon microformat: span.h-card > a.u-url.mention + const a = doc.createElement('a'); + a.href = userInfo.url ?? `${config.url}/${acct}`; + a.className = 'u-url mention'; + a.textContent = acct; - const card = doc.createElement('span'); - card.className = 'h-card'; - card.appendChild(a); - return card; + const card = doc.createElement('span'); + card.className = 'h-card'; + card.appendChild(a); + return card; + } } // this user does not actually exist return doc.createTextNode(acct);