From 88698462a91e0fe15501a44f923a812d169bb030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8A=E3=81=95=E3=82=80=E3=81=AE=E3=81=B2=E3=81=A8?= <46447427+samunohito@users.noreply.github.com> Date: Sat, 5 Oct 2024 12:51:46 +0900 Subject: [PATCH] =?UTF-8?q?feat(backend):=20=E9=80=9A=E5=A0=B1=E3=81=8A?= =?UTF-8?q?=E3=82=88=E3=81=B3=E9=80=9A=E5=A0=B1=E8=A7=A3=E6=B1=BA=E6=99=82?= =?UTF-8?q?=E3=81=AB=E9=80=81=E5=87=BA=E3=81=95=E3=82=8C=E3=82=8BSystemWeb?= =?UTF-8?q?hook=E3=81=AB=E3=83=A6=E3=83=BC=E3=82=B6=E6=83=85=E5=A0=B1?= =?UTF-8?q?=E3=82=92=E5=90=AB=E3=82=81=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= =?UTF-8?q?=E3=81=99=E3=82=8B=20(#14698)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(backend): 通報および通報解決時に送出されるSystemWebhookにユーザ情報を含めるようにする * テスト送信もペイロード形式を合わせる * add spaces * fix test --- CHANGELOG.md | 2 +- .../core/AbuseReportNotificationService.ts | 24 ++++++++++++++++++- .../backend/src/core/WebhookTestService.ts | 20 +++++++++++++--- .../unit/AbuseReportNotificationService.ts | 6 ++++- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a31be063f008..04acc11ac37e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ ### Server - Enhance: セキュリティ向上のため、ログイン時にメール通知を行うように - Enhance: 自分とモデレーター以外のユーザーから二要素認証関連のデータが取得できないように - +- Enhance: 通報および通報解決時に送出されるSystemWebhookにユーザ情報を含めるように ( #14697 ) ## 2024.9.0 diff --git a/packages/backend/src/core/AbuseReportNotificationService.ts b/packages/backend/src/core/AbuseReportNotificationService.ts index fe2c63e7d646..fb7c7bd2c3fc 100644 --- a/packages/backend/src/core/AbuseReportNotificationService.ts +++ b/packages/backend/src/core/AbuseReportNotificationService.ts @@ -22,6 +22,7 @@ import { RoleService } from '@/core/RoleService.js'; import { RecipientMethod } from '@/models/AbuseReportNotificationRecipient.js'; import { ModerationLogService } from '@/core/ModerationLogService.js'; import { SystemWebhookService } from '@/core/SystemWebhookService.js'; +import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { IdService } from './IdService.js'; @Injectable() @@ -42,6 +43,7 @@ export class AbuseReportNotificationService implements OnApplicationShutdown { private emailService: EmailService, private moderationLogService: ModerationLogService, private globalEventService: GlobalEventService, + private userEntityService: UserEntityService, ) { this.redisForSub.on('message', this.onMessage); } @@ -135,6 +137,26 @@ export class AbuseReportNotificationService implements OnApplicationShutdown { return; } + const usersMap = await this.userEntityService.packMany( + [ + ...new Set([ + ...abuseReports.map(it => it.reporter ?? it.reporterId), + ...abuseReports.map(it => it.targetUser ?? it.targetUserId), + ...abuseReports.map(it => it.assignee ?? it.assigneeId), + ].filter(x => x != null)), + ], + null, + { schema: 'UserLite' }, + ).then(it => new Map(it.map(it => [it.id, it]))); + const convertedReports = abuseReports.map(it => { + return { + ...it, + reporter: usersMap.get(it.reporterId), + targetUser: usersMap.get(it.targetUserId), + assignee: it.assigneeId ? usersMap.get(it.assigneeId) : null, + }; + }); + const recipientWebhookIds = await this.fetchWebhookRecipients() .then(it => it .filter(it => it.isActive && it.systemWebhookId && it.method === 'webhook') @@ -142,7 +164,7 @@ export class AbuseReportNotificationService implements OnApplicationShutdown { .filter(x => x != null)); for (const webhookId of recipientWebhookIds) { await Promise.all( - abuseReports.map(it => { + convertedReports.map(it => { return this.systemWebhookService.enqueueSystemWebhook( webhookId, type, diff --git a/packages/backend/src/core/WebhookTestService.ts b/packages/backend/src/core/WebhookTestService.ts index c2764f30e82f..149c753d4cb2 100644 --- a/packages/backend/src/core/WebhookTestService.ts +++ b/packages/backend/src/core/WebhookTestService.ts @@ -15,8 +15,14 @@ import { QueueService } from '@/core/QueueService.js'; const oneDayMillis = 24 * 60 * 60 * 1000; -function generateAbuseReport(override?: Partial): MiAbuseUserReport { - return { +type AbuseUserReportDto = Omit & { + targetUser: Packed<'UserLite'> | null, + reporter: Packed<'UserLite'> | null, + assignee: Packed<'UserLite'> | null, +}; + +function generateAbuseReport(override?: Partial): AbuseUserReportDto { + const result: MiAbuseUserReport = { id: 'dummy-abuse-report1', targetUserId: 'dummy-target-user', targetUser: null, @@ -31,6 +37,13 @@ function generateAbuseReport(override?: Partial): MiAbuseUser reporterHost: null, ...override, }; + + return { + ...result, + targetUser: result.targetUser ? toPackedUserLite(result.targetUser) : null, + reporter: result.reporter ? toPackedUserLite(result.reporter) : null, + assignee: result.assignee ? toPackedUserLite(result.assignee) : null, + }; } function generateDummyUser(override?: Partial): MiUser { @@ -268,7 +281,8 @@ const dummyUser3 = generateDummyUser({ @Injectable() export class WebhookTestService { - public static NoSuchWebhookError = class extends Error {}; + public static NoSuchWebhookError = class extends Error { + }; constructor( private userWebhookService: UserWebhookService, diff --git a/packages/backend/test/unit/AbuseReportNotificationService.ts b/packages/backend/test/unit/AbuseReportNotificationService.ts index e971659070ea..235af29f0dc9 100644 --- a/packages/backend/test/unit/AbuseReportNotificationService.ts +++ b/packages/backend/test/unit/AbuseReportNotificationService.ts @@ -5,6 +5,7 @@ import { jest } from '@jest/globals'; import { Test, TestingModule } from '@nestjs/testing'; +import { randomString } from '../utils.js'; import { AbuseReportNotificationService } from '@/core/AbuseReportNotificationService.js'; import { AbuseReportNotificationRecipientRepository, @@ -25,7 +26,7 @@ import { ModerationLogService } from '@/core/ModerationLogService.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import { RecipientMethod } from '@/models/AbuseReportNotificationRecipient.js'; import { SystemWebhookService } from '@/core/SystemWebhookService.js'; -import { randomString } from '../utils.js'; +import { UserEntityService } from '@/core/entities/UserEntityService.js'; process.env.NODE_ENV = 'test'; @@ -110,6 +111,9 @@ describe('AbuseReportNotificationService', () => { { provide: SystemWebhookService, useFactory: () => ({ enqueueSystemWebhook: jest.fn() }), }, + { + provide: UserEntityService, useFactory: () => ({ pack: (v: any) => v }), + }, { provide: EmailService, useFactory: () => ({ sendEmail: jest.fn() }), },