feat: renamed old frontend and fixed some minor bugs

This commit is contained in:
=
2025-01-06 14:56:49 +05:30
parent 8c902d7699
commit 54377a44d3
2577 changed files with 35240 additions and 35116 deletions
@@ -0,0 +1,145 @@
import { useEffect } from "react";
import { Helmet } from "react-helmet";
import { useSearch } from "@tanstack/react-router";
import { OrgPermissionCan } from "@app/components/permissions";
import { Button, NoticeBanner } from "@app/components/v2";
import { ROUTE_PATHS } from "@app/const/routes";
import {
OrgPermissionActions,
OrgPermissionSubjects,
useOrganization,
useServerConfig
} from "@app/context";
import { withPermission } from "@app/hoc";
import {
useCreateNewInstallationSession,
useGetSecretScanningInstallationStatus,
useLinkGitAppInstallationWithOrg
} from "@app/hooks/api/secretScanning";
import { SecretScanningLogsTable } from "./components";
export const SecretScanningPage = withPermission(
() => {
const queryParams = useSearch({
from: ROUTE_PATHS.Organization.SecretScanning.id
});
const { config } = useServerConfig();
const { currentOrg } = useOrganization();
const organizationId = currentOrg.id;
const { mutateAsync: linkGitAppInstallationWithOrganization } =
useLinkGitAppInstallationWithOrg();
const { mutateAsync: createNewIntegrationSession } = useCreateNewInstallationSession();
const { data: installationStatus, isPending: isSecretScanningInstatllationStatusLoading } =
useGetSecretScanningInstallationStatus(organizationId);
const integrationEnabled =
!isSecretScanningInstatllationStatusLoading && installationStatus?.appInstallationCompleted;
useEffect(() => {
const linkInstallation = async () => {
if (queryParams.state && queryParams.installation_id) {
try {
const isLinked = await linkGitAppInstallationWithOrganization({
installationId: queryParams.installation_id as string,
sessionId: queryParams.state as string
});
if (isLinked) {
window.location.reload();
}
console.log("installation verification complete");
} catch (e) {
console.log("app installation is stale, start new session", e);
}
}
};
linkInstallation();
}, [queryParams.state, queryParams.installation_id]);
const generateNewIntegrationSession = async () => {
const session = await createNewIntegrationSession({ organizationId });
window.location.href = `https://github.com/apps/infisical-radar/installations/new?state=${session.sessionId}`;
};
return (
<div>
<Helmet>
<title>Secret scanning</title>
<link rel="icon" href="/infisical.ico" />
<meta property="og:image" content="/images/message.png" />
</Helmet>
<div className="flex h-full w-full justify-center bg-bunker-800 text-white">
<div className="w-full max-w-7xl px-6">
<div className="mt-6 text-3xl font-semibold text-gray-200">Secret Scanning</div>
<div className="mb-6 text-lg text-mineshaft-300">
Automatically monitor your GitHub activity and prevent secret leaks
</div>
{config.isSecretScanningDisabled && (
<NoticeBanner title="Secret scanning is in maintenance" className="mb-4">
We are working on improving the performance of secret scanning due to increased
usage.
</NoticeBanner>
)}
<div className="relative mb-6 flex justify-between rounded-md border border-mineshaft-600 bg-mineshaft-800 p-6">
<div className="flex flex-col items-start">
<div className="mb-1 flex flex-row">
Secret Scanning Status:{" "}
{integrationEnabled ? (
<p className="ml-1.5 font-semibold text-green">Enabled</p>
) : (
<p className="ml-1.5 font-semibold text-red">Not enabled</p>
)}
</div>
<div>
{integrationEnabled ? (
<p className="text-mineshaft-300">
Your GitHub organization is connected to Infisical, and is being continuously
monitored for secret leaks.
</p>
) : (
<p className="text-mineshaft-300">
Connect your GitHub organization to Infisical.
</p>
)}
</div>
</div>
{integrationEnabled ? (
<div>
<div className="absolute right-[2.5rem] top-[2.5rem] flex h-6 w-6 animate-ping items-center justify-center rounded-full bg-green" />
<div className="absolute right-[2.63rem] top-[2.63rem] flex h-5 w-5 animate-ping items-center justify-center rounded-full bg-green" />
<div className="absolute right-[2.82rem] top-[2.82rem] flex h-3.5 w-3.5 animate-ping items-center justify-center rounded-full bg-green" />
</div>
) : (
<div className="flex h-[3.25rem] items-center">
<OrgPermissionCan
I={OrgPermissionActions.Create}
a={OrgPermissionSubjects.SecretScanning}
>
{(isAllowed) => (
<Button
variant="solid"
colorSchema="primary"
onClick={generateNewIntegrationSession}
className="h-min py-2"
isDisabled={!isAllowed}
>
Integrate with GitHub
</Button>
)}
</OrgPermissionCan>
</div>
)}
</div>
<SecretScanningLogsTable />
</div>
</div>
</div>
);
},
{
action: OrgPermissionActions.Read,
subject: OrgPermissionSubjects.SecretScanning
}
);
@@ -0,0 +1,46 @@
import { useState } from "react";
import { OrgPermissionCan } from "@app/components/permissions";
import { OrgPermissionActions, OrgPermissionSubjects, useOrganization } from "@app/context";
import { useUpdateRiskStatus } from "@app/hooks/api/secretScanning";
import { RiskStatus } from "@app/hooks/api/secretScanning/types";
export const RiskStatusSelection = ({
riskId,
currentSelection
}: {
riskId: any;
currentSelection: any;
}) => {
const [selectedRiskStatus, setSelectedRiskStatus] = useState(currentSelection);
const { mutate: updateRiskStatus } = useUpdateRiskStatus();
const { currentOrg } = useOrganization();
const organizationId = currentOrg.id;
return (
<OrgPermissionCan I={OrgPermissionActions.Edit} a={OrgPermissionSubjects.SecretScanning}>
{(isAllowed) => (
<select
disabled={!isAllowed}
value={selectedRiskStatus}
onChange={(e) => {
setSelectedRiskStatus(e.target.value);
updateRiskStatus({
organizationId,
status: e.target.value as RiskStatus,
riskId
});
}}
className="block w-full rounded-md px-3 py-2 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-blue-500"
>
<option>Unresolved</option>
<option value={RiskStatus.RESOLVED_FALSE_POSITIVE}>
This is a false positive, resolved
</option>
<option value={RiskStatus.RESOLVED_REVOKED}>I have rotated the secret, resolved</option>
<option value={RiskStatus.RESOLVED_NOT_REVOKED}>No rotate needed, resolved</option>
</select>
)}
</OrgPermissionCan>
);
};
@@ -0,0 +1,91 @@
import { faCheck } from "@fortawesome/free-solid-svg-icons";
import { formatDistance } from "date-fns";
import {
EmptyState,
Table,
TableContainer,
TableSkeleton,
TBody,
Td,
Th,
THead,
Tr
} from "@app/components/v2";
import { useOrganization } from "@app/context";
import { useGetSecretScanningRisks } from "@app/hooks/api/secretScanning";
import { RiskStatusSelection } from "./RiskStatusSelection";
export const SecretScanningLogsTable = () => {
const { currentOrg } = useOrganization();
const organizationId = currentOrg.id;
const { isPending, data: gitRisks } = useGetSecretScanningRisks(organizationId);
return (
<TableContainer className="mt-8">
<Table>
<THead>
<Tr>
<Th className="flex-1">Date</Th>
<Th className="flex-1">Secret Type</Th>
<Th className="flex-1">View Risk</Th>
<Th className="flex-1">Info</Th>
<Th className="flex-1">Status</Th>
<Th className="flex-1">Action</Th>
<Th className="w-5" />
</Tr>
</THead>
<TBody>
{!isPending &&
gitRisks &&
gitRisks?.map((risk) => {
return (
<Tr key={risk.ruleID} className="h-10">
<Td>{formatDistance(new Date(risk.createdAt), new Date())}</Td>
<Td>{risk.ruleID}</Td>
<Td>
<a
href={`https://github.com/${risk.repositoryFullName}/blob/${risk.commit}/${risk.file}#L${risk.startLine}-L${risk.endLine}`}
target="_blank"
className="text-red-500"
rel="noreferrer"
>
View Exposed Secret
</a>
</Td>
<Td>
<div className="font-bold">
<a href={`https://github.com/${risk.repositoryFullName}`}>
{risk.repositoryFullName}
</a>
</div>
<div className="text-xs">
<span>{risk.file}</span>
<br />
<br />
<span className="font-bold">{risk.author}</span>
<br />
<span>{risk.email}</span>
</div>
</Td>
<Td>{risk.isResolved ? "Resolved" : "Needs Attention"}</Td>
<Td>
<RiskStatusSelection riskId={risk.id} currentSelection={risk.status} />
</Td>
</Tr>
);
})}
{isPending && <TableSkeleton columns={7} innerKey="gitRisks" />}
{!isPending && gitRisks && gitRisks?.length === 0 && (
<Tr>
<Td colSpan={7}>
<EmptyState title="No risks detected." icon={faCheck} />
</Td>
</Tr>
)}
</TBody>
</Table>
</TableContainer>
);
};
@@ -0,0 +1 @@
export { SecretScanningLogsTable } from "./SecretScanningLogsTable";
@@ -0,0 +1,25 @@
import { createFileRoute, stripSearchParams } from "@tanstack/react-router";
import { zodValidator } from "@tanstack/zod-adapter";
import { z } from "zod";
import { SecretScanningPage } from "./SecretScanningPage";
const SecretScanningQueryParams = z.object({
state: z.string().catch(""),
installation_id: z.string().catch("")
});
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/organization/_layout/secret-scanning"
)({
component: SecretScanningPage,
validateSearch: zodValidator(SecretScanningQueryParams),
search: {
middlewares: [
stripSearchParams({
installation_id: "",
state: ""
})
]
}
});