mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
improvement: rollback deprecate all secret rotation v1 create, update UI to only prevent pg/mssql
This commit is contained in:
@@ -23,7 +23,8 @@ export const registerSecretRotationProviderRouter = async (server: FastifyZodPro
|
||||
title: z.string(),
|
||||
image: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
template: z.any()
|
||||
template: z.any(),
|
||||
isDeprecated: z.boolean().optional()
|
||||
})
|
||||
.array()
|
||||
})
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { SecretRotationOutputsSchema, SecretRotationsSchema } from "@app/db/schemas";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { removeTrailingSlash } from "@app/lib/fn";
|
||||
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
@@ -41,10 +40,16 @@ export const registerSecretRotationRouter = async (server: FastifyZodProvider) =
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async () => {
|
||||
throw new BadRequestError({
|
||||
message: `This version of Secret Rotations has been deprecated. Please see docs for new version.`
|
||||
handler: async (req) => {
|
||||
const secretRotation = await server.services.secretRotation.createRotation({
|
||||
actor: req.permission.type,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
...req.body,
|
||||
projectId: req.body.workspaceId
|
||||
});
|
||||
return { secretRotation };
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -127,6 +127,13 @@ export const secretRotationServiceFactory = ({
|
||||
});
|
||||
if (selectedSecrets.length !== Object.values(outputs).length)
|
||||
throw new NotFoundError({ message: `Secrets not found in folder with ID '${folder.id}'` });
|
||||
const rotatedSecrets = selectedSecrets.filter(({ isRotatedSecret }) => isRotatedSecret);
|
||||
if (rotatedSecrets.length)
|
||||
throw new BadRequestError({
|
||||
message: `Selected secrets are already used for rotation: ${rotatedSecrets
|
||||
.map((secret) => secret.key)
|
||||
.join(", ")}`
|
||||
});
|
||||
} else {
|
||||
const selectedSecrets = await secretDAL.find({
|
||||
folderId: folder.id,
|
||||
|
||||
@@ -18,7 +18,8 @@ export const rotationTemplates: TSecretRotationProviderTemplate[] = [
|
||||
title: "PostgreSQL",
|
||||
image: "postgres.png",
|
||||
description: "Rotate PostgreSQL/CockroachDB user credentials",
|
||||
template: POSTGRES_TEMPLATE
|
||||
template: POSTGRES_TEMPLATE,
|
||||
isDeprecated: true
|
||||
},
|
||||
{
|
||||
name: "mysql",
|
||||
@@ -32,7 +33,8 @@ export const rotationTemplates: TSecretRotationProviderTemplate[] = [
|
||||
title: "Microsoft SQL Server",
|
||||
image: "mssqlserver.png",
|
||||
description: "Rotate Microsoft SQL server user credentials",
|
||||
template: MSSQL_TEMPLATE
|
||||
template: MSSQL_TEMPLATE,
|
||||
isDeprecated: true
|
||||
},
|
||||
{
|
||||
name: "aws-iam",
|
||||
|
||||
@@ -50,6 +50,7 @@ export type TSecretRotationProviderTemplate = {
|
||||
image?: string;
|
||||
description?: string;
|
||||
template: THttpProviderTemplate | TDbProviderTemplate | TAwsProviderTemplate;
|
||||
isDeprecated?: boolean;
|
||||
};
|
||||
|
||||
export type THttpProviderTemplate = {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Knex } from "knex";
|
||||
|
||||
import { ProjectType, TProjectKeys, SortDirection } from "@app/db/schemas";
|
||||
import { ProjectType, SortDirection, TProjectKeys } from "@app/db/schemas";
|
||||
import { TSshCertificateAuthorityDALFactory } from "@app/ee/services/ssh/ssh-certificate-authority-dal";
|
||||
import { TSshCertificateAuthoritySecretDALFactory } from "@app/ee/services/ssh/ssh-certificate-authority-secret-dal";
|
||||
import { OrgServiceActor, TProjectPermission } from "@app/lib/types";
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { TProjectSshConfigDALFactory } from "@app/services/project/project-ssh-config-dal";
|
||||
import { OrgServiceActor, TProjectPermission } from "@app/lib/types";
|
||||
|
||||
import { ActorAuthMethod, ActorType } from "../auth/auth-type";
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ export type TSecretRotationProviderTemplate = {
|
||||
image?: string;
|
||||
description?: string;
|
||||
template: THttpProviderTemplate | TDbProviderTemplate;
|
||||
isDeprecated?: boolean;
|
||||
};
|
||||
|
||||
export type THttpProviderTemplate = {
|
||||
|
||||
@@ -38,7 +38,12 @@ import {
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { NoticeBannerV2 } from "@app/components/v2/NoticeBannerV2/NoticeBannerV2";
|
||||
import { ProjectPermissionSub, useWorkspace } from "@app/context";
|
||||
import {
|
||||
ProjectPermissionSub,
|
||||
useProjectPermission,
|
||||
useSubscription,
|
||||
useWorkspace
|
||||
} from "@app/context";
|
||||
import { ProjectPermissionSecretRotationActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import {
|
||||
@@ -47,20 +52,29 @@ import {
|
||||
useGetSecretRotations,
|
||||
useRestartSecretRotation
|
||||
} from "@app/hooks/api";
|
||||
import { TSecretRotationProviderTemplate } from "@app/hooks/api/secretRotation/types";
|
||||
import { ProjectType } from "@app/hooks/api/workspace/types";
|
||||
import { CreateRotationForm } from "@app/pages/secret-manager/SecretRotationPage/components/CreateRotationForm";
|
||||
|
||||
const Page = () => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { permission } = useProjectPermission();
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { popUp, handlePopUpOpen, handlePopUpToggle, handlePopUpClose } = usePopUp([
|
||||
"createRotation",
|
||||
"activeBot",
|
||||
"deleteRotation",
|
||||
"upgradePlan",
|
||||
"secretRotationV2"
|
||||
] as const);
|
||||
const workspaceId = currentWorkspace?.id || "";
|
||||
const canCreateRotation = permission.can(
|
||||
ProjectPermissionSecretRotationActions.Create,
|
||||
ProjectPermissionSub.SecretRotation
|
||||
);
|
||||
const { subscription } = useSubscription();
|
||||
|
||||
const { data: secretRotationProviders, isPending: isRotationProviderLoading } =
|
||||
useGetSecretRotationProviders({ workspaceId });
|
||||
@@ -119,6 +133,18 @@ const Page = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleCreateRotation = (provider: TSecretRotationProviderTemplate) => {
|
||||
if (subscription && !subscription?.secretRotation) {
|
||||
handlePopUpOpen("upgradePlan");
|
||||
return;
|
||||
}
|
||||
if (!canCreateRotation) {
|
||||
createNotification({ type: "error", text: "Access permission denied!!" });
|
||||
return;
|
||||
}
|
||||
handlePopUpOpen("createRotation", provider);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container mx-auto w-full max-w-7xl bg-bunker-800 text-white">
|
||||
<PageHeader
|
||||
@@ -144,7 +170,7 @@ const Page = () => {
|
||||
Infisical is revamping its Secret Rotation experience.
|
||||
</p>
|
||||
<p className="mt-2 text-sm text-bunker-200">
|
||||
Secret Rotations can now be created from the{" "}
|
||||
PostgreSQL and Microsoft SQL Server Rotations can now be created from the{" "}
|
||||
<Link
|
||||
className="text-mineshaft-100 underline decoration-primary underline-offset-2 hover:text-mineshaft-200"
|
||||
to={`/${ProjectType.SecretManager}/$projectId/overview` as const}
|
||||
@@ -308,11 +334,20 @@ const Page = () => {
|
||||
key={`infisical-rotation-provider-${provider.name}`}
|
||||
tabIndex={0}
|
||||
role="button"
|
||||
onKeyDown={() => {
|
||||
handlePopUpOpen("secretRotationV2", provider.title);
|
||||
onKeyDown={(evt) => {
|
||||
if (evt.key !== "Enter") return;
|
||||
if (provider.isDeprecated) {
|
||||
handlePopUpOpen("secretRotationV2", provider.title);
|
||||
} else {
|
||||
handleCreateRotation(provider);
|
||||
}
|
||||
}}
|
||||
onClick={() => {
|
||||
handlePopUpOpen("secretRotationV2", provider.title);
|
||||
if (provider.isDeprecated) {
|
||||
handlePopUpOpen("secretRotationV2", provider.title);
|
||||
} else {
|
||||
handleCreateRotation(provider);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<img
|
||||
@@ -344,6 +379,12 @@ const Page = () => {
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<CreateRotationForm
|
||||
isOpen={popUp.createRotation.isOpen}
|
||||
workspaceId={workspaceId}
|
||||
onToggle={(isOpen) => handlePopUpToggle("createRotation", isOpen)}
|
||||
provider={(popUp.createRotation.data as TSecretRotationProviderTemplate) || {}}
|
||||
/>
|
||||
<DeleteActionModal
|
||||
isOpen={popUp.deleteRotation.isOpen}
|
||||
title="Are you sure want to delete this rotation?"
|
||||
@@ -372,7 +413,7 @@ const Page = () => {
|
||||
>
|
||||
Secret Manager Dashboard
|
||||
</Link>{" "}
|
||||
to create a Secret Rotation.
|
||||
to create a {popUp.secretRotationV2.data} Rotation.
|
||||
</p>
|
||||
<div className="overflow-clip rounded border border-mineshaft-600">
|
||||
<img
|
||||
|
||||
Reference in New Issue
Block a user