mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-10-26 19:14:12 +00:00 
			
		
		
		
	View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/662 Closes #579, #715, and #716 Approved-by: dakkar <dakkar@thenautilus.net> Approved-by: Marie <github@yuugi.dev>
This commit is contained in:
		
						commit
						28bfd87537
					
				
					 10 changed files with 125 additions and 2 deletions
				
			
		|  | @ -154,6 +154,7 @@ renoteUnmute: "Unmute Boosts" | ||||||
| block: "Block" | block: "Block" | ||||||
| unblock: "Unblock" | unblock: "Unblock" | ||||||
| markAsNSFW: "Mark all media from user as NSFW" | markAsNSFW: "Mark all media from user as NSFW" | ||||||
|  | markInstanceAsNSFW: "Mark as NSFW" | ||||||
| suspend: "Suspend" | suspend: "Suspend" | ||||||
| unsuspend: "Unsuspend" | unsuspend: "Unsuspend" | ||||||
| blockConfirm: "Are you sure that you want to block this account?" | blockConfirm: "Are you sure that you want to block this account?" | ||||||
|  | @ -228,6 +229,7 @@ stopActivityDelivery: "Stop sending activities" | ||||||
| blockThisInstance: "Block this instance" | blockThisInstance: "Block this instance" | ||||||
| silenceThisInstance: "Silence this instance" | silenceThisInstance: "Silence this instance" | ||||||
| mediaSilenceThisInstance: "Silence media from this instance" | mediaSilenceThisInstance: "Silence media from this instance" | ||||||
|  | rejectReports: "Reject reports from this instance" | ||||||
| operations: "Operations" | operations: "Operations" | ||||||
| software: "Software" | software: "Software" | ||||||
| version: "Version" | version: "Version" | ||||||
|  | @ -2579,6 +2581,10 @@ _moderationLogTypes: | ||||||
|   resetPassword: "Password reset" |   resetPassword: "Password reset" | ||||||
|   suspendRemoteInstance: "Remote instance suspended" |   suspendRemoteInstance: "Remote instance suspended" | ||||||
|   unsuspendRemoteInstance: "Remote instance unsuspended" |   unsuspendRemoteInstance: "Remote instance unsuspended" | ||||||
|  |   setRemoteInstanceNSFW: "Set remote instance as NSFW" | ||||||
|  |   unsetRemoteInstanceNSFW: "Set remote instance as NSFW" | ||||||
|  |   rejectRemoteInstanceReports: "Rejected reports from remote instance" | ||||||
|  |   acceptRemoteInstanceReports: "Accepted reports from remote instance" | ||||||
|   updateRemoteInstanceNote: "Moderation note updated for remote instance." |   updateRemoteInstanceNote: "Moderation note updated for remote instance." | ||||||
|   markSensitiveDriveFile: "File marked as sensitive" |   markSensitiveDriveFile: "File marked as sensitive" | ||||||
|   unmarkSensitiveDriveFile: "File unmarked as sensitive" |   unmarkSensitiveDriveFile: "File unmarked as sensitive" | ||||||
|  |  | ||||||
							
								
								
									
										24
									
								
								locales/index.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								locales/index.d.ts
									
										
									
									
										vendored
									
									
								
							|  | @ -632,6 +632,10 @@ export interface Locale extends ILocale { | ||||||
|      * ユーザーのすべてのメディアをNSFWとしてマークする |      * ユーザーのすべてのメディアをNSFWとしてマークする | ||||||
|      */ |      */ | ||||||
|     "markAsNSFW": string; |     "markAsNSFW": string; | ||||||
|  |     /** | ||||||
|  |      * Mark as NSFW | ||||||
|  |      */ | ||||||
|  |     "markInstanceAsNSFW": string; | ||||||
|     /** |     /** | ||||||
|      * 凍結 |      * 凍結 | ||||||
|      */ |      */ | ||||||
|  | @ -928,6 +932,10 @@ export interface Locale extends ILocale { | ||||||
|      * サーバーをメディアサイレンス |      * サーバーをメディアサイレンス | ||||||
|      */ |      */ | ||||||
|     "mediaSilenceThisInstance": string; |     "mediaSilenceThisInstance": string; | ||||||
|  |     /** | ||||||
|  |      * Reject reports from this instance | ||||||
|  |      */ | ||||||
|  |     "rejectReports": string; | ||||||
|     /** |     /** | ||||||
|      * 操作 |      * 操作 | ||||||
|      */ |      */ | ||||||
|  | @ -10000,6 +10008,22 @@ export interface Locale extends ILocale { | ||||||
|          * リモートサーバーを再開 |          * リモートサーバーを再開 | ||||||
|          */ |          */ | ||||||
|         "unsuspendRemoteInstance": string; |         "unsuspendRemoteInstance": string; | ||||||
|  |         /** | ||||||
|  |          * Set remote instance as NSFW | ||||||
|  |          */ | ||||||
|  |         "setRemoteInstanceNSFW": string; | ||||||
|  |         /** | ||||||
|  |          * Set remote instance as NSFW | ||||||
|  |          */ | ||||||
|  |         "unsetRemoteInstanceNSFW": string; | ||||||
|  |         /** | ||||||
|  |          * Rejected reports from remote instance | ||||||
|  |          */ | ||||||
|  |         "rejectRemoteInstanceReports": string; | ||||||
|  |         /** | ||||||
|  |          * Accepted reports from remote instance | ||||||
|  |          */ | ||||||
|  |         "acceptRemoteInstanceReports": string; | ||||||
|         /** |         /** | ||||||
|          * リモートサーバーのモデレーションノート更新 |          * リモートサーバーのモデレーションノート更新 | ||||||
|          */ |          */ | ||||||
|  |  | ||||||
|  | @ -154,6 +154,7 @@ renoteUnmute: "ブーストのミュートを解除" | ||||||
| block: "ブロック" | block: "ブロック" | ||||||
| unblock: "ブロック解除" | unblock: "ブロック解除" | ||||||
| markAsNSFW: "ユーザーのすべてのメディアをNSFWとしてマークする" | markAsNSFW: "ユーザーのすべてのメディアをNSFWとしてマークする" | ||||||
|  | markInstanceAsNSFW: "Mark as NSFW" | ||||||
| suspend: "凍結" | suspend: "凍結" | ||||||
| unsuspend: "解凍" | unsuspend: "解凍" | ||||||
| blockConfirm: "ブロックしますか?" | blockConfirm: "ブロックしますか?" | ||||||
|  | @ -228,6 +229,7 @@ stopActivityDelivery: "アクティビティの配送を停止" | ||||||
| blockThisInstance: "このサーバーをブロック" | blockThisInstance: "このサーバーをブロック" | ||||||
| silenceThisInstance: "サーバーをサイレンス" | silenceThisInstance: "サーバーをサイレンス" | ||||||
| mediaSilenceThisInstance: "サーバーをメディアサイレンス" | mediaSilenceThisInstance: "サーバーをメディアサイレンス" | ||||||
|  | rejectReports: "Reject reports from this instance" | ||||||
| operations: "操作" | operations: "操作" | ||||||
| software: "ソフトウェア" | software: "ソフトウェア" | ||||||
| version: "バージョン" | version: "バージョン" | ||||||
|  | @ -2647,6 +2649,10 @@ _moderationLogTypes: | ||||||
|   resetPassword: "パスワードをリセット" |   resetPassword: "パスワードをリセット" | ||||||
|   suspendRemoteInstance: "リモートサーバーを停止" |   suspendRemoteInstance: "リモートサーバーを停止" | ||||||
|   unsuspendRemoteInstance: "リモートサーバーを再開" |   unsuspendRemoteInstance: "リモートサーバーを再開" | ||||||
|  |   setRemoteInstanceNSFW: "Set remote instance as NSFW" | ||||||
|  |   unsetRemoteInstanceNSFW: "Set remote instance as NSFW" | ||||||
|  |   rejectRemoteInstanceReports: "Rejected reports from remote instance" | ||||||
|  |   acceptRemoteInstanceReports: "Accepted reports from remote instance" | ||||||
|   updateRemoteInstanceNote: "リモートサーバーのモデレーションノート更新" |   updateRemoteInstanceNote: "リモートサーバーのモデレーションノート更新" | ||||||
|   markSensitiveDriveFile: "ファイルをセンシティブ付与" |   markSensitiveDriveFile: "ファイルをセンシティブ付与" | ||||||
|   unmarkSensitiveDriveFile: "ファイルをセンシティブ解除" |   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"`); | ||||||
|  | 		} | ||||||
|  | } | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
| 
 | 
 | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { In } from 'typeorm'; | import { In } from 'typeorm'; | ||||||
|  | import * as Bull from 'bullmq'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import type { Config } from '@/config.js'; | import type { Config } from '@/config.js'; | ||||||
| import { UserFollowingService } from '@/core/UserFollowingService.js'; | import { UserFollowingService } from '@/core/UserFollowingService.js'; | ||||||
|  | @ -29,6 +30,7 @@ import { bindThis } from '@/decorators.js'; | ||||||
| import type { MiRemoteUser } from '@/models/User.js'; | import type { MiRemoteUser } from '@/models/User.js'; | ||||||
| import { GlobalEventService } from '@/core/GlobalEventService.js'; | import { GlobalEventService } from '@/core/GlobalEventService.js'; | ||||||
| import { AbuseReportService } from '@/core/AbuseReportService.js'; | import { AbuseReportService } from '@/core/AbuseReportService.js'; | ||||||
|  | import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; | ||||||
| import { getApHrefNullable, getApId, getApIds, getApType, isAccept, isActor, isAdd, isAnnounce, isBlock, isCollection, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isLike, isMove, isPost, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost } from './type.js'; | import { getApHrefNullable, getApId, getApIds, getApType, isAccept, isActor, isAdd, isAnnounce, isBlock, isCollection, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isLike, isMove, isPost, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost } from './type.js'; | ||||||
| import { ApNoteService } from './models/ApNoteService.js'; | import { ApNoteService } from './models/ApNoteService.js'; | ||||||
| import { ApLoggerService } from './ApLoggerService.js'; | import { ApLoggerService } from './ApLoggerService.js'; | ||||||
|  | @ -83,6 +85,7 @@ export class ApInboxService { | ||||||
| 		private apQuestionService: ApQuestionService, | 		private apQuestionService: ApQuestionService, | ||||||
| 		private queueService: QueueService, | 		private queueService: QueueService, | ||||||
| 		private globalEventService: GlobalEventService, | 		private globalEventService: GlobalEventService, | ||||||
|  | 		private federatedInstanceService: FederatedInstanceService, | ||||||
| 	) { | 	) { | ||||||
| 		this.logger = this.apLoggerService.logger; | 		this.logger = this.apLoggerService.logger; | ||||||
| 	} | 	} | ||||||
|  | @ -530,6 +533,12 @@ export class ApInboxService { | ||||||
| 
 | 
 | ||||||
| 	@bindThis | 	@bindThis | ||||||
| 	private async flag(actor: MiRemoteUser, activity: IFlag): Promise<string> { | 	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スキーマと対応させられないので
 | 		// objectは `(User|Note) | (User|Note)[]` だけど、全パターンDBスキーマと対応させられないので
 | ||||||
| 		// 対象ユーザーは一番最初のユーザー として あとはコメントとして格納する
 | 		// 対象ユーザーは一番最初のユーザー として あとはコメントとして格納する
 | ||||||
| 		const uris = getApIds(activity.object); | 		const uris = getApIds(activity.object); | ||||||
|  |  | ||||||
|  | @ -159,6 +159,11 @@ export class MiInstance { | ||||||
| 	}) | 	}) | ||||||
| 	public isNSFW: boolean; | 	public isNSFW: boolean; | ||||||
| 
 | 
 | ||||||
|  | 	@Column('boolean', { | ||||||
|  | 		default: false, | ||||||
|  | 	}) | ||||||
|  | 	public rejectReports: boolean; | ||||||
|  | 
 | ||||||
| 	@Column('varchar', { | 	@Column('varchar', { | ||||||
| 		length: 16384, default: '', | 		length: 16384, default: '', | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
|  | @ -25,6 +25,7 @@ export const paramDef = { | ||||||
| 		host: { type: 'string' }, | 		host: { type: 'string' }, | ||||||
| 		isSuspended: { type: 'boolean' }, | 		isSuspended: { type: 'boolean' }, | ||||||
| 		isNSFW: { type: 'boolean' }, | 		isNSFW: { type: 'boolean' }, | ||||||
|  | 		rejectReports: { type: 'boolean' }, | ||||||
| 		moderationNote: { type: 'string' }, | 		moderationNote: { type: 'string' }, | ||||||
| 	}, | 	}, | ||||||
| 	required: ['host'], | 	required: ['host'], | ||||||
|  | @ -57,6 +58,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- | ||||||
| 			await this.federatedInstanceService.update(instance.id, { | 			await this.federatedInstanceService.update(instance.id, { | ||||||
| 				suspensionState, | 				suspensionState, | ||||||
| 				isNSFW: ps.isNSFW, | 				isNSFW: ps.isNSFW, | ||||||
|  | 				rejectReports: ps.rejectReports, | ||||||
| 				moderationNote: ps.moderationNote, | 				moderationNote: ps.moderationNote, | ||||||
| 			}); | 			}); | ||||||
| 
 | 
 | ||||||
|  | @ -74,6 +76,22 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | 			if (ps.isNSFW != null && instance.isNSFW !== ps.isNSFW) { | ||||||
|  | 				const message = ps.rejectReports ? 'setRemoteInstanceNSFW' : 'unsetRemoteInstanceNSFW'; | ||||||
|  | 				this.moderationLogService.log(me, message, { | ||||||
|  | 					id: instance.id, | ||||||
|  | 					host: instance.host, | ||||||
|  | 				}); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			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) { | 			if (ps.moderationNote != null && instance.moderationNote !== ps.moderationNote) { | ||||||
| 				this.moderationLogService.log(me, 'updateRemoteInstanceNote', { | 				this.moderationLogService.log(me, 'updateRemoteInstanceNote', { | ||||||
| 					id: instance.id, | 					id: instance.id, | ||||||
|  |  | ||||||
|  | @ -77,8 +77,12 @@ export const moderationLogTypes = [ | ||||||
| 	'deleteGlobalAnnouncement', | 	'deleteGlobalAnnouncement', | ||||||
| 	'deleteUserAnnouncement', | 	'deleteUserAnnouncement', | ||||||
| 	'resetPassword', | 	'resetPassword', | ||||||
|  | 	'setRemoteInstanceNSFW', | ||||||
|  | 	'unsetRemoteInstanceNSFW', | ||||||
| 	'suspendRemoteInstance', | 	'suspendRemoteInstance', | ||||||
| 	'unsuspendRemoteInstance', | 	'unsuspendRemoteInstance', | ||||||
|  | 	'rejectRemoteInstanceReports', | ||||||
|  | 	'acceptRemoteInstanceReports', | ||||||
| 	'updateRemoteInstanceNote', | 	'updateRemoteInstanceNote', | ||||||
| 	'markSensitiveDriveFile', | 	'markSensitiveDriveFile', | ||||||
| 	'unmarkSensitiveDriveFile', | 	'unmarkSensitiveDriveFile', | ||||||
|  | @ -227,6 +231,14 @@ export type ModerationLogPayloads = { | ||||||
| 		userUsername: string; | 		userUsername: string; | ||||||
| 		userHost: string | null; | 		userHost: string | null; | ||||||
| 	}; | 	}; | ||||||
|  | 	setRemoteInstanceNSFW: { | ||||||
|  | 		id: string; | ||||||
|  | 		host: string; | ||||||
|  | 	}; | ||||||
|  | 	unsetRemoteInstanceNSFW: { | ||||||
|  | 		id: string; | ||||||
|  | 		host: string; | ||||||
|  | 	}; | ||||||
| 	suspendRemoteInstance: { | 	suspendRemoteInstance: { | ||||||
| 		id: string; | 		id: string; | ||||||
| 		host: string; | 		host: string; | ||||||
|  | @ -235,6 +247,14 @@ export type ModerationLogPayloads = { | ||||||
| 		id: string; | 		id: string; | ||||||
| 		host: string; | 		host: string; | ||||||
| 	}; | 	}; | ||||||
|  | 	rejectRemoteInstanceReports: { | ||||||
|  | 		id: string; | ||||||
|  | 		host: string; | ||||||
|  | 	}; | ||||||
|  | 	acceptRemoteInstanceReports: { | ||||||
|  | 		id: string; | ||||||
|  | 		host: string; | ||||||
|  | 	}; | ||||||
| 	updateRemoteInstanceNote: { | 	updateRemoteInstanceNote: { | ||||||
| 		id: string; | 		id: string; | ||||||
| 		host: string; | 		host: string; | ||||||
|  |  | ||||||
|  | @ -23,6 +23,10 @@ SPDX-License-Identifier: AGPL-3.0-only | ||||||
| 					'markSensitiveDriveFile', | 					'markSensitiveDriveFile', | ||||||
| 					'resetPassword', | 					'resetPassword', | ||||||
| 					'suspendRemoteInstance', | 					'suspendRemoteInstance', | ||||||
|  | 					'setRemoteInstanceNSFW', | ||||||
|  | 					'unsetRemoteInstanceNSFW', | ||||||
|  | 					'rejectRemoteInstanceReports', | ||||||
|  | 					'acceptRemoteInstanceReports', | ||||||
| 				].includes(log.type), | 				].includes(log.type), | ||||||
| 				[$style.logRed]: [ | 				[$style.logRed]: [ | ||||||
| 					'suspend', | 					'suspend', | ||||||
|  | @ -61,6 +65,10 @@ 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 === '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 === 'suspendRemoteInstance'">: {{ log.info.host }}</span> | ||||||
| 		<span v-else-if="log.type === 'unsuspendRemoteInstance'">: {{ log.info.host }}</span> | 		<span v-else-if="log.type === 'unsuspendRemoteInstance'">: {{ log.info.host }}</span> | ||||||
|  | 		<span v-else-if="log.type === 'setRemoteInstanceNSFW'">: {{ log.info.host }}</span> | ||||||
|  | 		<span v-else-if="log.type === 'unsetRemoteInstanceNSFW'">: {{ 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 === 'createGlobalAnnouncement'">: {{ log.info.announcement.title }}</span> | ||||||
| 		<span v-else-if="log.type === 'updateGlobalAnnouncement'">: {{ log.info.before.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> | 		<span v-else-if="log.type === 'deleteGlobalAnnouncement'">: {{ log.info.announcement.title }}</span> | ||||||
|  |  | ||||||
|  | @ -49,7 +49,8 @@ SPDX-License-Identifier: AGPL-3.0-only | ||||||
| 						<MkSwitch v-model="isBlocked" :disabled="!meta || !instance || isBaseBlocked" @update:modelValue="toggleBlock">{{ i18n.ts.blockThisInstance }}</MkSwitch> | 						<MkSwitch v-model="isBlocked" :disabled="!meta || !instance || isBaseBlocked" @update:modelValue="toggleBlock">{{ i18n.ts.blockThisInstance }}</MkSwitch> | ||||||
| 						<MkInfo v-if="isBaseSilenced" warn>{{ i18n.ts.silencedByBase }}</MkInfo> | 						<MkInfo v-if="isBaseSilenced" warn>{{ i18n.ts.silencedByBase }}</MkInfo> | ||||||
| 						<MkSwitch v-model="isSilenced" :disabled="!meta || !instance || isBaseSilenced" @update:modelValue="toggleSilenced">{{ i18n.ts.silenceThisInstance }}</MkSwitch> | 						<MkSwitch v-model="isSilenced" :disabled="!meta || !instance || isBaseSilenced" @update:modelValue="toggleSilenced">{{ i18n.ts.silenceThisInstance }}</MkSwitch> | ||||||
| 						<MkSwitch v-model="isNSFW" :disabled="!instance" @update:modelValue="toggleNSFW">Mark as NSFW</MkSwitch> | 						<MkSwitch v-model="isNSFW" :disabled="!instance" @update:modelValue="toggleNSFW">{{ i18n.ts.markInstanceAsNSFW }}</MkSwitch> | ||||||
|  | 						<MkSwitch v-model="rejectReports" :disabled="!instance" @update:modelValue="toggleRejectReports">{{ i18n.ts.rejectReports }}</MkSwitch> | ||||||
| 						<MkInfo v-if="isBaseMediaSilenced" warn>{{ i18n.ts.mediaSilencedByBase }}</MkInfo> | 						<MkInfo v-if="isBaseMediaSilenced" warn>{{ i18n.ts.mediaSilencedByBase }}</MkInfo> | ||||||
| 						<MkSwitch v-model="isMediaSilenced" :disabled="!meta || !instance || isBaseMediaSilenced" @update:modelValue="toggleMediaSilenced">{{ i18n.ts.mediaSilenceThisInstance }}</MkSwitch> | 						<MkSwitch v-model="isMediaSilenced" :disabled="!meta || !instance || isBaseMediaSilenced" @update:modelValue="toggleMediaSilenced">{{ i18n.ts.mediaSilenceThisInstance }}</MkSwitch> | ||||||
| 						<MkButton @click="refreshMetadata"><i class="ti ti-refresh"></i> Refresh metadata</MkButton> | 						<MkButton @click="refreshMetadata"><i class="ti ti-refresh"></i> Refresh metadata</MkButton> | ||||||
|  | @ -174,6 +175,7 @@ const suspensionState = ref<'none' | 'manuallySuspended' | 'goneSuspended' | 'au | ||||||
| const isBlocked = ref(false); | const isBlocked = ref(false); | ||||||
| const isSilenced = ref(false); | const isSilenced = ref(false); | ||||||
| const isNSFW = ref(false); | const isNSFW = ref(false); | ||||||
|  | const rejectReports = ref(false); | ||||||
| const isMediaSilenced = ref(false); | const isMediaSilenced = ref(false); | ||||||
| const faviconUrl = ref<string | null>(null); | const faviconUrl = ref<string | null>(null); | ||||||
| const moderationNote = ref(''); | const moderationNote = ref(''); | ||||||
|  | @ -219,6 +221,7 @@ async function fetch(): Promise<void> { | ||||||
| 	isBlocked.value = instance.value?.isBlocked ?? false; | 	isBlocked.value = instance.value?.isBlocked ?? false; | ||||||
| 	isSilenced.value = instance.value?.isSilenced ?? false; | 	isSilenced.value = instance.value?.isSilenced ?? false; | ||||||
| 	isNSFW.value = instance.value?.isNSFW ?? false; | 	isNSFW.value = instance.value?.isNSFW ?? false; | ||||||
|  | 	rejectReports.value = instance.value?.rejectReports ?? false; | ||||||
| 	isMediaSilenced.value = instance.value?.isMediaSilenced ?? false; | 	isMediaSilenced.value = instance.value?.isMediaSilenced ?? false; | ||||||
| 	faviconUrl.value = getProxiedImageUrlNullable(instance.value?.faviconUrl, 'preview') ?? getProxiedImageUrlNullable(instance.value?.iconUrl, 'preview'); | 	faviconUrl.value = getProxiedImageUrlNullable(instance.value?.faviconUrl, 'preview') ?? getProxiedImageUrlNullable(instance.value?.iconUrl, 'preview'); | ||||||
| 	moderationNote.value = instance.value?.moderationNote ?? ''; | 	moderationNote.value = instance.value?.moderationNote ?? ''; | ||||||
|  | @ -279,6 +282,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 { | function refreshMetadata(): void { | ||||||
| 	if (!instance.value) throw new Error('No instance?'); | 	if (!instance.value) throw new Error('No instance?'); | ||||||
| 	misskeyApi('admin/federation/refresh-remote-instance-metadata', { | 	misskeyApi('admin/federation/refresh-remote-instance-metadata', { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue