mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-20 13:43:37 +00:00
feature: secret scanning pt 3
This commit is contained in:
+1
-1
@@ -114,7 +114,7 @@ export const SecretScanningScanRow = ({ scan }: Props) => {
|
||||
<span className="text-xs">
|
||||
{totalFindings}{" "}
|
||||
{unresolvedFindings
|
||||
? `Secret ${totalFindings > 1 ? "s" : ""} Detected`
|
||||
? `Secret${totalFindings > 1 ? "s" : ""} Detected`
|
||||
: "Leak Resolved"}
|
||||
</span>
|
||||
</Badge>
|
||||
|
||||
@@ -3,9 +3,11 @@ import { useTranslation } from "react-i18next";
|
||||
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
|
||||
import { ProjectPermissionSub } from "@app/context";
|
||||
import { ProjectPermissionSecretScanningConfigActions } from "@app/context/ProjectPermissionContext/types";
|
||||
|
||||
import { ProjectGeneralTab } from "./components/ProjectGeneralTab";
|
||||
import { ProjectScanningConfigTab } from "./components/ProjectScanningConfigTab";
|
||||
|
||||
export const SettingsPage = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -21,26 +23,29 @@ export const SettingsPage = () => {
|
||||
<TabList>
|
||||
<Tab value="tab-project-general">General</Tab>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={ProjectPermissionSub.Project}
|
||||
I={ProjectPermissionSecretScanningConfigActions.Read}
|
||||
a={ProjectPermissionSub.SecretScanningConfigs}
|
||||
>
|
||||
{(isAllowed) =>
|
||||
isAllowed && <Tab value="tab-project-secret-scannings">Rule Settings</Tab>
|
||||
isAllowed && <Tab value="tab-project-scanning-config">Scanning Configuration</Tab>
|
||||
}
|
||||
</ProjectPermissionCan>
|
||||
</TabList>
|
||||
<TabPanel value="tab-project-general">
|
||||
<ProjectGeneralTab />
|
||||
</TabPanel>
|
||||
{/* <ProjectPermissionCan I={ProjectPermissionActions.Edit} a={ProjectPermissionSub.Project}>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionSecretScanningConfigActions.Read}
|
||||
a={ProjectPermissionSub.SecretScanningConfigs}
|
||||
>
|
||||
{(isAllowed) =>
|
||||
isAllowed && (
|
||||
<TabPanel value="tab-project-ssh">
|
||||
<ProjectSshTab />
|
||||
<TabPanel value="tab-project-scanning-config">
|
||||
<ProjectScanningConfigTab />
|
||||
</TabPanel>
|
||||
)
|
||||
}
|
||||
</ProjectPermissionCan> */}
|
||||
</ProjectPermissionCan>
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
import { faBan } from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
import { ContentLoader, EmptyState } from "@app/components/v2";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useGetSecretScanningConfig } from "@app/hooks/api/secretScanningV2";
|
||||
|
||||
import { SecretScanningConfigForm } from "./SecretScanningConfigForm";
|
||||
|
||||
export const ProjectScanningConfigTab = () => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { data: config, isPending: isConfigPending } = useGetSecretScanningConfig(
|
||||
currentWorkspace.id
|
||||
);
|
||||
|
||||
if (isConfigPending) {
|
||||
return (
|
||||
<div className="flex h-full w-full items-center justify-center">
|
||||
<ContentLoader />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!config) {
|
||||
return (
|
||||
<div className="flex h-full w-full items-center justify-center px-20">
|
||||
<EmptyState
|
||||
className="max-w-2xl rounded-md text-center"
|
||||
icon={faBan}
|
||||
title="Could not find Project Configuration"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<SecretScanningConfigForm config={config} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { Button, FormControl, TextArea } from "@app/components/v2";
|
||||
import { ProjectPermissionSub } from "@app/context";
|
||||
import { ProjectPermissionSecretScanningConfigActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import {
|
||||
TSecretScanningConfig,
|
||||
useUpdateSecretScanningConfig
|
||||
} from "@app/hooks/api/secretScanningV2";
|
||||
|
||||
type Props = {
|
||||
config: TSecretScanningConfig;
|
||||
};
|
||||
|
||||
const FormSchema = z.object({
|
||||
content: z.string().max(5000, "Configuration cannot exceed 5000 characters").optional()
|
||||
});
|
||||
|
||||
type FormType = z.infer<typeof FormSchema>;
|
||||
|
||||
export const SecretScanningConfigForm = ({ config }: Props) => {
|
||||
const updateConfig = useUpdateSecretScanningConfig();
|
||||
|
||||
const {
|
||||
handleSubmit,
|
||||
control,
|
||||
formState: { isDirty }
|
||||
} = useForm<FormType>({
|
||||
resolver: zodResolver(FormSchema),
|
||||
defaultValues: {
|
||||
content: config.content ?? ""
|
||||
}
|
||||
});
|
||||
|
||||
const onSubmit = async ({ content }: FormType) => {
|
||||
try {
|
||||
await updateConfig.mutateAsync({
|
||||
projectId: config.projectId,
|
||||
content: content || null
|
||||
});
|
||||
|
||||
createNotification({
|
||||
type: "success",
|
||||
text: "Configuration successfully updated"
|
||||
});
|
||||
} catch {
|
||||
createNotification({
|
||||
type: "error",
|
||||
text: "Failed to update Configuration"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<h2 className="text-xl font-semibold text-mineshaft-100">Project Configuration</h2>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://infisical.com/docs/documentation/platform/secret-scanning/overview#configuration"
|
||||
className="mt-[0.02rem]"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="inline-block rounded-md bg-yellow/20 px-1.5 text-sm text-yellow opacity-80 hover:opacity-100">
|
||||
<FontAwesomeIcon icon={faBookOpen} className="mb-[0.03rem] mr-1 text-[12px]" />
|
||||
<span>Docs</span>
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowUpRightFromSquare}
|
||||
className="mb-[0.07rem] ml-1 text-[10px]"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<p className="leading-5 text-mineshaft-400">
|
||||
Configure rules and exceptions to customize scanning
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="flex w-full flex-col">
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionSecretScanningConfigActions.Update}
|
||||
a={ProjectPermissionSub.SecretScanningConfigs}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Controller
|
||||
defaultValue=""
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl isError={Boolean(error)} errorText={error?.message}>
|
||||
<TextArea
|
||||
placeholder={
|
||||
"[extend]\n\nuseDefault = true\n\n# See docs for configuration guide"
|
||||
}
|
||||
{...field}
|
||||
rows={3}
|
||||
className="thin-scrollbar min-h-[36rem] w-full !resize-none !resize-y"
|
||||
isDisabled={!isAllowed}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
control={control}
|
||||
name="content"
|
||||
/>
|
||||
)}
|
||||
</ProjectPermissionCan>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionSecretScanningConfigActions.Update}
|
||||
a={ProjectPermissionSub.SecretScanningConfigs}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
colorSchema="secondary"
|
||||
type="submit"
|
||||
className="w-min"
|
||||
isLoading={updateConfig.isPending}
|
||||
isDisabled={updateConfig.isPending || !isAllowed || !isDirty}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
)}
|
||||
</ProjectPermissionCan>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
+1
@@ -0,0 +1 @@
|
||||
export { ProjectScanningConfigTab } from "./ProjectScanningConfigTab";
|
||||
Reference in New Issue
Block a user