enhance(backend): 内部用と外部(ActivityPub)用で違うアセットドメインが使えるようにする (MisskeyIO#572)
resolves MisskeyIO#569
This commit is contained in:
		
							parent
							
								
									4a10205746
								
							
						
					
					
						commit
						197e39781d
					
				|  | @ -100,6 +100,7 @@ type Source = { | |||
| 
 | ||||
| 	bypassRateLimit?: { header: string; value: string }[]; | ||||
| 
 | ||||
| 	remapDriveFileUrlForActivityPub?: { target: string; replacement: string }[]; | ||||
| 	signToActivityPubGet?: boolean; | ||||
| 
 | ||||
| 	perChannelMaxNoteCacheCount?: number; | ||||
|  | @ -160,6 +161,7 @@ export type Config = { | |||
| 	deliverJobMaxAttempts: number | undefined; | ||||
| 	inboxJobMaxAttempts: number | undefined; | ||||
| 	proxyRemoteFiles: boolean | undefined; | ||||
| 	remapDriveFileUrlForActivityPub: { target: string; replacement: string }[] | undefined; | ||||
| 	signToActivityPubGet: boolean | undefined; | ||||
| 
 | ||||
| 	version: string; | ||||
|  | @ -285,6 +287,7 @@ export function loadConfig(): Config { | |||
| 		deliverJobMaxAttempts: config.deliverJobMaxAttempts, | ||||
| 		inboxJobMaxAttempts: config.inboxJobMaxAttempts, | ||||
| 		proxyRemoteFiles: config.proxyRemoteFiles, | ||||
| 		remapDriveFileUrlForActivityPub: config.remapDriveFileUrlForActivityPub, | ||||
| 		signToActivityPubGet: config.signToActivityPubGet, | ||||
| 		mediaProxy: externalMediaProxy ?? internalMediaProxy, | ||||
| 		externalMediaProxyEnabled: externalMediaProxy !== null && externalMediaProxy !== internalMediaProxy, | ||||
|  |  | |||
|  | @ -164,13 +164,20 @@ export class ApRendererService { | |||
| 		return { | ||||
| 			type: 'Document', | ||||
| 			mediaType: file.webpublicType ?? file.type, | ||||
| 			url: this.driveFileEntityService.getPublicUrl(file), | ||||
| 			url: this.driveFileEntityService.getPublicUrl(file, { remapActivityPub: true }), | ||||
| 			name: file.comment, | ||||
| 		}; | ||||
| 	} | ||||
| 
 | ||||
| 	@bindThis | ||||
| 	public renderEmoji(emoji: MiEmoji): IApEmoji { | ||||
| 		// || emoji.originalUrl してるのは後方互換性のため(publicUrlはstringなので??はだめ)
 | ||||
| 		let url = emoji.publicUrl || emoji.originalUrl; | ||||
| 
 | ||||
| 		this.config.remapDriveFileUrlForActivityPub?.forEach(({ target, replacement }) => { | ||||
| 			url = url.replace(target, replacement); | ||||
| 		}); | ||||
| 
 | ||||
| 		return { | ||||
| 			id: `${this.config.url}/emojis/${emoji.name}`, | ||||
| 			type: 'Emoji', | ||||
|  | @ -179,8 +186,7 @@ export class ApRendererService { | |||
| 			icon: { | ||||
| 				type: 'Image', | ||||
| 				mediaType: emoji.type ?? 'image/png', | ||||
| 				// || emoji.originalUrl してるのは後方互換性のため(publicUrlはstringなので??はだめ)
 | ||||
| 				url: emoji.publicUrl || emoji.originalUrl, | ||||
| 				url: url, | ||||
| 			}, | ||||
| 		}; | ||||
| 	} | ||||
|  | @ -243,7 +249,7 @@ export class ApRendererService { | |||
| 	public renderImage(file: MiDriveFile): IApImage { | ||||
| 		return { | ||||
| 			type: 'Image', | ||||
| 			url: this.driveFileEntityService.getPublicUrl(file), | ||||
| 			url: this.driveFileEntityService.getPublicUrl(file, { remapActivityPub: true }), | ||||
| 			sensitive: file.isSensitive, | ||||
| 			name: file.comment, | ||||
| 		}; | ||||
|  |  | |||
|  | @ -267,12 +267,12 @@ export class ApPersonService implements OnModuleInit { | |||
| 		return { | ||||
| 			...( avatar ? { | ||||
| 				avatarId: avatar.id, | ||||
| 				avatarUrl: avatar.url ? this.driveFileEntityService.getPublicUrl(avatar, 'avatar') : null, | ||||
| 				avatarUrl: avatar.url ? this.driveFileEntityService.getPublicUrl(avatar, { mode: 'avatar', remapActivityPub: true }) : null, | ||||
| 				avatarBlurhash: avatar.blurhash, | ||||
| 			} : {}), | ||||
| 			...( banner ? { | ||||
| 				bannerId: banner.id, | ||||
| 				bannerUrl: banner.url ? this.driveFileEntityService.getPublicUrl(banner) : null, | ||||
| 				bannerUrl: banner.url ? this.driveFileEntityService.getPublicUrl(banner, { remapActivityPub: true }) : null, | ||||
| 				bannerBlurhash: banner.blurhash, | ||||
| 			} : {}), | ||||
| 		}; | ||||
|  |  | |||
|  | @ -109,10 +109,10 @@ export class DriveFileEntityService { | |||
| 	} | ||||
| 
 | ||||
| 	@bindThis | ||||
| 	public getPublicUrl(file: MiDriveFile, mode?: 'avatar'): string { // static = thumbnail
 | ||||
| 	public getPublicUrl(file: MiDriveFile, option?: { mode?: 'avatar', remapActivityPub?: boolean }): string { // static = thumbnail
 | ||||
| 		// リモートかつメディアプロキシ
 | ||||
| 		if (file.uri != null && file.userHost != null && this.config.externalMediaProxyEnabled) { | ||||
| 			return this.getProxiedUrl(file.uri, mode); | ||||
| 			return this.getProxiedUrl(file.uri, option?.mode); | ||||
| 		} | ||||
| 
 | ||||
| 		// リモートかつ期限切れはローカルプロキシを試みる
 | ||||
|  | @ -121,17 +121,23 @@ export class DriveFileEntityService { | |||
| 
 | ||||
| 			if (key && !key.match('/')) {	// 古いものはここにオブジェクトストレージキーが入ってるので除外
 | ||||
| 				const url = `${this.config.url}/files/${key}`; | ||||
| 				if (mode === 'avatar') return this.getProxiedUrl(file.uri, 'avatar'); | ||||
| 				if (option?.mode === 'avatar') return this.getProxiedUrl(file.uri, 'avatar'); | ||||
| 				return url; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		const url = file.webpublicUrl ?? file.url; | ||||
| 
 | ||||
| 		if (mode === 'avatar') { | ||||
| 			return this.getProxiedUrl(url, 'avatar'); | ||||
| 		let publicUrl = file.webpublicUrl ?? file.url; | ||||
| 		if (option?.remapActivityPub) { | ||||
| 			this.config.remapDriveFileUrlForActivityPub?.forEach(({ target, replacement }) => { | ||||
| 				publicUrl = publicUrl.replace(target, replacement); | ||||
| 			}); | ||||
| 		} | ||||
| 		return url; | ||||
| 
 | ||||
| 		const url = new URL(publicUrl); | ||||
| 		if (file.isSensitive) url.searchParams.set('sensitive', 'true'); | ||||
| 
 | ||||
| 		if (option?.mode === 'avatar') return this.getProxiedUrl(url.href, 'avatar'); | ||||
| 		else return url.href; | ||||
| 	} | ||||
| 
 | ||||
| 	@bindThis | ||||
|  |  | |||
|  | @ -314,7 +314,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- | |||
| 				if (!avatar.type.startsWith('image/')) throw new ApiError(meta.errors.avatarNotAnImage); | ||||
| 
 | ||||
| 				updates.avatarId = avatar.id; | ||||
| 				updates.avatarUrl = this.driveFileEntityService.getPublicUrl(avatar, 'avatar'); | ||||
| 				updates.avatarUrl = this.driveFileEntityService.getPublicUrl(avatar, { mode: 'avatar' }); | ||||
| 				updates.avatarBlurhash = avatar.blurhash; | ||||
| 			} else if (ps.avatarId === null) { | ||||
| 				updates.avatarId = null; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue