1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-05 13:55:21 +02:00

fix(activity logs): decode base64 [BE-11418] (#172)

This commit is contained in:
Ali 2024-11-28 08:54:32 +13:00 committed by GitHub
parent f2e7680bf3
commit 4f708309af
4 changed files with 118 additions and 40 deletions

View file

@ -1,8 +1,19 @@
export interface ActivityLog {
interface BaseActivityLog {
timestamp: number;
action: string;
context: string;
id: number;
payload: object;
username: string;
}
export interface ActivityLogResponse extends BaseActivityLog {
payload: string;
}
export interface ActivityLog extends BaseActivityLog {
payload: string | object;
}
export interface ActivityLogsResponse {
logs: Array<ActivityLogResponse>;
totalCount: number;
}

View file

@ -4,7 +4,7 @@ import axios, { parseAxiosError } from '@/portainer/services/axios';
import { isBE } from '../../feature-flags/feature-flags.service';
import { ActivityLog } from './types';
import { ActivityLogResponse, ActivityLogsResponse } from './types';
export const sortKeys = ['Context', 'Action', 'Timestamp', 'Username'] as const;
export type SortKey = (typeof sortKeys)[number];
@ -30,19 +30,18 @@ export function useActivityLogs(query: Query) {
queryKey: ['activityLogs', query] as const,
queryFn: () => fetchActivityLogs(query),
keepPreviousData: true,
select: (data) => ({
...data,
logs: decorateLogs(data.logs),
}),
});
}
interface ActivityLogsResponse {
logs: Array<ActivityLog>;
totalCount: number;
}
async function fetchActivityLogs(query: Query): Promise<ActivityLogsResponse> {
try {
if (!isBE) {
return {
logs: [{}, {}, {}, {}, {}] as Array<ActivityLog>,
logs: [{}, {}, {}, {}, {}] as Array<ActivityLogResponse>,
totalCount: 5,
};
}
@ -56,3 +55,40 @@ async function fetchActivityLogs(query: Query): Promise<ActivityLogsResponse> {
throw parseAxiosError(err, 'Failed loading user activity logs csv');
}
}
/**
* Decorates logs with the payload parsed from base64
*/
function decorateLogs(logs?: ActivityLogResponse[]) {
if (!logs || logs.length === 0) {
return [];
}
return logs.map((log) => ({
...log,
payload: parseBase64AsObject(log.payload),
}));
}
function parseBase64AsObject(value: string): string | object {
if (!value) {
return value;
}
try {
return JSON.parse(safeAtob(value));
} catch (err) {
return safeAtob(value);
}
}
function safeAtob(value: string) {
if (!value) {
return value;
}
try {
return window.atob(value);
} catch (err) {
// If the payload is not base64 encoded, return the original value
return value;
}
}