diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 2c67cb772b..6678f9a8a9 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -369,7 +369,7 @@ export class UserEntityService implements OnModuleInit { ...(opts.detail ? { url: profile!.url, uri: user.uri, - movedToUri: user.movedToUri ? await this.apPersonService.resolvePerson(user.movedToUri) : null, + movedToUri: user.movedToUri ? this.apPersonService.resolvePerson(user.movedToUri).then(user => user.uri).catch(() => null) : null, alsoKnownAs: user.alsoKnownAs, createdAt: user.createdAt.toISOString(), updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null, diff --git a/packages/backend/src/server/api/endpoints/i/known-as.ts b/packages/backend/src/server/api/endpoints/i/known-as.ts index dc96e5e2eb..d63e4a9716 100644 --- a/packages/backend/src/server/api/endpoints/i/known-as.ts +++ b/packages/backend/src/server/api/endpoints/i/known-as.ts @@ -32,6 +32,11 @@ export const meta = { code: 'URI_NULL', id: 'bf326f31-d430-4f97-9933-5d61e4d48a23', }, + forbiddenToSetYourself: { + message: 'You can\'t set yourself as your own alias.', + code: 'FORBIDDEN_TO_SET_YOURSELF', + id: '25c90186-4ab0-49c8-9bba-a1fa6c202ba4', + }, }, } as const; @@ -51,9 +56,6 @@ export default class extends Endpoint { private accountMoveService: AccountMoveService, ) { super(meta, paramDef, async (ps, me) => { - // Check parameter - if (!ps.alsoKnownAs) throw new ApiError(meta.errors.noSuchUser); - let unfiltered = ps.alsoKnownAs; const updates = {} as Partial; @@ -71,6 +73,7 @@ export default class extends Endpoint { this.apiLoggerService.logger.warn(`failed to resolve dstination user: ${e}`); throw new ApiError(meta.errors.noSuchUser); }); + if (knownAs.id === me.id) throw new ApiError(meta.errors.forbiddenToSetYourself); const toUrl = this.accountMoveService.getUserUri(knownAs); if (!toUrl) throw new ApiError(meta.errors.uriNull); diff --git a/packages/backend/test/e2e/move.ts b/packages/backend/test/e2e/move.ts index 7330d50ef3..ee478dea0c 100644 --- a/packages/backend/test/e2e/move.ts +++ b/packages/backend/test/e2e/move.ts @@ -54,6 +54,49 @@ describe('Account Move', () => { await Users.update(bob.id, { alsoKnownAs: null }); }, 1000 * 10); + test('Able to create an alias', async () => { + await api('/i/known-as', { + alsoKnownAs: `@alice@${url.hostname}`, + }, bob); + + const newBob = await Users.findOneByOrFail({ id: bob.id }); + assert.strictEqual(newBob.alsoKnownAs?.length, 1); + assert.strictEqual(newBob.alsoKnownAs[0], `${url.origin}/users/${alice.id}`); + }); + + test('Able to set remote user (but may fail)', async () => { + const res = await api('/i/known-as', { + alsoKnownAs: `@syuilo@example.com`, + }, bob); + + assert.strictEqual(res.status, 400); + assert.strictEqual(res.body.error.code, 'NO_SUCH_USER'); + assert.strictEqual(res.body.error.id, 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5'); + }); + + test('Nothing happen when alias duplicated', async () => { + await api('/i/known-as', { + alsoKnownAs: `@alice@${url.hostname}`, + }, bob); + await api('/i/known-as', { + alsoKnownAs: `@alice@${url.hostname}`, + }, bob); + + const newBob = await Users.findOneByOrFail({ id: bob.id }); + assert.strictEqual(newBob.alsoKnownAs?.length, 1); + assert.strictEqual(newBob.alsoKnownAs[0], `${url.origin}/users/${alice.id}`); + }); + + test('Unable to add itself', async () => { + const res = await api('/i/known-as', { + alsoKnownAs: `@bob@${url.hostname}`, + }, bob); + + assert.strictEqual(res.status, 400); + assert.strictEqual(res.body.error.code, 'FORBIDDEN_TO_SET_YOURSELF'); + assert.strictEqual(res.body.error.id, '25c90186-4ab0-49c8-9bba-a1fa6c202ba4'); + }); + test('Unable to add a nonexisting local account to alsoKnownAs', async () => { const res = await api('/i/known-as', { alsoKnownAs: `@nonexist@${url.hostname}`, @@ -72,10 +115,10 @@ describe('Account Move', () => { alsoKnownAs: `@carol@${url.hostname}`, }, bob); - const newAlice = await Users.findOneByOrFail({ id: bob.id }); - assert.strictEqual(newAlice.alsoKnownAs?.length, 2); - assert.strictEqual(newAlice.alsoKnownAs[0], `${url.origin}/users/${alice.id}`); - assert.strictEqual(newAlice.alsoKnownAs[1], `${url.origin}/users/${carol.id}`); + const newBob = await Users.findOneByOrFail({ id: bob.id }); + assert.strictEqual(newBob.alsoKnownAs?.length, 2); + assert.strictEqual(newBob.alsoKnownAs[0], `${url.origin}/users/${alice.id}`); + assert.strictEqual(newBob.alsoKnownAs[1], `${url.origin}/users/${carol.id}`); }); test('Unable to create an alias without the second @', async () => { @@ -95,7 +138,7 @@ describe('Account Move', () => { assert.strictEqual(res2.body.error.code, 'NO_SUCH_USER'); assert.strictEqual(res2.body.error.id, 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5'); }); - }) + }); describe('Local to Local', () => { let antennaId = ''; diff --git a/packages/misskey-js/src/entities.ts b/packages/misskey-js/src/entities.ts index 34857f431f..9efc062eac 100644 --- a/packages/misskey-js/src/entities.ts +++ b/packages/misskey-js/src/entities.ts @@ -15,7 +15,6 @@ export type UserLite = { avatarUrl: string; avatarBlurhash: string; alsoKnownAs: string[]; - movedToUri: any; emojis: { name: string; url: string; @@ -58,6 +57,7 @@ export type UserDetailed = UserLite & { lang: string | null; lastFetchedAt?: DateString; location: string | null; + movedToUri: string; notesCount: number; pinnedNoteIds: ID[]; pinnedNotes: Note[];