add option to reject reports from an instance
This commit is contained in:
parent
ac1e5a0fb5
commit
4da0d4be71
|
@ -223,6 +223,7 @@ stopActivityDelivery: "Stop sending activities"
|
|||
blockThisInstance: "Block this instance"
|
||||
silenceThisInstance: "Silence this instance"
|
||||
mediaSilenceThisInstance: "Silence media from this instance"
|
||||
rejectReports: "Reject reports from this instance"
|
||||
operations: "Operations"
|
||||
software: "Software"
|
||||
version: "Version"
|
||||
|
@ -2572,6 +2573,8 @@ _moderationLogTypes:
|
|||
resetPassword: "Password reset"
|
||||
suspendRemoteInstance: "Remote instance suspended"
|
||||
unsuspendRemoteInstance: "Remote instance unsuspended"
|
||||
rejectRemoteInstanceReports: "Rejected reports from remote instance"
|
||||
acceptRemoteInstanceReports: "Accepted reports from remote instance"
|
||||
updateRemoteInstanceNote: "Moderation note updated for remote instance."
|
||||
markSensitiveDriveFile: "File marked as sensitive"
|
||||
unmarkSensitiveDriveFile: "File unmarked as sensitive"
|
||||
|
|
|
@ -908,6 +908,10 @@ export interface Locale extends ILocale {
|
|||
* サーバーをメディアサイレンス
|
||||
*/
|
||||
"mediaSilenceThisInstance": string;
|
||||
/**
|
||||
* Reject reports from this instance
|
||||
*/
|
||||
"rejectReports": string;
|
||||
/**
|
||||
* 操作
|
||||
*/
|
||||
|
@ -3128,6 +3132,10 @@ export interface Locale extends ILocale {
|
|||
* 返信にサーバー情報を表示する
|
||||
*/
|
||||
"showTickerOnReplies": string;
|
||||
/**
|
||||
* 猫の話し方を無効にする
|
||||
*/
|
||||
"disableCatSpeak": string;
|
||||
/**
|
||||
* 検索MFMの検索エンジン
|
||||
*/
|
||||
|
@ -9972,6 +9980,14 @@ export interface Locale extends ILocale {
|
|||
* リモートサーバーを再開
|
||||
*/
|
||||
"unsuspendRemoteInstance": string;
|
||||
/**
|
||||
* Rejected reports from remote instance
|
||||
*/
|
||||
"rejectRemoteInstanceReports": string;
|
||||
/**
|
||||
* Accepted reports from remote instance
|
||||
*/
|
||||
"acceptRemoteInstanceReports": string;
|
||||
/**
|
||||
* リモートサーバーのモデレーションノート更新
|
||||
*/
|
||||
|
|
|
@ -223,6 +223,7 @@ stopActivityDelivery: "アクティビティの配送を停止"
|
|||
blockThisInstance: "このサーバーをブロック"
|
||||
silenceThisInstance: "サーバーをサイレンス"
|
||||
mediaSilenceThisInstance: "サーバーをメディアサイレンス"
|
||||
rejectReports: "Reject reports from this instance"
|
||||
operations: "操作"
|
||||
software: "ソフトウェア"
|
||||
version: "バージョン"
|
||||
|
@ -2640,6 +2641,8 @@ _moderationLogTypes:
|
|||
resetPassword: "パスワードをリセット"
|
||||
suspendRemoteInstance: "リモートサーバーを停止"
|
||||
unsuspendRemoteInstance: "リモートサーバーを再開"
|
||||
rejectRemoteInstanceReports: "Rejected reports from remote instance"
|
||||
acceptRemoteInstanceReports: "Accepted reports from remote instance"
|
||||
updateRemoteInstanceNote: "リモートサーバーのモデレーションノート更新"
|
||||
markSensitiveDriveFile: "ファイルをセンシティブ付与"
|
||||
unmarkSensitiveDriveFile: "ファイルをセンシティブ解除"
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class AddRejectReports1728177700920 {
|
||||
name = 'AddRejectReports1728177700920'
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "instance" ADD "rejectReports" boolean NOT NULL DEFAULT false`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "rejectReports"`);
|
||||
}
|
||||
}
|
|
@ -39,6 +39,8 @@ import { ApPersonService } from './models/ApPersonService.js';
|
|||
import { ApQuestionService } from './models/ApQuestionService.js';
|
||||
import type { Resolver } from './ApResolverService.js';
|
||||
import type { IAccept, IAdd, IAnnounce, IBlock, ICreate, IDelete, IFlag, IFollow, ILike, IObject, IReject, IRemove, IUndo, IUpdate, IMove, IPost } from './type.js';
|
||||
import * as Bull from 'bullmq';
|
||||
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
|
||||
|
||||
@Injectable()
|
||||
export class ApInboxService {
|
||||
|
@ -83,6 +85,7 @@ export class ApInboxService {
|
|||
private apQuestionService: ApQuestionService,
|
||||
private queueService: QueueService,
|
||||
private globalEventService: GlobalEventService,
|
||||
private federatedInstanceService: FederatedInstanceService,
|
||||
) {
|
||||
this.logger = this.apLoggerService.logger;
|
||||
}
|
||||
|
@ -530,6 +533,12 @@ export class ApInboxService {
|
|||
|
||||
@bindThis
|
||||
private async flag(actor: MiRemoteUser, activity: IFlag): Promise<string> {
|
||||
// Make sure the source instance is allowed to send reports.
|
||||
const instance = await this.federatedInstanceService.fetch(actor.host);
|
||||
if (instance.rejectReports) {
|
||||
throw new Bull.UnrecoverableError(`Rejecting report from instance: ${actor.host}`);
|
||||
}
|
||||
|
||||
// objectは `(User|Note) | (User|Note)[]` だけど、全パターンDBスキーマと対応させられないので
|
||||
// 対象ユーザーは一番最初のユーザー として あとはコメントとして格納する
|
||||
const uris = getApIds(activity.object);
|
||||
|
|
|
@ -159,6 +159,11 @@ export class MiInstance {
|
|||
})
|
||||
public isNSFW: boolean;
|
||||
|
||||
@Column('boolean', {
|
||||
default: false,
|
||||
})
|
||||
public rejectReports: boolean;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 16384, default: '',
|
||||
})
|
||||
|
|
|
@ -25,6 +25,7 @@ export const paramDef = {
|
|||
host: { type: 'string' },
|
||||
isSuspended: { type: 'boolean' },
|
||||
isNSFW: { type: 'boolean' },
|
||||
rejectReports: { type: 'boolean' },
|
||||
moderationNote: { type: 'string' },
|
||||
},
|
||||
required: ['host'],
|
||||
|
@ -57,6 +58,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
await this.federatedInstanceService.update(instance.id, {
|
||||
suspensionState,
|
||||
isNSFW: ps.isNSFW,
|
||||
rejectReports: ps.rejectReports,
|
||||
moderationNote: ps.moderationNote,
|
||||
});
|
||||
|
||||
|
@ -74,6 +76,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
}
|
||||
}
|
||||
|
||||
if (ps.rejectReports != null && instance.rejectReports !== ps.rejectReports) {
|
||||
const message = ps.rejectReports ? 'rejectRemoteInstanceReports' : 'acceptRemoteInstanceReports';
|
||||
this.moderationLogService.log(me, message, {
|
||||
id: instance.id,
|
||||
host: instance.host,
|
||||
});
|
||||
}
|
||||
|
||||
if (ps.moderationNote != null && instance.moderationNote !== ps.moderationNote) {
|
||||
this.moderationLogService.log(me, 'updateRemoteInstanceNote', {
|
||||
id: instance.id,
|
||||
|
|
|
@ -79,6 +79,8 @@ export const moderationLogTypes = [
|
|||
'resetPassword',
|
||||
'suspendRemoteInstance',
|
||||
'unsuspendRemoteInstance',
|
||||
'rejectRemoteInstanceReports',
|
||||
'acceptRemoteInstanceReports',
|
||||
'updateRemoteInstanceNote',
|
||||
'markSensitiveDriveFile',
|
||||
'unmarkSensitiveDriveFile',
|
||||
|
@ -235,6 +237,14 @@ export type ModerationLogPayloads = {
|
|||
id: string;
|
||||
host: string;
|
||||
};
|
||||
rejectRemoteInstanceReports: {
|
||||
id: string;
|
||||
host: string;
|
||||
};
|
||||
acceptRemoteInstanceReports: {
|
||||
id: string;
|
||||
host: string;
|
||||
};
|
||||
updateRemoteInstanceNote: {
|
||||
id: string;
|
||||
host: string;
|
||||
|
|
|
@ -23,6 +23,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
'markSensitiveDriveFile',
|
||||
'resetPassword',
|
||||
'suspendRemoteInstance',
|
||||
'rejectRemoteInstanceReports',
|
||||
'acceptRemoteInstanceReports',
|
||||
].includes(log.type),
|
||||
[$style.logRed]: [
|
||||
'suspend',
|
||||
|
@ -61,6 +63,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<span v-else-if="log.type === 'unmarkSensitiveDriveFile'">: @{{ log.info.fileUserUsername }}{{ log.info.fileUserHost ? '@' + log.info.fileUserHost : '' }}</span>
|
||||
<span v-else-if="log.type === 'suspendRemoteInstance'">: {{ log.info.host }}</span>
|
||||
<span v-else-if="log.type === 'unsuspendRemoteInstance'">: {{ log.info.host }}</span>
|
||||
<span v-else-if="log.type === 'rejectRemoteInstanceReports'">: {{ log.info.host }}</span>
|
||||
<span v-else-if="log.type === 'acceptRemoteInstanceReports'">: {{ log.info.host }}</span>
|
||||
<span v-else-if="log.type === 'createGlobalAnnouncement'">: {{ log.info.announcement.title }}</span>
|
||||
<span v-else-if="log.type === 'updateGlobalAnnouncement'">: {{ log.info.before.title }}</span>
|
||||
<span v-else-if="log.type === 'deleteGlobalAnnouncement'">: {{ log.info.announcement.title }}</span>
|
||||
|
|
|
@ -48,6 +48,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkSwitch v-model="isBlocked" :disabled="!meta || !instance" @update:modelValue="toggleBlock">{{ i18n.ts.blockThisInstance }}</MkSwitch>
|
||||
<MkSwitch v-model="isSilenced" :disabled="!meta || !instance" @update:modelValue="toggleSilenced">{{ i18n.ts.silenceThisInstance }}</MkSwitch>
|
||||
<MkSwitch v-model="isNSFW" :disabled="!instance" @update:modelValue="toggleNSFW">Mark as NSFW</MkSwitch>
|
||||
<MkSwitch v-model="rejectReports" :disabled="!instance" @update:modelValue="toggleRejectReports">{{ i18n.ts.rejectReports }}</MkSwitch>
|
||||
<MkSwitch v-model="isMediaSilenced" :disabled="!meta || !instance" @update:modelValue="toggleMediaSilenced">{{ i18n.ts.mediaSilenceThisInstance }}</MkSwitch>
|
||||
<MkButton @click="refreshMetadata"><i class="ti ti-refresh"></i> Refresh metadata</MkButton>
|
||||
<MkTextarea v-model="moderationNote" manualSave>
|
||||
|
@ -170,6 +171,7 @@ const suspensionState = ref<'none' | 'manuallySuspended' | 'goneSuspended' | 'au
|
|||
const isBlocked = ref(false);
|
||||
const isSilenced = ref(false);
|
||||
const isNSFW = ref(false);
|
||||
const rejectReports = ref(false);
|
||||
const isMediaSilenced = ref(false);
|
||||
const faviconUrl = ref<string | null>(null);
|
||||
const moderationNote = ref('');
|
||||
|
@ -200,6 +202,7 @@ async function fetch(): Promise<void> {
|
|||
isBlocked.value = instance.value?.isBlocked ?? false;
|
||||
isSilenced.value = instance.value?.isSilenced ?? false;
|
||||
isNSFW.value = instance.value?.isNSFW ?? false;
|
||||
rejectReports.value = instance.value?.rejectReports ?? false;
|
||||
isMediaSilenced.value = instance.value?.isMediaSilenced ?? false;
|
||||
faviconUrl.value = getProxiedImageUrlNullable(instance.value?.faviconUrl, 'preview') ?? getProxiedImageUrlNullable(instance.value?.iconUrl, 'preview');
|
||||
moderationNote.value = instance.value?.moderationNote ?? '';
|
||||
|
@ -260,6 +263,14 @@ async function toggleNSFW(): Promise<void> {
|
|||
});
|
||||
}
|
||||
|
||||
async function toggleRejectReports(): Promise<void> {
|
||||
if (!instance.value) throw new Error('No instance?');
|
||||
await misskeyApi('admin/federation/update-instance', {
|
||||
host: instance.value.host,
|
||||
rejectReports: rejectReports.value,
|
||||
});
|
||||
}
|
||||
|
||||
function refreshMetadata(): void {
|
||||
if (!instance.value) throw new Error('No instance?');
|
||||
misskeyApi('admin/federation/refresh-remote-instance-metadata', {
|
||||
|
|
Loading…
Reference in New Issue