Revise SAML flow, update Okta SAML docs
@@ -57,7 +57,6 @@ export const updateSSOConfig = async (req: Request, res: Response) => {
|
||||
entryPoint,
|
||||
issuer,
|
||||
cert,
|
||||
audience
|
||||
} = req.body;
|
||||
|
||||
const plan = await EELicenseService.getPlan(organizationId);
|
||||
@@ -78,9 +77,6 @@ export const updateSSOConfig = async (req: Request, res: Response) => {
|
||||
encryptedCert?: string;
|
||||
certIV?: string;
|
||||
certTag?: string;
|
||||
encryptedAudience?: string;
|
||||
audienceIV?: string;
|
||||
audienceTag?: string;
|
||||
}
|
||||
|
||||
const update: PatchUpdate = {};
|
||||
@@ -132,18 +128,6 @@ export const updateSSOConfig = async (req: Request, res: Response) => {
|
||||
update.certIV = certIV;
|
||||
update.certTag = certTag;
|
||||
}
|
||||
|
||||
if (audience) {
|
||||
const {
|
||||
ciphertext: encryptedAudience,
|
||||
iv: audienceIV,
|
||||
tag: audienceTag
|
||||
} = client.encryptSymmetric(audience, key);
|
||||
|
||||
update.encryptedAudience = encryptedAudience;
|
||||
update.audienceIV = audienceIV;
|
||||
update.audienceTag = audienceTag;
|
||||
}
|
||||
|
||||
const ssoConfig = await SSOConfig.findOneAndUpdate(
|
||||
{
|
||||
@@ -207,8 +191,7 @@ export const createSSOConfig = async (req: Request, res: Response) => {
|
||||
isActive,
|
||||
entryPoint,
|
||||
issuer,
|
||||
cert,
|
||||
audience
|
||||
cert
|
||||
} = req.body;
|
||||
|
||||
const plan = await EELicenseService.getPlan(organizationId);
|
||||
@@ -238,12 +221,6 @@ export const createSSOConfig = async (req: Request, res: Response) => {
|
||||
iv: certIV,
|
||||
tag: certTag
|
||||
} = client.encryptSymmetric(cert, key);
|
||||
|
||||
const {
|
||||
ciphertext: encryptedAudience,
|
||||
iv: audienceIV,
|
||||
tag: audienceTag
|
||||
} = client.encryptSymmetric(audience, key);
|
||||
|
||||
const ssoConfig = await new SSOConfig({
|
||||
organization: new Types.ObjectId(organizationId),
|
||||
@@ -257,10 +234,7 @@ export const createSSOConfig = async (req: Request, res: Response) => {
|
||||
issuerTag,
|
||||
encryptedCert,
|
||||
certIV,
|
||||
certTag,
|
||||
encryptedAudience,
|
||||
audienceIV,
|
||||
audienceTag
|
||||
certTag
|
||||
}).save();
|
||||
|
||||
return res.status(200).send(ssoConfig);
|
||||
|
||||
@@ -51,13 +51,6 @@ export const getSSOConfigHelper = async ({
|
||||
ssoConfig.certIV,
|
||||
ssoConfig.certTag
|
||||
);
|
||||
|
||||
const audience = client.decryptSymmetric(
|
||||
ssoConfig.encryptedAudience,
|
||||
key,
|
||||
ssoConfig.audienceIV,
|
||||
ssoConfig.audienceTag
|
||||
);
|
||||
|
||||
return ({
|
||||
_id: ssoConfig._id,
|
||||
@@ -66,7 +59,6 @@ export const getSSOConfigHelper = async ({
|
||||
isActive: ssoConfig.isActive,
|
||||
entryPoint,
|
||||
issuer,
|
||||
cert,
|
||||
audience
|
||||
cert
|
||||
});
|
||||
}
|
||||
@@ -1,8 +1,12 @@
|
||||
import { Schema, Types, model } from "mongoose";
|
||||
|
||||
export enum AuthProvider {
|
||||
OKTA_SAML = "okta-saml"
|
||||
}
|
||||
|
||||
export interface ISSOConfig {
|
||||
organization: Types.ObjectId;
|
||||
authProvider: "okta-saml"
|
||||
authProvider: AuthProvider;
|
||||
isActive: boolean;
|
||||
encryptedEntryPoint: string;
|
||||
entryPointIV: string;
|
||||
@@ -13,9 +17,6 @@ export interface ISSOConfig {
|
||||
encryptedCert: string;
|
||||
certIV: string;
|
||||
certTag: string;
|
||||
encryptedAudience: string;
|
||||
audienceIV: string;
|
||||
audienceTag: string;
|
||||
}
|
||||
|
||||
const ssoConfigSchema = new Schema<ISSOConfig>(
|
||||
@@ -26,9 +27,7 @@ const ssoConfigSchema = new Schema<ISSOConfig>(
|
||||
},
|
||||
authProvider: {
|
||||
type: String,
|
||||
enum: [
|
||||
"okta-saml"
|
||||
],
|
||||
enum: AuthProvider,
|
||||
required: true
|
||||
},
|
||||
isActive: {
|
||||
@@ -61,15 +60,6 @@ const ssoConfigSchema = new Schema<ISSOConfig>(
|
||||
},
|
||||
certTag: {
|
||||
type: String
|
||||
},
|
||||
encryptedAudience: {
|
||||
type: String
|
||||
},
|
||||
audienceIV: {
|
||||
type: String
|
||||
},
|
||||
audienceTag: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import express from "express";
|
||||
const router = express.Router();
|
||||
import passport from "passport";
|
||||
import {
|
||||
AuthProvider
|
||||
} from "../../models";
|
||||
import {
|
||||
requireAuth,
|
||||
requireOrganizationAuth,
|
||||
@@ -87,12 +90,11 @@ router.post(
|
||||
locationOrganizationId: "body"
|
||||
}),
|
||||
body("organizationId").exists().trim(),
|
||||
body("authProvider").exists().isString(),
|
||||
body("authProvider").exists().isString().isIn([AuthProvider.OKTA_SAML]),
|
||||
body("isActive").exists().isBoolean(),
|
||||
body("entryPoint").exists().isString(),
|
||||
body("issuer").exists().isString(),
|
||||
body("cert").exists().isString(),
|
||||
body("audience").exists().isString(),
|
||||
validateRequest,
|
||||
ssoController.createSSOConfig
|
||||
);
|
||||
@@ -113,7 +115,6 @@ router.patch(
|
||||
body("entryPoint").optional().isString(),
|
||||
body("issuer").optional().isString(),
|
||||
body("cert").optional().isString(),
|
||||
body("audience").optional().isString(),
|
||||
validateRequest,
|
||||
ssoController.updateSSOConfig
|
||||
);
|
||||
|
||||
@@ -66,7 +66,7 @@ class EELicenseService {
|
||||
customRateLimits: true,
|
||||
customAlerts: true,
|
||||
auditLogs: false,
|
||||
samlSSO: false,
|
||||
samlSSO: true,
|
||||
status: null,
|
||||
trial_end: null,
|
||||
has_used_trial: true
|
||||
|
||||
@@ -147,7 +147,7 @@ const initializePassport = async () => {
|
||||
entryPoint: ssoConfig.entryPoint,
|
||||
issuer: ssoConfig.issuer,
|
||||
cert: ssoConfig.cert,
|
||||
audience: ssoConfig.audience
|
||||
audience: await getSiteURL()
|
||||
});
|
||||
|
||||
req.ssoConfig = ssoConfig;
|
||||
|
||||
@@ -3,7 +3,10 @@ title: "Azure SAML"
|
||||
description: "Configure Azure SAML for Infisical SSO"
|
||||
---
|
||||
|
||||
1. In the Azure Portal, navigate to the Azure Active Directory and select Enterprise applications. On this screen, select
|
||||
1. In Infisical, head over to your organization Settings > Authentication > SAML SSO Configuration and select **Set up SAML SSO**.
|
||||
Next, copy the **ACS URL** and **Entity ID** to use when configuring the Okta SAML 2.0 application.
|
||||
|
||||
2. In the Azure Portal, navigate to the Azure Active Directory and select Enterprise applications. On this screen, select
|
||||
the **+ New application** button.
|
||||
|
||||
TODO: insert image.
|
||||
|
||||
@@ -1,72 +1,77 @@
|
||||
---
|
||||
title: "Okta SAML"
|
||||
description: "Configure Okta SAML for Infisical SSO"
|
||||
description: "Configure Okta SAML 2.0 for Infisical SSO"
|
||||
---
|
||||
|
||||
1. In the Okta Admin Portal, select Applications > Applications from the
|
||||
navigation. On the Applications screen, select the Create App Integration
|
||||
Prerequisites:
|
||||
- Okta Developer Account with access to create custom application integrations.
|
||||
|
||||
|
||||
1. In Infisical, head over to your organization Settings > Authentication > SAML SSO Configuration and select **Set up SAML SSO**.
|
||||
Next, copy the **ACS URL** and **Entity ID** to use when configuring the Okta SAML 2.0 application.
|
||||
|
||||

|
||||
|
||||
2. In the Okta Admin Portal, select Applications > Applications from the
|
||||
navigation. On the Applications screen, select the **Create App Integration**
|
||||
button.
|
||||
|
||||

|
||||
|
||||
2. In the Create a New Application Integration dialog, select the SAML 2.0 radio button:
|
||||
3. In the Create a New Application Integration dialog, select the **SAML 2.0** radio button:
|
||||
|
||||

|
||||
|
||||
3. On the General Settings screen, give the application a unique, Infisical-specific name and select Next.
|
||||
4. On the General Settings screen, give the application a unique name like Infisical and select **Next**.
|
||||
|
||||
4. On the Configure SAML screen, configure the following fields:
|
||||

|
||||
|
||||
- Single sign on URL: `https://app.infisical.com/api/v1/sso/saml2/:identifier`; we'll update the `:identifier` part later in step 6.
|
||||
- Audience URI (SP Entity ID): `https://app.infisical.com`
|
||||
5. On the Configure SAML screen, set the **Single sign-on URL** to **ACS URL** and **Audience URI (SP Entity ID)** to
|
||||
**Entity ID** from step 1.
|
||||
|
||||

|
||||

|
||||
|
||||
<Note>
|
||||
If you're self-hosting Infisical, then you will want to replace
|
||||
`https://app.infisical.com` with your own domain.
|
||||
</Note>
|
||||
|
||||
4. Also on the Configure SAML screen, configure the Attribute Statements to map:
|
||||
6. Also on the Configure SAML screen, configure the **Attribute Statements** to map:
|
||||
|
||||
- `id -> user.id`,
|
||||
- `email -> user.email`,
|
||||
- `firstName -> user.firstName`
|
||||
- `lastName -> user.lastName`
|
||||
|
||||

|
||||

|
||||
|
||||
Once configured, select the Next button to proceed to the Feedback screen and select Finish.
|
||||
Once configured, select the **Next** button to proceed to the Feedback screen and select **Finish**.
|
||||
|
||||
5. Get IdP values
|
||||
7. Get IdP values
|
||||
|
||||
Once your application is created, select the Sign On tab for the app and select the View Setup Instructions button located on the right side of the screen:
|
||||
Once your application is created, select the **Sign On** tab for the app and select the **View Setup Instructions** button located on the right side of the screen:
|
||||
|
||||
Copy the Identity Provider Single Sign-On URL, the Identity Provider Issuer, and the X.509 Certificate to be pasted into your Infisical SAML SSO configuration details with the following map:
|
||||

|
||||
|
||||
- `Audience -> Audience URI (SP Entity ID) from Okta`
|
||||
- `Entrypoint -> Identity Provider Single Sign-On URL from Okta`
|
||||
- `Issuer -> Identity Provider Issuer from Okta`
|
||||
- `Certificate -> X.509 Certificate from Okta`
|
||||
Copy the **Identity Provider Single Sign-On URL**, the **Identity Provider Issuer**, and the **X.509 Certificate** to use when finishing configuring the Okta SAML in Infisical.
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||
Back in Infisical, set **Entrypoint** to **Identity Provider Single Sign-On URL**, **Issuer** to **Identity Provider Issuer**,
|
||||
and **Certificate** to **X.509 Certificate** from above. Once you've done that, press **Add** to complete the required configuration.
|
||||
|
||||
6. Create the SSO configuration and copy your SSO identifier in Infisical; update `:identifier` from step 4 earlier to be this value.
|
||||

|
||||
|
||||

|
||||
|
||||
7. Assignments
|
||||
|
||||
Finally, navigate to the Assignments tab and select the Assign button:
|
||||
8. Finally, navigate to the **Assignments** tab and select **Assign**
|
||||
|
||||
You can assign access to the application on a user-by-user basis using the Assign to People option, or in-bulk using the Assign to Groups option.
|
||||
|
||||

|
||||

|
||||
|
||||
At this point, you have configured everything you need within the context of the Okta Admin Portal.
|
||||
|
||||
8. Return to Infisical and enable SAML SSO.
|
||||
9. Return to Infisical and enable SAML SSO.
|
||||
|
||||
Enabling SAML SSO enforces all members in your organization to only be able to log into Infisical via Okta.
|
||||
|
||||

|
||||
@@ -13,11 +13,4 @@ description: "Log in to Infisical via SSO protocols"
|
||||
You can configure your organization in Infisical to have members authenticate with the platform via protocols like [SAML 2.0](https://en.wikipedia.org/wiki/SAML_2.0).
|
||||
|
||||
To note, configuring SSO retains the end-to-end encrypted architecture of Infisical because we decouple the **authentication** and **decryption** steps. In all login with SSO implementations,
|
||||
your IdP cannot and will not have access to the decryption key needed to decrypt your secrets.
|
||||
|
||||
## Configuration
|
||||
|
||||
Head over to your organization Settings > Authentication > SAML SSO Configuration.
|
||||
|
||||
Next, press "Set up SAML SSO" in the SAML SSO and follow the instructions
|
||||
below to configure SSO for your identity provider.
|
||||
your IdP cannot and will not have access to the decryption key needed to decrypt your secrets.
|
||||
BIN
docs/images/sso-okta-0.png
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
docs/images/sso-okta-10.png
Normal file
|
After Width: | Height: | Size: 563 KiB |
|
Before Width: | Height: | Size: 423 KiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 316 KiB After Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 598 KiB After Width: | Height: | Size: 316 KiB |
|
Before Width: | Height: | Size: 443 KiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 563 KiB After Width: | Height: | Size: 598 KiB |
|
Before Width: | Height: | Size: 386 KiB After Width: | Height: | Size: 443 KiB |
BIN
docs/images/sso-okta-9.png
Normal file
|
After Width: | Height: | Size: 386 KiB |
@@ -4,7 +4,8 @@ import SecurityClient from "@app/components/utilities/SecurityClient";
|
||||
import {
|
||||
getAuthToken,
|
||||
getMfaTempToken,
|
||||
getSignupTempToken} from "@app/reactQuery";
|
||||
getSignupTempToken
|
||||
} from "@app/reactQuery";
|
||||
|
||||
export const apiRequest = axios.create({
|
||||
baseURL: "/",
|
||||
|
||||
@@ -29,8 +29,7 @@ export const useCreateSSOConfig = () => {
|
||||
isActive,
|
||||
entryPoint,
|
||||
issuer,
|
||||
cert,
|
||||
audience
|
||||
cert
|
||||
}: {
|
||||
organizationId: string;
|
||||
authProvider: string;
|
||||
@@ -38,7 +37,6 @@ export const useCreateSSOConfig = () => {
|
||||
entryPoint: string;
|
||||
issuer: string;
|
||||
cert: string;
|
||||
audience: string;
|
||||
}) => {
|
||||
const { data } = await apiRequest.post(
|
||||
"/api/v1/sso/config",
|
||||
@@ -48,8 +46,7 @@ export const useCreateSSOConfig = () => {
|
||||
isActive,
|
||||
entryPoint,
|
||||
issuer,
|
||||
cert,
|
||||
audience
|
||||
cert
|
||||
}
|
||||
);
|
||||
|
||||
@@ -70,8 +67,7 @@ export const useUpdateSSOConfig = () => {
|
||||
isActive,
|
||||
entryPoint,
|
||||
issuer,
|
||||
cert,
|
||||
audience
|
||||
cert
|
||||
}: {
|
||||
organizationId: string;
|
||||
authProvider?: string;
|
||||
@@ -79,7 +75,6 @@ export const useUpdateSSOConfig = () => {
|
||||
entryPoint?: string;
|
||||
issuer?: string;
|
||||
cert?: string;
|
||||
audience?: string;
|
||||
}) => {
|
||||
const { data } = await apiRequest.patch(
|
||||
"/api/v1/sso/config",
|
||||
@@ -89,8 +84,7 @@ export const useUpdateSSOConfig = () => {
|
||||
...(isActive !== undefined ? { isActive } : {}),
|
||||
...(entryPoint !== undefined ? { entryPoint } : {}),
|
||||
...(issuer !== undefined ? { issuer } : {}),
|
||||
...(cert !== undefined ? { cert } : {}),
|
||||
...(audience !== undefined ? { audience } : {})
|
||||
...(cert !== undefined ? { cert } : {})
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Button, Switch, UpgradePlanModal } from "@app/components/v2";
|
||||
import { useOrganization, useSubscription } from "@app/context";
|
||||
import {
|
||||
useGetSSOConfig,
|
||||
useCreateSSOConfig,
|
||||
useUpdateSSOConfig
|
||||
} from "@app/hooks/api";
|
||||
import { usePopUp } from "@app/hooks/usePopUp";
|
||||
@@ -27,6 +28,8 @@ export const OrgSSOSection = (): JSX.Element => {
|
||||
"addSSO"
|
||||
] as const);
|
||||
|
||||
const { mutateAsync: createMutateAsync, isLoading: createIsLoading } = useCreateSSOConfig();
|
||||
|
||||
const handleSamlSSOToggle = async (value: boolean) => {
|
||||
try {
|
||||
if (!currentOrg?._id) return;
|
||||
@@ -49,6 +52,33 @@ export const OrgSSOSection = (): JSX.Element => {
|
||||
}
|
||||
}
|
||||
|
||||
const addSSOBtnClick = async () => {
|
||||
try {
|
||||
if (subscription?.samlSSO && currentOrg) {
|
||||
if (!data) {
|
||||
// case: SAML SSO is not configured
|
||||
// -> initialize empty SAML SSO configuration
|
||||
await createMutateAsync({
|
||||
organizationId: currentOrg._id,
|
||||
authProvider: "okta-saml",
|
||||
isActive: false,
|
||||
entryPoint: "",
|
||||
issuer: "",
|
||||
cert: ""
|
||||
});
|
||||
}
|
||||
|
||||
handlePopUpOpen("addSSO");
|
||||
} else {
|
||||
handlePopUpOpen("upgradePlan");
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("getSSOConfig: ", data);
|
||||
|
||||
return (
|
||||
<div className="p-4 bg-mineshaft-900 mb-6 rounded-lg border border-mineshaft-600">
|
||||
<div className="flex items-center mb-8">
|
||||
@@ -57,13 +87,7 @@ export const OrgSSOSection = (): JSX.Element => {
|
||||
</h2>
|
||||
{!isLoading && (
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (subscription?.samlSSO) {
|
||||
handlePopUpOpen("addSSO");
|
||||
} else {
|
||||
handlePopUpOpen("upgradePlan");
|
||||
}
|
||||
}}
|
||||
onClick={addSSOBtnClick}
|
||||
colorSchema="secondary"
|
||||
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
||||
>
|
||||
@@ -71,39 +95,33 @@ export const OrgSSOSection = (): JSX.Element => {
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
{!isLoading && data && (
|
||||
<>
|
||||
<div className="mb-4">
|
||||
<Switch
|
||||
id="enable-saml-sso"
|
||||
onCheckedChange={(value) => handleSamlSSOToggle(value)}
|
||||
isChecked={data.isActive}
|
||||
>
|
||||
Enable SAML SSO
|
||||
</Switch>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<h3 className="text-mineshaft-400 text-sm">SSO identifier</h3>
|
||||
<p className="text-gray-400 text-md">{data._id}</p>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<h3 className="text-mineshaft-400 text-sm">Type</h3>
|
||||
<p className="text-gray-400 text-md">{ssoAuthProviderMap[data.authProvider]}</p>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<h3 className="text-mineshaft-400 text-sm">Audience</h3>
|
||||
<p className="text-gray-400 text-md">{data.audience}</p>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<h3 className="text-mineshaft-400 text-sm">Entrypoint</h3>
|
||||
<p className="text-gray-400 text-md">{data.entryPoint}</p>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<h3 className="text-mineshaft-400 text-sm">Issuer</h3>
|
||||
<p className="text-gray-400 text-md">{data.issuer}</p>
|
||||
</div>
|
||||
</>
|
||||
{data && (
|
||||
<div className="mb-4">
|
||||
<Switch
|
||||
id="enable-saml-sso"
|
||||
onCheckedChange={(value) => handleSamlSSOToggle(value)}
|
||||
isChecked={data ? data.isActive : false}
|
||||
>
|
||||
Enable SAML SSO
|
||||
</Switch>
|
||||
</div>
|
||||
)}
|
||||
<div className="mb-4">
|
||||
<h3 className="text-mineshaft-400 text-sm">SSO identifier</h3>
|
||||
<p className="text-gray-400 text-md">{(data && data._id !== "") ? data._id : "-"}</p>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<h3 className="text-mineshaft-400 text-sm">Type</h3>
|
||||
<p className="text-gray-400 text-md">{(data && data.authProvider !== "") ? ssoAuthProviderMap[data.authProvider] : "-"}</p>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<h3 className="text-mineshaft-400 text-sm">Entrypoint</h3>
|
||||
<p className="text-gray-400 text-md">{(data && data.entryPoint !== "") ? data.entryPoint : "-"}</p>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<h3 className="text-mineshaft-400 text-sm">Issuer</h3>
|
||||
<p className="text-gray-400 text-md">{(data && data.issuer !== "") ? data.issuer : "-"}</p>
|
||||
</div>
|
||||
<SSOModal
|
||||
popUp={popUp}
|
||||
handlePopUpClose={handlePopUpClose}
|
||||
|
||||
@@ -2,7 +2,6 @@ import { useEffect } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import * as yup from "yup";
|
||||
|
||||
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
|
||||
import {
|
||||
Button,
|
||||
@@ -29,8 +28,7 @@ const schema = yup.object({
|
||||
authProvider: yup.string().required("SSO Type is required"),
|
||||
entryPoint: yup.string().required("IDP entrypoint is required"),
|
||||
issuer: yup.string().required("Issuer string is required"),
|
||||
cert: yup.string().required("IDP's public signing certificate is required"),
|
||||
audience: yup.string().required("Expected SAML response audience is required"),
|
||||
cert: yup.string().required("IDP's public signing certificate is required")
|
||||
}).required();
|
||||
|
||||
export type AddSSOFormData = yup.InferType<typeof schema>;
|
||||
@@ -70,8 +68,7 @@ export const SSOModal = ({
|
||||
authProvider: data?.authProvider ?? "",
|
||||
entryPoint: data?.entryPoint ?? "",
|
||||
issuer: data?.issuer ?? "",
|
||||
cert: data?.cert ?? "",
|
||||
audience: data?.audience ?? ""
|
||||
cert: data?.cert ?? ""
|
||||
});
|
||||
}
|
||||
}, [data]);
|
||||
@@ -80,8 +77,7 @@ export const SSOModal = ({
|
||||
authProvider,
|
||||
entryPoint,
|
||||
issuer,
|
||||
cert,
|
||||
audience
|
||||
cert
|
||||
}: AddSSOFormData) => {
|
||||
try {
|
||||
if (!currentOrg) return;
|
||||
@@ -93,8 +89,7 @@ export const SSOModal = ({
|
||||
isActive: false,
|
||||
entryPoint,
|
||||
issuer,
|
||||
cert,
|
||||
audience
|
||||
cert
|
||||
});
|
||||
} else {
|
||||
await updateMutateAsync({
|
||||
@@ -103,8 +98,7 @@ export const SSOModal = ({
|
||||
isActive: false,
|
||||
entryPoint,
|
||||
issuer,
|
||||
cert,
|
||||
audience
|
||||
cert
|
||||
});
|
||||
}
|
||||
|
||||
@@ -160,24 +154,16 @@ export const SSOModal = ({
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
{authProvider && authProvider === "okta-saml" && (
|
||||
{authProvider && authProvider === "okta-saml" && data && (
|
||||
<>
|
||||
<Controller
|
||||
control={control}
|
||||
name="audience"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Audience"
|
||||
errorText={error?.message}
|
||||
isError={Boolean(error)}
|
||||
>
|
||||
<Input
|
||||
{...field}
|
||||
placeholder="https://your-domain.com"
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
<div className="mb-4">
|
||||
<h3 className="text-mineshaft-400 text-sm">ACS URL</h3>
|
||||
<p className="text-gray-400 text-md break-all">{`${window.origin}/api/v1/sso/saml2/${data._id}`}</p>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<h3 className="text-mineshaft-400 text-sm">Entity ID</h3>
|
||||
<p className="text-gray-400 text-md">{window.origin}</p>
|
||||
</div>
|
||||
<Controller
|
||||
control={control}
|
||||
name="entryPoint"
|
||||
|
||||