mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-13 19:29:54 +00:00
feat(infisical-pg): completed secret rotation with queue service
This commit is contained in:
@@ -14,7 +14,7 @@ export const useUpdateSecretApprovalReviewStatus = () => {
|
||||
|
||||
return useMutation<{}, {}, TUpdateSecretApprovalReviewStatusDTO>({
|
||||
mutationFn: async ({ id, status }) => {
|
||||
const { data } = await apiRequest.post(`/api/v1/secret-approval-requests/${id}/review`, {
|
||||
const { data } = await apiRequest.post(`/api/ee/v1/secret-approval-requests/${id}/review`, {
|
||||
status
|
||||
});
|
||||
return data;
|
||||
@@ -30,7 +30,7 @@ export const useUpdateSecretApprovalRequestStatus = () => {
|
||||
|
||||
return useMutation<{}, {}, TUpdateSecretApprovalRequestStatusDTO>({
|
||||
mutationFn: async ({ id, status }) => {
|
||||
const { data } = await apiRequest.post(`/api/v1/secret-approval-requests/${id}/status`, {
|
||||
const { data } = await apiRequest.post(`/api/ee/v1/secret-approval-requests/${id}/status`, {
|
||||
status
|
||||
});
|
||||
return data;
|
||||
@@ -47,7 +47,7 @@ export const usePerformSecretApprovalRequestMerge = () => {
|
||||
|
||||
return useMutation<{}, {}, TPerformSecretApprovalRequestMerge>({
|
||||
mutationFn: async ({ id }) => {
|
||||
const { data } = await apiRequest.post(`/api/v1/secret-approval-requests/${id}/merge`);
|
||||
const { data } = await apiRequest.post(`/api/ee/v1/secret-approval-requests/${id}/merge`);
|
||||
return data;
|
||||
},
|
||||
onSuccess: (_, { id, workspaceId }) => {
|
||||
|
||||
@@ -15,12 +15,12 @@ import { UserWsKeyPair } from "../keys/types";
|
||||
import { decryptSecrets } from "../secrets/queries";
|
||||
import { DecryptedSecret } from "../secrets/types";
|
||||
import {
|
||||
CommitType,
|
||||
TGetSecretApprovalRequestCount,
|
||||
TGetSecretApprovalRequestDetails,
|
||||
TGetSecretApprovalRequestList,
|
||||
TSecretApprovalRequest,
|
||||
TSecretApprovalRequestCount,
|
||||
TSecretApprovalSecChange,
|
||||
TSecretApprovalSecChangeData
|
||||
} from "./types";
|
||||
|
||||
@@ -96,7 +96,7 @@ const fetchSecretApprovalRequestList = async ({
|
||||
offset
|
||||
}: TGetSecretApprovalRequestList) => {
|
||||
const { data } = await apiRequest.get<{ approvals: TSecretApprovalRequest[] }>(
|
||||
"/api/v1/secret-approval-requests",
|
||||
"/api/ee/v1/secret-approval-requests",
|
||||
{
|
||||
params: {
|
||||
workspaceId,
|
||||
@@ -158,7 +158,7 @@ const fetchSecretApprovalRequestDetails = async ({
|
||||
id
|
||||
}: Omit<TGetSecretApprovalRequestDetails, "decryptKey">) => {
|
||||
const { data } = await apiRequest.get<{ approval: TSecretApprovalRequest }>(
|
||||
`/api/v1/secret-approval-requests/${id}`
|
||||
`/api/ee/v1/secret-approval-requests/${id}`
|
||||
);
|
||||
|
||||
return data.approval;
|
||||
@@ -173,7 +173,7 @@ export const useGetSecretApprovalRequestDetails = ({
|
||||
UseQueryOptions<
|
||||
TSecretApprovalRequest,
|
||||
unknown,
|
||||
TSecretApprovalRequest<TSecretApprovalSecChange, DecryptedSecret>,
|
||||
TSecretApprovalRequest<DecryptedSecret>,
|
||||
ReturnType<typeof secretApprovalRequestKeys.detail>
|
||||
>,
|
||||
"queryKey" | "queryFn"
|
||||
@@ -184,11 +184,12 @@ export const useGetSecretApprovalRequestDetails = ({
|
||||
queryFn: () => fetchSecretApprovalRequestDetails({ id }),
|
||||
select: (data) => ({
|
||||
...data,
|
||||
commits: data.commits.map(({ secretVersion, op, newVersion, secret }) => ({
|
||||
commits: data.commits.map(({ secretVersion, op, secret, ...newVersion }) => ({
|
||||
op,
|
||||
secret,
|
||||
secretVersion: secretVersion ? decryptSecrets([secretVersion], decryptKey)[0] : undefined,
|
||||
newVersion: newVersion ? decryptSecretApprovalSecret(newVersion, decryptKey) : undefined
|
||||
newVersion:
|
||||
op !== CommitType.DELETE ? decryptSecretApprovalSecret(newVersion, decryptKey) : undefined
|
||||
}))
|
||||
}),
|
||||
enabled: Boolean(id && decryptKey) && (options?.enabled ?? true)
|
||||
@@ -196,7 +197,7 @@ export const useGetSecretApprovalRequestDetails = ({
|
||||
|
||||
const fetchSecretApprovalRequestCount = async ({ workspaceId }: TGetSecretApprovalRequestCount) => {
|
||||
const { data } = await apiRequest.get<{ approvals: TSecretApprovalRequestCount }>(
|
||||
"/api/v1/secret-approval-requests/count",
|
||||
"/api/ee/v1/secret-approval-requests/count",
|
||||
{ params: { workspaceId } }
|
||||
);
|
||||
|
||||
|
||||
@@ -42,10 +42,7 @@ export type TSecretApprovalSecChange = {
|
||||
tags?: string[];
|
||||
};
|
||||
|
||||
export type TSecretApprovalRequest<
|
||||
T extends unknown = TSecretApprovalSecChangeData,
|
||||
J extends unknown = EncryptedSecret
|
||||
> = {
|
||||
export type TSecretApprovalRequest<J extends unknown = EncryptedSecret> = {
|
||||
id: string;
|
||||
slug: string;
|
||||
createdAt: string;
|
||||
@@ -63,14 +60,13 @@ export type TSecretApprovalRequest<
|
||||
policy: TSecretApprovalPolicy;
|
||||
statusChangeBy: string;
|
||||
conflicts: Array<{ secretId: string; op: CommitType.UPDATE }>;
|
||||
commits: {
|
||||
commits: ({
|
||||
// if there is no secret means it was creation
|
||||
secret?: { version: number };
|
||||
secretVersion: J;
|
||||
// if there is no new version its for Delete
|
||||
newVersion?: T;
|
||||
op: CommitType;
|
||||
}[];
|
||||
} & TSecretApprovalSecChangeData)[];
|
||||
};
|
||||
|
||||
export type TSecretApprovalRequestCount = {
|
||||
|
||||
@@ -14,7 +14,7 @@ export const useCreateSecretRotation = () => {
|
||||
|
||||
return useMutation<{}, {}, TCreateSecretRotationDTO>({
|
||||
mutationFn: async (dto) => {
|
||||
const { data } = await apiRequest.post("/api/v1/secret-rotations", dto);
|
||||
const { data } = await apiRequest.post("/api/ee/v1/secret-rotations", dto);
|
||||
return data;
|
||||
},
|
||||
onSuccess: (_, { workspaceId }) => {
|
||||
@@ -28,7 +28,7 @@ export const useDeleteSecretRotation = () => {
|
||||
|
||||
return useMutation<{}, {}, TDeleteSecretRotationDTO>({
|
||||
mutationFn: async (dto) => {
|
||||
const { data } = await apiRequest.delete(`/api/v1/secret-rotations/${dto.id}`);
|
||||
const { data } = await apiRequest.delete(`/api/ee/v1/secret-rotations/${dto.id}`);
|
||||
return data;
|
||||
},
|
||||
onSuccess: (_, { workspaceId }) => {
|
||||
@@ -42,7 +42,7 @@ export const useRestartSecretRotation = () => {
|
||||
|
||||
return useMutation<{}, {}, TRestartSecretRotationDTO>({
|
||||
mutationFn: async (dto) => {
|
||||
const { data } = await apiRequest.post("/api/v1/secret-rotations/restart", { id: dto.id });
|
||||
const { data } = await apiRequest.post("/api/ee/v1/secret-rotations/restart", { id: dto.id });
|
||||
return data;
|
||||
},
|
||||
onSuccess: (_, { workspaceId }) => {
|
||||
|
||||
@@ -25,7 +25,7 @@ export const secretRotationKeys = {
|
||||
|
||||
const fetchSecretRotationProviders = async ({ workspaceId }: TGetSecretRotationProviders) => {
|
||||
const { data } = await apiRequest.get<TSecretRotationProviderList>(
|
||||
`/api/v1/secret-rotation-providers/${workspaceId}`
|
||||
`/api/ee/v1/secret-rotation-providers/${workspaceId}`
|
||||
);
|
||||
return data;
|
||||
};
|
||||
@@ -55,7 +55,7 @@ const fetchSecretRotations = async ({
|
||||
workspaceId
|
||||
}: Omit<TGetSecretRotationList, "decryptFileKey">) => {
|
||||
const { data } = await apiRequest.get<{ secretRotations: TSecretRotation[] }>(
|
||||
"/api/v1/secret-rotations",
|
||||
"/api/ee/v1/secret-rotations",
|
||||
{ params: { workspaceId } }
|
||||
);
|
||||
return data.secretRotations;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { UserWsKeyPair } from "../keys/types";
|
||||
import { EncryptedSecret } from "../secrets/types";
|
||||
import { WorkspaceEnv } from "../workspace/types";
|
||||
|
||||
export enum TProviderFunctionTypes {
|
||||
HTTP = "http",
|
||||
@@ -31,7 +32,6 @@ export type TDirectAssignOp = {
|
||||
export type TAssignFunction = TJmesPathAssignOp | TDirectAssignOp;
|
||||
|
||||
export type THttpProviderFunction = {
|
||||
type: TProviderFunctionTypes.HTTP;
|
||||
url: string;
|
||||
method: string;
|
||||
header?: Record<string, string>;
|
||||
@@ -41,42 +41,47 @@ export type THttpProviderFunction = {
|
||||
pre?: Record<string, TDirectAssignOp>;
|
||||
};
|
||||
|
||||
export type TDbProviderFunction = {
|
||||
type: TProviderFunctionTypes.DB;
|
||||
client: TDbProviderClients;
|
||||
username: string;
|
||||
password: string;
|
||||
host: string;
|
||||
database: string;
|
||||
port: string;
|
||||
query: string;
|
||||
setter?: Record<string, TAssignFunction>;
|
||||
pre?: Record<string, TDirectAssignOp>;
|
||||
export type TSecretRotationProviderTemplate = {
|
||||
name: string;
|
||||
title: string;
|
||||
image?: string;
|
||||
description?: string;
|
||||
template: THttpProviderTemplate | TDbProviderTemplate;
|
||||
};
|
||||
|
||||
export type TProviderFunction = THttpProviderFunction | TDbProviderFunction;
|
||||
|
||||
export type TProviderTemplate = {
|
||||
export type THttpProviderTemplate = {
|
||||
type: TProviderFunctionTypes.HTTP;
|
||||
inputs: {
|
||||
properties: Record<string, { type: string; helperText?: string; defaultValue?: string }>;
|
||||
type: "object";
|
||||
properties: Record<string, { type: string; [x: string]: unknown; desc?: string }>;
|
||||
required: string[];
|
||||
};
|
||||
outputs: Record<string, unknown>;
|
||||
functions: {
|
||||
set: TProviderFunction;
|
||||
remove?: TProviderFunction;
|
||||
test: TProviderFunction;
|
||||
set: THttpProviderFunction;
|
||||
remove?: THttpProviderFunction;
|
||||
test: THttpProviderFunction;
|
||||
};
|
||||
};
|
||||
|
||||
export type TDbProviderTemplate = {
|
||||
type: TProviderFunctionTypes.DB;
|
||||
inputs: {
|
||||
type: "object";
|
||||
properties: Record<string, { type: string; [x: string]: unknown; desc?: string }>;
|
||||
required: string[];
|
||||
};
|
||||
outputs: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export type TSecretRotation<T extends unknown = EncryptedSecret> = {
|
||||
id: string;
|
||||
interval: number;
|
||||
provider: string;
|
||||
customProvider: string;
|
||||
workspace: string;
|
||||
environment: string;
|
||||
envId: string;
|
||||
environment: WorkspaceEnv;
|
||||
secretPath: string;
|
||||
outputs: Array<{
|
||||
key: string;
|
||||
@@ -89,17 +94,9 @@ export type TSecretRotation<T extends unknown = EncryptedSecret> = {
|
||||
keyEncoding: string;
|
||||
};
|
||||
|
||||
export type TSecretRotationProvider = {
|
||||
name: string;
|
||||
image: string;
|
||||
title: string;
|
||||
description: string;
|
||||
template: TProviderTemplate;
|
||||
};
|
||||
|
||||
export type TSecretRotationProviderList = {
|
||||
custom: TSecretRotationProvider[];
|
||||
providers: TSecretRotationProvider[];
|
||||
custom: TSecretRotationProviderTemplate[];
|
||||
providers: TSecretRotationProviderTemplate[];
|
||||
};
|
||||
|
||||
export type TGetSecretRotationProviders = {
|
||||
|
||||
@@ -15,9 +15,8 @@ export type { TSecretFolder } from "./secretFolders/types";
|
||||
export type { TImportedSecrets, TSecretImport } from "./secretImports/types";
|
||||
export type {
|
||||
TGetSecretRotationProviders,
|
||||
TProviderTemplate,
|
||||
TSecretRotationProvider,
|
||||
TSecretRotationProviderList
|
||||
TSecretRotationProviderList,
|
||||
TSecretRotationProviderTemplate
|
||||
} from "./secretRotation/types";
|
||||
export * from "./secrets/types";
|
||||
export type { CreateServiceTokenDTO, ServiceToken } from "./serviceTokens/types";
|
||||
|
||||
+1
@@ -93,6 +93,7 @@ export const SecretApprovalRequestChanges = ({
|
||||
id: approvalRequestId,
|
||||
decryptKey: decryptFileKey!
|
||||
});
|
||||
console.log(secretApprovalRequestDetails);
|
||||
|
||||
const {
|
||||
mutateAsync: updateSecretApprovalRequestStatus,
|
||||
|
||||
@@ -53,7 +53,7 @@ import {
|
||||
useRestartSecretRotation,
|
||||
useUpdateBotActiveStatus
|
||||
} from "@app/hooks/api";
|
||||
import { TSecretRotationProvider } from "@app/hooks/api/types";
|
||||
import { TSecretRotationProviderTemplate } from "@app/hooks/api/types";
|
||||
|
||||
import { CreateRotationForm } from "./components/CreateRotationForm";
|
||||
import { generateBotKey } from "./SecretRotationPage.utils";
|
||||
@@ -143,7 +143,7 @@ export const SecretRotationPage = withProjectPermission(
|
||||
};
|
||||
|
||||
const handleUserAcceptBotCondition = async () => {
|
||||
const provider = popUp.activeBot?.data as TSecretRotationProvider;
|
||||
const provider = popUp.activeBot?.data as TSecretRotationProviderTemplate;
|
||||
try {
|
||||
if (bot?.id) {
|
||||
const botKey = generateBotKey(bot.publicKey, userWsKey!);
|
||||
@@ -165,7 +165,7 @@ export const SecretRotationPage = withProjectPermission(
|
||||
}
|
||||
};
|
||||
|
||||
const handleCreateRotation = async (provider: TSecretRotationProvider) => {
|
||||
const handleCreateRotation = async (provider: TSecretRotationProviderTemplate) => {
|
||||
if (subscription && !subscription?.secretRotation) {
|
||||
handlePopUpOpen("upgradePlan");
|
||||
return;
|
||||
@@ -256,7 +256,7 @@ export const SecretRotationPage = withProjectPermission(
|
||||
</Td>
|
||||
<Td>
|
||||
<div className="flex w-min items-center rounded border border-bunker-400 p-1 px-2">
|
||||
<div>{environment}</div>
|
||||
<div>{environment.slug}</div>
|
||||
<div className="ml-1 flex items-center border-l border-bunker-400 pl-1 text-xs">
|
||||
<FontAwesomeIcon icon={faFolder} className="mr-1" />
|
||||
{secretPath}
|
||||
@@ -389,7 +389,7 @@ export const SecretRotationPage = withProjectPermission(
|
||||
isOpen={popUp.createRotation.isOpen}
|
||||
workspaceId={workspaceId}
|
||||
onToggle={(isOpen) => handlePopUpToggle("createRotation", isOpen)}
|
||||
provider={(popUp.createRotation.data as TSecretRotationProvider) || {}}
|
||||
provider={(popUp.createRotation.data as TSecretRotationProviderTemplate) || {}}
|
||||
/>
|
||||
<Modal
|
||||
isOpen={popUp.activeBot?.isOpen}
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@ import { AnimatePresence, motion } from "framer-motion";
|
||||
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
|
||||
import { Modal, ModalContent, Step, Stepper } from "@app/components/v2";
|
||||
import { useCreateSecretRotation } from "@app/hooks/api";
|
||||
import { TSecretRotationProvider } from "@app/hooks/api/types";
|
||||
import { TSecretRotationProviderTemplate } from "@app/hooks/api/types";
|
||||
|
||||
import { RotationInputForm } from "./steps/RotationInputForm";
|
||||
import {
|
||||
@@ -28,7 +28,7 @@ type Props = {
|
||||
onToggle: (isOpen: boolean) => void;
|
||||
customProvider?: string;
|
||||
workspaceId: string;
|
||||
provider: TSecretRotationProvider;
|
||||
provider: TSecretRotationProviderTemplate;
|
||||
};
|
||||
|
||||
export const CreateRotationForm = ({
|
||||
|
||||
Reference in New Issue
Block a user