Merge branch 'heads/main' into daniel/gateway-auth-methods

This commit is contained in:
Daniel Hougaard
2025-06-05 04:49:35 +04:00
400 changed files with 15599 additions and 1473 deletions
@@ -1,6 +1,7 @@
export enum AppConnection {
AWS = "aws",
GitHub = "github",
GitHubRadar = "github-radar",
GCP = "gcp",
AzureKeyVault = "azure-key-vault",
AzureAppConfiguration = "azure-app-configuration",
@@ -0,0 +1,2 @@
export * from "./queries";
export * from "./types";
@@ -0,0 +1,40 @@
import { useQuery, UseQueryOptions } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { appConnectionKeys } from "@app/hooks/api/appConnections";
import {
TGitHubRadarConnectionListRepositoriesResponse,
TGitHubRadarConnectionRepository
} from "./types";
const githubRadarConnectionKeys = {
all: [...appConnectionKeys.all, "github-radar"] as const,
listRepositories: (connectionId: string) =>
[...githubRadarConnectionKeys.all, "repositories", connectionId] as const
};
export const useGitHubRadarConnectionListRepositories = (
connectionId: string,
options?: Omit<
UseQueryOptions<
TGitHubRadarConnectionRepository[],
unknown,
TGitHubRadarConnectionRepository[],
ReturnType<typeof githubRadarConnectionKeys.listRepositories>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: githubRadarConnectionKeys.listRepositories(connectionId),
queryFn: async () => {
const { data } = await apiRequest.get<TGitHubRadarConnectionListRepositoriesResponse>(
`/api/v1/app-connections/github-radar/${connectionId}/repositories`
);
return data.repositories;
},
...options
});
};
@@ -0,0 +1,14 @@
export type TGitHubRadarConnectionOrganization = {
login: string;
id: number;
};
export type TGitHubRadarConnectionRepository = {
id: number;
name: string;
owner: TGitHubRadarConnectionOrganization;
};
export type TGitHubRadarConnectionListRepositoriesResponse = {
repositories: TGitHubRadarConnectionRepository[];
};
@@ -17,6 +17,11 @@ export type TGitHubConnectionOption = TAppConnectionOptionBase & {
appClientSlug?: string;
};
export type TGitHubRadarConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.GitHubRadar;
appClientSlug?: string;
};
export type TGcpConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.GCP;
};
@@ -121,6 +126,7 @@ export type TAppConnectionOption =
export type TAppConnectionOptionMap = {
[AppConnection.AWS]: TAwsConnectionOption;
[AppConnection.GitHub]: TGitHubConnectionOption;
[AppConnection.GitHubRadar]: TGitHubRadarConnectionOption;
[AppConnection.GCP]: TGcpConnectionOption;
[AppConnection.AzureKeyVault]: TAzureKeyVaultConnectionOption;
[AppConnection.AzureAppConfiguration]: TAzureAppConfigurationConnectionOption;
@@ -0,0 +1,14 @@
import { AppConnection } from "@app/hooks/api/appConnections/enums";
import { TRootAppConnection } from "@app/hooks/api/appConnections/types/root-connection";
export enum GitHubRadarConnectionMethod {
App = "github-app"
}
export type TGitHubRadarConnection = TRootAppConnection & { app: AppConnection.GitHubRadar } & {
method: GitHubRadarConnectionMethod.App;
credentials: {
code: string;
installationId: string;
};
};
@@ -10,6 +10,7 @@ import { TCamundaConnection } from "./camunda-connection";
import { TDatabricksConnection } from "./databricks-connection";
import { TGcpConnection } from "./gcp-connection";
import { TGitHubConnection } from "./github-connection";
import { TGitHubRadarConnection } from "./github-radar-connection";
import { THCVaultConnection } from "./hc-vault-connection";
import { THumanitecConnection } from "./humanitec-connection";
import { TLdapConnection } from "./ldap-connection";
@@ -32,6 +33,7 @@ export * from "./camunda-connection";
export * from "./databricks-connection";
export * from "./gcp-connection";
export * from "./github-connection";
export * from "./github-radar-connection";
export * from "./hc-vault-connection";
export * from "./humanitec-connection";
export * from "./ldap-connection";
@@ -47,6 +49,7 @@ export * from "./windmill-connection";
export type TAppConnection =
| TAwsConnection
| TGitHubConnection
| TGitHubRadarConnection
| TGcpConnection
| TAzureKeyVaultConnection
| TAzureAppConfigurationConnection
@@ -95,6 +98,7 @@ export type TDeleteAppConnectionDTO = {
export type TAppConnectionMap = {
[AppConnection.AWS]: TAwsConnection;
[AppConnection.GitHub]: TGitHubConnection;
[AppConnection.GitHubRadar]: TGitHubRadarConnection;
[AppConnection.GCP]: TGcpConnection;
[AppConnection.AzureKeyVault]: TAzureKeyVaultConnection;
[AppConnection.AzureAppConfiguration]: TAzureAppConfigurationConnection;
@@ -191,6 +191,20 @@ export const eventToNameMap: { [K in EventType]: string } = {
[EventType.GET_IDENTITY_LDAP_AUTH]: "Retrieved LDAP Auth for identity",
[EventType.REVOKE_IDENTITY_LDAP_AUTH]: "Revoked LDAP Auth for identity",
[EventType.SECRET_SCANNING_DATA_SOURCE_LIST]: "List Secret Scanning Data Sources",
[EventType.SECRET_SCANNING_DATA_SOURCE_CREATE]: "Create Secret Scanning Data Source",
[EventType.SECRET_SCANNING_DATA_SOURCE_UPDATE]: "Update Secret Scanning Data Source",
[EventType.SECRET_SCANNING_DATA_SOURCE_DELETE]: "Delete Secret Scanning Data Source",
[EventType.SECRET_SCANNING_DATA_SOURCE_GET]: "Get Secret Scanning Data Source",
[EventType.SECRET_SCANNING_DATA_SOURCE_TRIGGER_SCAN]: "Trigger Secret Scanning Data Source Scan",
[EventType.SECRET_SCANNING_DATA_SOURCE_SCAN]: "Secret Scanning Data Source Scan",
[EventType.SECRET_SCANNING_RESOURCE_LIST]: "List Secret Scanning Resources",
[EventType.SECRET_SCANNING_SCAN_LIST]: "List Secret Scanning Scans",
[EventType.SECRET_SCANNING_FINDING_LIST]: "List Secret Scanning Findings",
[EventType.SECRET_SCANNING_FINDING_UPDATE]: "Update Secret Scanning Finding Status",
[EventType.SECRET_SCANNING_CONFIG_GET]: "Get Secret Scanning Configuration",
[EventType.SECRET_SCANNING_CONFIG_UPDATE]: "Update Secret Scanning Configuration",
[EventType.CREATE_PKI_SUBSCRIBER]: "Create PKI subscriber",
[EventType.UPDATE_PKI_SUBSCRIBER]: "Update PKI subscriber",
[EventType.DELETE_PKI_SUBSCRIBER]: "Delete PKI subscriber",
@@ -185,6 +185,20 @@ export enum EventType {
MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_GET = "microsoft-teams-workflow-integration-get",
MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_LIST = "microsoft-teams-workflow-integration-list",
SECRET_SCANNING_DATA_SOURCE_LIST = "secret-scanning-data-source-list",
SECRET_SCANNING_DATA_SOURCE_CREATE = "secret-scanning-data-source-create",
SECRET_SCANNING_DATA_SOURCE_UPDATE = "secret-scanning-data-source-update",
SECRET_SCANNING_DATA_SOURCE_DELETE = "secret-scanning-data-source-delete",
SECRET_SCANNING_DATA_SOURCE_GET = "secret-scanning-data-source-get",
SECRET_SCANNING_DATA_SOURCE_TRIGGER_SCAN = "secret-scanning-data-source-trigger-scan",
SECRET_SCANNING_DATA_SOURCE_SCAN = "secret-scanning-data-source-scan",
SECRET_SCANNING_RESOURCE_LIST = "secret-scanning-resource-list",
SECRET_SCANNING_SCAN_LIST = "secret-scanning-scan-list",
SECRET_SCANNING_FINDING_LIST = "secret-scanning-finding-list",
SECRET_SCANNING_FINDING_UPDATE = "secret-scanning-finding-update",
SECRET_SCANNING_CONFIG_GET = "secret-scanning-config-get",
SECRET_SCANNING_CONFIG_UPDATE = "secret-scanning-config-update",
CREATE_PKI_SUBSCRIBER = "create-pki-subscriber",
UPDATE_PKI_SUBSCRIBER = "update-pki-subscriber",
DELETE_PKI_SUBSCRIBER = "delete-pki-subscriber",
+14 -1
View File
@@ -33,7 +33,8 @@ export enum DynamicSecretProviders {
Snowflake = "snowflake",
Totp = "totp",
SapAse = "sap-ase",
Kubernetes = "kubernetes"
Kubernetes = "kubernetes",
Vertica = "vertica"
}
export enum SqlProviders {
@@ -277,6 +278,18 @@ export type TDynamicSecretProvider =
sslEnabled: boolean;
audiences: string[];
};
}
| {
type: DynamicSecretProviders.Vertica;
inputs: {
host: string;
port: number;
database: string;
username: string;
password: string;
creationStatement: string;
revocationStatement: string;
};
};
export type TCreateDynamicSecretDTO = {
+35 -29
View File
@@ -1,3 +1,4 @@
import { useState } from "react";
import { MutationCache, QueryClient } from "@tanstack/react-query";
import axios from "axios";
@@ -18,6 +19,39 @@ export const SIGNUP_TEMP_TOKEN_CACHE_KEY = ["infisical__signup-temp-token"];
export const MFA_TEMP_TOKEN_CACHE_KEY = ["infisical__mfa-temp-token"];
export const AUTH_TOKEN_CACHE_KEY = ["infisical__auth-token"];
function ValidationErrorModal({ serverResponse }: { serverResponse: TApiErrors }) {
const [open, setOpen] = useState(true);
if (serverResponse.error !== ApiErrorTypes.ValidationError) {
return null;
}
return (
<Modal isOpen={open} onOpenChange={setOpen}>
<ModalContent title="Validation Error Details">
<TableContainer>
<Table>
<THead>
<Tr>
<Th>Field</Th>
<Th>Issue</Th>
</Tr>
</THead>
<TBody>
{serverResponse.message?.map(({ message, path }) => (
<Tr key={path.join(".")}>
<Td>{path.join(".")}</Td>
<Td>{message.toLowerCase()}</Td>
</Tr>
))}
</TBody>
</Table>
</TableContainer>
</ModalContent>
</Modal>
);
}
export const onRequestError = (error: unknown) => {
if (axios.isAxiosError(error)) {
const serverResponse = error.response?.data as TApiErrors;
@@ -27,35 +61,7 @@ export const onRequestError = (error: unknown) => {
title: "Validation Error",
type: "error",
text: "Please check the input and try again.",
callToAction: (
<Modal>
<ModalTrigger asChild>
<Button variant="outline_bg" size="xs">
Show more
</Button>
</ModalTrigger>
<ModalContent title="Validation Error Details">
<TableContainer>
<Table>
<THead>
<Tr>
<Th>Field</Th>
<Th>Issue</Th>
</Tr>
</THead>
<TBody>
{serverResponse.message?.map(({ message, path }) => (
<Tr key={path.join(".")}>
<Td>{path.join(".")}</Td>
<Td>{message.toLowerCase()}</Td>
</Tr>
))}
</TBody>
</Table>
</TableContainer>
</ModalContent>
</Modal>
),
callToAction: <ValidationErrorModal serverResponse={serverResponse} />,
copyActions: [
{
value: serverResponse.reqId,
@@ -0,0 +1,33 @@
export enum SecretScanningDataSource {
GitHub = "github"
}
export enum SecretScanningScanStatus {
Completed = "completed",
Failed = "failed",
Queued = "queued",
Scanning = "scanning"
}
export enum SecretScanningScanType {
FullScan = "full-scan",
DiffScan = "diff-scan"
}
export enum SecretScanningFindingStatus {
Resolved = "resolved",
Unresolved = "unresolved",
FalsePositive = "false-positive",
Ignore = "ignore"
}
export enum SecretScanningResource {
Repository = "repository",
Project = "project"
}
export enum SecretScanningFindingSeverity {
High = "high",
Medium = "medium",
Low = "low"
}
@@ -0,0 +1,4 @@
export * from "./enums";
export * from "./mutations";
export * from "./queries";
export * from "./types";
@@ -0,0 +1,160 @@
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { secretScanningV2Keys } from "./queries";
import {
TCreateSecretScanningDataSourceDTO,
TDeleteSecretScanningDataSourceDTO,
TGetSecretScanningConfigResponse,
TSecretScanningConfig,
TSecretScanningDataSourceResponse,
TSecretScanningFindingResponse,
TTriggerSecretScanningDataSourceDTO,
TUpdateSecretScanningDataSourceDTO,
TUpdateSecretScanningFinding
} from "./types";
export const useCreateSecretScanningDataSource = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ type, ...params }: TCreateSecretScanningDataSourceDTO) => {
const { data } = await apiRequest.post<TSecretScanningDataSourceResponse>(
`/api/v2/secret-scanning/data-sources/${type}`,
params
);
return data.dataSource;
},
onSuccess: (_, { projectId }) =>
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.listDataSources(projectId)
})
});
};
export const useUpdateSecretScanningDataSource = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ type, dataSourceId, ...params }: TUpdateSecretScanningDataSourceDTO) => {
const { data } = await apiRequest.patch<TSecretScanningDataSourceResponse>(
`/api/v2/secret-scanning/data-sources/${type}/${dataSourceId}`,
params
);
return data.dataSource;
},
onSuccess: (_, { projectId, dataSourceId }) => {
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.listDataSources(projectId)
});
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.dataSourceById(dataSourceId)
});
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.listResources(dataSourceId)
});
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.listScans(dataSourceId)
});
}
});
};
export const useDeleteSecretScanningDataSource = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ type, dataSourceId }: TDeleteSecretScanningDataSourceDTO) => {
const { data } = await apiRequest.delete<TSecretScanningDataSourceResponse>(
`/api/v2/secret-scanning/data-sources/${type}/${dataSourceId}`
);
return data.dataSource;
},
onSuccess: (_, { projectId, dataSourceId }) => {
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.listDataSources(projectId)
});
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.dataSourceById(dataSourceId)
});
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.listResources(dataSourceId)
});
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.listScans(dataSourceId)
});
}
});
};
export const useTriggerSecretScanningDataSource = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ type, dataSourceId, resourceId }: TTriggerSecretScanningDataSourceDTO) => {
const { data } = await apiRequest.post<TSecretScanningDataSourceResponse>(
`/api/v2/secret-scanning/data-sources/${type}/${dataSourceId}${resourceId ? `/resources/${resourceId}` : ""}/scan`
);
return data.dataSource;
},
onSuccess: (_, { projectId, dataSourceId }) => {
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.listDataSources(projectId)
});
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.dataSourceById(dataSourceId)
});
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.listResources(dataSourceId)
});
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.listScans(dataSourceId)
});
}
});
};
export const useUpdateSecretScanningFinding = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ findingId, ...params }: TUpdateSecretScanningFinding) => {
const { data } = await apiRequest.patch<TSecretScanningFindingResponse>(
`/api/v2/secret-scanning/findings/${findingId}`,
params
);
return data.finding;
},
onSuccess: (_, { projectId }) => {
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.listFindings(projectId)
});
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.findingCount(projectId)
});
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.dataSource()
});
}
});
};
export const useUpdateSecretScanningConfig = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectId, ...params }: TSecretScanningConfig) => {
const { data } = await apiRequest.patch<TGetSecretScanningConfigResponse>(
`/api/v2/secret-scanning/configs?projectId=${projectId}`,
params
);
return data.config;
},
onSuccess: (_, { projectId }) => {
queryClient.invalidateQueries({
queryKey: secretScanningV2Keys.configByProjectId(projectId)
});
}
});
};
@@ -0,0 +1,248 @@
import { useQuery, UseQueryOptions } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import {
TGetSecretScanningConfigResponse,
TGetSecretScanningDataSource,
TGetSecretScanningUnresolvedFindingsResponse,
TListSecretScanningDataSourceOptions,
TListSecretScanningDataSources,
TListSecretScanningFindingsResponse,
TListSecretScanningResourcesResponse,
TListSecretScanningScansResponse,
TSecretScanningConfig,
TSecretScanningDataSource,
TSecretScanningDataSourceOption,
TSecretScanningDataSourceResponse,
TSecretScanningDataSourceWithDetails,
TSecretScanningFinding,
TSecretScanningResourceWithDetails,
TSecretScanningScanWithDetails
} from "./types";
export const secretScanningV2Keys = {
all: ["secret-scanning-v2"] as const,
dataSource: () => [...secretScanningV2Keys.all, "data-source"] as const,
dataSourceOptions: () => [...secretScanningV2Keys.dataSource(), "options"] as const,
dataSourceById: (dataSourceId: string) => [
...secretScanningV2Keys.dataSource(),
"byId",
dataSourceId
],
listDataSources: (projectId: string) => [...secretScanningV2Keys.dataSource(), "list", projectId],
listResources: (dataSourceId: string) => [
...secretScanningV2Keys.dataSource(),
"resources",
dataSourceId
],
listScans: (dataSourceId: string) => [
...secretScanningV2Keys.dataSource(),
"scans",
dataSourceId
],
finding: () => [...secretScanningV2Keys.all, "finding"] as const,
findingCount: (projectId: string) =>
[...secretScanningV2Keys.finding(), "count", projectId] as const,
listFindings: (projectId: string) => [...secretScanningV2Keys.finding(), "list", projectId],
configByProjectId: (projectId: string) =>
[...secretScanningV2Keys.all, "config", projectId] as const
};
export const useSecretScanningDataSourceOptions = (
options?: Omit<
UseQueryOptions<
TSecretScanningDataSourceOption[],
unknown,
TSecretScanningDataSourceOption[],
ReturnType<typeof secretScanningV2Keys.dataSourceOptions>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: secretScanningV2Keys.dataSourceOptions(),
queryFn: async () => {
const { data } = await apiRequest.get<TListSecretScanningDataSourceOptions>(
"/api/v2/secret-scanning/data-sources/options"
);
return data.dataSourceOptions;
},
...options
});
};
export const useListSecretScanningDataSources = (
projectId: string,
options?: Omit<
UseQueryOptions<
TSecretScanningDataSourceWithDetails[],
unknown,
TSecretScanningDataSourceWithDetails[],
ReturnType<typeof secretScanningV2Keys.listDataSources>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: secretScanningV2Keys.listDataSources(projectId),
queryFn: async () => {
const { data } = await apiRequest.get<TListSecretScanningDataSources>(
"/api/v2/secret-scanning/data-sources-dashboard",
{ params: { projectId } }
);
return data.dataSources;
},
...options
});
};
export const useGetSecretScanningDataSource = (
{ dataSourceId, type }: TGetSecretScanningDataSource,
options?: Omit<
UseQueryOptions<
TSecretScanningDataSource,
unknown,
TSecretScanningDataSource,
ReturnType<typeof secretScanningV2Keys.dataSourceById>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: secretScanningV2Keys.dataSourceById(dataSourceId),
queryFn: async () => {
const { data } = await apiRequest.get<TSecretScanningDataSourceResponse>(
`/api/v2/secret-scanning/data-sources/${type}/${dataSourceId}`
);
return data.dataSource;
},
...options
});
};
export const useListSecretScanningResources = (
{ dataSourceId, type }: TGetSecretScanningDataSource,
options?: Omit<
UseQueryOptions<
TSecretScanningResourceWithDetails[],
unknown,
TSecretScanningResourceWithDetails[],
ReturnType<typeof secretScanningV2Keys.listResources>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: secretScanningV2Keys.listResources(dataSourceId),
queryFn: async () => {
const { data } = await apiRequest.get<TListSecretScanningResourcesResponse>(
`/api/v2/secret-scanning/data-sources/${type}/${dataSourceId}/resources-dashboard`
);
return data.resources;
},
...options
});
};
export const useListSecretScanningScans = (
{ dataSourceId, type }: TGetSecretScanningDataSource,
options?: Omit<
UseQueryOptions<
TSecretScanningScanWithDetails[],
unknown,
TSecretScanningScanWithDetails[],
ReturnType<typeof secretScanningV2Keys.listScans>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: secretScanningV2Keys.listScans(dataSourceId),
queryFn: async () => {
const { data } = await apiRequest.get<TListSecretScanningScansResponse>(
`/api/v2/secret-scanning/data-sources/${type}/${dataSourceId}/scans-dashboard`
);
return data.scans;
},
...options
});
};
export const useGetSecretScanningUnresolvedFindingCount = (
projectId: string,
options?: Omit<
UseQueryOptions<number, unknown, number, ReturnType<typeof secretScanningV2Keys.findingCount>>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: secretScanningV2Keys.findingCount(projectId),
queryFn: async () => {
const { data } = await apiRequest.get<TGetSecretScanningUnresolvedFindingsResponse>(
"/api/v2/secret-scanning/unresolved-findings-count",
{ params: { projectId } }
);
return data.unresolvedFindings;
},
...options
});
};
export const useListSecretScanningFindings = (
projectId: string,
options?: Omit<
UseQueryOptions<
TSecretScanningFinding[],
unknown,
TSecretScanningFinding[],
ReturnType<typeof secretScanningV2Keys.listFindings>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: secretScanningV2Keys.listFindings(projectId),
queryFn: async () => {
const { data } = await apiRequest.get<TListSecretScanningFindingsResponse>(
"/api/v2/secret-scanning/findings",
{ params: { projectId } }
);
return data.findings;
},
...options
});
};
export const useGetSecretScanningConfig = (
projectId: string,
options?: Omit<
UseQueryOptions<
TSecretScanningConfig,
unknown,
TSecretScanningConfig,
ReturnType<typeof secretScanningV2Keys.configByProjectId>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: secretScanningV2Keys.configByProjectId(projectId),
queryFn: async () => {
const { data } = await apiRequest.get<TGetSecretScanningConfigResponse>(
"/api/v2/secret-scanning/configs",
{ params: { projectId } }
);
return data.config;
},
...options
});
};
@@ -0,0 +1,17 @@
import { AppConnection } from "@app/hooks/api/appConnections/enums";
import { SecretScanningDataSource } from "../enums";
import { TSecretScanningDataSourceBase } from "./shared";
export type TGitHubDataSource = TSecretScanningDataSourceBase & {
type: SecretScanningDataSource.GitHub;
config: {
includeRepos: string[];
};
};
export type TGitHubDataSourceOption = {
name: string;
type: SecretScanningDataSource.GitHub;
connection: AppConnection.GitHub;
};
@@ -0,0 +1,166 @@
import { DiscriminativePick } from "@app/types";
import {
SecretScanningDataSource,
SecretScanningFindingSeverity,
SecretScanningFindingStatus,
SecretScanningResource,
SecretScanningScanStatus,
SecretScanningScanType
} from "../enums";
import { TGitHubDataSource, TGitHubDataSourceOption } from "./github-data-source";
export type TSecretScanningDataSource = TGitHubDataSource;
export type TSecretScanningDataSourceWithDetails = TSecretScanningDataSource & {
lastScannedAt: string | null;
lastScanStatus: SecretScanningScanStatus | null;
lastScanStatusMessage: string | null;
unresolvedFindings: number | null;
};
export type TListSecretScanningDataSources = {
dataSources: TSecretScanningDataSourceWithDetails[];
};
export type TSecretScanningDataSourceOption = TGitHubDataSourceOption;
export type TListSecretScanningDataSourceOptions = {
dataSourceOptions: TSecretScanningDataSourceOption[];
};
export type TSecretScanningDataSourceResponse = { dataSource: TSecretScanningDataSource };
export type TCreateSecretScanningDataSourceDTO = DiscriminativePick<
TSecretScanningDataSource,
"name" | "config" | "description" | "connectionId" | "type" | "isAutoScanEnabled" | "projectId"
>;
export type TUpdateSecretScanningDataSourceDTO = Partial<
Omit<TCreateSecretScanningDataSourceDTO, "type" | "connectionId" | "projectId">
> & {
type: SecretScanningDataSource;
dataSourceId: string;
// required for query invalidation
projectId: string;
};
export type TDeleteSecretScanningDataSourceDTO = {
type: SecretScanningDataSource;
dataSourceId: string;
// required for query invalidation
projectId: string;
};
export type TTriggerSecretScanningDataSourceDTO = {
type: SecretScanningDataSource;
dataSourceId: string;
resourceId?: string;
// required for query invalidation
projectId: string;
};
export type TUpdateSecretScanningFinding = {
findingId: string;
status: SecretScanningFindingStatus;
remarks?: string | null;
// required for query invalidation
projectId: string;
};
export type TSecretScanningFindingResponse = {
finding: TSecretScanningFinding;
};
export type TGetSecretScanningDataSource = {
dataSourceId: string;
type: SecretScanningDataSource;
};
export type TSecretScanningResourceWithDetails = {
id: string;
dataSourceId: string;
type: SecretScanningResource;
externalId: string;
name: string;
createdAt: string;
updatedAt: string;
lastScannedAt: string;
lastScanStatus: SecretScanningScanStatus;
lastScanStatusMessage: string | null;
unresolvedFindings: number;
};
export type TListSecretScanningResourcesResponse = {
resources: TSecretScanningResourceWithDetails[];
};
export type TSecretScanningScanWithDetails = {
id: string;
createdAt: string;
resourceId: string;
type: SecretScanningScanType;
status: SecretScanningScanStatus;
statusMessage?: string | null;
unresolvedFindings: number;
resolvedFindings: number;
resourceName: string;
};
export type TListSecretScanningScansResponse = {
scans: TSecretScanningScanWithDetails[];
};
export type TGetSecretScanningUnresolvedFindingsResponse = {
unresolvedFindings: number;
};
export type TSecretScanningConfig = {
projectId: string;
content: string | null;
};
export type TGetSecretScanningConfigResponse = {
config: TSecretScanningConfig;
};
export type TSecretScanningFinding = {
id: string;
dataSourceName: string;
dataSourceType: SecretScanningDataSource;
resourceName: string;
resourceType: SecretScanningResource;
rule: string;
severity: SecretScanningFindingSeverity;
status: SecretScanningFindingStatus;
remarks?: string;
fingerprint: string;
// TODO scott: this will need to be type differentiated once we add other scan types
details: {
description: string;
startLine: number;
endLine: number;
startColumn: number;
endColumn: number;
file: string;
link: string;
symlinkFile: string;
commit: string;
entropy: string;
author: string;
email: string;
date: string;
message: string;
tags: string[];
ruleID: string;
fingerprint: string;
};
projectId: string;
scanId: string;
createdAt: string;
updatedAt: string;
};
export type TListSecretScanningFindingsResponse = {
findings: TSecretScanningFinding[];
};
@@ -0,0 +1 @@
export * from "./secret-scanning-data-source-base";
@@ -0,0 +1,18 @@
import { AppConnection } from "@app/hooks/api/appConnections/enums";
export type TSecretScanningDataSourceBase = {
id: string;
name: string;
description?: string | null;
connectionId?: string | null;
createdAt: string;
updatedAt: string;
projectId: string;
connection?: {
app: AppConnection;
id: string;
name: string;
} | null;
isAutoScanEnabled: boolean;
isDisconnected: boolean;
};
@@ -50,6 +50,7 @@ export type SubscriptionPlan = {
enforceMfa: boolean;
projectTemplates: boolean;
kmip: boolean;
secretScanning: boolean;
enterpriseSecretSyncs: boolean;
enterpriseAppConnections: boolean;
};
+2 -1
View File
@@ -12,7 +12,8 @@ export enum ProjectType {
SecretManager = "secret-manager",
CertificateManager = "cert-manager",
KMS = "kms",
SSH = "ssh"
SSH = "ssh",
SecretScanning = "secret-scanning"
}
export enum ProjectUserMembershipTemporaryMode {
+4 -2
View File
@@ -6,16 +6,18 @@ import { useDebounce } from "@app/hooks/useDebounce";
export const usePagination = <T extends string>(
initialOrderBy: T,
{
initPerPage = 100
initPerPage = 100,
initSearch = ""
}: {
initPerPage?: number;
initSearch?: string;
} = {}
) => {
const [page, setPage] = useState(1);
const [perPage, setPerPage] = useState(initPerPage);
const [orderDirection, setOrderDirection] = useState(OrderByDirection.ASC);
const [orderBy, setOrderBy] = useState<T>(initialOrderBy);
const [search, setSearch] = useState("");
const [search, setSearch] = useState(initSearch);
const [debouncedSearch] = useDebounce(search);
const offset = (page - 1) * perPage;