X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fhelpers%2Faudit-logger.ts;h=7e8a03e8fc4b974d35feec3c4adf17c0649dd537;hb=3a380e9a71037b0fcbace58a7599221e7cc76e20;hp=4b237316fa017c3a8ec5879c6bcb459386094875;hpb=59390818384baa0ffc0cb71af2e67350c6b39172;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/helpers/audit-logger.ts b/server/helpers/audit-logger.ts index 4b237316f..7e8a03e8f 100644 --- a/server/helpers/audit-logger.ts +++ b/server/helpers/audit-logger.ts @@ -1,11 +1,17 @@ -import * as path from 'path' import { diff } from 'deep-object-diff' +import express from 'express' +import flatten from 'flat' import { chain } from 'lodash' -import * as flatten from 'flat' -import * as winston from 'winston' -import { CONFIG } from '../initializers' +import { join } from 'path' +import { addColors, config, createLogger, format, transports } from 'winston' +import { AUDIT_LOG_FILENAME } from '@server/initializers/constants' +import { AdminAbuse, CustomConfig, User, VideoChannel, VideoChannelSync, VideoComment, VideoDetails, VideoImport } from '@shared/models' +import { CONFIG } from '../initializers/config' import { jsonLoggerFormat, labelFormatter } from './logger' -import { VideoDetails } from '../../shared' + +function getAuditIdFromRes (res: express.Response) { + return res.locals.oauth.token.User.username +} enum AUDIT_TYPE { CREATE = 'create', @@ -13,23 +19,23 @@ enum AUDIT_TYPE { DELETE = 'delete' } -const colors = winston.config.npm.colors -colors.audit = winston.config.npm.colors.info +const colors = config.npm.colors +colors.audit = config.npm.colors.info -winston.addColors(colors) +addColors(colors) -const auditLogger = winston.createLogger({ +const auditLogger = createLogger({ levels: { audit: 0 }, transports: [ - new winston.transports.File({ - filename: path.join(CONFIG.STORAGE.LOG_DIR, 'peertube-audit.log'), + new transports.File({ + filename: join(CONFIG.STORAGE.LOG_DIR, AUDIT_LOG_FILENAME), level: 'audit', maxsize: 5242880, maxFiles: 5, - format: winston.format.combine( - winston.format.timestamp(), - labelFormatter, - winston.format.splat(), + format: format.combine( + format.timestamp(), + labelFormatter(), + format.splat(), jsonLoggerFormat ) }) @@ -73,11 +79,12 @@ function auditLoggerFactory (domain: string) { } abstract class EntityAuditView { - constructor (private keysToKeep: Array, private prefix: string, private entityInfos: object) { } + constructor (private readonly keysToKeep: string[], private readonly prefix: string, private readonly entityInfos: object) { } + toLogKeys (): object { - return chain(flatten(this.entityInfos, { delimiter: '-', safe: true })) + return chain(flatten(this.entityInfos, { delimiter: '-', safe: true })) .pick(this.keysToKeep) - .mapKeys((value, key) => `${this.prefix}-${key}`) + .mapKeys((_value, key) => `${this.prefix}-${key}`) .value() } } @@ -109,15 +116,172 @@ const videoKeysToKeep = [ 'channel-uuid', 'channel-name', 'support', - 'commentsEnabled' + 'commentsEnabled', + 'downloadEnabled' ] -class VideoAuditView extends AuditEntity { - constructor (private video: VideoDetails) { +class VideoAuditView extends EntityAuditView { + constructor (video: VideoDetails) { super(videoKeysToKeep, 'video', video) } } +const videoImportKeysToKeep = [ + 'id', + 'targetUrl', + 'video-name' +] +class VideoImportAuditView extends EntityAuditView { + constructor (videoImport: VideoImport) { + super(videoImportKeysToKeep, 'video-import', videoImport) + } +} + +const commentKeysToKeep = [ + 'id', + 'text', + 'threadId', + 'inReplyToCommentId', + 'videoId', + 'createdAt', + 'updatedAt', + 'totalReplies', + 'account-id', + 'account-uuid', + 'account-name' +] +class CommentAuditView extends EntityAuditView { + constructor (comment: VideoComment) { + super(commentKeysToKeep, 'comment', comment) + } +} + +const userKeysToKeep = [ + 'id', + 'username', + 'email', + 'nsfwPolicy', + 'autoPlayVideo', + 'role', + 'videoQuota', + 'createdAt', + 'account-id', + 'account-uuid', + 'account-name', + 'account-followingCount', + 'account-followersCount', + 'account-createdAt', + 'account-updatedAt', + 'account-avatar-path', + 'account-avatar-createdAt', + 'account-avatar-updatedAt', + 'account-displayName', + 'account-description', + 'videoChannels' +] +class UserAuditView extends EntityAuditView { + constructor (user: User) { + super(userKeysToKeep, 'user', user) + } +} + +const channelKeysToKeep = [ + 'id', + 'uuid', + 'name', + 'followingCount', + 'followersCount', + 'createdAt', + 'updatedAt', + 'avatar-path', + 'avatar-createdAt', + 'avatar-updatedAt', + 'displayName', + 'description', + 'support', + 'isLocal', + 'ownerAccount-id', + 'ownerAccount-uuid', + 'ownerAccount-name', + 'ownerAccount-displayedName' +] +class VideoChannelAuditView extends EntityAuditView { + constructor (channel: VideoChannel) { + super(channelKeysToKeep, 'channel', channel) + } +} + +const abuseKeysToKeep = [ + 'id', + 'reason', + 'reporterAccount', + 'createdAt' +] +class AbuseAuditView extends EntityAuditView { + constructor (abuse: AdminAbuse) { + super(abuseKeysToKeep, 'abuse', abuse) + } +} + +const customConfigKeysToKeep = [ + 'instance-name', + 'instance-shortDescription', + 'instance-description', + 'instance-terms', + 'instance-defaultClientRoute', + 'instance-defaultNSFWPolicy', + 'instance-customizations-javascript', + 'instance-customizations-css', + 'services-twitter-username', + 'services-twitter-whitelisted', + 'cache-previews-size', + 'cache-captions-size', + 'signup-enabled', + 'signup-limit', + 'signup-requiresEmailVerification', + 'admin-email', + 'user-videoQuota', + 'transcoding-enabled', + 'transcoding-threads', + 'transcoding-resolutions' +] +class CustomConfigAuditView extends EntityAuditView { + constructor (customConfig: CustomConfig) { + const infos: any = customConfig + const resolutionsDict = infos.transcoding.resolutions + const resolutionsArray = [] + + Object.entries(resolutionsDict) + .forEach(([ resolution, isEnabled ]) => { + if (isEnabled) resolutionsArray.push(resolution) + }) + + Object.assign({}, infos, { transcoding: { resolutions: resolutionsArray } }) + super(customConfigKeysToKeep, 'config', infos) + } +} + +const channelSyncKeysToKeep = [ + 'id', + 'externalChannelUrl', + 'channel-id', + 'channel-name' +] +class VideoChannelSyncAuditView extends EntityAuditView { + constructor (channelSync: VideoChannelSync) { + super(channelSyncKeysToKeep, 'channelSync', channelSync) + } +} + export { + getAuditIdFromRes, + auditLoggerFactory, - VideoAuditView + VideoImportAuditView, + VideoChannelAuditView, + CommentAuditView, + UserAuditView, + VideoAuditView, + AbuseAuditView, + CustomConfigAuditView, + VideoChannelSyncAuditView }