diff --git a/src/app/[orgId]/settings/(private)/idp/[idpId]/general/page.tsx b/src/app/[orgId]/settings/(private)/idp/[idpId]/general/page.tsx index 69d57345c..b2ad61d67 100644 --- a/src/app/[orgId]/settings/(private)/idp/[idpId]/general/page.tsx +++ b/src/app/[orgId]/settings/(private)/idp/[idpId]/general/page.tsx @@ -500,6 +500,7 @@ export default function GeneralPage() { onAutoProvisionChange={(checked) => { form.setValue("autoProvision", checked); }} + orgId={orgId as string} roleMappingMode={roleMappingMode} onRoleMappingModeChange={(data) => { setRoleMappingMode(data); diff --git a/src/app/[orgId]/settings/(private)/idp/create/page.tsx b/src/app/[orgId]/settings/(private)/idp/create/page.tsx index a7796e2a9..33ef71eee 100644 --- a/src/app/[orgId]/settings/(private)/idp/create/page.tsx +++ b/src/app/[orgId]/settings/(private)/idp/create/page.tsx @@ -246,523 +246,559 @@ export default function Page() { -
- - - - - {t("idpTitle")} - - - {t("idpCreateSettingsDescription")} - - - - { - applyOidcIdpProviderType(form.setValue, next); - }} - /> +
+ + + + + {t("idpTitle")} + + + {t("idpCreateSettingsDescription")} + + + + { + applyOidcIdpProviderType( + form.setValue, + next + ); + }} + /> - + +
+ + ( + + + {t("name")} + + + + + + {t("idpDisplayName")} + + + + )} + /> + + +
+
+
+ + {/* Auto Provision Settings */} + + + + {t("idpAutoProvisionUsers")} + + + + + + +
- ( - - - {t("name")} - - - - - - {t("idpDisplayName")} - - - - )} + { + form.setValue( + "autoProvision", + checked + ); + }} + orgId={params.orgId as string} + roleMappingMode={roleMappingMode} + onRoleMappingModeChange={(data) => { + setRoleMappingMode(data); + }} + roles={roles} + fixedRoleNames={fixedRoleNames} + onFixedRoleNamesChange={ + setFixedRoleNames + } + mappingBuilderClaimPath={ + mappingBuilderClaimPath + } + onMappingBuilderClaimPathChange={ + setMappingBuilderClaimPath + } + mappingBuilderRules={ + mappingBuilderRules + } + onMappingBuilderRulesChange={ + setMappingBuilderRules + } + rawExpression={rawRoleExpression} + onRawExpressionChange={ + setRawRoleExpression + } + orgMappingField={{ + control: form.control, + name: "orgMapping" + }} /> - -
-
- - {/* Auto Provision Settings */} - - - - {t("idpAutoProvisionUsers")} - - - - - - - -
- - { - form.setValue("autoProvision", checked); - }} - roleMappingMode={roleMappingMode} - onRoleMappingModeChange={(data) => { - setRoleMappingMode(data); - }} - roles={roles} - fixedRoleNames={fixedRoleNames} - onFixedRoleNamesChange={setFixedRoleNames} - mappingBuilderClaimPath={ - mappingBuilderClaimPath - } - onMappingBuilderClaimPathChange={ - setMappingBuilderClaimPath - } - mappingBuilderRules={mappingBuilderRules} - onMappingBuilderRulesChange={ - setMappingBuilderRules - } - rawExpression={rawRoleExpression} - onRawExpressionChange={setRawRoleExpression} - orgMappingField={{ - control: form.control, - name: "orgMapping" - }} - /> - - -
-
- - {form.watch("type") === "google" && ( - - - - {t("idpGoogleConfigurationTitle")} - - - {t("idpGoogleConfigurationDescription")} - - - - -
- - ( - - - {t("idpClientId")} - - - - - - {t( - "idpGoogleClientIdDescription" - )} - - - - )} - /> - - ( - - - {t("idpClientSecret")} - - - - - - {t( - "idpGoogleClientSecretDescription" - )} - - - - )} - /> - - -
- )} - {form.watch("type") === "azure" && ( - - - - {t("idpAzureConfigurationTitle")} - - - {t("idpAzureConfigurationDescription")} - - - - -
- - ( - - - {t("idpTenantIdLabel")} - - - - - - {t( - "idpAzureTenantIdDescription" - )} - - - - )} - /> - - ( - - - {t("idpClientId")} - - - - - - {t( - "idpAzureClientIdDescription2" - )} - - - - )} - /> - - ( - - - {t("idpClientSecret")} - - - - - - {t( - "idpAzureClientSecretDescription2" - )} - - - - )} - /> - - -
-
-
- )} - - {form.watch("type") === "oidc" && ( - + {form.watch("type") === "google" && ( - {t("idpOidcConfigure")} + {t("idpGoogleConfigurationTitle")} - {t("idpOidcConfigureDescription")} + {t("idpGoogleConfigurationDescription")} -
- - ( - - - {t("idpClientId")} - - - - - - {t( - "idpClientIdDescription" - )} - - - + + + + > + ( + + + {t("idpClientId")} + + + + + + {t( + "idpGoogleClientIdDescription" + )} + + + + )} + /> - ( - - - {t("idpClientSecret")} - - - - - - {t( - "idpClientSecretDescription" - )} - - - - )} - /> - - ( - - - {t("idpAuthUrl")} - - - - - - {t( - "idpAuthUrlDescription" - )} - - - - )} - /> - - ( - - - {t("idpTokenUrl")} - - - - - - {t( - "idpTokenUrlDescription" - )} - - - - )} - /> - - + ( + + + {t( + "idpClientSecret" + )} + + + + + + {t( + "idpGoogleClientSecretDescription" + )} + + + + )} + /> + + +
+ )} + {form.watch("type") === "azure" && ( - {t("idpToken")} + {t("idpAzureConfigurationTitle")} - {t("idpTokenDescription")} + {t("idpAzureConfigurationDescription")} -
- - ( - - - {t("idpJmespathLabel")} - - - - - - {t( - "idpJmespathLabelDescription" - )} - - - + + + + > + ( + + + {t( + "idpTenantIdLabel" + )} + + + + + + {t( + "idpAzureTenantIdDescription" + )} + + + + )} + /> - ( - - - {t( - "idpJmespathEmailPathOptional" - )} - - - - - - {t( - "idpJmespathEmailPathOptionalDescription" - )} - - - - )} - /> + ( + + + {t("idpClientId")} + + + + + + {t( + "idpAzureClientIdDescription2" + )} + + + + )} + /> - ( - - - {t( - "idpJmespathNamePathOptional" - )} - - - - - - {t( - "idpJmespathNamePathOptionalDescription" - )} - - - - )} - /> - - ( - - - {t( - "idpOidcConfigureScopes" - )} - - - - - - {t( - "idpOidcConfigureScopesDescription" - )} - - - - )} - /> - - + ( + + + {t( + "idpClientSecret" + )} + + + + + + {t( + "idpAzureClientSecretDescription2" + )} + + + + )} + /> + + +
-
- )} -
+ )} -
- - -
+ {form.watch("type") === "oidc" && ( + + + + + {t("idpOidcConfigure")} + + + {t("idpOidcConfigureDescription")} + + + +
+ + ( + + + {t("idpClientId")} + + + + + + {t( + "idpClientIdDescription" + )} + + + + )} + /> + + ( + + + {t( + "idpClientSecret" + )} + + + + + + {t( + "idpClientSecretDescription" + )} + + + + )} + /> + + ( + + + {t("idpAuthUrl")} + + + + + + {t( + "idpAuthUrlDescription" + )} + + + + )} + /> + + ( + + + {t("idpTokenUrl")} + + + + + + {t( + "idpTokenUrlDescription" + )} + + + + )} + /> + + +
+
+ + + + + {t("idpToken")} + + + {t("idpTokenDescription")} + + + +
+ + ( + + + {t( + "idpJmespathLabel" + )} + + + + + + {t( + "idpJmespathLabelDescription" + )} + + + + )} + /> + + ( + + + {t( + "idpJmespathEmailPathOptional" + )} + + + + + + {t( + "idpJmespathEmailPathOptionalDescription" + )} + + + + )} + /> + + ( + + + {t( + "idpJmespathNamePathOptional" + )} + + + + + + {t( + "idpJmespathNamePathOptionalDescription" + )} + + + + )} + /> + + ( + + + {t( + "idpOidcConfigureScopes" + )} + + + + + + {t( + "idpOidcConfigureScopesDescription" + )} + + + + )} + /> + + +
+
+
+ )} + + +
+ + +
); diff --git a/src/app/admin/idp/[idpId]/policies/page.tsx b/src/app/admin/idp/[idpId]/policies/page.tsx index e9438da33..e1a098e83 100644 --- a/src/app/admin/idp/[idpId]/policies/page.tsx +++ b/src/app/admin/idp/[idpId]/policies/page.tsx @@ -681,6 +681,9 @@ export default function PoliciesPage() { control: form.control, name: "orgMapping" }} + orgId={ + editingPolicy?.orgId || policyFormOrgId + } roleMappingFieldIdPrefix="admin-idp-policy-role" roleMappingMode={policyRoleMappingMode} onRoleMappingModeChange={ diff --git a/src/components/AutoProvisionConfigWidget.tsx b/src/components/AutoProvisionConfigWidget.tsx index 4767544d0..4cf939444 100644 --- a/src/components/AutoProvisionConfigWidget.tsx +++ b/src/components/AutoProvisionConfigWidget.tsx @@ -47,6 +47,7 @@ type AutoProvisionConfigWidgetProps = { roleMappingFieldIdPrefix?: string; showFreeformRoleNamesHint?: boolean; autoProvisionSwitchId?: string; + orgId?: string; }; export default function AutoProvisionConfigWidget({ @@ -67,7 +68,8 @@ export default function AutoProvisionConfigWidget({ showAutoProvisionSwitch = true, roleMappingFieldIdPrefix = "org-idp-auto-provision", showFreeformRoleNamesHint = false, - autoProvisionSwitchId = "auto-provision-toggle" + autoProvisionSwitchId = "auto-provision-toggle", + orgId }: AutoProvisionConfigWidgetProps) { const t = useTranslations(); const { isPaidUser } = usePaidStatus(); @@ -106,6 +108,7 @@ export default function AutoProvisionConfigWidget({ showFreeformRoleNamesHint={ showFreeformRoleNamesHint } + orgId={orgId} roleMappingMode={roleMappingMode} onRoleMappingModeChange={onRoleMappingModeChange} roles={roles} diff --git a/src/components/RoleMappingConfigFields.tsx b/src/components/RoleMappingConfigFields.tsx index 906f85f62..08b4e36bc 100644 --- a/src/components/RoleMappingConfigFields.tsx +++ b/src/components/RoleMappingConfigFields.tsx @@ -17,7 +17,6 @@ import { useEnvContext } from "@app/hooks/useEnvContext"; import { tierMatrix } from "@server/lib/billing/tierMatrix"; import { build } from "@server/build"; import { RolesSelector } from "./roles-selector"; -import { useParams } from "next/navigation"; export type RoleMappingRoleOption = { roleId: number; @@ -40,6 +39,8 @@ export type RoleMappingConfigFieldsProps = { fieldIdPrefix?: string; /** When true, show extra hint for global default policies (no org role list). */ showFreeformRoleNamesHint?: boolean; + /** Org ID to use for role lookup. Falls back to URL params when not provided. */ + orgId?: string; }; export default function RoleMappingConfigFields({ @@ -55,14 +56,13 @@ export default function RoleMappingConfigFields({ rawExpression, onRawExpressionChange, fieldIdPrefix = "role-mapping", - showFreeformRoleNamesHint = false + showFreeformRoleNamesHint = false, + orgId }: RoleMappingConfigFieldsProps) { const t = useTranslations(); const { env } = useEnvContext(); const { isPaidUser } = usePaidStatus(); - const { orgId } = useParams(); - const supportsMultipleRolesPerUser = isPaidUser(tierMatrix.fullRbac); const showSingleRoleDisclaimer = !env.flags.disableEnterpriseFeatures && @@ -242,6 +242,7 @@ export default function RoleMappingConfigFields({ showFreeformRoleNamesHint={ showFreeformRoleNamesHint } + orgId={orgId} supportsMultipleRolesPerUser={ supportsMultipleRolesPerUser } @@ -318,7 +319,8 @@ function BuilderRuleRow({ supportsMultipleRolesPerUser, showRemoveButton, onChange, - onRemove + onRemove, + orgId }: { rule: MappingBuilderRule; roleOptions: Tag[]; @@ -330,10 +332,10 @@ function BuilderRuleRow({ showRemoveButton: boolean; onChange: (rule: MappingBuilderRule) => void; onRemove: () => void; + orgId?: string; }) { const t = useTranslations(); const [activeTagIndex, setActiveTagIndex] = useState(null); - const { orgId } = useParams(); return (