diff --git a/backend/src/ee/routes/v1/saml-router.ts b/backend/src/ee/routes/v1/saml-router.ts index b195d32b35..933015a663 100644 --- a/backend/src/ee/routes/v1/saml-router.ts +++ b/backend/src/ee/routes/v1/saml-router.ts @@ -84,7 +84,10 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => { samlConfig.audience = `spn:${ssoConfig.issuer}`; } } - if (ssoConfig.authProvider === SamlProviders.GOOGLE_SAML) { + if ( + ssoConfig.authProvider === SamlProviders.GOOGLE_SAML || + ssoConfig.authProvider === SamlProviders.AUTH0_SAML + ) { samlConfig.wantAssertionsSigned = false; } @@ -123,7 +126,10 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => { `email: ${email} firstName: ${profile.firstName as string}` ); - throw new Error("Invalid saml request. Missing email or first name"); + throw new BadRequestError({ + message: + "Missing email or first name. Please double check your SAML attribute mapping for the selected provider." + }); } const userMetadata = Object.keys(profile.attributes || {}) diff --git a/backend/src/ee/services/license/license-service.ts b/backend/src/ee/services/license/license-service.ts index 6becaaf2bb..910cff70f5 100644 --- a/backend/src/ee/services/license/license-service.ts +++ b/backend/src/ee/services/license/license-service.ts @@ -246,8 +246,7 @@ export const licenseServiceFactory = ({ }; const getOrgPlan = async ({ orgId, actor, actorId, actorOrgId, actorAuthMethod, projectId }: TOrgPlanDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); - ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); + await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); const plan = await getPlan(orgId, projectId); return plan; }; diff --git a/backend/src/ee/services/saml-config/saml-config-types.ts b/backend/src/ee/services/saml-config/saml-config-types.ts index 96cb910357..03db4cfa1e 100644 --- a/backend/src/ee/services/saml-config/saml-config-types.ts +++ b/backend/src/ee/services/saml-config/saml-config-types.ts @@ -6,7 +6,8 @@ export enum SamlProviders { AZURE_SAML = "azure-saml", JUMPCLOUD_SAML = "jumpcloud-saml", GOOGLE_SAML = "google-saml", - KEYCLOAK_SAML = "keycloak-saml" + KEYCLOAK_SAML = "keycloak-saml", + AUTH0_SAML = "auth0-saml" } export type TCreateSamlCfgDTO = { diff --git a/backend/src/server/plugins/serve-ui.ts b/backend/src/server/plugins/serve-ui.ts index 1cda2fbd5e..6bcc59d003 100644 --- a/backend/src/server/plugins/serve-ui.ts +++ b/backend/src/server/plugins/serve-ui.ts @@ -21,6 +21,9 @@ export const registerServeUI = async ( server.route({ method: "GET", url: "/runtime-ui-env.js", + schema: { + hide: true + }, handler: (_req, res) => { const appCfg = getConfig(); void res.type("application/javascript"); @@ -43,12 +46,19 @@ export const registerServeUI = async ( wildcard: false }); - server.get("/*", (request, reply) => { - if (request.url.startsWith("/api")) { - reply.callNotFound(); - return; + server.route({ + method: "GET", + url: "/*", + schema: { + hide: true + }, + handler: (request, reply) => { + if (request.url.startsWith("/api")) { + reply.callNotFound(); + return; + } + void reply.sendFile("index.html"); } - void reply.sendFile("index.html"); }); } }; diff --git a/docs/documentation/platform/dynamic-secrets/overview.mdx b/docs/documentation/platform/dynamic-secrets/overview.mdx index 24c7fae4e1..1f17869eff 100644 --- a/docs/documentation/platform/dynamic-secrets/overview.mdx +++ b/docs/documentation/platform/dynamic-secrets/overview.mdx @@ -4,6 +4,13 @@ sidebarTitle: "Overview" description: "Learn how to generate secrets dynamically on-demand." --- + + Note that Dynamic Secrets is a paid feature. + + If you're using Infisical Cloud, then it is available under the **Enterprise Tier** + If you're self-hosting Infisical, then you should contact sales@infisical.com to purchase an enterprise license to use it. + + ## Introduction Contrary to static key-value secrets, which require manual input of data into the secure Infisical storage, **dynamic secrets are generated on-demand upon access**. diff --git a/docs/documentation/platform/pr-workflows.mdx b/docs/documentation/platform/pr-workflows.mdx index d582c838bf..187bae5d48 100644 --- a/docs/documentation/platform/pr-workflows.mdx +++ b/docs/documentation/platform/pr-workflows.mdx @@ -3,6 +3,13 @@ title: "Approval Workflows" description: "Learn how to enable a set of policies to manage changes to sensitive secrets and environments." --- + + Approval Workflows is a paid feature. + + If you're using Infisical Cloud, then it is available under the **Pro Tier** and **Enterprise Tire**. + If you're self-hosting Infisical, then you should contact sales@infisical.com to purchase an enterprise license to use it. + + ## Problem at hand Updating secrets in high-stakes environments (e.g., production) can have a number of problematic issues: @@ -40,4 +47,4 @@ When a user submits a change to an enviropnment that is under a particular polic Approvers are notified by email and/or Slack as soon as the request is initiated. In the Infisical Dashboard, they will be able to `approve` and `merge` (or `deny`) a request for a change in a particular environment. After that, depending on the workflows setup, the change will be automatically propagated to the right applications (e.g., using [Infisical Kubernetes Operator](https://infisical.com/docs/integrations/platforms/kubernetes)). -![secrets update pull request](../../images/platform/pr-workflows/secret-update-pr.png) \ No newline at end of file +![secrets update pull request](../../images/platform/pr-workflows/secret-update-pr.png) diff --git a/docs/documentation/platform/scim/azure.mdx b/docs/documentation/platform/scim/azure.mdx index 74a6c20308..0e86f61493 100644 --- a/docs/documentation/platform/scim/azure.mdx +++ b/docs/documentation/platform/scim/azure.mdx @@ -15,7 +15,7 @@ Prerequisites: - In Infisical, head to your Organization Settings > Authentication > SCIM Configuration and + In Infisical, head to your Organization Settings > Security > SCIM Configuration and press the **Enable SCIM provisioning** toggle to allow Azure to provision/deprovision users for your organization. ![SCIM enable provisioning](/images/platform/scim/scim-enable-provisioning.png) diff --git a/docs/documentation/platform/scim/jumpcloud.mdx b/docs/documentation/platform/scim/jumpcloud.mdx index ce4542035d..42d33247a2 100644 --- a/docs/documentation/platform/scim/jumpcloud.mdx +++ b/docs/documentation/platform/scim/jumpcloud.mdx @@ -15,7 +15,7 @@ Prerequisites: - In Infisical, head to your Organization Settings > Authentication > SCIM Configuration and + In Infisical, head to your Organization Settings > Security > SCIM Configuration and press the **Enable SCIM provisioning** toggle to allow JumpCloud to provision/deprovision users and user groups for your organization. ![SCIM enable provisioning](/images/platform/scim/scim-enable-provisioning.png) diff --git a/docs/documentation/platform/scim/okta.mdx b/docs/documentation/platform/scim/okta.mdx index 6b0bf6ccff..d33bd242de 100644 --- a/docs/documentation/platform/scim/okta.mdx +++ b/docs/documentation/platform/scim/okta.mdx @@ -15,7 +15,7 @@ Prerequisites: - In Infisical, head to your Organization Settings > Authentication > SCIM Configuration and + In Infisical, head to your Organization Settings > Security > SCIM Configuration and press the **Enable SCIM provisioning** toggle to allow Okta to provision/deprovision users and user groups for your organization. ![SCIM enable provisioning](/images/platform/scim/scim-enable-provisioning.png) diff --git a/docs/documentation/platform/sso/auth0-saml.mdx b/docs/documentation/platform/sso/auth0-saml.mdx new file mode 100644 index 0000000000..b77c733f71 --- /dev/null +++ b/docs/documentation/platform/sso/auth0-saml.mdx @@ -0,0 +1,93 @@ +--- +title: "Auth0 SAML" +description: "Learn how to configure Auth0 SAML for Infisical SSO." +--- + + + Auth0 SAML SSO feature is a paid feature. If you're using Infisical Cloud, + then it is available under the **Pro Tier**. If you're self-hosting Infisical, + then you should contact sales@infisical.com to purchase an enterprise license + to use it. + + + + + In Infisical, head to Organization Settings > Security and click **Connect** for SAML under the Connect to an Identity Provider section. Select Auth0, then click **Connect** again. + + Next, note the **Application Callback URL** and **Audience** to use when configuring the Auth0 SAML application. + + ![Auth0 SAML initial configuration](../../../images/sso/auth0-saml/init-config.png) + + + + 2.1. In your Auth0 account, head to Applications and create an application. + + ![Auth0 SAML app creation](../../../images/sso/auth0-saml/create-application.png) + + Select **Regular Web Application** and press **Create**. + + ![Auth0 SAML app creation](../../../images/sso/auth0-saml/create-application-2.png) + + 2.2. In the Application head to Settings > Application URIs and add the **Application Callback URL** from step 1 into the **Allowed Callback URLs** field. + + ![Auth0 SAML allowed callback URLs](../../../images/sso/auth0-saml/auth0-config.png) + + 2.3. In the Application head to Addons > SAML2 Web App and copy the **Issuer**, **Identity Provider Login URL**, and **Identity Provider Certificate** from the **Usage** tab. + + ![Auth0 SAML config](../../../images/sso/auth0-saml/auth0-config-2.png) + + 2.4. Back in Infisical, set **Issuer**, **Identity Provider Login URL**, and **Certificate** to the corresponding items from step 2.3. + + ![Auth0 SAML Infisical config](../../../images/sso/auth0-saml/infisical-config.png) + + 2.5. Back in Auth0, in the **Settings** tab, set the **Application Callback URL** to the **Application Callback URL** from step 1 + and update the **Settings** field with the JSON under the picture below (replacing `` with the **Audience** from step 1). + + ![Auth0 SAML config](../../../images/sso/auth0-saml/auth0-config-3.png) + + ```json + { + "audience": "", + "mappings": { + "email": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/email", + "given_name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/firstName", + "family_name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/lastName" + }, + "signatureAlgorithm": "rsa-sha256", + "digestAlgorithm": "sha256", + "signResponse": true + } + ``` + + Click **Save**. + + + Enabling SAML SSO allows members in your organization to log into Infisical via Auth0. + + ![Auth0 SAML enable](../../../images/sso/auth0-saml/enable-saml.png) + + + Enforcing SAML SSO ensures that members in your organization can only access Infisical + by logging into the organization via Auth0. + + To enforce SAML SSO, you're required to test out the SAML connection by successfully authenticating at least one Auth0 user with Infisical; + Once you've completed this requirement, you can toggle the **Enforce SAML SSO** button to enforce SAML SSO. + + + + + + If you are only using one organization on your Infisical instance, you can configure a default organization in the [Server Admin Console](../admin-panel/server-admin#default-organization) to expedite SAML login. + + + + If you're configuring SAML SSO on a self-hosted instance of Infisical, make + sure to set the `AUTH_SECRET` and `SITE_URL` environment variable for it to + work: +
+ - `AUTH_SECRET`: A secret key used for signing and verifying JWT. This + can be a random 32-byte base64 string generated with `openssl rand -base64 + 32`. +
+ - `SITE_URL`: The absolute URL of your self-hosted instance of Infisical including the protocol (e.g. https://app.infisical.com) + \ No newline at end of file diff --git a/docs/documentation/platform/sso/azure.mdx b/docs/documentation/platform/sso/azure.mdx index 185d5fcfb0..44935a4df1 100644 --- a/docs/documentation/platform/sso/azure.mdx +++ b/docs/documentation/platform/sso/azure.mdx @@ -12,7 +12,7 @@ description: "Learn how to configure Microsoft Entra ID for Infisical SSO." - In Infisical, head to your Organization Settings > Authentication > SAML SSO Configuration and select **Set up SAML SSO**. + In Infisical, head to Organization Settings > Security and click **Connect** for SAML under the Connect to an Identity Provider section. Select Azure / Entra, then click **Connect** again. Next, copy the **Reply URL (Assertion Consumer Service URL)** and **Identifier (Entity ID)** to use when configuring the Azure SAML application. diff --git a/docs/documentation/platform/sso/google-saml.mdx b/docs/documentation/platform/sso/google-saml.mdx index 4f31bffb1f..7e47d1137e 100644 --- a/docs/documentation/platform/sso/google-saml.mdx +++ b/docs/documentation/platform/sso/google-saml.mdx @@ -12,7 +12,7 @@ description: "Learn how to configure Google SAML for Infisical SSO." - In Infisical, head to your Organization Settings > Authentication > SAML SSO Configuration and select **Set up SAML SSO**. + In Infisical, head to Organization Settings > Security and click **Connect** for SAML under the Connect to an Identity Provider section. Select Google, then click **Connect** again. Next, note the **ACS URL** and **SP Entity ID** to use when configuring the Google SAML application. diff --git a/docs/documentation/platform/sso/jumpcloud.mdx b/docs/documentation/platform/sso/jumpcloud.mdx index ce89b8e0dd..ec876b9dad 100644 --- a/docs/documentation/platform/sso/jumpcloud.mdx +++ b/docs/documentation/platform/sso/jumpcloud.mdx @@ -12,7 +12,7 @@ description: "Learn how to configure JumpCloud SAML for Infisical SSO." - In Infisical, head to your Organization Settings > Authentication > SAML SSO Configuration and select **Set up SAML SSO**. + In Infisical, head to Organization Settings > Security and click **Connect** for SAML under the Connect to an Identity Provider section. Select JumpCloud, then click **Connect** again. Next, copy the **ACS URL** and **SP Entity ID** to use when configuring the JumpCloud SAML application. diff --git a/docs/documentation/platform/sso/keycloak-saml.mdx b/docs/documentation/platform/sso/keycloak-saml.mdx index 53f47f1ae0..86352bb9dc 100644 --- a/docs/documentation/platform/sso/keycloak-saml.mdx +++ b/docs/documentation/platform/sso/keycloak-saml.mdx @@ -12,7 +12,7 @@ description: "Learn how to configure Keycloak SAML for Infisical SSO." - In Infisical, head to your Organization Settings > Authentication > SAML SSO Configuration and select **Manage**. + In Infisical, head to Organization Settings > Security and click **Connect** for SAML under the Connect to an Identity Provider section. Select Keycloak, then click **Connect** again. ![Keycloak SAML organization security section](../../../images/sso/keycloak/org-security-section.png) diff --git a/docs/documentation/platform/sso/okta.mdx b/docs/documentation/platform/sso/okta.mdx index 9a1d4aa2f6..9f28f4c4e5 100644 --- a/docs/documentation/platform/sso/okta.mdx +++ b/docs/documentation/platform/sso/okta.mdx @@ -12,7 +12,7 @@ description: "Learn how to configure Okta SAML 2.0 for Infisical SSO." - In Infisical, head to your Organization Settings > Authentication > SAML SSO Configuration and select **Set up SAML SSO**. + In Infisical, head to Organization Settings > Security and click **Connect** for SAML under the Connect to an Identity Provider section. Select Okta, then click **Connect** again. Next, copy the **Single sign-on URL** and **Audience URI (SP Entity ID)** to use when configuring the Okta SAML 2.0 application. ![Okta SAML initial configuration](../../../images/sso/okta/init-config.png) diff --git a/docs/documentation/platform/sso/overview.mdx b/docs/documentation/platform/sso/overview.mdx index 227a7502f3..0d4b8da899 100644 --- a/docs/documentation/platform/sso/overview.mdx +++ b/docs/documentation/platform/sso/overview.mdx @@ -28,6 +28,7 @@ Infisical supports these and many other identity providers: - [JumpCloud SAML](/documentation/platform/sso/jumpcloud) - [Keycloak SAML](/documentation/platform/sso/keycloak-saml) - [Google SAML](/documentation/platform/sso/google-saml) +- [Auth0 SAML](/documentation/platform/sso/auth0-saml) - [Keycloak OIDC](/documentation/platform/sso/keycloak-oidc) - [Auth0 OIDC](/documentation/platform/sso/auth0-oidc) - [General OIDC](/documentation/platform/sso/general-oidc) diff --git a/docs/images/sso/auth0-saml/auth0-config-2.png b/docs/images/sso/auth0-saml/auth0-config-2.png new file mode 100644 index 0000000000..1fbc683636 Binary files /dev/null and b/docs/images/sso/auth0-saml/auth0-config-2.png differ diff --git a/docs/images/sso/auth0-saml/auth0-config-3.png b/docs/images/sso/auth0-saml/auth0-config-3.png new file mode 100644 index 0000000000..f4287e51a5 Binary files /dev/null and b/docs/images/sso/auth0-saml/auth0-config-3.png differ diff --git a/docs/images/sso/auth0-saml/auth0-config.png b/docs/images/sso/auth0-saml/auth0-config.png new file mode 100644 index 0000000000..6fca6247db Binary files /dev/null and b/docs/images/sso/auth0-saml/auth0-config.png differ diff --git a/docs/images/sso/auth0-saml/create-application-2.png b/docs/images/sso/auth0-saml/create-application-2.png new file mode 100644 index 0000000000..71990fbef1 Binary files /dev/null and b/docs/images/sso/auth0-saml/create-application-2.png differ diff --git a/docs/images/sso/auth0-saml/create-application.png b/docs/images/sso/auth0-saml/create-application.png new file mode 100644 index 0000000000..c113d2dda0 Binary files /dev/null and b/docs/images/sso/auth0-saml/create-application.png differ diff --git a/docs/images/sso/auth0-saml/enable-saml.png b/docs/images/sso/auth0-saml/enable-saml.png new file mode 100644 index 0000000000..bb084ebac0 Binary files /dev/null and b/docs/images/sso/auth0-saml/enable-saml.png differ diff --git a/docs/images/sso/auth0-saml/infisical-config.png b/docs/images/sso/auth0-saml/infisical-config.png new file mode 100644 index 0000000000..07a7cdc74a Binary files /dev/null and b/docs/images/sso/auth0-saml/infisical-config.png differ diff --git a/docs/images/sso/auth0-saml/init-config.png b/docs/images/sso/auth0-saml/init-config.png new file mode 100644 index 0000000000..5ab5a01e53 Binary files /dev/null and b/docs/images/sso/auth0-saml/init-config.png differ diff --git a/docs/mint.json b/docs/mint.json index 69ad84f111..5d06a10f97 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -248,6 +248,7 @@ "documentation/platform/sso/jumpcloud", "documentation/platform/sso/keycloak-saml", "documentation/platform/sso/google-saml", + "documentation/platform/sso/auth0-saml", "documentation/platform/sso/keycloak-oidc", "documentation/platform/sso/auth0-oidc", "documentation/platform/sso/general-oidc" diff --git a/frontend/src/const/routes.ts b/frontend/src/const/routes.ts index 221917b94a..a7b6d13756 100644 --- a/frontend/src/const/routes.ts +++ b/frontend/src/const/routes.ts @@ -101,6 +101,10 @@ export const ROUTE_PATHS = Object.freeze({ "/secret-manager/$projectId/integrations/azure-devops/create", "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-devops/create" ), + AzureKeyVaultAuthorizePage: setRoute( + "/secret-manager/$projectId/integrations/azure-key-vault/authorize", + "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize" + ), AzureKeyVaultOauthCallbackPage: setRoute( "/secret-manager/$projectId/integrations/azure-key-vault/oauth2/callback", "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback" diff --git a/frontend/src/pages/organization/AccessManagementPage/components/OrgGroupsTab/components/OrgGroupsSection/OrgGroupsSection.tsx b/frontend/src/pages/organization/AccessManagementPage/components/OrgGroupsTab/components/OrgGroupsSection/OrgGroupsSection.tsx index ec3ef159c7..4bdb62d602 100644 --- a/frontend/src/pages/organization/AccessManagementPage/components/OrgGroupsTab/components/OrgGroupsSection/OrgGroupsSection.tsx +++ b/frontend/src/pages/organization/AccessManagementPage/components/OrgGroupsTab/components/OrgGroupsSection/OrgGroupsSection.tsx @@ -27,7 +27,7 @@ export const OrgGroupsSection = () => { if (!subscription?.groups) { handlePopUpOpen("upgradePlan", { description: - "You can manage users more efficiently with groups if you upgrade your Infisical plan." + "You can manage users more efficiently with groups if you upgrade your Infisical plan to an Enterprise license." }); } else { handlePopUpOpen("group"); diff --git a/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/SSOModal.tsx b/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/SSOModal.tsx index eab111c154..9bb793c804 100644 --- a/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/SSOModal.tsx +++ b/frontend/src/pages/organization/SettingsPage/components/OrgAuthTab/SSOModal.tsx @@ -25,7 +25,8 @@ enum AuthProvider { AZURE_SAML = "azure-saml", JUMPCLOUD_SAML = "jumpcloud-saml", KEYCLOAK_SAML = "keycloak-saml", - GOOGLE_SAML = "google-saml" + GOOGLE_SAML = "google-saml", + AUTH0_SAML = "auth0-saml" } const ssoAuthProviders = [ @@ -33,7 +34,8 @@ const ssoAuthProviders = [ { label: "Azure / Entra SAML", value: AuthProvider.AZURE_SAML }, { label: "JumpCloud SAML", value: AuthProvider.JUMPCLOUD_SAML }, { label: "Keycloak SAML", value: AuthProvider.KEYCLOAK_SAML }, - { label: "Google SAML", value: AuthProvider.GOOGLE_SAML } + { label: "Google SAML", value: AuthProvider.GOOGLE_SAML }, + { label: "Auth0 SAML", value: AuthProvider.AUTH0_SAML } ]; const schema = z @@ -191,6 +193,15 @@ export const SSOModal = ({ popUp, handlePopUpClose, handlePopUpToggle, hideDelet issuer: "Issuer", issuerPlaceholder: window.origin }; + case AuthProvider.AUTH0_SAML: + return { + acsUrl: "Application Callback URL", + entityId: "Audience", + entryPoint: "Identity Provider Login URL", + entryPointPlaceholder: "https://xxx.auth0.com/samlp/xxx", + issuer: "Issuer", + issuerPlaceholder: "urn:xxx-xxx.us.auth0.com" + }; default: return { acsUrl: "ACS URL", diff --git a/frontend/src/pages/project/AccessControlPage/components/GroupsTab/components/GroupsSection/GroupsSection.tsx b/frontend/src/pages/project/AccessControlPage/components/GroupsTab/components/GroupsSection/GroupsSection.tsx index 8ae2727253..8c5d18b752 100644 --- a/frontend/src/pages/project/AccessControlPage/components/GroupsTab/components/GroupsSection/GroupsSection.tsx +++ b/frontend/src/pages/project/AccessControlPage/components/GroupsTab/components/GroupsSection/GroupsSection.tsx @@ -33,7 +33,7 @@ export const GroupsSection = () => { if (!subscription?.groups) { handlePopUpOpen("upgradePlan", { description: - "You can manage users more efficiently with groups if you upgrade your Infisical plan." + "You can manage users more efficiently with groups if you upgrade your Infisical plan to an Enterprise license." }); } else { handlePopUpOpen("group"); diff --git a/frontend/src/pages/secret-manager/IntegrationsListPage/IntegrationsListPage.utils.tsx b/frontend/src/pages/secret-manager/IntegrationsListPage/IntegrationsListPage.utils.tsx index 439ada69d7..040274b16a 100644 --- a/frontend/src/pages/secret-manager/IntegrationsListPage/IntegrationsListPage.utils.tsx +++ b/frontend/src/pages/secret-manager/IntegrationsListPage/IntegrationsListPage.utils.tsx @@ -80,8 +80,16 @@ export const redirectForProviderAuth = ( createIntegrationMissingEnvVarsNotification(integrationOption.slug); return; } - const link = `https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=${integrationOption.clientId}&response_type=code&redirect_uri=${window.location.origin}/integrations/azure-key-vault/oauth2/callback&response_mode=query&scope=https://vault.azure.net/.default openid offline_access&state=${state}`; - window.location.assign(link); + navigate({ + to: "/secret-manager/$projectId/integrations/azure-key-vault/authorize", + params: { + projectId + }, + search: { + clientId: integrationOption.clientId, + state, + } + }); break; } case "azure-app-configuration": { diff --git a/frontend/src/pages/secret-manager/integrations/AwsSecretManagerConfigurePage/AwsSecretManagerConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/AwsSecretManagerConfigurePage/AwsSecretManagerConfigurePage.tsx index 870aa2b69b..a64d84f17d 100644 --- a/frontend/src/pages/secret-manager/integrations/AwsSecretManagerConfigurePage/AwsSecretManagerConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/AwsSecretManagerConfigurePage/AwsSecretManagerConfigurePage.tsx @@ -296,7 +296,7 @@ export const AwsSecretManagerConfigurePage = () => { errorText={error?.message} isError={Boolean(error)} > - + )} /> diff --git a/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationConfigurePage/AzureAppConfigurationConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationConfigurePage/AzureAppConfigurationConfigurePage.tsx index a5c4538f3e..792ed9010d 100644 --- a/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationConfigurePage/AzureAppConfigurationConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationConfigurePage/AzureAppConfigurationConfigurePage.tsx @@ -76,6 +76,7 @@ export const AzureAppConfigurationConfigurePage = () => { } }); + const selectedEnvironment = watch("sourceEnvironment"); const { mutateAsync } = useCreateIntegration(); const integrationAuthId = useSearch({ @@ -248,7 +249,7 @@ export const AzureAppConfigurationConfigurePage = () => { name="secretPath" render={({ field, fieldState: { error } }) => ( - + )} /> diff --git a/frontend/src/pages/secret-manager/integrations/AzureKeyVaultAuthorizePage/AzureKeyVaultAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/AzureKeyVaultAuthorizePage/AzureKeyVaultAuthorizePage.tsx new file mode 100644 index 0000000000..419aa30bfb --- /dev/null +++ b/frontend/src/pages/secret-manager/integrations/AzureKeyVaultAuthorizePage/AzureKeyVaultAuthorizePage.tsx @@ -0,0 +1,97 @@ +import { Controller, useForm } from "react-hook-form"; + +import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { zodResolver } from "@hookform/resolvers/zod"; +import z from "zod"; + +import { Button, Card, CardTitle, FormControl, Input } from "@app/components/v2"; +import { Helmet } from "react-helmet"; +import { useSearch } from "@tanstack/react-router"; +import { ROUTE_PATHS } from "@app/const/routes"; + +const schema = z.object({ + tenantId: z.string().trim().optional() +}); + +type FormData = z.infer; + +export function AzureKeyVaultAuthorizePage() { + const { state, clientId } = useSearch({ + from: ROUTE_PATHS.SecretManager.Integratons.AzureKeyVaultAuthorizePage.id, + }); + + const { control, handleSubmit } = useForm({ + resolver: zodResolver(schema) + }); + + const onFormSubmit = async ({ tenantId }: FormData) => { + const link = `https://login.microsoftonline.com/${ + tenantId ?? "common" + }/oauth2/v2.0/authorize?client_id=${clientId}&response_type=code&redirect_uri=${ + window.location.origin + }/integrations/azure-key-vault/oauth2/callback&response_mode=query&scope=https://vault.azure.net/.default openid offline_access&state=${state}`; + + window.location.assign(link); + }; + + return ( +
+ + Authorize Azure Key Vault Integration + + + + +
+
+ Github logo +
+ Azure Key Vault Integration + +
+ + Docs + +
+
+
+
+
+ ( + + + + )} + /> + + +
+
+ ); +} diff --git a/frontend/src/pages/secret-manager/integrations/AzureKeyVaultAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/AzureKeyVaultAuthorizePage/route.tsx new file mode 100644 index 0000000000..cb8c477644 --- /dev/null +++ b/frontend/src/pages/secret-manager/integrations/AzureKeyVaultAuthorizePage/route.tsx @@ -0,0 +1,17 @@ +import { createFileRoute } from "@tanstack/react-router"; +import z from 'zod' + +import { AzureKeyVaultAuthorizePage } from "./AzureKeyVaultAuthorizePage"; + + +const PageQueryParamsSchema = z.object({ + state: z.string(), + clientId: z.string().optional(), +}); + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize" +)({ + component: AzureKeyVaultAuthorizePage, + validateSearch: PageQueryParamsSchema +}); diff --git a/frontend/src/pages/secret-manager/integrations/CircleCIConfigurePage/CircleCIConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/CircleCIConfigurePage/CircleCIConfigurePage.tsx index 23737dc2c7..36a3b99643 100644 --- a/frontend/src/pages/secret-manager/integrations/CircleCIConfigurePage/CircleCIConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/CircleCIConfigurePage/CircleCIConfigurePage.tsx @@ -62,6 +62,7 @@ export const CircleCIConfigurePage = () => { const selectedScope = watch("scope"); const selectedOrg = watch("targetOrg"); + const selectedEnvironment = watch("sourceEnvironment"); const { data: circleCIOrganizations, isPending: isCircleCIOrganizationsLoading } = useGetIntegrationAuthCircleCIOrganizations(integrationAuthId); @@ -186,7 +187,7 @@ export const CircleCIConfigurePage = () => { name="secretPath" render={({ field, fieldState: { error } }) => ( - + )} /> diff --git a/frontend/src/pages/secret-manager/integrations/GitlabAuthorizePage/GitlabAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/GitlabAuthorizePage/GitlabAuthorizePage.tsx index d6a387e149..2ce82d97cb 100644 --- a/frontend/src/pages/secret-manager/integrations/GitlabAuthorizePage/GitlabAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/GitlabAuthorizePage/GitlabAuthorizePage.tsx @@ -72,7 +72,7 @@ export const GitlabAuthorizePage = () => { >
- Gitlab logo + Gitlab logo
GitLab Integration { >
- Gitlab logo + Gitlab logo
GitLab Integration
+ AuthenticateInjectOrgDetailsSecretManagerProjectIdSecretManagerLayoutIntegrationsRoute, + } as any) + const secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute = secretManagerIntegrationsAzureDevopsConfigurePageRouteImport.update({ id: '/azure-devops/create', @@ -2251,6 +2260,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteImport parentRoute: typeof AuthenticateInjectOrgDetailsSecretManagerProjectIdSecretManagerLayoutIntegrationsImport } + '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize': { + id: '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize' + path: '/azure-key-vault/authorize' + fullPath: '/secret-manager/$projectId/integrations/azure-key-vault/authorize' + preLoaderRoute: typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsSecretManagerProjectIdSecretManagerLayoutIntegrationsImport + } '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/create': { id: '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/create' path: '/azure-key-vault/create' @@ -2944,6 +2960,7 @@ interface AuthenticateInjectOrgDetailsSecretManagerProjectIdSecretManagerLayoutI secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute: typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute: typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute: typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute + secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute: typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute: typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute secretManagerIntegrationsBitbucketConfigurePageRouteRoute: typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute secretManagerIntegrationsChecklyAuthorizePageRouteRoute: typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute @@ -3034,6 +3051,8 @@ const AuthenticateInjectOrgDetailsSecretManagerProjectIdSecretManagerLayoutInteg secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute, secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute: secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute, + secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute: + secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute, secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute: secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute, secretManagerIntegrationsBitbucketConfigurePageRouteRoute: @@ -3513,6 +3532,7 @@ export interface FileRoutesByFullPath { '/secret-manager/$projectId/integrations/azure-app-configuration/create': typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute '/secret-manager/$projectId/integrations/azure-devops/authorize': typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute '/secret-manager/$projectId/integrations/azure-devops/create': typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute + '/secret-manager/$projectId/integrations/azure-key-vault/authorize': typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute '/secret-manager/$projectId/integrations/azure-key-vault/create': typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute '/secret-manager/$projectId/integrations/bitbucket/create': typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute '/secret-manager/$projectId/integrations/checkly/authorize': typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute @@ -3676,6 +3696,7 @@ export interface FileRoutesByTo { '/secret-manager/$projectId/integrations/azure-app-configuration/create': typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute '/secret-manager/$projectId/integrations/azure-devops/authorize': typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute '/secret-manager/$projectId/integrations/azure-devops/create': typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute + '/secret-manager/$projectId/integrations/azure-key-vault/authorize': typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute '/secret-manager/$projectId/integrations/azure-key-vault/create': typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute '/secret-manager/$projectId/integrations/bitbucket/create': typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute '/secret-manager/$projectId/integrations/checkly/authorize': typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute @@ -3854,6 +3875,7 @@ export interface FileRoutesById { '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create': typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-devops/authorize': typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-devops/create': typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute + '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize': typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/create': typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/bitbucket/create': typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/checkly/authorize': typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute @@ -4024,6 +4046,7 @@ export interface FileRouteTypes { | '/secret-manager/$projectId/integrations/azure-app-configuration/create' | '/secret-manager/$projectId/integrations/azure-devops/authorize' | '/secret-manager/$projectId/integrations/azure-devops/create' + | '/secret-manager/$projectId/integrations/azure-key-vault/authorize' | '/secret-manager/$projectId/integrations/azure-key-vault/create' | '/secret-manager/$projectId/integrations/bitbucket/create' | '/secret-manager/$projectId/integrations/checkly/authorize' @@ -4186,6 +4209,7 @@ export interface FileRouteTypes { | '/secret-manager/$projectId/integrations/azure-app-configuration/create' | '/secret-manager/$projectId/integrations/azure-devops/authorize' | '/secret-manager/$projectId/integrations/azure-devops/create' + | '/secret-manager/$projectId/integrations/azure-key-vault/authorize' | '/secret-manager/$projectId/integrations/azure-key-vault/create' | '/secret-manager/$projectId/integrations/bitbucket/create' | '/secret-manager/$projectId/integrations/checkly/authorize' @@ -4362,6 +4386,7 @@ export interface FileRouteTypes { | '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create' | '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-devops/authorize' | '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-devops/create' + | '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize' | '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/create' | '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/bitbucket/create' | '/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/checkly/authorize' @@ -4925,6 +4950,7 @@ export const routeTree = rootRoute "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create", "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-devops/authorize", "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-devops/create", + "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize", "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/create", "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/bitbucket/create", "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/checkly/authorize", @@ -5105,6 +5131,10 @@ export const routeTree = rootRoute "filePath": "secret-manager/integrations/AzureDevopsConfigurePage/route.tsx", "parent": "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations" }, + "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize": { + "filePath": "secret-manager/integrations/AzureKeyVaultAuthorizePage/route.tsx", + "parent": "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations" + }, "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/create": { "filePath": "secret-manager/integrations/AzureKeyVaultConfigurePage/route.tsx", "parent": "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations" diff --git a/frontend/src/routes.ts b/frontend/src/routes.ts index 2dff3cc78c..d8913ec66d 100644 --- a/frontend/src/routes.ts +++ b/frontend/src/routes.ts @@ -75,6 +75,10 @@ const secretManagerRoutes = route("/secret-manager/$projectId", [ "/azure-devops/create", "secret-manager/integrations/AzureDevopsConfigurePage/route.tsx" ), + route( + "/azure-key-vault/authorize", + "secret-manager/integrations/AzureKeyVaultAuthorizePage/route.tsx" + ), route( "/azure-key-vault/oauth2/callback", "secret-manager/integrations/AzureKeyVaultOauthCallbackPage/route.tsx"