improve moderation log
This commit is contained in:
		
							
								
								
									
										2
									
								
								locales/index.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								locales/index.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -2256,6 +2256,8 @@ export interface Locale { | ||||
|         "suspend": string; | ||||
|         "unsuspend": string; | ||||
|         "addCustomEmoji": string; | ||||
|         "updateCustomEmoji": string; | ||||
|         "deleteCustomEmoji": string; | ||||
|         "updateServerSettings": string; | ||||
|         "updateUserNote": string; | ||||
|         "deleteDriveFile": string; | ||||
|   | ||||
| @@ -2169,6 +2169,8 @@ _moderationLogTypes: | ||||
|   suspend: "凍結" | ||||
|   unsuspend: "凍結解除" | ||||
|   addCustomEmoji: "カスタム絵文字追加" | ||||
|   updateCustomEmoji: "カスタム絵文字更新" | ||||
|   deleteCustomEmoji: "カスタム絵文字削除" | ||||
|   updateServerSettings: "サーバー設定更新" | ||||
|   updateUserNote: "モデレーションノート更新" | ||||
|   deleteDriveFile: "ファイルを削除" | ||||
|   | ||||
| @@ -12,12 +12,13 @@ import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js'; | ||||
| import { GlobalEventService } from '@/core/GlobalEventService.js'; | ||||
| import type { MiDriveFile } from '@/models/DriveFile.js'; | ||||
| import type { MiEmoji } from '@/models/Emoji.js'; | ||||
| import type { EmojisRepository, MiRole } from '@/models/_.js'; | ||||
| import type { EmojisRepository, MiRole, MiUser } from '@/models/_.js'; | ||||
| import { bindThis } from '@/decorators.js'; | ||||
| import { MemoryKVCache, RedisSingleCache } from '@/misc/cache.js'; | ||||
| import { UtilityService } from '@/core/UtilityService.js'; | ||||
| import { query } from '@/misc/prelude/url.js'; | ||||
| import type { Serialized } from '@/server/api/stream/types.js'; | ||||
| import { ModerationLogService } from '@/core/ModerationLogService.js'; | ||||
|  | ||||
| const parseEmojiStrRegexp = /^(\w+)(?:@([\w.-]+))?$/; | ||||
|  | ||||
| @@ -36,6 +37,7 @@ export class CustomEmojiService implements OnApplicationShutdown { | ||||
| 		private utilityService: UtilityService, | ||||
| 		private idService: IdService, | ||||
| 		private emojiEntityService: EmojiEntityService, | ||||
| 		private moderationLogService: ModerationLogService, | ||||
| 		private globalEventService: GlobalEventService, | ||||
| 	) { | ||||
| 		this.cache = new MemoryKVCache<MiEmoji | null>(1000 * 60 * 60 * 12); | ||||
| @@ -66,7 +68,7 @@ export class CustomEmojiService implements OnApplicationShutdown { | ||||
| 		isSensitive: boolean; | ||||
| 		localOnly: boolean; | ||||
| 		roleIdsThatCanBeUsedThisEmojiAsReaction: MiRole['id'][]; | ||||
| 	}): Promise<MiEmoji> { | ||||
| 	}, moderator?: MiUser): Promise<MiEmoji> { | ||||
| 		const emoji = await this.emojisRepository.insert({ | ||||
| 			id: this.idService.genId(), | ||||
| 			updatedAt: new Date(), | ||||
| @@ -89,6 +91,13 @@ export class CustomEmojiService implements OnApplicationShutdown { | ||||
| 			this.globalEventService.publishBroadcastStream('emojiAdded', { | ||||
| 				emoji: await this.emojiEntityService.packDetailed(emoji.id), | ||||
| 			}); | ||||
|  | ||||
| 			if (moderator) { | ||||
| 				this.moderationLogService.log(moderator, 'addCustomEmoji', { | ||||
| 					emojiId: emoji.id, | ||||
| 					emoji: emoji, | ||||
| 				}); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		return emoji; | ||||
| @@ -104,7 +113,7 @@ export class CustomEmojiService implements OnApplicationShutdown { | ||||
| 		isSensitive?: boolean; | ||||
| 		localOnly?: boolean; | ||||
| 		roleIdsThatCanBeUsedThisEmojiAsReaction?: MiRole['id'][]; | ||||
| 	}): Promise<void> { | ||||
| 	}, moderator?: MiUser): Promise<void> { | ||||
| 		const emoji = await this.emojisRepository.findOneByOrFail({ id: id }); | ||||
| 		const sameNameEmoji = await this.emojisRepository.findOneBy({ name: data.name, host: IsNull() }); | ||||
| 		if (sameNameEmoji != null && sameNameEmoji.id !== id) throw new Error('name already exists'); | ||||
| @@ -140,6 +149,14 @@ export class CustomEmojiService implements OnApplicationShutdown { | ||||
| 				emoji: updated, | ||||
| 			}); | ||||
| 		} | ||||
|  | ||||
| 		if (moderator) { | ||||
| 			this.moderationLogService.log(moderator, 'updateCustomEmoji', { | ||||
| 				emojiId: emoji.id, | ||||
| 				before: emoji, | ||||
| 				after: updated, | ||||
| 			}); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	@bindThis | ||||
| @@ -231,7 +248,7 @@ export class CustomEmojiService implements OnApplicationShutdown { | ||||
| 	} | ||||
|  | ||||
| 	@bindThis | ||||
| 	public async delete(id: MiEmoji['id']) { | ||||
| 	public async delete(id: MiEmoji['id'], moderator?: MiUser) { | ||||
| 		const emoji = await this.emojisRepository.findOneByOrFail({ id: id }); | ||||
|  | ||||
| 		await this.emojisRepository.delete(emoji.id); | ||||
| @@ -241,16 +258,30 @@ export class CustomEmojiService implements OnApplicationShutdown { | ||||
| 		this.globalEventService.publishBroadcastStream('emojiDeleted', { | ||||
| 			emojis: [await this.emojiEntityService.packDetailed(emoji)], | ||||
| 		}); | ||||
|  | ||||
| 		if (moderator) { | ||||
| 			this.moderationLogService.log(moderator, 'deleteCustomEmoji', { | ||||
| 				emojiId: emoji.id, | ||||
| 				emoji: emoji, | ||||
| 			}); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	@bindThis | ||||
| 	public async deleteBulk(ids: MiEmoji['id'][]) { | ||||
| 	public async deleteBulk(ids: MiEmoji['id'][], moderator?: MiUser) { | ||||
| 		const emojis = await this.emojisRepository.findBy({ | ||||
| 			id: In(ids), | ||||
| 		}); | ||||
|  | ||||
| 		for (const emoji of emojis) { | ||||
| 			await this.emojisRepository.delete(emoji.id); | ||||
|  | ||||
| 			if (moderator) { | ||||
| 				this.moderationLogService.log(moderator, 'deleteCustomEmoji', { | ||||
| 					emojiId: emoji.id, | ||||
| 					emoji: emoji, | ||||
| 				}); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		this.localEmojisCache.refresh(); | ||||
|   | ||||
| @@ -8,7 +8,6 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||
| import type { DriveFilesRepository } from '@/models/_.js'; | ||||
| import { DI } from '@/di-symbols.js'; | ||||
| import { CustomEmojiService } from '@/core/CustomEmojiService.js'; | ||||
| import { ModerationLogService } from '@/core/ModerationLogService.js'; | ||||
| import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js'; | ||||
| import { ApiError } from '../../../error.js'; | ||||
|  | ||||
| @@ -61,7 +60,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- | ||||
| 		private customEmojiService: CustomEmojiService, | ||||
|  | ||||
| 		private emojiEntityService: EmojiEntityService, | ||||
| 		private moderationLogService: ModerationLogService, | ||||
| 	) { | ||||
| 		super(meta, paramDef, async (ps, me) => { | ||||
| 			const driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId }); | ||||
| @@ -77,11 +75,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- | ||||
| 				isSensitive: ps.isSensitive ?? false, | ||||
| 				localOnly: ps.localOnly ?? false, | ||||
| 				roleIdsThatCanBeUsedThisEmojiAsReaction: ps.roleIdsThatCanBeUsedThisEmojiAsReaction ?? [], | ||||
| 			}); | ||||
|  | ||||
| 			this.moderationLogService.log(me, 'addCustomEmoji', { | ||||
| 				emojiId: emoji.id, | ||||
| 			}); | ||||
| 			}, me); | ||||
|  | ||||
| 			return this.emojiEntityService.packDetailed(emoji); | ||||
| 		}); | ||||
|   | ||||
| @@ -30,7 +30,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- | ||||
| 		private customEmojiService: CustomEmojiService, | ||||
| 	) { | ||||
| 		super(meta, paramDef, async (ps, me) => { | ||||
| 			await this.customEmojiService.deleteBulk(ps.ids); | ||||
| 			await this.customEmojiService.deleteBulk(ps.ids, me); | ||||
| 		}); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -36,7 +36,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- | ||||
| 		private customEmojiService: CustomEmojiService, | ||||
| 	) { | ||||
| 		super(meta, paramDef, async (ps, me) => { | ||||
| 			await this.customEmojiService.delete(ps.id); | ||||
| 			await this.customEmojiService.delete(ps.id, me); | ||||
| 		}); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -84,7 +84,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- | ||||
| 				isSensitive: ps.isSensitive, | ||||
| 				localOnly: ps.localOnly, | ||||
| 				roleIdsThatCanBeUsedThisEmojiAsReaction: ps.roleIdsThatCanBeUsedThisEmojiAsReaction, | ||||
| 			}); | ||||
| 			}, me); | ||||
| 		}); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -33,6 +33,8 @@ export const moderationLogTypes = [ | ||||
| 	'unsuspend', | ||||
| 	'updateUserNote', | ||||
| 	'addCustomEmoji', | ||||
| 	'updateCustomEmoji', | ||||
| 	'deleteCustomEmoji', | ||||
| 	'assignRole', | ||||
| 	'unassignRole', | ||||
| 	'updateRole', | ||||
| @@ -70,6 +72,16 @@ export type ModerationLogPayloads = { | ||||
| 	}; | ||||
| 	addCustomEmoji: { | ||||
| 		emojiId: string; | ||||
| 		emoji: any; | ||||
| 	}; | ||||
| 	updateCustomEmoji: { | ||||
| 		emojiId: string; | ||||
| 		before: any; | ||||
| 		after: any; | ||||
| 	}; | ||||
| 	deleteCustomEmoji: { | ||||
| 		emojiId: string; | ||||
| 		emoji: any; | ||||
| 	}; | ||||
| 	assignRole: { | ||||
| 		userId: string; | ||||
|   | ||||
| @@ -2538,6 +2538,12 @@ type ModerationLog = { | ||||
| } | { | ||||
|     type: 'addCustomEmoji'; | ||||
|     info: ModerationLogPayloads['addCustomEmoji']; | ||||
| } | { | ||||
|     type: 'updateCustomEmoji'; | ||||
|     info: ModerationLogPayloads['updateCustomEmoji']; | ||||
| } | { | ||||
|     type: 'deleteCustomEmoji'; | ||||
|     info: ModerationLogPayloads['deleteCustomEmoji']; | ||||
| } | { | ||||
|     type: 'assignRole'; | ||||
|     info: ModerationLogPayloads['assignRole']; | ||||
| @@ -2592,7 +2598,7 @@ type ModerationLog = { | ||||
| }); | ||||
|  | ||||
| // @public (undocumented) | ||||
| export const moderationLogTypes: readonly ["updateServerSettings", "suspend", "unsuspend", "updateUserNote", "addCustomEmoji", "assignRole", "unassignRole", "updateRole", "deleteRole", "clearQueue", "promoteQueue", "deleteDriveFile", "deleteNote", "createGlobalAnnouncement", "createUserAnnouncement", "updateGlobalAnnouncement", "updateUserAnnouncement", "deleteGlobalAnnouncement", "deleteUserAnnouncement", "resetPassword", "suspendRemoteInstance", "unsuspendRemoteInstance"]; | ||||
| export const moderationLogTypes: readonly ["updateServerSettings", "suspend", "unsuspend", "updateUserNote", "addCustomEmoji", "updateCustomEmoji", "deleteCustomEmoji", "assignRole", "unassignRole", "updateRole", "deleteRole", "clearQueue", "promoteQueue", "deleteDriveFile", "deleteNote", "createGlobalAnnouncement", "createUserAnnouncement", "updateGlobalAnnouncement", "updateUserAnnouncement", "deleteGlobalAnnouncement", "deleteUserAnnouncement", "resetPassword", "suspendRemoteInstance", "unsuspendRemoteInstance"]; | ||||
|  | ||||
| // @public (undocumented) | ||||
| export const mutedNoteReasons: readonly ["word", "manual", "spam", "other"]; | ||||
|   | ||||
| @@ -51,6 +51,8 @@ export const moderationLogTypes = [ | ||||
| 	'unsuspend', | ||||
| 	'updateUserNote', | ||||
| 	'addCustomEmoji', | ||||
| 	'updateCustomEmoji', | ||||
| 	'deleteCustomEmoji', | ||||
| 	'assignRole', | ||||
| 	'unassignRole', | ||||
| 	'updateRole', | ||||
| @@ -88,6 +90,16 @@ export type ModerationLogPayloads = { | ||||
| 	}; | ||||
| 	addCustomEmoji: { | ||||
| 		emojiId: string; | ||||
| 		emoji: any; | ||||
| 	}; | ||||
| 	updateCustomEmoji: { | ||||
| 		emojiId: string; | ||||
| 		before: any; | ||||
| 		after: any; | ||||
| 	}; | ||||
| 	deleteCustomEmoji: { | ||||
| 		emojiId: string; | ||||
| 		emoji: any; | ||||
| 	}; | ||||
| 	assignRole: { | ||||
| 		userId: string; | ||||
|   | ||||
| @@ -589,6 +589,12 @@ export type ModerationLog = { | ||||
| } | { | ||||
| 	type: 'addCustomEmoji'; | ||||
| 	info: ModerationLogPayloads['addCustomEmoji']; | ||||
| } | { | ||||
| 	type: 'updateCustomEmoji'; | ||||
| 	info: ModerationLogPayloads['updateCustomEmoji']; | ||||
| } | { | ||||
| 	type: 'deleteCustomEmoji'; | ||||
| 	info: ModerationLogPayloads['deleteCustomEmoji']; | ||||
| } | { | ||||
| 	type: 'assignRole'; | ||||
| 	info: ModerationLogPayloads['assignRole']; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 syuilo
					syuilo