Enhance ActivityPub image attachments with width/height metadata (#17563)

* Initial plan

* enhance(backend): include image dimensions in AP attachments

* fix(backend): guard AP attachment dimension properties

* fix(changelog): move AP dimensions note to 2026.6.0

* Update CHANGELOG.md

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
This commit is contained in:
Copilot 2026-06-12 20:47:12 +09:00 committed by GitHub
commit ec6b1cc6a8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 28 additions and 0 deletions

View file

@ -172,6 +172,8 @@ export class ApRendererService {
mediaType: file.webpublicType ?? file.type,
url: this.driveFileEntityService.getPublicUrl(file),
name: file.comment,
width: file.properties?.width,
height: file.properties?.height,
sensitive: file.isSensitive,
};
}

View file

@ -34,6 +34,8 @@ export interface IObject {
href?: string;
tag?: IObject | IObject[];
sensitive?: boolean;
width?: number;
height?: number;
}
/**

View file

@ -15,6 +15,7 @@ import { Test } from '@nestjs/testing';
import { MockResolver } from '../misc/mock-resolver.js';
import type { IActor, IApDocument, ICollection, IObject, IPost } from '@/core/activitypub/type.js';
import type { MiRemoteUser } from '@/models/User.js';
import type { MiDriveFile } from '@/models/DriveFile.js';
import { ApImageService } from '@/core/activitypub/models/ApImageService.js';
import { ApNoteService } from '@/core/activitypub/models/ApNoteService.js';
import { ApPersonService } from '@/core/activitypub/models/ApPersonService.js';
@ -399,6 +400,28 @@ describe('ActivityPub', () => {
});
describe('Images', () => {
test('Render image document with dimensions', () => {
const rendered = rendererService.renderDocument({
id: genAidx(Date.now()),
type: 'image/png',
webpublicType: null,
url: 'https://example.test/files/image.png',
webpublicUrl: null,
comment: null,
isSensitive: false,
properties: { width: 3600, height: 1890 },
uri: null,
userHost: null,
isLink: false,
webpublicAccessKey: null,
} as MiDriveFile);
assert.strictEqual(rendered.type, 'Document');
assert.strictEqual(rendered.mediaType, 'image/png');
assert.strictEqual(rendered.width, 3600);
assert.strictEqual(rendered.height, 1890);
});
test('Create images', async () => {
const imageObject: IApDocument = {
type: 'Document',