diff --git a/CHANGELOG.md b/CHANGELOG.md index f705bae06..ac0e270a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ You should also include the user name that made the change. - 代わりに今後任意の検索プロバイダを設定できる仕組みを構想しています。その仕組みを使えば今まで通りElasticsearchも利用できます - Migrate to Yarn Berry (v3.2.1) @ThatOneCalculator - You may have to `yarn run clean-all`, `sudo corepack enable` and `yarn set version berry` before running `yarn install` if you're still on yarn classic +- インスタンスブロックはサブドメインにも適用されるようになります - ロールの導入に伴い、いくつかの機能がロールと統合されました - モデレーターはロールに統合されました。今までのモデレーター情報は失われるため、予めモデレーター一覧を記録しておき、アップデート後にモデレーターロールを作りアサインし直してください。 - サイレンスはロールに統合されました。今までのユーザーは恩赦されるため、予めサイレンス一覧を記録しておくのをおすすめします。 diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 934ee0615..daeacf769 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -193,7 +193,7 @@ clearQueueConfirmText: "未配達の投稿は配送されなくなります。 clearCachedFiles: "キャッシュをクリア" clearCachedFilesConfirm: "キャッシュされたリモートファイルをすべて削除しますか?" blockedInstances: "ブロックしたインスタンス" -blockedInstancesDescription: "ブロックしたいインスタンスのホストを改行で区切って設定します。ブロックされたインスタンスは、このインスタンスとやり取りできなくなります。" +blockedInstancesDescription: "ブロックしたいインスタンスのホストを改行で区切って設定します。ブロックされたインスタンスは、このインスタンスとやり取りできなくなります。サブドメインもブロックされます。" muteAndBlock: "ミュートとブロック" mutedUsers: "ミュートしたユーザー" blockedUsers: "ブロックしたユーザー" diff --git a/packages/backend/src/core/UtilityService.ts b/packages/backend/src/core/UtilityService.ts index 1412e6e9a..d00708a44 100644 --- a/packages/backend/src/core/UtilityService.ts +++ b/packages/backend/src/core/UtilityService.ts @@ -24,6 +24,12 @@ export class UtilityService { return this.toPuny(this.config.host) === this.toPuny(host); } + @bindThis + public isBlockedHost(blockedHosts: string[], host: string | null): boolean { + if (host == null) return false; + return blockedHosts.some(x => `.${host.toLowerCase()}`.endsWith(`.${x}`)); + } + @bindThis public extractDbHost(uri: string): string { const url = new URL(uri); diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index 79a917426..76c8bf68d 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -291,7 +291,7 @@ export class ApInboxService { // アナウンス先をブロックしてたら中断 const meta = await this.metaService.fetch(); - if (meta.blockedHosts.includes(this.utilityService.extractDbHost(uri))) return; + if (this.utilityService.isBlockedHost(meta.blockedHosts, this.utilityService.extractDbHost(uri))) return; const unlock = await this.appLockService.getApLock(uri); diff --git a/packages/backend/src/core/activitypub/ApResolverService.ts b/packages/backend/src/core/activitypub/ApResolverService.ts index dc84f06a6..e51ae3795 100644 --- a/packages/backend/src/core/activitypub/ApResolverService.ts +++ b/packages/backend/src/core/activitypub/ApResolverService.ts @@ -96,7 +96,7 @@ export class Resolver { } const meta = await this.metaService.fetch(); - if (meta.blockedHosts.includes(host)) { + if (this.utilityService.isBlockedHost(meta.blockedHosts, host)) { throw new Error('Instance is blocked'); } diff --git a/packages/backend/src/core/activitypub/models/ApNoteService.ts b/packages/backend/src/core/activitypub/models/ApNoteService.ts index e1d93a08b..c9192f53b 100644 --- a/packages/backend/src/core/activitypub/models/ApNoteService.ts +++ b/packages/backend/src/core/activitypub/models/ApNoteService.ts @@ -324,7 +324,7 @@ export class ApNoteService { // ブロックしてたら中断 const meta = await this.metaService.fetch(); - if (meta.blockedHosts.includes(this.utilityService.extractDbHost(uri))) throw { statusCode: 451 }; + if (this.utilityService.isBlockedHost(meta.blockedHosts, this.utilityService.extractDbHost(uri))) throw { statusCode: 451 }; const unlock = await this.appLockService.getApLock(uri); diff --git a/packages/backend/src/core/chart/charts/federation.ts b/packages/backend/src/core/chart/charts/federation.ts index b8012809f..ae4eb6e48 100644 --- a/packages/backend/src/core/chart/charts/federation.ts +++ b/packages/backend/src/core/chart/charts/federation.ts @@ -61,21 +61,21 @@ export default class FederationChart extends Chart { this.followingsRepository.createQueryBuilder('following') .select('COUNT(DISTINCT following.followeeHost)') .where('following.followeeHost IS NOT NULL') - .andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'following.followeeHost NOT IN (:...blocked)', { blocked: meta.blockedHosts }) + .andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'following.followeeHost NOT ILIKE ANY(ARRAY[:...blocked])', { blocked: meta.blockedHosts.flatMap(x => [x, `%.${x}`]) }) .andWhere(`following.followeeHost NOT IN (${ suspendedInstancesQuery.getQuery() })`) .getRawOne() .then(x => parseInt(x.count, 10)), this.followingsRepository.createQueryBuilder('following') .select('COUNT(DISTINCT following.followerHost)') .where('following.followerHost IS NOT NULL') - .andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'following.followerHost NOT IN (:...blocked)', { blocked: meta.blockedHosts }) + .andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'following.followerHost NOT ILIKE ANY(ARRAY[:...blocked])', { blocked: meta.blockedHosts.flatMap(x => [x, `%.${x}`]) }) .andWhere(`following.followerHost NOT IN (${ suspendedInstancesQuery.getQuery() })`) .getRawOne() .then(x => parseInt(x.count, 10)), this.followingsRepository.createQueryBuilder('following') .select('COUNT(DISTINCT following.followeeHost)') .where('following.followeeHost IS NOT NULL') - .andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'following.followeeHost NOT IN (:...blocked)', { blocked: meta.blockedHosts }) + .andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'following.followeeHost NOT ILIKE ANY(ARRAY[:...blocked])', { blocked: meta.blockedHosts.flatMap(x => [x, `%.${x}`]) }) .andWhere(`following.followeeHost NOT IN (${ suspendedInstancesQuery.getQuery() })`) .andWhere(`following.followeeHost IN (${ pubsubSubQuery.getQuery() })`) .setParameters(pubsubSubQuery.getParameters()) @@ -84,7 +84,7 @@ export default class FederationChart extends Chart { this.instancesRepository.createQueryBuilder('instance') .select('COUNT(instance.id)') .where(`instance.host IN (${ subInstancesQuery.getQuery() })`) - .andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'instance.host NOT IN (:...blocked)', { blocked: meta.blockedHosts }) + .andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'instance.host NOT ILIKE ANY(ARRAY[:...blocked])', { blocked: meta.blockedHosts.flatMap(x => [x, `%.${x}`]) }) .andWhere('instance.isSuspended = false') .andWhere('instance.isNotResponding = false') .getRawOne() @@ -92,7 +92,7 @@ export default class FederationChart extends Chart { this.instancesRepository.createQueryBuilder('instance') .select('COUNT(instance.id)') .where(`instance.host IN (${ pubInstancesQuery.getQuery() })`) - .andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'instance.host NOT IN (:...blocked)', { blocked: meta.blockedHosts }) + .andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'instance.host NOT ILIKE ANY(ARRAY[:...blocked])', { blocked: meta.blockedHosts.flatMap(x => [x, `%.${x}`]) }) .andWhere('instance.isSuspended = false') .andWhere('instance.isNotResponding = false') .getRawOne() diff --git a/packages/backend/src/core/entities/InstanceEntityService.ts b/packages/backend/src/core/entities/InstanceEntityService.ts index 81d02bb33..c8bb74deb 100644 --- a/packages/backend/src/core/entities/InstanceEntityService.ts +++ b/packages/backend/src/core/entities/InstanceEntityService.ts @@ -7,8 +7,8 @@ import type { } from '@/models/entities/Blocking.js'; import type { User } from '@/models/entities/User.js'; import type { Instance } from '@/models/entities/Instance.js'; import { MetaService } from '@/core/MetaService.js'; +import { UtilityService } from '../UtilityService.js'; import { bindThis } from '@/decorators.js'; -import { UserEntityService } from './UserEntityService.js'; @Injectable() export class InstanceEntityService { @@ -17,6 +17,8 @@ export class InstanceEntityService { private instancesRepository: InstancesRepository, private metaService: MetaService, + + private utilityService: UtilityService, ) { } @@ -35,7 +37,7 @@ export class InstanceEntityService { followersCount: instance.followersCount, isNotResponding: instance.isNotResponding, isSuspended: instance.isSuspended, - isBlocked: meta.blockedHosts.includes(instance.host), + isBlocked: this.utilityService.isBlockedHost(meta.blockedHosts, instance.host), softwareName: instance.softwareName, softwareVersion: instance.softwareVersion, openRegistrations: instance.openRegistrations, diff --git a/packages/backend/src/queue/processors/DeliverProcessorService.ts b/packages/backend/src/queue/processors/DeliverProcessorService.ts index c5e4a6651..10fcb5684 100644 --- a/packages/backend/src/queue/processors/DeliverProcessorService.ts +++ b/packages/backend/src/queue/processors/DeliverProcessorService.ts @@ -56,7 +56,7 @@ export class DeliverProcessorService { // ブロックしてたら中断 const meta = await this.metaService.fetch(); - if (meta.blockedHosts.includes(this.utilityService.toPuny(host))) { + if (this.utilityService.isBlockedHost(meta.blockedHosts, this.utilityService.toPuny(host))) { return 'skip (blocked)'; } diff --git a/packages/backend/src/queue/processors/InboxProcessorService.ts b/packages/backend/src/queue/processors/InboxProcessorService.ts index d03363784..f814368a7 100644 --- a/packages/backend/src/queue/processors/InboxProcessorService.ts +++ b/packages/backend/src/queue/processors/InboxProcessorService.ts @@ -76,7 +76,7 @@ export class InboxProcessorService { // ブロックしてたら中断 const meta = await this.metaService.fetch(); - if (meta.blockedHosts.includes(host)) { + if (this.utilityService.isBlockedHost(meta.blockedHosts, host)) { return `Blocked request: ${host}`; } @@ -158,7 +158,7 @@ export class InboxProcessorService { // ブロックしてたら中断 const ldHost = this.utilityService.extractDbHost(authUser.user.uri); - if (meta.blockedHosts.includes(ldHost)) { + if (this.utilityService.isBlockedHost(meta.blockedHosts, ldHost)) { return `Blocked request: ${ldHost}`; } } else { diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts index c5b44b6b8..aacd634ed 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -139,7 +139,7 @@ export default class extends Endpoint { } if (Array.isArray(ps.blockedHosts)) { - set.blockedHosts = ps.blockedHosts.filter(Boolean); + set.blockedHosts = ps.blockedHosts.filter(Boolean).map(x => x.toLowerCase()); } if (ps.themeColor !== undefined) { diff --git a/packages/backend/src/server/api/endpoints/ap/show.ts b/packages/backend/src/server/api/endpoints/ap/show.ts index 1068a2eec..9470dd3cb 100644 --- a/packages/backend/src/server/api/endpoints/ap/show.ts +++ b/packages/backend/src/server/api/endpoints/ap/show.ts @@ -117,7 +117,7 @@ export default class extends Endpoint { private async fetchAny(uri: string, me: CacheableLocalUser | null | undefined): Promise | null> { // ブロックしてたら中断 const fetchedMeta = await this.metaService.fetch(); - if (fetchedMeta.blockedHosts.includes(this.utilityService.extractDbHost(uri))) return null; + if (this.utilityService.isBlockedHost(fetchedMeta.blockedHosts, this.utilityService.extractDbHost(uri))) return null; let local = await this.mergePack(me, ...await Promise.all([ this.apDbResolverService.getUserFromApId(uri),