From b40cabda747641f13fcf183557ce023d12eec2b1 Mon Sep 17 00:00:00 2001 From: Kamil Kisiela Date: Thu, 16 Jan 2025 12:53:36 +0100 Subject: [PATCH] Fix the audit log export (#6369) --- .changeset/dirty-stingrays-press.md | 5 ++++ .../providers/audit-logs-manager.ts | 21 +++++----------- .../audit-logs/providers/audit-logs-types.ts | 2 +- .../Mutation/exportOrganizationAuditLog.ts | 9 ++++--- .../app/src/pages/organization-settings.tsx | 24 +++++++------------ 5 files changed, 26 insertions(+), 35 deletions(-) create mode 100644 .changeset/dirty-stingrays-press.md diff --git a/.changeset/dirty-stingrays-press.md b/.changeset/dirty-stingrays-press.md new file mode 100644 index 000000000..888281679 --- /dev/null +++ b/.changeset/dirty-stingrays-press.md @@ -0,0 +1,5 @@ +--- +'hive': patch +--- + +Fix the audit log export diff --git a/packages/services/api/src/modules/audit-logs/providers/audit-logs-manager.ts b/packages/services/api/src/modules/audit-logs/providers/audit-logs-manager.ts index e02c41902..55312da4c 100644 --- a/packages/services/api/src/modules/audit-logs/providers/audit-logs-manager.ts +++ b/packages/services/api/src/modules/audit-logs/providers/audit-logs-manager.ts @@ -7,11 +7,10 @@ import { Session } from '../../auth/lib/authz'; import { type AwsClient } from '../../cdn/providers/aws'; import { ClickHouse, sql } from '../../operations/providers/clickhouse-client'; import { Emails, mjml } from '../../shared/providers/emails'; -import { IdTranslator } from '../../shared/providers/id-translator'; import { Logger } from '../../shared/providers/logger'; import { Storage } from '../../shared/providers/storage'; import { formatToClickhouseDateTime } from './audit-log-recorder'; -import { AuditLogClickhouseArrayModel, AuditLogType } from './audit-logs-types'; +import { AuditLogClickhouseArrayModel } from './audit-logs-types'; export class AuditLogS3Config { constructor( @@ -37,7 +36,6 @@ export class AuditLogManager { private emailProvider: Emails, private session: Session, private storage: Storage, - private idTranslator: IdTranslator, ) { this.logger = logger.child({ source: 'AuditLogManager' }); } @@ -45,7 +43,7 @@ export class AuditLogManager { async getAuditLogsByDateRange( organizationId: string, filter: { startDate: Date; endDate: Date }, - ): Promise<{ data: AuditLogType[] }> { + ) { await this.session.assertPerformAction({ action: 'auditLog:export', organizationId, @@ -82,11 +80,7 @@ export class AuditLogManager { timeout: 10000, }); - const data = AuditLogClickhouseArrayModel.parse(result.data); - - return { - data, - }; + return AuditLogClickhouseArrayModel.parse(result.data); } @traceFn('AuditLogsManager.exportAndSendEmail', { @@ -103,7 +97,7 @@ export class AuditLogManager { }), }) async exportAndSendEmail( - organizationSlug: string, + organizationId: string, filter: { startDate: Date; endDate: Date }, ): Promise< | { @@ -119,9 +113,6 @@ export class AuditLogManager { }; } > { - const organizationId = await this.idTranslator.translateOrganizationId({ - organizationSlug, - }); await this.session.assertPerformAction({ action: 'auditLog:export', organizationId, @@ -132,7 +123,7 @@ export class AuditLogManager { const getAllAuditLogs = await this.getAuditLogsByDateRange(organizationId, filter); - if (!getAllAuditLogs || !getAllAuditLogs.data || getAllAuditLogs.data.length === 0) { + if (!getAllAuditLogs || !getAllAuditLogs || getAllAuditLogs.length === 0) { return { error: { message: 'No audit logs found for the given date range', @@ -144,7 +135,7 @@ export class AuditLogManager { const { email } = await this.session.getViewer(); const csvData = await new Promise((resolve, reject) => { stringify( - getAllAuditLogs.data, + getAllAuditLogs, { header: true, columns: { diff --git a/packages/services/api/src/modules/audit-logs/providers/audit-logs-types.ts b/packages/services/api/src/modules/audit-logs/providers/audit-logs-types.ts index bd67d3014..968f3bd05 100644 --- a/packages/services/api/src/modules/audit-logs/providers/audit-logs-types.ts +++ b/packages/services/api/src/modules/audit-logs/providers/audit-logs-types.ts @@ -340,7 +340,7 @@ const AuditLogClickhouseObjectModel = z.object({ eventAction: z.enum(auditLogEventTypes as [string, ...string[]]), userId: z.string(), userEmail: z.string(), - metadata: z.string().transform(x => JSON.parse(x)), + metadata: z.string(), }); export type AuditLogType = z.infer; diff --git a/packages/services/api/src/modules/audit-logs/resolvers/Mutation/exportOrganizationAuditLog.ts b/packages/services/api/src/modules/audit-logs/resolvers/Mutation/exportOrganizationAuditLog.ts index eab035509..6769e218e 100644 --- a/packages/services/api/src/modules/audit-logs/resolvers/Mutation/exportOrganizationAuditLog.ts +++ b/packages/services/api/src/modules/audit-logs/resolvers/Mutation/exportOrganizationAuditLog.ts @@ -1,12 +1,15 @@ import { AuditLogManager } from '../../../audit-logs/providers/audit-logs-manager'; +import { IdTranslator } from '../../../shared/providers/id-translator'; import type { MutationResolvers } from './../../../../__generated__/types'; export const exportOrganizationAuditLog: NonNullable< MutationResolvers['exportOrganizationAuditLog'] -> = async (_parent, arg, ctx) => { - const auditLogManager = ctx.injector.get(AuditLogManager); +> = async (_parent, arg, { injector }) => { + const organizationId = await injector + .get(IdTranslator) + .translateOrganizationId(arg.input.selector); - const result = await auditLogManager.exportAndSendEmail(arg.input.selector.organizationSlug, { + const result = await injector.get(AuditLogManager).exportAndSendEmail(organizationId, { endDate: arg.input.filter.endDate, startDate: arg.input.filter.startDate, }); diff --git a/packages/web/app/src/pages/organization-settings.tsx b/packages/web/app/src/pages/organization-settings.tsx index f5c872cf0..02df73179 100644 --- a/packages/web/app/src/pages/organization-settings.tsx +++ b/packages/web/app/src/pages/organization-settings.tsx @@ -1,4 +1,5 @@ import { useCallback } from 'react'; +import { ArrowRightIcon } from 'lucide-react'; import { useForm } from 'react-hook-form'; import { useMutation, useQuery } from 'urql'; import { z } from 'zod'; @@ -22,14 +23,7 @@ import { DialogTitle, } from '@/components/ui/dialog'; import { DocsLink } from '@/components/ui/docs-note'; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from '@/components/ui/form'; +import { Form, FormControl, FormField, FormItem, FormMessage } from '@/components/ui/form'; import { GitHubIcon, SlackIcon } from '@/components/ui/icon'; import { Input } from '@/components/ui/input'; import { Meta } from '@/components/ui/meta'; @@ -714,9 +708,8 @@ function AuditLogsOrganizationModal(props: { props.toggleModalOpen(); form.reset(); toast({ - variant: 'warning', - title: 'Audit logs report started', - description: 'Your audit logs report is being generated. You will receive an email shortly.', + title: 'Audit logs report generated', + description: 'The audit logs report has been generated and will be sent to your email.', }); } @@ -731,13 +724,12 @@ function AuditLogsOrganizationModal(props: { Select a date range to generate an audit logs report. -
+
( - Start Date @@ -745,14 +737,14 @@ function AuditLogsOrganizationModal(props: { )} /> -
-
+
+ +
( - End Date