mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 05:19:49 +00:00
Merge branch 'main' into feat/point-in-time-revamp
This commit is contained in:
@@ -21,6 +21,7 @@ export const useCreateAccessApprovalPolicy = () => {
|
||||
projectSlug,
|
||||
approvals,
|
||||
approvers,
|
||||
bypassers,
|
||||
name,
|
||||
secretPath,
|
||||
enforcementLevel,
|
||||
@@ -30,6 +31,7 @@ export const useCreateAccessApprovalPolicy = () => {
|
||||
environment,
|
||||
projectSlug,
|
||||
approvals,
|
||||
bypassers,
|
||||
approvers,
|
||||
secretPath,
|
||||
name,
|
||||
@@ -53,6 +55,7 @@ export const useUpdateAccessApprovalPolicy = () => {
|
||||
mutationFn: async ({
|
||||
id,
|
||||
approvers,
|
||||
bypassers,
|
||||
approvals,
|
||||
name,
|
||||
secretPath,
|
||||
@@ -62,6 +65,7 @@ export const useUpdateAccessApprovalPolicy = () => {
|
||||
const { data } = await apiRequest.patch(`/api/v1/access-approvals/policies/${id}`, {
|
||||
approvals,
|
||||
approvers,
|
||||
bypassers,
|
||||
secretPath,
|
||||
name,
|
||||
enforcementLevel,
|
||||
|
||||
@@ -16,6 +16,7 @@ export type TAccessApprovalPolicy = {
|
||||
enforcementLevel: EnforcementLevel;
|
||||
updatedAt: Date;
|
||||
approvers?: Approver[];
|
||||
bypassers?: Bypasser[];
|
||||
allowedSelfApprovals: boolean;
|
||||
};
|
||||
|
||||
@@ -24,11 +25,21 @@ export enum ApproverType {
|
||||
Group = "group"
|
||||
}
|
||||
|
||||
export enum BypasserType {
|
||||
User = "user",
|
||||
Group = "group"
|
||||
}
|
||||
|
||||
export type Approver = {
|
||||
id: string;
|
||||
type: ApproverType;
|
||||
};
|
||||
|
||||
export type Bypasser = {
|
||||
id: string;
|
||||
type: BypasserType;
|
||||
};
|
||||
|
||||
export type TAccessApprovalRequest = {
|
||||
id: string;
|
||||
policyId: string;
|
||||
@@ -68,6 +79,7 @@ export type TAccessApprovalRequest = {
|
||||
name: string;
|
||||
approvals: number;
|
||||
approvers: string[];
|
||||
bypassers: string[];
|
||||
secretPath?: string | null;
|
||||
envId: string;
|
||||
enforcementLevel: EnforcementLevel;
|
||||
@@ -146,6 +158,7 @@ export type TCreateAccessPolicyDTO = {
|
||||
name?: string;
|
||||
environment: string;
|
||||
approvers?: Approver[];
|
||||
bypassers?: Bypasser[];
|
||||
approvals?: number;
|
||||
secretPath?: string;
|
||||
enforcementLevel?: EnforcementLevel;
|
||||
@@ -156,6 +169,7 @@ export type TUpdateAccessPolicyDTO = {
|
||||
id: string;
|
||||
name?: string;
|
||||
approvers?: Approver[];
|
||||
bypassers?: Bypasser[];
|
||||
secretPath?: string;
|
||||
environment?: string;
|
||||
approvals?: number;
|
||||
|
||||
@@ -1,16 +1,2 @@
|
||||
export {
|
||||
useAdminDeleteUser,
|
||||
useAdminGrantServerAdminAccess,
|
||||
useAdminRemoveIdentitySuperAdminAccess,
|
||||
useCreateAdminUser,
|
||||
useInvalidateCache,
|
||||
useRemoveUserServerAdminAccess,
|
||||
useUpdateServerConfig,
|
||||
useUpdateServerEncryptionStrategy
|
||||
} from "./mutation";
|
||||
export {
|
||||
useAdminGetUsers,
|
||||
useGetAdminIntegrationsConfig,
|
||||
useGetServerConfig,
|
||||
useGetServerRootKmsEncryptionDetails
|
||||
} from "./queries";
|
||||
export * from "./mutation";
|
||||
export * from "./queries";
|
||||
|
||||
@@ -63,6 +63,41 @@ export const useAdminDeleteUser = () => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: [adminStandaloneKeys.getUsers]
|
||||
});
|
||||
queryClient.invalidateQueries({ queryKey: adminStandaloneKeys.getOrganizations });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useAdminDeleteOrganizationMembership = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation<object, object, { organizationId: string; membershipId: string }>({
|
||||
mutationFn: async ({ organizationId, membershipId }) => {
|
||||
await apiRequest.delete(
|
||||
`/api/v1/admin/organization-management/organizations/${organizationId}/memberships/${membershipId}`
|
||||
);
|
||||
|
||||
return {};
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: [adminStandaloneKeys.getOrganizations]
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useAdminDeleteOrganization = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: async (organizationId: string) => {
|
||||
await apiRequest.delete(
|
||||
`/api/v1/admin/organization-management/organizations/${organizationId}`
|
||||
);
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: [adminStandaloneKeys.getOrganizations]
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -6,8 +6,10 @@ import { Identity } from "@app/hooks/api/identities/types";
|
||||
import { User } from "../types";
|
||||
import {
|
||||
AdminGetIdentitiesFilters,
|
||||
AdminGetOrganizationsFilters,
|
||||
AdminGetUsersFilters,
|
||||
AdminIntegrationsConfig,
|
||||
OrganizationWithProjects,
|
||||
TGetInvalidatingCacheStatus,
|
||||
TGetServerRootKmsEncryptionDetails,
|
||||
TServerConfig
|
||||
@@ -15,12 +17,15 @@ import {
|
||||
|
||||
export const adminStandaloneKeys = {
|
||||
getUsers: "get-users",
|
||||
getOrganizations: "get-organizations",
|
||||
getIdentities: "get-identities"
|
||||
};
|
||||
|
||||
export const adminQueryKeys = {
|
||||
serverConfig: () => ["server-config"] as const,
|
||||
getUsers: (filters: AdminGetUsersFilters) => [adminStandaloneKeys.getUsers, { filters }] as const,
|
||||
getOrganizations: (filters: AdminGetOrganizationsFilters) =>
|
||||
[adminStandaloneKeys.getOrganizations, { filters }] as const,
|
||||
getIdentities: (filters: AdminGetIdentitiesFilters) =>
|
||||
[adminStandaloneKeys.getIdentities, { filters }] as const,
|
||||
getAdminSlackConfig: () => ["admin-slack-config"] as const,
|
||||
@@ -34,6 +39,28 @@ export const fetchServerConfig = async () => {
|
||||
return data.config;
|
||||
};
|
||||
|
||||
export const useAdminGetOrganizations = (filters: AdminGetOrganizationsFilters) => {
|
||||
return useInfiniteQuery({
|
||||
initialPageParam: 0,
|
||||
queryKey: adminQueryKeys.getOrganizations(filters),
|
||||
queryFn: async ({ pageParam }) => {
|
||||
const { data } = await apiRequest.get<{ organizations: OrganizationWithProjects[] }>(
|
||||
"/api/v1/admin/organization-management/organizations",
|
||||
{
|
||||
params: {
|
||||
...filters,
|
||||
offset: pageParam
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return data.organizations;
|
||||
},
|
||||
getNextPageParam: (lastPage, pages) =>
|
||||
lastPage.length !== 0 ? pages.length * filters.limit : undefined
|
||||
});
|
||||
};
|
||||
|
||||
export const useGetServerConfig = ({
|
||||
options = {}
|
||||
}: {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { Organization } from "../types";
|
||||
|
||||
export enum LoginMethod {
|
||||
EMAIL = "email",
|
||||
GOOGLE = "google",
|
||||
@@ -8,6 +10,27 @@ export enum LoginMethod {
|
||||
OIDC = "oidc"
|
||||
}
|
||||
|
||||
export type OrganizationWithProjects = Organization & {
|
||||
members: {
|
||||
user: {
|
||||
id: string;
|
||||
email: string | null;
|
||||
username: string;
|
||||
firstName: string | null;
|
||||
lastName: string | null;
|
||||
};
|
||||
membershipId: string;
|
||||
role: string;
|
||||
roleId: string | null;
|
||||
}[];
|
||||
projects: {
|
||||
name: string;
|
||||
id: string;
|
||||
slug: string;
|
||||
createdAt: string;
|
||||
}[];
|
||||
};
|
||||
|
||||
export type TServerConfig = {
|
||||
initialized: boolean;
|
||||
allowSignUp: boolean;
|
||||
@@ -51,6 +74,11 @@ export type TCreateAdminUserDTO = {
|
||||
salt: string;
|
||||
};
|
||||
|
||||
export type AdminGetOrganizationsFilters = {
|
||||
limit: number;
|
||||
searchTerm: string;
|
||||
};
|
||||
|
||||
export type AdminGetUsersFilters = {
|
||||
limit: number;
|
||||
searchTerm: string;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export enum AppConnection {
|
||||
AWS = "aws",
|
||||
GitHub = "github",
|
||||
GitHubRadar = "github-radar",
|
||||
GCP = "gcp",
|
||||
AzureKeyVault = "azure-key-vault",
|
||||
AzureAppConfiguration = "azure-app-configuration",
|
||||
@@ -11,6 +12,7 @@ export enum AppConnection {
|
||||
Vercel = "vercel",
|
||||
Postgres = "postgres",
|
||||
MsSql = "mssql",
|
||||
MySql = "mysql",
|
||||
Camunda = "camunda",
|
||||
Windmill = "windmill",
|
||||
Auth0 = "auth0",
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
@@ -60,6 +65,10 @@ export type TMsSqlConnectionOption = TAppConnectionOptionBase & {
|
||||
app: AppConnection.MsSql;
|
||||
};
|
||||
|
||||
export type TMySqlConnectionOption = TAppConnectionOptionBase & {
|
||||
app: AppConnection.MySql;
|
||||
};
|
||||
|
||||
export type TCamundaConnectionOption = TAppConnectionOptionBase & {
|
||||
app: AppConnection.Camunda;
|
||||
};
|
||||
@@ -105,6 +114,7 @@ export type TAppConnectionOption =
|
||||
| TVercelConnectionOption
|
||||
| TPostgresConnectionOption
|
||||
| TMsSqlConnectionOption
|
||||
| TMySqlConnectionOption
|
||||
| TCamundaConnectionOption
|
||||
| TWindmillConnectionOption
|
||||
| TAuth0ConnectionOption
|
||||
@@ -116,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;
|
||||
@@ -126,6 +137,7 @@ export type TAppConnectionOptionMap = {
|
||||
[AppConnection.Vercel]: TVercelConnectionOption;
|
||||
[AppConnection.Postgres]: TPostgresConnectionOption;
|
||||
[AppConnection.MsSql]: TMsSqlConnectionOption;
|
||||
[AppConnection.MySql]: TMySqlConnectionOption;
|
||||
[AppConnection.Camunda]: TCamundaConnectionOption;
|
||||
[AppConnection.Windmill]: TWindmillConnectionOption;
|
||||
[AppConnection.Auth0]: TAuth0ConnectionOption;
|
||||
|
||||
@@ -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,10 +10,12 @@ 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";
|
||||
import { TMsSqlConnection } from "./mssql-connection";
|
||||
import { TMySqlConnection } from "./mysql-connection";
|
||||
import { TOCIConnection } from "./oci-connection";
|
||||
import { TPostgresConnection } from "./postgres-connection";
|
||||
import { TTeamCityConnection } from "./teamcity-connection";
|
||||
@@ -31,10 +33,12 @@ 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";
|
||||
export * from "./mssql-connection";
|
||||
export * from "./mysql-connection";
|
||||
export * from "./oci-connection";
|
||||
export * from "./postgres-connection";
|
||||
export * from "./teamcity-connection";
|
||||
@@ -45,6 +49,7 @@ export * from "./windmill-connection";
|
||||
export type TAppConnection =
|
||||
| TAwsConnection
|
||||
| TGitHubConnection
|
||||
| TGitHubRadarConnection
|
||||
| TGcpConnection
|
||||
| TAzureKeyVaultConnection
|
||||
| TAzureAppConfigurationConnection
|
||||
@@ -55,6 +60,7 @@ export type TAppConnection =
|
||||
| TVercelConnection
|
||||
| TPostgresConnection
|
||||
| TMsSqlConnection
|
||||
| TMySqlConnection
|
||||
| TCamundaConnection
|
||||
| TWindmillConnection
|
||||
| TAuth0Connection
|
||||
@@ -92,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;
|
||||
@@ -102,6 +109,7 @@ export type TAppConnectionMap = {
|
||||
[AppConnection.Vercel]: TVercelConnection;
|
||||
[AppConnection.Postgres]: TPostgresConnection;
|
||||
[AppConnection.MsSql]: TMsSqlConnection;
|
||||
[AppConnection.MySql]: TMySqlConnection;
|
||||
[AppConnection.Camunda]: TCamundaConnection;
|
||||
[AppConnection.Windmill]: TWindmillConnection;
|
||||
[AppConnection.Auth0]: TAuth0Connection;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { AppConnection } from "@app/hooks/api/appConnections/enums";
|
||||
import { TRootAppConnection } from "@app/hooks/api/appConnections/types/root-connection";
|
||||
|
||||
import { TBaseSqlConnectionCredentials } from "./shared";
|
||||
|
||||
export enum MySqlConnectionMethod {
|
||||
UsernameAndPassword = "username-and-password"
|
||||
}
|
||||
|
||||
export type TMySqlConnection = TRootAppConnection & { app: AppConnection.MySql } & {
|
||||
method: MySqlConnectionMethod.UsernameAndPassword;
|
||||
credentials: TBaseSqlConnectionCredentials;
|
||||
};
|
||||
@@ -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",
|
||||
|
||||
@@ -31,10 +31,14 @@ export const useUpdateCa = () => {
|
||||
|
||||
return data;
|
||||
},
|
||||
onSuccess: ({ projectId, type }) => {
|
||||
onSuccess: ({ projectId, type }, { caName }) => {
|
||||
caKeys.getCaByNameAndProjectId(caName, projectId);
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: caKeys.listCasByTypeAndProjectId(type, projectId)
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: caKeys.getCaByNameAndProjectId(caName, projectId)
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
export {
|
||||
useCreateCertTemplate,
|
||||
useCreateCertTemplateV2,
|
||||
useCreateEstConfig,
|
||||
useDeleteCertTemplate,
|
||||
useDeleteCertTemplateV2,
|
||||
useUpdateCertTemplate,
|
||||
useUpdateCertTemplateV2,
|
||||
useUpdateEstConfig
|
||||
} from "./mutations";
|
||||
export { useGetCertTemplate, useGetEstConfig } from "./queries";
|
||||
export { useGetCertTemplate, useGetEstConfig, useListCertificateTemplates } from "./queries";
|
||||
|
||||
@@ -8,9 +8,12 @@ import { certTemplateKeys } from "./queries";
|
||||
import {
|
||||
TCertificateTemplate,
|
||||
TCreateCertificateTemplateDTO,
|
||||
TCreateCertificateTemplateV2DTO,
|
||||
TCreateEstConfigDTO,
|
||||
TDeleteCertificateTemplateDTO,
|
||||
TDeleteCertificateTemplateV2DTO,
|
||||
TUpdateCertificateTemplateDTO,
|
||||
TUpdateCertificateTemplateV2DTO,
|
||||
TUpdateEstConfigDTO
|
||||
} from "./types";
|
||||
|
||||
@@ -73,6 +76,58 @@ export const useDeleteCertTemplate = () => {
|
||||
});
|
||||
};
|
||||
|
||||
export const useCreateCertTemplateV2 = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation<TCertificateTemplate, object, TCreateCertificateTemplateV2DTO>({
|
||||
mutationFn: async (dto) => {
|
||||
const { data } = await apiRequest.post<{
|
||||
certificateTemplate: TCertificateTemplate;
|
||||
}>("/api/v2/pki/certificate-templates", dto);
|
||||
return data.certificateTemplate;
|
||||
},
|
||||
onSuccess: (_, { projectId }) => {
|
||||
queryClient.invalidateQueries({ queryKey: certTemplateKeys.listTemplates({ projectId }) });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateCertTemplateV2 = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation<TCertificateTemplate, object, TUpdateCertificateTemplateV2DTO>({
|
||||
mutationFn: async (dto) => {
|
||||
const { data } = await apiRequest.patch<{ certificateTemplate: TCertificateTemplate }>(
|
||||
`/api/v2/pki/certificate-templates/${dto.templateName}`,
|
||||
dto
|
||||
);
|
||||
|
||||
return data.certificateTemplate;
|
||||
},
|
||||
onSuccess: (_, { projectId }) => {
|
||||
queryClient.invalidateQueries({ queryKey: certTemplateKeys.listTemplates({ projectId }) });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useDeleteCertTemplateV2 = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation<TCertificateTemplate, object, TDeleteCertificateTemplateV2DTO>({
|
||||
mutationFn: async (dto) => {
|
||||
const { data } = await apiRequest.delete<{ certificateTemplate: TCertificateTemplate }>(
|
||||
`/api/v2/pki/certificate-templates/${dto.templateName}`,
|
||||
{
|
||||
data: {
|
||||
projectId: dto.projectId
|
||||
}
|
||||
}
|
||||
);
|
||||
return data.certificateTemplate;
|
||||
},
|
||||
onSuccess: (_, { projectId }) => {
|
||||
queryClient.invalidateQueries({ queryKey: certTemplateKeys.listTemplates({ projectId }) });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useCreateEstConfig = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation<object, object, TCreateEstConfigDTO>({
|
||||
|
||||
@@ -2,10 +2,20 @@ import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
import { apiRequest } from "@app/config/request";
|
||||
|
||||
import { TCertificateTemplate, TEstConfig } from "./types";
|
||||
import {
|
||||
TCertificateTemplate,
|
||||
TCertificateTemplateV2,
|
||||
TEstConfig,
|
||||
TListCertificateTemplatesDTO
|
||||
} from "./types";
|
||||
|
||||
export const certTemplateKeys = {
|
||||
getCertTemplateById: (id: string) => [{ id }, "cert-template"],
|
||||
listTemplates: ({ projectId, ...el }: { limit?: number; offset?: number; projectId: string }) => [
|
||||
"list-template",
|
||||
projectId,
|
||||
el
|
||||
],
|
||||
getEstConfig: (id: string) => [{ id }, "cert-template-est-config"]
|
||||
};
|
||||
|
||||
@@ -22,6 +32,29 @@ export const useGetCertTemplate = (id: string) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const useListCertificateTemplates = ({
|
||||
limit = 100,
|
||||
offset = 0,
|
||||
projectId
|
||||
}: TListCertificateTemplatesDTO) => {
|
||||
return useQuery({
|
||||
queryKey: certTemplateKeys.listTemplates({ limit, offset, projectId }),
|
||||
queryFn: async () => {
|
||||
const { data } = await apiRequest.get<{
|
||||
certificateTemplates: TCertificateTemplateV2[];
|
||||
totalCount?: number;
|
||||
}>("/api/v2/pki/certificate-templates", {
|
||||
params: {
|
||||
limit,
|
||||
offset,
|
||||
projectId
|
||||
}
|
||||
});
|
||||
return data;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useGetEstConfig = (certificateTemplateId: string) => {
|
||||
return useQuery({
|
||||
queryKey: certTemplateKeys.getEstConfig(certificateTemplateId),
|
||||
|
||||
@@ -14,6 +14,26 @@ export type TCertificateTemplate = {
|
||||
extendedKeyUsages: CertExtendedKeyUsage[];
|
||||
};
|
||||
|
||||
export type TCertificateTemplateV2 = {
|
||||
id: string;
|
||||
caId: string;
|
||||
caName: string;
|
||||
projectId: string;
|
||||
pkiCollectionId?: string;
|
||||
name: string;
|
||||
commonName: string;
|
||||
subjectAlternativeName: string;
|
||||
ttl: string;
|
||||
keyUsages: CertKeyUsage[];
|
||||
extendedKeyUsages: CertExtendedKeyUsage[];
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
ca: {
|
||||
name: string;
|
||||
id: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type TCreateCertificateTemplateDTO = {
|
||||
caId: string;
|
||||
pkiCollectionId?: string;
|
||||
@@ -44,6 +64,34 @@ export type TDeleteCertificateTemplateDTO = {
|
||||
projectId: string;
|
||||
};
|
||||
|
||||
export type TCreateCertificateTemplateV2DTO = {
|
||||
caName: string;
|
||||
name: string;
|
||||
commonName: string;
|
||||
subjectAlternativeName: string;
|
||||
ttl: string;
|
||||
projectId: string;
|
||||
keyUsages: CertKeyUsage[];
|
||||
extendedKeyUsages: CertExtendedKeyUsage[];
|
||||
};
|
||||
|
||||
export type TUpdateCertificateTemplateV2DTO = {
|
||||
templateName: string;
|
||||
caName?: string;
|
||||
name?: string;
|
||||
commonName?: string;
|
||||
subjectAlternativeName?: string;
|
||||
ttl?: string;
|
||||
projectId: string;
|
||||
keyUsages?: CertKeyUsage[];
|
||||
extendedKeyUsages?: CertExtendedKeyUsage[];
|
||||
};
|
||||
|
||||
export type TDeleteCertificateTemplateV2DTO = {
|
||||
templateName: string;
|
||||
projectId: string;
|
||||
};
|
||||
|
||||
export type TCreateEstConfigDTO = {
|
||||
certificateTemplateId: string;
|
||||
caChain?: string;
|
||||
@@ -67,3 +115,9 @@ export type TEstConfig = {
|
||||
isEnabled: boolean;
|
||||
disableBootstrapCertValidation: boolean;
|
||||
};
|
||||
|
||||
export type TListCertificateTemplatesDTO = {
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
projectId: string;
|
||||
};
|
||||
|
||||
@@ -13,6 +13,7 @@ export type TDynamicSecret = {
|
||||
status?: DynamicSecretStatus;
|
||||
statusDetails?: string;
|
||||
maxTTL: string;
|
||||
usernameTemplate?: string | null;
|
||||
metadata?: { key: string; value: string }[];
|
||||
};
|
||||
|
||||
@@ -31,7 +32,9 @@ export enum DynamicSecretProviders {
|
||||
SapHana = "sap-hana",
|
||||
Snowflake = "snowflake",
|
||||
Totp = "totp",
|
||||
SapAse = "sap-ase"
|
||||
SapAse = "sap-ase",
|
||||
Kubernetes = "kubernetes",
|
||||
Vertica = "vertica"
|
||||
}
|
||||
|
||||
export enum SqlProviders {
|
||||
@@ -261,6 +264,32 @@ export type TDynamicSecretProvider =
|
||||
algorithm?: string;
|
||||
digits?: number;
|
||||
};
|
||||
}
|
||||
| {
|
||||
type: DynamicSecretProviders.Kubernetes;
|
||||
inputs: {
|
||||
url: string;
|
||||
clusterToken: string;
|
||||
ca?: string;
|
||||
serviceAccountName: string;
|
||||
credentialType: "dynamic" | "static";
|
||||
namespace: string;
|
||||
gatewayId?: string;
|
||||
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 = {
|
||||
@@ -272,6 +301,7 @@ export type TCreateDynamicSecretDTO = {
|
||||
environmentSlug: string;
|
||||
name: string;
|
||||
metadata?: { key: string; value: string }[];
|
||||
usernameTemplate?: string;
|
||||
};
|
||||
|
||||
export type TUpdateDynamicSecretDTO = {
|
||||
@@ -285,6 +315,7 @@ export type TUpdateDynamicSecretDTO = {
|
||||
defaultTTL?: string;
|
||||
maxTTL?: string | null;
|
||||
inputs?: unknown;
|
||||
usernameTemplate?: string | null;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -843,7 +843,8 @@ export const useAddIdentityKubernetesAuth = () => {
|
||||
accessTokenMaxTTL,
|
||||
accessTokenNumUsesLimit,
|
||||
accessTokenTrustedIps,
|
||||
gatewayId
|
||||
gatewayId,
|
||||
tokenReviewMode
|
||||
}) => {
|
||||
const {
|
||||
data: { identityKubernetesAuth }
|
||||
@@ -860,7 +861,8 @@ export const useAddIdentityKubernetesAuth = () => {
|
||||
accessTokenMaxTTL,
|
||||
accessTokenNumUsesLimit,
|
||||
accessTokenTrustedIps,
|
||||
gatewayId
|
||||
gatewayId,
|
||||
tokenReviewMode
|
||||
}
|
||||
);
|
||||
|
||||
@@ -950,7 +952,8 @@ export const useUpdateIdentityKubernetesAuth = () => {
|
||||
accessTokenMaxTTL,
|
||||
accessTokenNumUsesLimit,
|
||||
accessTokenTrustedIps,
|
||||
gatewayId
|
||||
gatewayId,
|
||||
tokenReviewMode
|
||||
}) => {
|
||||
const {
|
||||
data: { identityKubernetesAuth }
|
||||
@@ -967,7 +970,8 @@ export const useUpdateIdentityKubernetesAuth = () => {
|
||||
accessTokenMaxTTL,
|
||||
accessTokenNumUsesLimit,
|
||||
accessTokenTrustedIps,
|
||||
gatewayId
|
||||
gatewayId,
|
||||
tokenReviewMode
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -379,10 +379,16 @@ export type DeleteIdentityAzureAuthDTO = {
|
||||
identityId: string;
|
||||
};
|
||||
|
||||
export enum IdentityKubernetesAuthTokenReviewMode {
|
||||
Api = "api",
|
||||
Gateway = "gateway"
|
||||
}
|
||||
|
||||
export type IdentityKubernetesAuth = {
|
||||
identityId: string;
|
||||
kubernetesHost: string;
|
||||
tokenReviewerJwt: string;
|
||||
tokenReviewMode: IdentityKubernetesAuthTokenReviewMode;
|
||||
allowedNamespaces: string;
|
||||
allowedNames: string;
|
||||
allowedAudience: string;
|
||||
@@ -399,6 +405,7 @@ export type AddIdentityKubernetesAuthDTO = {
|
||||
identityId: string;
|
||||
kubernetesHost: string;
|
||||
tokenReviewerJwt?: string;
|
||||
tokenReviewMode: IdentityKubernetesAuthTokenReviewMode;
|
||||
allowedNamespaces: string;
|
||||
allowedNames: string;
|
||||
allowedAudience: string;
|
||||
@@ -417,6 +424,7 @@ export type UpdateIdentityKubernetesAuthDTO = {
|
||||
identityId: string;
|
||||
kubernetesHost?: string;
|
||||
tokenReviewerJwt?: string | null;
|
||||
tokenReviewMode?: IdentityKubernetesAuthTokenReviewMode;
|
||||
allowedNamespaces?: string;
|
||||
allowedNames?: string;
|
||||
allowedAudience?: string;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -96,7 +96,7 @@ export const useUpdateOrgRole = () => {
|
||||
data: { role }
|
||||
} = await apiRequest.patch(`/api/v1/organization/${orgId}/roles/${id}`, {
|
||||
...dto,
|
||||
permissions: permissions?.length ? packRules(permissions) : undefined
|
||||
permissions: permissions ? packRules(permissions) : undefined
|
||||
});
|
||||
|
||||
return role;
|
||||
|
||||
@@ -14,6 +14,7 @@ export const useCreateSecretApprovalPolicy = () => {
|
||||
workspaceId,
|
||||
approvals,
|
||||
approvers,
|
||||
bypassers,
|
||||
secretPath,
|
||||
name,
|
||||
enforcementLevel,
|
||||
@@ -24,6 +25,7 @@ export const useCreateSecretApprovalPolicy = () => {
|
||||
workspaceId,
|
||||
approvals,
|
||||
approvers,
|
||||
bypassers,
|
||||
secretPath,
|
||||
name,
|
||||
enforcementLevel,
|
||||
@@ -46,6 +48,7 @@ export const useUpdateSecretApprovalPolicy = () => {
|
||||
mutationFn: async ({
|
||||
id,
|
||||
approvers,
|
||||
bypassers,
|
||||
approvals,
|
||||
secretPath,
|
||||
name,
|
||||
@@ -55,6 +58,7 @@ export const useUpdateSecretApprovalPolicy = () => {
|
||||
const { data } = await apiRequest.patch(`/api/v1/secret-approvals/${id}`, {
|
||||
approvals,
|
||||
approvers,
|
||||
bypassers,
|
||||
secretPath,
|
||||
name,
|
||||
enforcementLevel,
|
||||
|
||||
@@ -25,6 +25,16 @@ export type Approver = {
|
||||
type: ApproverType;
|
||||
};
|
||||
|
||||
export enum BypasserType {
|
||||
User = "user",
|
||||
Group = "group"
|
||||
}
|
||||
|
||||
export type Bypasser = {
|
||||
id: string;
|
||||
type: BypasserType;
|
||||
};
|
||||
|
||||
export type TGetSecretApprovalPoliciesDTO = {
|
||||
workspaceId: string;
|
||||
};
|
||||
@@ -41,6 +51,7 @@ export type TCreateSecretPolicyDTO = {
|
||||
environment: string;
|
||||
secretPath?: string | null;
|
||||
approvers?: Approver[];
|
||||
bypassers?: Bypasser[];
|
||||
approvals?: number;
|
||||
enforcementLevel: EnforcementLevel;
|
||||
allowedSelfApprovals: boolean;
|
||||
@@ -50,6 +61,7 @@ export type TUpdateSecretPolicyDTO = {
|
||||
id: string;
|
||||
name?: string;
|
||||
approvers?: Approver[];
|
||||
bypassers?: Bypasser[];
|
||||
secretPath?: string | null;
|
||||
approvals?: number;
|
||||
allowedSelfApprovals?: boolean;
|
||||
|
||||
@@ -58,7 +58,7 @@ export type TSecretApprovalRequest = {
|
||||
secretPath: string;
|
||||
hasMerged: boolean;
|
||||
status: "open" | "close";
|
||||
policy: Omit<TSecretApprovalPolicy, "approvers"> & {
|
||||
policy: Omit<TSecretApprovalPolicy, "approvers" | "bypassers"> & {
|
||||
approvers: {
|
||||
userId: string;
|
||||
email: string;
|
||||
@@ -66,6 +66,13 @@ export type TSecretApprovalRequest = {
|
||||
lastName: string;
|
||||
username: string;
|
||||
}[];
|
||||
bypassers: {
|
||||
userId: string;
|
||||
email: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
username: string;
|
||||
}[];
|
||||
};
|
||||
statusChangedByUserId: string;
|
||||
statusChangedByUser?: {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export enum SecretRotation {
|
||||
PostgresCredentials = "postgres-credentials",
|
||||
MsSqlCredentials = "mssql-credentials",
|
||||
MySqlCredentials = "mysql-credentials",
|
||||
Auth0ClientSecret = "auth0-client-secret",
|
||||
AzureClientSecret = "azure-client-secret",
|
||||
LdapPassword = "ldap-password",
|
||||
|
||||
@@ -31,9 +31,15 @@ import { TSqlCredentialsRotationOption } from "@app/hooks/api/secretRotationsV2/
|
||||
import { SecretV3RawSanitized } from "@app/hooks/api/secrets/types";
|
||||
import { DiscriminativePick } from "@app/types";
|
||||
|
||||
import {
|
||||
TMySqlCredentialsRotation,
|
||||
TMySqlCredentialsRotationGeneratedCredentialsResponse
|
||||
} from "./mysql-credentials-rotation";
|
||||
|
||||
export type TSecretRotationV2 = (
|
||||
| TPostgresCredentialsRotation
|
||||
| TMsSqlCredentialsRotation
|
||||
| TMySqlCredentialsRotation
|
||||
| TAuth0ClientSecretRotation
|
||||
| TAzureClientSecretRotation
|
||||
| TLdapPasswordRotation
|
||||
@@ -56,6 +62,7 @@ export type TSecretRotationV2Response = { secretRotation: TSecretRotationV2 };
|
||||
export type TViewSecretRotationGeneratedCredentialsResponse =
|
||||
| TPostgresCredentialsRotationGeneratedCredentialsResponse
|
||||
| TMsSqlCredentialsRotationGeneratedCredentialsResponse
|
||||
| TMySqlCredentialsRotationGeneratedCredentialsResponse
|
||||
| TAuth0ClientSecretRotationGeneratedCredentialsResponse
|
||||
| TAzureClientSecretRotationGeneratedCredentialsResponse
|
||||
| TLdapPasswordRotationGeneratedCredentialsResponse
|
||||
@@ -105,6 +112,7 @@ export type TViewSecretRotationV2GeneratedCredentialsDTO = {
|
||||
export type TSecretRotationOptionMap = {
|
||||
[SecretRotation.PostgresCredentials]: TSqlCredentialsRotationOption;
|
||||
[SecretRotation.MsSqlCredentials]: TSqlCredentialsRotationOption;
|
||||
[SecretRotation.MySqlCredentials]: TSqlCredentialsRotationOption;
|
||||
[SecretRotation.Auth0ClientSecret]: TAuth0ClientSecretRotationOption;
|
||||
[SecretRotation.AzureClientSecret]: TAzureClientSecretRotationOption;
|
||||
[SecretRotation.LdapPassword]: TLdapPasswordRotationOption;
|
||||
@@ -114,6 +122,7 @@ export type TSecretRotationOptionMap = {
|
||||
export type TSecretRotationGeneratedCredentialsResponseMap = {
|
||||
[SecretRotation.PostgresCredentials]: TPostgresCredentialsRotationGeneratedCredentialsResponse;
|
||||
[SecretRotation.MsSqlCredentials]: TMsSqlCredentialsRotationGeneratedCredentialsResponse;
|
||||
[SecretRotation.MySqlCredentials]: TMySqlCredentialsRotationGeneratedCredentialsResponse;
|
||||
[SecretRotation.Auth0ClientSecret]: TAuth0ClientSecretRotationGeneratedCredentialsResponse;
|
||||
[SecretRotation.AzureClientSecret]: TAzureClientSecretRotationGeneratedCredentialsResponse;
|
||||
[SecretRotation.LdapPassword]: TLdapPasswordRotationGeneratedCredentialsResponse;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { SecretRotation } from "@app/hooks/api/secretRotationsV2";
|
||||
import {
|
||||
TSecretRotationV2Base,
|
||||
TSecretRotationV2GeneratedCredentialsResponseBase,
|
||||
TSqlCredentialsRotationGeneratedCredentials,
|
||||
TSqlCredentialsRotationProperties
|
||||
} from "@app/hooks/api/secretRotationsV2/types/shared";
|
||||
|
||||
export type TMySqlCredentialsRotation = TSecretRotationV2Base & {
|
||||
type: SecretRotation.MySqlCredentials;
|
||||
} & TSqlCredentialsRotationProperties;
|
||||
|
||||
export type TMySqlCredentialsRotationGeneratedCredentialsResponse =
|
||||
TSecretRotationV2GeneratedCredentialsResponseBase<
|
||||
SecretRotation.MySqlCredentials,
|
||||
TSqlCredentialsRotationGeneratedCredentials
|
||||
>;
|
||||
@@ -14,8 +14,11 @@ export type TSqlCredentialsRotationProperties = {
|
||||
|
||||
export type TSqlCredentialsRotationOption = {
|
||||
name: string;
|
||||
type: SecretRotation.PostgresCredentials | SecretRotation.MsSqlCredentials;
|
||||
connection: AppConnection.Postgres | AppConnection.MsSql;
|
||||
type:
|
||||
| SecretRotation.PostgresCredentials
|
||||
| SecretRotation.MsSqlCredentials
|
||||
| SecretRotation.MySqlCredentials;
|
||||
connection: AppConnection.Postgres | AppConnection.MsSql | AppConnection.MySql;
|
||||
template: {
|
||||
secretsMapping: TSqlCredentialsRotationProperties["secretsMapping"];
|
||||
createUserStatement: string;
|
||||
|
||||
@@ -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";
|
||||
+18
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user