From 27d43879a24b9243657af50d32d459a36b6596ec Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Wed, 26 Feb 2025 23:18:30 -0500 Subject: add moderation logs for many endpoints - `/admin/delete-all-files-of-a-user` - `/admin/nsfw-user` - `/admin/unnsfw-user` - `/admin/silence-user` - `/admin/unsilence-user` - `/admin/accounts/create` - `/admin/drive/clean-remote-files` - `/admin/drive/cleanup` - `/admin/emoji/set-category-bulk` - `/admin/emoji/set-license-bulk` - `/admin/emoji/set-aliases-bulk` - `/admin/emoji/add-aliases-bulk` - `/admin/emoji/remove-aliases-bulk` - `/admin/emoji/import-zip` - `/admin/federation/delete-all-files` - `/admin/federation/remove-all-following` - `/admin/promo/create` - `/admin/relay/add` - `/admin/relay/remove` --- .../server/api/endpoints/admin/accounts/create.ts | 9 +++ .../endpoints/admin/delete-all-files-of-a-user.ts | 13 +++- .../endpoints/admin/drive/clean-remote-files.ts | 5 +- .../server/api/endpoints/admin/drive/cleanup.ts | 7 +- .../api/endpoints/admin/emoji/add-aliases-bulk.ts | 6 ++ .../server/api/endpoints/admin/emoji/import-zip.ts | 15 +++- .../endpoints/admin/emoji/remove-aliases-bulk.ts | 6 ++ .../api/endpoints/admin/emoji/set-aliases-bulk.ts | 6 ++ .../api/endpoints/admin/emoji/set-category-bulk.ts | 6 ++ .../api/endpoints/admin/emoji/set-license-bulk.ts | 6 ++ .../endpoints/admin/federation/delete-all-files.ts | 8 ++- .../admin/federation/remove-all-following.ts | 6 ++ .../src/server/api/endpoints/admin/nsfw-user.ts | 18 ++--- .../src/server/api/endpoints/admin/promo/create.ts | 14 +++- .../src/server/api/endpoints/admin/relays/add.ts | 6 ++ .../server/api/endpoints/admin/relays/remove.ts | 7 +- .../src/server/api/endpoints/admin/silence-user.ts | 27 +++++--- .../src/server/api/endpoints/admin/unnsfw-user.ts | 21 +++--- .../server/api/endpoints/admin/unsilence-user.ts | 22 ++++-- packages/backend/src/types.ts | 81 ++++++++++++++++++++++ 20 files changed, 250 insertions(+), 39 deletions(-) (limited to 'packages/backend/src') diff --git a/packages/backend/src/server/api/endpoints/admin/accounts/create.ts b/packages/backend/src/server/api/endpoints/admin/accounts/create.ts index 5843457676..1a47f56bc6 100644 --- a/packages/backend/src/server/api/endpoints/admin/accounts/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/accounts/create.ts @@ -15,6 +15,7 @@ import type { Config } from '@/config.js'; import { ApiError } from '@/server/api/error.js'; import { Packed } from '@/misc/json-schema.js'; import { RoleService } from '@/core/RoleService.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; export const meta = { tags: ['admin'], @@ -96,6 +97,7 @@ export default class extends Endpoint { // eslint- private userEntityService: UserEntityService, private signupService: SignupService, private instanceActorService: InstanceActorService, + private readonly moderationLogService: ModerationLogService, ) { super(meta, paramDef, async (ps, _me, token) => { const me = _me ? await this.usersRepository.findOneByOrFail({ id: _me.id }) : null; @@ -137,6 +139,13 @@ export default class extends Endpoint { // eslint- approved: true, }); + if (me) { + await this.moderationLogService.log(me, 'createAccount', { + userId: account.id, + userUsername: account.username, + }); + } + const res = await this.userEntityService.pack(account, account, { schema: 'MeDetailed', includeSecrets: true, diff --git a/packages/backend/src/server/api/endpoints/admin/delete-all-files-of-a-user.ts b/packages/backend/src/server/api/endpoints/admin/delete-all-files-of-a-user.ts index 747c9f48d0..8b4a450ccb 100644 --- a/packages/backend/src/server/api/endpoints/admin/delete-all-files-of-a-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/delete-all-files-of-a-user.ts @@ -8,6 +8,8 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFilesRepository } from '@/models/_.js'; import { DriveService } from '@/core/DriveService.js'; import { DI } from '@/di-symbols.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; +import { CacheService } from '@/core/CacheService.js'; export const meta = { tags: ['admin'], @@ -30,14 +32,23 @@ export default class extends Endpoint { // eslint- constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, - + private readonly cacheService: CacheService, + private readonly moderationLogService: ModerationLogService, private driveService: DriveService, ) { super(meta, paramDef, async (ps, me) => { + const user = await this.cacheService.findUserById(ps.userId); const files = await this.driveFilesRepository.findBy({ userId: ps.userId, }); + await this.moderationLogService.log(me, 'clearUserFiles', { + userId: ps.userId, + userUsername: user.username, + userHost: user.host, + count: files.length, + }); + for (const file of files) { this.driveService.deleteFile(file, false, me); } diff --git a/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts b/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts index d420a929bd..9a7b3d5d62 100644 --- a/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts +++ b/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts @@ -6,6 +6,7 @@ import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueueService } from '@/core/QueueService.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; export const meta = { tags: ['admin'], @@ -25,9 +26,11 @@ export const paramDef = { export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private queueService: QueueService, + private readonly moderationLogService: ModerationLogService, ) { super(meta, paramDef, async (ps, me) => { - this.queueService.createCleanRemoteFilesJob(); + await this.moderationLogService.log(me, 'clearRemoteFiles', {}); + await this.queueService.createCleanRemoteFilesJob(); }); } } diff --git a/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts b/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts index d612572e2e..f5d20366cf 100644 --- a/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts +++ b/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts @@ -9,6 +9,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFilesRepository } from '@/models/_.js'; import { DriveService } from '@/core/DriveService.js'; import { DI } from '@/di-symbols.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; export const meta = { tags: ['admin'], @@ -29,7 +30,7 @@ export default class extends Endpoint { // eslint- constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, - + private readonly moderationLogService: ModerationLogService, private driveService: DriveService, ) { super(meta, paramDef, async (ps, me) => { @@ -37,6 +38,10 @@ export default class extends Endpoint { // eslint- userId: IsNull(), }); + await this.moderationLogService.log(me, 'clearOwnerlessFiles', { + count: files.length, + }); + for (const file of files) { this.driveService.deleteFile(file); } diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/add-aliases-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/add-aliases-bulk.ts index f4fc79bdb3..795b579041 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/add-aliases-bulk.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/add-aliases-bulk.ts @@ -6,6 +6,7 @@ import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; export const meta = { tags: ['admin'], @@ -32,8 +33,13 @@ export const paramDef = { export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private customEmojiService: CustomEmojiService, + private readonly moderationLogService: ModerationLogService, ) { super(meta, paramDef, async (ps, me) => { + await this.moderationLogService.log(me, 'updateCustomEmojis', { + ids: ps.ids, + addAliases: ps.aliases, + }); await this.customEmojiService.addAliasesBulk(ps.ids, ps.aliases.map(a => a.normalize('NFC'))); }); } diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts b/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts index 8e5f69c894..b3dc3978d1 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts @@ -3,9 +3,12 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { Injectable } from '@nestjs/common'; +import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueueService } from '@/core/QueueService.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; +import type { DriveFilesRepository } from '@/models/_.js'; +import { DI } from '@/di-symbols.js'; export const meta = { secure: true, @@ -25,9 +28,17 @@ export const paramDef = { export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private queueService: QueueService, + private readonly moderationLogService: ModerationLogService, + @Inject(DI.driveFilesRepository) + private readonly driveFilesRepository: DriveFilesRepository, ) { super(meta, paramDef, async (ps, me) => { - this.queueService.createImportCustomEmojisJob(me, ps.fileId); + const file = await driveFilesRepository.findOneByOrFail({ id: ps.fileId }); + await this.moderationLogService.log(me, 'importCustomEmojis', { + fileId: file.id, + fileName: file.name, + }); + await this.queueService.createImportCustomEmojisJob(me, ps.fileId); }); } } diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/remove-aliases-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/remove-aliases-bulk.ts index e78620eac1..066eb1c7d9 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/remove-aliases-bulk.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/remove-aliases-bulk.ts @@ -6,6 +6,7 @@ import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; export const meta = { tags: ['admin'], @@ -32,8 +33,13 @@ export const paramDef = { export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private customEmojiService: CustomEmojiService, + private readonly moderationLogService: ModerationLogService, ) { super(meta, paramDef, async (ps, me) => { + await this.moderationLogService.log(me, 'updateCustomEmojis', { + ids: ps.ids, + delAliases: ps.aliases, + }); await this.customEmojiService.removeAliasesBulk(ps.ids, ps.aliases.map(a => a.normalize('NFC'))); }); } diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/set-aliases-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/set-aliases-bulk.ts index 69fc8e0cb5..8980ef0c86 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/set-aliases-bulk.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/set-aliases-bulk.ts @@ -6,6 +6,7 @@ import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; export const meta = { tags: ['admin'], @@ -32,8 +33,13 @@ export const paramDef = { export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private customEmojiService: CustomEmojiService, + private readonly moderationLogService: ModerationLogService, ) { super(meta, paramDef, async (ps, me) => { + await this.moderationLogService.log(me, 'updateCustomEmojis', { + ids: ps.ids, + setAliases: ps.aliases, + }); await this.customEmojiService.setAliasesBulk(ps.ids, ps.aliases.map(a => a.normalize('NFC'))); }); } diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/set-category-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/set-category-bulk.ts index 679a9f9c42..2510349210 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/set-category-bulk.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/set-category-bulk.ts @@ -6,6 +6,7 @@ import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; export const meta = { tags: ['admin'], @@ -34,8 +35,13 @@ export const paramDef = { export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private customEmojiService: CustomEmojiService, + private readonly moderationLogService: ModerationLogService, ) { super(meta, paramDef, async (ps, me) => { + await this.moderationLogService.log(me, 'updateCustomEmojis', { + ids: ps.ids, + category: ps.category, + }); await this.customEmojiService.setCategoryBulk(ps.ids, ps.category?.normalize('NFC') ?? null); }); } diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/set-license-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/set-license-bulk.ts index 4ba99faab7..a0205ae24a 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/set-license-bulk.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/set-license-bulk.ts @@ -6,6 +6,7 @@ import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; export const meta = { tags: ['admin'], @@ -34,8 +35,13 @@ export const paramDef = { export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private customEmojiService: CustomEmojiService, + private readonly moderationLogService: ModerationLogService, ) { super(meta, paramDef, async (ps, me) => { + await this.moderationLogService.log(me, 'updateCustomEmojis', { + ids: ps.ids, + license: ps.license, + }); await this.customEmojiService.setLicenseBulk(ps.ids, ps.license ?? null); }); } diff --git a/packages/backend/src/server/api/endpoints/admin/federation/delete-all-files.ts b/packages/backend/src/server/api/endpoints/admin/federation/delete-all-files.ts index 4a54c26009..89fd4be99c 100644 --- a/packages/backend/src/server/api/endpoints/admin/federation/delete-all-files.ts +++ b/packages/backend/src/server/api/endpoints/admin/federation/delete-all-files.ts @@ -8,6 +8,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFilesRepository } from '@/models/_.js'; import { DriveService } from '@/core/DriveService.js'; import { DI } from '@/di-symbols.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; export const meta = { tags: ['admin'], @@ -30,7 +31,7 @@ export default class extends Endpoint { // eslint- constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, - + private readonly moderationLogService: ModerationLogService, private driveService: DriveService, ) { super(meta, paramDef, async (ps, me) => { @@ -38,6 +39,11 @@ export default class extends Endpoint { // eslint- userHost: ps.host, }); + await this.moderationLogService.log(me, 'clearInstanceFiles', { + host: ps.host, + count: files.length, + }); + for (const file of files) { this.driveService.deleteFile(file); } diff --git a/packages/backend/src/server/api/endpoints/admin/federation/remove-all-following.ts b/packages/backend/src/server/api/endpoints/admin/federation/remove-all-following.ts index 601c898f52..e5d85e1d57 100644 --- a/packages/backend/src/server/api/endpoints/admin/federation/remove-all-following.ts +++ b/packages/backend/src/server/api/endpoints/admin/federation/remove-all-following.ts @@ -8,6 +8,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import type { FollowingsRepository, UsersRepository } from '@/models/_.js'; import { DI } from '@/di-symbols.js'; import { QueueService } from '@/core/QueueService.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; export const meta = { tags: ['admin'], @@ -35,6 +36,7 @@ export default class extends Endpoint { // eslint- private followingsRepository: FollowingsRepository, private queueService: QueueService, + private readonly moderationLogService: ModerationLogService, ) { super(meta, paramDef, async (ps, me) => { const followings = await this.followingsRepository.findBy([ @@ -51,6 +53,10 @@ export default class extends Endpoint { // eslint- this.usersRepository.findOneByOrFail({ id: f.followeeId }), ]).then(([from, to]) => [{ id: from.id }, { id: to.id }]))); + await this.moderationLogService.log(me, 'severFollowRelations', { + host: ps.host, + }); + this.queueService.createUnfollowJob(pairs.map(p => ({ from: p[0], to: p[1], silent: true }))); }); } diff --git a/packages/backend/src/server/api/endpoints/admin/nsfw-user.ts b/packages/backend/src/server/api/endpoints/admin/nsfw-user.ts index f64ba7f48a..194e793eda 100644 --- a/packages/backend/src/server/api/endpoints/admin/nsfw-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/nsfw-user.ts @@ -5,9 +5,10 @@ import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { UsersRepository, UserProfilesRepository } from '@/models/_.js'; +import type { UserProfilesRepository } from '@/models/_.js'; import { DI } from '@/di-symbols.js'; import { CacheService } from '@/core/CacheService.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; export const meta = { tags: ['admin'], @@ -28,20 +29,19 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private readonly usersRepository: UsersRepository, - @Inject(DI.userProfilesRepository) private readonly userProfilesRepository: UserProfilesRepository, - + private readonly moderationLogService: ModerationLogService, private readonly cacheService: CacheService, ) { super(meta, paramDef, async (ps, me) => { - const user = await this.usersRepository.findOneBy({ id: ps.userId }); + const user = await this.cacheService.findUserById(ps.userId); - if (user == null) { - throw new Error('user not found'); - } + await this.moderationLogService.log(me, 'nsfwUser', { + userId: ps.userId, + userUsername: user.username, + userHost: user.host, + }); await this.userProfilesRepository.update(user.id, { alwaysMarkNsfw: true, diff --git a/packages/backend/src/server/api/endpoints/admin/promo/create.ts b/packages/backend/src/server/api/endpoints/admin/promo/create.ts index 1d32c6cc00..69891d5454 100644 --- a/packages/backend/src/server/api/endpoints/admin/promo/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/promo/create.ts @@ -8,6 +8,8 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import type { PromoNotesRepository } from '@/models/_.js'; import { GetterService } from '@/server/api/GetterService.js'; import { DI } from '@/di-symbols.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; +import { CacheService } from '@/core/CacheService.js'; import { ApiError } from '../../../error.js'; export const meta = { @@ -46,7 +48,8 @@ export default class extends Endpoint { // eslint- constructor( @Inject(DI.promoNotesRepository) private promoNotesRepository: PromoNotesRepository, - + private readonly moderationLogService: ModerationLogService, + private readonly cacheService: CacheService, private getterService: GetterService, ) { super(meta, paramDef, async (ps, me) => { @@ -61,6 +64,15 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.alreadyPromoted); } + const user = await this.cacheService.findUserById(note.userId); + await this.moderationLogService.log(me, 'createPromo', { + noteId: note.id, + noteUserId: user.id, + noteUserUsername: user.username, + noteUserHost: user.host, + note: note, + }); + await this.promoNotesRepository.insert({ noteId: note.id, expiresAt: new Date(ps.expiresAt), diff --git a/packages/backend/src/server/api/endpoints/admin/relays/add.ts b/packages/backend/src/server/api/endpoints/admin/relays/add.ts index 3d7bc4567e..129f69aca9 100644 --- a/packages/backend/src/server/api/endpoints/admin/relays/add.ts +++ b/packages/backend/src/server/api/endpoints/admin/relays/add.ts @@ -8,6 +8,7 @@ import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { RelayService } from '@/core/RelayService.js'; import { ApiError } from '../../../error.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; export const meta = { tags: ['admin'], @@ -64,6 +65,7 @@ export const paramDef = { export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private relayService: RelayService, + private readonly moderationLogService: ModerationLogService, ) { super(meta, paramDef, async (ps, me) => { try { @@ -72,6 +74,10 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.invalidUrl); } + await this.moderationLogService.log(me, 'addRelay', { + inbox: ps.inbox, + }); + return await this.relayService.addRelay(ps.inbox); }); } diff --git a/packages/backend/src/server/api/endpoints/admin/relays/remove.ts b/packages/backend/src/server/api/endpoints/admin/relays/remove.ts index 1f6e773cd4..292f21fde9 100644 --- a/packages/backend/src/server/api/endpoints/admin/relays/remove.ts +++ b/packages/backend/src/server/api/endpoints/admin/relays/remove.ts @@ -6,6 +6,7 @@ import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { RelayService } from '@/core/RelayService.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; export const meta = { tags: ['admin'], @@ -27,9 +28,13 @@ export const paramDef = { export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private relayService: RelayService, + private readonly moderationLogService: ModerationLogService, ) { super(meta, paramDef, async (ps, me) => { - return await this.relayService.removeRelay(ps.inbox); + await this.moderationLogService.log(me, 'removeRelay', { + inbox: ps.inbox, + }); + await this.relayService.removeRelay(ps.inbox); }); } } diff --git a/packages/backend/src/server/api/endpoints/admin/silence-user.ts b/packages/backend/src/server/api/endpoints/admin/silence-user.ts index 7e6045049a..eed21c6576 100644 --- a/packages/backend/src/server/api/endpoints/admin/silence-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/silence-user.ts @@ -8,6 +8,9 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import type { UsersRepository } from '@/models/_.js'; import { DI } from '@/di-symbols.js'; import { RoleService } from '@/core/RoleService.js'; +import { CacheService } from '@/core/CacheService.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; +import { GlobalEventService } from '@/core/GlobalEventService.js'; export const meta = { tags: ['admin'], @@ -29,24 +32,32 @@ export const paramDef = { export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - - private roleService: RoleService, + private readonly usersRepository: UsersRepository, + private readonly cacheService: CacheService, + private readonly moderationLogService: ModerationLogService, + private readonly roleService: RoleService, + private readonly globalEventService: GlobalEventService, ) { super(meta, paramDef, async (ps, me) => { - const user = await this.usersRepository.findOneBy({ id: ps.userId }); - - if (user == null) { - throw new Error('user not found'); - } + const user = await this.cacheService.findUserById(ps.userId); if (await this.roleService.isModerator(user)) { throw new Error('cannot silence moderator account'); } + await this.moderationLogService.log(me, 'silenceUser', { + userId: ps.userId, + userUsername: user.username, + userHost: user.host, + }); + await this.usersRepository.update(user.id, { isSilenced: true, }); + + this.globalEventService.publishInternalEvent(user.host == null ? 'localUserUpdated' : 'remoteUserUpdated', { + id: user.id, + }); }); } } diff --git a/packages/backend/src/server/api/endpoints/admin/unnsfw-user.ts b/packages/backend/src/server/api/endpoints/admin/unnsfw-user.ts index 26588365e1..52a0c076be 100644 --- a/packages/backend/src/server/api/endpoints/admin/unnsfw-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/unnsfw-user.ts @@ -5,8 +5,10 @@ import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { UsersRepository, UserProfilesRepository } from '@/models/_.js'; +import type { UserProfilesRepository } from '@/models/_.js'; import { DI } from '@/di-symbols.js'; +import { CacheService } from '@/core/CacheService.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; export const meta = { tags: ['admin'], @@ -27,18 +29,19 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - + private readonly cacheService: CacheService, + private readonly moderationLogService: ModerationLogService, @Inject(DI.userProfilesRepository) - private userProfilesRepository: UserProfilesRepository, + private readonly userProfilesRepository: UserProfilesRepository, ) { super(meta, paramDef, async (ps, me) => { - const user = await this.usersRepository.findOneBy({ id: ps.userId }); + const user = await this.cacheService.findUserById(ps.userId); - if (user == null) { - throw new Error('user not found'); - } + await this.moderationLogService.log(me, 'unNsfwUser', { + userId: ps.userId, + userUsername: user.username, + userHost: user.host, + }); await this.userProfilesRepository.update(user.id, { alwaysMarkNsfw: false, diff --git a/packages/backend/src/server/api/endpoints/admin/unsilence-user.ts b/packages/backend/src/server/api/endpoints/admin/unsilence-user.ts index f92be0d8e0..9318943785 100644 --- a/packages/backend/src/server/api/endpoints/admin/unsilence-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/unsilence-user.ts @@ -7,6 +7,9 @@ import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { UsersRepository } from '@/models/_.js'; import { DI } from '@/di-symbols.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; +import { CacheService } from '@/core/CacheService.js'; +import { GlobalEventService } from '@/core/GlobalEventService.js'; export const meta = { tags: ['admin'], @@ -28,18 +31,27 @@ export const paramDef = { export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) - private usersRepository: UsersRepository, + private readonly usersRepository: UsersRepository, + private readonly cacheService: CacheService, + private readonly moderationLogService: ModerationLogService, + private readonly globalEventService: GlobalEventService, ) { super(meta, paramDef, async (ps, me) => { - const user = await this.usersRepository.findOneBy({ id: ps.userId }); + const user = await this.cacheService.findUserById(ps.userId); - if (user == null) { - throw new Error('user not found'); - } + await this.moderationLogService.log(me, 'unSilenceUser', { + userId: ps.userId, + userUsername: user.username, + userHost: user.host, + }); await this.usersRepository.update(user.id, { isSilenced: false, }); + + this.globalEventService.publishInternalEvent(user.host == null ? 'localUserUpdated' : 'remoteUserUpdated', { + id: user.id, + }); }); } } diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts index b5d982e3a5..977d6157bc 100644 --- a/packages/backend/src/types.ts +++ b/packages/backend/src/types.ts @@ -136,6 +136,21 @@ export const moderationLogTypes = [ 'rejectQuotesUser', 'acceptQuotesInstance', 'rejectQuotesInstance', + 'clearUserFiles', + 'nsfwUser', + 'unNsfwUser', + 'silenceUser', + 'unSilenceUser', + 'createAccount', + 'clearRemoteFiles', + 'clearOwnerlessFiles', + 'updateCustomEmojis', + 'importCustomEmojis', + 'clearInstanceFiles', + 'severFollowRelations', + 'createPromo', + 'addRelay', + 'removeRelay', ] as const; export type ModerationLogPayloads = { @@ -439,6 +454,72 @@ export type ModerationLogPayloads = { id: string; host: string; }; + clearUserFiles: { + userId: string; + userUsername: string; + userHost: string | null; + count: number; + }; + nsfwUser: { + userId: string; + userUsername: string; + userHost: string | null; + }; + unNsfwUser: { + userId: string; + userUsername: string; + userHost: string | null; + }; + silenceUser: { + userId: string; + userUsername: string; + userHost: string | null; + }; + unSilenceUser: { + userId: string; + userUsername: string; + userHost: string | null; + }; + createAccount: { + userId: string; + userUsername: string; + }; + clearRemoteFiles: Record; + clearOwnerlessFiles: { + count: number; + }; + updateCustomEmojis: { + ids: string[], + category?: string | null, + license?: string | null, + setAliases?: string[], + addAliases?: string[], + delAliases?: string[], + }, + importCustomEmojis: { + fileId: string, + fileName: string, + }, + clearInstanceFiles: { + host: string; + count: number; + }, + severFollowRelations: { + host: string; + }, + createPromo: { + noteId: string, + noteUserId: string; + noteUserUsername: string; + noteUserHost: string | null; + note: any; + }, + addRelay: { + inbox: string; + }, + removeRelay: { + inbox: string; + }, }; export type Serialized = { -- cgit v1.2.3-freya From c44c59e9ae7ed172a6bbabf0846ffb3123ac06ab Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Thu, 27 Feb 2025 10:28:47 -0500 Subject: remove embedded Note from "createPromo" mod logs --- packages/backend/src/types.ts | 1 - packages/misskey-js/src/consts.ts | 12 ++++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'packages/backend/src') diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts index 977d6157bc..530613ef4b 100644 --- a/packages/backend/src/types.ts +++ b/packages/backend/src/types.ts @@ -512,7 +512,6 @@ export type ModerationLogPayloads = { noteUserId: string; noteUserUsername: string; noteUserHost: string | null; - note: any; }, addRelay: { inbox: string; diff --git a/packages/misskey-js/src/consts.ts b/packages/misskey-js/src/consts.ts index b520c05d8e..a69ab168b8 100644 --- a/packages/misskey-js/src/consts.ts +++ b/packages/misskey-js/src/consts.ts @@ -510,4 +510,16 @@ export type ModerationLogPayloads = { id: string; host: string; }; + createPromo: { + noteId: string, + noteUserId: string; + noteUserUsername: string; + noteUserHost: string | null; + }; + addRelay: { + inbox: string; + }; + removeRelay: { + inbox: string; + }; }; -- cgit v1.2.3-freya From f42790ad32ff9ef2cc8d49336a759338b6aeeda2 Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Thu, 27 Feb 2025 10:52:52 -0500 Subject: don't pass note into moderationLogService.log --- packages/backend/src/server/api/endpoints/admin/promo/create.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'packages/backend/src') diff --git a/packages/backend/src/server/api/endpoints/admin/promo/create.ts b/packages/backend/src/server/api/endpoints/admin/promo/create.ts index 69891d5454..63fe2988ee 100644 --- a/packages/backend/src/server/api/endpoints/admin/promo/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/promo/create.ts @@ -70,7 +70,6 @@ export default class extends Endpoint { // eslint- noteUserId: user.id, noteUserUsername: user.username, noteUserHost: user.host, - note: note, }); await this.promoNotesRepository.insert({ -- cgit v1.2.3-freya From e030facaa992b1b836f75e8bbf23c763c7db7d89 Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Thu, 27 Feb 2025 11:20:13 -0500 Subject: don't record deleted note, flash, page, or gallery post in modlog --- packages/backend/src/core/NoteDeleteService.ts | 1 - packages/backend/src/server/api/endpoints/flash/delete.ts | 1 - packages/backend/src/server/api/endpoints/gallery/posts/delete.ts | 1 - packages/backend/src/server/api/endpoints/pages/delete.ts | 1 - packages/backend/src/types.ts | 4 ---- packages/misskey-js/src/consts.ts | 8 -------- 6 files changed, 16 deletions(-) (limited to 'packages/backend/src') diff --git a/packages/backend/src/core/NoteDeleteService.ts b/packages/backend/src/core/NoteDeleteService.ts index cb258a4f5a..1f94e65809 100644 --- a/packages/backend/src/core/NoteDeleteService.ts +++ b/packages/backend/src/core/NoteDeleteService.ts @@ -162,7 +162,6 @@ export class NoteDeleteService { noteUserId: note.userId, noteUserUsername: user.username, noteUserHost: user.host, - note: note, }); } diff --git a/packages/backend/src/server/api/endpoints/flash/delete.ts b/packages/backend/src/server/api/endpoints/flash/delete.ts index 5b7d936b1c..271a44f8d5 100644 --- a/packages/backend/src/server/api/endpoints/flash/delete.ts +++ b/packages/backend/src/server/api/endpoints/flash/delete.ts @@ -78,7 +78,6 @@ export default class extends Endpoint { // eslint- flashId: flash.id, flashUserId: flash.userId, flashUserUsername: user.username, - flash, }); } }); diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/delete.ts b/packages/backend/src/server/api/endpoints/gallery/posts/delete.ts index 28c8237761..9854358e3e 100644 --- a/packages/backend/src/server/api/endpoints/gallery/posts/delete.ts +++ b/packages/backend/src/server/api/endpoints/gallery/posts/delete.ts @@ -78,7 +78,6 @@ export default class extends Endpoint { // eslint- postId: post.id, postUserId: post.userId, postUserUsername: user.username, - post, }); } }); diff --git a/packages/backend/src/server/api/endpoints/pages/delete.ts b/packages/backend/src/server/api/endpoints/pages/delete.ts index 0ad7a3633a..c95f8ecf6b 100644 --- a/packages/backend/src/server/api/endpoints/pages/delete.ts +++ b/packages/backend/src/server/api/endpoints/pages/delete.ts @@ -79,7 +79,6 @@ export default class extends Endpoint { // eslint- pageId: page.id, pageUserId: page.userId, pageUserUsername: user.username, - page, }); } }); diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts index 530613ef4b..6d58a9ef0a 100644 --- a/packages/backend/src/types.ts +++ b/packages/backend/src/types.ts @@ -239,7 +239,6 @@ export type ModerationLogPayloads = { noteUserId: string; noteUserUsername: string; noteUserHost: string | null; - note: any; }; createGlobalAnnouncement: { announcementId: string; @@ -422,19 +421,16 @@ export type ModerationLogPayloads = { pageId: string; pageUserId: string; pageUserUsername: string; - page: any; }; deleteFlash: { flashId: string; flashUserId: string; flashUserUsername: string; - flash: any; }; deleteGalleryPost: { postId: string; postUserId: string; postUserUsername: string; - post: any; }; acceptQuotesUser: { userId: string, diff --git a/packages/misskey-js/src/consts.ts b/packages/misskey-js/src/consts.ts index a69ab168b8..f6d3d682af 100644 --- a/packages/misskey-js/src/consts.ts +++ b/packages/misskey-js/src/consts.ts @@ -4,12 +4,8 @@ import type { Ad, Announcement, EmojiDetailed, - Flash, - GalleryPost, InviteCode, MetaDetailed, - Note, - Page, Role, ReversiGameDetailed, SystemWebhook, @@ -295,7 +291,6 @@ export type ModerationLogPayloads = { noteUserId: string; noteUserUsername: string; noteUserHost: string | null; - note: Note; }; createGlobalAnnouncement: { announcementId: string; @@ -478,19 +473,16 @@ export type ModerationLogPayloads = { pageId: string; pageUserId: string; pageUserUsername: string; - page: Page; }; deleteFlash: { flashId: string; flashUserId: string; flashUserUsername: string; - flash: Flash; }; deleteGalleryPost: { postId: string; postUserId: string; postUserUsername: string; - post: GalleryPost; }; acceptQuotesUser: { userId: string, -- cgit v1.2.3-freya From 9fdb68d5689fc0f2ccbad0f02cd1f331e145ea6e Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Sun, 2 Mar 2025 13:47:02 -0500 Subject: remove `fileId` from `importCustomEmojis` log --- packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts | 1 - packages/backend/src/types.ts | 1 - packages/frontend/src/pages/admin/modlog.ModLog.vue | 2 +- packages/misskey-js/src/consts.ts | 1 - 4 files changed, 1 insertion(+), 4 deletions(-) (limited to 'packages/backend/src') diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts b/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts index b3dc3978d1..ee7706f31a 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts @@ -35,7 +35,6 @@ export default class extends Endpoint { // eslint- super(meta, paramDef, async (ps, me) => { const file = await driveFilesRepository.findOneByOrFail({ id: ps.fileId }); await this.moderationLogService.log(me, 'importCustomEmojis', { - fileId: file.id, fileName: file.name, }); await this.queueService.createImportCustomEmojisJob(me, ps.fileId); diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts index 6d58a9ef0a..2c6ef731b8 100644 --- a/packages/backend/src/types.ts +++ b/packages/backend/src/types.ts @@ -493,7 +493,6 @@ export type ModerationLogPayloads = { delAliases?: string[], }, importCustomEmojis: { - fileId: string, fileName: string, }, clearInstanceFiles: { diff --git a/packages/frontend/src/pages/admin/modlog.ModLog.vue b/packages/frontend/src/pages/admin/modlog.ModLog.vue index 1d60403f07..9ce6499e2d 100644 --- a/packages/frontend/src/pages/admin/modlog.ModLog.vue +++ b/packages/frontend/src/pages/admin/modlog.ModLog.vue @@ -256,7 +256,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.filesRemoved }}: {{ log.info.count }}