From 3fe351df6d4e21f7748c46adfa6ca165abd030c0 Mon Sep 17 00:00:00 2001 From: Johann150 Date: Fri, 10 Jun 2022 08:06:02 +0200 Subject: [PATCH] fix: catch errors from packing with detail Packing with detail can cause an error if the reply or renote are not visible to the user, even though the original note is visible to the user. --- .../src/server/api/endpoints/notes/show.ts | 4 ++ packages/backend/src/server/web/index.ts | 39 ++++++++++++------- packages/backend/src/services/note/create.ts | 26 ++++++++----- 3 files changed, 44 insertions(+), 25 deletions(-) diff --git a/packages/backend/src/server/api/endpoints/notes/show.ts b/packages/backend/src/server/api/endpoints/notes/show.ts index 0f5d0c942..c9c148747 100644 --- a/packages/backend/src/server/api/endpoints/notes/show.ts +++ b/packages/backend/src/server/api/endpoints/notes/show.ts @@ -39,6 +39,10 @@ export default define(meta, paramDef, async (ps, user) => { }); return await Notes.pack(note, user, { + // FIXME: packing with detail may throw an error if the reply or renote is not visible (#8774) detail: true, + }).catch(err => { + if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); + throw err; }); }); diff --git a/packages/backend/src/server/web/index.ts b/packages/backend/src/server/web/index.ts index 3e2011587..03ee8d5ba 100644 --- a/packages/backend/src/server/web/index.ts +++ b/packages/backend/src/server/web/index.ts @@ -322,23 +322,32 @@ router.get('/notes/:note', async (ctx, next) => { }); if (note) { - const _note = await Notes.pack(note); - const profile = await UserProfiles.findOneByOrFail({ userId: note.userId }); - const meta = await fetchMeta(); - await ctx.render('note', { - note: _note, - profile, - avatarUrl: await Users.getAvatarUrl(await Users.findOneByOrFail({ id: note.userId })), - // TODO: Let locale changeable by instance setting - summary: getNoteSummary(_note), - instanceName: meta.name || 'Misskey', - icon: meta.iconUrl, - themeColor: meta.themeColor, - }); + try { + // FIXME: packing with detail may throw an error if the reply or renote is not visible (#8774) + const _note = await Notes.pack(note); + const profile = await UserProfiles.findOneByOrFail({ userId: note.userId }); + const meta = await fetchMeta(); + await ctx.render('note', { + note: _note, + profile, + avatarUrl: await Users.getAvatarUrl(await Users.findOneByOrFail({ id: note.userId })), + // TODO: Let locale changeable by instance setting + summary: getNoteSummary(_note), + instanceName: meta.name || 'Misskey', + icon: meta.iconUrl, + themeColor: meta.themeColor, + }); - ctx.set('Cache-Control', 'public, max-age=15'); + ctx.set('Cache-Control', 'public, max-age=15'); - return; + return; + } catch (err) { + if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') { + // note not visible to user + } else { + throw err; + } + } } await next(); diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 61a811d70..0fce38029 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -640,17 +640,23 @@ async function createMentionedEvents(mentionedUsers: MinimumUser[], note: Note, continue; } - const detailPackedNote = await Notes.pack(note, u, { - detail: true, - }); - - publishMainStream(u.id, 'mention', detailPackedNote); - - const webhooks = (await getActiveWebhooks()).filter(x => x.userId === u.id && x.on.includes('mention')); - for (const webhook of webhooks) { - webhookDeliver(webhook, 'mention', { - note: detailPackedNote, + // note with "specified" visibility might not be visible to mentioned users + try { + const detailPackedNote = await Notes.pack(note, u, { + detail: true, }); + + publishMainStream(u.id, 'mention', detailPackedNote); + + const webhooks = (await getActiveWebhooks()).filter(x => x.userId === u.id && x.on.includes('mention')); + for (const webhook of webhooks) { + webhookDeliver(webhook, 'mention', { + note: detailPackedNote, + }); + } + } catch (err) { + if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') continue; + throw err; } // Create notification