Resolve #3238
This commit is contained in:
parent
0fc965f342
commit
b34c1379e9
@ -1529,6 +1529,12 @@ admin/views/moderators.vue:
|
|||||||
added: "モデレーターを登録しました"
|
added: "モデレーターを登録しました"
|
||||||
remove: "解除"
|
remove: "解除"
|
||||||
removed: "モデレーター登録を解除しました"
|
removed: "モデレーター登録を解除しました"
|
||||||
|
logs:
|
||||||
|
title: "ログ"
|
||||||
|
moderator: "モデレーター"
|
||||||
|
type: "操作"
|
||||||
|
at: "日時"
|
||||||
|
info: "情報"
|
||||||
|
|
||||||
admin/views/emoji.vue:
|
admin/views/emoji.vue:
|
||||||
add-emoji:
|
add-emoji:
|
||||||
|
17
migration/1562869971568-ModerationLog.ts
Normal file
17
migration/1562869971568-ModerationLog.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||||
|
|
||||||
|
export class ModerationLog1562869971568 implements MigrationInterface {
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||||
|
await queryRunner.query(`CREATE TABLE "moderation_log" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "type" character varying(128) NOT NULL, "info" jsonb NOT NULL, CONSTRAINT "PK_d0adca6ecfd068db83e4526cc26" PRIMARY KEY ("id"))`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_a08ad074601d204e0f69da9a95" ON "moderation_log" ("userId") `);
|
||||||
|
await queryRunner.query(`ALTER TABLE "moderation_log" ADD CONSTRAINT "FK_a08ad074601d204e0f69da9a954" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "moderation_log" DROP CONSTRAINT "FK_a08ad074601d204e0f69da9a954"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "IDX_a08ad074601d204e0f69da9a95"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "moderation_log"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -12,6 +12,31 @@
|
|||||||
</ui-horizon-group>
|
</ui-horizon-group>
|
||||||
</section>
|
</section>
|
||||||
</ui-card>
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card>
|
||||||
|
<template #title>{{ $t('logs.title') }}</template>
|
||||||
|
<section class="fit-top">
|
||||||
|
<sequential-entrance animation="entranceFromTop" delay="25">
|
||||||
|
<div v-for="log in logs" :key="log.id" class="">
|
||||||
|
<ui-horizon-group inputs>
|
||||||
|
<ui-input :value="log.user | acct" type="text" readonly>
|
||||||
|
<span>{{ $t('logs.moderator') }}</span>
|
||||||
|
</ui-input>
|
||||||
|
<ui-input :value="log.type" type="text" readonly>
|
||||||
|
<span>{{ $t('logs.type') }}</span>
|
||||||
|
</ui-input>
|
||||||
|
<ui-input :value="log.createdAt | date" type="text" readonly>
|
||||||
|
<span>{{ $t('logs.at') }}</span>
|
||||||
|
</ui-input>
|
||||||
|
</ui-horizon-group>
|
||||||
|
<ui-textarea :value="JSON.stringify(log.info, null, 4)" readonly>
|
||||||
|
<span>{{ $t('logs.info') }}</span>
|
||||||
|
</ui-textarea>
|
||||||
|
</div>
|
||||||
|
</sequential-entrance>
|
||||||
|
<ui-button v-if="existMoreLogs" @click="fetchLogs">{{ $t('@.load-more') }}</ui-button>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -26,10 +51,17 @@ export default Vue.extend({
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
username: '',
|
username: '',
|
||||||
changing: false
|
changing: false,
|
||||||
|
logs: [],
|
||||||
|
untilLogId: null,
|
||||||
|
existMoreLogs: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.fetchLogs();
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
async add() {
|
async add() {
|
||||||
this.changing = true;
|
this.changing = true;
|
||||||
@ -74,6 +106,22 @@ export default Vue.extend({
|
|||||||
|
|
||||||
this.changing = false;
|
this.changing = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
fetchLogs() {
|
||||||
|
this.$root.api('admin/show-moderation-logs', {
|
||||||
|
untilId: this.untilId,
|
||||||
|
limit: 10 + 1
|
||||||
|
}).then(logs => {
|
||||||
|
if (logs.length == 10 + 1) {
|
||||||
|
logs.pop();
|
||||||
|
this.existMoreLogs = true;
|
||||||
|
} else {
|
||||||
|
this.existMoreLogs = false;
|
||||||
|
}
|
||||||
|
this.logs = this.logs.concat(logs);
|
||||||
|
this.untilLogId = this.logs[this.logs.length - 1].id;
|
||||||
|
});
|
||||||
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -47,6 +47,7 @@ import { UserSecurityKey } from '../models/entities/user-security-key';
|
|||||||
import { AttestationChallenge } from '../models/entities/attestation-challenge';
|
import { AttestationChallenge } from '../models/entities/attestation-challenge';
|
||||||
import { Page } from '../models/entities/page';
|
import { Page } from '../models/entities/page';
|
||||||
import { PageLike } from '../models/entities/page-like';
|
import { PageLike } from '../models/entities/page-like';
|
||||||
|
import { ModerationLog } from '../models/entities/moderation-log';
|
||||||
|
|
||||||
const sqlLogger = dbLogger.createSubLogger('sql', 'white', false);
|
const sqlLogger = dbLogger.createSubLogger('sql', 'white', false);
|
||||||
|
|
||||||
@ -124,6 +125,7 @@ export const entities = [
|
|||||||
RegistrationTicket,
|
RegistrationTicket,
|
||||||
MessagingMessage,
|
MessagingMessage,
|
||||||
Signin,
|
Signin,
|
||||||
|
ModerationLog,
|
||||||
ReversiGame,
|
ReversiGame,
|
||||||
ReversiMatching,
|
ReversiMatching,
|
||||||
...charts as any
|
...charts as any
|
||||||
|
32
src/models/entities/moderation-log.ts
Normal file
32
src/models/entities/moderation-log.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
|
||||||
|
import { User } from './user';
|
||||||
|
import { id } from '../id';
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
export class ModerationLog {
|
||||||
|
@PrimaryColumn(id())
|
||||||
|
public id: string;
|
||||||
|
|
||||||
|
@Column('timestamp with time zone', {
|
||||||
|
comment: 'The created date of the ModerationLog.'
|
||||||
|
})
|
||||||
|
public createdAt: Date;
|
||||||
|
|
||||||
|
@Index()
|
||||||
|
@Column(id())
|
||||||
|
public userId: User['id'];
|
||||||
|
|
||||||
|
@ManyToOne(type => User, {
|
||||||
|
onDelete: 'CASCADE'
|
||||||
|
})
|
||||||
|
@JoinColumn()
|
||||||
|
public user: User | null;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 128,
|
||||||
|
})
|
||||||
|
public type: string;
|
||||||
|
|
||||||
|
@Column('jsonb')
|
||||||
|
public info: Record<string, any>;
|
||||||
|
}
|
@ -42,6 +42,7 @@ import { UserSecurityKey } from './entities/user-security-key';
|
|||||||
import { HashtagRepository } from './repositories/hashtag';
|
import { HashtagRepository } from './repositories/hashtag';
|
||||||
import { PageRepository } from './repositories/page';
|
import { PageRepository } from './repositories/page';
|
||||||
import { PageLikeRepository } from './repositories/page-like';
|
import { PageLikeRepository } from './repositories/page-like';
|
||||||
|
import { ModerationLogRepository } from './repositories/moderation-logs';
|
||||||
|
|
||||||
export const Apps = getCustomRepository(AppRepository);
|
export const Apps = getCustomRepository(AppRepository);
|
||||||
export const Notes = getCustomRepository(NoteRepository);
|
export const Notes = getCustomRepository(NoteRepository);
|
||||||
@ -86,3 +87,4 @@ export const ReversiMatchings = getCustomRepository(ReversiMatchingRepository);
|
|||||||
export const Logs = getRepository(Log);
|
export const Logs = getRepository(Log);
|
||||||
export const Pages = getCustomRepository(PageRepository);
|
export const Pages = getCustomRepository(PageRepository);
|
||||||
export const PageLikes = getCustomRepository(PageLikeRepository);
|
export const PageLikes = getCustomRepository(PageLikeRepository);
|
||||||
|
export const ModerationLogs = getCustomRepository(ModerationLogRepository);
|
||||||
|
31
src/models/repositories/moderation-logs.ts
Normal file
31
src/models/repositories/moderation-logs.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { EntityRepository, Repository } from 'typeorm';
|
||||||
|
import { Users } from '..';
|
||||||
|
import { ModerationLog } from '../entities/moderation-log';
|
||||||
|
import { ensure } from '../../prelude/ensure';
|
||||||
|
import { awaitAll } from '../../prelude/await-all';
|
||||||
|
|
||||||
|
@EntityRepository(ModerationLog)
|
||||||
|
export class ModerationLogRepository extends Repository<ModerationLog> {
|
||||||
|
public async pack(
|
||||||
|
src: ModerationLog['id'] | ModerationLog,
|
||||||
|
) {
|
||||||
|
const log = typeof src === 'object' ? src : await this.findOne(src).then(ensure);
|
||||||
|
|
||||||
|
return await awaitAll({
|
||||||
|
id: log.id,
|
||||||
|
createdAt: log.createdAt,
|
||||||
|
type: log.type,
|
||||||
|
info: log.info,
|
||||||
|
userId: log.userId,
|
||||||
|
user: Users.pack(log.user || log.userId, null, {
|
||||||
|
detail: true
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public packMany(
|
||||||
|
reports: any[],
|
||||||
|
) {
|
||||||
|
return Promise.all(reports.map(x => this.pack(x)));
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ import { detectUrlMine } from '../../../../../misc/detect-url-mine';
|
|||||||
import { Emojis } from '../../../../../models';
|
import { Emojis } from '../../../../../models';
|
||||||
import { genId } from '../../../../../misc/gen-id';
|
import { genId } from '../../../../../misc/gen-id';
|
||||||
import { getConnection } from 'typeorm';
|
import { getConnection } from 'typeorm';
|
||||||
|
import { insertModerationLog } from '../../../../../services/insert-moderation-log';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
desc: {
|
desc: {
|
||||||
@ -31,7 +32,7 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps) => {
|
export default define(meta, async (ps, me) => {
|
||||||
const type = await detectUrlMine(ps.url);
|
const type = await detectUrlMine(ps.url);
|
||||||
|
|
||||||
const emoji = await Emojis.save({
|
const emoji = await Emojis.save({
|
||||||
@ -46,6 +47,10 @@ export default define(meta, async (ps) => {
|
|||||||
|
|
||||||
await getConnection().queryResultCache!.remove(['meta_emojis']);
|
await getConnection().queryResultCache!.remove(['meta_emojis']);
|
||||||
|
|
||||||
|
insertModerationLog(me, 'addEmoji', {
|
||||||
|
emojiId: emoji.id
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: emoji.id
|
id: emoji.id
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,7 @@ import define from '../../../define';
|
|||||||
import { ID } from '../../../../../misc/cafy-id';
|
import { ID } from '../../../../../misc/cafy-id';
|
||||||
import { Emojis } from '../../../../../models';
|
import { Emojis } from '../../../../../models';
|
||||||
import { getConnection } from 'typeorm';
|
import { getConnection } from 'typeorm';
|
||||||
|
import { insertModerationLog } from '../../../../../services/insert-moderation-log';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
desc: {
|
desc: {
|
||||||
@ -21,7 +22,7 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps) => {
|
export default define(meta, async (ps, me) => {
|
||||||
const emoji = await Emojis.findOne(ps.id);
|
const emoji = await Emojis.findOne(ps.id);
|
||||||
|
|
||||||
if (emoji == null) throw new Error('emoji not found');
|
if (emoji == null) throw new Error('emoji not found');
|
||||||
@ -29,4 +30,8 @@ export default define(meta, async (ps) => {
|
|||||||
await Emojis.delete(emoji.id);
|
await Emojis.delete(emoji.id);
|
||||||
|
|
||||||
await getConnection().queryResultCache!.remove(['meta_emojis']);
|
await getConnection().queryResultCache!.remove(['meta_emojis']);
|
||||||
|
|
||||||
|
insertModerationLog(me, 'removeEmoji', {
|
||||||
|
emoji: emoji
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import define from '../../../define';
|
import define from '../../../define';
|
||||||
import { destroy } from '../../../../../queue';
|
import { destroy } from '../../../../../queue';
|
||||||
|
import { insertModerationLog } from '../../../../../services/insert-moderation-log';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
@ -10,8 +11,8 @@ export const meta = {
|
|||||||
params: {}
|
params: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps) => {
|
export default define(meta, async (ps, me) => {
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
return;
|
insertModerationLog(me, 'clearQueue');
|
||||||
});
|
});
|
||||||
|
35
src/server/api/endpoints/admin/show-moderation-logs.ts
Normal file
35
src/server/api/endpoints/admin/show-moderation-logs.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import $ from 'cafy';
|
||||||
|
import { ID } from '../../../../misc/cafy-id';
|
||||||
|
import define from '../../define';
|
||||||
|
import { ModerationLogs } from '../../../../models';
|
||||||
|
import { makePaginationQuery } from '../../common/make-pagination-query';
|
||||||
|
|
||||||
|
export const meta = {
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
|
requireCredential: true,
|
||||||
|
requireModerator: true,
|
||||||
|
|
||||||
|
params: {
|
||||||
|
limit: {
|
||||||
|
validator: $.optional.num.range(1, 100),
|
||||||
|
default: 10
|
||||||
|
},
|
||||||
|
|
||||||
|
sinceId: {
|
||||||
|
validator: $.optional.type(ID),
|
||||||
|
},
|
||||||
|
|
||||||
|
untilId: {
|
||||||
|
validator: $.optional.type(ID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default define(meta, async (ps) => {
|
||||||
|
const query = makePaginationQuery(ModerationLogs.createQueryBuilder('report'), ps.sinceId, ps.untilId);
|
||||||
|
|
||||||
|
const reports = await query.take(ps.limit!).getMany();
|
||||||
|
|
||||||
|
return await ModerationLogs.packMany(reports);
|
||||||
|
});
|
@ -2,6 +2,7 @@ import $ from 'cafy';
|
|||||||
import { ID } from '../../../../misc/cafy-id';
|
import { ID } from '../../../../misc/cafy-id';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { Users } from '../../../../models';
|
import { Users } from '../../../../models';
|
||||||
|
import { insertModerationLog } from '../../../../services/insert-moderation-log';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
desc: {
|
desc: {
|
||||||
@ -25,7 +26,7 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps) => {
|
export default define(meta, async (ps, me) => {
|
||||||
const user = await Users.findOne(ps.userId as string);
|
const user = await Users.findOne(ps.userId as string);
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
@ -39,4 +40,8 @@ export default define(meta, async (ps) => {
|
|||||||
await Users.update(user.id, {
|
await Users.update(user.id, {
|
||||||
isSilenced: true
|
isSilenced: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
insertModerationLog(me, 'silence', {
|
||||||
|
targetId: user.id,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -4,6 +4,7 @@ import define from '../../define';
|
|||||||
import deleteFollowing from '../../../../services/following/delete';
|
import deleteFollowing from '../../../../services/following/delete';
|
||||||
import { Users, Followings } from '../../../../models';
|
import { Users, Followings } from '../../../../models';
|
||||||
import { User } from '../../../../models/entities/user';
|
import { User } from '../../../../models/entities/user';
|
||||||
|
import { insertModerationLog } from '../../../../services/insert-moderation-log';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
desc: {
|
desc: {
|
||||||
@ -27,7 +28,7 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps) => {
|
export default define(meta, async (ps, me) => {
|
||||||
const user = await Users.findOne(ps.userId as string);
|
const user = await Users.findOne(ps.userId as string);
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
@ -46,6 +47,10 @@ export default define(meta, async (ps) => {
|
|||||||
isSuspended: true
|
isSuspended: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
insertModerationLog(me, 'suspend', {
|
||||||
|
targetId: user.id,
|
||||||
|
});
|
||||||
|
|
||||||
unFollowAll(user);
|
unFollowAll(user);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import $ from 'cafy';
|
|||||||
import { ID } from '../../../../misc/cafy-id';
|
import { ID } from '../../../../misc/cafy-id';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { Users } from '../../../../models';
|
import { Users } from '../../../../models';
|
||||||
|
import { insertModerationLog } from '../../../../services/insert-moderation-log';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
desc: {
|
desc: {
|
||||||
@ -25,7 +26,7 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps) => {
|
export default define(meta, async (ps, me) => {
|
||||||
const user = await Users.findOne(ps.userId as string);
|
const user = await Users.findOne(ps.userId as string);
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
@ -35,4 +36,8 @@ export default define(meta, async (ps) => {
|
|||||||
await Users.update(user.id, {
|
await Users.update(user.id, {
|
||||||
isSilenced: false
|
isSilenced: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
insertModerationLog(me, 'unsilence', {
|
||||||
|
targetId: user.id,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -2,6 +2,7 @@ import $ from 'cafy';
|
|||||||
import { ID } from '../../../../misc/cafy-id';
|
import { ID } from '../../../../misc/cafy-id';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { Users } from '../../../../models';
|
import { Users } from '../../../../models';
|
||||||
|
import { insertModerationLog } from '../../../../services/insert-moderation-log';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
desc: {
|
desc: {
|
||||||
@ -25,7 +26,7 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps) => {
|
export default define(meta, async (ps, me) => {
|
||||||
const user = await Users.findOne(ps.userId as string);
|
const user = await Users.findOne(ps.userId as string);
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
@ -35,4 +36,8 @@ export default define(meta, async (ps) => {
|
|||||||
await Users.update(user.id, {
|
await Users.update(user.id, {
|
||||||
isSuspended: false
|
isSuspended: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
insertModerationLog(me, 'unsuspend', {
|
||||||
|
targetId: user.id,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -2,6 +2,7 @@ import $ from 'cafy';
|
|||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { getConnection } from 'typeorm';
|
import { getConnection } from 'typeorm';
|
||||||
import { Meta } from '../../../../models/entities/meta';
|
import { Meta } from '../../../../models/entities/meta';
|
||||||
|
import { insertModerationLog } from '../../../../services/insert-moderation-log';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
desc: {
|
desc: {
|
||||||
@ -401,7 +402,7 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps) => {
|
export default define(meta, async (ps, me) => {
|
||||||
const set = {} as Partial<Meta>;
|
const set = {} as Partial<Meta>;
|
||||||
|
|
||||||
if (ps.announcements) {
|
if (ps.announcements) {
|
||||||
@ -653,4 +654,6 @@ export default define(meta, async (ps) => {
|
|||||||
await transactionalEntityManager.save(Meta, set);
|
await transactionalEntityManager.save(Meta, set);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
insertModerationLog(me, 'updateMeta');
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { getConnection } from 'typeorm';
|
import { getConnection } from 'typeorm';
|
||||||
|
import { insertModerationLog } from '../../../../services/insert-moderation-log';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
@ -18,7 +19,7 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps) => {
|
export default define(meta, async (ps, me) => {
|
||||||
const params: string[] = [];
|
const params: string[] = [];
|
||||||
|
|
||||||
if (ps.full) {
|
if (ps.full) {
|
||||||
@ -30,4 +31,6 @@ export default define(meta, async (ps) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getConnection().query('VACUUM ' + params.join(' '));
|
getConnection().query('VACUUM ' + params.join(' '));
|
||||||
|
|
||||||
|
insertModerationLog(me, 'vacuum', ps);
|
||||||
});
|
});
|
||||||
|
13
src/services/insert-moderation-log.ts
Normal file
13
src/services/insert-moderation-log.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { ILocalUser } from '../models/entities/user';
|
||||||
|
import { ModerationLogs } from '../models';
|
||||||
|
import { genId } from '../misc/gen-id';
|
||||||
|
|
||||||
|
export async function insertModerationLog(moderator: ILocalUser, type: string, info?: Record<string, any>) {
|
||||||
|
await ModerationLogs.save({
|
||||||
|
id: genId(),
|
||||||
|
createdAt: new Date(),
|
||||||
|
userId: moderator.id,
|
||||||
|
type: type,
|
||||||
|
info: info || {}
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user