-
Notifications
You must be signed in to change notification settings - Fork 8
Feature/audit log #670
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/audit log #670
Changes from 34 commits
735b460
211f5ba
b50694c
1dcd90e
728020c
6381d51
3c18feb
89768bb
63018bf
4a873cc
f126fe4
71cba12
9afb8fe
31b982a
3e00106
bb3e96e
efcc858
5f8db6f
db6b964
c22a4d4
200834c
9b176f5
1de2e77
7bbb2b7
c27aa75
6553de1
33bb119
b39ac30
7027f55
4e0b065
52d7d4a
c68dbcd
e4caa35
f6320a9
1e25054
7491e66
e31be7a
bfe94a2
cc45917
b0e886e
5321412
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,13 @@ | ||
| fileignoreconfig: | ||
| - filename: .github/workflows/secrets-scan.yml | ||
| ignore_detectors: | ||
| - filecontent | ||
| - filename: remove-broken-imports.js | ||
| checksum: d9d3ca95b2f4df855c8811c73b5714e80b31e5e84b46affa0cb514dcfcc145bf | ||
| ignoreconfig: | ||
| - filename: .github/workflows/secrets-scan.yml | ||
| ignore_detectors: | ||
| - filecontent | ||
|
|
||
| - filename: remove-broken-imports.js | ||
| checksum: d9d3ca95b2f4df855c8811c73b5714e80b31e5e84b46affa0cb514dcfcc145bf | ||
|
|
||
| - filename: ui/package-lock.json | ||
| ignore_detectors: | ||
| - Base64Detector | ||
|
|
||
| version: "1.0" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ import https from "../utils/https.utils.js"; | |
| import { LoginServiceType } from "../models/types.js"; | ||
| import getAuthtoken from "../utils/auth.utils.js"; | ||
| import logger from "../utils/logger.js"; | ||
| import { GET_AUDT_DATA } from "../constants/index.js"; | ||
| import { | ||
| HTTP_TEXTS, | ||
| HTTP_CODES, | ||
|
|
@@ -118,12 +119,10 @@ const createTestStack = async (req: Request): Promise<LoginServiceType> => { | |
| } | ||
| return { | ||
| data: { | ||
| data: res.data, | ||
| url: `${ | ||
| config.CS_URL[token_payload?.region as keyof typeof config.CS_URL] | ||
| }/stack/${res.data.stack.api_key}/dashboard`, | ||
| data: res?.data, | ||
| url: `${config?.CS_URL[token_payload?.region as keyof typeof config.CS_URL]}/stack/${res?.data?.stack?.api_key}/dashboard`, | ||
| }, | ||
| status: res.status, | ||
| status: res?.status, | ||
| }; | ||
| } catch (error: any) { | ||
| logger.error( | ||
|
|
@@ -142,6 +141,150 @@ const createTestStack = async (req: Request): Promise<LoginServiceType> => { | |
| } | ||
| }; | ||
|
|
||
| const getAuditData = async (req: Request): Promise<any> => { | ||
| const projectId = path?.basename(req?.params?.projectId); | ||
| const stackId = path?.basename(req?.params?.stackId); | ||
| const moduleName = path.basename(req?.params?.moduleName); | ||
| const limit = parseInt(req?.params?.limit); | ||
| const startIndex = parseInt(req?.params?.startIndex); | ||
| const stopIndex = startIndex + limit; | ||
| const searchText = req?.params?.searchText; | ||
| const filter = req?.params?.filter; | ||
| const srcFunc = "getAuditData"; | ||
|
|
||
| if (projectId.includes('..') || stackId.includes('..') || moduleName.includes('..')) { | ||
|
||
| throw new BadRequestError("Invalid projectId, stackId, or moduleName"); | ||
| } | ||
|
|
||
| try { | ||
| const mainPath = process?.cwd()?.split?.(GET_AUDT_DATA?.MIGRATION)?.[0]; | ||
| const logsDir = path.join(mainPath, GET_AUDT_DATA?.MIGRATION, GET_AUDT_DATA?.API_DIR, GET_AUDT_DATA?.MIGRATION_DATA_DIR); | ||
|
|
||
| const stackFolders = fs.readdirSync(logsDir); | ||
|
|
||
| const stackFolder = stackFolders.find(folder => folder.startsWith(stackId)); | ||
|
||
| if (!stackFolder) { | ||
| throw new BadRequestError("Migration data not found for this stack"); | ||
| } | ||
|
|
||
| const auditLogPath = path.resolve(logsDir, stackFolder, GET_AUDT_DATA?.LOGS_DIR, GET_AUDT_DATA?.AUDIT_DIR, GET_AUDT_DATA?.AUDIT_REPORT); | ||
|
||
| if (!fs.existsSync(auditLogPath)) { | ||
| throw new BadRequestError("Audit log path not found"); | ||
| } | ||
|
|
||
|
|
||
| // Read and parse the JSON file for the module | ||
| const filePath = path?.resolve(auditLogPath, `${moduleName}.json`); | ||
| let fileData; | ||
| if (fs.existsSync(filePath)) { | ||
|
||
| const fileContent = await fsPromises.readFile(filePath, 'utf8'); | ||
| try { | ||
| if (typeof fileContent === 'string') { | ||
| fileData = JSON.parse(fileContent); | ||
| } | ||
| } catch (error) { | ||
| logger.error(`Error parsing JSON from file ${filePath}:`, error); | ||
| throw new BadRequestError('Invalid JSON format in audit file'); | ||
| } | ||
| } | ||
|
|
||
| if (!fileData) { | ||
| throw new BadRequestError(`No audit data found for module: ${moduleName}`); | ||
| } | ||
| let transformedData = transformAndFlattenData(fileData); | ||
| if (filter != GET_AUDT_DATA.FILTERALL) { | ||
| const filters = filter.split("-"); | ||
|
||
| moduleName === 'Entries_Select_feild' ? transformedData = transformedData.filter((log) => { | ||
| return filters.some((filter) => { | ||
| return ( | ||
| log?.display_type?.toLowerCase()?.includes(filter?.toLowerCase()) | ||
| ); | ||
| }); | ||
| }) : transformedData = transformedData.filter((log) => { | ||
| return filters.some((filter) => { | ||
| return ( | ||
| log?.data_type?.toLowerCase()?.includes(filter?.toLowerCase()) | ||
| ); | ||
| }); | ||
| }); | ||
|
|
||
| } | ||
| if (searchText && searchText !== null && searchText !== "null") { | ||
| transformedData = transformedData?.filter((item: any) => { | ||
| return Object.values(item).some(value => | ||
| value && | ||
| typeof value === 'string' && | ||
| value?.toLowerCase?.()?.includes(searchText.toLowerCase()) | ||
| ); | ||
| }); | ||
| } | ||
| const paginatedData = transformedData?.slice?.(startIndex, stopIndex); | ||
|
|
||
| return { | ||
| data: paginatedData, | ||
| totalCount: transformedData?.length | ||
| }; | ||
|
|
||
| } catch (error: any) { | ||
| logger.error( | ||
| getLogMessage( | ||
| srcFunc, | ||
| `Error getting audit log data for module: ${moduleName}`, | ||
| error | ||
| ) | ||
| ); | ||
| throw new ExceptionFunction( | ||
| error?.message || HTTP_TEXTS.INTERNAL_ERROR, | ||
| error?.statusCode || error?.status || HTTP_CODES.SERVER_ERROR | ||
| ); | ||
| } | ||
| }; | ||
| /** | ||
| * Transforms and flattens nested data structure into an array of items | ||
| * with sequential tuid values | ||
| */ | ||
| const transformAndFlattenData = (data: any): Array<{ [key: string]: any, id: number }> => { | ||
| try { | ||
| const flattenedItems: Array<{ [key: string]: any }> = []; | ||
|
|
||
| // Handle the data based on its structure | ||
| if (Array.isArray(data)) { | ||
| // If data is already an array, use it directly | ||
| data.forEach((item, index) => { | ||
| flattenedItems.push({ | ||
|
||
| ...item ?? {}, | ||
| uid: item?.uid || `item-${index}` | ||
| }); | ||
| }); | ||
| } else if (typeof data === 'object' && data !== null) { | ||
| Object.entries(data).forEach(([key, value]) => { | ||
|
||
| if (Array.isArray(value)) { | ||
| value.forEach((item, index) => { | ||
| flattenedItems?.push({ | ||
| ...item ?? {}, | ||
| parentKey: key, | ||
| uid: item.uid || `${key}-${index}` | ||
| }); | ||
| }); | ||
| } else if (typeof value === 'object' && value !== null) { | ||
| flattenedItems?.push({ | ||
| ...value, | ||
| key, | ||
| uid: (value as any)?.uid || key | ||
| }); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| return flattenedItems.map((item, index) => ({ | ||
|
||
| ...item ?? {}, | ||
| id: index + 1 | ||
| })); | ||
| } catch (error) { | ||
| console.error('Error transforming data:', error); | ||
| return []; | ||
| } | ||
| }; | ||
| /** | ||
| * Deletes a test stack. | ||
| * @param req - The request object. | ||
|
|
@@ -971,4 +1114,5 @@ export const migrationService = { | |
| getLogs, | ||
| createSourceLocales, | ||
| updateLocaleMapper, | ||
| getAuditData | ||
| }; | ||
Uh oh!
There was an error while loading. Please reload this page.