add setting to disable proxy account (resolves #766)

This commit is contained in:
Hazelnoot 2025-05-01 12:07:38 -04:00
parent b124c39ed2
commit 8dce293dff
9 changed files with 68 additions and 5 deletions

8
locales/index.d.ts vendored
View file

@ -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;

View file

@ -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"`);
}
}

View file

@ -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 } }]);
}

View file

@ -759,4 +759,9 @@ export class MiMeta {
default: 'always',
})
public allowUnsignedFetch: InstanceUnsignedFetchOption;
@Column('boolean', {
default: false,
})
public enableProxyAccount: boolean;
}

View file

@ -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<typeof meta, typeof paramDef> { // eslint-
federationHosts: instance.federationHosts,
hasLegacyAuthFetchSetting: config.checkActivityPubGetSignature != null,
allowUnsignedFetch: instance.allowUnsignedFetch,
enableProxyAccount: instance.enableProxyAccount,
};
});
}

View file

@ -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<typeof meta, typeof paramDef> { // 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);

View file

@ -275,6 +275,11 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="_gaps">
<MkInfo>{{ i18n.ts.proxyAccountDescription }}</MkInfo>
<MkSwitch v-model="proxyAccountForm.state.enabled">
<template #label>{{ i18n.ts.enableProxyAccount }}</template>
<template #caption>{{ i18n.ts.enableProxyAccountDescription }}</template>
</MkSwitch>
<MkTextarea v-model="proxyAccountForm.state.description" :max="500" tall mfmAutocomplete :mfmPreview="true">
<template #label>{{ i18n.ts._profile.description }}</template>
<template #caption>{{ i18n.ts._profile.youCanIncludeHashtags }}</template>
@ -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);
});

View file

@ -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;
};
};
};

View file

@ -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."