enhance(backend): ActivityPub Deliver queueでBodyを事前処理するように (misskey-dev#12916) (MisskeyIO#327)
Co-authored-by: MeiMei <30769358+mei23@users.noreply.github.com> Co-authored-by: riku6460 <17585784+riku6460@users.noreply.github.com>
This commit is contained in:
		| @@ -17,6 +17,7 @@ import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, Obj | |||||||
| import type { DbJobData, DeliverJobData, RelationshipJobData, ThinUser } from '../queue/types.js'; | import type { DbJobData, DeliverJobData, RelationshipJobData, ThinUser } from '../queue/types.js'; | ||||||
| import type httpSignature from '@peertube/http-signature'; | import type httpSignature from '@peertube/http-signature'; | ||||||
| import type * as Bull from 'bullmq'; | import type * as Bull from 'bullmq'; | ||||||
|  | import { ApRequestCreator } from '@/core/activitypub/ApRequestService.js'; | ||||||
|  |  | ||||||
| @Injectable() | @Injectable() | ||||||
| export class QueueService { | export class QueueService { | ||||||
| @@ -75,11 +76,15 @@ export class QueueService { | |||||||
| 		if (content == null) return null; | 		if (content == null) return null; | ||||||
| 		if (to == null) return null; | 		if (to == null) return null; | ||||||
|  |  | ||||||
|  | 		const contentBody = JSON.stringify(content); | ||||||
|  | 		const digest = ApRequestCreator.createDigest(contentBody); | ||||||
|  |  | ||||||
| 		const data: DeliverJobData = { | 		const data: DeliverJobData = { | ||||||
| 			user: { | 			user: { | ||||||
| 				id: user.id, | 				id: user.id, | ||||||
| 			}, | 			}, | ||||||
| 			content, | 			content: contentBody, | ||||||
|  | 			digest, | ||||||
| 			to, | 			to, | ||||||
| 			isSharedInbox, | 			isSharedInbox, | ||||||
| 		}; | 		}; | ||||||
| @@ -104,6 +109,8 @@ export class QueueService { | |||||||
| 	@bindThis | 	@bindThis | ||||||
| 	public async deliverMany(user: ThinUser, content: IActivity | null, inboxes: Map<string, boolean>) { | 	public async deliverMany(user: ThinUser, content: IActivity | null, inboxes: Map<string, boolean>) { | ||||||
| 		if (content == null) return null; | 		if (content == null) return null; | ||||||
|  | 		const contentBody = JSON.stringify(content); | ||||||
|  | 		const digest = ApRequestCreator.createDigest(contentBody); | ||||||
|  |  | ||||||
| 		const opts = { | 		const opts = { | ||||||
| 			attempts: this.config.deliverJobMaxAttempts ?? 12, | 			attempts: this.config.deliverJobMaxAttempts ?? 12, | ||||||
| @@ -118,7 +125,8 @@ export class QueueService { | |||||||
| 			name: d[0], | 			name: d[0], | ||||||
| 			data: { | 			data: { | ||||||
| 				user, | 				user, | ||||||
| 				content, | 				content: contentBody, | ||||||
|  | 				digest, | ||||||
| 				to: d[0], | 				to: d[0], | ||||||
| 				isSharedInbox: d[1], | 				isSharedInbox: d[1], | ||||||
| 			}, | 			}, | ||||||
|   | |||||||
| @@ -34,9 +34,9 @@ type PrivateKey = { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| export class ApRequestCreator { | export class ApRequestCreator { | ||||||
| 	static createSignedPost(args: { key: PrivateKey, url: string, body: string, additionalHeaders: Record<string, string> }): Signed { | 	static createSignedPost(args: { key: PrivateKey, url: string, body: string, digest?: string, additionalHeaders: Record<string, string> }): Signed { | ||||||
| 		const u = new URL(args.url); | 		const u = new URL(args.url); | ||||||
| 		const digestHeader = `SHA-256=${crypto.createHash('sha256').update(args.body).digest('base64')}`; | 		const digestHeader = args.digest ?? this.createDigest(args.body); | ||||||
|  |  | ||||||
| 		const request: Request = { | 		const request: Request = { | ||||||
| 			url: u.href, | 			url: u.href, | ||||||
| @@ -59,6 +59,10 @@ export class ApRequestCreator { | |||||||
| 		}; | 		}; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	static createDigest(body: string) { | ||||||
|  | 		return `SHA-256=${crypto.createHash('sha256').update(body).digest('base64')}`; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	static createSignedGet(args: { key: PrivateKey, url: string, additionalHeaders: Record<string, string> }): Signed { | 	static createSignedGet(args: { key: PrivateKey, url: string, additionalHeaders: Record<string, string> }): Signed { | ||||||
| 		const u = new URL(args.url); | 		const u = new URL(args.url); | ||||||
|  |  | ||||||
| @@ -145,8 +149,8 @@ export class ApRequestService { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	@bindThis | 	@bindThis | ||||||
| 	public async signedPost(user: { id: MiUser['id'] }, url: string, object: unknown): Promise<void> { | 	public async signedPost(user: { id: MiUser['id'] }, url: string, object: unknown, digest?: string): Promise<void> { | ||||||
| 		const body = JSON.stringify(object); | 		const body = typeof object === 'string' ? object : JSON.stringify(object); | ||||||
|  |  | ||||||
| 		const keypair = await this.userKeypairService.getUserKeypair(user.id); | 		const keypair = await this.userKeypairService.getUserKeypair(user.id); | ||||||
|  |  | ||||||
| @@ -157,6 +161,7 @@ export class ApRequestService { | |||||||
| 			}, | 			}, | ||||||
| 			url, | 			url, | ||||||
| 			body, | 			body, | ||||||
|  | 			digest, | ||||||
| 			additionalHeaders: { | 			additionalHeaders: { | ||||||
| 			}, | 			}, | ||||||
| 		}); | 		}); | ||||||
|   | |||||||
| @@ -72,7 +72,7 @@ export class DeliverProcessorService { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		try { | 		try { | ||||||
| 			await this.apRequestService.signedPost(job.data.user, job.data.to, job.data.content); | 			await this.apRequestService.signedPost(job.data.user, job.data.to, job.data.content, job.data.digest); | ||||||
|  |  | ||||||
| 			// Update stats | 			// Update stats | ||||||
| 			this.federatedInstanceService.fetch(host).then(i => { | 			this.federatedInstanceService.fetch(host).then(i => { | ||||||
|   | |||||||
| @@ -16,7 +16,9 @@ export type DeliverJobData = { | |||||||
| 	/** Actor */ | 	/** Actor */ | ||||||
| 	user: ThinUser; | 	user: ThinUser; | ||||||
| 	/** Activity */ | 	/** Activity */ | ||||||
| 	content: unknown; | 	content: string; | ||||||
|  | 	/** Digest header */ | ||||||
|  | 	digest: string; | ||||||
| 	/** inbox URL to deliver */ | 	/** inbox URL to deliver */ | ||||||
| 	to: string; | 	to: string; | ||||||
| 	/** whether it is sharedInbox */ | 	/** whether it is sharedInbox */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 まっちゃとーにゅ
					まっちゃとーにゅ