Merge remote-tracking branch 'origin/main' into feat/azureDevopsSecretSync

This commit is contained in:
carlosmonastyrski
2025-06-11 19:20:26 -03:00
336 changed files with 19380 additions and 2390 deletions
@@ -3,12 +3,14 @@ import { useQuery, UseQueryOptions } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { appConnectionKeys } from "../queries";
import { TGcpProject } from "./types";
import { TGcpLocation, TGcpProject, TListProjectLocations } from "./types";
const gcpConnectionKeys = {
all: [...appConnectionKeys.all, "gcp"] as const,
listProjects: (connectionId: string) =>
[...gcpConnectionKeys.all, "projects", connectionId] as const
[...gcpConnectionKeys.all, "projects", connectionId] as const,
listProjectLocations: ({ projectId, connectionId }: TListProjectLocations) =>
[...gcpConnectionKeys.all, "project-locations", connectionId, projectId] as const
};
export const useGcpConnectionListProjects = (
@@ -35,3 +37,29 @@ export const useGcpConnectionListProjects = (
...options
});
};
export const useGcpConnectionListProjectLocations = (
{ connectionId, projectId }: TListProjectLocations,
options?: Omit<
UseQueryOptions<
TGcpLocation[],
unknown,
TGcpLocation[],
ReturnType<typeof gcpConnectionKeys.listProjectLocations>
>,
"queryKey" | "queryFn"
>
) => {
return useQuery({
queryKey: gcpConnectionKeys.listProjectLocations({ connectionId, projectId }),
queryFn: async () => {
const { data } = await apiRequest.get<TGcpLocation[]>(
`/api/v1/app-connections/gcp/${connectionId}/secret-manager-project-locations`,
{ params: { projectId } }
);
return data;
},
...options
});
};
@@ -2,3 +2,13 @@ export type TGcpProject = {
id: string;
name: string;
};
export type TListProjectLocations = {
connectionId: string;
projectId: string;
};
export type TGcpLocation = {
displayName: string;
locationId: string;
};
@@ -52,6 +52,7 @@ export const eventToNameMap: { [K in EventType]: string } = {
[EventType.CREATE_WEBHOOK]: "Create webhook",
[EventType.UPDATE_WEBHOOK_STATUS]: "Update webhook status",
[EventType.DELETE_WEBHOOK]: "Delete webhook",
[EventType.WEBHOOK_TRIGGERED]: "Webhook event",
[EventType.GET_SECRET_IMPORTS]: "List secret imports",
[EventType.CREATE_SECRET_IMPORT]: "Create secret import",
[EventType.UPDATE_SECRET_IMPORT]: "Update secret import",
@@ -65,6 +65,7 @@ export enum EventType {
CREATE_WEBHOOK = "create-webhook",
UPDATE_WEBHOOK_STATUS = "update-webhook-status",
DELETE_WEBHOOK = "delete-webhook",
WEBHOOK_TRIGGERED = "webhook-triggered",
GET_SECRET_IMPORTS = "get-secret-imports",
CREATE_SECRET_IMPORT = "create-secret-import",
UPDATE_SECRET_IMPORT = "update-secret-import",
@@ -427,6 +427,16 @@ interface DeleteWebhookEvent {
};
}
export interface WebhookTriggeredEvent {
type: EventType.WEBHOOK_TRIGGERED;
metadata: {
webhookId: string;
status: string;
type: string;
payload: { [k: string]: string | null };
};
}
interface GetSecretImportsEvent {
type: EventType.GET_SECRET_IMPORTS;
metadata: {
@@ -891,6 +901,7 @@ export type Event =
| CreateWebhookEvent
| UpdateWebhookStatusEvent
| DeleteWebhookEvent
| WebhookTriggeredEvent
| GetSecretImportsEvent
| CreateSecretImportEvent
| UpdateSecretImportEvent
+56 -20
View File
@@ -37,6 +37,11 @@ export enum DynamicSecretProviders {
Vertica = "vertica"
}
export enum KubernetesDynamicSecretCredentialType {
Static = "static",
Dynamic = "dynamic"
}
export enum SqlProviders {
Postgres = "postgres",
MySql = "mysql2",
@@ -44,6 +49,11 @@ export enum SqlProviders {
MsSQL = "mssql"
}
export enum DynamicSecretAwsIamAuth {
AssumeRole = "assume-role",
AccessKey = "access-key"
}
export type TDynamicSecretProvider =
| {
type: DynamicSecretProviders.SqlDatabase;
@@ -78,15 +88,26 @@ export type TDynamicSecretProvider =
}
| {
type: DynamicSecretProviders.AwsIam;
inputs: {
accessKey: string;
secretAccessKey: string;
region: string;
awsPath?: string;
policyDocument?: string;
userGroups?: string;
policyArns?: string;
};
inputs:
| {
method: DynamicSecretAwsIamAuth.AccessKey;
accessKey: string;
secretAccessKey: string;
region: string;
awsPath?: string;
policyDocument?: string;
userGroups?: string;
policyArns?: string;
}
| {
method: DynamicSecretAwsIamAuth.AssumeRole;
roleArn: string;
region: string;
awsPath?: string;
policyDocument?: string;
userGroups?: string;
policyArns?: string;
};
}
| {
type: DynamicSecretProviders.Redis;
@@ -267,17 +288,32 @@ export type TDynamicSecretProvider =
}
| {
type: DynamicSecretProviders.Kubernetes;
inputs: {
url: string;
clusterToken: string;
ca?: string;
serviceAccountName: string;
credentialType: "dynamic" | "static";
namespace: string;
gatewayId?: string;
sslEnabled: boolean;
audiences: string[];
};
inputs:
| {
url?: string;
clusterToken?: string;
ca?: string;
serviceAccountName: string;
credentialType: KubernetesDynamicSecretCredentialType.Static;
namespace: string;
gatewayId?: string;
sslEnabled: boolean;
audiences: string[];
authMethod: string;
}
| {
url?: string;
clusterToken?: string;
ca?: string;
credentialType: KubernetesDynamicSecretCredentialType.Dynamic;
namespace: string;
gatewayId?: string;
sslEnabled: boolean;
audiences: string[];
roleType: string;
role: string;
authMethod: string;
};
}
| {
type: DynamicSecretProviders.Vertica;
@@ -2,6 +2,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { DynamicSecretProviders } from "../dynamicSecret/types";
import { dynamicSecretLeaseKeys } from "./queries";
import {
TCreateDynamicSecretLeaseDTO,
@@ -19,6 +20,14 @@ export const useCreateDynamicSecretLease = () => {
TCreateDynamicSecretLeaseDTO
>({
mutationFn: async (dto) => {
if (dto.provider === DynamicSecretProviders.Kubernetes) {
const { data } = await apiRequest.post<{ lease: TDynamicSecretLease; data: unknown }>(
"/api/v1/dynamic-secrets/leases/kubernetes",
dto
);
return data;
}
const { data } = await apiRequest.post<{ lease: TDynamicSecretLease; data: unknown }>(
"/api/v1/dynamic-secrets/leases",
dto
@@ -1,3 +1,5 @@
import { DynamicSecretProviders } from "../dynamicSecret/types";
export enum DynamicSecretLeaseStatus {
FailedDeletion = "Failed to delete"
}
@@ -13,12 +15,20 @@ export type TDynamicSecretLease = {
updatedAt: string;
};
export type TDynamicSecretKubernetesLeaseConfig = {
namespace?: string;
};
export type TDynamicSecretLeaseConfig = TDynamicSecretKubernetesLeaseConfig;
export type TCreateDynamicSecretLeaseDTO = {
dynamicSecretName: string;
projectSlug: string;
ttl?: string;
path: string;
environmentSlug: string;
config?: TDynamicSecretLeaseConfig;
provider: DynamicSecretProviders;
};
export type TRenewDynamicSecretLeaseDTO = {
@@ -0,0 +1,2 @@
export { useGetFolderCommitHistory, useGetFolderCommitsCount } from "./queries";
export * from "./types";
@@ -0,0 +1,294 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
import { CommitHistoryItem, CommitWithChanges, RollbackPreview } from "./types";
export const commitKeys = {
count: ({
workspaceId,
environment,
directory
}: {
workspaceId: string;
environment: string;
directory?: string;
}) => [{ workspaceId, environment, directory }, "folder-commits-count"] as const,
history: ({
workspaceId,
environment,
directory
}: {
workspaceId: string;
environment: string;
directory?: string;
}) => [{ workspaceId, environment, directory }, "folder-commits"] as const,
details: ({ workspaceId, commitId }: { workspaceId: string; commitId: string }) =>
[{ workspaceId, commitId }, "commit-details"] as const,
rollbackPreview: ({
folderId,
commitId,
envSlug,
projectId,
deepRollback
}: {
folderId: string;
commitId: string;
envSlug: string;
projectId: string;
deepRollback: boolean;
}) => [{ folderId, commitId, envSlug, projectId, deepRollback }, "rollback-preview"] as const
};
const fetchFolderCommitsCount = async ({
workspaceId,
environment,
directory
}: {
workspaceId: string;
environment: string;
directory?: string;
}) => {
const res = await apiRequest.get<{ count: number; folderId: string }>(
"/api/v1/pit/commits/count",
{
params: {
environment,
path: directory,
projectId: workspaceId
}
}
);
return res.data;
};
const fetchFolderCommitHistory = async (
workspaceId: string,
environment: string,
directory: string,
offset: number = 0,
limit: number = 20,
search?: string,
sort: "asc" | "desc" = "desc"
): Promise<{
commits: CommitHistoryItem[];
total: number;
hasMore: boolean;
}> => {
const res = await apiRequest.get<{
commits: CommitHistoryItem[];
total: number;
hasMore: boolean;
}>("/api/v1/pit/commits", {
params: {
environment,
path: directory,
projectId: workspaceId,
offset,
limit,
search,
sort
}
});
return res.data;
};
export const fetchCommitDetails = async (workspaceId: string, commitId: string) => {
const { data } = await apiRequest.get<CommitWithChanges>(
`/api/v1/pit/commits/${commitId}/changes`,
{
params: {
projectId: workspaceId
}
}
);
return data;
};
export const fetchRollbackPreview = async (
folderId: string,
commitId: string,
envSlug: string,
workspaceId: string,
deepRollback: boolean,
secretPath: string
): Promise<RollbackPreview[]> => {
const { data } = await apiRequest.get<RollbackPreview[]>(
`/api/v1/pit/commits/${commitId}/compare`,
{
params: {
folderId,
environment: envSlug,
deepRollback,
secretPath,
projectId: workspaceId
}
}
);
return data;
};
const fetchRollback = async (
folderId: string,
commitId: string,
workspaceId: string,
deepRollback: boolean,
message?: string,
envSlug?: string
) => {
const { data } = await apiRequest.post<{ success: boolean }>(
`/api/v1/pit/commits/${commitId}/rollback`,
{
folderId,
deepRollback,
message,
environment: envSlug,
projectId: workspaceId
}
);
return data;
};
const fetchRevert = async (commitId: string, workspaceId: string) => {
const { data } = await apiRequest.post<{ success: boolean; message: string }>(
`/api/v1/pit/commits/${commitId}/revert`,
{
projectId: workspaceId
}
);
return data;
};
export const useCommitRevert = ({
commitId,
projectId,
environment,
directory
}: {
commitId: string;
projectId: string;
environment: string;
directory: string;
}) => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: () => fetchRevert(commitId, projectId),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: [
commitKeys.details({ workspaceId: projectId, commitId }),
commitKeys.history({ workspaceId: projectId, environment, directory }),
commitKeys.count({ workspaceId: projectId, environment, directory })
]
});
}
});
};
export const useCommitRollback = ({
workspaceId,
commitId,
folderId,
deepRollback,
environment,
directory,
envSlug
}: {
workspaceId: string;
commitId: string;
folderId: string;
deepRollback: boolean;
environment: string;
directory: string;
envSlug: string;
}) => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (message: string) =>
fetchRollback(folderId, commitId, workspaceId, deepRollback, message, envSlug),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: [
commitKeys.details({ workspaceId, commitId }),
commitKeys.history({ workspaceId, environment, directory }),
commitKeys.count({ workspaceId, environment, directory })
]
});
}
});
};
export const useGetFolderCommitsCount = ({
workspaceId,
environment,
directory,
isPaused
}: {
workspaceId: string;
environment: string;
directory: string;
isPaused?: boolean;
}) =>
useQuery({
enabled: Boolean(workspaceId && environment) && !isPaused,
queryKey: commitKeys.count({ workspaceId, environment, directory }),
queryFn: () => fetchFolderCommitsCount({ workspaceId, environment, directory })
});
export const useGetFolderCommitHistory = ({
workspaceId,
environment,
directory,
offset = 0,
limit = 20,
search,
sort = "desc"
}: {
workspaceId: string;
environment: string;
directory: string;
offset?: number;
limit?: number;
search?: string;
sort?: "asc" | "desc";
}) => {
return useQuery({
queryKey: [
commitKeys.history({ workspaceId, environment, directory }),
offset,
limit,
search,
sort
],
queryFn: () =>
fetchFolderCommitHistory(workspaceId, environment, directory, offset, limit, search, sort),
enabled: Boolean(workspaceId && environment)
});
};
export const useGetCommitDetails = (workspaceId: string, commitId: string) => {
return useQuery({
queryKey: commitKeys.details({ workspaceId, commitId }),
queryFn: () => fetchCommitDetails(workspaceId, commitId),
enabled: Boolean(workspaceId) && Boolean(commitId)
});
};
export const useGetRollbackPreview = (
folderId: string,
commitId: string,
envSlug: string,
projectId: string,
deepRollback: boolean,
secretPath: string
) => {
return useQuery({
queryKey: commitKeys.rollbackPreview({ folderId, commitId, envSlug, projectId, deepRollback }),
queryFn: () =>
fetchRollbackPreview(folderId, commitId, envSlug, projectId, deepRollback, secretPath),
enabled: Boolean(folderId) && Boolean(commitId)
});
};
@@ -0,0 +1,64 @@
import { CommitType, SecretVersions } from "../types";
export type CommitHistoryItem = {
id: string;
commitId: string;
actorMetadata: {
id: string;
name?: string;
};
actorType: string;
message: string;
folderId: string;
envId: string;
createdAt: string;
updatedAt: string;
isLatest: boolean;
};
export type TFolderCommitChanges = {
id: string;
folderCommitId: string;
changeType: CommitType;
isUpdate: boolean;
secretVersionId: string | null;
folderVersionId: string | null;
createdAt: string;
updatedAt: string;
versions: SecretVersions[];
secretKey?: string;
folderName?: string;
secretVersion?: string;
folderVersion?: string;
};
export type FolderReconstructedItem = {
type: string;
id: string;
versionId: string;
folderName?: string;
folderVersion?: number;
secretKey?: string;
secretVersion?: number;
};
export type CommitWithChanges = {
changes: CommitHistoryItem & {
changes: TFolderCommitChanges[];
};
};
export type RollbackChange = {
type: "folder" | "secret";
id: string;
versionId: string;
changeType: "create" | "update" | "delete";
commitId: string;
};
export type RollbackPreview = {
folderId: string;
folderName: string;
folderPath: string;
changes: RollbackChange[];
};
+69 -1
View File
@@ -21,7 +21,27 @@ export const groupKeys = {
limit: number;
search: string;
filter?: EFilterReturnedUsers;
}) => [...groupKeys.forGroupUserMemberships(slug), { offset, limit, search, filter }] as const
}) => [...groupKeys.forGroupUserMemberships(slug), { offset, limit, search, filter }] as const,
specificProjectGroupUserMemberships: ({
projectId,
slug,
offset,
limit,
search,
filter
}: {
slug: string;
projectId: string;
offset: number;
limit: number;
search: string;
filter?: EFilterReturnedUsers;
}) =>
[
...groupKeys.forGroupUserMemberships(slug),
projectId,
{ offset, limit, search, filter }
] as const
};
export const useGetGroupById = (groupId: string) => {
@@ -80,3 +100,51 @@ export const useListGroupUsers = ({
}
});
};
export const useListProjectGroupUsers = ({
id,
projectId,
groupSlug,
offset = 0,
limit = 10,
search,
filter
}: {
id: string;
groupSlug: string;
projectId: string;
offset: number;
limit: number;
search: string;
filter?: EFilterReturnedUsers;
}) => {
return useQuery({
queryKey: groupKeys.specificProjectGroupUserMemberships({
slug: groupSlug,
projectId,
offset,
limit,
search,
filter
}),
enabled: Boolean(groupSlug),
placeholderData: (previousData) => previousData,
queryFn: async () => {
const params = new URLSearchParams({
offset: String(offset),
limit: String(limit),
search,
...(filter && { filter })
});
const { data } = await apiRequest.get<{ users: TGroupUser[]; totalCount: number }>(
`/api/v2/workspace/${projectId}/groups/${id}/users`,
{
params
}
);
return data;
}
});
};
@@ -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
}
);
+10 -2
View File
@@ -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;
@@ -397,8 +403,9 @@ export type IdentityKubernetesAuth = {
export type AddIdentityKubernetesAuthDTO = {
organizationId: string;
identityId: string;
kubernetesHost: string;
kubernetesHost: string | null;
tokenReviewerJwt?: string;
tokenReviewMode: IdentityKubernetesAuthTokenReviewMode;
allowedNamespaces: string;
allowedNames: string;
allowedAudience: string;
@@ -415,8 +422,9 @@ export type AddIdentityKubernetesAuthDTO = {
export type UpdateIdentityKubernetesAuthDTO = {
organizationId: string;
identityId: string;
kubernetesHost?: string;
kubernetesHost?: string | null;
tokenReviewerJwt?: string | null;
tokenReviewMode?: IdentityKubernetesAuthTokenReviewMode;
allowedNamespaces?: string;
allowedNames?: string;
allowedAudience?: string;
+1 -1
View File
@@ -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;
@@ -11,7 +11,8 @@ export enum ApprovalStatus {
export enum CommitType {
DELETE = "delete",
UPDATE = "update",
CREATE = "create"
CREATE = "create",
ADD = "add"
}
export type TSecretApprovalSecChangeData = {
@@ -10,6 +10,7 @@ import {
import { apiRequest } from "@app/config/request";
import { dashboardKeys } from "@app/hooks/api/dashboard/queries";
import { commitKeys } from "../folderCommits/queries";
import { secretSnapshotKeys } from "../secretSnapshots/queries";
import {
TCreateFolderDTO,
@@ -166,6 +167,9 @@ export const useCreateFolder = () => {
queryClient.invalidateQueries({
queryKey: secretSnapshotKeys.count({ workspaceId: projectId, environment, directory: path })
});
queryClient.invalidateQueries({
queryKey: commitKeys.count({ workspaceId: projectId, environment, directory: path })
});
}
});
};
@@ -200,6 +204,12 @@ export const useUpdateFolder = () => {
queryClient.invalidateQueries({
queryKey: secretSnapshotKeys.count({ workspaceId: projectId, environment, directory: path })
});
queryClient.invalidateQueries({
queryKey: commitKeys.count({ workspaceId: projectId, environment, directory: path })
});
queryClient.invalidateQueries({
queryKey: commitKeys.history({ workspaceId: projectId, environment, directory: path })
});
}
});
};
@@ -234,6 +244,12 @@ export const useDeleteFolder = () => {
queryClient.invalidateQueries({
queryKey: secretSnapshotKeys.count({ workspaceId: projectId, environment, directory: path })
});
queryClient.invalidateQueries({
queryKey: commitKeys.count({ workspaceId: projectId, environment, directory: path })
});
queryClient.invalidateQueries({
queryKey: commitKeys.history({ workspaceId: projectId, environment, directory: path })
});
}
});
};
@@ -279,6 +295,20 @@ export const useUpdateFolderBatch = () => {
directory: folder.path
})
});
queryClient.invalidateQueries({
queryKey: commitKeys.count({
workspaceId: projectId,
environment: folder.environment,
directory: folder.path
})
});
queryClient.invalidateQueries({
queryKey: commitKeys.history({
workspaceId: projectId,
environment: folder.environment,
directory: folder.path
})
});
});
}
});
@@ -3,15 +3,22 @@ import { SecretSync } from "@app/hooks/api/secretSyncs";
import { TRootSecretSync } from "@app/hooks/api/secretSyncs/types/root-sync";
export enum GcpSyncScope {
Global = "global"
Global = "global",
Region = "region"
}
export type TGcpSync = TRootSecretSync & {
destination: SecretSync.GCPSecretManager;
destinationConfig: {
scope: GcpSyncScope.Global;
projectId: string;
};
destinationConfig:
| {
scope: GcpSyncScope.Global;
projectId: string;
}
| {
scope: GcpSyncScope.Region;
projectId: string;
locationId: string;
};
connection: {
app: AppConnection.GCP;
name: string;
@@ -3,6 +3,7 @@ import { MutationOptions, useMutation, useQueryClient } from "@tanstack/react-qu
import { apiRequest } from "@app/config/request";
import { dashboardKeys } from "@app/hooks/api/dashboard/queries";
import { commitKeys } from "../folderCommits/queries";
import { secretApprovalRequestKeys } from "../secretApprovalRequest/queries";
import { secretSnapshotKeys } from "../secretSnapshots/queries";
import { secretKeys } from "./queries";
@@ -59,6 +60,12 @@ export const useCreateSecretV3 = ({
queryClient.invalidateQueries({
queryKey: secretSnapshotKeys.count({ environment, workspaceId, directory: secretPath })
});
queryClient.invalidateQueries({
queryKey: commitKeys.count({ workspaceId, environment, directory: secretPath })
});
queryClient.invalidateQueries({
queryKey: commitKeys.history({ workspaceId, environment, directory: secretPath })
});
queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.count({ workspaceId }) });
},
...options
@@ -118,6 +125,12 @@ export const useUpdateSecretV3 = ({
queryClient.invalidateQueries({
queryKey: secretSnapshotKeys.count({ environment, workspaceId, directory: secretPath })
});
queryClient.invalidateQueries({
queryKey: commitKeys.count({ workspaceId, environment, directory: secretPath })
});
queryClient.invalidateQueries({
queryKey: commitKeys.history({ workspaceId, environment, directory: secretPath })
});
queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.count({ workspaceId }) });
},
...options
@@ -164,6 +177,12 @@ export const useDeleteSecretV3 = ({
queryClient.invalidateQueries({
queryKey: secretSnapshotKeys.count({ environment, workspaceId, directory: secretPath })
});
queryClient.invalidateQueries({
queryKey: commitKeys.count({ workspaceId, environment, directory: secretPath })
});
queryClient.invalidateQueries({
queryKey: commitKeys.history({ workspaceId, environment, directory: secretPath })
});
queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.count({ workspaceId }) });
},
...options
@@ -200,6 +219,12 @@ export const useCreateSecretBatch = ({
queryClient.invalidateQueries({
queryKey: secretSnapshotKeys.count({ environment, workspaceId, directory: secretPath })
});
queryClient.invalidateQueries({
queryKey: commitKeys.count({ workspaceId, environment, directory: secretPath })
});
queryClient.invalidateQueries({
queryKey: commitKeys.history({ workspaceId, environment, directory: secretPath })
});
queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.count({ workspaceId }) });
},
...options
@@ -236,6 +261,12 @@ export const useUpdateSecretBatch = ({
queryClient.invalidateQueries({
queryKey: secretSnapshotKeys.count({ environment, workspaceId, directory: secretPath })
});
queryClient.invalidateQueries({
queryKey: commitKeys.count({ workspaceId, environment, directory: secretPath })
});
queryClient.invalidateQueries({
queryKey: commitKeys.history({ workspaceId, environment, directory: secretPath })
});
queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.count({ workspaceId }) });
},
...options
@@ -274,6 +305,12 @@ export const useDeleteSecretBatch = ({
queryClient.invalidateQueries({
queryKey: secretSnapshotKeys.count({ environment, workspaceId, directory: secretPath })
});
queryClient.invalidateQueries({
queryKey: commitKeys.count({ workspaceId, environment, directory: secretPath })
});
queryClient.invalidateQueries({
queryKey: commitKeys.history({ workspaceId, environment, directory: secretPath })
});
queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.count({ workspaceId }) });
},
...options
@@ -347,6 +384,20 @@ export const useMoveSecrets = ({
directory: sourceSecretPath
})
});
queryClient.invalidateQueries({
queryKey: commitKeys.count({
workspaceId: projectId,
environment: sourceEnvironment,
directory: sourceSecretPath
})
});
queryClient.invalidateQueries({
queryKey: commitKeys.history({
workspaceId: projectId,
environment: sourceEnvironment,
directory: sourceSecretPath
})
});
queryClient.invalidateQueries({
queryKey: secretApprovalRequestKeys.count({ workspaceId: projectId })
});
@@ -50,10 +50,13 @@ export const useUpdateGroupWorkspaceRole = () => {
return groupMembership;
},
onSuccess: (_, { projectId }) => {
onSuccess: (_, { projectId, groupId }) => {
queryClient.invalidateQueries({
queryKey: workspaceKeys.getWorkspaceGroupMemberships(projectId)
});
queryClient.invalidateQueries({
queryKey: workspaceKeys.getWorkspaceGroupMembershipDetails(projectId, groupId)
});
}
});
};
+19 -2
View File
@@ -282,7 +282,8 @@ export const useUpdateProject = () => {
newProjectName,
newProjectDescription,
newSlug,
secretSharing
secretSharing,
showSnapshotsLegacy
}) => {
const { data } = await apiRequest.patch<{ workspace: Workspace }>(
`/api/v1/workspace/${projectID}`,
@@ -290,7 +291,8 @@ export const useUpdateProject = () => {
name: newProjectName,
description: newProjectDescription,
slug: newSlug,
secretSharing
secretSharing,
showSnapshotsLegacy
}
);
return data.workspace;
@@ -691,6 +693,21 @@ export const useGetWorkspaceIdentityMembershipDetails = (projectId: string, iden
});
};
export const useGetWorkspaceGroupMembershipDetails = (projectId: string, groupId: string) => {
return useQuery({
enabled: Boolean(projectId && groupId),
queryKey: workspaceKeys.getWorkspaceGroupMembershipDetails(projectId, groupId),
queryFn: async () => {
const {
data: { groupMembership }
} = await apiRequest.get<{ groupMembership: TGroupMembership }>(
`/api/v2/workspace/${projectId}/groups/${groupId}`
);
return groupMembership;
}
});
};
export const useListWorkspaceGroups = (projectId: string) => {
return useQuery({
queryKey: workspaceKeys.getWorkspaceGroupMemberships(projectId),
@@ -36,6 +36,8 @@ export const workspaceKeys = {
searchWorkspace: (dto: TSearchProjectsDTO) => ["search-projects", dto] as const,
getWorkspaceGroupMemberships: (workspaceId: string) =>
[{ workspaceId }, "workspace-groups"] as const,
getWorkspaceGroupMembershipDetails: (workspaceId: string, groupId: string) =>
[{ workspaceId, groupId }, "workspace-group-membership-details"] as const,
getWorkspaceCas: ({ projectSlug }: { projectSlug: string }) =>
[{ projectSlug }, "workspace-cas"] as const,
specificWorkspaceCas: ({ projectSlug, status }: { projectSlug: string; status?: CaStatus }) =>
@@ -39,6 +39,7 @@ export type Workspace = {
roles?: TProjectRole[];
hasDeleteProtection: boolean;
secretSharing: boolean;
showSnapshotsLegacy: boolean;
};
export type WorkspaceEnv = {
@@ -79,6 +80,7 @@ export type UpdateProjectDTO = {
newProjectDescription?: string;
newSlug?: string;
secretSharing?: boolean;
showSnapshotsLegacy?: boolean;
};
export type UpdatePitVersionLimitDTO = { projectSlug: string; pitVersionLimit: number };