merge main

This commit is contained in:
Scott Wilson
2025-06-02 16:24:55 -07:00
722 changed files with 30947 additions and 13097 deletions
@@ -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,
@@ -131,20 +135,27 @@ export const useReviewAccessRequest = () => {
projectSlug: string;
envSlug?: string;
requestedBy?: string;
bypassReason?: string;
}
>({
mutationFn: async ({ requestId, status }) => {
mutationFn: async ({ requestId, status, bypassReason }) => {
const { data } = await apiRequest.post(
`/api/v1/access-approvals/requests/${requestId}/review`,
{
status
status,
bypassReason
}
);
return data;
},
onSuccess: (_, { projectSlug, envSlug, requestedBy }) => {
onSuccess: (_, { projectSlug, envSlug, requestedBy, bypassReason }) => {
queryClient.invalidateQueries({
queryKey: accessApprovalKeys.getAccessApprovalRequests(projectSlug, envSlug, requestedBy)
queryKey: accessApprovalKeys.getAccessApprovalRequests(
projectSlug,
envSlug,
requestedBy,
bypassReason
)
});
queryClient.invalidateQueries({
queryKey: accessApprovalKeys.getAccessApprovalRequestCount(projectSlug)
@@ -19,8 +19,12 @@ export const accessApprovalKeys = {
getAccessApprovalPolicyOfABoard: (workspaceId: string, environment: string) =>
[{ workspaceId, environment }, "access-approval-policy"] as const,
getAccessApprovalRequests: (projectSlug: string, envSlug?: string, requestedBy?: string) =>
[{ projectSlug, envSlug, requestedBy }, "access-approvals-requests"] as const,
getAccessApprovalRequests: (
projectSlug: string,
envSlug?: string,
requestedBy?: string,
bypassReason?: string
) => [{ projectSlug, envSlug, requestedBy, bypassReason }, "access-approvals-requests"] as const,
getAccessApprovalRequestCount: (projectSlug: string) =>
[{ projectSlug }, "access-approval-request-count"] as const
};
@@ -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;
+2 -16
View File
@@ -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";
+35
View File
@@ -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]
});
}
});
};
+27
View File
@@ -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 = {}
}: {
+28
View File
@@ -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;
@@ -0,0 +1,2 @@
export * from "./queries";
export * from "./types";
@@ -0,0 +1,37 @@
import { useQuery, UseQueryOptions } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { appConnectionKeys } from "../queries";
import { TOnePassVault } from "./types";
const onePassConnectionKeys = {
all: [...appConnectionKeys.all, "1password"] as const,
listVaults: (connectionId: string) =>
[...onePassConnectionKeys.all, "vaults", connectionId] as const
};
export const useOnePassConnectionListVaults = (
connectionId: string,
options?: Omit<
UseQueryOptions<
TOnePassVault[],
unknown,
TOnePassVault[],
ReturnType<typeof onePassConnectionKeys.listVaults>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: onePassConnectionKeys.listVaults(connectionId),
queryFn: async () => {
const { data } = await apiRequest.get<TOnePassVault[]>(
`/api/v1/app-connections/1password/${connectionId}/vaults`
);
return data;
},
...options
});
};
@@ -0,0 +1,12 @@
export type TOnePassVault = {
id: string;
name: string;
type: string;
items: number;
attributeVersion: number;
contentVersion: number;
createdAt: string;
updatedAt: string;
};
@@ -12,11 +12,13 @@ export enum AppConnection {
Vercel = "vercel",
Postgres = "postgres",
MsSql = "mssql",
MySql = "mysql",
Camunda = "camunda",
Windmill = "windmill",
Auth0 = "auth0",
HCVault = "hashicorp-vault",
LDAP = "ldap",
TeamCity = "teamcity",
OCI = "oci"
OCI = "oci",
OnePass = "1password"
}
@@ -0,0 +1,14 @@
import { AppConnection } from "@app/hooks/api/appConnections/enums";
import { TRootAppConnection } from "@app/hooks/api/appConnections/types/root-connection";
export enum OnePassConnectionMethod {
ApiToken = "api-token"
}
export type TOnePassConnection = TRootAppConnection & { app: AppConnection.OnePass } & {
method: OnePassConnectionMethod.ApiToken;
credentials: {
apiToken: string;
instanceUrl: string;
};
};
@@ -65,6 +65,10 @@ export type TMsSqlConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.MsSql;
};
export type TMySqlConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.MySql;
};
export type TCamundaConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.Camunda;
};
@@ -93,6 +97,10 @@ export type TOCIConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.OCI;
};
export type TOnePassConnectionOption = TAppConnectionOptionBase & {
app: AppConnection.OnePass;
};
export type TAppConnectionOption =
| TAwsConnectionOption
| TGitHubConnectionOption
@@ -106,12 +114,14 @@ export type TAppConnectionOption =
| TVercelConnectionOption
| TPostgresConnectionOption
| TMsSqlConnectionOption
| TMySqlConnectionOption
| TCamundaConnectionOption
| TWindmillConnectionOption
| TAuth0ConnectionOption
| THCVaultConnectionOption
| TTeamCityConnectionOption
| TOCIConnectionOption;
| TOCIConnectionOption
| TOnePassConnectionOption;
export type TAppConnectionOptionMap = {
[AppConnection.AWS]: TAwsConnectionOption;
@@ -127,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;
@@ -134,4 +145,5 @@ export type TAppConnectionOptionMap = {
[AppConnection.LDAP]: TLdapConnectionOption;
[AppConnection.TeamCity]: TTeamCityConnectionOption;
[AppConnection.OCI]: TOCIConnectionOption;
[AppConnection.OnePass]: TOnePassConnectionOption;
};
@@ -1,4 +1,5 @@
import { AppConnection } from "../enums";
import { TOnePassConnection } from "./1password-connection";
import { TAppConnectionOption } from "./app-options";
import { TAuth0Connection } from "./auth0-connection";
import { TAwsConnection } from "./aws-connection";
@@ -14,6 +15,7 @@ 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";
@@ -21,6 +23,7 @@ import { TTerraformCloudConnection } from "./terraform-cloud-connection";
import { TVercelConnection } from "./vercel-connection";
import { TWindmillConnection } from "./windmill-connection";
export * from "./1password-connection";
export * from "./auth0-connection";
export * from "./aws-connection";
export * from "./azure-app-configuration-connection";
@@ -35,6 +38,7 @@ 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";
@@ -56,13 +60,15 @@ export type TAppConnection =
| TVercelConnection
| TPostgresConnection
| TMsSqlConnection
| TMySqlConnection
| TCamundaConnection
| TWindmillConnection
| TAuth0Connection
| THCVaultConnection
| TLdapConnection
| TTeamCityConnection
| TOCIConnection;
| TOCIConnection
| TOnePassConnection;
export type TAvailableAppConnection = Pick<TAppConnection, "name" | "id">;
@@ -103,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;
@@ -110,4 +117,5 @@ export type TAppConnectionMap = {
[AppConnection.LDAP]: TLdapConnection;
[AppConnection.TeamCity]: TTeamCityConnection;
[AppConnection.OCI]: TOCIConnection;
[AppConnection.OnePass]: TOnePassConnection;
};
@@ -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;
};
+16 -2
View File
@@ -68,6 +68,7 @@ export const eventToNameMap: { [K in EventType]: string } = {
[EventType.IMPORT_CA_CERT]: "Import CA certificate",
[EventType.GET_CA_CRL]: "Get CA CRL",
[EventType.ISSUE_CERT]: "Issue certificate",
[EventType.IMPORT_CERT]: "Import certificate",
[EventType.GET_CERT]: "Get certificate",
[EventType.DELETE_CERT]: "Delete certificate",
[EventType.REVOKE_CERT]: "Revoke certificate",
@@ -123,7 +124,6 @@ export const eventToNameMap: { [K in EventType]: string } = {
[EventType.CREATE_PROJECT_TEMPLATE]: "Create project template",
[EventType.UPDATE_PROJECT_TEMPLATE]: "Update project template",
[EventType.DELETE_PROJECT_TEMPLATE]: "Delete project template",
[EventType.APPLY_PROJECT_TEMPLATE]: "Apply project template",
[EventType.GET_APP_CONNECTIONS]: "List App Connections",
[EventType.GET_AVAILABLE_APP_CONNECTIONS_DETAILS]: "List App Connections Details",
[EventType.GET_APP_CONNECTION]: "Get App Connection",
@@ -203,7 +203,21 @@ export const eventToNameMap: { [K in EventType]: string } = {
[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.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",
[EventType.GET_PKI_SUBSCRIBER]: "Get PKI subscriber",
[EventType.ISSUE_PKI_SUBSCRIBER_CERT]: "Issue PKI subscriber certificate",
[EventType.SIGN_PKI_SUBSCRIBER_CERT]: "Sign PKI subscriber certificate",
[EventType.AUTOMATED_RENEW_SUBSCRIBER_CERT]: "Automated renew PKI subscriber certificate",
[EventType.LIST_PKI_SUBSCRIBER_CERTS]: "List PKI subscriber certificates",
[EventType.UPDATE_ORG]: "Update Organization",
[EventType.CREATE_PROJECT]: "Create Project",
[EventType.UPDATE_PROJECT]: "Update Project",
[EventType.DELETE_PROJECT]: "Delete Project"
};
export const userAgentTypeToNameMap: { [K in UserAgentType]: string } = {
+16 -2
View File
@@ -81,6 +81,7 @@ export enum EventType {
IMPORT_CA_CERT = "import-certificate-authority-cert",
GET_CA_CRL = "get-certificate-authority-crl",
ISSUE_CERT = "issue-cert",
IMPORT_CERT = "import-cert",
GET_CERT = "get-cert",
DELETE_CERT = "delete-cert",
REVOKE_CERT = "revoke-cert",
@@ -131,7 +132,6 @@ export enum EventType {
CREATE_PROJECT_TEMPLATE = "create-project-template",
UPDATE_PROJECT_TEMPLATE = "update-project-template",
DELETE_PROJECT_TEMPLATE = "delete-project-template",
APPLY_PROJECT_TEMPLATE = "apply-project-template",
GET_APP_CONNECTIONS = "get-app-connections",
GET_AVAILABLE_APP_CONNECTIONS_DETAILS = "get-available-app-connections-details",
GET_APP_CONNECTION = "get-app-connection",
@@ -197,5 +197,19 @@ export enum EventType {
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"
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",
GET_PKI_SUBSCRIBER = "get-pki-subscriber",
ISSUE_PKI_SUBSCRIBER_CERT = "issue-pki-subscriber-cert",
SIGN_PKI_SUBSCRIBER_CERT = "sign-pki-subscriber-cert",
AUTOMATED_RENEW_SUBSCRIBER_CERT = "automated-renew-subscriber-cert",
LIST_PKI_SUBSCRIBER_CERTS = "list-pki-subscriber-certs",
UPDATE_ORG = "update-org",
CREATE_PROJECT = "create-project",
UPDATE_PROJECT = "update-project",
DELETE_PROJECT = "delete-project"
}
+14 -1
View File
@@ -505,7 +505,8 @@ interface CreateCa {
type: EventType.CREATE_CA;
metadata: {
caId: string;
dn: string;
name: string;
dn?: string;
};
}
@@ -514,12 +515,14 @@ interface GetCa {
metadata: {
caId: string;
dn: string;
name: string;
};
}
interface UpdateCa {
type: EventType.UPDATE_CA;
metadata: {
name: string;
caId: string;
dn: string;
status: CaStatus;
@@ -530,6 +533,7 @@ interface DeleteCa {
type: EventType.DELETE_CA;
metadata: {
caId: string;
name: string;
dn: string;
};
}
@@ -583,6 +587,14 @@ interface IssueCert {
serialNumber: string;
};
}
interface ImportCert {
type: EventType.IMPORT_CERT;
metadata: {
certId: string;
cn: string;
serialNumber: string;
};
}
interface GetCert {
type: EventType.GET_CERT;
@@ -895,6 +907,7 @@ export type Event =
| ImportCaCert
| GetCaCrl
| IssueCert
| ImportCert
| GetCert
| DeleteCert
| RevokeCert
+4 -4
View File
@@ -1,10 +1,10 @@
import { SshCaStatus } from "../sshCa";
import { SshCertTemplateStatus } from "../sshCertificateTemplates";
import { CaStatus, CaType } from "./enums";
import { CaStatus, InternalCaType } from "./enums";
export const caTypeToNameMap: { [K in CaType]: string } = {
[CaType.ROOT]: "Root",
[CaType.INTERMEDIATE]: "Intermediate"
export const caTypeToNameMap: { [K in InternalCaType]: string } = {
[InternalCaType.ROOT]: "Root",
[InternalCaType.INTERMEDIATE]: "Intermediate"
};
export const caStatusToNameMap: { [K in CaStatus]: string } = {
+9
View File
@@ -1,4 +1,9 @@
export enum CaType {
INTERNAL = "internal",
ACME = "acme"
}
export enum InternalCaType {
ROOT = "root",
INTERMEDIATE = "intermediate"
}
@@ -12,3 +17,7 @@ export enum CaStatus {
export enum CaRenewalType {
EXISTING = "existing"
}
export enum AcmeDnsProvider {
ROUTE53 = "route53"
}
+5 -2
View File
@@ -1,4 +1,4 @@
export { CaRenewalType, CaStatus, CaType } from "./enums";
export { AcmeDnsProvider, CaRenewalType, CaStatus, CaType, InternalCaType } from "./enums";
export {
useCreateCa,
useCreateCertificate,
@@ -9,10 +9,13 @@ export {
useUpdateCa
} from "./mutations";
export {
useGetCa,
useGetCaById,
useGetCaCert,
useGetCaCerts,
useGetCaCertTemplates,
useGetCaCrls,
useGetCaCsr
useGetCaCsr,
useListCasByProjectId,
useListCasByTypeAndProjectId
} from "./queries";
+53 -32
View File
@@ -3,64 +3,82 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { workspaceKeys } from "../workspace";
import { CaType } from "./enums";
import { caKeys } from "./queries";
import {
TCertificateAuthority,
TCreateCaDTO,
TCreateCertificateAuthorityDTO,
TCreateCertificateDTO,
TCreateCertificateResponse,
TDeleteCaDTO,
TDeleteCertificateAuthorityDTO,
TImportCaCertificateDTO,
TImportCaCertificateResponse,
TRenewCaDTO,
TRenewCaResponse,
TSignIntermediateDTO,
TSignIntermediateResponse,
TUpdateCaDTO
TUnifiedCertificateAuthority,
TUpdateCertificateAuthorityDTO
} from "./types";
export const useCreateCa = () => {
export const useUpdateCa = () => {
const queryClient = useQueryClient();
return useMutation<TCertificateAuthority, object, TCreateCaDTO>({
mutationFn: async (body) => {
const {
data: { ca }
} = await apiRequest.post<{ ca: TCertificateAuthority }>("/api/v1/pki/ca/", body);
return ca;
return useMutation<TUnifiedCertificateAuthority, object, TUpdateCertificateAuthorityDTO>({
mutationFn: async ({ caName, ...body }) => {
const { data } = await apiRequest.patch<TUnifiedCertificateAuthority>(
`/api/v1/pki/ca/${body.type}/${caName}`,
body
);
return data;
},
onSuccess: (_, { projectSlug }) => {
queryClient.invalidateQueries({ queryKey: workspaceKeys.getWorkspaceCas({ projectSlug }) });
onSuccess: ({ projectId, type }, { caName }) => {
caKeys.getCaByNameAndProjectId(caName, projectId);
queryClient.invalidateQueries({
queryKey: caKeys.listCasByTypeAndProjectId(type, projectId)
});
queryClient.invalidateQueries({
queryKey: caKeys.getCaByNameAndProjectId(caName, projectId)
});
}
});
};
export const useUpdateCa = () => {
export const useCreateCa = () => {
const queryClient = useQueryClient();
return useMutation<TCertificateAuthority, object, TUpdateCaDTO>({
mutationFn: async ({ caId, projectSlug, ...body }) => {
const {
data: { ca }
} = await apiRequest.patch<{ ca: TCertificateAuthority }>(`/api/v1/pki/ca/${caId}`, body);
return ca;
return useMutation<TUnifiedCertificateAuthority, object, TCreateCertificateAuthorityDTO>({
mutationFn: async (body) => {
const { data } = await apiRequest.post<TUnifiedCertificateAuthority>(
`/api/v1/pki/ca/${body.type}`,
body
);
return data;
},
onSuccess: ({ id }, { projectSlug }) => {
queryClient.invalidateQueries({ queryKey: workspaceKeys.getWorkspaceCas({ projectSlug }) });
queryClient.invalidateQueries({ queryKey: caKeys.getCaById(id) });
onSuccess: (_, { type, projectId }) => {
queryClient.invalidateQueries({
queryKey: caKeys.listCasByTypeAndProjectId(type, projectId)
});
}
});
};
export const useDeleteCa = () => {
const queryClient = useQueryClient();
return useMutation<TCertificateAuthority, object, TDeleteCaDTO>({
mutationFn: async ({ caId }) => {
const {
data: { ca }
} = await apiRequest.delete<{ ca: TCertificateAuthority }>(`/api/v1/pki/ca/${caId}`);
return ca;
return useMutation<TUnifiedCertificateAuthority, object, TDeleteCertificateAuthorityDTO>({
mutationFn: async ({ caName, type, projectId }) => {
const { data } = await apiRequest.delete<TUnifiedCertificateAuthority>(
`/api/v1/pki/ca/${type}/${caName}`,
{
data: {
projectId
}
}
);
return data;
},
onSuccess: (_, { projectSlug }) => {
queryClient.invalidateQueries({ queryKey: workspaceKeys.getWorkspaceCas({ projectSlug }) });
onSuccess: (_, { type, projectId }) => {
queryClient.invalidateQueries({
queryKey: caKeys.listCasByTypeAndProjectId(type, projectId)
});
}
});
};
@@ -78,7 +96,7 @@ export const useSignIntermediate = () => {
});
};
export const useImportCaCertificate = () => {
export const useImportCaCertificate = (projectId: string) => {
const queryClient = useQueryClient();
return useMutation<TImportCaCertificateResponse, object, TImportCaCertificateDTO>({
mutationFn: async ({ caId, ...body }) => {
@@ -92,6 +110,9 @@ export const useImportCaCertificate = () => {
queryClient.invalidateQueries({ queryKey: workspaceKeys.getWorkspaceCas({ projectSlug }) });
queryClient.invalidateQueries({ queryKey: caKeys.getCaCerts(caId) });
queryClient.invalidateQueries({ queryKey: caKeys.getCaCert(caId) });
queryClient.invalidateQueries({
queryKey: caKeys.listCasByTypeAndProjectId(CaType.INTERNAL, projectId)
});
}
});
};
+52 -1
View File
@@ -3,10 +3,14 @@ import { useQuery } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { TCertificateTemplate } from "../certificateTemplates/types";
import { TCertificateAuthority } from "./types";
import { CaType } from "./enums";
import { TCertificateAuthority, TUnifiedCertificateAuthority } from "./types";
export const caKeys = {
getCaById: (caId: string) => [{ caId }, "ca"],
getCaByNameAndProjectId: (caName: string, projectId: string) => [{ caName, projectId }, "ca"],
listCasByTypeAndProjectId: (type: CaType, projectId: string) => [{ type, projectId }, "cas"],
listCasByProjectId: (projectId: string) => [{ projectId }, "cas"],
getCaCerts: (caId: string) => [{ caId }, "ca-cert"],
getCaCrls: (caId: string) => [{ caId }, "ca-crls"],
getCaCert: (caId: string) => [{ caId }, "ca-cert"],
@@ -16,6 +20,53 @@ export const caKeys = {
getCaEstConfig: (caId: string) => [{ caId }, "ca-est-config"]
};
export const useGetCa = ({
caName,
projectId,
type
}: {
caName: string;
projectId: string;
type: CaType;
}) => {
return useQuery({
queryKey: caKeys.getCaByNameAndProjectId(caName, projectId),
queryFn: async () => {
const { data } = await apiRequest.get<TUnifiedCertificateAuthority>(
`/api/v1/pki/ca/${type}/${caName}?projectId=${projectId}`
);
return data;
},
enabled: Boolean(caName && projectId && type)
});
};
export const useListCasByTypeAndProjectId = (type: CaType, projectId: string) => {
return useQuery({
queryKey: caKeys.listCasByTypeAndProjectId(type, projectId),
queryFn: async () => {
const { data } = await apiRequest.get<TUnifiedCertificateAuthority[]>(
`/api/v1/pki/ca/${type}?projectId=${projectId}`
);
return data;
}
});
};
export const useListCasByProjectId = (projectId: string) => {
return useQuery({
queryKey: caKeys.listCasByProjectId(projectId),
queryFn: async () => {
const { data } = await apiRequest.get<{
certificateAuthorities: TUnifiedCertificateAuthority[];
}>(`/api/v2/pki/ca?projectId=${projectId}`);
return data.certificateAuthorities;
}
});
};
export const useGetCaById = (caId: string) => {
return useQuery({
queryKey: caKeys.getCaById(caId),
+64 -18
View File
@@ -1,11 +1,73 @@
import { CertExtendedKeyUsage, CertKeyAlgorithm, CertKeyUsage } from "../certificates/enums";
import { CaRenewalType, CaStatus, CaType } from "./enums";
import { AcmeDnsProvider, CaRenewalType, CaStatus, CaType, InternalCaType } from "./enums";
export type TAcmeCertificateAuthority = {
id: string;
projectId: string;
type: CaType.ACME;
status: CaStatus;
name: string;
enableDirectIssuance: boolean;
configuration: {
dnsAppConnectionId: string;
dnsProviderConfig: {
provider: AcmeDnsProvider.ROUTE53;
hostedZoneId: string;
};
directoryUrl: string;
accountEmail: string;
};
};
export type TInternalCertificateAuthority = {
id: string;
projectId: string;
type: CaType.INTERNAL;
status: CaStatus;
name: string;
enableDirectIssuance: boolean;
configuration: {
type: InternalCaType;
friendlyName?: string;
commonName: string;
organization: string;
ou: string;
country: string;
province: string;
locality: string;
maxPathLength: number;
keyAlgorithm: CertKeyAlgorithm;
notAfter?: string;
notBefore?: string;
dn?: string;
parentCaId?: string;
serialNumber?: string;
activeCaCertId?: string;
};
};
export type TUnifiedCertificateAuthority =
| TAcmeCertificateAuthority
| TInternalCertificateAuthority;
export type TCreateCertificateAuthorityDTO = Omit<TUnifiedCertificateAuthority, "id">;
export type TUpdateCertificateAuthorityDTO = Partial<TUnifiedCertificateAuthority> & {
caName: string;
projectId: string;
type: CaType;
};
export type TDeleteCertificateAuthorityDTO = {
caName: string;
type: CaType;
projectId: string;
};
export type TCertificateAuthority = {
id: string;
parentCaId?: string;
projectId: string;
type: CaType;
type: InternalCaType;
status: CaStatus;
friendlyName: string;
organization: string;
@@ -25,22 +87,6 @@ export type TCertificateAuthority = {
updatedAt: string;
};
export type TCreateCaDTO = {
projectSlug: string;
type: string;
friendlyName?: string;
organization: string;
ou: string;
country: string;
province: string;
locality: string;
commonName: string;
notAfter?: string;
maxPathLength: number;
keyAlgorithm: CertKeyAlgorithm;
requireTemplateForIssuance: boolean;
};
export type TUpdateCaDTO = {
projectSlug: string;
caId: string;
@@ -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;
};
@@ -1,2 +1,2 @@
export { useDeleteCert, useRevokeCert } from "./mutations";
export { useDeleteCert, useImportCertificate, useRevokeCert } from "./mutations";
export { useGetCert, useGetCertBody } from "./queries";
@@ -4,7 +4,13 @@ import { apiRequest } from "@app/config/request";
import { pkiSubscriberKeys } from "../pkiSubscriber/queries";
import { workspaceKeys } from "../workspace";
import { TCertificate, TDeleteCertDTO, TRevokeCertDTO } from "./types";
import {
TCertificate,
TDeleteCertDTO,
TImportCertificateDTO,
TImportCertificateResponse,
TRevokeCertDTO
} from "./types";
export const useDeleteCert = () => {
const queryClient = useQueryClient();
@@ -49,3 +55,21 @@ export const useRevokeCert = () => {
}
});
};
export const useImportCertificate = () => {
const queryClient = useQueryClient();
return useMutation<TImportCertificateResponse, object, TImportCertificateDTO>({
mutationFn: async (body) => {
const { data } = await apiRequest.post<TImportCertificateResponse>(
"/api/v1/pki/certificates/import-certificate",
body
);
return data;
},
onSuccess: (_, { projectSlug }) => {
queryClient.invalidateQueries({
queryKey: workspaceKeys.forWorkspaceCertificates(projectSlug)
});
}
});
};
@@ -25,3 +25,21 @@ export type TRevokeCertDTO = {
serialNumber: string;
revocationReason: string;
};
export type TImportCertificateDTO = {
projectSlug: string;
certificatePem: string;
privateKeyPem: string;
chainPem: string;
pkiCollectionId?: string;
friendlyName?: string;
};
export type TImportCertificateResponse = {
certificate: string;
certificateChain: string;
privateKey: string;
serialNumber: string;
};
+19 -1
View File
@@ -13,6 +13,7 @@ export type TDynamicSecret = {
status?: DynamicSecretStatus;
statusDetails?: string;
maxTTL: string;
usernameTemplate?: string | null;
metadata?: { key: string; value: string }[];
};
@@ -31,7 +32,8 @@ export enum DynamicSecretProviders {
SapHana = "sap-hana",
Snowflake = "snowflake",
Totp = "totp",
SapAse = "sap-ase"
SapAse = "sap-ase",
Kubernetes = "kubernetes"
}
export enum SqlProviders {
@@ -261,6 +263,20 @@ 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[];
};
};
export type TCreateDynamicSecretDTO = {
@@ -272,6 +288,7 @@ export type TCreateDynamicSecretDTO = {
environmentSlug: string;
name: string;
metadata?: { key: string; value: string }[];
usernameTemplate?: string;
};
export type TUpdateDynamicSecretDTO = {
@@ -285,6 +302,7 @@ export type TUpdateDynamicSecretDTO = {
defaultTTL?: string;
maxTTL?: string | null;
inputs?: unknown;
usernameTemplate?: string | null;
};
};
@@ -163,7 +163,8 @@ export const useUpdateIdentityUniversalAuth = () => {
accessTokenTTL,
accessTokenMaxTTL,
accessTokenNumUsesLimit,
accessTokenTrustedIps
accessTokenTrustedIps,
accessTokenPeriod
}) => {
const {
data: { identityUniversalAuth }
@@ -172,7 +173,8 @@ export const useUpdateIdentityUniversalAuth = () => {
accessTokenTTL,
accessTokenMaxTTL,
accessTokenNumUsesLimit,
accessTokenTrustedIps
accessTokenTrustedIps,
accessTokenPeriod
});
return identityUniversalAuth;
},
@@ -107,6 +107,7 @@ export type IdentityUniversalAuth = {
accessTokenMaxTTL: number;
accessTokenNumUsesLimit: number;
accessTokenTrustedIps: IdentityTrustedIp[];
accessTokenPeriod: number;
};
export type AddIdentityUniversalAuthDTO = {
@@ -118,6 +119,7 @@ export type AddIdentityUniversalAuthDTO = {
accessTokenTTL: number;
accessTokenMaxTTL: number;
accessTokenNumUsesLimit: number;
accessTokenPeriod: number;
accessTokenTrustedIps: {
ipAddress: string;
}[];
@@ -132,6 +134,7 @@ export type UpdateIdentityUniversalAuthDTO = {
accessTokenTTL?: number;
accessTokenMaxTTL?: number;
accessTokenNumUsesLimit?: number;
accessTokenPeriod?: number;
accessTokenTrustedIps?: {
ipAddress: string;
}[];
@@ -118,7 +118,9 @@ export const useUpdateOrg = () => {
kmsProductEnabled,
sshProductEnabled,
scannerProductEnabled,
shareSecretsProductEnabled
shareSecretsProductEnabled,
maxSharedSecretLifetime,
maxSharedSecretViewLimit
}) => {
return apiRequest.patch(`/api/v1/organization/${orgId}`, {
name,
@@ -136,7 +138,9 @@ export const useUpdateOrg = () => {
kmsProductEnabled,
sshProductEnabled,
scannerProductEnabled,
shareSecretsProductEnabled
shareSecretsProductEnabled,
maxSharedSecretLifetime,
maxSharedSecretViewLimit
});
},
onSuccess: () => {
@@ -26,6 +26,8 @@ export type Organization = {
sshProductEnabled: boolean;
scannerProductEnabled: boolean;
shareSecretsProductEnabled: boolean;
maxSharedSecretLifetime: number;
maxSharedSecretViewLimit: number | null;
};
export type UpdateOrgDTO = {
@@ -46,6 +48,8 @@ export type UpdateOrgDTO = {
sshProductEnabled?: boolean;
scannerProductEnabled?: boolean;
shareSecretsProductEnabled?: boolean;
maxSharedSecretViewLimit?: number | null;
maxSharedSecretLifetime?: number;
};
export type BillingDetails = {
@@ -2,6 +2,7 @@ export {
useCreatePkiSubscriber,
useDeletePkiSubscriber,
useIssuePkiSubscriberCert,
useOrderPkiSubscriberCert,
useUpdatePkiSubscriber
} from "./mutations";
export { useGetPkiSubscriber, useGetPkiSubscriberCertificates } from "./queries";
@@ -108,3 +108,17 @@ export const useIssuePkiSubscriberCert = () => {
}
});
};
export const useOrderPkiSubscriberCert = () => {
return useMutation<{ message: string }, object, TIssuePkiSubscriberCertDTO>({
mutationFn: async ({ subscriberName, projectId }) => {
const { data } = await apiRequest.post(
`/api/v1/pki/subscribers/${subscriberName}/order-certificate`,
{
projectId
}
);
return data;
}
});
};
@@ -1,6 +1,7 @@
import { useQuery } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { TReactQueryOptions } from "@app/types/reactQuery";
import { TCertificate } from "../certificates/types";
import { TPkiSubscriber } from "./types";
@@ -38,13 +39,16 @@ export const pkiSubscriberKeys = {
] as const
};
export const useGetPkiSubscriber = ({
subscriberName,
projectId
}: {
subscriberName: string;
projectId: string;
}) => {
export const useGetPkiSubscriber = (
{
subscriberName,
projectId
}: {
subscriberName: string;
projectId: string;
},
options?: TReactQueryOptions["options"]
) => {
return useQuery({
queryKey: pkiSubscriberKeys.getPkiSubscriber({ subscriberName, projectId }),
queryFn: async () => {
@@ -58,21 +62,25 @@ export const useGetPkiSubscriber = ({
);
return pkiSubscriber;
},
enabled: Boolean(subscriberName) && Boolean(projectId)
enabled: Boolean(subscriberName) && Boolean(projectId),
...options
});
};
export const useGetPkiSubscriberCertificates = ({
subscriberName,
projectId,
offset,
limit
}: {
subscriberName: string;
projectId: string;
offset: number;
limit: number;
}) => {
export const useGetPkiSubscriberCertificates = (
{
subscriberName,
projectId,
offset,
limit
}: {
subscriberName: string;
projectId: string;
offset: number;
limit: number;
},
options?: TReactQueryOptions["options"]
) => {
return useQuery({
queryKey: pkiSubscriberKeys.specificPkiSubscriberCertificates({
subscriberName,
@@ -97,6 +105,7 @@ export const useGetPkiSubscriberCertificates = ({
);
return { certificates, totalCount };
},
enabled: Boolean(subscriberName) && Boolean(projectId)
enabled: Boolean(subscriberName) && Boolean(projectId),
...options
});
};
+22 -2
View File
@@ -5,6 +5,11 @@ export enum PkiSubscriberStatus {
DISABLED = "disabled"
}
export enum SubscriberOperationStatus {
SUCCESS = "success",
FAILED = "failed"
}
export type TPkiSubscriber = {
id: string;
projectId: string;
@@ -12,10 +17,16 @@ export type TPkiSubscriber = {
name: string;
commonName: string;
status: PkiSubscriberStatus;
ttl: string;
ttl?: string;
subjectAlternativeNames: string[];
keyUsages: CertKeyUsage[];
extendedKeyUsages: CertExtendedKeyUsage[];
supportsImmediateCertIssuance?: boolean;
enableAutoRenewal?: boolean;
autoRenewalPeriodInDays?: number;
lastOperationStatus?: SubscriberOperationStatus;
lastOperationMessage?: string;
lastOperationAt?: string;
};
export type TCreatePkiSubscriberDTO = {
@@ -23,10 +34,12 @@ export type TCreatePkiSubscriberDTO = {
caId: string;
name: string;
commonName: string;
ttl: string;
ttl?: string;
subjectAlternativeNames: string[];
keyUsages: CertKeyUsage[];
extendedKeyUsages: CertExtendedKeyUsage[];
enableAutoRenewal?: boolean;
autoRenewalPeriodInDays?: number;
};
export type TUpdatePkiSubscriberDTO = {
@@ -40,6 +53,8 @@ export type TUpdatePkiSubscriberDTO = {
subjectAlternativeNames?: string[];
keyUsages?: CertKeyUsage[];
extendedKeyUsages?: CertExtendedKeyUsage[];
enableAutoRenewal?: boolean;
autoRenewalPeriodInDays?: number;
};
export type TDeletePkiSubscriberDTO = {
@@ -51,3 +66,8 @@ export type TIssuePkiSubscriberCertDTO = {
subscriberName: string;
projectId: string;
};
export type TOrderPkiSubscriberCertDTO = {
subscriberName: string;
projectId: string;
};
@@ -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;
@@ -57,7 +57,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;
@@ -65,6 +65,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;
@@ -1,3 +1,4 @@
import { TPasswordRequirements } from "@app/components/secret-rotations-v2/forms/schemas/shared";
import { AppConnection } from "@app/hooks/api/appConnections/enums";
import { SecretRotation } from "@app/hooks/api/secretRotationsV2";
import {
@@ -5,10 +6,17 @@ import {
TSecretRotationV2GeneratedCredentialsResponseBase
} from "@app/hooks/api/secretRotationsV2/types/shared";
export enum LdapPasswordRotationMethod {
ConnectionPrincipal = "connection-principal",
TargetPrincipal = "target-principal"
}
export type TLdapPasswordRotation = TSecretRotationV2Base & {
type: SecretRotation.LdapPassword;
parameters: {
dn: string;
rotationMethod?: LdapPasswordRotationMethod;
passwordRequirements?: TPasswordRequirements;
};
secretsMapping: {
dn: string;
@@ -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;
@@ -11,13 +11,10 @@ export const secretSharingKeys = {
allSecretRequests: () => ["secretRequests"] as const,
specificSecretRequests: ({ offset, limit }: { offset: number; limit: number }) =>
[...secretSharingKeys.allSecretRequests(), { offset, limit }] as const,
getSecretById: (arg: {
id: string;
hashedHex: string | null;
password?: string;
email?: string;
hash?: string;
}) => ["shared-secret", arg],
getSecretById: (arg: { id: string; hashedHex: string | null; password?: string }) => [
"shared-secret",
arg
],
getSecretRequestById: (arg: { id: string }) => ["secret-request", arg] as const
};
@@ -73,34 +70,24 @@ export const useGetSecretRequests = ({
export const useGetActiveSharedSecretById = ({
sharedSecretId,
hashedHex,
password,
email,
hash
password
}: {
sharedSecretId: string;
hashedHex: string | null;
password?: string;
// For secrets shared to specific emails (optional)
email?: string;
hash?: string;
}) => {
return useQuery({
queryKey: secretSharingKeys.getSecretById({
id: sharedSecretId,
hashedHex,
password,
email,
hash
password
}),
queryFn: async () => {
const { data } = await apiRequest.post<TViewSharedSecretResponse>(
`/api/v1/secret-sharing/shared/public/${sharedSecretId}`,
{
...(hashedHex && { hashedHex }),
password,
email,
hash
password
}
);
+2 -1
View File
@@ -13,7 +13,8 @@ export enum SecretSync {
Windmill = "windmill",
HCVault = "hashicorp-vault",
TeamCity = "teamcity",
OCIVault = "oci-vault"
OCIVault = "oci-vault",
OnePass = "1password"
}
export enum SecretSyncStatus {
@@ -0,0 +1,15 @@
import { AppConnection } from "@app/hooks/api/appConnections/enums";
import { SecretSync } from "@app/hooks/api/secretSyncs";
import { TRootSecretSync } from "@app/hooks/api/secretSyncs/types/root-sync";
export type TOnePassSync = TRootSecretSync & {
destination: SecretSync.OnePass;
destinationConfig: {
vaultId: string;
};
connection: {
app: AppConnection.OnePass;
name: string;
id: string;
};
};
@@ -1,6 +1,7 @@
import { SecretSync, SecretSyncImportBehavior } from "@app/hooks/api/secretSyncs";
import { DiscriminativePick } from "@app/types";
import { TOnePassSync } from "./1password-sync";
import { TAwsParameterStoreSync } from "./aws-parameter-store-sync";
import { TAwsSecretsManagerSync } from "./aws-secrets-manager-sync";
import { TAzureAppConfigurationSync } from "./azure-app-configuration-sync";
@@ -21,6 +22,7 @@ export type TSecretSyncOption = {
name: string;
destination: SecretSync;
canImportSecrets: boolean;
enterprise?: boolean;
};
export type TSecretSync =
@@ -38,7 +40,8 @@ export type TSecretSync =
| TWindmillSync
| THCVaultSync
| TTeamCitySync
| TOCIVaultSync;
| TOCIVaultSync
| TOnePassSync;
export type TListSecretSyncs = { secretSyncs: TSecretSync[] };
@@ -51,4 +51,6 @@ export type SubscriptionPlan = {
projectTemplates: boolean;
kmip: boolean;
secretScanning: boolean;
enterpriseSecretSyncs: boolean;
enterpriseAppConnections: boolean;
};
+2
View File
@@ -1,6 +1,7 @@
export {
useAddUserToWsE2EE,
useAddUserToWsNonE2EE,
useRemoveMyDuplicateAccounts,
useRevokeMySessionById,
useSendEmailVerificationCode,
useVerifyEmailVerificationCode
@@ -14,6 +15,7 @@ export {
useDeleteOrgMembership,
useGetMyAPIKeys,
useGetMyAPIKeysV2,
useGetMyDuplicateAccount,
useGetMyIp,
useGetMyOrganizationProjects,
useGetMySessions,
@@ -184,3 +184,12 @@ export const useRevokeMySessionById = () => {
}
});
};
export const useRemoveMyDuplicateAccounts = () => {
return useMutation({
mutationFn: async () => {
const { data } = await apiRequest.post("/api/v1/user/remove-duplicate-accounts");
return data;
}
});
};
+27
View File
@@ -37,6 +37,33 @@ export const useGetUser = () =>
queryFn: fetchUserDetails
});
export const fetchUserDuplicateAccounts = async () => {
const { data } = await apiRequest.get<{
users: Array<
User & {
isMyAccount: boolean;
organizations: { name: string; slug: string }[];
devices: {
ip: string;
userAgent: string;
}[];
}
>;
}>("/api/v1/user/duplicate-accounts");
return data.users;
};
export const useGetMyDuplicateAccount = () =>
useQuery({
queryKey: userKeys.getMyDuplicateAccount,
staleTime: 60 * 1000, // 1 min in ms
queryFn: fetchUserDuplicateAccounts,
select: (users) => ({
duplicateAccounts: users.filter((el) => !el.isMyAccount),
myAccount: users?.find((el) => el.isMyAccount)
})
});
export const useDeleteMe = () => {
const queryClient = useQueryClient();
@@ -1,5 +1,6 @@
export const userKeys = {
getUser: ["user"] as const,
getMyDuplicateAccount: ["user-duplicate-account"] as const,
getPrivateKey: ["user"] as const,
userAction: ["user-action"] as const,
userProjectFavorites: (orgId: string) => [{ orgId }, "user-project-favorites"] as const,