improve moderation log
This commit is contained in:
parent
82a51d49a0
commit
841e6ff901
7 changed files with 90 additions and 51 deletions
|
@ -2184,3 +2184,5 @@ _moderationLogTypes:
|
||||||
resetPassword: "パスワードをリセット"
|
resetPassword: "パスワードをリセット"
|
||||||
suspendRemoteInstance: "リモートサーバーを停止"
|
suspendRemoteInstance: "リモートサーバーを停止"
|
||||||
unsuspendRemoteInstance: "リモートサーバーを再開"
|
unsuspendRemoteInstance: "リモートサーバーを再開"
|
||||||
|
markSensitiveDriveFile: "ファイルをセンシティブ付与"
|
||||||
|
unmarkSensitiveDriveFile: "ファイルをセンシティブ解除"
|
||||||
|
|
|
@ -649,6 +649,57 @@ export class DriveService {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@bindThis
|
||||||
|
public async update(file: MiDriveFile, values: Partial<MiDriveFile>, updater: MiUser) {
|
||||||
|
const alwaysMarkNsfw = (await this.roleService.getUserPolicies(file.userId)).alwaysMarkNsfw;
|
||||||
|
|
||||||
|
if (values.name && !this.driveFileEntityService.validateFileName(file.name)) {
|
||||||
|
throw new Error('invalid filename');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values.isSensitive !== undefined && values.isSensitive !== file.isSensitive && alwaysMarkNsfw && !values.isSensitive) {
|
||||||
|
throw new Error('cannot unmark nsfw');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values.folderId != null) {
|
||||||
|
const folder = await this.driveFoldersRepository.findOneBy({
|
||||||
|
id: values.folderId,
|
||||||
|
userId: file.userId!,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (folder == null) {
|
||||||
|
throw new Error('folder-not-found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.driveFilesRepository.update(file.id, values);
|
||||||
|
|
||||||
|
const fileObj = await this.driveFileEntityService.pack(file, { self: true });
|
||||||
|
|
||||||
|
// Publish fileUpdated event
|
||||||
|
if (file.userId) {
|
||||||
|
this.globalEventService.publishDriveStream(file.userId, 'fileUpdated', fileObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await this.roleService.isModerator(updater) && (file.userId !== updater.id)) {
|
||||||
|
if (values.isSensitive !== undefined && values.isSensitive !== file.isSensitive) {
|
||||||
|
if (values.isSensitive) {
|
||||||
|
this.moderationLogService.log(updater, 'markSensitiveDriveFile', {
|
||||||
|
fileId: file.id,
|
||||||
|
fileUserId: file.userId,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.moderationLogService.log(updater, 'unmarkSensitiveDriveFile', {
|
||||||
|
fileId: file.id,
|
||||||
|
fileUserId: file.userId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileObj;
|
||||||
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async deleteFile(file: MiDriveFile, isExpired = false, deleter?: MiUser) {
|
public async deleteFile(file: MiDriveFile, isExpired = false, deleter?: MiUser) {
|
||||||
if (file.storedInternal) {
|
if (file.storedInternal) {
|
||||||
|
|
|
@ -4,12 +4,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import type { DriveFilesRepository, DriveFoldersRepository } from '@/models/_.js';
|
import type { DriveFilesRepository } from '@/models/_.js';
|
||||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
|
|
||||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { RoleService } from '@/core/RoleService.js';
|
import { RoleService } from '@/core/RoleService.js';
|
||||||
|
import { DriveService } from '@/core/DriveService.js';
|
||||||
import { ApiError } from '../../../error.js';
|
import { ApiError } from '../../../error.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
@ -77,16 +76,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
@Inject(DI.driveFilesRepository)
|
@Inject(DI.driveFilesRepository)
|
||||||
private driveFilesRepository: DriveFilesRepository,
|
private driveFilesRepository: DriveFilesRepository,
|
||||||
|
|
||||||
@Inject(DI.driveFoldersRepository)
|
private driveService: DriveService,
|
||||||
private driveFoldersRepository: DriveFoldersRepository,
|
|
||||||
|
|
||||||
private driveFileEntityService: DriveFileEntityService,
|
|
||||||
private roleService: RoleService,
|
private roleService: RoleService,
|
||||||
private globalEventService: GlobalEventService,
|
|
||||||
) {
|
) {
|
||||||
super(meta, paramDef, async (ps, me) => {
|
super(meta, paramDef, async (ps, me) => {
|
||||||
const file = await this.driveFilesRepository.findOneBy({ id: ps.fileId });
|
const file = await this.driveFilesRepository.findOneBy({ id: ps.fileId });
|
||||||
const alwaysMarkNsfw = (await this.roleService.getUserPolicies(me.id)).alwaysMarkNsfw;
|
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
throw new ApiError(meta.errors.noSuchFile);
|
throw new ApiError(meta.errors.noSuchFile);
|
||||||
}
|
}
|
||||||
|
@ -95,47 +89,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
throw new ApiError(meta.errors.accessDenied);
|
throw new ApiError(meta.errors.accessDenied);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps.name) file.name = ps.name;
|
const fileObj = await this.driveService.update(file, ps, me);
|
||||||
if (!this.driveFileEntityService.validateFileName(file.name)) {
|
|
||||||
throw new ApiError(meta.errors.invalidFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ps.comment !== undefined) file.comment = ps.comment;
|
|
||||||
|
|
||||||
if (ps.isSensitive !== undefined && ps.isSensitive !== file.isSensitive && alwaysMarkNsfw && !ps.isSensitive) {
|
|
||||||
throw new ApiError(meta.errors.restrictedByRole);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ps.isSensitive !== undefined) file.isSensitive = ps.isSensitive;
|
|
||||||
|
|
||||||
if (ps.folderId !== undefined) {
|
|
||||||
if (ps.folderId === null) {
|
|
||||||
file.folderId = null;
|
|
||||||
} else {
|
|
||||||
const folder = await this.driveFoldersRepository.findOneBy({
|
|
||||||
id: ps.folderId,
|
|
||||||
userId: me.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (folder == null) {
|
|
||||||
throw new ApiError(meta.errors.noSuchFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
file.folderId = folder.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.driveFilesRepository.update(file.id, {
|
|
||||||
name: file.name,
|
|
||||||
comment: file.comment,
|
|
||||||
folderId: file.folderId,
|
|
||||||
isSensitive: file.isSensitive,
|
|
||||||
});
|
|
||||||
|
|
||||||
const fileObj = await this.driveFileEntityService.pack(file, { self: true });
|
|
||||||
|
|
||||||
// Publish fileUpdated event
|
|
||||||
this.globalEventService.publishDriveStream(me.id, 'fileUpdated', fileObj);
|
|
||||||
|
|
||||||
return fileObj;
|
return fileObj;
|
||||||
});
|
});
|
||||||
|
|
|
@ -52,6 +52,8 @@ export const moderationLogTypes = [
|
||||||
'resetPassword',
|
'resetPassword',
|
||||||
'suspendRemoteInstance',
|
'suspendRemoteInstance',
|
||||||
'unsuspendRemoteInstance',
|
'unsuspendRemoteInstance',
|
||||||
|
'markSensitiveDriveFile',
|
||||||
|
'unmarkSensitiveDriveFile',
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export type ModerationLogPayloads = {
|
export type ModerationLogPayloads = {
|
||||||
|
@ -152,4 +154,12 @@ export type ModerationLogPayloads = {
|
||||||
id: string;
|
id: string;
|
||||||
host: string;
|
host: string;
|
||||||
};
|
};
|
||||||
|
markSensitiveDriveFile: {
|
||||||
|
fileId: string;
|
||||||
|
fileUserId: string | null;
|
||||||
|
};
|
||||||
|
unmarkSensitiveDriveFile: {
|
||||||
|
fileId: string;
|
||||||
|
fileUserId: string | null;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -2595,10 +2595,16 @@ type ModerationLog = {
|
||||||
} | {
|
} | {
|
||||||
type: 'unsuspendRemoteInstance';
|
type: 'unsuspendRemoteInstance';
|
||||||
info: ModerationLogPayloads['unsuspendRemoteInstance'];
|
info: ModerationLogPayloads['unsuspendRemoteInstance'];
|
||||||
|
} | {
|
||||||
|
type: 'markSensitiveDriveFile';
|
||||||
|
info: ModerationLogPayloads['markSensitiveDriveFile'];
|
||||||
|
} | {
|
||||||
|
type: 'unmarkSensitiveDriveFile';
|
||||||
|
info: ModerationLogPayloads['unmarkSensitiveDriveFile'];
|
||||||
});
|
});
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
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"];
|
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", "markSensitiveDriveFile", "unmarkSensitiveDriveFile"];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
export const mutedNoteReasons: readonly ["word", "manual", "spam", "other"];
|
export const mutedNoteReasons: readonly ["word", "manual", "spam", "other"];
|
||||||
|
|
|
@ -70,6 +70,8 @@ export const moderationLogTypes = [
|
||||||
'resetPassword',
|
'resetPassword',
|
||||||
'suspendRemoteInstance',
|
'suspendRemoteInstance',
|
||||||
'unsuspendRemoteInstance',
|
'unsuspendRemoteInstance',
|
||||||
|
'markSensitiveDriveFile',
|
||||||
|
'unmarkSensitiveDriveFile',
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export type ModerationLogPayloads = {
|
export type ModerationLogPayloads = {
|
||||||
|
@ -170,4 +172,12 @@ export type ModerationLogPayloads = {
|
||||||
id: string;
|
id: string;
|
||||||
host: string;
|
host: string;
|
||||||
};
|
};
|
||||||
|
markSensitiveDriveFile: {
|
||||||
|
fileId: string;
|
||||||
|
fileUserId: string | null;
|
||||||
|
};
|
||||||
|
unmarkSensitiveDriveFile: {
|
||||||
|
fileId: string;
|
||||||
|
fileUserId: string | null;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -646,4 +646,10 @@ export type ModerationLog = {
|
||||||
} | {
|
} | {
|
||||||
type: 'unsuspendRemoteInstance';
|
type: 'unsuspendRemoteInstance';
|
||||||
info: ModerationLogPayloads['unsuspendRemoteInstance'];
|
info: ModerationLogPayloads['unsuspendRemoteInstance'];
|
||||||
|
} | {
|
||||||
|
type: 'markSensitiveDriveFile';
|
||||||
|
info: ModerationLogPayloads['markSensitiveDriveFile'];
|
||||||
|
} | {
|
||||||
|
type: 'unmarkSensitiveDriveFile';
|
||||||
|
info: ModerationLogPayloads['unmarkSensitiveDriveFile'];
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue