mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-04 04:26:11 +00:00
Mass-update endpoint
This commit is contained in:
@@ -187,6 +187,55 @@ export const registerSecretScanningV2Router = async (server: FastifyZodProvider)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
method: "PATCH",
|
||||||
|
url: "/findings",
|
||||||
|
config: {
|
||||||
|
rateLimit: writeLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.SecretScanning],
|
||||||
|
description: "Update one or more Secret Scanning Findings in a batch.",
|
||||||
|
body: z
|
||||||
|
.object({
|
||||||
|
findingId: z.string().trim().min(1, "Finding ID required").describe(SecretScanningFindings.UPDATE.findingId),
|
||||||
|
status: z.nativeEnum(SecretScanningFindingStatus).optional().describe(SecretScanningFindings.UPDATE.status),
|
||||||
|
remarks: z.string().nullish().describe(SecretScanningFindings.UPDATE.remarks)
|
||||||
|
})
|
||||||
|
.array(),
|
||||||
|
response: {
|
||||||
|
200: z.object({ findings: SecretScanningFindingSchema.array() })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const { body, permission } = req;
|
||||||
|
|
||||||
|
const updatedFindingPromises = body.map(async (findingUpdatePayload) => {
|
||||||
|
const { finding, projectId } = await server.services.secretScanningV2.updateSecretScanningFindingById(
|
||||||
|
findingUpdatePayload,
|
||||||
|
permission
|
||||||
|
);
|
||||||
|
|
||||||
|
await server.services.auditLog.createAuditLog({
|
||||||
|
...req.auditLogInfo,
|
||||||
|
projectId,
|
||||||
|
event: {
|
||||||
|
type: EventType.SECRET_SCANNING_FINDING_UPDATE,
|
||||||
|
metadata: findingUpdatePayload
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return finding;
|
||||||
|
});
|
||||||
|
|
||||||
|
const findings = await Promise.all(updatedFindingPromises);
|
||||||
|
|
||||||
|
return { findings };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
method: "GET",
|
method: "GET",
|
||||||
url: "/configs",
|
url: "/configs",
|
||||||
|
|||||||
@@ -140,6 +140,31 @@ export const useUpdateSecretScanningFinding = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useUpdateMultipleSecretScanningFinding = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: async (findings: TUpdateSecretScanningFinding[]) => {
|
||||||
|
const { data } = await apiRequest.patch<TSecretScanningFindingResponse>(
|
||||||
|
`/api/v2/secret-scanning/findings`,
|
||||||
|
findings
|
||||||
|
);
|
||||||
|
|
||||||
|
return data.finding;
|
||||||
|
},
|
||||||
|
onSuccess: (_, findings) => {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: secretScanningV2Keys.listFindings(findings[0].projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: secretScanningV2Keys.findingCount(findings[0].projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: secretScanningV2Keys.dataSource()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const useUpdateSecretScanningConfig = () => {
|
export const useUpdateSecretScanningConfig = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
return useMutation({
|
return useMutation({
|
||||||
|
|||||||
+19
-9
@@ -17,6 +17,7 @@ import { SECRET_SCANNING_FINDING_STATUS_ICON_MAP } from "@app/helpers/secretScan
|
|||||||
import {
|
import {
|
||||||
SecretScanningFindingStatus,
|
SecretScanningFindingStatus,
|
||||||
TSecretScanningFinding,
|
TSecretScanningFinding,
|
||||||
|
useUpdateMultipleSecretScanningFinding,
|
||||||
useUpdateSecretScanningFinding
|
useUpdateSecretScanningFinding
|
||||||
} from "@app/hooks/api/secretScanningV2";
|
} from "@app/hooks/api/secretScanningV2";
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@ type ContentProps = {
|
|||||||
|
|
||||||
const Content = ({ findings, onComplete }: ContentProps) => {
|
const Content = ({ findings, onComplete }: ContentProps) => {
|
||||||
const updateFinding = useUpdateSecretScanningFinding();
|
const updateFinding = useUpdateSecretScanningFinding();
|
||||||
|
const updateMultipleFindings = useUpdateMultipleSecretScanningFinding();
|
||||||
|
|
||||||
const single = findings.length === 1;
|
const single = findings.length === 1;
|
||||||
|
|
||||||
@@ -52,17 +54,25 @@ const Content = ({ findings, onComplete }: ContentProps) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const onSubmit = async (data: FormType) => {
|
const onSubmit = async (data: FormType) => {
|
||||||
|
if (!data.status) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for await (const finding of findings) {
|
if (findings.length > 1) {
|
||||||
// If a status wasn't set, don't update
|
await updateMultipleFindings.mutateAsync(
|
||||||
if (data.status) {
|
findings.map((f) => ({
|
||||||
await updateFinding.mutateAsync({
|
|
||||||
...data,
|
...data,
|
||||||
status: data.status,
|
status: data.status!,
|
||||||
findingId: finding.id,
|
findingId: f.id,
|
||||||
projectId: finding.projectId
|
projectId: f.projectId
|
||||||
});
|
}))
|
||||||
}
|
);
|
||||||
|
} else {
|
||||||
|
await updateFinding.mutateAsync({
|
||||||
|
...data,
|
||||||
|
status: data.status,
|
||||||
|
findingId: findings[0].id,
|
||||||
|
projectId: findings[0].projectId
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
|
|||||||
Reference in New Issue
Block a user