mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-14 08:45:44 +02:00
fix(backend): handle array or string in alsoKnownAs (#17275)
* fix: handle array or string in alsoKnownAs, closes #17274 * style: use more idiomatic toArray() for UserEntityService handling of alsoKnownAs * fix: handle array-valued or unwrapped alsoKnownAs in ApPersonService * doc: note about bugfix for alsoKnownAs
This commit is contained in:
@@ -376,7 +376,7 @@ export class ApPersonService implements OnModuleInit {
|
||||
isLocked: person.manuallyApprovesFollowers,
|
||||
movedToUri: person.movedTo,
|
||||
movedAt: person.movedTo ? new Date() : null,
|
||||
alsoKnownAs: person.alsoKnownAs,
|
||||
alsoKnownAs: toArray(person.alsoKnownAs),
|
||||
isExplorable: person.discoverable,
|
||||
username: person.preferredUsername,
|
||||
usernameLower: person.preferredUsername?.toLowerCase(),
|
||||
@@ -568,7 +568,7 @@ export class ApPersonService implements OnModuleInit {
|
||||
isCat: (person as any).isCat === true,
|
||||
isLocked: person.manuallyApprovesFollowers,
|
||||
movedToUri: person.movedTo ?? null,
|
||||
alsoKnownAs: person.alsoKnownAs ?? null,
|
||||
alsoKnownAs: person.alsoKnownAs ? toArray(person.alsoKnownAs) : null,
|
||||
isExplorable: person.discoverable,
|
||||
...(await this.resolveAvatarAndBanner(exist, person.icon, person.image).catch(() => ({}))),
|
||||
} as Partial<MiRemoteUser> & Pick<MiRemoteUser, 'isBot' | 'isCat' | 'isLocked' | 'movedToUri' | 'alsoKnownAs' | 'isExplorable'>;
|
||||
|
||||
@@ -51,6 +51,7 @@ import { ChatService } from '@/core/ChatService.js';
|
||||
import type { OnModuleInit } from '@nestjs/common';
|
||||
import type { NoteEntityService } from './NoteEntityService.js';
|
||||
import type { PageEntityService } from './PageEntityService.js';
|
||||
import { toArray } from '@/misc/prelude/array.js';
|
||||
|
||||
const Ajv = _Ajv.default;
|
||||
const ajv = new Ajv();
|
||||
@@ -527,10 +528,10 @@ export class UserEntityService implements OnModuleInit {
|
||||
url: profile!.url,
|
||||
uri: user.uri,
|
||||
movedTo: user.movedToUri ? this.apPersonService.resolvePerson(user.movedToUri).then(user => user.id).catch(() => null) : null,
|
||||
alsoKnownAs: user.alsoKnownAs
|
||||
? Promise.all(user.alsoKnownAs.map(uri => this.apPersonService.fetchPerson(uri).then(user => user?.id).catch(() => null)))
|
||||
.then(xs => xs.length === 0 ? null : xs.filter(x => x != null))
|
||||
: null,
|
||||
alsoKnownAs: user.alsoKnownAs ?
|
||||
Promise.all(toArray(user.alsoKnownAs).map(uri => this.apPersonService.fetchPerson(uri).then(user => user?.id).catch(() => null)))
|
||||
.then(xs => xs.length === 0 ? null : xs.filter(x => x != null))
|
||||
: null,
|
||||
createdAt: this.idService.parse(user.id).date.toISOString(),
|
||||
updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null,
|
||||
lastFetchedAt: user.lastFetchedAt ? user.lastFetchedAt.toISOString() : null,
|
||||
|
||||
@@ -224,6 +224,51 @@ describe('ActivityPub', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('alsoKnownAs field', () => {
|
||||
test('Handle alsoKnownAs as an array', async () => {
|
||||
const actor = {
|
||||
...createRandomActor(),
|
||||
alsoKnownAs: ['https://example.com/users/alice', 'https://example.com/users/alice2'],
|
||||
};
|
||||
|
||||
resolver.register(actor.id, actor);
|
||||
|
||||
const user = await personService.createPerson(actor.id, resolver);
|
||||
|
||||
assert.deepStrictEqual(user.alsoKnownAs, actor.alsoKnownAs);
|
||||
});
|
||||
|
||||
test('Handle alsoKnownAs as a string', async () => {
|
||||
const actor = {
|
||||
...createRandomActor(),
|
||||
alsoKnownAs: 'https://example.com/users/alice',
|
||||
};
|
||||
|
||||
resolver.register(actor.id, actor);
|
||||
|
||||
const user = await personService.createPerson(actor.id, resolver);
|
||||
|
||||
assert.deepStrictEqual(user.alsoKnownAs, [actor.alsoKnownAs]);
|
||||
});
|
||||
|
||||
test('Update person with alsoKnownAs as a string', async () => {
|
||||
const actor = createRandomActor();
|
||||
resolver.register(actor.id, actor);
|
||||
const user = await personService.createPerson(actor.id, resolver);
|
||||
|
||||
const updatedActor = {
|
||||
...actor,
|
||||
alsoKnownAs: 'https://example.com/users/alice',
|
||||
};
|
||||
resolver.register(actor.id, updatedActor);
|
||||
|
||||
await personService.updatePerson(actor.id, resolver, updatedActor);
|
||||
|
||||
const updatedUser = await personService.fetchPerson(actor.id);
|
||||
assert.deepStrictEqual(updatedUser?.alsoKnownAs, [updatedActor.alsoKnownAs]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Collection visibility', () => {
|
||||
test('Public following/followers', async () => {
|
||||
const actor = createRandomActor();
|
||||
|
||||
@@ -248,6 +248,16 @@ describe('UserEntityService', () => {
|
||||
expect(actual.achievements).toEqual(achievements);
|
||||
});
|
||||
|
||||
test('alsoKnownAs as string does not throw', async () => {
|
||||
const me = await createUser();
|
||||
const who = await createUser();
|
||||
|
||||
const whoWithStringAlsoKnownAs: MiUser = { ...who, alsoKnownAs: 'https://remote.example.com/users/alice' as any };
|
||||
|
||||
const actual = await service.pack(whoWithStringAlsoKnownAs, me, { schema: 'UserDetailedNotMe' }) as any;
|
||||
expect(Array.isArray(actual.alsoKnownAs)).toBe(true);
|
||||
});
|
||||
|
||||
describe('packManyによるpreloadがある時、preloadが無い時とpackの結果が同じになるか見たい', () => {
|
||||
test('no-preload', async() => {
|
||||
const me = await createUser();
|
||||
|
||||
Reference in New Issue
Block a user