From 8dce293dfff6b38de5d47b580507ceb32be31bb1 Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Thu, 1 May 2025 12:07:38 -0400 Subject: [PATCH] add setting to disable proxy account (resolves #766) --- locales/index.d.ts | 8 ++++++++ ...46029830779-add_meta-enableProxyAccount.js | 16 ++++++++++++++++ packages/backend/src/core/UserListService.ts | 7 +++++-- packages/backend/src/models/Meta.ts | 5 +++++ .../src/server/api/endpoints/admin/meta.ts | 5 +++++ .../server/api/endpoints/admin/update-meta.ts | 8 ++++++++ .../frontend/src/pages/admin/settings.vue | 19 ++++++++++++++++--- packages/misskey-js/src/autogen/types.ts | 2 ++ sharkey-locales/en-US.yml | 3 +++ 9 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 packages/backend/migration/1746029830779-add_meta-enableProxyAccount.js diff --git a/locales/index.d.ts b/locales/index.d.ts index 55b248b241..4d5ae94762 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -12939,6 +12939,14 @@ export interface Locale extends ILocale { * Deleted */ "deleted": string; + /** + * Enable the proxy account. + */ + "enableProxyAccount": string; + /** + * If disabled, then the proxy account will not be used. + */ + "enableProxyAccountDescription": string; } declare const locales: { [lang: string]: Locale; diff --git a/packages/backend/migration/1746029830779-add_meta-enableProxyAccount.js b/packages/backend/migration/1746029830779-add_meta-enableProxyAccount.js new file mode 100644 index 0000000000..2a6aac96af --- /dev/null +++ b/packages/backend/migration/1746029830779-add_meta-enableProxyAccount.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class AddMetaEnableProxyAccount1746029830779 { + name = 'AddMetaEnableProxyAccount1746029830779' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "enableProxyAccount" boolean NOT NULL DEFAULT false`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableProxyAccount"`); + } +} diff --git a/packages/backend/src/core/UserListService.ts b/packages/backend/src/core/UserListService.ts index a4c5eb5416..e7200ab1bf 100644 --- a/packages/backend/src/core/UserListService.ts +++ b/packages/backend/src/core/UserListService.ts @@ -6,7 +6,7 @@ import { Inject, Injectable, OnApplicationShutdown, OnModuleInit } from '@nestjs/common'; import * as Redis from 'ioredis'; import { ModuleRef } from '@nestjs/core'; -import type { UserListMembershipsRepository } from '@/models/_.js'; +import type { MiMeta, UserListMembershipsRepository } from '@/models/_.js'; import type { MiUser } from '@/models/User.js'; import type { MiUserList } from '@/models/UserList.js'; import type { MiUserListMembership } from '@/models/UserListMembership.js'; @@ -40,6 +40,9 @@ export class UserListService implements OnApplicationShutdown, OnModuleInit { @Inject(DI.userListMembershipsRepository) private userListMembershipsRepository: UserListMembershipsRepository, + @Inject(DI.meta) + private readonly meta: MiMeta, + private userEntityService: UserEntityService, private idService: IdService, private globalEventService: GlobalEventService, @@ -110,7 +113,7 @@ export class UserListService implements OnApplicationShutdown, OnModuleInit { this.globalEventService.publishUserListStream(list.id, 'userAdded', await this.userEntityService.pack(target)); // このインスタンス内にこのリモートユーザーをフォローしているユーザーがいなくても投稿を受け取るためにダミーのユーザーがフォローしたということにする - if (this.userEntityService.isRemoteUser(target)) { + if (this.userEntityService.isRemoteUser(target) && this.meta.enableProxyAccount) { const proxy = await this.systemAccountService.fetch('proxy'); this.queueService.createFollowJob([{ from: { id: proxy.id }, to: { id: target.id } }]); } diff --git a/packages/backend/src/models/Meta.ts b/packages/backend/src/models/Meta.ts index 1ccffcfa75..78b3175458 100644 --- a/packages/backend/src/models/Meta.ts +++ b/packages/backend/src/models/Meta.ts @@ -759,4 +759,9 @@ export class MiMeta { default: 'always', }) public allowUnsignedFetch: InstanceUnsignedFetchOption; + + @Column('boolean', { + default: false, + }) + public enableProxyAccount: boolean; } diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index 4ff12a70c4..f059a3ed4d 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -601,6 +601,10 @@ export const meta = { enum: instanceUnsignedFetchOptions, optional: false, nullable: false, }, + enableProxyAccount: { + type: 'boolean', + optional: false, nullable: false, + }, }, }, } as const; @@ -762,6 +766,7 @@ export default class extends Endpoint { // eslint- federationHosts: instance.federationHosts, hasLegacyAuthFetchSetting: config.checkActivityPubGetSignature != null, allowUnsignedFetch: instance.allowUnsignedFetch, + enableProxyAccount: instance.enableProxyAccount, }; }); } 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 2cdb8feb1b..eb73c4b616 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -210,6 +210,10 @@ export const paramDef = { enum: instanceUnsignedFetchOptions, nullable: false, }, + enableProxyAccount: { + type: 'boolean', + nullable: false, + }, }, required: [], } as const; @@ -758,6 +762,10 @@ export default class extends Endpoint { // eslint- set.allowUnsignedFetch = ps.allowUnsignedFetch; } + if (ps.enableProxyAccount !== undefined) { + set.enableProxyAccount = ps.enableProxyAccount; + } + const before = await this.metaService.fetch(true); await this.metaService.update(set); diff --git a/packages/frontend/src/pages/admin/settings.vue b/packages/frontend/src/pages/admin/settings.vue index 40335e7914..c64d602e8b 100644 --- a/packages/frontend/src/pages/admin/settings.vue +++ b/packages/frontend/src/pages/admin/settings.vue @@ -275,6 +275,11 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.proxyAccountDescription }} + + + + + @@ -425,10 +430,18 @@ const federationForm = useForm({ const proxyAccountForm = useForm({ description: proxyAccount.description, + enabled: meta.enableProxyAccount, }, async (state) => { - await os.apiWithDialog('admin/update-proxy-account', { - description: state.description, - }); + if (state.description !== proxyAccount.description) { + await os.apiWithDialog('admin/update-proxy-account', { + description: state.description, + }); + } + if (state.enabled !== proxyAccount.enabled) { + await os.apiWithDialog('admin/update-meta', { + enableProxyAccount: state.enabled, + }); + } fetchInstance(true); }); diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index b96cec5e7b..1868ba44d5 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -9279,6 +9279,7 @@ export type operations = { hasLegacyAuthFetchSetting: boolean; /** @enum {string} */ allowUnsignedFetch: 'never' | 'always' | 'essential'; + enableProxyAccount: boolean; }; }; }; @@ -12225,6 +12226,7 @@ export type operations = { federationHosts?: string[]; /** @enum {string} */ allowUnsignedFetch?: 'never' | 'always' | 'essential'; + enableProxyAccount?: boolean; }; }; }; diff --git a/sharkey-locales/en-US.yml b/sharkey-locales/en-US.yml index 58cfd745c4..aaef102ed7 100644 --- a/sharkey-locales/en-US.yml +++ b/sharkey-locales/en-US.yml @@ -533,3 +533,6 @@ _followRequest: sent: "Sent" deleted: "Deleted" + +enableProxyAccount: "Enable the proxy account." +enableProxyAccountDescription: "If disabled, then the proxy account will not be used."