From 57cac0aa23bd9340c58d81e80798a66fcc7e09cf Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Sun, 12 Mar 2023 04:11:37 +0100 Subject: [PATCH] fix(backend/ApRendererService): allow announces with visibility: followers (#10291) * fix(backend/ApRendererService): allow announces with visibility: followers * Update CHANGELOG.md --------- Co-authored-by: syuilo --- CHANGELOG.md | 1 + .../src/core/activitypub/ApRendererService.ts | 3 +++ packages/backend/test/e2e/note.ts | 25 +++++++++++++++++++ packages/backend/test/unit/activitypub.ts | 13 ++++++++++ 4 files changed, 42 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b96b6178..0b6c79571 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ You should also include the user name that made the change. - ロールで広告を無効にするとadmin/adsでプレビューがでてこない問題を修正 - /api-consoleページにアクセスすると404が出る問題を修正 - SMTP Login id length is too short +- API上で`visibility`を`followers`に設定してrenoteすると連合や削除で不具合が発生する問題を修正 - AWS S3からのファイル削除でNoSuchKeyエラーが出ると進めらない状態になる問題を修正 - fix(frontend): Safariでプラグインが複数ある場合に正常に読み込まれない問題を修正 diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index 4601eca2f..0d03e3d90 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -91,6 +91,9 @@ export class ApRendererService { } else if (note.visibility === 'home') { to = [`${attributedTo}/followers`]; cc = ['https://www.w3.org/ns/activitystreams#Public']; + } else if (note.visibility === 'followers') { + to = [`${attributedTo}/followers`]; + cc = []; } else { throw new Error('renderAnnounce: cannot render non-public note'); } diff --git a/packages/backend/test/e2e/note.ts b/packages/backend/test/e2e/note.ts index 1b5f9580d..f286152e8 100644 --- a/packages/backend/test/e2e/note.ts +++ b/packages/backend/test/e2e/note.ts @@ -136,6 +136,31 @@ describe('Note', () => { assert.strictEqual(res.body.createdNote.renote.text, bobPost.text); }); + test('visibility: followersでrenoteできる', async () => { + const createRes = await api('/notes/create', { + text: 'test', + visibility: 'followers', + }, alice); + + assert.strictEqual(createRes.status, 200); + + const renoteId = createRes.body.createdNote.id; + const renoteRes = await api('/notes/create', { + visibility: 'followers', + renoteId, + }, alice); + + assert.strictEqual(renoteRes.status, 200); + assert.strictEqual(renoteRes.body.createdNote.renoteId, renoteId); + assert.strictEqual(renoteRes.body.createdNote.visibility, 'followers'); + + const deleteRes = await api('/notes/delete', { + noteId: renoteRes.body.createdNote.id, + }, alice); + + assert.strictEqual(deleteRes.status, 204); + }); + test('文字数ぎりぎりで怒られない', async () => { const post = { text: '!'.repeat(3000), diff --git a/packages/backend/test/unit/activitypub.ts b/packages/backend/test/unit/activitypub.ts index 5335dff6d..146998937 100644 --- a/packages/backend/test/unit/activitypub.ts +++ b/packages/backend/test/unit/activitypub.ts @@ -7,12 +7,14 @@ import { jest } from '@jest/globals'; import { ApNoteService } from '@/core/activitypub/models/ApNoteService.js'; import { ApPersonService } from '@/core/activitypub/models/ApPersonService.js'; +import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; import { GlobalModule } from '@/GlobalModule.js'; import { CoreModule } from '@/core/CoreModule.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; import { LoggerService } from '@/core/LoggerService.js'; import type { IActor } from '@/core/activitypub/type.js'; import { MockResolver } from '../misc/mock-resolver.js'; +import { Note } from '@/models/index.js'; const host = 'https://host1.test'; @@ -33,6 +35,7 @@ function createRandomActor(): IActor & { id: string } { describe('ActivityPub', () => { let noteService: ApNoteService; let personService: ApPersonService; + let rendererService: ApRendererService; let resolver: MockResolver; beforeEach(async () => { @@ -45,6 +48,7 @@ describe('ActivityPub', () => { noteService = app.get(ApNoteService); personService = app.get(ApPersonService); + rendererService = app.get(ApRendererService); resolver = new MockResolver(await app.resolve(LoggerService)); // Prevent ApPersonService from fetching instance, as it causes Jest import-after-test error @@ -113,4 +117,13 @@ describe('ActivityPub', () => { assert.strictEqual(user.name, null); }); }); + + describe('Renderer', () => { + test('Render an announce with visibility: followers', () => { + rendererService.renderAnnounce(null, { + createdAt: new Date(0), + visibility: 'followers', + } as Note); + }); + }); });