Fix the audit log export (#6369)

This commit is contained in:
Kamil Kisiela 2025-01-16 12:53:36 +01:00 committed by GitHub
parent 92959e166d
commit b40cabda74
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 26 additions and 35 deletions

View file

@ -0,0 +1,5 @@
---
'hive': patch
---
Fix the audit log export

View file

@ -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<string>((resolve, reject) => {
stringify(
getAllAuditLogs.data,
getAllAuditLogs,
{
header: true,
columns: {

View file

@ -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<typeof AuditLogClickhouseObjectModel>;

View file

@ -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,
});

View file

@ -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.
</DialogDescription>
</DialogHeader>
<div className="space-y-8">
<div className="flex flex-row justify-evenly gap-x-8">
<FormField
control={form.control}
name="startDate"
render={({ field }) => (
<FormItem>
<FormLabel>Start Date</FormLabel>
<FormControl>
<Input type="date" {...field} />
</FormControl>
@ -745,14 +737,14 @@ function AuditLogsOrganizationModal(props: {
</FormItem>
)}
/>
</div>
<div className="space-y-8">
<div className="mt-2">
<ArrowRightIcon className="text-muted-foreground size-6" />
</div>
<FormField
control={form.control}
name="endDate"
render={({ field }) => (
<FormItem>
<FormLabel>End Date</FormLabel>
<FormControl>
<Input type="date" {...field} />
</FormControl>