diff --git a/packages/backend/migration/1716345771510-SuspendedStateInsteadOfIsSspended.js b/packages/backend/migration/1716345771510-SuspendedStateInsteadOfIsSspended.js new file mode 100644 index 000000000000..92c9a814b29c --- /dev/null +++ b/packages/backend/migration/1716345771510-SuspendedStateInsteadOfIsSspended.js @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class SuspendedStateInsteadOfIsSspended1716345771510 { + name = 'SuspendedStateInsteadOfIsSspended1716345771510' + + async up(queryRunner) { + await queryRunner.query(`CREATE TYPE "public"."instance_suspendedstate_enum" AS ENUM('none', 'manuallySuspended', 'goneSuspended', 'autoSuspendedForNotResponding')`); + + await queryRunner.query(`DROP INDEX "public"."IDX_34500da2e38ac393f7bb6b299c"`); + + await queryRunner.query(`ALTER TABLE "instance" RENAME COLUMN "isSuspended" TO "suspendedState"`); + + await queryRunner.query(`ALTER TABLE "instance" ALTER COLUMN "suspendedState" DROP DEFAULT`); + + await queryRunner.query(`ALTER TABLE "instance" ALTER COLUMN "suspendedState" TYPE "public"."instance_suspendedstate_enum" USING ( + CASE "suspendedState" + WHEN TRUE THEN 'manuallySuspended'::instance_suspendedstate_enum + ELSE 'none'::instance_suspendedstate_enum + END + )`); + //await queryRunner.query(`ALTER TABLE "instance" ALTER COLUMN "suspendedState" TYPE "public"."instance_suspendedstate_enum" USING "suspendedState"::instance_suspendedstate_enum`); + + await queryRunner.query(`ALTER TABLE "instance" ALTER COLUMN "suspendedState" SET DEFAULT 'none'`); + + await queryRunner.query(`CREATE INDEX "IDX_f6d861bb95acd4639c5015d00c" ON "instance" ("suspendedState") `); + } + + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "public"."IDX_f6d861bb95acd4639c5015d00c"`); + + await queryRunner.query(`ALTER TABLE "instance" ALTER COLUMN "suspendedState" DROP DEFAULT`); + +// await queryRunner.query(`ALTER TABLE "instance" ALTER COLUMN "suspendedState" TYPE boolean`); + await queryRunner.query(`ALTER TABLE "instance" ALTER COLUMN "suspendedState" TYPE boolean USING ( + CASE "suspendedState" + WHEN 'none'::instance_suspendedstate_enum THEN FALSE + ELSE TRUE + END + )`); + + await queryRunner.query(`ALTER TABLE "instance" ALTER COLUMN "suspendedState" SET DEFAULT false`); + + await queryRunner.query(`ALTER TABLE "instance" RENAME COLUMN "suspendedState" TO "isSuspended"`); + + await queryRunner.query(`CREATE INDEX "IDX_34500da2e38ac393f7bb6b299c" ON "instance" ("isSuspended") `); + + await queryRunner.query(`DROP TYPE "public"."instance_suspendedstate_enum"`); + } +} diff --git a/packages/backend/src/core/entities/InstanceEntityService.ts b/packages/backend/src/core/entities/InstanceEntityService.ts index e46bd8b9637e..aa2fa9a9b493 100644 --- a/packages/backend/src/core/entities/InstanceEntityService.ts +++ b/packages/backend/src/core/entities/InstanceEntityService.ts @@ -39,7 +39,8 @@ export class InstanceEntityService { followingCount: instance.followingCount, followersCount: instance.followersCount, isNotResponding: instance.isNotResponding, - isSuspended: instance.isSuspended, + isSuspended: instance.suspendedState != 'none', + suspendedState: instance.suspendedState, isBlocked: this.utilityService.isBlockedHost(meta.blockedHosts, instance.host), softwareName: instance.softwareName, softwareVersion: instance.softwareVersion, diff --git a/packages/backend/src/models/Instance.ts b/packages/backend/src/models/Instance.ts index 6d276209859a..e096f418efe7 100644 --- a/packages/backend/src/models/Instance.ts +++ b/packages/backend/src/models/Instance.ts @@ -89,13 +89,14 @@ export class MiInstance { public notRespondingSince: Date | null; /** - * このインスタンスへの配信を停止するか + * このインスタンスへの配信状態 */ @Index() - @Column('boolean', { - default: false, + @Column('enum', { + default: 'none', + enum: ['none', 'manuallySuspended', 'goneSuspended', 'autoSuspendedForNotResponding'], }) - public isSuspended: boolean; + public suspendedState: 'none' | 'manuallySuspended' | 'goneSuspended' | 'autoSuspendedForNotResponding'; @Column('varchar', { length: 64, nullable: true, diff --git a/packages/backend/src/models/json-schema/federation-instance.ts b/packages/backend/src/models/json-schema/federation-instance.ts index 42d98fe5238e..283bc43f21a2 100644 --- a/packages/backend/src/models/json-schema/federation-instance.ts +++ b/packages/backend/src/models/json-schema/federation-instance.ts @@ -45,6 +45,11 @@ export const packedFederationInstanceSchema = { type: 'boolean', optional: false, nullable: false, }, + suspendedState: { + type: 'string', + nullable: false, optional: false, + enum: ['none', 'manuallySuspended', 'goneSuspended', 'autoSuspendedForNotResponding'], + }, isBlocked: { type: 'boolean', optional: false, nullable: false, diff --git a/packages/backend/src/queue/processors/DeliverProcessorService.ts b/packages/backend/src/queue/processors/DeliverProcessorService.ts index f2be75166e73..7efec669bab6 100644 --- a/packages/backend/src/queue/processors/DeliverProcessorService.ts +++ b/packages/backend/src/queue/processors/DeliverProcessorService.ts @@ -22,6 +22,7 @@ import { UtilityService } from '@/core/UtilityService.js'; import { bindThis } from '@/decorators.js'; import { QueueLoggerService } from '../QueueLoggerService.js'; import type { DeliverJobData } from '../types.js'; +import {Not} from "typeorm"; @Injectable() export class DeliverProcessorService { @@ -62,7 +63,7 @@ export class DeliverProcessorService { if (suspendedHosts == null) { suspendedHosts = await this.instancesRepository.find({ where: { - isSuspended: true, + suspendedState: Not("none"), }, }); this.suspendedHostsCache.set(suspendedHosts); @@ -103,9 +104,9 @@ export class DeliverProcessorService { }); } else if (i.notRespondingSince) { // 1週間以上不通ならサスペンド - if (i.notRespondingSince.getTime() <= Date.now() - 1000 * 60 * 60 * 24 * 7) { + if (i.suspendedState == 'none' && i.notRespondingSince.getTime() <= Date.now() - 1000 * 60 * 60 * 24 * 7) { this.federatedInstanceService.update(i.id, { - isSuspended: true, + suspendedState: 'autoSuspendedForNotResponding', }); } } @@ -125,7 +126,7 @@ export class DeliverProcessorService { if (job.data.isSharedInbox && res.statusCode === 410) { this.federatedInstanceService.fetch(host).then(i => { this.federatedInstanceService.update(i.id, { - isSuspended: true, + suspendedState: 'goneSuspended', }); }); throw new Bull.UnrecoverableError(`${host} is gone`); diff --git a/packages/backend/src/server/api/ApiServerService.ts b/packages/backend/src/server/api/ApiServerService.ts index e99244cdd02d..886d8dc5ece5 100644 --- a/packages/backend/src/server/api/ApiServerService.ts +++ b/packages/backend/src/server/api/ApiServerService.ts @@ -137,7 +137,7 @@ export class ApiServerService { const instances = await this.instancesRepository.find({ select: ['host'], where: { - isSuspended: false, + suspendedState: 'none', }, }); diff --git a/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts b/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts index 0bcdc2a4b81e..ef88ebaac5d0 100644 --- a/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts +++ b/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts @@ -46,12 +46,19 @@ export default class extends Endpoint { // eslint- throw new Error('instance not found'); } + let isSuspendedBefore = instance.suspendedState !== 'none'; + let suspendedState: undefined | 'manuallySuspended' | 'none'; + + if (ps.isSuspended != null && isSuspendedBefore !== ps.isSuspended) { + suspendedState = ps.isSuspended ? 'manuallySuspended' : 'none'; + } + await this.federatedInstanceService.update(instance.id, { - isSuspended: ps.isSuspended, + suspendedState, moderationNote: ps.moderationNote, }); - if (ps.isSuspended != null && instance.isSuspended !== ps.isSuspended) { + if (ps.isSuspended != null && isSuspendedBefore !== ps.isSuspended) { if (ps.isSuspended) { this.moderationLogService.log(me, 'suspendRemoteInstance', { id: instance.id, diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index 302587ccfa6b..a71b708ec0b0 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -4475,6 +4475,8 @@ export type components = { followersCount: number; isNotResponding: boolean; isSuspended: boolean; + /** @enum {string} */ + suspendedState: 'none' | 'manuallySuspended' | 'goneSuspended' | 'autoSuspendedForNotResponding'; isBlocked: boolean; /** @example misskey */ softwareName: string | null;