Skip to content

Commit

Permalink
enhance: improve moderation log
Browse files Browse the repository at this point in the history
  • Loading branch information
syuilo committed Sep 25, 2023
1 parent 646a8d1 commit 5318532
Show file tree
Hide file tree
Showing 19 changed files with 209 additions and 60 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@

## (unreleased)
### General
-
- Enhance: モデレーションログ機能の強化

### Client
-

### Server
- Fix: お知らせのページネーションが機能しない

## 2023.9.0 (unreleased)
## 2023.9.0

### Note
- meilisearchを使用する場合、v1.2以上が必要です
Expand Down
5 changes: 4 additions & 1 deletion locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1123,6 +1123,7 @@ export interface Locale {
"unnotifyNotes": string;
"authentication": string;
"authenticationRequiredToContinue": string;
"dateAndTime": string;
"_announcement": {
"forExistingUsers": string;
"forExistingUsersDescription": string;
Expand Down Expand Up @@ -2250,9 +2251,11 @@ export interface Locale {
};
};
"_moderationLogTypes": {
"createRole": string;
"deleteRole": string;
"updateRole": string;
"assignRole": string;
"unassignRole": string;
"updateRole": string;
"suspend": string;
"unsuspend": string;
"addCustomEmoji": string;
Expand Down
5 changes: 4 additions & 1 deletion locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1120,6 +1120,7 @@ notifyNotes: "投稿を通知"
unnotifyNotes: "投稿の通知を解除"
authentication: "認証"
authenticationRequiredToContinue: "続けるには認証を行ってください"
dateAndTime: "日時"

_announcement:
forExistingUsers: "既存ユーザーのみ"
Expand Down Expand Up @@ -2163,9 +2164,11 @@ _webhookSettings:
mention: "メンションされたとき"

_moderationLogTypes:
createRole: "ロールを作成"
deleteRole: "ロールを削除"
updateRole: "ロールを更新"
assignRole: "ロールへアサイン"
unassignRole: "ロールのアサイン解除"
updateRole: "ロール設定更新"
suspend: "凍結"
unsuspend: "凍結解除"
addCustomEmoji: "カスタム絵文字追加"
Expand Down
12 changes: 11 additions & 1 deletion packages/backend/src/core/AnnouncementService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { Brackets } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { MiUser } from '@/models/User.js';
import type { AnnouncementReadsRepository, AnnouncementsRepository, MiAnnouncement, MiAnnouncementRead } from '@/models/_.js';
import type { AnnouncementReadsRepository, AnnouncementsRepository, MiAnnouncement, MiAnnouncementRead, UsersRepository } from '@/models/_.js';
import { bindThis } from '@/decorators.js';
import { Packed } from '@/misc/json-schema.js';
import { IdService } from '@/core/IdService.js';
Expand All @@ -23,6 +23,9 @@ export class AnnouncementService {
@Inject(DI.announcementReadsRepository)
private announcementReadsRepository: AnnouncementReadsRepository,

@Inject(DI.usersRepository)
private usersRepository: UsersRepository,

private idService: IdService,
private globalEventService: GlobalEventService,
private moderationLogService: ModerationLogService,
Expand Down Expand Up @@ -83,10 +86,13 @@ export class AnnouncementService {
});

if (moderator) {
const user = await this.usersRepository.findOneByOrFail({ id: values.userId });
this.moderationLogService.log(moderator, 'createUserAnnouncement', {
announcementId: announcement.id,
announcement: announcement,
userId: values.userId,
userUsername: user.username,
userHost: user.host,
});
}
} else {
Expand Down Expand Up @@ -127,10 +133,14 @@ export class AnnouncementService {

if (moderator) {
if (announcement.userId) {
const user = await this.usersRepository.findOneByOrFail({ id: announcement.userId });
this.moderationLogService.log(moderator, 'updateUserAnnouncement', {
announcementId: announcement.id,
before: announcement,
after: after,
userId: announcement.userId,
userUsername: user.username,
userHost: user.host,
});
} else {
this.moderationLogService.log(moderator, 'updateGlobalAnnouncement', {
Expand Down
7 changes: 4 additions & 3 deletions packages/backend/src/core/CustomEmojiService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,23 +134,24 @@ export class CustomEmojiService implements OnApplicationShutdown {

this.localEmojisCache.refresh();

const updated = await this.emojiEntityService.packDetailed(emoji.id);
const packed = await this.emojiEntityService.packDetailed(emoji.id);

if (emoji.name === data.name) {
this.globalEventService.publishBroadcastStream('emojiUpdated', {
emojis: [updated],
emojis: [packed],
});
} else {
this.globalEventService.publishBroadcastStream('emojiDeleted', {
emojis: [await this.emojiEntityService.packDetailed(emoji)],
});

this.globalEventService.publishBroadcastStream('emojiAdded', {
emoji: updated,
emoji: packed,
});
}

if (moderator) {
const updated = await this.emojisRepository.findOneByOrFail({ id: id });
this.moderationLogService.log(moderator, 'updateCustomEmoji', {
emojiId: emoji.id,
before: emoji,
Expand Down
8 changes: 8 additions & 0 deletions packages/backend/src/core/DriveService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -686,15 +686,20 @@ export class DriveService {

if (await this.roleService.isModerator(updater) && (file.userId !== updater.id)) {
if (values.isSensitive !== undefined && values.isSensitive !== file.isSensitive) {
const user = file.userId ? await this.usersRepository.findOneByOrFail({ id: file.userId }) : null;
if (values.isSensitive) {
this.moderationLogService.log(updater, 'markSensitiveDriveFile', {
fileId: file.id,
fileUserId: file.userId,
fileUserUsername: user?.username ?? null,
fileUserHost: user?.host ?? null,
});
} else {
this.moderationLogService.log(updater, 'unmarkSensitiveDriveFile', {
fileId: file.id,
fileUserId: file.userId,
fileUserUsername: user?.username ?? null,
fileUserHost: user?.host ?? null,
});
}
}
Expand Down Expand Up @@ -795,9 +800,12 @@ export class DriveService {
}

if (deleter && await this.roleService.isModerator(deleter) && (file.userId !== deleter.id)) {
const user = file.userId ? await this.usersRepository.findOneByOrFail({ id: file.userId }) : null;
this.moderationLogService.log(deleter, 'deleteDriveFile', {
fileId: file.id,
fileUserId: file.userId,
fileUserUsername: user?.username ?? null,
fileUserHost: user?.host ?? null,
});
}
}
Expand Down
3 changes: 3 additions & 0 deletions packages/backend/src/core/NoteDeleteService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,12 @@ export class NoteDeleteService {
});

if (deleter && (note.userId !== deleter.id)) {
const user = await this.usersRepository.findOneByOrFail({ id: note.userId });
this.moderationLogService.log(deleter, 'deleteNote', {
noteId: note.id,
noteUserId: note.userId,
noteUserUsername: user.username,
noteUserHost: user.host,
note: note,
});
}
Expand Down
46 changes: 45 additions & 1 deletion packages/backend/src/core/RoleService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -412,10 +412,13 @@ export class RoleService implements OnApplicationShutdown {
this.globalEventService.publishInternalEvent('userRoleAssigned', created);

if (moderator) {
const user = await this.usersRepository.findOneByOrFail({ id: userId });
this.moderationLogService.log(moderator, 'assignRole', {
roleId: roleId,
roleName: role.name,
userId: userId,
userUsername: user.username,
userHost: user.host,
expiresAt: expiresAt ? expiresAt.toISOString() : null,
});
}
Expand Down Expand Up @@ -445,11 +448,16 @@ export class RoleService implements OnApplicationShutdown {
this.globalEventService.publishInternalEvent('userRoleUnassigned', existing);

if (moderator) {
const role = await this.rolesRepository.findOneByOrFail({ id: roleId });
const [user, role] = await Promise.all([
this.usersRepository.findOneByOrFail({ id: userId }),
this.rolesRepository.findOneByOrFail({ id: roleId }),
]);
this.moderationLogService.log(moderator, 'unassignRole', {
roleId: roleId,
roleName: role.name,
userId: userId,
userUsername: user.username,
userHost: user.host,
});
}
}
Expand All @@ -473,6 +481,42 @@ export class RoleService implements OnApplicationShutdown {
redisPipeline.exec();
}

@bindThis
public async create(values: Partial<MiRole>, moderator?: MiUser): Promise<MiRole> {
const date = new Date();
const created = await this.rolesRepository.insert({
id: this.idService.genId(),
createdAt: date,
updatedAt: date,
lastUsedAt: date,
name: values.name,
description: values.description,
color: values.color,
iconUrl: values.iconUrl,
target: values.target,
condFormula: values.condFormula,
isPublic: values.isPublic,
isAdministrator: values.isAdministrator,
isModerator: values.isModerator,
isExplorable: values.isExplorable,
asBadge: values.asBadge,
canEditMembersByModerator: values.canEditMembersByModerator,
displayOrder: values.displayOrder,
policies: values.policies,
}).then(x => this.rolesRepository.findOneByOrFail(x.identifiers[0]));

this.globalEventService.publishInternalEvent('roleCreated', created);

if (moderator) {
this.moderationLogService.log(moderator, 'createRole', {
roleId: created.id,
role: created,
});
}

return created;
}

@bindThis
public async update(role: MiRole, params: Partial<MiRole>, moderator?: MiUser): Promise<void> {
const date = new Date();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
});

this.moderationLogService.log(me, 'resetPassword', {
targetId: user.id,
userId: user.id,
userUsername: user.username,
userHost: user.host,
});

return {
Expand Down
35 changes: 3 additions & 32 deletions packages/backend/src/server/api/endpoints/admin/roles/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@

import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import type { RolesRepository } from '@/models/_.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { DI } from '@/di-symbols.js';
import { IdService } from '@/core/IdService.js';
import { RoleEntityService } from '@/core/entities/RoleEntityService.js';
import { RoleService } from '@/core/RoleService.js';

export const meta = {
tags: ['admin', 'role'],
Expand Down Expand Up @@ -58,37 +55,11 @@ export const paramDef = {
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
constructor(
@Inject(DI.rolesRepository)
private rolesRepository: RolesRepository,

private globalEventService: GlobalEventService,
private idService: IdService,
private roleEntityService: RoleEntityService,
private roleService: RoleService,
) {
super(meta, paramDef, async (ps, me) => {
const date = new Date();
const created = await this.rolesRepository.insert({
id: this.idService.genId(),
createdAt: date,
updatedAt: date,
lastUsedAt: date,
name: ps.name,
description: ps.description,
color: ps.color,
iconUrl: ps.iconUrl,
target: ps.target,
condFormula: ps.condFormula,
isPublic: ps.isPublic,
isAdministrator: ps.isAdministrator,
isModerator: ps.isModerator,
isExplorable: ps.isExplorable,
asBadge: ps.asBadge,
canEditMembersByModerator: ps.canEditMembersByModerator,
displayOrder: ps.displayOrder,
policies: ps.policies,
}).then(x => this.rolesRepository.findOneByOrFail(x.identifiers[0]));

this.globalEventService.publishInternalEvent('roleCreated', created);
const created = await this.roleService.create(ps, me);

return await this.roleEntityService.pack(created, me);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw new ApiError(meta.errors.noSuchRole);
}

const date = new Date();
await this.roleService.update(role, {
updatedAt: date,
name: ps.name,
description: ps.description,
color: ps.color,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
});

this.moderationLogService.log(me, 'suspend', {
targetId: user.id,
userId: user.id,
userUsername: user.username,
userHost: user.host,
});

(async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
});

this.moderationLogService.log(me, 'unsuspend', {
targetId: user.id,
userId: user.id,
userUsername: user.username,
userHost: user.host,
});

this.userSuspendService.doPostUnsuspend(user);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-

this.moderationLogService.log(me, 'updateUserNote', {
userId: user.id,
userUsername: user.username,
userHost: user.host,
before: currentProfile.moderationNote,
after: ps.text,
});
Expand Down
Loading

0 comments on commit 5318532

Please sign in to comment.