Преглед изворни кода

change to use id instead of username

ryosei-f пре 3 недеља
родитељ
комит
123057e3ac

+ 2 - 2
apps/app/src/client/components/Admin/AuditLog/AuditLogExportModal.tsx

@@ -4,7 +4,7 @@ import { useAtomValue } from 'jotai';
 import { useTranslation } from 'react-i18next';
 import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
 
-import type { IAuditLogBulkExportFilters } from '~/features/audit-log-bulk-export/interfaces/audit-log-bulk-export';
+import type { IAuditLogBulkExportRequestFilters } from '~/features/audit-log-bulk-export/interfaces/audit-log-bulk-export';
 import type { SupportedActionType } from '~/interfaces/activity';
 import { auditLogAvailableActionsAtom } from '~/states/server-configurations';
 
@@ -78,7 +78,7 @@ const AuditLogExportModalSubstance = ({
       .filter((v) => v[1])
       .map((v) => v[0]);
 
-    const filters: IAuditLogBulkExportFilters = {};
+    const filters: IAuditLogBulkExportRequestFilters = {};
 
     if (selectedUsernames.length > 0) {
       filters.usernames = selectedUsernames;

+ 7 - 1
apps/app/src/features/audit-log-bulk-export/interfaces/audit-log-bulk-export.ts

@@ -23,12 +23,18 @@ export const AuditLogBulkExportJobStatus = {
 export type AuditLogBulkExportJobStatus =
   (typeof AuditLogBulkExportJobStatus)[keyof typeof AuditLogBulkExportJobStatus];
 
-export interface IAuditLogBulkExportFilters {
+export interface IAuditLogBulkExportRequestFilters {
   usernames?: string[];
   actions?: SupportedActionType[];
   dateFrom?: Date;
   dateTo?: Date;
 }
+export interface IAuditLogBulkExportFilters {
+  users?: Array<Ref<IUser>>;
+  actions?: SupportedActionType[];
+  dateFrom?: Date;
+  dateTo?: Date;
+}
 
 export interface IAuditLogBulkExportJob {
   user: Ref<IUser>; // user who initiated the audit log export job

+ 1 - 1
apps/app/src/features/audit-log-bulk-export/server/models/audit-log-bulk-export-job.ts

@@ -20,7 +20,7 @@ const auditLogBulkExportJobSchema = new Schema<IAuditLogBulkExportJob>(
     user: { type: Schema.Types.ObjectId, ref: 'User', required: true },
     filters: {
       type: {
-        usernames: [{ type: String }],
+        users: [{ type: Schema.Types.ObjectId, ref: 'User' }],
         actions: [{ type: String, enum: AllSupportedActions }],
         dateFrom: { type: Date },
         dateTo: { type: Date },

+ 1 - 1
apps/app/src/features/audit-log-bulk-export/server/service/audit-log-bulk-export-job-cron/audit-log-bulk-export-job-cron-service.integ.ts

@@ -582,7 +582,7 @@ describe('AuditLogBulkExportJobCronService Integration Test', () => {
         const job = await AuditLogBulkExportJob.create({
           user: testUser._id,
           filters: {
-            usernames: ['nonexistent-user-xyz-999'],
+            users: [new mongoose.Types.ObjectId()],
           },
           format: AuditLogBulkExportFormat.json,
           status: AuditLogBulkExportJobStatus.exporting,

+ 3 - 8
apps/app/src/features/audit-log-bulk-export/server/service/audit-log-bulk-export-job-cron/steps/exportAuditLogsToFsAsync.ts

@@ -1,8 +1,7 @@
 import fs from 'node:fs';
 import path from 'node:path';
 import { pipeline, Writable } from 'node:stream';
-import type { IUser } from '@growi/core';
-import mongoose, { type FilterQuery } from 'mongoose';
+import type { FilterQuery } from 'mongoose';
 
 import { AuditLogBulkExportJobStatus } from '~/features/audit-log-bulk-export/interfaces/audit-log-bulk-export';
 import { SupportedAction } from '~/interfaces/activity';
@@ -100,12 +99,8 @@ export async function exportAuditLogsToFsAsync(
       query.createdAt.$lte = new Date(filters.dateTo);
     }
   }
-  if (filters.usernames && filters.usernames.length > 0) {
-    const User = mongoose.model<IUser>('User');
-    const userIds = await User.find({
-      username: { $in: filters.usernames },
-    }).distinct('_id');
-    query.user = { $in: userIds };
+  if (filters.users && filters.users.length > 0) {
+    query.user = { $in: filters.users };
   }
 
   // If the previous export was incomplete, resume from the last exported ID by adding it to the query filter

+ 4 - 2
apps/app/src/features/audit-log-bulk-export/server/service/audit-log-bulk-export.integ.ts

@@ -74,7 +74,7 @@ describe('AuditLogBulkExportService', () => {
         expect(createdJob?.status).toBe(AuditLogBulkExportJobStatus.exporting);
         expect(createdJob?.totalExportedCount).toBe(0);
         expect(createdJob?.filters).toMatchObject({
-          actions: ['PAGE_CREATE', 'PAGE_VIEW'],
+          actions: ['PAGE_VIEW', 'PAGE_CREATE'],
           dateFrom: new Date('2023-01-01T00:00:00.000Z'),
           dateTo: new Date('2023-12-31T00:00:00.000Z'),
         });
@@ -114,7 +114,9 @@ describe('AuditLogBulkExportService', () => {
 
         const createdJob = await AuditLogBulkExportJob.findById(jobId);
         expect(createdJob?.filters.actions).toEqual(['PAGE_CREATE']);
-        expect(createdJob?.filters.usernames).toEqual([user.username]);
+        expect(createdJob?.filters.users?.map(String)).toContain(
+          user._id.toString(),
+        );
       });
 
       it('should reset existing job when restartJob is true', async () => {

+ 20 - 5
apps/app/src/features/audit-log-bulk-export/server/service/audit-log-bulk-export.ts

@@ -1,8 +1,10 @@
 import { createHash } from 'node:crypto';
+import mongoose from 'mongoose';
 
 import type {
   AuditLogBulkExportFormat,
   IAuditLogBulkExportFilters,
+  IAuditLogBulkExportRequestFilters,
 } from '../../interfaces/audit-log-bulk-export';
 import {
   AuditLogBulkExportJobInProgressJobStatus,
@@ -13,7 +15,7 @@ import AuditLogBulkExportJob from '../models/audit-log-bulk-export-job';
 
 export interface IAuditLogBulkExportService {
   createOrResetExportJob: (
-    filters: IAuditLogBulkExportFilters,
+    requestFilters: IAuditLogBulkExportRequestFilters,
     format: AuditLogBulkExportFormat,
     currentUser,
     restartJob?: boolean,
@@ -30,8 +32,8 @@ export interface IAuditLogBulkExportService {
 function canonicalizeFilters(filters: IAuditLogBulkExportFilters) {
   const normalized: Record<string, unknown> = {};
 
-  if (filters.usernames?.length) {
-    normalized.usernames = [...filters.usernames].sort();
+  if (filters.users?.length) {
+    normalized.users = filters.users.map(String).sort();
   }
   if (filters.actions?.length) {
     normalized.actions = [...filters.actions].sort();
@@ -72,11 +74,24 @@ class AuditLogBulkExportService implements IAuditLogBulkExportService {
    * Create a new audit-log bulk export job or reset the existing one
    */
   async createOrResetExportJob(
-    filters: IAuditLogBulkExportFilters,
+    requestFilters: IAuditLogBulkExportRequestFilters,
     format: AuditLogBulkExportFormat,
     currentUser,
     restartJob?: boolean,
   ): Promise<string> {
+    const filters: IAuditLogBulkExportFilters = {
+      actions: requestFilters.actions,
+      dateFrom: requestFilters.dateFrom,
+      dateTo: requestFilters.dateTo,
+    };
+    if (requestFilters.usernames?.length) {
+      const User = mongoose.model('User');
+      const userIds = await User.find({
+        username: { $in: requestFilters.usernames },
+      }).distinct('_id');
+      filters.users = userIds;
+    }
+
     const normalizedFilters = canonicalizeFilters(filters);
     const filterHash = sha256(JSON.stringify(normalizedFilters));
 
@@ -99,7 +114,7 @@ class AuditLogBulkExportService implements IAuditLogBulkExportService {
 
     const createdJob = await AuditLogBulkExportJob.create({
       user: currentUser,
-      filters: normalizedFilters,
+      filters,
       filterHash,
       format,
       status: AuditLogBulkExportJobStatus.exporting,