refactor(backend): SystemWebhookで送信されるペイロードの型を追加 (#14980)
This commit is contained in:
		| @@ -154,9 +154,9 @@ export class AbuseReportNotificationService implements OnApplicationShutdown { | ||||
| 		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, | ||||
| 				reporter: usersMap.get(it.reporterId) ?? null, | ||||
| 				targetUser: usersMap.get(it.targetUserId) ?? null, | ||||
| 				assignee: it.assigneeId ? (usersMap.get(it.assigneeId) ?? null) : null, | ||||
| 			}; | ||||
| 		}); | ||||
|  | ||||
|   | ||||
| @@ -7,13 +7,15 @@ import { randomUUID } from 'node:crypto'; | ||||
| import { Inject, Injectable } from '@nestjs/common'; | ||||
| import type { IActivity } from '@/core/activitypub/type.js'; | ||||
| import type { MiDriveFile } from '@/models/DriveFile.js'; | ||||
| import type { MiWebhook, WebhookEventTypes, webhookEventTypes } from '@/models/Webhook.js'; | ||||
| import type { MiWebhook, WebhookEventTypes } from '@/models/Webhook.js'; | ||||
| import type { MiSystemWebhook, SystemWebhookEventType } from '@/models/SystemWebhook.js'; | ||||
| import type { Config } from '@/config.js'; | ||||
| import { DI } from '@/di-symbols.js'; | ||||
| import { bindThis } from '@/decorators.js'; | ||||
| import type { Antenna } from '@/server/api/endpoints/i/import-antennas.js'; | ||||
| import { ApRequestCreator } from '@/core/activitypub/ApRequestService.js'; | ||||
| import { type SystemWebhookPayload } from '@/core/SystemWebhookService.js'; | ||||
| import { type UserWebhookPayload } from './UserWebhookService.js'; | ||||
| import type { | ||||
| 	DbJobData, | ||||
| 	DeliverJobData, | ||||
| @@ -30,12 +32,11 @@ import type { | ||||
| 	ObjectStorageQueue, | ||||
| 	RelationshipQueue, | ||||
| 	SystemQueue, | ||||
| 	UserWebhookDeliverQueue, | ||||
| 	SystemWebhookDeliverQueue, | ||||
| 	UserWebhookDeliverQueue, | ||||
| } from './QueueModule.js'; | ||||
| import type httpSignature from '@peertube/http-signature'; | ||||
| import type * as Bull from 'bullmq'; | ||||
| import { type UserWebhookPayload } from './UserWebhookService.js'; | ||||
|  | ||||
| @Injectable() | ||||
| export class QueueService { | ||||
| @@ -501,10 +502,10 @@ export class QueueService { | ||||
| 	 * @see SystemWebhookDeliverProcessorService | ||||
| 	 */ | ||||
| 	@bindThis | ||||
| 	public systemWebhookDeliver( | ||||
| 	public systemWebhookDeliver<T extends SystemWebhookEventType>( | ||||
| 		webhook: MiSystemWebhook, | ||||
| 		type: SystemWebhookEventType, | ||||
| 		content: unknown, | ||||
| 		type: T, | ||||
| 		content: SystemWebhookPayload<T>, | ||||
| 		opts?: { attempts?: number }, | ||||
| 	) { | ||||
| 		const data: SystemWebhookDeliverJobData = { | ||||
|   | ||||
| @@ -15,8 +15,39 @@ import { QueueService } from '@/core/QueueService.js'; | ||||
| import { ModerationLogService } from '@/core/ModerationLogService.js'; | ||||
| import { LoggerService } from '@/core/LoggerService.js'; | ||||
| import Logger from '@/logger.js'; | ||||
| import { Packed } from '@/misc/json-schema.js'; | ||||
| import { AbuseReportResolveType } from '@/models/AbuseUserReport.js'; | ||||
| import { ModeratorInactivityRemainingTime } from '@/queue/processors/CheckModeratorsActivityProcessorService.js'; | ||||
| import type { OnApplicationShutdown } from '@nestjs/common'; | ||||
|  | ||||
| export type AbuseReportPayload = { | ||||
| 	id: string; | ||||
| 	targetUserId: string; | ||||
| 	targetUser: Packed<'UserLite'> | null; | ||||
| 	targetUserHost: string | null; | ||||
| 	reporterId: string; | ||||
| 	reporter: Packed<'UserLite'> | null; | ||||
| 	reporterHost: string | null; | ||||
| 	assigneeId: string | null; | ||||
| 	assignee: Packed<'UserLite'> | null; | ||||
| 	resolved: boolean; | ||||
| 	forwarded: boolean; | ||||
| 	comment: string; | ||||
| 	moderationNote: string; | ||||
| 	resolvedAs: AbuseReportResolveType | null; | ||||
| }; | ||||
|  | ||||
| export type InactiveModeratorsWarningPayload = { | ||||
| 	remainingTime: ModeratorInactivityRemainingTime; | ||||
| }; | ||||
|  | ||||
| export type SystemWebhookPayload<T extends SystemWebhookEventType> = | ||||
| 	T extends 'abuseReport' | 'abuseReportResolved' ? AbuseReportPayload : | ||||
| 	T extends 'userCreated' ? Packed<'UserLite'> : | ||||
| 	T extends 'inactiveModeratorsWarning' ? InactiveModeratorsWarningPayload : | ||||
| 	T extends 'inactiveModeratorsInvitationOnlyChanged' ? Record<string, never> : | ||||
| 		never; | ||||
|  | ||||
| @Injectable() | ||||
| export class SystemWebhookService implements OnApplicationShutdown { | ||||
| 	private logger: Logger; | ||||
| @@ -168,7 +199,7 @@ export class SystemWebhookService implements OnApplicationShutdown { | ||||
| 	public async enqueueSystemWebhook<T extends SystemWebhookEventType>( | ||||
| 		webhook: MiSystemWebhook | MiSystemWebhook['id'], | ||||
| 		type: T, | ||||
| 		content: unknown, | ||||
| 		content: SystemWebhookPayload<T>, | ||||
| 	) { | ||||
| 		const webhookEntity = typeof webhook === 'string' | ||||
| 			? (await this.fetchActiveSystemWebhooks()).find(a => a.id === webhook) | ||||
|   | ||||
| @@ -7,7 +7,7 @@ import { Injectable } from '@nestjs/common'; | ||||
| import { MiAbuseUserReport, MiNote, MiUser, MiWebhook } from '@/models/_.js'; | ||||
| import { bindThis } from '@/decorators.js'; | ||||
| import { MiSystemWebhook, type SystemWebhookEventType } from '@/models/SystemWebhook.js'; | ||||
| import { SystemWebhookService } from '@/core/SystemWebhookService.js'; | ||||
| import { AbuseReportPayload, SystemWebhookPayload, SystemWebhookService } from '@/core/SystemWebhookService.js'; | ||||
| import { Packed } from '@/misc/json-schema.js'; | ||||
| import { type WebhookEventTypes } from '@/models/Webhook.js'; | ||||
| import { type UserWebhookPayload, UserWebhookService } from '@/core/UserWebhookService.js'; | ||||
| @@ -16,13 +16,7 @@ import { ModeratorInactivityRemainingTime } from '@/queue/processors/CheckModera | ||||
|  | ||||
| const oneDayMillis = 24 * 60 * 60 * 1000; | ||||
|  | ||||
| type AbuseUserReportDto = Omit<MiAbuseUserReport, 'targetUser' | 'reporter' | 'assignee'> & { | ||||
| 	targetUser: Packed<'UserLite'> | null, | ||||
| 	reporter: Packed<'UserLite'> | null, | ||||
| 	assignee: Packed<'UserLite'> | null, | ||||
| }; | ||||
|  | ||||
| function generateAbuseReport(override?: Partial<MiAbuseUserReport>): AbuseUserReportDto { | ||||
| function generateAbuseReport(override?: Partial<MiAbuseUserReport>): AbuseReportPayload { | ||||
| 	const result: MiAbuseUserReport = { | ||||
| 		id: 'dummy-abuse-report1', | ||||
| 		targetUserId: 'dummy-target-user', | ||||
| @@ -389,7 +383,8 @@ export class WebhookTestService { | ||||
| 				break; | ||||
| 			} | ||||
| 			// まだ実装されていない (#9485) | ||||
| 			case 'reaction': return; | ||||
| 			case 'reaction': | ||||
| 				return; | ||||
| 			default: { | ||||
| 				// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||||
| 				const _exhaustiveAssertion: never = params.type; | ||||
| @@ -407,10 +402,10 @@ export class WebhookTestService { | ||||
| 	 * - 送信対象イベント(on)に関する設定 | ||||
| 	 */ | ||||
| 	@bindThis | ||||
| 	public async testSystemWebhook( | ||||
| 	public async testSystemWebhook<T extends SystemWebhookEventType>( | ||||
| 		params: { | ||||
| 			webhookId: MiSystemWebhook['id'], | ||||
| 			type: SystemWebhookEventType, | ||||
| 			type: T, | ||||
| 			override?: Partial<Omit<MiSystemWebhook, 'id'>>, | ||||
| 		}, | ||||
| 	) { | ||||
| @@ -420,7 +415,7 @@ export class WebhookTestService { | ||||
| 		} | ||||
|  | ||||
| 		const webhook = webhooks[0]; | ||||
| 		const send = (contents: unknown) => { | ||||
| 		const send = <U extends SystemWebhookEventType>(type: U, contents: SystemWebhookPayload<U>) => { | ||||
| 			const merged = { | ||||
| 				...webhook, | ||||
| 				...params.override, | ||||
| @@ -428,12 +423,12 @@ export class WebhookTestService { | ||||
|  | ||||
| 			// テスト目的なのでSystemWebhookServiceの機能を経由せず直接キューに追加する(チェック処理などをスキップする意図). | ||||
| 			// また、Jobの試行回数も1回だけ. | ||||
| 			this.queueService.systemWebhookDeliver(merged, params.type, contents, { attempts: 1 }); | ||||
| 			this.queueService.systemWebhookDeliver(merged, type, contents, { attempts: 1 }); | ||||
| 		}; | ||||
|  | ||||
| 		switch (params.type) { | ||||
| 			case 'abuseReport': { | ||||
| 				send(generateAbuseReport({ | ||||
| 				send('abuseReport', generateAbuseReport({ | ||||
| 					targetUserId: dummyUser1.id, | ||||
| 					targetUser: dummyUser1, | ||||
| 					reporterId: dummyUser2.id, | ||||
| @@ -442,7 +437,7 @@ export class WebhookTestService { | ||||
| 				break; | ||||
| 			} | ||||
| 			case 'abuseReportResolved': { | ||||
| 				send(generateAbuseReport({ | ||||
| 				send('abuseReportResolved', generateAbuseReport({ | ||||
| 					targetUserId: dummyUser1.id, | ||||
| 					targetUser: dummyUser1, | ||||
| 					reporterId: dummyUser2.id, | ||||
| @@ -454,7 +449,7 @@ export class WebhookTestService { | ||||
| 				break; | ||||
| 			} | ||||
| 			case 'userCreated': { | ||||
| 				send(toPackedUserLite(dummyUser1)); | ||||
| 				send('userCreated', toPackedUserLite(dummyUser1)); | ||||
| 				break; | ||||
| 			} | ||||
| 			case 'inactiveModeratorsWarning': { | ||||
| @@ -464,15 +459,20 @@ export class WebhookTestService { | ||||
| 					asHours: 24, | ||||
| 				}; | ||||
|  | ||||
| 				send({ | ||||
| 				send('inactiveModeratorsWarning', { | ||||
| 					remainingTime: dummyTime, | ||||
| 				}); | ||||
| 				break; | ||||
| 			} | ||||
| 			case 'inactiveModeratorsInvitationOnlyChanged': { | ||||
| 				send({}); | ||||
| 				send('inactiveModeratorsInvitationOnlyChanged', {}); | ||||
| 				break; | ||||
| 			} | ||||
| 			default: { | ||||
| 				// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||||
| 				const _exhaustiveAssertion: never = params.type; | ||||
| 				return; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 おさむのひと
					おさむのひと