From 3c5c6aeca8534bb2a02422ec0f4ff4c4594fbe29 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 11 Apr 2025 23:09:27 +0530 Subject: [PATCH 01/23] feat: updated error message on update org for saml/oidc enforcement --- .../src/ee/services/oidc/oidc-config-dal.ts | 20 +------------ .../services/saml-config/saml-config-dal.ts | 23 +-------------- backend/src/services/org/org-service.ts | 28 ++++++++++++++++--- 3 files changed, 26 insertions(+), 45 deletions(-) diff --git a/backend/src/ee/services/oidc/oidc-config-dal.ts b/backend/src/ee/services/oidc/oidc-config-dal.ts index ffdba2cf7..b9b0a2659 100644 --- a/backend/src/ee/services/oidc/oidc-config-dal.ts +++ b/backend/src/ee/services/oidc/oidc-config-dal.ts @@ -1,6 +1,5 @@ import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; -import { DatabaseError } from "@app/lib/errors"; import { ormify } from "@app/lib/knex"; export type TOidcConfigDALFactory = ReturnType; @@ -8,22 +7,5 @@ export type TOidcConfigDALFactory = ReturnType; export const oidcConfigDALFactory = (db: TDbClient) => { const oidcCfgOrm = ormify(db, TableName.OidcConfig); - const findEnforceableOidcCfg = async (orgId: string) => { - try { - const oidcCfg = await db - .replicaNode()(TableName.OidcConfig) - .where({ - orgId, - isActive: true - }) - .whereNotNull("lastUsed") - .first(); - - return oidcCfg; - } catch (error) { - throw new DatabaseError({ error, name: "Find org by id" }); - } - }; - - return { ...oidcCfgOrm, findEnforceableOidcCfg }; + return oidcCfgOrm; }; diff --git a/backend/src/ee/services/saml-config/saml-config-dal.ts b/backend/src/ee/services/saml-config/saml-config-dal.ts index aff42230f..c82adcb89 100644 --- a/backend/src/ee/services/saml-config/saml-config-dal.ts +++ b/backend/src/ee/services/saml-config/saml-config-dal.ts @@ -1,6 +1,5 @@ import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; -import { DatabaseError } from "@app/lib/errors"; import { ormify } from "@app/lib/knex"; export type TSamlConfigDALFactory = ReturnType; @@ -8,25 +7,5 @@ export type TSamlConfigDALFactory = ReturnType; export const samlConfigDALFactory = (db: TDbClient) => { const samlCfgOrm = ormify(db, TableName.SamlConfig); - const findEnforceableSamlCfg = async (orgId: string) => { - try { - const samlCfg = await db - .replicaNode()(TableName.SamlConfig) - .where({ - orgId, - isActive: true - }) - .whereNotNull("lastUsed") - .first(); - - return samlCfg; - } catch (error) { - throw new DatabaseError({ error, name: "Find org by id" }); - } - }; - - return { - ...samlCfgOrm, - findEnforceableSamlCfg - }; + return samlCfgOrm; }; diff --git a/backend/src/services/org/org-service.ts b/backend/src/services/org/org-service.ts index 98b35f68f..455d0ab22 100644 --- a/backend/src/services/org/org-service.ts +++ b/backend/src/services/org/org-service.ts @@ -110,8 +110,8 @@ type TOrgServiceFactoryDep = { projectKeyDAL: Pick; orgMembershipDAL: Pick; incidentContactDAL: TIncidentContactsDALFactory; - samlConfigDAL: Pick; - oidcConfigDAL: Pick; + samlConfigDAL: Pick; + oidcConfigDAL: Pick; smtpService: TSmtpService; tokenService: TAuthTokenServiceFactory; permissionService: TPermissionServiceFactory; @@ -402,13 +402,33 @@ export const orgServiceFactory = ({ } if (authEnforced) { - const samlCfg = await samlConfigDAL.findEnforceableSamlCfg(orgId); - const oidcCfg = await oidcConfigDAL.findEnforceableOidcCfg(orgId); + const samlCfg = await samlConfigDAL.findOne({ + orgId, + isActive: true + }); + const oidcCfg = await oidcConfigDAL.findOne({ + orgId, + isActive: true + }); if (!samlCfg && !oidcCfg) throw new NotFoundError({ message: `SAML or OIDC configuration for organization with ID '${orgId}' not found` }); + + if (samlCfg && !samlCfg.lastUsed) { + throw new BadRequestError({ + message: + "To apply the new SAML auth enforcement, please log in via SAML again. This step is required to enforce SAML-based authentication." + }); + } + + if (oidcCfg && !oidcCfg.lastUsed) { + throw new BadRequestError({ + message: + "To apply the new SAML auth enforcement, please log in via SAML again. This step is required to enforce SAML-based authentication." + }); + } } let defaultMembershipRole: string | undefined; From 7dcd3d24aa354b3dceaf835f36232a2018c3c226 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 11 Apr 2025 23:11:23 +0530 Subject: [PATCH 02/23] feat: corrected oidc message --- backend/src/services/org/org-service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/services/org/org-service.ts b/backend/src/services/org/org-service.ts index 455d0ab22..531673806 100644 --- a/backend/src/services/org/org-service.ts +++ b/backend/src/services/org/org-service.ts @@ -426,7 +426,7 @@ export const orgServiceFactory = ({ if (oidcCfg && !oidcCfg.lastUsed) { throw new BadRequestError({ message: - "To apply the new SAML auth enforcement, please log in via SAML again. This step is required to enforce SAML-based authentication." + "To apply the new OIDC auth enforcement, please log in via OIDC again. This step is required to enforce OIDC-based authentication." }); } } From dd323eccd44a404fac54eb17d8b8e878b11262f9 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 15 Apr 2025 22:00:22 +0530 Subject: [PATCH 03/23] feat: added banner on projects when limit reached --- .../layouts/ProjectLayout/ProjectLayout.tsx | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx b/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx index 8b0d88ad5..caab7ddff 100644 --- a/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx +++ b/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx @@ -1,9 +1,10 @@ import { useTranslation } from "react-i18next"; import { faMobile } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Link, Outlet, useRouterState } from "@tanstack/react-router"; +import { Link, Outlet, useNavigate, useRouterState } from "@tanstack/react-router"; import { motion } from "framer-motion"; +import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal"; import { BreadcrumbContainer, Menu, @@ -31,6 +32,19 @@ export const ProjectLayout = () => { const { t } = useTranslation(); const workspaceId = currentWorkspace?.id || ""; const projectSlug = currentWorkspace?.slug || ""; + const { subscription } = useSubscription(); + const navigate = useNavigate(); + const hasIdentityLimitCrossed = + subscription?.identityLimit && subscription?.identitiesUsed > subscription?.identityLimit; + const hasUserLimitCrossed = + subscription?.memberLimit && subscription?.membersUsed > subscription?.memberLimit; + const shouldUpgrade = Boolean(hasUserLimitCrossed || hasIdentityLimitCrossed); + let upgradeText = ""; + if (hasUserLimitCrossed) { + upgradeText = `You've reached the maximum number of organisation users(${subscription.membersUsed}/${subscription?.memberLimit}).`; + } else if (hasIdentityLimitCrossed) { + upgradeText = `You've reached the maximum number of organisation identities(${subscription.identitiesUsed}/${subscription?.identityLimit}).`; + } const isSecretManager = currentWorkspace?.type === ProjectType.SecretManager; const isCertManager = currentWorkspace?.type === ProjectType.CertificateManager; @@ -47,7 +61,6 @@ export const ProjectLayout = () => { }); // we only show the secret rotations v1 tab if they have existing rotations - const { subscription } = useSubscription(); const { data: secretRotations } = useGetSecretRotations({ workspaceId, options: { @@ -267,6 +280,17 @@ export const ProjectLayout = () => { + {shouldUpgrade && ( + { + if (!isOpen) { + navigate({ to: "/organization/access-management" }); + } + }} + /> + )}

From ac73800acb3a0701d91c877de164d8715f0f97a1 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 16 Apr 2025 00:25:21 +0530 Subject: [PATCH 04/23] feat: added banner on crossing user/identity limit --- frontend/src/layouts/ProjectLayout/ProjectLayout.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx b/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx index caab7ddff..948b65e9d 100644 --- a/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx +++ b/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx @@ -41,9 +41,9 @@ export const ProjectLayout = () => { const shouldUpgrade = Boolean(hasUserLimitCrossed || hasIdentityLimitCrossed); let upgradeText = ""; if (hasUserLimitCrossed) { - upgradeText = `You've reached the maximum number of organisation users(${subscription.membersUsed}/${subscription?.memberLimit}).`; + upgradeText = `You've reached the maximum number of organisation users(${subscription?.memberLimit}).`; } else if (hasIdentityLimitCrossed) { - upgradeText = `You've reached the maximum number of organisation identities(${subscription.identitiesUsed}/${subscription?.identityLimit}).`; + upgradeText = `You've reached the maximum number of organisation identities(${subscription?.identityLimit}).`; } const isSecretManager = currentWorkspace?.type === ProjectType.SecretManager; From 5b20c1feba19c04fff4a1951d32e2618a127ca4a Mon Sep 17 00:00:00 2001 From: = Date: Wed, 16 Apr 2025 00:30:11 +0530 Subject: [PATCH 05/23] feat: reptile jaw spaced --- frontend/src/layouts/ProjectLayout/ProjectLayout.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx b/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx index 948b65e9d..92356b9d7 100644 --- a/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx +++ b/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx @@ -41,9 +41,9 @@ export const ProjectLayout = () => { const shouldUpgrade = Boolean(hasUserLimitCrossed || hasIdentityLimitCrossed); let upgradeText = ""; if (hasUserLimitCrossed) { - upgradeText = `You've reached the maximum number of organisation users(${subscription?.memberLimit}).`; + upgradeText = `You've reached the maximum number of organisation users (${subscription?.memberLimit}).`; } else if (hasIdentityLimitCrossed) { - upgradeText = `You've reached the maximum number of organisation identities(${subscription?.identityLimit}).`; + upgradeText = `You've reached the maximum number of organisation identities (${subscription?.identityLimit}).`; } const isSecretManager = currentWorkspace?.type === ProjectType.SecretManager; From 7364717f6044ee74408ec16490edfdda6078338d Mon Sep 17 00:00:00 2001 From: = Date: Fri, 18 Apr 2025 22:35:41 +0530 Subject: [PATCH 06/23] feat: added an additional 10 as threshold --- frontend/src/layouts/ProjectLayout/ProjectLayout.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx b/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx index 92356b9d7..0e2d8bba9 100644 --- a/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx +++ b/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx @@ -35,9 +35,9 @@ export const ProjectLayout = () => { const { subscription } = useSubscription(); const navigate = useNavigate(); const hasIdentityLimitCrossed = - subscription?.identityLimit && subscription?.identitiesUsed > subscription?.identityLimit; + subscription?.identityLimit && subscription?.identitiesUsed > subscription.identityLimit + 10; const hasUserLimitCrossed = - subscription?.memberLimit && subscription?.membersUsed > subscription?.memberLimit; + subscription?.memberLimit && subscription?.membersUsed > subscription.memberLimit + 10; const shouldUpgrade = Boolean(hasUserLimitCrossed || hasIdentityLimitCrossed); let upgradeText = ""; if (hasUserLimitCrossed) { From 80edccc953983b1eac2b67a3391cb7a87282cfe8 Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Sun, 20 Apr 2025 12:06:34 -0400 Subject: [PATCH 07/23] Update org-service.ts --- backend/src/services/org/org-service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/services/org/org-service.ts b/backend/src/services/org/org-service.ts index 531673806..86625d71a 100644 --- a/backend/src/services/org/org-service.ts +++ b/backend/src/services/org/org-service.ts @@ -419,14 +419,14 @@ export const orgServiceFactory = ({ if (samlCfg && !samlCfg.lastUsed) { throw new BadRequestError({ message: - "To apply the new SAML auth enforcement, please log in via SAML again. This step is required to enforce SAML-based authentication." + "To apply the new SAML auth enforcement, please log in via SAML at least once. This step is required to enforce SAML-based authentication." }); } if (oidcCfg && !oidcCfg.lastUsed) { throw new BadRequestError({ message: - "To apply the new OIDC auth enforcement, please log in via OIDC again. This step is required to enforce OIDC-based authentication." + "To apply the new OIDC auth enforcement, please log in via OIDC at least once. This step is required to enforce OIDC-based authentication." }); } } From 5fccc6221316486130908b6c6da780e32cca92c1 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 21 Apr 2025 13:22:42 +0530 Subject: [PATCH 08/23] feat: updated docs to include various endpoints in cli only --- .../routes/v1/dynamic-secret-lease-router.ts | 10 ++- .../src/ee/routes/v1/dynamic-secret-router.ts | 14 +++- backend/src/ee/routes/v1/group-router.ts | 18 ++++- backend/src/ee/routes/v1/project-router.ts | 4 +- .../ee/routes/v1/project-template-router.ts | 12 +++- backend/src/ee/routes/v1/snapshot-router.ts | 4 +- .../v1/ssh-certificate-authority-router.ts | 14 +++- .../ee/routes/v1/ssh-certificate-router.ts | 6 +- .../v1/ssh-certificate-template-router.ts | 10 ++- ...ity-project-additional-privilege-router.ts | 14 +++- .../src/ee/routes/v2/project-role-router.ts | 12 +++- .../secret-rotation-v2-endpoints.ts | 18 ++++- .../secret-rotation-v2-router.ts | 6 +- backend/src/lib/api-docs/constants.ts | 69 +++++++++++++++++++ backend/src/main.ts | 16 +++-- backend/src/server/plugins/fastify-zod.ts | 7 +- .../app-connection-endpoints.ts | 16 ++++- .../app-connection-router.ts | 5 ++ .../routes/v1/certificate-authority-router.ts | 32 ++++++++- .../server/routes/v1/certificate-router.ts | 14 +++- .../routes/v1/certificate-template-router.ts | 16 ++++- backend/src/server/routes/v1/cmek-router.ts | 26 ++++++- .../routes/v1/identity-access-token-router.ts | 6 +- .../routes/v1/identity-aws-iam-auth-router.ts | 12 +++- .../routes/v1/identity-azure-auth-router.ts | 12 +++- .../routes/v1/identity-gcp-auth-router.ts | 12 +++- .../routes/v1/identity-jwt-auth-router.ts | 12 +++- .../v1/identity-kubernetes-auth-router.ts | 12 +++- .../routes/v1/identity-oidc-auth-router.ts | 12 +++- .../src/server/routes/v1/identity-router.ts | 14 +++- .../routes/v1/identity-token-auth-router.ts | 18 ++++- .../v1/identity-universal-auth-router.ts | 20 +++++- .../routes/v1/integration-auth-router.ts | 14 +++- .../server/routes/v1/integration-router.ts | 12 +++- .../server/routes/v1/organization-router.ts | 4 +- .../src/server/routes/v1/pki-alert-router.ts | 10 ++- .../server/routes/v1/pki-collection-router.ts | 16 ++++- .../server/routes/v1/project-env-router.ts | 12 +++- .../routes/v1/project-membership-router.ts | 8 ++- .../src/server/routes/v1/project-router.ts | 8 ++- .../server/routes/v1/secret-folder-router.ts | 14 +++- .../server/routes/v1/secret-import-router.ts | 12 +++- .../secret-sync-endpoints.ts | 20 +++++- .../secret-sync-routers/secret-sync-router.ts | 6 +- .../src/server/routes/v1/secret-tag-router.ts | 14 +++- .../server/routes/v2/group-project-router.ts | 12 +++- .../server/routes/v2/identity-org-router.ts | 4 +- .../routes/v2/identity-project-router.ts | 14 +++- .../server/routes/v2/organization-router.ts | 10 ++- .../routes/v2/project-membership-router.ts | 6 +- .../src/server/routes/v2/project-router.ts | 6 +- .../server/routes/v2/service-token-router.ts | 3 + backend/src/server/routes/v3/secret-router.ts | 28 +++++++- 53 files changed, 650 insertions(+), 56 deletions(-) diff --git a/backend/src/ee/routes/v1/dynamic-secret-lease-router.ts b/backend/src/ee/routes/v1/dynamic-secret-lease-router.ts index b75a2dae0..7c42c7f99 100644 --- a/backend/src/ee/routes/v1/dynamic-secret-lease-router.ts +++ b/backend/src/ee/routes/v1/dynamic-secret-lease-router.ts @@ -1,7 +1,7 @@ import { z } from "zod"; import { DynamicSecretLeasesSchema } from "@app/db/schemas"; -import { DYNAMIC_SECRET_LEASES } from "@app/lib/api-docs"; +import { ApiDocsTags, DYNAMIC_SECRET_LEASES } from "@app/lib/api-docs"; import { daysToMillisecond } from "@app/lib/dates"; import { removeTrailingSlash } from "@app/lib/fn"; import { ms } from "@app/lib/ms"; @@ -18,6 +18,8 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.DynamicSecrets], body: z.object({ dynamicSecretName: z.string().min(1).describe(DYNAMIC_SECRET_LEASES.CREATE.dynamicSecretName).toLowerCase(), projectSlug: z.string().min(1).describe(DYNAMIC_SECRET_LEASES.CREATE.projectSlug), @@ -65,6 +67,8 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.DynamicSecrets], params: z.object({ leaseId: z.string().min(1).describe(DYNAMIC_SECRET_LEASES.DELETE.leaseId) }), @@ -107,6 +111,8 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.DynamicSecrets], params: z.object({ leaseId: z.string().min(1).describe(DYNAMIC_SECRET_LEASES.RENEW.leaseId) }), @@ -160,6 +166,8 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.DynamicSecrets], params: z.object({ leaseId: z.string().min(1).describe(DYNAMIC_SECRET_LEASES.GET_BY_LEASEID.leaseId) }), diff --git a/backend/src/ee/routes/v1/dynamic-secret-router.ts b/backend/src/ee/routes/v1/dynamic-secret-router.ts index fdaaf5932..3ff4fae7c 100644 --- a/backend/src/ee/routes/v1/dynamic-secret-router.ts +++ b/backend/src/ee/routes/v1/dynamic-secret-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { DynamicSecretLeasesSchema } from "@app/db/schemas"; import { DynamicSecretProviderSchema } from "@app/ee/services/dynamic-secret/providers/models"; -import { DYNAMIC_SECRETS } from "@app/lib/api-docs"; +import { ApiDocsTags, DYNAMIC_SECRETS } from "@app/lib/api-docs"; import { daysToMillisecond } from "@app/lib/dates"; import { removeTrailingSlash } from "@app/lib/fn"; import { ms } from "@app/lib/ms"; @@ -21,6 +21,8 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.DynamicSecrets], body: z.object({ projectSlug: z.string().min(1).describe(DYNAMIC_SECRETS.CREATE.projectSlug), provider: DynamicSecretProviderSchema.describe(DYNAMIC_SECRETS.CREATE.provider), @@ -111,6 +113,8 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.DynamicSecrets], params: z.object({ name: z.string().toLowerCase().describe(DYNAMIC_SECRETS.UPDATE.name) }), @@ -179,6 +183,8 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.DynamicSecrets], params: z.object({ name: z.string().toLowerCase().describe(DYNAMIC_SECRETS.DELETE.name) }), @@ -215,6 +221,8 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.DynamicSecrets], params: z.object({ name: z.string().min(1).describe(DYNAMIC_SECRETS.GET_BY_NAME.name) }), @@ -253,6 +261,8 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.DynamicSecrets], querystring: z.object({ projectSlug: z.string().min(1).describe(DYNAMIC_SECRETS.LIST.projectSlug), path: z.string().trim().default("/").transform(removeTrailingSlash).describe(DYNAMIC_SECRETS.LIST.path), @@ -284,6 +294,8 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.DynamicSecrets], params: z.object({ name: z.string().min(1).describe(DYNAMIC_SECRETS.LIST_LEAES_BY_NAME.name) }), diff --git a/backend/src/ee/routes/v1/group-router.ts b/backend/src/ee/routes/v1/group-router.ts index 67f955ecb..d10e1800b 100644 --- a/backend/src/ee/routes/v1/group-router.ts +++ b/backend/src/ee/routes/v1/group-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { GroupsSchema, OrgMembershipRole, UsersSchema } from "@app/db/schemas"; import { EFilterReturnedUsers } from "@app/ee/services/group/group-types"; -import { GROUPS } from "@app/lib/api-docs"; +import { ApiDocsTags, GROUPS } from "@app/lib/api-docs"; import { slugSchema } from "@app/server/lib/schemas"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -13,6 +13,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => { method: "POST", onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Groups], body: z.object({ name: z.string().trim().min(1).max(50).describe(GROUPS.CREATE.name), slug: slugSchema({ min: 5, max: 36 }).optional().describe(GROUPS.CREATE.slug), @@ -40,6 +42,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => { method: "GET", onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Groups], params: z.object({ id: z.string().trim().describe(GROUPS.GET_BY_ID.id) }), @@ -65,6 +69,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => { method: "GET", onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Groups], response: { 200: GroupsSchema.array() } @@ -87,6 +93,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => { method: "PATCH", onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Groups], params: z.object({ id: z.string().trim().describe(GROUPS.UPDATE.id) }), @@ -120,6 +128,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => { method: "DELETE", onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Groups], params: z.object({ id: z.string().trim().describe(GROUPS.DELETE.id) }), @@ -145,6 +155,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => { url: "/:id/users", onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Groups], params: z.object({ id: z.string().trim().describe(GROUPS.LIST_USERS.id) }), @@ -194,6 +206,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => { url: "/:id/users/:username", onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Groups], params: z.object({ id: z.string().trim().describe(GROUPS.ADD_USER.id), username: z.string().trim().describe(GROUPS.ADD_USER.username) @@ -227,6 +241,8 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => { url: "/:id/users/:username", onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Groups], params: z.object({ id: z.string().trim().describe(GROUPS.DELETE_USER.id), username: z.string().trim().describe(GROUPS.DELETE_USER.username) diff --git a/backend/src/ee/routes/v1/project-router.ts b/backend/src/ee/routes/v1/project-router.ts index e3956731e..ab9d1be6c 100644 --- a/backend/src/ee/routes/v1/project-router.ts +++ b/backend/src/ee/routes/v1/project-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { AuditLogsSchema, SecretSnapshotsSchema } from "@app/db/schemas"; import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types"; -import { AUDIT_LOGS, PROJECTS } from "@app/lib/api-docs"; +import { ApiDocsTags, AUDIT_LOGS, PROJECTS } from "@app/lib/api-docs"; import { getLastMidnightDateISO, removeTrailingSlash } from "@app/lib/fn"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -17,6 +17,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Projects], description: "Return project secret snapshots ids", security: [ { diff --git a/backend/src/ee/routes/v1/project-template-router.ts b/backend/src/ee/routes/v1/project-template-router.ts index cabf65337..08d16414b 100644 --- a/backend/src/ee/routes/v1/project-template-router.ts +++ b/backend/src/ee/routes/v1/project-template-router.ts @@ -5,7 +5,7 @@ import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission"; import { ProjectTemplateDefaultEnvironments } from "@app/ee/services/project-template/project-template-constants"; import { isInfisicalProjectTemplate } from "@app/ee/services/project-template/project-template-fns"; -import { ProjectTemplates } from "@app/lib/api-docs"; +import { ApiDocsTags, ProjectTemplates } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { slugSchema } from "@app/server/lib/schemas"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -101,6 +101,8 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider) rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectTemplates], description: "List project templates for the current organization.", response: { 200: z.object({ @@ -137,6 +139,8 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider) rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectTemplates], description: "Get a project template by ID.", params: z.object({ templateId: z.string().uuid() @@ -176,6 +180,8 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider) rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectTemplates], description: "Create a project template.", body: z.object({ name: slugSchema({ field: "name" }) @@ -219,6 +225,8 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider) rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectTemplates], description: "Update a project template.", params: z.object({ templateId: z.string().uuid().describe(ProjectTemplates.UPDATE.templateId) }), body: z.object({ @@ -269,6 +277,8 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider) rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectTemplates], description: "Delete a project template.", params: z.object({ templateId: z.string().uuid().describe(ProjectTemplates.DELETE.templateId) }), diff --git a/backend/src/ee/routes/v1/snapshot-router.ts b/backend/src/ee/routes/v1/snapshot-router.ts index 494871ec1..3ee80adce 100644 --- a/backend/src/ee/routes/v1/snapshot-router.ts +++ b/backend/src/ee/routes/v1/snapshot-router.ts @@ -1,7 +1,7 @@ import { z } from "zod"; import { SecretSnapshotsSchema } from "@app/db/schemas"; -import { PROJECTS } from "@app/lib/api-docs"; +import { ApiDocsTags, PROJECTS } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { SanitizedTagSchema, secretRawSchema } from "@app/server/routes/sanitizedSchemas"; @@ -65,6 +65,8 @@ export const registerSnapshotRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Projects], description: "Roll back project secrets to those captured in a secret snapshot version.", security: [ { diff --git a/backend/src/ee/routes/v1/ssh-certificate-authority-router.ts b/backend/src/ee/routes/v1/ssh-certificate-authority-router.ts index 783cb9b72..e20d49263 100644 --- a/backend/src/ee/routes/v1/ssh-certificate-authority-router.ts +++ b/backend/src/ee/routes/v1/ssh-certificate-authority-router.ts @@ -6,7 +6,7 @@ import { sanitizedSshCa } from "@app/ee/services/ssh/ssh-certificate-authority-s import { SshCaKeySource, SshCaStatus } from "@app/ee/services/ssh/ssh-certificate-authority-types"; import { SshCertKeyAlgorithm } from "@app/ee/services/ssh-certificate/ssh-certificate-types"; import { sanitizedSshCertificateTemplate } from "@app/ee/services/ssh-certificate-template/ssh-certificate-template-schema"; -import { SSH_CERTIFICATE_AUTHORITIES } from "@app/lib/api-docs"; +import { ApiDocsTags, SSH_CERTIFICATE_AUTHORITIES } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -20,6 +20,8 @@ export const registerSshCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.SshCertificateAuthorities], description: "Create SSH CA", body: z .object({ @@ -92,6 +94,8 @@ export const registerSshCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.SshCertificateAuthorities], description: "Get SSH CA", params: z.object({ sshCaId: z.string().trim().describe(SSH_CERTIFICATE_AUTHORITIES.GET.sshCaId) @@ -138,6 +142,8 @@ export const registerSshCaRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SshCertificateAuthorities], description: "Get public key of SSH CA", params: z.object({ sshCaId: z.string().trim().describe(SSH_CERTIFICATE_AUTHORITIES.GET_PUBLIC_KEY.sshCaId) @@ -163,6 +169,8 @@ export const registerSshCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.SshCertificateAuthorities], description: "Update SSH CA", params: z.object({ sshCaId: z.string().trim().describe(SSH_CERTIFICATE_AUTHORITIES.UPDATE.sshCaId) @@ -216,6 +224,8 @@ export const registerSshCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.SshCertificateAuthorities], description: "Delete SSH CA", params: z.object({ sshCaId: z.string().trim().describe(SSH_CERTIFICATE_AUTHORITIES.DELETE.sshCaId) @@ -261,6 +271,8 @@ export const registerSshCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.SshCertificateAuthorities], description: "Get list of certificate templates for the SSH CA", params: z.object({ sshCaId: z.string().trim().describe(SSH_CERTIFICATE_AUTHORITIES.GET_CERTIFICATE_TEMPLATES.sshCaId) diff --git a/backend/src/ee/routes/v1/ssh-certificate-router.ts b/backend/src/ee/routes/v1/ssh-certificate-router.ts index eb0fc158a..cb576e496 100644 --- a/backend/src/ee/routes/v1/ssh-certificate-router.ts +++ b/backend/src/ee/routes/v1/ssh-certificate-router.ts @@ -3,7 +3,7 @@ import { z } from "zod"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { SshCertType } from "@app/ee/services/ssh/ssh-certificate-authority-types"; import { SshCertKeyAlgorithm } from "@app/ee/services/ssh-certificate/ssh-certificate-types"; -import { SSH_CERTIFICATE_AUTHORITIES } from "@app/lib/api-docs"; +import { ApiDocsTags, SSH_CERTIFICATE_AUTHORITIES } from "@app/lib/api-docs"; import { ms } from "@app/lib/ms"; import { writeLimit } from "@app/server/config/rateLimiter"; import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; @@ -20,6 +20,8 @@ export const registerSshCertRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.SshCertificates], description: "Sign SSH public key", body: z.object({ certificateTemplateId: z @@ -100,6 +102,8 @@ export const registerSshCertRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.SshCertificates], description: "Issue SSH credentials (certificate + key)", body: z.object({ certificateTemplateId: z diff --git a/backend/src/ee/routes/v1/ssh-certificate-template-router.ts b/backend/src/ee/routes/v1/ssh-certificate-template-router.ts index a7dc55661..e44693643 100644 --- a/backend/src/ee/routes/v1/ssh-certificate-template-router.ts +++ b/backend/src/ee/routes/v1/ssh-certificate-template-router.ts @@ -8,7 +8,7 @@ import { isValidHostPattern, isValidUserPattern } from "@app/ee/services/ssh-certificate-template/ssh-certificate-template-validators"; -import { SSH_CERTIFICATE_TEMPLATES } from "@app/lib/api-docs"; +import { ApiDocsTags, SSH_CERTIFICATE_TEMPLATES } from "@app/lib/api-docs"; import { ms } from "@app/lib/ms"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -22,6 +22,8 @@ export const registerSshCertificateTemplateRouter = async (server: FastifyZodPro rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SshCertificateTemplates], params: z.object({ certificateTemplateId: z.string().describe(SSH_CERTIFICATE_TEMPLATES.GET.certificateTemplateId) }), @@ -61,6 +63,8 @@ export const registerSshCertificateTemplateRouter = async (server: FastifyZodPro rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SshCertificateTemplates], body: z .object({ sshCaId: z.string().describe(SSH_CERTIFICATE_TEMPLATES.CREATE.sshCaId), @@ -141,6 +145,8 @@ export const registerSshCertificateTemplateRouter = async (server: FastifyZodPro rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SshCertificateTemplates], body: z.object({ status: z.nativeEnum(SshCertTemplateStatus).optional(), name: z @@ -224,6 +230,8 @@ export const registerSshCertificateTemplateRouter = async (server: FastifyZodPro rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SshCertificateTemplates], params: z.object({ certificateTemplateId: z.string().describe(SSH_CERTIFICATE_TEMPLATES.DELETE.certificateTemplateId) }), diff --git a/backend/src/ee/routes/v2/identity-project-additional-privilege-router.ts b/backend/src/ee/routes/v2/identity-project-additional-privilege-router.ts index c8f0ba16c..f5c5f0459 100644 --- a/backend/src/ee/routes/v2/identity-project-additional-privilege-router.ts +++ b/backend/src/ee/routes/v2/identity-project-additional-privilege-router.ts @@ -4,7 +4,7 @@ import { z } from "zod"; import { IdentityProjectAdditionalPrivilegeTemporaryMode } from "@app/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-types"; import { checkForInvalidPermissionCombination } from "@app/ee/services/permission/permission-fns"; import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission"; -import { IDENTITY_ADDITIONAL_PRIVILEGE_V2 } from "@app/lib/api-docs"; +import { ApiDocsTags, IDENTITY_ADDITIONAL_PRIVILEGE_V2 } from "@app/lib/api-docs"; import { ms } from "@app/lib/ms"; import { alphaNumericNanoId } from "@app/lib/nanoid"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; @@ -21,6 +21,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.IdentitySpecificPrivileges], description: "Add an additional privilege for identity.", security: [ { @@ -84,6 +86,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.IdentitySpecificPrivileges], description: "Update a specific identity privilege.", security: [ { @@ -148,6 +152,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.IdentitySpecificPrivileges], description: "Delete the specified identity privilege.", security: [ { @@ -183,6 +189,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.IdentitySpecificPrivileges], description: "Retrieve details of a specific privilege by id.", security: [ { @@ -218,6 +226,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.IdentitySpecificPrivileges], description: "Retrieve details of a specific privilege by slug.", security: [ { @@ -258,6 +268,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.IdentitySpecificPrivileges], description: "List privileges for the specified identity by project.", security: [ { diff --git a/backend/src/ee/routes/v2/project-role-router.ts b/backend/src/ee/routes/v2/project-role-router.ts index 0bb83b8d4..538929316 100644 --- a/backend/src/ee/routes/v2/project-role-router.ts +++ b/backend/src/ee/routes/v2/project-role-router.ts @@ -4,7 +4,7 @@ import { z } from "zod"; import { ProjectMembershipRole, ProjectRolesSchema } from "@app/db/schemas"; import { checkForInvalidPermissionCombination } from "@app/ee/services/permission/permission-fns"; import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission"; -import { PROJECT_ROLE } from "@app/lib/api-docs"; +import { ApiDocsTags, PROJECT_ROLE } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { slugSchema } from "@app/server/lib/schemas"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -20,6 +20,8 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectRoles], description: "Create a project role", security: [ { @@ -75,6 +77,8 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectRoles], description: "Update a project role", security: [ { @@ -130,6 +134,8 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectRoles], description: "Delete a project role", security: [ { @@ -166,6 +172,8 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectRoles], description: "List project role", security: [ { @@ -204,6 +212,8 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectRoles], params: z.object({ projectId: z.string().trim().describe(PROJECT_ROLE.GET_ROLE_BY_SLUG.projectId), roleSlug: z.string().trim().describe(PROJECT_ROLE.GET_ROLE_BY_SLUG.roleSlug) diff --git a/backend/src/ee/routes/v2/secret-rotation-v2-routers/secret-rotation-v2-endpoints.ts b/backend/src/ee/routes/v2/secret-rotation-v2-routers/secret-rotation-v2-endpoints.ts index 05d3c7961..17fe14dbf 100644 --- a/backend/src/ee/routes/v2/secret-rotation-v2-routers/secret-rotation-v2-endpoints.ts +++ b/backend/src/ee/routes/v2/secret-rotation-v2-routers/secret-rotation-v2-endpoints.ts @@ -9,7 +9,7 @@ import { TSecretRotationV2GeneratedCredentials, TSecretRotationV2Input } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-types"; -import { SecretRotations } from "@app/lib/api-docs"; +import { ApiDocsTags, SecretRotations } from "@app/lib/api-docs"; import { startsWithVowel } from "@app/lib/fn"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -66,6 +66,8 @@ export const registerSecretRotationEndpoints = < rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretRotations], description: `List the ${rotationType} Rotations for the specified project.`, querystring: z.object({ projectId: z.string().trim().min(1, "Project ID required").describe(SecretRotations.LIST(type).projectId) @@ -109,6 +111,8 @@ export const registerSecretRotationEndpoints = < rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretRotations], description: `Get the specified ${rotationType} Rotation by ID.`, params: z.object({ rotationId: z.string().uuid().describe(SecretRotations.GET_BY_ID(type).rotationId) @@ -151,6 +155,8 @@ export const registerSecretRotationEndpoints = < rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretRotations], description: `Get the specified ${rotationType} Rotation by name, secret path, environment and project ID.`, params: z.object({ rotationName: z @@ -215,6 +221,8 @@ export const registerSecretRotationEndpoints = < rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretRotations], description: `Create ${ startsWithVowel(rotationType) ? "an" : "a" } ${rotationType} Rotation for the specified project.`, @@ -254,6 +262,8 @@ export const registerSecretRotationEndpoints = < rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretRotations], description: `Update the specified ${rotationType} Rotation.`, params: z.object({ rotationId: z.string().uuid().describe(SecretRotations.UPDATE(type).rotationId) @@ -296,6 +306,8 @@ export const registerSecretRotationEndpoints = < rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretRotations], description: `Delete the specified ${rotationType} Rotation.`, params: z.object({ rotationId: z.string().uuid().describe(SecretRotations.DELETE(type).rotationId) @@ -349,6 +361,8 @@ export const registerSecretRotationEndpoints = < rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretRotations], description: `Get the generated credentials for the specified ${rotationType} Rotation.`, params: z.object({ rotationId: z.string().uuid().describe(SecretRotations.GET_GENERATED_CREDENTIALS_BY_ID(type).rotationId) @@ -402,6 +416,8 @@ export const registerSecretRotationEndpoints = < rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretRotations], description: `Rotate the generated credentials for the specified ${rotationType} Rotation.`, params: z.object({ rotationId: z.string().uuid().describe(SecretRotations.ROTATE(type).rotationId) diff --git a/backend/src/ee/routes/v2/secret-rotation-v2-routers/secret-rotation-v2-router.ts b/backend/src/ee/routes/v2/secret-rotation-v2-routers/secret-rotation-v2-router.ts index bfb8b38c0..c1a2cb69d 100644 --- a/backend/src/ee/routes/v2/secret-rotation-v2-routers/secret-rotation-v2-router.ts +++ b/backend/src/ee/routes/v2/secret-rotation-v2-routers/secret-rotation-v2-router.ts @@ -5,7 +5,7 @@ import { Auth0ClientSecretRotationListItemSchema } from "@app/ee/services/secret import { MsSqlCredentialsRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/mssql-credentials"; import { PostgresCredentialsRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/postgres-credentials"; import { SecretRotationV2Schema } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-union-schema"; -import { SecretRotations } from "@app/lib/api-docs"; +import { ApiDocsTags, SecretRotations } from "@app/lib/api-docs"; import { readLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -24,6 +24,8 @@ export const registerSecretRotationV2Router = async (server: FastifyZodProvider) rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretRotations], description: "List the available Secret Rotation Options.", response: { 200: z.object({ @@ -45,6 +47,8 @@ export const registerSecretRotationV2Router = async (server: FastifyZodProvider) rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretRotations], description: "List all the Secret Rotations for the specified project.", querystring: z.object({ projectId: z.string().trim().min(1, "Project ID required").describe(SecretRotations.LIST().projectId) diff --git a/backend/src/lib/api-docs/constants.ts b/backend/src/lib/api-docs/constants.ts index ff07940bc..eab172b97 100644 --- a/backend/src/lib/api-docs/constants.ts +++ b/backend/src/lib/api-docs/constants.ts @@ -8,6 +8,75 @@ import { APP_CONNECTION_NAME_MAP } from "@app/services/app-connection/app-connec import { SecretSync } from "@app/services/secret-sync/secret-sync-enums"; import { SECRET_SYNC_CONNECTION_MAP, SECRET_SYNC_NAME_MAP } from "@app/services/secret-sync/secret-sync-maps"; +export enum ApiDocsTags { + Identities = "Identities", + TokenAuth = "Token Auth", + UniversalAuth = "Universal Auth", + GcpAuth = "Gcp Auth", + AwsAuth = "Aws Auth", + AzureAuth = "Azure Auth", + KubernetesAuth = "Kubernetes Auth", + JwtAuth = "JWT Auth", + OidcAuth = "OIDC Auth", + Groups = "Groups", + Organizations = "Organizations", + Projects = "Projects", + ProjectUsers = "Project Users", + ProjectGroups = "Project Groups", + ProjectIdentities = "Project Identities", + ProjectRoles = "ProjectRoles", + ProjectTemplates = "ProjectTemplates", + Environments = "Environments", + Folders = "Folders", + SecretTags = "Secret Tags", + Secrets = "Secrets", + DynamicSecrets = "Dynamic Secrets", + SecretImports = "Secret Imports", + SecretRotations = "Secret Rotations", + IdentitySpecificPrivileges = "Identity Specific Privileges", + AppConnections = "App Connections", + AppConnectionsAuth0 = "App Connection Auth0", + AppConnectionsAWS = "App Connection AWS", + AppConnectionsAzureAppConfiguration = "App Connection Azure App Configuration", + AppConnectionsAzureKeyVault = "App Connection Azure Key Vault", + AppConnectionsCamunda = "App Connection Camunda", + AppConnectionsDatabricks = "App Connection Databricks", + AppConnectionsGCP = "App Connection GCP", + AppConnectionsGitHub = "App Connection GitHub", + AppConnectionHumanitec = "App Connection Humanitec", + AppConnectionMsSQL = "App Connection Microsoft SQL Server", + AppConnectionPostgreSQL = "App Connection PostgreSQL", + AppConnectionTerraformCloud = "App Connection Terraform Cloud", + AppConnectionVercel = "App Connection Vercel", + AppConnectionWindmill = "App Connection Windmill", + SecretSyncs = "Secret Syncs", + SecretSyncAwsParameterStore = "Secret Syncs AWS Parameter Store", + SecretSyncsAwsSecretManager = "Secret Syncs AWS Secret Manager", + SecretSyncAzureAppConfiguration = "Secret Syncs Azure App Configuration", + SecretSyncCamunda = "Secret Syncs Camunda", + SecretSyncDatabricks = "Secret Syncs Databricks", + SecretSyncGcpSecretManager = "Secret Syncs GCP Secret Manager", + SecretSyncGitHub = "Secret Syncs GitHub", + SecretSyncHumanitec = "Secret Syncs Humanitec", + SecretSyncTerraformCloud = "Secret Syncs Terraform Cloud", + SecretSyncVercel = "Secret Syncs Vercel", + SecretSyncWindmill = "Secret Syncs Windmill", + Integrations = "Integrations", + ServiceTokens = "Service Tokens", + AuditLogs = "Audit Logs", + PkiCertificateAuthorities = "PKI Certificate Authorities", + PkiCertificates = "PKI Certificates", + PkiCertificateTemplates = "PKI Certificate Templates", + PkiCertificateCollections = "PKI Certificate Collections", + PkiAlerting = "PKI Alerting", + SshCertificates = "SSH Certificates", + SshCertificateAuthorities = "SSH Certificate Authorities", + SshCertificateTemplates = "SSH Certificate Templates", + KmsKeys = "KMS Keys", + KmsEncryption = "KMS Encryption", + KmsSigning = "KMS Signing" +} + export const GROUPS = { CREATE: { name: "The name of the group to create.", diff --git a/backend/src/main.ts b/backend/src/main.ts index 80d98abcf..c3b5a0900 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -73,6 +73,7 @@ const run = async () => { // eslint-disable-next-line process.on("SIGINT", async () => { await server.close(); + await queue.shutdown(); await db.destroy(); await removeTemporaryBaseDirectory(); hsmModule.finalize(); @@ -82,19 +83,22 @@ const run = async () => { // eslint-disable-next-line process.on("SIGTERM", async () => { await server.close(); + await queue.shutdown(); await db.destroy(); await removeTemporaryBaseDirectory(); hsmModule.finalize(); process.exit(0); }); - process.on("uncaughtException", (error) => { - logger.error(error, "CRITICAL ERROR: Uncaught Exception"); - }); + if (!envConfig.isDevelopmentMode) { + process.on("uncaughtException", (error) => { + logger.error(error, "CRITICAL ERROR: Uncaught Exception"); + }); - process.on("unhandledRejection", (error) => { - logger.error(error, "CRITICAL ERROR: Unhandled Promise Rejection"); - }); + process.on("unhandledRejection", (error) => { + logger.error(error, "CRITICAL ERROR: Unhandled Promise Rejection"); + }); + } await server.listen({ port: envConfig.PORT, diff --git a/backend/src/server/plugins/fastify-zod.ts b/backend/src/server/plugins/fastify-zod.ts index 02636a066..4e898a9b5 100644 --- a/backend/src/server/plugins/fastify-zod.ts +++ b/backend/src/server/plugins/fastify-zod.ts @@ -49,14 +49,17 @@ function resolveSchema(maybeSchema: ZodAny | { properties: ZodAny }): Pick { - return ({ schema, url }: { schema: Schema; url: string }) => { + return ({ schema = {}, url }: { schema: Schema; url: string }) => { if (!schema) { return { - schema, + schema: { hide: true }, url }; } + if (typeof schema.hide === "undefined") { + schema.hide = true; + } const { response, headers, querystring, body, params, hide, ...rest } = schema; const transformed: FreeformRecord = {}; diff --git a/backend/src/server/routes/v1/app-connection-routers/app-connection-endpoints.ts b/backend/src/server/routes/v1/app-connection-routers/app-connection-endpoints.ts index dfb451a4c..0bc8f7c59 100644 --- a/backend/src/server/routes/v1/app-connection-routers/app-connection-endpoints.ts +++ b/backend/src/server/routes/v1/app-connection-routers/app-connection-endpoints.ts @@ -1,7 +1,7 @@ import { z } from "zod"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { AppConnections } from "@app/lib/api-docs"; +import { ApiDocsTags, AppConnections } from "@app/lib/api-docs"; import { startsWithVowel } from "@app/lib/fn"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -43,6 +43,8 @@ export const registerAppConnectionEndpoints = rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.AppConnections], description: "List the available App Connection Options.", response: { 200: z.object({ @@ -107,6 +110,8 @@ export const registerAppConnectionRouter = async (server: FastifyZodProvider) => rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.AppConnections], description: "List all the App Connections for the current organization.", response: { 200: z.object({ appConnections: SanitizedAppConnectionSchema.array() }) diff --git a/backend/src/server/routes/v1/certificate-authority-router.ts b/backend/src/server/routes/v1/certificate-authority-router.ts index b108215ca..f6538b797 100644 --- a/backend/src/server/routes/v1/certificate-authority-router.ts +++ b/backend/src/server/routes/v1/certificate-authority-router.ts @@ -3,7 +3,7 @@ import { z } from "zod"; import { CertificateAuthoritiesSchema, CertificateTemplatesSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { CERTIFICATE_AUTHORITIES } from "@app/lib/api-docs"; +import { ApiDocsTags, CERTIFICATE_AUTHORITIES } from "@app/lib/api-docs"; import { ms } from "@app/lib/ms"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; @@ -26,6 +26,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateAuthorities], description: "Create CA", body: z .object({ @@ -105,6 +107,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateAuthorities], description: "Get CA", params: z.object({ caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET.caId) @@ -151,6 +155,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateAuthorities], description: "Get DER-encoded certificate of CA", params: z.object({ caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET_CERT_BY_ID.caId), @@ -177,6 +183,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateAuthorities], description: "Update CA", params: z.object({ caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.UPDATE.caId) @@ -231,6 +239,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateAuthorities], description: "Delete CA", params: z.object({ caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.DELETE.caId) @@ -276,6 +286,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateAuthorities], description: "Get CA CSR", params: z.object({ caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET_CSR.caId) @@ -321,6 +333,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateAuthorities], description: "Perform CA certificate renewal", params: z.object({ caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.RENEW_CA_CERT.caId) @@ -376,6 +390,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateAuthorities], description: "Get list of past and current CA certificates for a CA", params: z.object({ caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET_CA_CERTS.caId) @@ -424,6 +440,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateAuthorities], description: "Get current CA cert and cert chain of a CA", params: z.object({ caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET_CERT.caId) @@ -473,6 +491,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateAuthorities], description: "Create intermediate CA certificate from parent CA", params: z.object({ caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.SIGN_INTERMEDIATE.caId) @@ -536,6 +556,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateAuthorities], description: "Import certificate and chain to CA", params: z.object({ caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.IMPORT_CERT.caId) @@ -588,6 +610,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateAuthorities], description: "Issue certificate from CA", params: z.object({ caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.ISSUE_CERT.caId) @@ -679,6 +703,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateAuthorities], description: "Sign certificate from CA", params: z.object({ caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.SIGN_CERT.caId) @@ -770,6 +796,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateAuthorities], description: "Get list of certificate templates for the CA", params: z.object({ caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.SIGN_CERT.caId) @@ -815,6 +843,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateAuthorities], description: "Get list of CRLs of the CA", params: z.object({ caId: z.string().trim().describe(CERTIFICATE_AUTHORITIES.GET_CRLS.caId) diff --git a/backend/src/server/routes/v1/certificate-router.ts b/backend/src/server/routes/v1/certificate-router.ts index 3101393bd..ea33e948f 100644 --- a/backend/src/server/routes/v1/certificate-router.ts +++ b/backend/src/server/routes/v1/certificate-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { CertificatesSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { CERTIFICATE_AUTHORITIES, CERTIFICATES } from "@app/lib/api-docs"; +import { ApiDocsTags, CERTIFICATE_AUTHORITIES, CERTIFICATES } from "@app/lib/api-docs"; import { ms } from "@app/lib/ms"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; @@ -24,6 +24,8 @@ export const registerCertRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificates], description: "Get certificate", params: z.object({ serialNumber: z.string().trim().describe(CERTIFICATES.GET.serialNumber) @@ -70,6 +72,8 @@ export const registerCertRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificates], description: "Issue certificate", body: z .object({ @@ -181,6 +185,8 @@ export const registerCertRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificates], description: "Sign certificate", body: z .object({ @@ -292,6 +298,8 @@ export const registerCertRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificates], description: "Revoke", params: z.object({ serialNumber: z.string().trim().describe(CERTIFICATES.REVOKE.serialNumber) @@ -346,6 +354,8 @@ export const registerCertRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificates], description: "Delete certificate", params: z.object({ serialNumber: z.string().trim().describe(CERTIFICATES.DELETE.serialNumber) @@ -392,6 +402,8 @@ export const registerCertRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificates], description: "Get certificate body of certificate", params: z.object({ serialNumber: z.string().trim().describe(CERTIFICATES.GET_CERT.serialNumber) diff --git a/backend/src/server/routes/v1/certificate-template-router.ts b/backend/src/server/routes/v1/certificate-template-router.ts index 2217445cb..b0c186206 100644 --- a/backend/src/server/routes/v1/certificate-template-router.ts +++ b/backend/src/server/routes/v1/certificate-template-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { CertificateTemplateEstConfigsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { CERTIFICATE_TEMPLATES } from "@app/lib/api-docs"; +import { ApiDocsTags, CERTIFICATE_TEMPLATES } from "@app/lib/api-docs"; import { ms } from "@app/lib/ms"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -26,6 +26,8 @@ export const registerCertificateTemplateRouter = async (server: FastifyZodProvid rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateTemplates], params: z.object({ certificateTemplateId: z.string().describe(CERTIFICATE_TEMPLATES.GET.certificateTemplateId) }), @@ -65,6 +67,8 @@ export const registerCertificateTemplateRouter = async (server: FastifyZodProvid rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateTemplates], body: z.object({ caId: z.string().describe(CERTIFICATE_TEMPLATES.CREATE.caId), pkiCollectionId: z.string().optional().describe(CERTIFICATE_TEMPLATES.CREATE.pkiCollectionId), @@ -132,6 +136,8 @@ export const registerCertificateTemplateRouter = async (server: FastifyZodProvid rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateTemplates], body: z.object({ caId: z.string().optional().describe(CERTIFICATE_TEMPLATES.UPDATE.caId), pkiCollectionId: z.string().optional().describe(CERTIFICATE_TEMPLATES.UPDATE.pkiCollectionId), @@ -198,6 +204,8 @@ export const registerCertificateTemplateRouter = async (server: FastifyZodProvid rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateTemplates], params: z.object({ certificateTemplateId: z.string().describe(CERTIFICATE_TEMPLATES.DELETE.certificateTemplateId) }), @@ -238,6 +246,8 @@ export const registerCertificateTemplateRouter = async (server: FastifyZodProvid }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateTemplates], description: "Create Certificate Template EST configuration", params: z.object({ certificateTemplateId: z.string().trim() @@ -292,6 +302,8 @@ export const registerCertificateTemplateRouter = async (server: FastifyZodProvid }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateTemplates], description: "Update Certificate Template EST configuration", params: z.object({ certificateTemplateId: z.string().trim() @@ -340,6 +352,8 @@ export const registerCertificateTemplateRouter = async (server: FastifyZodProvid }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateTemplates], description: "Get Certificate Template EST configuration", params: z.object({ certificateTemplateId: z.string().trim() diff --git a/backend/src/server/routes/v1/cmek-router.ts b/backend/src/server/routes/v1/cmek-router.ts index 64f47f980..c8fd485a7 100644 --- a/backend/src/server/routes/v1/cmek-router.ts +++ b/backend/src/server/routes/v1/cmek-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { InternalKmsSchema, KmsKeysSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { KMS } from "@app/lib/api-docs"; +import { ApiDocsTags, KMS } from "@app/lib/api-docs"; import { getBase64SizeInBytes, isBase64 } from "@app/lib/base64"; import { AllowedEncryptionKeyAlgorithms, SymmetricKeyAlgorithm } from "@app/lib/crypto/cipher"; import { AsymmetricKeyAlgorithm, SigningAlgorithm } from "@app/lib/crypto/sign"; @@ -46,6 +46,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.KmsKeys], description: "Create KMS key", body: z .object({ @@ -138,6 +140,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.KmsKeys], description: "Update KMS key", params: z.object({ keyId: z.string().uuid().describe(KMS.UPDATE_KEY.keyId) @@ -187,6 +191,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.KmsKeys], description: "Delete KMS key", params: z.object({ keyId: z.string().uuid().describe(KMS.DELETE_KEY.keyId) @@ -229,6 +235,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.KmsKeys], description: "List KMS keys", querystring: z.object({ projectId: z.string().describe(KMS.LIST_KEYS.projectId), @@ -280,6 +288,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.KmsKeys], description: "Get KMS key by ID", params: z.object({ keyId: z.string().uuid().describe(KMS.GET_KEY_BY_ID.keyId) @@ -321,6 +331,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.KmsKeys], description: "Get KMS key by name", params: z.object({ keyName: slugSchema({ field: "Key name" }).describe(KMS.GET_KEY_BY_NAME.keyName) @@ -367,6 +379,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.KmsEncryption], description: "Encrypt data with KMS key", params: z.object({ keyId: z.string().uuid().describe(KMS.ENCRYPT.keyId) @@ -412,6 +426,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.KmsSigning], description: "Get the public key for a KMS key that is used for signing and verifying data. This endpoint is only available for asymmetric keys.", params: z.object({ @@ -454,6 +470,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.KmsSigning], description: "List all available signing algorithms for a KMS key", params: z.object({ keyId: z.string().uuid().describe(KMS.LIST_SIGNING_ALGORITHMS.keyId) @@ -495,6 +513,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.KmsSigning], description: "Sign data with a KMS key.", params: z.object({ keyId: z.string().uuid().describe(KMS.SIGN.keyId) @@ -548,6 +568,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.KmsSigning], description: "Verify data signatures with a KMS key.", params: z.object({ keyId: z.string().uuid().describe(KMS.VERIFY.keyId) @@ -604,6 +626,8 @@ export const registerCmekRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.KmsEncryption], description: "Decrypt data with KMS key", params: z.object({ keyId: z.string().uuid().describe(KMS.DECRYPT.keyId) diff --git a/backend/src/server/routes/v1/identity-access-token-router.ts b/backend/src/server/routes/v1/identity-access-token-router.ts index 7ed62e679..20ed8d150 100644 --- a/backend/src/server/routes/v1/identity-access-token-router.ts +++ b/backend/src/server/routes/v1/identity-access-token-router.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { UNIVERSAL_AUTH } from "@app/lib/api-docs"; +import { ApiDocsTags, UNIVERSAL_AUTH } from "@app/lib/api-docs"; import { writeLimit } from "@app/server/config/rateLimiter"; export const registerIdentityAccessTokenRouter = async (server: FastifyZodProvider) => { @@ -11,6 +11,8 @@ export const registerIdentityAccessTokenRouter = async (server: FastifyZodProvid rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.UniversalAuth], description: "Renew access token", body: z.object({ accessToken: z.string().trim().describe(UNIVERSAL_AUTH.RENEW_ACCESS_TOKEN.accessToken) @@ -44,6 +46,8 @@ export const registerIdentityAccessTokenRouter = async (server: FastifyZodProvid rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.UniversalAuth], description: "Revoke access token", body: z.object({ accessToken: z.string().trim().describe(UNIVERSAL_AUTH.REVOKE_ACCESS_TOKEN.accessToken) diff --git a/backend/src/server/routes/v1/identity-aws-iam-auth-router.ts b/backend/src/server/routes/v1/identity-aws-iam-auth-router.ts index 82387a3cc..246bf935c 100644 --- a/backend/src/server/routes/v1/identity-aws-iam-auth-router.ts +++ b/backend/src/server/routes/v1/identity-aws-iam-auth-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { IdentityAwsAuthsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { AWS_AUTH } from "@app/lib/api-docs"; +import { AWS_AUTH, ApiDocsTags } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -21,6 +21,8 @@ export const registerIdentityAwsAuthRouter = async (server: FastifyZodProvider) rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.AwsAuth], description: "Login with AWS Auth", body: z.object({ identityId: z.string().trim().describe(AWS_AUTH.LOGIN.identityId), @@ -71,6 +73,8 @@ export const registerIdentityAwsAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.AwsAuth], description: "Attach AWS Auth configuration onto identity", security: [ { @@ -165,6 +169,8 @@ export const registerIdentityAwsAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.AwsAuth], description: "Update AWS Auth configuration on identity", security: [ { @@ -247,6 +253,8 @@ export const registerIdentityAwsAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.AwsAuth], description: "Retrieve AWS Auth configuration on identity", security: [ { @@ -293,6 +301,8 @@ export const registerIdentityAwsAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.AwsAuth], description: "Delete AWS Auth configuration on identity", security: [ { diff --git a/backend/src/server/routes/v1/identity-azure-auth-router.ts b/backend/src/server/routes/v1/identity-azure-auth-router.ts index 1cf59e682..ee13642e9 100644 --- a/backend/src/server/routes/v1/identity-azure-auth-router.ts +++ b/backend/src/server/routes/v1/identity-azure-auth-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { IdentityAzureAuthsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { AZURE_AUTH } from "@app/lib/api-docs"; +import { AZURE_AUTH, ApiDocsTags } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -18,6 +18,8 @@ export const registerIdentityAzureAuthRouter = async (server: FastifyZodProvider rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.AzureAuth], description: "Login with Azure Auth", body: z.object({ identityId: z.string().trim().describe(AZURE_AUTH.LOGIN.identityId), @@ -66,6 +68,8 @@ export const registerIdentityAzureAuthRouter = async (server: FastifyZodProvider }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.AzureAuth], description: "Attach Azure Auth configuration onto identity", security: [ { @@ -159,6 +163,8 @@ export const registerIdentityAzureAuthRouter = async (server: FastifyZodProvider }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.AzureAuth], description: "Update Azure Auth configuration on identity", security: [ { @@ -247,6 +253,8 @@ export const registerIdentityAzureAuthRouter = async (server: FastifyZodProvider }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.AzureAuth], description: "Retrieve Azure Auth configuration on identity", security: [ { @@ -294,6 +302,8 @@ export const registerIdentityAzureAuthRouter = async (server: FastifyZodProvider }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.AzureAuth], description: "Delete Azure Auth configuration on identity", security: [ { diff --git a/backend/src/server/routes/v1/identity-gcp-auth-router.ts b/backend/src/server/routes/v1/identity-gcp-auth-router.ts index d269072d9..82b5bfb8b 100644 --- a/backend/src/server/routes/v1/identity-gcp-auth-router.ts +++ b/backend/src/server/routes/v1/identity-gcp-auth-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { IdentityGcpAuthsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { GCP_AUTH } from "@app/lib/api-docs"; +import { ApiDocsTags, GCP_AUTH } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -18,6 +18,8 @@ export const registerIdentityGcpAuthRouter = async (server: FastifyZodProvider) rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.GcpAuth], description: "Login with GCP Auth", body: z.object({ identityId: z.string().trim().describe(GCP_AUTH.LOGIN.identityId).trim(), @@ -66,6 +68,8 @@ export const registerIdentityGcpAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.GcpAuth], description: "Attach GCP Auth configuration onto identity", security: [ { @@ -157,6 +161,8 @@ export const registerIdentityGcpAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.GcpAuth], description: "Update GCP Auth configuration on identity", security: [ { @@ -241,6 +247,8 @@ export const registerIdentityGcpAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.GcpAuth], description: "Retrieve GCP Auth configuration on identity", security: [ { @@ -288,6 +296,8 @@ export const registerIdentityGcpAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.GcpAuth], description: "Delete GCP Auth configuration on identity", security: [ { diff --git a/backend/src/server/routes/v1/identity-jwt-auth-router.ts b/backend/src/server/routes/v1/identity-jwt-auth-router.ts index bb09898a3..373a8b927 100644 --- a/backend/src/server/routes/v1/identity-jwt-auth-router.ts +++ b/backend/src/server/routes/v1/identity-jwt-auth-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { IdentityJwtAuthsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { JWT_AUTH } from "@app/lib/api-docs"; +import { ApiDocsTags, JWT_AUTH } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -94,6 +94,8 @@ export const registerIdentityJwtAuthRouter = async (server: FastifyZodProvider) rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.JwtAuth], description: "Login with JWT Auth", body: z.object({ identityId: z.string().trim().describe(JWT_AUTH.LOGIN.identityId), @@ -144,6 +146,8 @@ export const registerIdentityJwtAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.JwtAuth], description: "Attach JWT Auth configuration onto identity", security: [ { @@ -211,6 +215,8 @@ export const registerIdentityJwtAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.JwtAuth], description: "Update JWT Auth configuration on identity", security: [ { @@ -275,6 +281,8 @@ export const registerIdentityJwtAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.JwtAuth], description: "Retrieve JWT Auth configuration on identity", security: [ { @@ -322,6 +330,8 @@ export const registerIdentityJwtAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.JwtAuth], description: "Delete JWT Auth configuration on identity", security: [ { diff --git a/backend/src/server/routes/v1/identity-kubernetes-auth-router.ts b/backend/src/server/routes/v1/identity-kubernetes-auth-router.ts index 0105afd76..21759e0cd 100644 --- a/backend/src/server/routes/v1/identity-kubernetes-auth-router.ts +++ b/backend/src/server/routes/v1/identity-kubernetes-auth-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { IdentityKubernetesAuthsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { KUBERNETES_AUTH } from "@app/lib/api-docs"; +import { ApiDocsTags, KUBERNETES_AUTH } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -35,6 +35,8 @@ export const registerIdentityKubernetesRouter = async (server: FastifyZodProvide rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.KubernetesAuth], description: "Login with Kubernetes Auth", body: z.object({ identityId: z.string().trim().describe(KUBERNETES_AUTH.LOGIN.identityId), @@ -85,6 +87,8 @@ export const registerIdentityKubernetesRouter = async (server: FastifyZodProvide }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.KubernetesAuth], description: "Attach Kubernetes Auth configuration onto identity", security: [ { @@ -182,6 +186,8 @@ export const registerIdentityKubernetesRouter = async (server: FastifyZodProvide }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.KubernetesAuth], description: "Update Kubernetes Auth configuration on identity", security: [ { @@ -278,6 +284,8 @@ export const registerIdentityKubernetesRouter = async (server: FastifyZodProvide }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.KubernetesAuth], description: "Retrieve Kubernetes Auth configuration on identity", security: [ { @@ -325,6 +333,8 @@ export const registerIdentityKubernetesRouter = async (server: FastifyZodProvide }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.KubernetesAuth], description: "Delete Kubernetes Auth configuration on identity", security: [ { diff --git a/backend/src/server/routes/v1/identity-oidc-auth-router.ts b/backend/src/server/routes/v1/identity-oidc-auth-router.ts index 4a7b66146..74cd94eb5 100644 --- a/backend/src/server/routes/v1/identity-oidc-auth-router.ts +++ b/backend/src/server/routes/v1/identity-oidc-auth-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { IdentityOidcAuthsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { OIDC_AUTH } from "@app/lib/api-docs"; +import { ApiDocsTags, OIDC_AUTH } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -42,6 +42,8 @@ export const registerIdentityOidcAuthRouter = async (server: FastifyZodProvider) rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.OidcAuth], description: "Login with OIDC Auth", body: z.object({ identityId: z.string().trim().describe(OIDC_AUTH.LOGIN.identityId), @@ -96,6 +98,8 @@ export const registerIdentityOidcAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.OidcAuth], description: "Attach OIDC Auth configuration onto identity", security: [ { @@ -195,6 +199,8 @@ export const registerIdentityOidcAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.OidcAuth], description: "Update OIDC Auth configuration on identity", security: [ { @@ -292,6 +298,8 @@ export const registerIdentityOidcAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.OidcAuth], description: "Retrieve OIDC Auth configuration on identity", security: [ { @@ -339,6 +347,8 @@ export const registerIdentityOidcAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.OidcAuth], description: "Delete OIDC Auth configuration on identity", security: [ { diff --git a/backend/src/server/routes/v1/identity-router.ts b/backend/src/server/routes/v1/identity-router.ts index 107a4b9ef..7731aad98 100644 --- a/backend/src/server/routes/v1/identity-router.ts +++ b/backend/src/server/routes/v1/identity-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { IdentitiesSchema, IdentityOrgMembershipsSchema, OrgMembershipRole, OrgRolesSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { IDENTITIES } from "@app/lib/api-docs"; +import { ApiDocsTags, IDENTITIES } from "@app/lib/api-docs"; import { buildSearchZodSchema, SearchResourceOperators } from "@app/lib/search-resource/search"; import { OrderByDirection } from "@app/lib/types"; import { CharacterType, zodValidateCharacters } from "@app/lib/validator/validate-string"; @@ -32,6 +32,8 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Identities], description: "Create identity", security: [ { @@ -100,6 +102,8 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Identities], description: "Update identity", security: [ { @@ -158,6 +162,8 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Identities], description: "Delete identity", security: [ { @@ -205,6 +211,8 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Identities], description: "Get an identity by id", security: [ { @@ -260,6 +268,8 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Identities], description: "List identities", security: [ { @@ -308,6 +318,8 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Identities], description: "Search identities", security: [ { diff --git a/backend/src/server/routes/v1/identity-token-auth-router.ts b/backend/src/server/routes/v1/identity-token-auth-router.ts index d6e7259be..e22c41889 100644 --- a/backend/src/server/routes/v1/identity-token-auth-router.ts +++ b/backend/src/server/routes/v1/identity-token-auth-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { IdentityAccessTokensSchema, IdentityTokenAuthsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { TOKEN_AUTH } from "@app/lib/api-docs"; +import { ApiDocsTags, TOKEN_AUTH } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -18,6 +18,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.TokenAuth], description: "Attach Token Auth configuration onto identity", security: [ { @@ -108,6 +110,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.TokenAuth], description: "Update Token Auth configuration on identity", security: [ { @@ -192,6 +196,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.TokenAuth], description: "Retrieve Token Auth configuration on identity", security: [ { @@ -239,6 +245,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.TokenAuth], description: "Delete Token Auth configuration on identity", security: [ { @@ -287,6 +295,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.TokenAuth], description: "Create token for identity with Token Auth", security: [ { @@ -349,6 +359,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.TokenAuth], description: "Get tokens for identity with Token Auth", security: [ { @@ -402,6 +414,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.TokenAuth], description: "Update token for identity with Token Auth", security: [ { @@ -456,6 +470,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.TokenAuth], description: "Revoke token for identity with Token Auth", security: [ { diff --git a/backend/src/server/routes/v1/identity-universal-auth-router.ts b/backend/src/server/routes/v1/identity-universal-auth-router.ts index 5a9363f3d..6fe4c7a85 100644 --- a/backend/src/server/routes/v1/identity-universal-auth-router.ts +++ b/backend/src/server/routes/v1/identity-universal-auth-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { IdentityUaClientSecretsSchema, IdentityUniversalAuthsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { UNIVERSAL_AUTH } from "@app/lib/api-docs"; +import { ApiDocsTags, UNIVERSAL_AUTH } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -30,6 +30,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.UniversalAuth], description: "Login with Universal Auth", body: z.object({ clientId: z.string().trim().describe(UNIVERSAL_AUTH.LOGIN.clientId), @@ -78,6 +80,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.UniversalAuth], description: "Attach Universal Auth configuration onto identity", security: [ { @@ -175,6 +179,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.UniversalAuth], description: "Update Universal Auth configuration on identity", security: [ { @@ -271,6 +277,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.UniversalAuth], description: "Retrieve Universal Auth configuration on identity", security: [ { @@ -318,6 +326,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.UniversalAuth], description: "Delete Universal Auth configuration on identity", security: [ { @@ -365,6 +375,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.UniversalAuth], description: "Create Universal Auth Client Secret for identity", security: [ { @@ -421,6 +433,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.UniversalAuth], description: "List Universal Auth Client Secrets for identity", security: [ { @@ -469,6 +483,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.UniversalAuth], description: "Get Universal Auth Client Secret for identity", security: [ { @@ -519,6 +535,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.UniversalAuth], description: "Revoke Universal Auth Client Secrets for identity", security: [ { diff --git a/backend/src/server/routes/v1/integration-auth-router.ts b/backend/src/server/routes/v1/integration-auth-router.ts index bca11cbf3..e5156724d 100644 --- a/backend/src/server/routes/v1/integration-auth-router.ts +++ b/backend/src/server/routes/v1/integration-auth-router.ts @@ -1,7 +1,7 @@ import { z } from "zod"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { INTEGRATION_AUTH } from "@app/lib/api-docs"; +import { ApiDocsTags, INTEGRATION_AUTH } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -19,6 +19,8 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Integrations], description: "List of integrations available.", security: [ { @@ -57,6 +59,8 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Integrations], description: "Get details of an integration authorization by auth object id.", security: [ { @@ -92,6 +96,8 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Integrations], description: "Update the integration authentication object required for syncing secrets.", security: [ { @@ -153,6 +159,8 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Integrations], description: "Remove all integration's auth object from the project.", security: [ { @@ -202,6 +210,8 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Integrations], description: "Remove an integration auth object by object id.", security: [ { @@ -294,6 +304,8 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Integrations], description: "Create the integration authentication object required for syncing secrets.", security: [ { diff --git a/backend/src/server/routes/v1/integration-router.ts b/backend/src/server/routes/v1/integration-router.ts index f0c28478c..f3964e7b7 100644 --- a/backend/src/server/routes/v1/integration-router.ts +++ b/backend/src/server/routes/v1/integration-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { IntegrationsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { INTEGRATION } from "@app/lib/api-docs"; +import { ApiDocsTags, INTEGRATION } from "@app/lib/api-docs"; import { removeTrailingSlash, shake } from "@app/lib/fn"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; @@ -22,6 +22,8 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Integrations], description: "Create an integration to sync secrets.", security: [ { @@ -119,6 +121,8 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Integrations], description: "Update an integration by integration id", security: [ { @@ -178,6 +182,8 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Integrations], description: "Get an integration by integration id", security: [ { @@ -247,6 +253,8 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Integrations], description: "Remove an integration using the integration object ID", security: [ { @@ -315,6 +323,8 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Integrations], description: "Manually trigger sync of an integration by integration id", security: [ { diff --git a/backend/src/server/routes/v1/organization-router.ts b/backend/src/server/routes/v1/organization-router.ts index 90ca3d255..e52149740 100644 --- a/backend/src/server/routes/v1/organization-router.ts +++ b/backend/src/server/routes/v1/organization-router.ts @@ -9,7 +9,7 @@ import { UsersSchema } from "@app/db/schemas"; import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types"; -import { AUDIT_LOGS, ORGANIZATIONS } from "@app/lib/api-docs"; +import { AUDIT_LOGS, ApiDocsTags, ORGANIZATIONS } from "@app/lib/api-docs"; import { getLastMidnightDateISO, removeTrailingSlash } from "@app/lib/fn"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { GenericResourceNameSchema, slugSchema } from "@app/server/lib/schemas"; @@ -109,6 +109,8 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.AuditLogs], description: "Get all audit logs for an organization", querystring: z.object({ projectId: z.string().optional().describe(AUDIT_LOGS.EXPORT.projectId), diff --git a/backend/src/server/routes/v1/pki-alert-router.ts b/backend/src/server/routes/v1/pki-alert-router.ts index f64ec9e47..43ce91e88 100644 --- a/backend/src/server/routes/v1/pki-alert-router.ts +++ b/backend/src/server/routes/v1/pki-alert-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { PkiAlertsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { ALERTS } from "@app/lib/api-docs"; +import { ALERTS, ApiDocsTags } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -16,6 +16,8 @@ export const registerPkiAlertRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiAlerting], description: "Create PKI alert", body: z.object({ projectId: z.string().trim().describe(ALERTS.CREATE.projectId), @@ -68,6 +70,8 @@ export const registerPkiAlertRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiAlerting], description: "Get PKI alert", params: z.object({ alertId: z.string().trim().describe(ALERTS.GET.alertId) @@ -108,6 +112,8 @@ export const registerPkiAlertRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiAlerting], description: "Update PKI alert", params: z.object({ alertId: z.string().trim().describe(ALERTS.UPDATE.alertId) @@ -164,6 +170,8 @@ export const registerPkiAlertRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiAlerting], description: "Delete PKI alert", params: z.object({ alertId: z.string().trim().describe(ALERTS.DELETE.alertId) diff --git a/backend/src/server/routes/v1/pki-collection-router.ts b/backend/src/server/routes/v1/pki-collection-router.ts index 2f2add5c1..92f883b38 100644 --- a/backend/src/server/routes/v1/pki-collection-router.ts +++ b/backend/src/server/routes/v1/pki-collection-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { PkiCollectionItemsSchema, PkiCollectionsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { PKI_COLLECTIONS } from "@app/lib/api-docs"; +import { ApiDocsTags, PKI_COLLECTIONS } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -17,6 +17,8 @@ export const registerPkiCollectionRouter = async (server: FastifyZodProvider) => }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateCollections], description: "Create PKI collection", body: z.object({ projectId: z.string().trim().describe(PKI_COLLECTIONS.CREATE.projectId), @@ -60,6 +62,8 @@ export const registerPkiCollectionRouter = async (server: FastifyZodProvider) => }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateCollections], description: "Get PKI collection", params: z.object({ collectionId: z.string().trim().describe(PKI_COLLECTIONS.GET.collectionId) @@ -100,6 +104,8 @@ export const registerPkiCollectionRouter = async (server: FastifyZodProvider) => }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateCollections], description: "Update PKI collection", params: z.object({ collectionId: z.string().trim().describe(PKI_COLLECTIONS.UPDATE.collectionId) @@ -146,6 +152,8 @@ export const registerPkiCollectionRouter = async (server: FastifyZodProvider) => }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateCollections], description: "Delete PKI collection", params: z.object({ collectionId: z.string().trim().describe(PKI_COLLECTIONS.DELETE.collectionId) @@ -186,6 +194,8 @@ export const registerPkiCollectionRouter = async (server: FastifyZodProvider) => }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateCollections], description: "Get items in PKI collection", params: z.object({ collectionId: z.string().trim().describe(PKI_COLLECTIONS.LIST_ITEMS.collectionId) @@ -247,6 +257,8 @@ export const registerPkiCollectionRouter = async (server: FastifyZodProvider) => }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateCollections], description: "Add item to PKI collection", params: z.object({ collectionId: z.string().trim().describe(PKI_COLLECTIONS.ADD_ITEM.collectionId) @@ -298,6 +310,8 @@ export const registerPkiCollectionRouter = async (server: FastifyZodProvider) => }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateCollections], description: "Remove item from PKI collection", params: z.object({ collectionId: z.string().trim().describe(PKI_COLLECTIONS.DELETE_ITEM.collectionId), diff --git a/backend/src/server/routes/v1/project-env-router.ts b/backend/src/server/routes/v1/project-env-router.ts index 705016696..48b6f0195 100644 --- a/backend/src/server/routes/v1/project-env-router.ts +++ b/backend/src/server/routes/v1/project-env-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { ProjectEnvironmentsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { ENVIRONMENTS } from "@app/lib/api-docs"; +import { ApiDocsTags, ENVIRONMENTS } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { slugSchema } from "@app/server/lib/schemas"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -16,6 +16,8 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Environments], description: "Get Environment", security: [ { @@ -65,6 +67,8 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Environments], description: "Get Environment by ID", security: [ { @@ -112,6 +116,8 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Environments], description: "Create environment", security: [ { @@ -171,6 +177,8 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Environments], description: "Update environment", security: [ { @@ -237,6 +245,8 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Environments], description: "Delete environment", security: [ { diff --git a/backend/src/server/routes/v1/project-membership-router.ts b/backend/src/server/routes/v1/project-membership-router.ts index b5a4a8677..cd3734efc 100644 --- a/backend/src/server/routes/v1/project-membership-router.ts +++ b/backend/src/server/routes/v1/project-membership-router.ts @@ -8,7 +8,7 @@ import { UsersSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { PROJECT_USERS } from "@app/lib/api-docs"; +import { ApiDocsTags, PROJECT_USERS } from "@app/lib/api-docs"; import { ms } from "@app/lib/ms"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -23,6 +23,8 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectUsers], description: "Return project user memberships", security: [ { @@ -141,6 +143,8 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectUsers], description: "Return project user memberships", security: [ { @@ -255,6 +259,8 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectUsers], description: "Update project user membership", security: [ { diff --git a/backend/src/server/routes/v1/project-router.ts b/backend/src/server/routes/v1/project-router.ts index 4182ce389..ad21ecc1b 100644 --- a/backend/src/server/routes/v1/project-router.ts +++ b/backend/src/server/routes/v1/project-router.ts @@ -13,7 +13,7 @@ import { UsersSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { PROJECTS } from "@app/lib/api-docs"; +import { ApiDocsTags, PROJECTS } from "@app/lib/api-docs"; import { CharacterType, characterValidator } from "@app/lib/validator/validate-string"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -176,6 +176,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Projects], description: "Get project", security: [ { @@ -289,6 +291,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Projects], description: "Update project", security: [ { @@ -512,6 +516,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Integrations], description: "List integrations for a project.", security: [ { diff --git a/backend/src/server/routes/v1/secret-folder-router.ts b/backend/src/server/routes/v1/secret-folder-router.ts index dbfa715ea..b307347b8 100644 --- a/backend/src/server/routes/v1/secret-folder-router.ts +++ b/backend/src/server/routes/v1/secret-folder-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { SecretFoldersSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { FOLDERS } from "@app/lib/api-docs"; +import { ApiDocsTags, FOLDERS } from "@app/lib/api-docs"; import { prefixWithSlash, removeTrailingSlash } from "@app/lib/fn"; import { isValidFolderName } from "@app/lib/validator"; import { readLimit, secretsLimit } from "@app/server/config/rateLimiter"; @@ -19,6 +19,8 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) => rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Folders], description: "Create folders", security: [ { @@ -98,6 +100,8 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) => rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Folders], description: "Update folder", security: [ { @@ -181,6 +185,8 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) => rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Folders], description: "Update folders by batch", security: [ { @@ -259,6 +265,8 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) => rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Folders], description: "Delete a folder", security: [ { @@ -332,6 +340,8 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) => rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Folders], description: "Get folders", security: [ { @@ -390,6 +400,8 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) => rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Folders], description: "Get folder by id", security: [ { diff --git a/backend/src/server/routes/v1/secret-import-router.ts b/backend/src/server/routes/v1/secret-import-router.ts index aa6efdf36..5d1cd65df 100644 --- a/backend/src/server/routes/v1/secret-import-router.ts +++ b/backend/src/server/routes/v1/secret-import-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { SecretImportsSchema, SecretsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { SECRET_IMPORTS } from "@app/lib/api-docs"; +import { ApiDocsTags, SECRET_IMPORTS } from "@app/lib/api-docs"; import { removeTrailingSlash } from "@app/lib/fn"; import { readLimit, secretsLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -18,6 +18,8 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) => rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretImports], description: "Create secret imports", security: [ { @@ -83,6 +85,8 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) => rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretImports], description: "Update secret imports", security: [ { @@ -157,6 +161,8 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) => rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretImports], description: "Delete secret imports", security: [ { @@ -319,6 +325,8 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) => rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretImports], description: "Get single secret import", security: [ { @@ -421,6 +429,8 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) => rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretImports], querystring: z.object({ workspaceId: z.string().trim(), environment: z.string().trim(), diff --git a/backend/src/server/routes/v1/secret-sync-routers/secret-sync-endpoints.ts b/backend/src/server/routes/v1/secret-sync-routers/secret-sync-endpoints.ts index 31826f86f..6ab9b5939 100644 --- a/backend/src/server/routes/v1/secret-sync-routers/secret-sync-endpoints.ts +++ b/backend/src/server/routes/v1/secret-sync-routers/secret-sync-endpoints.ts @@ -1,7 +1,7 @@ import { z } from "zod"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { SecretSyncs } from "@app/lib/api-docs"; +import { ApiDocsTags, SecretSyncs } from "@app/lib/api-docs"; import { startsWithVowel } from "@app/lib/fn"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -51,6 +51,8 @@ export const registerSyncSecretsEndpoints = { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretSyncs], description: "List the available Secret Sync Options.", response: { 200: z.object({ @@ -86,6 +88,8 @@ export const registerSecretSyncRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretSyncs], description: "List all the Secret Syncs for the specified project.", querystring: z.object({ projectId: z.string().trim().min(1, "Project ID required").describe(SecretSyncs.LIST().projectId) diff --git a/backend/src/server/routes/v1/secret-tag-router.ts b/backend/src/server/routes/v1/secret-tag-router.ts index ed9837084..01ba783fe 100644 --- a/backend/src/server/routes/v1/secret-tag-router.ts +++ b/backend/src/server/routes/v1/secret-tag-router.ts @@ -1,7 +1,7 @@ import { z } from "zod"; import { SecretTagsSchema } from "@app/db/schemas"; -import { SECRET_TAGS } from "@app/lib/api-docs"; +import { ApiDocsTags, SECRET_TAGS } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { slugSchema } from "@app/server/lib/schemas"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -15,6 +15,8 @@ export const registerSecretTagRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Folders], params: z.object({ projectId: z.string().trim().describe(SECRET_TAGS.LIST.projectId) }), @@ -44,6 +46,8 @@ export const registerSecretTagRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Folders], params: z.object({ projectId: z.string().trim().describe(SECRET_TAGS.GET_TAG_BY_ID.projectId), tagId: z.string().trim().describe(SECRET_TAGS.GET_TAG_BY_ID.tagId) @@ -75,6 +79,8 @@ export const registerSecretTagRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Folders], params: z.object({ projectId: z.string().trim().describe(SECRET_TAGS.GET_TAG_BY_SLUG.projectId), tagSlug: z.string().trim().describe(SECRET_TAGS.GET_TAG_BY_SLUG.tagSlug) @@ -107,6 +113,8 @@ export const registerSecretTagRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Folders], params: z.object({ projectId: z.string().trim().describe(SECRET_TAGS.CREATE.projectId) }), @@ -141,6 +149,8 @@ export const registerSecretTagRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Folders], params: z.object({ projectId: z.string().trim().describe(SECRET_TAGS.UPDATE.projectId), tagId: z.string().trim().describe(SECRET_TAGS.UPDATE.tagId) @@ -176,6 +186,8 @@ export const registerSecretTagRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Folders], params: z.object({ projectId: z.string().trim().describe(SECRET_TAGS.DELETE.projectId), tagId: z.string().trim().describe(SECRET_TAGS.DELETE.tagId) diff --git a/backend/src/server/routes/v2/group-project-router.ts b/backend/src/server/routes/v2/group-project-router.ts index 47456e622..5a081a3d9 100644 --- a/backend/src/server/routes/v2/group-project-router.ts +++ b/backend/src/server/routes/v2/group-project-router.ts @@ -6,7 +6,7 @@ import { ProjectMembershipRole, ProjectUserMembershipRolesSchema } from "@app/db/schemas"; -import { PROJECTS } from "@app/lib/api-docs"; +import { ApiDocsTags, PROJECTS } from "@app/lib/api-docs"; import { ms } from "@app/lib/ms"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -22,6 +22,8 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) => rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectGroups], description: "Add group to project", security: [ { @@ -88,6 +90,8 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) => url: "/:projectId/groups/:groupId", onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.ProjectGroups], description: "Update group in project", security: [ { @@ -147,6 +151,8 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) => rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectGroups], description: "Remove group from project", security: [ { @@ -185,6 +191,8 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) => rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectGroups], description: "Return list of groups in project", security: [ { @@ -243,6 +251,8 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) => rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectGroups], description: "Return project group", security: [ { diff --git a/backend/src/server/routes/v2/identity-org-router.ts b/backend/src/server/routes/v2/identity-org-router.ts index 52940eb44..8680a2dca 100644 --- a/backend/src/server/routes/v2/identity-org-router.ts +++ b/backend/src/server/routes/v2/identity-org-router.ts @@ -1,7 +1,7 @@ import { z } from "zod"; import { IdentitiesSchema, IdentityOrgMembershipsSchema, OrgRolesSchema } from "@app/db/schemas"; -import { ORGANIZATIONS } from "@app/lib/api-docs"; +import { ApiDocsTags, ORGANIZATIONS } from "@app/lib/api-docs"; import { OrderByDirection } from "@app/lib/types"; import { readLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -17,6 +17,8 @@ export const registerIdentityOrgRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Organizations], description: "Return organization identity memberships", security: [ { diff --git a/backend/src/server/routes/v2/identity-project-router.ts b/backend/src/server/routes/v2/identity-project-router.ts index 4205d9326..9de7ed1aa 100644 --- a/backend/src/server/routes/v2/identity-project-router.ts +++ b/backend/src/server/routes/v2/identity-project-router.ts @@ -6,7 +6,7 @@ import { ProjectMembershipRole, ProjectUserMembershipRolesSchema } from "@app/db/schemas"; -import { ORGANIZATIONS, PROJECT_IDENTITIES } from "@app/lib/api-docs"; +import { ApiDocsTags, ORGANIZATIONS, PROJECT_IDENTITIES } from "@app/lib/api-docs"; import { BadRequestError } from "@app/lib/errors"; import { ms } from "@app/lib/ms"; import { OrderByDirection } from "@app/lib/types"; @@ -27,6 +27,8 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.ProjectIdentities], description: "Create project identity membership", security: [ { @@ -101,6 +103,8 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.ProjectIdentities], description: "Update project identity memberships", security: [ { @@ -170,6 +174,8 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.ProjectIdentities], description: "Delete project identity memberships", security: [ { @@ -207,6 +213,8 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.ProjectIdentities], description: "Return project identity memberships", security: [ { @@ -300,6 +308,8 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.ProjectIdentities], description: "Return project identity membership", security: [ { @@ -360,6 +370,8 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.ProjectIdentities], params: z.object({ identityMembershipId: z.string().trim() }), diff --git a/backend/src/server/routes/v2/organization-router.ts b/backend/src/server/routes/v2/organization-router.ts index 90b500a5a..504359726 100644 --- a/backend/src/server/routes/v2/organization-router.ts +++ b/backend/src/server/routes/v2/organization-router.ts @@ -8,7 +8,7 @@ import { UserEncryptionKeysSchema, UsersSchema } from "@app/db/schemas"; -import { ORGANIZATIONS } from "@app/lib/api-docs"; +import { ApiDocsTags, ORGANIZATIONS } from "@app/lib/api-docs"; import { getConfig } from "@app/lib/config/env"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { GenericResourceNameSchema } from "@app/server/lib/schemas"; @@ -24,6 +24,8 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Organizations], description: "Return organization user memberships", security: [ { @@ -72,6 +74,8 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Organizations], description: "Return projects in organization that user is apart of", security: [ { @@ -179,6 +183,8 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Organizations], description: "Update organization user memberships", security: [ { @@ -229,6 +235,8 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Organizations], description: "Delete organization user memberships", security: [ { diff --git a/backend/src/server/routes/v2/project-membership-router.ts b/backend/src/server/routes/v2/project-membership-router.ts index 0c3ceb01e..a1a1cfc96 100644 --- a/backend/src/server/routes/v2/project-membership-router.ts +++ b/backend/src/server/routes/v2/project-membership-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { OrgMembershipRole, ProjectMembershipRole, ProjectMembershipsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { PROJECT_USERS } from "@app/lib/api-docs"; +import { ApiDocsTags, PROJECT_USERS } from "@app/lib/api-docs"; import { writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -15,6 +15,8 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectUsers], description: "Invite members to project", security: [ { @@ -78,6 +80,8 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.ProjectUsers], description: "Remove members from project", security: [ { diff --git a/backend/src/server/routes/v2/project-router.ts b/backend/src/server/routes/v2/project-router.ts index c8f68a926..2df358c3e 100644 --- a/backend/src/server/routes/v2/project-router.ts +++ b/backend/src/server/routes/v2/project-router.ts @@ -14,7 +14,7 @@ import { sanitizedSshCa } from "@app/ee/services/ssh/ssh-certificate-authority-s import { sanitizedSshCertificate } from "@app/ee/services/ssh-certificate/ssh-certificate-schema"; import { sanitizedSshCertificateTemplate } from "@app/ee/services/ssh-certificate-template/ssh-certificate-template-schema"; import { loginMappingSchema, sanitizedSshHost } from "@app/ee/services/ssh-host/ssh-host-schema"; -import { PROJECTS } from "@app/lib/api-docs"; +import { ApiDocsTags, PROJECTS } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { slugSchema } from "@app/server/lib/schemas"; import { getTelemetryDistinctId } from "@app/server/lib/telemetry"; @@ -150,6 +150,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Projects], description: "Create a new project", security: [ { @@ -224,6 +226,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Projects], description: "Delete project", security: [ { diff --git a/backend/src/server/routes/v2/service-token-router.ts b/backend/src/server/routes/v2/service-token-router.ts index fb10f17db..4e01b7ec5 100644 --- a/backend/src/server/routes/v2/service-token-router.ts +++ b/backend/src/server/routes/v2/service-token-router.ts @@ -8,6 +8,7 @@ import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; import { sanitizedServiceTokenUserSchema } from "../sanitizedSchemas"; +import { ApiDocsTags } from "@app/lib/api-docs"; export const sanitizedServiceTokenSchema = ServiceTokensSchema.omit({ secretHash: true, @@ -25,6 +26,8 @@ export const registerServiceTokenRouter = async (server: FastifyZodProvider) => }, onRequest: verifyAuth([AuthMode.SERVICE_TOKEN]), schema: { + hide: false, + tags: [ApiDocsTags.Integrations], description: "Return Infisical Token data", security: [ { diff --git a/backend/src/server/routes/v3/secret-router.ts b/backend/src/server/routes/v3/secret-router.ts index 0f53b777a..40aed624b 100644 --- a/backend/src/server/routes/v3/secret-router.ts +++ b/backend/src/server/routes/v3/secret-router.ts @@ -3,7 +3,7 @@ import { z } from "zod"; import { SecretApprovalRequestsSchema, SecretsSchema, SecretType, ServiceTokenScopes } from "@app/db/schemas"; import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types"; -import { RAW_SECRETS, SECRETS } from "@app/lib/api-docs"; +import { ApiDocsTags, RAW_SECRETS, SECRETS } from "@app/lib/api-docs"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { removeTrailingSlash } from "@app/lib/fn"; import { secretsLimit, writeLimit } from "@app/server/config/rateLimiter"; @@ -48,6 +48,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Secrets], description: "Attach tags to a secret", security: [ { @@ -103,6 +105,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Secrets], description: "Detach tags from a secret", security: [ { @@ -158,6 +162,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Secrets], description: "List secrets", security: [ { @@ -355,6 +361,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Secrets], params: z.object({ secretId: z.string() }), @@ -390,6 +398,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Secrets], description: "Get a secret by name", security: [ { @@ -496,6 +506,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Secrets], description: "Create secret", security: [ { @@ -609,6 +621,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Secrets], description: "Update secret", security: [ { @@ -729,6 +743,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Secrets], description: "Delete secret", security: [ { @@ -1486,6 +1502,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Secrets], body: z.object({ projectSlug: z.string().trim(), sourceEnvironment: z.string().trim(), @@ -1911,6 +1929,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Secrets], description: "Create many secrets", security: [ { @@ -2017,6 +2037,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Secrets], description: "Update many secrets", security: [ { @@ -2170,6 +2192,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Secrets], description: "Delete many secrets", security: [ { @@ -2266,6 +2290,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { rateLimit: secretsLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Secrets], description: "Get secret reference tree", security: [ { From 4d569d70d69dfd0ba046cfc02fc468bb5f36f794 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 21 Apr 2025 14:36:33 +0530 Subject: [PATCH 09/23] fix: broken docs --- backend/src/server/routes/v1/project-router.ts | 2 ++ backend/src/server/routes/v1/secret-import-router.ts | 2 ++ docs/api-reference/endpoints/project-groups/create.mdx | 2 +- docs/api-reference/endpoints/project-roles/create.mdx | 8 +++++--- docs/api-reference/endpoints/project-roles/delete.mdx | 2 +- .../api-reference/endpoints/project-roles/get-by-slug.mdx | 2 +- docs/api-reference/endpoints/project-roles/list.mdx | 2 +- docs/api-reference/endpoints/project-roles/update.mdx | 2 +- 8 files changed, 14 insertions(+), 8 deletions(-) diff --git a/backend/src/server/routes/v1/project-router.ts b/backend/src/server/routes/v1/project-router.ts index ad21ecc1b..d0abbd3e8 100644 --- a/backend/src/server/routes/v1/project-router.ts +++ b/backend/src/server/routes/v1/project-router.ts @@ -216,6 +216,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Projects], description: "Delete project", security: [ { diff --git a/backend/src/server/routes/v1/secret-import-router.ts b/backend/src/server/routes/v1/secret-import-router.ts index 5d1cd65df..fca11f8a0 100644 --- a/backend/src/server/routes/v1/secret-import-router.ts +++ b/backend/src/server/routes/v1/secret-import-router.ts @@ -269,6 +269,8 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) => rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SecretImports], description: "Get secret imports", security: [ { diff --git a/docs/api-reference/endpoints/project-groups/create.mdx b/docs/api-reference/endpoints/project-groups/create.mdx index 6b468085e..6dd7f1a4f 100644 --- a/docs/api-reference/endpoints/project-groups/create.mdx +++ b/docs/api-reference/endpoints/project-groups/create.mdx @@ -1,4 +1,4 @@ --- title: "Create Project Membership" -openapi: "POST /api/v2/workspace/{projectId}/groups/{groupId}" +openapi: "POST /api/v2/workspace/{projectId}/groups/{groupIdOrName}" --- diff --git a/docs/api-reference/endpoints/project-roles/create.mdx b/docs/api-reference/endpoints/project-roles/create.mdx index 7ebfff262..97570ec36 100644 --- a/docs/api-reference/endpoints/project-roles/create.mdx +++ b/docs/api-reference/endpoints/project-roles/create.mdx @@ -1,8 +1,10 @@ --- title: "Create" -openapi: "POST /api/v1/workspace/{projectSlug}/roles" +openapi: "POST /api/v2/workspace/{projectId}/roles" --- - You can read more about the permissions field in the [permissions documentation](/internals/permissions). - \ No newline at end of file + You can read more about the permissions field in the [permissions + documentation](/internals/permissions). + + diff --git a/docs/api-reference/endpoints/project-roles/delete.mdx b/docs/api-reference/endpoints/project-roles/delete.mdx index 6362c2154..41edfa7c3 100644 --- a/docs/api-reference/endpoints/project-roles/delete.mdx +++ b/docs/api-reference/endpoints/project-roles/delete.mdx @@ -1,4 +1,4 @@ --- title: "Delete" -openapi: "DELETE /api/v1/workspace/{projectSlug}/roles/{roleId}" +openapi: "DELETE /api/v2/workspace/{projectId}/roles/{roleId}" --- diff --git a/docs/api-reference/endpoints/project-roles/get-by-slug.mdx b/docs/api-reference/endpoints/project-roles/get-by-slug.mdx index 18817bca9..dfc5c582a 100644 --- a/docs/api-reference/endpoints/project-roles/get-by-slug.mdx +++ b/docs/api-reference/endpoints/project-roles/get-by-slug.mdx @@ -1,4 +1,4 @@ --- title: "Get By Slug" -openapi: "GET /api/v1/workspace/{projectSlug}/roles/slug/{slug}" +openapi: "GET /api/v2/workspace/{projectId}/roles/slug/{roleSlug}" --- diff --git a/docs/api-reference/endpoints/project-roles/list.mdx b/docs/api-reference/endpoints/project-roles/list.mdx index ca83d6e7d..8d8dc10c1 100644 --- a/docs/api-reference/endpoints/project-roles/list.mdx +++ b/docs/api-reference/endpoints/project-roles/list.mdx @@ -1,4 +1,4 @@ --- title: "List" -openapi: "GET /api/v1/workspace/{projectSlug}/roles" +openapi: "GET /api/v2/workspace/{projectId}/roles" --- diff --git a/docs/api-reference/endpoints/project-roles/update.mdx b/docs/api-reference/endpoints/project-roles/update.mdx index 5a3d9668e..662d5e617 100644 --- a/docs/api-reference/endpoints/project-roles/update.mdx +++ b/docs/api-reference/endpoints/project-roles/update.mdx @@ -1,4 +1,4 @@ --- title: "Update" -openapi: "PATCH /api/v1/workspace/{projectSlug}/roles/{roleId}" +openapi: "PATCH /api/v2/workspace/{projectId}/roles/{roleId}" --- From ca1f7d34482d73e74a9d8851ffbb445d3edcb0e4 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 21 Apr 2025 15:23:48 +0530 Subject: [PATCH 10/23] feat: reptile and rabbit changes --- .../src/ee/routes/v1/dynamic-secret-router.ts | 8 ++-- ...ity-project-additional-privilege-router.ts | 14 ++++++- ...ity-project-additional-privilege-router.ts | 12 +++--- backend/src/lib/api-docs/constants.ts | 38 ++++--------------- .../app-connection-router.ts | 2 +- .../routes/v1/identity-aws-iam-auth-router.ts | 2 +- .../routes/v1/identity-azure-auth-router.ts | 2 +- .../routes/v1/identity-gcp-auth-router.ts | 2 +- .../server/routes/v1/organization-router.ts | 2 +- .../server/routes/v1/project-env-router.ts | 2 +- .../src/server/routes/v1/project-router.ts | 2 + .../src/server/routes/v2/project-router.ts | 8 ++++ .../server/routes/v2/service-token-router.ts | 2 +- 13 files changed, 47 insertions(+), 49 deletions(-) diff --git a/backend/src/ee/routes/v1/dynamic-secret-router.ts b/backend/src/ee/routes/v1/dynamic-secret-router.ts index 3ff4fae7c..6e70effe4 100644 --- a/backend/src/ee/routes/v1/dynamic-secret-router.ts +++ b/backend/src/ee/routes/v1/dynamic-secret-router.ts @@ -297,17 +297,17 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => hide: false, tags: [ApiDocsTags.DynamicSecrets], params: z.object({ - name: z.string().min(1).describe(DYNAMIC_SECRETS.LIST_LEAES_BY_NAME.name) + name: z.string().min(1).describe(DYNAMIC_SECRETS.LIST_LEASES_BY_NAME.name) }), querystring: z.object({ - projectSlug: z.string().min(1).describe(DYNAMIC_SECRETS.LIST_LEAES_BY_NAME.projectSlug), + projectSlug: z.string().min(1).describe(DYNAMIC_SECRETS.LIST_LEASES_BY_NAME.projectSlug), path: z .string() .trim() .default("/") .transform(removeTrailingSlash) - .describe(DYNAMIC_SECRETS.LIST_LEAES_BY_NAME.path), - environmentSlug: z.string().min(1).describe(DYNAMIC_SECRETS.LIST_LEAES_BY_NAME.environmentSlug) + .describe(DYNAMIC_SECRETS.LIST_LEASES_BY_NAME.path), + environmentSlug: z.string().min(1).describe(DYNAMIC_SECRETS.LIST_LEASES_BY_NAME.environmentSlug) }), response: { 200: z.object({ diff --git a/backend/src/ee/routes/v1/identity-project-additional-privilege-router.ts b/backend/src/ee/routes/v1/identity-project-additional-privilege-router.ts index d6b1a4c5c..f64d3c979 100644 --- a/backend/src/ee/routes/v1/identity-project-additional-privilege-router.ts +++ b/backend/src/ee/routes/v1/identity-project-additional-privilege-router.ts @@ -3,7 +3,7 @@ import { z } from "zod"; import { IdentityProjectAdditionalPrivilegeTemporaryMode } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-types"; import { backfillPermissionV1SchemaToV2Schema } from "@app/ee/services/permission/project-permission"; -import { IDENTITY_ADDITIONAL_PRIVILEGE } from "@app/lib/api-docs"; +import { ApiDocsTags, IDENTITY_ADDITIONAL_PRIVILEGE } from "@app/lib/api-docs"; import { UnauthorizedError } from "@app/lib/errors"; import { ms } from "@app/lib/ms"; import { alphaNumericNanoId } from "@app/lib/nanoid"; @@ -25,6 +25,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.IdentitySpecificPrivilegesV1], description: "Create a permanent or a non expiry specific privilege for identity.", security: [ { @@ -85,6 +87,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.IdentitySpecificPrivilegesV1], description: "Create a temporary or a expiring specific privilege for identity.", security: [ { @@ -157,6 +161,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.IdentitySpecificPrivilegesV1], description: "Update a specific privilege of an identity.", security: [ { @@ -240,6 +246,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.IdentitySpecificPrivilegesV1], description: "Delete a specific privilege of an identity.", security: [ { @@ -279,6 +287,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.IdentitySpecificPrivilegesV1], description: "Retrieve details of a specific privilege by privilege slug.", security: [ { @@ -319,6 +329,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.IdentitySpecificPrivilegesV1], description: "List of a specific privilege of an identity in a project.", security: [ { diff --git a/backend/src/ee/routes/v2/identity-project-additional-privilege-router.ts b/backend/src/ee/routes/v2/identity-project-additional-privilege-router.ts index f5c5f0459..a6d4459e4 100644 --- a/backend/src/ee/routes/v2/identity-project-additional-privilege-router.ts +++ b/backend/src/ee/routes/v2/identity-project-additional-privilege-router.ts @@ -22,7 +22,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F }, schema: { hide: false, - tags: [ApiDocsTags.IdentitySpecificPrivileges], + tags: [ApiDocsTags.IdentitySpecificPrivilegesV2], description: "Add an additional privilege for identity.", security: [ { @@ -87,7 +87,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F }, schema: { hide: false, - tags: [ApiDocsTags.IdentitySpecificPrivileges], + tags: [ApiDocsTags.IdentitySpecificPrivilegesV2], description: "Update a specific identity privilege.", security: [ { @@ -153,7 +153,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F }, schema: { hide: false, - tags: [ApiDocsTags.IdentitySpecificPrivileges], + tags: [ApiDocsTags.IdentitySpecificPrivilegesV2], description: "Delete the specified identity privilege.", security: [ { @@ -190,7 +190,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F }, schema: { hide: false, - tags: [ApiDocsTags.IdentitySpecificPrivileges], + tags: [ApiDocsTags.IdentitySpecificPrivilegesV2], description: "Retrieve details of a specific privilege by id.", security: [ { @@ -227,7 +227,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F }, schema: { hide: false, - tags: [ApiDocsTags.IdentitySpecificPrivileges], + tags: [ApiDocsTags.IdentitySpecificPrivilegesV2], description: "Retrieve details of a specific privilege by slug.", security: [ { @@ -269,7 +269,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F }, schema: { hide: false, - tags: [ApiDocsTags.IdentitySpecificPrivileges], + tags: [ApiDocsTags.IdentitySpecificPrivilegesV2], description: "List privileges for the specified identity by project.", security: [ { diff --git a/backend/src/lib/api-docs/constants.ts b/backend/src/lib/api-docs/constants.ts index eab172b97..84ea6ff21 100644 --- a/backend/src/lib/api-docs/constants.ts +++ b/backend/src/lib/api-docs/constants.ts @@ -12,8 +12,8 @@ export enum ApiDocsTags { Identities = "Identities", TokenAuth = "Token Auth", UniversalAuth = "Universal Auth", - GcpAuth = "Gcp Auth", - AwsAuth = "Aws Auth", + GcpAuth = "GCP Auth", + AwsAuth = "AWS Auth", AzureAuth = "Azure Auth", KubernetesAuth = "Kubernetes Auth", JwtAuth = "JWT Auth", @@ -24,8 +24,8 @@ export enum ApiDocsTags { ProjectUsers = "Project Users", ProjectGroups = "Project Groups", ProjectIdentities = "Project Identities", - ProjectRoles = "ProjectRoles", - ProjectTemplates = "ProjectTemplates", + ProjectRoles = "Project Roles", + ProjectTemplates = "Project Templates", Environments = "Environments", Folders = "Folders", SecretTags = "Secret Tags", @@ -33,34 +33,10 @@ export enum ApiDocsTags { DynamicSecrets = "Dynamic Secrets", SecretImports = "Secret Imports", SecretRotations = "Secret Rotations", - IdentitySpecificPrivileges = "Identity Specific Privileges", + IdentitySpecificPrivilegesV1 = "Identity Specific Privileges", + IdentitySpecificPrivilegesV2 = "Identity Specific Privileges V2", AppConnections = "App Connections", - AppConnectionsAuth0 = "App Connection Auth0", - AppConnectionsAWS = "App Connection AWS", - AppConnectionsAzureAppConfiguration = "App Connection Azure App Configuration", - AppConnectionsAzureKeyVault = "App Connection Azure Key Vault", - AppConnectionsCamunda = "App Connection Camunda", - AppConnectionsDatabricks = "App Connection Databricks", - AppConnectionsGCP = "App Connection GCP", - AppConnectionsGitHub = "App Connection GitHub", - AppConnectionHumanitec = "App Connection Humanitec", - AppConnectionMsSQL = "App Connection Microsoft SQL Server", - AppConnectionPostgreSQL = "App Connection PostgreSQL", - AppConnectionTerraformCloud = "App Connection Terraform Cloud", - AppConnectionVercel = "App Connection Vercel", - AppConnectionWindmill = "App Connection Windmill", SecretSyncs = "Secret Syncs", - SecretSyncAwsParameterStore = "Secret Syncs AWS Parameter Store", - SecretSyncsAwsSecretManager = "Secret Syncs AWS Secret Manager", - SecretSyncAzureAppConfiguration = "Secret Syncs Azure App Configuration", - SecretSyncCamunda = "Secret Syncs Camunda", - SecretSyncDatabricks = "Secret Syncs Databricks", - SecretSyncGcpSecretManager = "Secret Syncs GCP Secret Manager", - SecretSyncGitHub = "Secret Syncs GitHub", - SecretSyncHumanitec = "Secret Syncs Humanitec", - SecretSyncTerraformCloud = "Secret Syncs Terraform Cloud", - SecretSyncVercel = "Secret Syncs Vercel", - SecretSyncWindmill = "Secret Syncs Windmill", Integrations = "Integrations", ServiceTokens = "Service Tokens", AuditLogs = "Audit Logs", @@ -957,7 +933,7 @@ export const DYNAMIC_SECRETS = { environmentSlug: "The slug of the environment to list folders from.", path: "The path to list folders from." }, - LIST_LEAES_BY_NAME: { + LIST_LEASES_BY_NAME: { projectSlug: "The slug of the project to create dynamic secret in.", environmentSlug: "The slug of the environment to list folders from.", path: "The path to list folders from.", diff --git a/backend/src/server/routes/v1/app-connection-routers/app-connection-router.ts b/backend/src/server/routes/v1/app-connection-routers/app-connection-router.ts index 52ec37f9d..25bef7270 100644 --- a/backend/src/server/routes/v1/app-connection-routers/app-connection-router.ts +++ b/backend/src/server/routes/v1/app-connection-routers/app-connection-router.ts @@ -1,6 +1,7 @@ import { z } from "zod"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { ApiDocsTags } from "@app/lib/api-docs"; import { readLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { Auth0ConnectionListItemSchema, SanitizedAuth0ConnectionSchema } from "@app/services/app-connection/auth0"; @@ -42,7 +43,6 @@ import { WindmillConnectionListItemSchema } from "@app/services/app-connection/windmill"; import { AuthMode } from "@app/services/auth/auth-type"; -import { ApiDocsTags } from "@app/lib/api-docs"; // can't use discriminated due to multiple schemas for certain apps const SanitizedAppConnectionSchema = z.union([ diff --git a/backend/src/server/routes/v1/identity-aws-iam-auth-router.ts b/backend/src/server/routes/v1/identity-aws-iam-auth-router.ts index 246bf935c..effd66a68 100644 --- a/backend/src/server/routes/v1/identity-aws-iam-auth-router.ts +++ b/backend/src/server/routes/v1/identity-aws-iam-auth-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { IdentityAwsAuthsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { AWS_AUTH, ApiDocsTags } from "@app/lib/api-docs"; +import { ApiDocsTags, AWS_AUTH } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; diff --git a/backend/src/server/routes/v1/identity-azure-auth-router.ts b/backend/src/server/routes/v1/identity-azure-auth-router.ts index ee13642e9..9053bc2e3 100644 --- a/backend/src/server/routes/v1/identity-azure-auth-router.ts +++ b/backend/src/server/routes/v1/identity-azure-auth-router.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { IdentityAzureAuthsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { AZURE_AUTH, ApiDocsTags } from "@app/lib/api-docs"; +import { ApiDocsTags, AZURE_AUTH } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; diff --git a/backend/src/server/routes/v1/identity-gcp-auth-router.ts b/backend/src/server/routes/v1/identity-gcp-auth-router.ts index 82b5bfb8b..b83faf9d9 100644 --- a/backend/src/server/routes/v1/identity-gcp-auth-router.ts +++ b/backend/src/server/routes/v1/identity-gcp-auth-router.ts @@ -22,7 +22,7 @@ export const registerIdentityGcpAuthRouter = async (server: FastifyZodProvider) tags: [ApiDocsTags.GcpAuth], description: "Login with GCP Auth", body: z.object({ - identityId: z.string().trim().describe(GCP_AUTH.LOGIN.identityId).trim(), + identityId: z.string().trim().describe(GCP_AUTH.LOGIN.identityId), jwt: z.string() }), response: { diff --git a/backend/src/server/routes/v1/organization-router.ts b/backend/src/server/routes/v1/organization-router.ts index e52149740..22314b54b 100644 --- a/backend/src/server/routes/v1/organization-router.ts +++ b/backend/src/server/routes/v1/organization-router.ts @@ -9,7 +9,7 @@ import { UsersSchema } from "@app/db/schemas"; import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types"; -import { AUDIT_LOGS, ApiDocsTags, ORGANIZATIONS } from "@app/lib/api-docs"; +import { ApiDocsTags, AUDIT_LOGS, ORGANIZATIONS } from "@app/lib/api-docs"; import { getLastMidnightDateISO, removeTrailingSlash } from "@app/lib/fn"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { GenericResourceNameSchema, slugSchema } from "@app/server/lib/schemas"; diff --git a/backend/src/server/routes/v1/project-env-router.ts b/backend/src/server/routes/v1/project-env-router.ts index 48b6f0195..9a136e160 100644 --- a/backend/src/server/routes/v1/project-env-router.ts +++ b/backend/src/server/routes/v1/project-env-router.ts @@ -13,7 +13,7 @@ export const registerProjectEnvRouter = async (server: FastifyZodProvider) => { method: "GET", url: "/:workspaceId/environments/:envId", config: { - rateLimit: writeLimit + rateLimit: readLimit }, schema: { hide: false, diff --git a/backend/src/server/routes/v1/project-router.ts b/backend/src/server/routes/v1/project-router.ts index d0abbd3e8..2bb57767e 100644 --- a/backend/src/server/routes/v1/project-router.ts +++ b/backend/src/server/routes/v1/project-router.ts @@ -563,6 +563,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Integrations], description: "List integration auth objects for a workspace.", security: [ { diff --git a/backend/src/server/routes/v2/project-router.ts b/backend/src/server/routes/v2/project-router.ts index 2df358c3e..353c7525b 100644 --- a/backend/src/server/routes/v2/project-router.ts +++ b/backend/src/server/routes/v2/project-router.ts @@ -346,6 +346,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateAuthorities], params: z.object({ slug: slugSchema({ min: 5, max: 36 }).describe(PROJECTS.LIST_CAS.slug) }), @@ -387,6 +389,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificates], params: z.object({ slug: slugSchema({ min: 5, max: 36 }).describe(PROJECTS.LIST_CERTIFICATES.slug) }), @@ -555,6 +559,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SshCertificateTemplates], params: z.object({ projectId: z.string().trim().describe(PROJECTS.LIST_SSH_CERTIFICATE_TEMPLATES.projectId) }), @@ -585,6 +591,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.SshCertificateAuthorities], params: z.object({ projectId: z.string().trim().describe(PROJECTS.LIST_SSH_CAS.projectId) }), diff --git a/backend/src/server/routes/v2/service-token-router.ts b/backend/src/server/routes/v2/service-token-router.ts index 4e01b7ec5..fcc61a386 100644 --- a/backend/src/server/routes/v2/service-token-router.ts +++ b/backend/src/server/routes/v2/service-token-router.ts @@ -2,13 +2,13 @@ import { z } from "zod"; import { ServiceTokensSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { ApiDocsTags } from "@app/lib/api-docs"; import { removeTrailingSlash } from "@app/lib/fn"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; import { sanitizedServiceTokenUserSchema } from "../sanitizedSchemas"; -import { ApiDocsTags } from "@app/lib/api-docs"; export const sanitizedServiceTokenSchema = ServiceTokensSchema.omit({ secretHash: true, From efb8b69777f75f163730812f5a7089b17dec5d4f Mon Sep 17 00:00:00 2001 From: carlosmonastyrski Date: Mon, 21 Apr 2025 14:06:33 -0300 Subject: [PATCH 11/23] Fix SecretVersionV2 reference issue blocking users and identities deletion --- ...-user-deletion-secret-version-reference.ts | 29 +++++++++++++++++++ .../SecretListView/SecretDetailSidebar.tsx | 6 +++- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 backend/src/db/migrations/20250421165221_fix-identites-and-user-deletion-secret-version-reference.ts diff --git a/backend/src/db/migrations/20250421165221_fix-identites-and-user-deletion-secret-version-reference.ts b/backend/src/db/migrations/20250421165221_fix-identites-and-user-deletion-secret-version-reference.ts new file mode 100644 index 000000000..f5280c979 --- /dev/null +++ b/backend/src/db/migrations/20250421165221_fix-identites-and-user-deletion-secret-version-reference.ts @@ -0,0 +1,29 @@ +import { Knex } from "knex"; + +import { TableName } from "@app/db/schemas"; + +export async function up(knex: Knex): Promise { + await knex.schema.alterTable(TableName.SecretVersionV2, (table) => { + table.dropForeign(["userActorId"]); + table.dropForeign(["identityActorId"]); + }); + + await knex.schema.alterTable(TableName.SecretVersionV2, (table) => { + table.foreign("userActorId").references("id").inTable(TableName.Users).onDelete("SET NULL"); + + table.foreign("identityActorId").references("id").inTable(TableName.Identity).onDelete("SET NULL"); + }); +} + +export async function down(knex: Knex): Promise { + await knex.schema.alterTable(TableName.SecretVersionV2, (table) => { + table.dropForeign(["userActorId"]); + table.dropForeign(["identityActorId"]); + }); + + await knex.schema.alterTable(TableName.SecretVersionV2, (table) => { + table.foreign("userActorId").references("id").inTable(TableName.Users); + + table.foreign("identityActorId").references("id").inTable(TableName.Identity); + }); +} diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/components/SecretListView/SecretDetailSidebar.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/components/SecretListView/SecretDetailSidebar.tsx index 6c9c549af..c2d404ff6 100644 --- a/frontend/src/pages/secret-manager/SecretDashboardPage/components/SecretListView/SecretDetailSidebar.tsx +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/components/SecretListView/SecretDetailSidebar.tsx @@ -252,8 +252,12 @@ export const SecretDetailSidebar = ({ switch (userType) { case ActorType.PLATFORM: return "System-generated"; + case ActorType.IDENTITY: + return userName || "Deleted Identity"; + case ActorType.USER: + return userName || "Deleted User"; default: - return userName; + return "Unknown"; } }; From c15a1c6ed3172ef10e393410671d16382bc76b2a Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 22 Apr 2025 01:38:21 +0800 Subject: [PATCH 12/23] misc: moved regex use to re2 --- backend/package-lock.json | 714 +++++++++++++++++- backend/package.json | 1 + .../services/dynamic-secret/providers/ldap.ts | 7 +- .../ssh-certificate-template-validators.ts | 3 +- .../ssh/ssh-certificate-authority-fns.ts | 5 +- backend/src/lib/base64/index.ts | 12 +- backend/src/lib/fn/string.ts | 5 +- backend/src/lib/validator/validate-string.ts | 3 +- backend/src/lib/validator/validate-url.ts | 20 +- backend/src/lib/zod/index.ts | 6 + .../src/server/routes/v1/project-router.ts | 9 +- .../certificate-template-fns.ts | 6 +- .../identity-aws-auth-service.ts | 3 +- .../identity-aws-auth-validators.ts | 5 +- .../integration-sync-secret.ts | 3 +- .../secret-v2-bridge/secret-v2-bridge-fns.ts | 32 +- backend/src/services/secret/secret-fns.ts | 36 +- 17 files changed, 826 insertions(+), 44 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index 3cd03cd6e..be6137424 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -104,6 +104,7 @@ "pkijs": "^3.2.4", "posthog-node": "^3.6.2", "probot": "^13.3.8", + "re2": "^1.21.4", "safe-regex": "^2.1.1", "scim-patch": "^0.8.3", "scim2-parse-filter": "^0.2.10", @@ -6860,6 +6861,79 @@ "node": ">= 8" } }, + "node_modules/@npmcli/agent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz", + "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==", + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/agent/node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/@npmcli/agent/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@npmcli/agent/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/@npmcli/fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", + "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/@octokit/auth-app": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-7.1.1.tgz", @@ -11863,6 +11937,115 @@ "node": ">=8" } }, + "node_modules/cacache": { + "version": "18.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", + "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -12842,6 +13025,16 @@ "node": ">= 0.8" } }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -12874,6 +13067,21 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "license": "MIT" + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -13644,6 +13852,12 @@ "node": ">=0.10.0" } }, + "node_modules/exponential-backoff": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz", + "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==", + "license": "Apache-2.0" + }, "node_modules/express": { "version": "4.21.2", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", @@ -15221,6 +15435,12 @@ ], "license": "MIT" }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "license": "BSD-2-Clause" + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -15403,7 +15623,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, "engines": { "node": ">=0.8.19" } @@ -15436,6 +15655,16 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, + "node_modules/install-artifact-from-github": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/install-artifact-from-github/-/install-artifact-from-github-1.3.5.tgz", + "integrity": "sha512-gZHC7f/cJgXz7MXlHFBxPVMsvIbev1OQN1uKQYKVJDydGNm9oYf9JstbU4Atnh/eSvk41WtEovoRm+8IF686xg==", + "license": "BSD-3-Clause", + "bin": { + "install-from-cache": "bin/install-from-cache.js", + "save-to-github-cache": "bin/save-to-github-cache.js" + } + }, "node_modules/internal-slot": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", @@ -15518,6 +15747,19 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/ip-num": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/ip-num/-/ip-num-1.5.1.tgz", @@ -15717,6 +15959,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "license": "MIT" + }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -16860,6 +17108,38 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "node_modules/make-fetch-happen": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", + "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -17033,6 +17313,125 @@ "node": ">=8" } }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-fetch/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", @@ -17354,6 +17753,12 @@ "node": ">=12" } }, + "node_modules/nan": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.2.tgz", + "integrity": "sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==", + "license": "MIT" + }, "node_modules/nanoid": { "version": "3.3.8", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", @@ -17444,6 +17849,30 @@ } } }, + "node_modules/node-gyp": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.3.1.tgz", + "integrity": "sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==", + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^13.0.0", + "nopt": "^7.0.0", + "proc-log": "^4.1.0", + "semver": "^7.3.5", + "tar": "^6.2.1", + "which": "^4.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, "node_modules/node-gyp-build": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.9.0.tgz", @@ -17465,6 +17894,122 @@ "node-gyp-build-optional-packages-test": "build-test.js" } }, + "node_modules/node-gyp/node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/node-gyp/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/node-gyp/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/node-gyp/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/node-gyp/node_modules/nopt": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", + "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, "node_modules/node-releases": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", @@ -18125,6 +18670,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-queue": { "version": "6.6.2", "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", @@ -19202,6 +19762,15 @@ "real-require": "^0.2.0" } }, + "node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -19230,6 +19799,28 @@ "node": ">=0.4.0" } }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/promise-retry/node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/prompt-sync": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/prompt-sync/-/prompt-sync-4.2.0.tgz", @@ -19501,6 +20092,18 @@ "node": ">=0.10.0" } }, + "node_modules/re2": { + "version": "1.21.4", + "resolved": "https://registry.npmjs.org/re2/-/re2-1.21.4.tgz", + "integrity": "sha512-MVIfXWJmsP28mRsSt8HeL750ifb8H5+oF2UDIxGaiJCr8fkMqhLZ7kcX9ADRk2dC8qeGKedB7UVYRfBVpEiLfA==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "install-artifact-from-github": "^1.3.5", + "nan": "^2.20.0", + "node-gyp": "^10.2.0" + } + }, "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -20422,6 +21025,16 @@ "node": ">=8" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, "node_modules/smee-client": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/smee-client/-/smee-client-2.0.0.tgz", @@ -20625,6 +21238,60 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/socks": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz", + "integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==", + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/socks-proxy-agent/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/sonic-boom": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.7.0.tgz", @@ -20680,6 +21347,27 @@ "node": ">= 0.6" } }, + "node_modules/ssri": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ssri/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", @@ -22482,6 +23170,30 @@ "node": ">=4" } }, + "node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/universal-github-app-jwt": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-2.2.0.tgz", diff --git a/backend/package.json b/backend/package.json index 66eddcc10..b2c0d751a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -221,6 +221,7 @@ "pkijs": "^3.2.4", "posthog-node": "^3.6.2", "probot": "^13.3.8", + "re2": "^1.21.4", "safe-regex": "^2.1.1", "scim-patch": "^0.8.3", "scim2-parse-filter": "^0.2.10", diff --git a/backend/src/ee/services/dynamic-secret/providers/ldap.ts b/backend/src/ee/services/dynamic-secret/providers/ldap.ts index 992c9098e..cc68304e0 100644 --- a/backend/src/ee/services/dynamic-secret/providers/ldap.ts +++ b/backend/src/ee/services/dynamic-secret/providers/ldap.ts @@ -2,6 +2,7 @@ import handlebars from "handlebars"; import ldapjs from "ldapjs"; import ldif from "ldif"; import { customAlphabet } from "nanoid"; +import RE2 from "re2"; import { z } from "zod"; import { BadRequestError } from "@app/lib/errors"; @@ -194,7 +195,8 @@ export const LdapProvider = (): TDynamicProviderFns => { const client = await $getClient(providerInputs); if (providerInputs.credentialType === LdapCredentialType.Static) { - const dnMatch = providerInputs.rotationLdif.match(/^dn:\s*(.+)/m); + const dnRegex = new RE2("^dn:\\s*(.+)", "m"); + const dnMatch = dnRegex.exec(providerInputs.rotationLdif); if (dnMatch) { const username = dnMatch[1]; @@ -238,7 +240,8 @@ export const LdapProvider = (): TDynamicProviderFns => { const client = await $getClient(providerInputs); if (providerInputs.credentialType === LdapCredentialType.Static) { - const dnMatch = providerInputs.rotationLdif.match(/^dn:\s*(.+)/m); + const dnRegex = new RE2("^dn:\\s*(.+)", "m"); + const dnMatch = dnRegex.exec(providerInputs.rotationLdif); if (dnMatch) { const username = dnMatch[1]; diff --git a/backend/src/ee/services/ssh-certificate-template/ssh-certificate-template-validators.ts b/backend/src/ee/services/ssh-certificate-template/ssh-certificate-template-validators.ts index 48d793970..a09cc55ff 100644 --- a/backend/src/ee/services/ssh-certificate-template/ssh-certificate-template-validators.ts +++ b/backend/src/ee/services/ssh-certificate-template/ssh-certificate-template-validators.ts @@ -1,4 +1,5 @@ import { isIP } from "net"; +import RE2 from "re2"; import { isFQDN } from "@app/lib/validator/validate-url"; @@ -10,7 +11,7 @@ export const isValidUserPattern = (value: string): boolean => { if (value === "*") return true; // Handle wildcard separately // Simpler, more specific pattern for usernames - const userRegex = /^[a-z_][a-z0-9_-]*$/i; + const userRegex = new RE2(/^[a-z_][a-z0-9_-]*$/i); return userRegex.test(value); }; diff --git a/backend/src/ee/services/ssh/ssh-certificate-authority-fns.ts b/backend/src/ee/services/ssh/ssh-certificate-authority-fns.ts index 92f946747..60c966fcd 100644 --- a/backend/src/ee/services/ssh/ssh-certificate-authority-fns.ts +++ b/backend/src/ee/services/ssh/ssh-certificate-authority-fns.ts @@ -4,6 +4,7 @@ import { promises as fs } from "fs"; import { Knex } from "knex"; import os from "os"; import path from "path"; +import RE2 from "re2"; import { promisify } from "util"; import { TSshCertificateTemplates } from "@app/db/schemas"; @@ -156,14 +157,14 @@ export const validateSshCertificatePrincipals = ( }); } - if (/\r|\n|\t|\0/.test(sanitized)) { + if (new RE2(/\r|\n|\t|\0/).test(sanitized)) { throw new BadRequestError({ message: `Principal '${sanitized}' contains invalid whitespace or control characters.` }); } // disallow whitespace anywhere - if (/\s/.test(sanitized)) { + if (new RE2(/\s/).test(sanitized)) { throw new BadRequestError({ message: `Principal '${sanitized}' cannot contain whitespace.` }); diff --git a/backend/src/lib/base64/index.ts b/backend/src/lib/base64/index.ts index 2bffef3fc..dfdd03d47 100644 --- a/backend/src/lib/base64/index.ts +++ b/backend/src/lib/base64/index.ts @@ -1,12 +1,16 @@ +import RE2 from "re2"; + type Base64Options = { urlSafe?: boolean; padding?: boolean; }; -const base64WithPadding = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$/; -const base64WithoutPadding = /^[A-Za-z0-9+/]+$/; -const base64UrlWithPadding = /^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2}==|[A-Za-z0-9_-]{3}=|[A-Za-z0-9_-]{4})$/; -const base64UrlWithoutPadding = /^[A-Za-z0-9_-]+$/; +const base64WithPadding = new RE2(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$/); +const base64WithoutPadding = new RE2(/^[A-Za-z0-9+/]+$/); +const base64UrlWithPadding = new RE2( + /^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2}==|[A-Za-z0-9_-]{3}=|[A-Za-z0-9_-]{4})$/ +); +const base64UrlWithoutPadding = new RE2(/^[A-Za-z0-9_-]+$/); export const isBase64 = (str: string, options: Base64Options = {}): boolean => { if (typeof str !== "string") { diff --git a/backend/src/lib/fn/string.ts b/backend/src/lib/fn/string.ts index 1dc2bbfed..2fa4c9166 100644 --- a/backend/src/lib/fn/string.ts +++ b/backend/src/lib/fn/string.ts @@ -1,4 +1,5 @@ import path from "path"; +import RE2 from "re2"; // given two paths irrespective of ending with / or not // this will return true if its equal @@ -15,4 +16,6 @@ export const prefixWithSlash = (str: string) => { return `/${str}`; }; -export const startsWithVowel = (str: string) => /^[aeiou]/i.test(str); +const vowelRegex = new RE2(/^[aeiou]/i); + +export const startsWithVowel = (str: string) => vowelRegex.test(str); diff --git a/backend/src/lib/validator/validate-string.ts b/backend/src/lib/validator/validate-string.ts index d2d033693..4e89d313f 100644 --- a/backend/src/lib/validator/validate-string.ts +++ b/backend/src/lib/validator/validate-string.ts @@ -1,3 +1,4 @@ +import RE2 from "re2"; import { z } from "zod"; export enum CharacterType { @@ -92,7 +93,7 @@ export const characterValidator = (allowedCharacters: CharacterType[]) => { const combinedPattern = allowedCharacters.map((char) => patternMap[char]).join(""); // Create a regex that matches only the allowed characters - const regex = new RegExp(`^[${combinedPattern}]+$`); + const regex = new RE2(`^[${combinedPattern}]+$`); /** * Validates if the input string contains only the allowed character types diff --git a/backend/src/lib/validator/validate-url.ts b/backend/src/lib/validator/validate-url.ts index fdf99e405..6a8fa4941 100644 --- a/backend/src/lib/validator/validate-url.ts +++ b/backend/src/lib/validator/validate-url.ts @@ -1,6 +1,7 @@ import dns from "node:dns/promises"; import { isIPv4 } from "net"; +import RE2 from "re2"; import { getConfig } from "@app/lib/config/env"; @@ -80,42 +81,47 @@ export const isFQDN = (str: string, options: FQDNOptions = {}): boolean => { if ( !opts.allow_numeric_tld && - !/^([a-z\u00A1-\u00A8\u00AA-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,}|xn[a-z0-9-]{2,})$/i.test(tld) + !new RE2(/^([a-z\u00A1-\u00A8\u00AA-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,}|xn[a-z0-9-]{2,})$/i).test(tld) ) { return false; } // disallow spaces - if (/\s/.test(tld)) { + if (new RE2(/\s/).test(tld)) { return false; } } // reject numeric TLDs - if (!opts.allow_numeric_tld && /^\d+$/.test(tld)) { + if (!opts.allow_numeric_tld && new RE2(/^\d+$/).test(tld)) { return false; } + const partRegex = new RE2(/^[a-z_\u00a1-\uffff0-9-]+$/i); + const fullWidthRegex = new RE2(/[\uff01-\uff5e]/); + const hyphenRegex = new RE2(/^-|-$/); + const underscoreRegex = new RE2("_"); + return parts.every((part) => { if (part.length > 63 && !opts.ignore_max_length) { return false; } - if (!/^[a-z_\u00a1-\uffff0-9-]+$/i.test(part)) { + if (!partRegex.test(part)) { return false; } // disallow full-width chars - if (/[\uff01-\uff5e]/.test(part)) { + if (fullWidthRegex.test(part)) { return false; } // disallow parts starting or ending with hyphen - if (/^-|-$/.test(part)) { + if (hyphenRegex.test(part)) { return false; } - if (!opts.allow_underscores && /_/.test(part)) { + if (!opts.allow_underscores && underscoreRegex.test(part)) { return false; } diff --git a/backend/src/lib/zod/index.ts b/backend/src/lib/zod/index.ts index 4d3fea8c7..21c59b6ba 100644 --- a/backend/src/lib/zod/index.ts +++ b/backend/src/lib/zod/index.ts @@ -1,3 +1,4 @@ +import RE2 from "re2"; import { z, ZodTypeAny } from "zod"; // this is a patched zod string to remove empty string to undefined @@ -11,3 +12,8 @@ export const zpStr = (schema: T, opt: { stripNull: boolean export const zodBuffer = z.custom((data) => Buffer.isBuffer(data) || data instanceof Uint8Array, { message: "Expected binary data (Buffer Or Uint8Array)" }); + +export const re2Validator = (pattern: string | RegExp) => { + const re2Pattern = new RE2(pattern); + return (value: string) => re2Pattern.test(value); +}; diff --git a/backend/src/server/routes/v1/project-router.ts b/backend/src/server/routes/v1/project-router.ts index 4182ce389..407bdef1f 100644 --- a/backend/src/server/routes/v1/project-router.ts +++ b/backend/src/server/routes/v1/project-router.ts @@ -15,6 +15,7 @@ import { import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { PROJECTS } from "@app/lib/api-docs"; import { CharacterType, characterValidator } from "@app/lib/validator/validate-string"; +import { re2Validator } from "@app/lib/zod"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { ActorType, AuthMode } from "@app/services/auth/auth-type"; @@ -316,11 +317,11 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { slug: z .string() .trim() - .regex( - /^[a-z0-9]+(?:[_-][a-z0-9]+)*$/, - "Project slug can only contain lowercase letters and numbers, with optional single hyphens (-) or underscores (_) between words. Cannot start or end with a hyphen or underscore." - ) .max(64, { message: "Slug must be 64 characters or fewer" }) + .refine(re2Validator(/^[a-z0-9]+(?:[_-][a-z0-9]+)*$/), { + message: + "Project slug can only contain lowercase letters and numbers, with optional single hyphens (-) or underscores (_) between words. Cannot start or end with a hyphen or underscore." + }) .optional() .describe(PROJECTS.UPDATE.slug) }), diff --git a/backend/src/services/certificate-template/certificate-template-fns.ts b/backend/src/services/certificate-template/certificate-template-fns.ts index fa8055f69..b6ec8d755 100644 --- a/backend/src/services/certificate-template/certificate-template-fns.ts +++ b/backend/src/services/certificate-template/certificate-template-fns.ts @@ -1,3 +1,5 @@ +import RE2 from "re2"; + import { TCertificateTemplates } from "@app/db/schemas"; import { BadRequestError } from "@app/lib/errors"; import { ms } from "@app/lib/ms"; @@ -12,7 +14,7 @@ export const validateCertificateDetailsAgainstTemplate = ( template: TCertificateTemplates ) => { // these are validated in router using validateTemplateRegexField - const commonNameRegex = new RegExp(template.commonName); + const commonNameRegex = new RE2(template.commonName); if (!commonNameRegex.test(cert.commonName)) { throw new BadRequestError({ message: "Invalid common name based on template policy" @@ -25,7 +27,7 @@ export const validateCertificateDetailsAgainstTemplate = ( }); } - const subjectAlternativeNameRegex = new RegExp(template.subjectAlternativeName); + const subjectAlternativeNameRegex = new RE2(template.subjectAlternativeName); cert.altNames.forEach((altName) => { if (!subjectAlternativeNameRegex.test(altName)) { throw new BadRequestError({ diff --git a/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts b/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts index 7f0aadfca..68989893f 100644 --- a/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts +++ b/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts @@ -2,6 +2,7 @@ import { ForbiddenError } from "@casl/ability"; import axios from "axios"; import jwt from "jsonwebtoken"; +import RE2 from "re2"; import { IdentityAuthMethod } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; @@ -125,7 +126,7 @@ export const identityAwsAuthServiceFactory = ({ // convert wildcard ARN to a regular expression: "arn:aws:iam::123456789012:*" -> "^arn:aws:iam::123456789012:.*$" // considers exact matches + wildcard matches // heavily validated in router - const regex = new RegExp(`^${principalArn.replaceAll("*", ".*")}$`); + const regex = new RE2(`^${principalArn.replaceAll("*", ".*")}$`); return regex.test(extractPrincipalArn(Arn)); }); diff --git a/backend/src/services/identity-aws-auth/identity-aws-auth-validators.ts b/backend/src/services/identity-aws-auth/identity-aws-auth-validators.ts index b3f3ccc94..1a6e5cbd6 100644 --- a/backend/src/services/identity-aws-auth/identity-aws-auth-validators.ts +++ b/backend/src/services/identity-aws-auth/identity-aws-auth-validators.ts @@ -1,9 +1,10 @@ +import RE2 from "re2"; import safe from "safe-regex"; import { z } from "zod"; -const twelveDigitRegex = /^\d{12}$/; +const twelveDigitRegex = new RE2(/^\d{12}$/); // akhilmhdh: change this to a normal function later. Checked no redosable at the moment -const arnRegex = /^arn:aws:iam::\d{12}:(user\/[a-zA-Z0-9_.@+*/-]+|role\/[a-zA-Z0-9_.@+*/-]+|\*)$/; +const arnRegex = new RE2(/^arn:aws:iam::\d{12}:(user\/[a-zA-Z0-9_.@+*/-]+|role\/[a-zA-Z0-9_.@+*/-]+|\*)$/); export const validateAccountIds = z .string() diff --git a/backend/src/services/integration-auth/integration-sync-secret.ts b/backend/src/services/integration-auth/integration-sync-secret.ts index 6be7397f3..989a5a88c 100644 --- a/backend/src/services/integration-auth/integration-sync-secret.ts +++ b/backend/src/services/integration-auth/integration-sync-secret.ts @@ -27,6 +27,7 @@ import { randomUUID } from "crypto"; import https from "https"; import sodium from "libsodium-wrappers"; import isEqual from "lodash.isequal"; +import RE2 from "re2"; import { z } from "zod"; import { SecretType, TIntegrationAuths, TIntegrations } from "@app/db/schemas"; @@ -4151,7 +4152,7 @@ const syncSecretsWindmill = async ({ ); // eslint-disable-next-line - const pattern = new RegExp("^(u/|f/)[a-zA-Z0-9_-]+/([a-zA-Z0-9_-]+/)*[a-zA-Z0-9_-]*[^/]$"); + const pattern = new RE2("^(u/|f/)[a-zA-Z0-9_-]+/([a-zA-Z0-9_-]+/)*[a-zA-Z0-9_-]*[^/]$"); for await (const key of Object.keys(secrets)) { if ((key.startsWith("u/") || key.startsWith("f/")) && pattern.test(key)) { if (!(key in res)) { diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts index 3b35ab41a..4e7a5bca7 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts @@ -1,5 +1,7 @@ import path from "node:path"; +import RE2 from "re2"; + import { TableName, TSecretFolders, TSecretsV2 } from "@app/db/schemas"; import { ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; import { groupBy } from "@app/lib/fn"; @@ -13,9 +15,8 @@ import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; import { TSecretV2BridgeDALFactory } from "./secret-v2-bridge-dal"; import { TFnSecretBulkDelete, TFnSecretBulkInsert, TFnSecretBulkUpdate } from "./secret-v2-bridge-types"; -const INTERPOLATION_SYNTAX_REG = /\${([a-zA-Z0-9-_.]+)}/g; -// akhilmhdh: JS regex with global save state in .test -const INTERPOLATION_SYNTAX_REG_NON_GLOBAL = /\${([a-zA-Z0-9-_.]+)}/; +const INTERPOLATION_PATTERN_STRING = String.raw`\${([a-zA-Z0-9-_.]+)}`; +const INTERPOLATION_TEST_REGEX = new RE2(INTERPOLATION_PATTERN_STRING); export const shouldUseSecretV2Bridge = (version: number) => version === 3; @@ -36,7 +37,14 @@ export const shouldUseSecretV2Bridge = (version: number) => version === 3; * // ] */ export const getAllSecretReferences = (maybeSecretReference: string) => { - const references = Array.from(maybeSecretReference.matchAll(INTERPOLATION_SYNTAX_REG), (m) => m[1]); + const references = []; + let match; + + const regex = new RE2(INTERPOLATION_PATTERN_STRING, "g"); + // eslint-disable-next-line no-cond-assign + while ((match = regex.exec(maybeSecretReference)) !== null) { + references.push(match[1]); + } const nestedReferences = references .filter((el) => el.includes(".")) @@ -531,9 +539,17 @@ export const expandSecretReferencesFactory = ({ // eslint-disable-next-line no-continue if (depth > MAX_SECRET_REFERENCE_DEPTH) continue; - const refs = value?.match(INTERPOLATION_SYNTAX_REG); - if (refs) { + const matchRegex = new RE2(INTERPOLATION_PATTERN_STRING, "g"); + const refs = []; + let match; + + // eslint-disable-next-line no-cond-assign + while ((match = matchRegex.exec(value || "")) !== null) { + refs.push(match[0]); + } + + if (refs.length > 0) { for (const interpolationSyntax of refs) { const interpolationKey = interpolationSyntax.slice(2, interpolationSyntax.length - 1); const entities = interpolationKey.trim().split("."); @@ -592,7 +608,7 @@ export const expandSecretReferencesFactory = ({ trace }; - const shouldExpandMore = INTERPOLATION_SYNTAX_REG_NON_GLOBAL.test(referencedSecretValue); + const shouldExpandMore = INTERPOLATION_TEST_REGEX.test(referencedSecretValue); if (dto.shouldStackTrace) { const stackTraceNode = { ...node, children: [], key: referencedSecretKey, trace: null }; trace?.children.push(stackTraceNode); @@ -626,7 +642,7 @@ export const expandSecretReferencesFactory = ({ }) => { if (!inputSecret.value) return inputSecret.value; - const shouldExpand = Boolean(inputSecret.value?.match(INTERPOLATION_SYNTAX_REG)); + const shouldExpand = INTERPOLATION_TEST_REGEX.test(inputSecret.value); if (!shouldExpand) return inputSecret.value; const { expandedValue } = await recursivelyExpandSecret(inputSecret); diff --git a/backend/src/services/secret/secret-fns.ts b/backend/src/services/secret/secret-fns.ts index 2574dc13e..f08a5a04c 100644 --- a/backend/src/services/secret/secret-fns.ts +++ b/backend/src/services/secret/secret-fns.ts @@ -1,5 +1,6 @@ /* eslint-disable no-await-in-loop */ import path from "path"; +import RE2 from "re2"; import { ActionProjectType, @@ -218,7 +219,9 @@ type TInterpolateSecretArg = { }; const MAX_SECRET_REFERENCE_DEPTH = 5; -const INTERPOLATION_SYNTAX_REG = /\${([a-zA-Z0-9-_.]+)}/g; +const INTERPOLATION_PATTERN_STRING = String.raw`\${([a-zA-Z0-9-_.]+)}`; +const INTERPOLATION_TEST_REGEX = new RE2(INTERPOLATION_PATTERN_STRING); + export const interpolateSecrets = ({ projectId, secretEncKey, secretDAL, folderDAL }: TInterpolateSecretArg) => { const secretCache: Record> = {}; const getCacheUniqueKey = (environment: string, secretPath: string) => `${environment}-${secretPath}`; @@ -273,9 +276,17 @@ export const interpolateSecrets = ({ projectId, secretEncKey, secretDAL, folderD if (!value) return ""; if (depth > MAX_SECRET_REFERENCE_DEPTH) return ""; - const refs = value.match(INTERPOLATION_SYNTAX_REG); + const refs = []; + let match; + const execRegex = new RE2(INTERPOLATION_PATTERN_STRING, "g"); + + // eslint-disable-next-line no-cond-assign + while ((match = execRegex.exec(value)) !== null) { + refs.push(match[0]); + } + let expandedValue = value; - if (refs) { + if (refs.length > 0) { for (const interpolationSyntax of refs) { const interpolationKey = interpolationSyntax.slice(2, interpolationSyntax.length - 1); const entities = interpolationKey.trim().split("."); @@ -284,7 +295,7 @@ export const interpolateSecrets = ({ projectId, secretEncKey, secretDAL, folderD const [secretKey] = entities; // eslint-disable-next-line let referenceValue = await fetchSecret(environment, secretPath, secretKey); - if (INTERPOLATION_SYNTAX_REG.test(referenceValue)) { + if (INTERPOLATION_TEST_REGEX.test(referenceValue)) { // eslint-disable-next-line referenceValue = await recursivelyExpandSecret({ environment, @@ -305,7 +316,7 @@ export const interpolateSecrets = ({ projectId, secretEncKey, secretDAL, folderD // eslint-disable-next-line let referenceValue = await fetchSecret(secretReferenceEnvironment, secretReferencePath, secretReferenceKey); - if (INTERPOLATION_SYNTAX_REG.test(referenceValue)) { + if (INTERPOLATION_TEST_REGEX.test(referenceValue)) { // eslint-disable-next-line referenceValue = await recursivelyExpandSecret({ environment: secretReferenceEnvironment, @@ -332,7 +343,7 @@ export const interpolateSecrets = ({ projectId, secretEncKey, secretDAL, folderD }) => { if (!inputSecret.value) return inputSecret.value; - const shouldExpand = Boolean(inputSecret.value?.match(INTERPOLATION_SYNTAX_REG)); + const shouldExpand = INTERPOLATION_TEST_REGEX.test(inputSecret.value); if (!shouldExpand) return inputSecret.value; const expandedSecretValue = await recursivelyExpandSecret(inputSecret); @@ -451,7 +462,18 @@ export const fnSecretBlindIndexCheckV2 = async ({ * // ] */ export const getAllNestedSecretReferences = (maybeSecretReference: string) => { - const references = Array.from(maybeSecretReference.matchAll(INTERPOLATION_SYNTAX_REG), (m) => m[1]); + const matches = []; + let match; + + const execRegex = new RE2(INTERPOLATION_PATTERN_STRING, "g"); + + // eslint-disable-next-line no-cond-assign + while ((match = execRegex.exec(maybeSecretReference)) !== null) { + matches.push(match); + } + + const references = matches.map((m) => m[1]); + return references .filter((el) => el.includes(".")) .map((el) => { From 608e9a644cfb82fabafb795eef3ce10d98cfeb2b Mon Sep 17 00:00:00 2001 From: carlosmonastyrski Date: Mon, 21 Apr 2025 14:52:33 -0300 Subject: [PATCH 13/23] Make entryPoint mandatory on SSOModal and check all fields on isSamlConfigured check --- .../SettingsPage/components/OrgAuthTab/OrgAuthTab.tsx | 4 +++- .../SettingsPage/components/OrgAuthTab/SSOModal.tsx | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/OrgAuthTab.tsx b/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/OrgAuthTab.tsx index cc6358e3c..40d0e7840 100644 --- a/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/OrgAuthTab.tsx +++ b/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/OrgAuthTab.tsx @@ -45,6 +45,7 @@ export const OrgAuthTab = withPermission( const { data: samlConfig, isPending: isLoadingSamlConfig } = useGetSSOConfig( currentOrg?.id ?? "" ); + const { data: ldapConfig, isPending: isLoadingLdapConfig } = useGetLDAPConfig( currentOrg?.id ?? "" ); @@ -54,7 +55,8 @@ export const OrgAuthTab = withPermission( !enabledLoginMethods || enabledLoginMethods.includes(method); const isOidcConfigured = oidcConfig && (oidcConfig.discoveryURL || oidcConfig.issuer); - const isSamlConfigured = samlConfig && samlConfig.entryPoint; + const isSamlConfigured = + samlConfig && (samlConfig.entryPoint || samlConfig.issuer || samlConfig.cert); const isLdapConfigured = ldapConfig && ldapConfig.url; const shouldShowCreateIdentityProviderView = diff --git a/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/SSOModal.tsx b/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/SSOModal.tsx index 32fa681e2..a7dff9d02 100644 --- a/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/SSOModal.tsx +++ b/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/SSOModal.tsx @@ -301,6 +301,7 @@ export const SSOModal = ({ popUp, handlePopUpClose, handlePopUpToggle, hideDelet label={renderLabels(authProvider).entryPoint} errorText={error?.message} isError={Boolean(error)} + isRequired > Date: Tue, 22 Apr 2025 02:10:56 +0800 Subject: [PATCH 14/23] misc: updated to use regex literal --- backend/src/lib/validator/validate-url.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/lib/validator/validate-url.ts b/backend/src/lib/validator/validate-url.ts index 6a8fa4941..b555869d7 100644 --- a/backend/src/lib/validator/validate-url.ts +++ b/backend/src/lib/validator/validate-url.ts @@ -100,7 +100,7 @@ export const isFQDN = (str: string, options: FQDNOptions = {}): boolean => { const partRegex = new RE2(/^[a-z_\u00a1-\uffff0-9-]+$/i); const fullWidthRegex = new RE2(/[\uff01-\uff5e]/); const hyphenRegex = new RE2(/^-|-$/); - const underscoreRegex = new RE2("_"); + const underscoreRegex = new RE2(/_/); return parts.every((part) => { if (part.length > 63 && !opts.ignore_max_length) { From 7f4d4b931b6c336ff845fe9c2c692e3c5d1db53e Mon Sep 17 00:00:00 2001 From: carlosmonastyrski Date: Mon, 21 Apr 2025 15:28:59 -0300 Subject: [PATCH 15/23] Add entryPoint zod validation --- .../SettingsPage/components/OrgAuthTab/SSOModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/SSOModal.tsx b/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/SSOModal.tsx index a7dff9d02..c38ec6889 100644 --- a/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/SSOModal.tsx +++ b/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/SSOModal.tsx @@ -63,7 +63,7 @@ const ssoAuthProviders = [ const schema = z .object({ authProvider: z.string().min(1, "SSO Type is required"), - entryPoint: z.string().default(""), + entryPoint: z.string().min(1, "Entry Point is required").default(""), issuer: z.string().default(""), cert: z.string().default("") }) From a4eb2e77c2b699fc415e2c9b70af398ef14379b9 Mon Sep 17 00:00:00 2001 From: Scott Wilson Date: Mon, 21 Apr 2025 13:49:09 -0700 Subject: [PATCH 16/23] improvement: move client instantation to try/catch for sql connection validation for error propogation --- .../app-connection/shared/sql/sql-connection-fns.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/backend/src/services/app-connection/shared/sql/sql-connection-fns.ts b/backend/src/services/app-connection/shared/sql/sql-connection-fns.ts index ed1d99941..bc98e9bcc 100644 --- a/backend/src/services/app-connection/shared/sql/sql-connection-fns.ts +++ b/backend/src/services/app-connection/shared/sql/sql-connection-fns.ts @@ -77,20 +77,22 @@ export const getSqlConnectionClient = async (appConnection: Pick { const { credentials, app } = config; - const client = await getSqlConnectionClient({ app, credentials }); + let client: Knex | undefined; try { + client = await getSqlConnectionClient({ app, credentials }); + await client.raw(`Select 1`); return credentials; } catch (error) { throw new BadRequestError({ - message: - (error as Error)?.message?.replaceAll(credentials.password, "********************") ?? - "Unable to validate connection: verify credentials" + message: `Unable to validate connection: ${ + (error as Error)?.message?.replaceAll(credentials.password, "********************") ?? "verify credentials" + }` }); } finally { - await client.destroy(); + await client?.destroy(); } }; From f7d35e61f78b56c9b23f9d9664385cf90730ec37 Mon Sep 17 00:00:00 2001 From: x Date: Mon, 21 Apr 2025 19:40:20 -0400 Subject: [PATCH 17/23] removed low entropy password regexes that threw false positives --- .../utilities/checks/password/checkPassword.ts | 2 +- .../utilities/checks/password/passwordRegexes.ts | 12 ------------ 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/frontend/src/components/utilities/checks/password/checkPassword.ts b/frontend/src/components/utilities/checks/password/checkPassword.ts index 6e8acaaba..e641421c6 100644 --- a/frontend/src/components/utilities/checks/password/checkPassword.ts +++ b/frontend/src/components/utilities/checks/password/checkPassword.ts @@ -31,7 +31,7 @@ interface CheckPasswordParams { * - Contains at least 1 number (0-9) or special character (emojis included) * - Does not contain 3 repeat, consecutive characters * - Does not contain any escape characters/sequences - * - Does not contain PII and/or low entropy data (eg. email address, URL, phone number, DoB, SSN, driver's license, passport) + * - Does not contain PII and/or low entropy data (eg. email address, URL, SSN) * - Is not in a database of breached passwords * * The function returns whether or not the password [password] diff --git a/frontend/src/components/utilities/checks/password/passwordRegexes.ts b/frontend/src/components/utilities/checks/password/passwordRegexes.ts index 7a70aa8f8..1e2367b49 100644 --- a/frontend/src/components/utilities/checks/password/passwordRegexes.ts +++ b/frontend/src/components/utilities/checks/password/passwordRegexes.ts @@ -20,18 +20,6 @@ export const lowEntropyRegexes = [ // URL (incl. subdomains, paths, top-level domains & query params) /^(?:(?:https?|ftp):\/\/)?(?:\w+\.)?[a-zA-Z0-9.-]+\.(?:com|org|net|edu)(?:\/\S*)?(?:\?\S*)?$/, - // Date in various formats - /(\b\d{1,4}[-/.]?\d{1,2}[-/.]?\d{1,4}\b)|(\b\d{1,4}[-/.]?\w{3}[-/.]?\d{1,4}\b)/, - - // Phone numbers (generalized) - /(?:\+(?:[1-9]\d{0,2})\s?)?(?:\(\d{1,4}\)\s?)?(?:\d[-.\s]?){5,}\d/, - - // Passport numbers (generalized) - /\b(?:[A-Z0-9]{6,9}|[A-Z0-9]{8,9}|[A-Z0-9]{9}|[A-Z0-9]{10,11})\b/, - - // Driver's license numbers (generalized) - /\b(?:[A-Z0-9]{7,10}|[A-Z0-9]{10,11}|[A-Z0-9]{7,10})\b/, - // US social security number /\b\d{3}[-\s]?\d{2}[-\s]?\d{4}\b/ ]; From 109971916b19f52d599f425d0fd7db864e2fc5bb Mon Sep 17 00:00:00 2001 From: Daniel Hougaard Date: Tue, 22 Apr 2025 06:07:14 +0400 Subject: [PATCH 18/23] fix: stuck on saml sso creation page --- .../SettingsPage/components/OrgAuthTab/SSOModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/SSOModal.tsx b/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/SSOModal.tsx index c38ec6889..a7dff9d02 100644 --- a/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/SSOModal.tsx +++ b/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/SSOModal.tsx @@ -63,7 +63,7 @@ const ssoAuthProviders = [ const schema = z .object({ authProvider: z.string().min(1, "SSO Type is required"), - entryPoint: z.string().min(1, "Entry Point is required").default(""), + entryPoint: z.string().default(""), issuer: z.string().default(""), cert: z.string().default("") }) From f2a984e6b66927fd09811f5c2800b9abba8c0cec Mon Sep 17 00:00:00 2001 From: Scott Wilson Date: Mon, 21 Apr 2025 19:39:13 -0700 Subject: [PATCH 19/23] fix: correct plan check for when to display enterprise plan --- .../components/MinimizedOrgSidebar/MinimizedOrgSidebar.tsx | 2 +- .../components/SidebarHeader/SidebarHeader.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/layouts/OrganizationLayout/components/MinimizedOrgSidebar/MinimizedOrgSidebar.tsx b/frontend/src/layouts/OrganizationLayout/components/MinimizedOrgSidebar/MinimizedOrgSidebar.tsx index e31018334..ba0b4f194 100644 --- a/frontend/src/layouts/OrganizationLayout/components/MinimizedOrgSidebar/MinimizedOrgSidebar.tsx +++ b/frontend/src/layouts/OrganizationLayout/components/MinimizedOrgSidebar/MinimizedOrgSidebar.tsx @@ -57,7 +57,7 @@ import { MenuIconButton } from "../MenuIconButton"; import { ServerAdminsPanel } from "../ServerAdminsPanel/ServerAdminsPanel"; const getPlan = (subscription: SubscriptionPlan) => { - if (subscription.dynamicSecret) return "Enterprise Plan"; + if (subscription.groups) return "Enterprise Plan"; if (subscription.pitRecovery) return "Pro Plan"; return "Free Plan"; }; diff --git a/frontend/src/layouts/OrganizationLayout/components/SidebarHeader/SidebarHeader.tsx b/frontend/src/layouts/OrganizationLayout/components/SidebarHeader/SidebarHeader.tsx index 8c16668f3..e5ca023aa 100644 --- a/frontend/src/layouts/OrganizationLayout/components/SidebarHeader/SidebarHeader.tsx +++ b/frontend/src/layouts/OrganizationLayout/components/SidebarHeader/SidebarHeader.tsx @@ -2,7 +2,7 @@ import { useOrganization, useSubscription } from "@app/context"; import { SubscriptionPlan } from "@app/hooks/api/types"; const getPlan = (subscription: SubscriptionPlan) => { - if (subscription.dynamicSecret) return "Enterprise Plan"; + if (subscription.groups) return "Enterprise Plan"; if (subscription.pitRecovery) return "Pro Plan"; return "Free Plan"; }; From d7af9e84befcf38c78e0a765ba813a694ff5f26c Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Mon, 21 Apr 2025 22:09:42 -0700 Subject: [PATCH 20/23] added more validation to region --- .../identity-aws-auth-service.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts b/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts index 68989893f..0849a7523 100644 --- a/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts +++ b/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts @@ -68,6 +68,18 @@ const awsRegionFromHeader = (authorizationHeader: string): string | null => { return null; }; + + +function isValidAwsRegion(region: (string | null)): boolean { + const validRegionPattern = new RE2('^[a-z0-9-]+$'); + if (typeof region !== 'string' || region.length === 0 || region.length > 20) { + return false; + } + + return validRegionPattern.test(region); +} + + export const identityAwsAuthServiceFactory = ({ identityAccessTokenDAL, identityAwsAuthDAL, @@ -85,8 +97,12 @@ export const identityAwsAuthServiceFactory = ({ const headers: TAwsGetCallerIdentityHeaders = JSON.parse(Buffer.from(iamRequestHeaders, "base64").toString()); const body: string = Buffer.from(iamRequestBody, "base64").toString(); - const region = headers.Authorization ? awsRegionFromHeader(headers.Authorization) : null; + + if (!isValidAwsRegion(region)) { + throw new BadRequestError({message: "Invalid AWS region"}); + } + const url = region ? `https://sts.${region}.amazonaws.com` : identityAwsAuth.stsEndpoint; const { From 8bfbac153c9daf5fa5361b16e1adfc536451ed84 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 22 Apr 2025 12:44:45 +0530 Subject: [PATCH 21/23] feat: nit fixing --- backend/src/lib/api-docs/constants.ts | 2 +- backend/src/server/routes/v2/service-token-router.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/lib/api-docs/constants.ts b/backend/src/lib/api-docs/constants.ts index 84ea6ff21..0f88e269c 100644 --- a/backend/src/lib/api-docs/constants.ts +++ b/backend/src/lib/api-docs/constants.ts @@ -34,7 +34,7 @@ export enum ApiDocsTags { SecretImports = "Secret Imports", SecretRotations = "Secret Rotations", IdentitySpecificPrivilegesV1 = "Identity Specific Privileges", - IdentitySpecificPrivilegesV2 = "Identity Specific Privileges V2", + IdentitySpecificPrivilegesV2 = "Identity Specific Privileges V2", AppConnections = "App Connections", SecretSyncs = "Secret Syncs", Integrations = "Integrations", diff --git a/backend/src/server/routes/v2/service-token-router.ts b/backend/src/server/routes/v2/service-token-router.ts index fcc61a386..aa6165d90 100644 --- a/backend/src/server/routes/v2/service-token-router.ts +++ b/backend/src/server/routes/v2/service-token-router.ts @@ -27,7 +27,7 @@ export const registerServiceTokenRouter = async (server: FastifyZodProvider) => onRequest: verifyAuth([AuthMode.SERVICE_TOKEN]), schema: { hide: false, - tags: [ApiDocsTags.Integrations], + tags: [ApiDocsTags.ServiceTokens], description: "Return Infisical Token data", security: [ { From 8818d5c94bd4acba2cc4ffd92e2c4825cf1c9afa Mon Sep 17 00:00:00 2001 From: = Date: Tue, 22 Apr 2025 19:32:48 +0530 Subject: [PATCH 22/23] feat: removed banner for now --- .../layouts/ProjectLayout/ProjectLayout.tsx | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx b/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx index 0e2d8bba9..e1fd2e4bf 100644 --- a/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx +++ b/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx @@ -1,10 +1,9 @@ import { useTranslation } from "react-i18next"; import { faMobile } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Link, Outlet, useNavigate, useRouterState } from "@tanstack/react-router"; +import { Link, Outlet, useRouterState } from "@tanstack/react-router"; import { motion } from "framer-motion"; -import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal"; import { BreadcrumbContainer, Menu, @@ -33,18 +32,6 @@ export const ProjectLayout = () => { const workspaceId = currentWorkspace?.id || ""; const projectSlug = currentWorkspace?.slug || ""; const { subscription } = useSubscription(); - const navigate = useNavigate(); - const hasIdentityLimitCrossed = - subscription?.identityLimit && subscription?.identitiesUsed > subscription.identityLimit + 10; - const hasUserLimitCrossed = - subscription?.memberLimit && subscription?.membersUsed > subscription.memberLimit + 10; - const shouldUpgrade = Boolean(hasUserLimitCrossed || hasIdentityLimitCrossed); - let upgradeText = ""; - if (hasUserLimitCrossed) { - upgradeText = `You've reached the maximum number of organisation users (${subscription?.memberLimit}).`; - } else if (hasIdentityLimitCrossed) { - upgradeText = `You've reached the maximum number of organisation identities (${subscription?.identityLimit}).`; - } const isSecretManager = currentWorkspace?.type === ProjectType.SecretManager; const isCertManager = currentWorkspace?.type === ProjectType.CertificateManager; @@ -280,17 +267,6 @@ export const ProjectLayout = () => {

- {shouldUpgrade && ( - { - if (!isOpen) { - navigate({ to: "/organization/access-management" }); - } - }} - /> - )}

From 5de9bf25e0cfb3a89114a91dd10f1bb36dbd982e Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Tue, 22 Apr 2025 15:37:45 -0700 Subject: [PATCH 23/23] add winget docs --- docs/cli/overview.mdx | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/docs/cli/overview.mdx b/docs/cli/overview.mdx index 89824e9f7..e0cbbe387 100644 --- a/docs/cli/overview.mdx +++ b/docs/cli/overview.mdx @@ -28,21 +28,32 @@ You can use it across various environments, whether it's local development, CI/C ``` - Use [Scoop](https://scoop.sh/) package manager - ```bash - scoop bucket add org https://github.com/Infisical/scoop-infisical.git - ``` + + Use [Scoop](https://scoop.sh/) package manager - ```bash - scoop install infisical - ``` + ```bash + scoop bucket add org https://github.com/Infisical/scoop-infisical.git + ``` - ### Updates + ```bash + scoop install infisical + ``` - ```bash - scoop update infisical - ``` + ### Updates + + ```bash + scoop update infisical + ``` + + + + Use [Winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/) package manager + + ```bash + winget install infisical + ``` +