feat(ui): add Configure manually path to ConfigureSSO submit-config sub-step#8553
feat(ui): add Configure manually path to ConfigureSSO submit-config sub-step#8553iagodahlem wants to merge 10 commits into
Conversation
Wraps the SAML config submission body in a two-mode segmented control inside <__experimental_ConfigureSSO />'s Configure step. Users pick between Add via metadata URL (default) and Configure manually. The metadata URL form keeps its existing behavior; the manual entry form lands in a follow-up commit and is intentionally an empty body for now with the Continue button disabled. Mode is local component state in SubmitSamlConfigSubStep — internal flag, not wizard navigation — so the segmented control swap stays inside the sub-step. Locale keys added under configureSSO.configureStep.samlOkta.modes in en-US.
Two copy fixes against the Configure step's SAML submission sub-step: - The metadata segmented-control tab now reads "Add via metadata" instead of "Add via metadata URL". Figma's tab label is the shorter variant; the description below the field still spells out "metadata URL". - Add a section heading "Fill in your Okta SAML application details" above the segmented control, matching the per-sub-step subtitle pattern used in ConfigureAttributes and AssignUsers. Wired through a new configureSSO.configureStep.samlOkta.submitSamlConfig.title locale key.
Renders the Configure manually tab body in SubmitSamlConfigSubStep with
the per-mode description and three fields:
- Sign on URL — text input wired with useFormControl('idpSsoUrl')
- Issuer — text input wired with useFormControl('idpEntityId')
- Signing certificate — label plus a stub outline button with the
Upload icon. The button is intentionally inert; the file picker and
filename chip land in a follow-up commit.
Adds 'idpEntityId' and 'idpSsoUrl' to the FieldId union and a new
configureSSO.configureStep.samlOkta.manual locale block with the
description, per-field labels and placeholders, and the cert label
plus upload-file button copy.
The Continue button stays disabled in manual mode for now — its
payload handler ({ saml: { idpSsoUrl, idpEntityId, idpCertificate } })
ships in the next commit.
Replaces the stub Upload file button in SubmitSamlConfigSubStep with a working file picker. A hidden file input captures the selected cert (accepts .pem/.crt/.cer/.txt); when present, the cert row swaps to a filename label plus a small remove button that clears state and resets the input. Cert state lives in component-local React state — no useFormControl, no FieldId — since the Continue handler that consumes it ships in a follow-up. Adds a configureSSO.configureStep.samlOkta.manual.signingCertificate. removeFile locale key for the remove button's aria-label.
Enables Continue in Configure manually mode of SubmitSamlConfigSubStep
when Sign on URL, Issuer, and a cert file are all present. handleContinue
now branches on the mode: metadata URL keeps its existing single-field
payload; manual reads the selected cert via File.text() and posts
{ saml: { idpSsoUrl, idpEntityId, idpCertificate } } through the same
user.updateEnterpriseConnection mutation.
Backend rejections route through handleError into the relevant text
fields per mode (metadataUrlField for URL mode, signOnUrlField and
issuerField for manual). Cert-specific errors fall through to the card-
level error surface since the cert UI has no inline error slot.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: 5fbd791 The changes in this PR will be included in the next version bump. This PR includes changesets to release 20 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
📝 WalkthroughWalkthroughThis PR adds a two-mode segmented control to the SAML configuration submission flow in <__experimental_ConfigureSSO />. Users can choose Add via metadata URL (existing flow) or Configure manually (new manual entry fields). It adds new field identifiers (idpEntityId, idpSsoUrl, idpCertificate), extends localization types and en-US strings for the mode selector and manual form, implements mode state and cert-file handling, makes validation and submission mode-dependent, and includes UI and layout refinements for attribute mapping and user assignment. Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
@clerk/astro
@clerk/backend
@clerk/chrome-extension
@clerk/clerk-js
@clerk/dev-cli
@clerk/expo
@clerk/expo-passkeys
@clerk/express
@clerk/fastify
@clerk/hono
@clerk/localizations
@clerk/nextjs
@clerk/nuxt
@clerk/react
@clerk/react-router
@clerk/shared
@clerk/tanstack-react-start
@clerk/testing
@clerk/ui
@clerk/upgrade
@clerk/vue
commit: |
Extracts the metadata URL and manual-entry bodies of SubmitSamlConfigSubStep into MetadataUrlPanel and ManualEntryPanel components. State stays lifted in the parent — useFormControl hooks, certFile, mode, card, updateConnection, handleContinue, canSubmit, and Step.Footer all live in SubmitSamlConfigSubStep. The panels are pure render components that receive their fields and cert state as props. Field state is preserved across mode switches as a consequence — the lifted state outlives the panel that renders it. Acceptable trade-off given the "no useEffects, single hook upstream + prop-injection" rule. Also aligns the cert file input's accept list with the Clerk Dashboard's SAML connection form: .pem, .key, .crt, .cer, .cert. Drops .txt, adds .key and .cert.
Reorganizes SubmitSamlConfigSubStep so the orchestrator stays at the top of the file with the per-mode panels declared below it, mirroring the convention used elsewhere in the codebase. Also narrows certFile in handleContinue via an early return guard instead of a non-null assertion, and swaps the Step.Section sx callback for the gap shorthand prop.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/ui/src/components/ConfigureSSO/steps/ConfigureStep.tsx`:
- Around line 551-554: The handleContinue handler currently blocks all submits
when certFile is falsy; change the check so certFile is only required when the
flow is in manual/certificate-upload mode (e.g., gate certFile behind whatever
boolean indicates manual mode instead of unconditionally checking certFile),
keeping enterpriseConnection and canSubmit required for both flows; update any
UI state/props used to detect "metadataUrl" vs "manual" flow (referencing
handleContinue, certFile, enterpriseConnection, canSubmit, and
metadataUrl/manual-mode flag) and add a regression test that simulates the
metadata-mode submission (no certFile) to ensure Continue succeeds when
canSubmit is true.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 8da919c9-9e0a-4d43-b0bc-565b11adf210
📒 Files selected for processing (1)
packages/ui/src/components/ConfigureSSO/steps/ConfigureStep.tsx
…dback Two changes for the Configure manually flow: - Pre-fills the metadata URL, Sign on URL, and Issuer text inputs from the existing enterpriseConnection.samlConnection on mount and defaults to the manual segmented-control tab when prior config exists, so the Configure-again entry from Confirmation lands users on an editable form pre-populated with their current values. Fresh setups still default to the metadata-URL tab. - Promotes the cert picker to a real useFormControl-backed field with a new idpCertificate FieldId, so the cert label and inline error feedback render through Field.Root / Field.Label / Field.Feedback in the same chrome as the surrounding text inputs. Backend errors keyed idp_certificate now route inline below the cert UI via handleError. When the existing connection already has a cert on file, the picker shows a Replace file affordance and Continue stays enabled without requiring a fresh upload; the manual PATCH omits idpCertificate from the payload when no new file was selected.
Wraps the cert field section in a Box and groups Field.Label, the file input, and the upload/filename row inside a Col gap-2 so the label-to- control spacing stays consistent with the surrounding inputs. Field.Feedback sits outside the Col so the error row keeps its default spacing below the control. Also swaps the filename Text from an inline fontSize sx to the buttonSmall variant and adds vertical padding to the filename chip so it shares the upload button's baseline height.
…gain Reverts the metadata URL field to always initialize as an empty string, matching the Clerk Dashboard's SAML connection form behavior. The metadata URL flow is a one-shot operation; pre-filling it implies the user is editing the URL rather than re-submitting fresh metadata, which is the opposite of how the metadata mode works on every other surface. Sign on URL, Issuer, and the cert state are still pre-filled / preserved for the manual mode's edit flow.
Description
Adds the Configure manually path to the SAML config submission sub-step of
<__experimental_ConfigureSSO />'s Configure step, and reshapes the sub-step so the per-mode bodies are isolated, the cert field routes errors inline, and Configure-again from the Confirmation step lands users on an editable, pre-populated form.Segmented control + per-mode panels
The sub-step body now sits behind a two-mode
SegmentedControland the per-mode JSX is split intoMetadataUrlPanelandManualEntryPanelrender components (internal toConfigureStep.tsx). State stays lifted inSubmitSamlConfigSubStep—useFormControlhooks, cert file, mode, card state, mutation, Continue handler, andStep.Footerall live in the orchestrator. Panels receive their fields and cert state as props.{ saml: { idpMetadataUrl } }.idpSsoUrlFieldId.idpEntityIdFieldId.idpCertificateFieldId. A hidden<input type="file" accept=".pem,.key,.crt,.cer,.cert">is triggered by the visible Upload/Replace button. When a file is selected, the cert row swaps to a filename label plus a small remove button that clears the selection and resets the input value (so re-picking the same file refires the change). The accept list mirrors the Clerk Dashboard's existing SAML connection form.Continue is gated to the selected mode's required fields. In manual mode, the handler reads the cert via
File.text()and posts{ saml: { idpSsoUrl, idpEntityId, idpCertificate } }through the sameuser.updateEnterpriseConnectioncall wrapped inuseReverification.Cert errors route inline
The cert field is a real
useFormControl-backed field with its ownFieldId. The cert section renders insideField.Root/Field.LabelRow/Field.Label/Field.Feedback, matching the surrounding inputs. Backend errors keyedidp_certificateroute inline below the cert UI viahandleError([signOnUrlField, issuerField, certFileField], card.setError). Fresh interaction (file pick or remove) clears stale field-level feedback viaclearFeedback(). The field'svaluestays empty — we only use the field for label rendering and error state, not value tracking.Configure-again pre-fill
When the user lands on the Configure step with an existing
enterpriseConnection.samlConnection(typically viagoToStep('configure')from the Confirmation step's Configure again button), the form populates:signOnUrlFieldandissuerFieldinitialize fromsamlConnection.idpSsoUrl/idpEntityId.samlConnection.idpCertificateis present. Continue stays enabled without requiring a fresh upload; the manual PATCH conditionally includesidpCertificateonly when a new file was selected so the backend retains the existing cert on submit.Locale keys
Live under
configureSSO.configureStep.samlOkta:modes.*for the segmented control labels and aria-label.submitSamlConfig.titlefor the "Fill in your Okta SAML application details" section heading.manual.*for the per-mode description, field labels, placeholders, and the Upload file / Replace file / Remove file copy.Also tightens the metadata-mode tab label from "Add via metadata URL" to "Add via metadata" to match Figma.
Linear: ORGS-1535
Follow-ups (separate PR)
connection.provider. The Custom SAML manual path will reuse the segmented control, panel split, cert field, and Continue handler shipped here.canSubmitgate, no inline message).How to test
Fresh setup
In a sandbox with the ConfigureSSO wizard, walk through Select Provider → Verify Domain → land on Configure. Advance through sub-steps 1–3, then on the SAML config sub-step:
.pem/.key/.crt/.cer/.certcert file → Continue stays disabled until all three are present → click Continue → connection is patched with{ saml: { idpSsoUrl, idpEntityId, idpCertificate } }→ wizard advances to Test.Click the × on the filename chip → cert state clears and the Upload file button returns. Picking the same file again refires the change.
Configure-again (editing)
From the Confirmation step's Configure again button (
goToStep('configure')), land back on the SAML config sub-step:idpCertificatefrom the payload so the backend keeps the existing cert.Errors
Backend errors keyed
idp_sso_url,idp_entity_id, oridp_certificaterender inline below the corresponding field; everything else surfaces at the card level.Base
Branches from
main— stacks on top of #8535 (merged).Checklist
pnpm testruns as expected.pnpm buildruns as expected.Type of change