diff --git a/packages/backend/src/core/UserSuspendService.ts b/packages/backend/src/core/UserSuspendService.ts index 7772845bc5..3d109e0a40 100644 --- a/packages/backend/src/core/UserSuspendService.ts +++ b/packages/backend/src/core/UserSuspendService.ts @@ -56,7 +56,10 @@ export class UserSuspendService { isRemoteSuspended: true, }); - this.postSuspend(user, true); + (async () => { + await this.postSuspend(user, true).catch((e: any) => { }); + await this.suspendFollowings(user).catch((e: any) => { }); + })(); } @bindThis @@ -73,7 +76,7 @@ export class UserSuspendService { (async () => { await this.postUnsuspend(user, false).catch((e: any) => { }); - await this.restoreFollowings(user).catch((e: any) => { console.error(e); }); + await this.restoreFollowings(user).catch((e: any) => { }); })(); } @@ -83,7 +86,10 @@ export class UserSuspendService { isRemoteSuspended: false, }); - this.postUnsuspend(user, true); + (async () => { + await this.postUnsuspend(user, true).catch((e: any) => { }); + await this.restoreFollowings(user).catch((e: any) => { }); + })(); } @bindThis diff --git a/packages/backend/src/core/activitypub/models/ApPersonService.ts b/packages/backend/src/core/activitypub/models/ApPersonService.ts index 4e548347f0..fdba16eab4 100644 --- a/packages/backend/src/core/activitypub/models/ApPersonService.ts +++ b/packages/backend/src/core/activitypub/models/ApPersonService.ts @@ -38,6 +38,7 @@ import { RoleService } from '@/core/RoleService.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; import type { AccountMoveService } from '@/core/AccountMoveService.js'; import { checkHttps } from '@/misc/check-https.js'; +import { UserSuspendService } from '@/core/UserSuspendService.js'; import { getApId, getApType, getOneApHrefNullable, isActor, isCollection, isCollectionOrOrderedCollection, isPropertyValue } from '../type.js'; import { extractApHashtags } from './tag.js'; import type { OnModuleInit } from '@nestjs/common'; @@ -48,7 +49,6 @@ import type { ApLoggerService } from '../ApLoggerService.js'; import type { ApImageService } from './ApImageService.js'; import type { IActor, ICollection, IObject, IOrderedCollection } from '../type.js'; -import { UserSuspendService } from '@/core/UserSuspendService.js'; const nameLength = 128; const summaryLength = 2048; @@ -606,10 +606,12 @@ export class ApPersonService implements OnModuleInit { //#region suspend if (exist.isRemoteSuspended === false && person.suspended === true) { // リモートサーバーでアカウントが凍結された + this.logger.info(`Remote User Suspended: acct=${exist.username}@${exist.host} id=${exist.id} uri=${exist.uri}`); this.userSuspendService.suspendFromRemote({ id: exist.id, host: exist.host }); } if (exist.isRemoteSuspended === true && person.suspended === false) { // リモートサーバーでアカウントが解凍された + this.logger.info(`Remote User Unsuspended: acct=${exist.username}@${exist.host} id=${exist.id} uri=${exist.uri}`); this.userSuspendService.unsuspendFromRemote({ id: exist.id, host: exist.host }); } //#endregion diff --git a/packages/backend/src/server/api/endpoints/users/followers.ts b/packages/backend/src/server/api/endpoints/users/followers.ts index 3afba603a2..d2dd8cd744 100644 --- a/packages/backend/src/server/api/endpoints/users/followers.ts +++ b/packages/backend/src/server/api/endpoints/users/followers.ts @@ -137,13 +137,15 @@ export default class extends Endpoint { // eslint- const query = this.queryService.makePaginationQuery(this.followingsRepository.createQueryBuilder('following'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('following.followeeId = :userId', { userId: user.id }) - .andWhere('following.isFollowerSuspended = false') + .andWhere('following.isFollowerSuspended = FALSE') .innerJoinAndSelect('following.follower', 'follower'); const followings = await query .limit(ps.limit) .getMany(); + console.log(followings); + return await this.followingEntityService.packMany(followings, me, { populateFollower: true }); }); } diff --git a/packages/backend/test-federation/test/user-suspension.test.ts b/packages/backend/test-federation/test/user-suspension.test.ts index e5d119d564..a2e6fb787d 100644 --- a/packages/backend/test-federation/test/user-suspension.test.ts +++ b/packages/backend/test-federation/test/user-suspension.test.ts @@ -35,13 +35,15 @@ describe('User Suspension', () => { await aAdmin.client.request('admin/suspend-user', { userId: alice.id }); await sleep(); - const following = await bob.client.request('users/following', { userId: bob.id }); - strictEqual(following.length, 0); // no following relation + const aliceInBRaw = await bAdmin.client.request('admin/show-user', { userId: aliceInB.id }); + strictEqual(aliceInBRaw.isRemoteSuspended, true); + const renewedAliceInB = await bob.client.request('users/show', { userId: aliceInB.id }); + strictEqual(renewedAliceInB.isSuspended, true); await rejects( async () => await bob.client.request('following/create', { userId: aliceInB.id }), (err: any) => { - strictEqual(err.code, 'NO_SUCH_USER'); + strictEqual(err.code, 'ALREADY_FOLLOWING'); return true; }, ); @@ -51,35 +53,18 @@ describe('User Suspension', () => { await aAdmin.client.request('admin/unsuspend-user', { userId: alice.id }); await sleep(); - const followers = await alice.client.request('users/followers', { userId: alice.id }); - strictEqual(followers.length, 1); // FIXME: followers are not deleted?? + const aliceInBRenewed = await bAdmin.client.request('admin/show-user', { userId: aliceInB.id }); + strictEqual(aliceInBRenewed.isRemoteSuspended, false); - /** - * FIXME: still rejected! - * seems to can't process Undo Delete activity because it is not implemented - * related @see https://github.com/misskey-dev/misskey/issues/13273 - */ await rejects( async () => await bob.client.request('following/create', { userId: aliceInB.id }), (err: any) => { - strictEqual(err.code, 'NO_SUCH_USER'); - return true; - }, - ); - - // FIXME: resolving also fails - await rejects( - async () => await resolveRemoteUser('a.test', alice.id, bob), - (err: any) => { - strictEqual(err.code, 'INTERNAL_ERROR'); + strictEqual(err.code, 'ALREADY_FOLLOWING'); return true; }, ); }); - /** - * instead of simple unsuspension, let's tell existence by following from Alice - */ test('Alice can follow Bob', async () => { await alice.client.request('following/create', { userId: bobInA.id }); await sleep(); @@ -87,29 +72,23 @@ describe('User Suspension', () => { const bobFollowers = await bob.client.request('users/followers', { userId: bob.id }); strictEqual(bobFollowers.length, 1); // followed by Alice assert(bobFollowers[0].follower != null); - const renewedaliceInB = bobFollowers[0].follower; - assert(aliceInB.username === renewedaliceInB.username); - assert(aliceInB.host === renewedaliceInB.host); - assert(aliceInB.id !== renewedaliceInB.id); // TODO: Same username and host, but their ids are different! Is it OK? + const renewedAliceInB = bobFollowers[0].follower; + assert(aliceInB.username === renewedAliceInB.username); + assert(aliceInB.host === renewedAliceInB.host); + assert(aliceInB.id === renewedAliceInB.id); + }); - const following = await bob.client.request('users/following', { userId: bob.id }); - strictEqual(following.length, 0); // following are deleted + test('Alice follows Bob, and Alice gets suspended, the following relation hidden', async () => { + await aAdmin.client.request('admin/suspend-user', { userId: alice.id }); + await sleep(1000); - // Bob tries to follow Alice - await bob.client.request('following/create', { userId: renewedaliceInB.id }); - await sleep(); + const renewedAliceInB = await bob.client.request('users/show', { userId: aliceInB.id }); + strictEqual(renewedAliceInB.isSuspended, true); + const aliceInBRaw = await bAdmin.client.request('admin/show-user', { userId: aliceInB.id }); + strictEqual(aliceInBRaw.isRemoteSuspended, true); - const aliceFollowers = await alice.client.request('users/followers', { userId: alice.id }); - strictEqual(aliceFollowers.length, 1); - - // FIXME: but resolving still fails ... - await rejects( - async () => await resolveRemoteUser('a.test', alice.id, bob), - (err: any) => { - strictEqual(err.code, 'INTERNAL_ERROR'); - return true; - }, - ); + const bobFollowers = await bob.client.request('users/followers', { userId: bob.id }); + strictEqual(bobFollowers.length, 0); // Relation is hidden }); }); });