{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "sso-identity-provider-config",
  "title": "Sso Identity Provider Config",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/sso-identity-provider-config/SsoIdentityProviderConfig.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  Check,\n  CheckCircle2,\n  Copy,\n  Download,\n  ExternalLink,\n  FileCode,\n  Globe,\n  KeyRound,\n  Lock,\n  Play,\n  RotateCw,\n  Save,\n  ShieldAlert,\n  ShieldCheck,\n  UploadCloud,\n  UserCheck,\n  X,\n} from 'lucide-react'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { Input } from '@/components/ui/input'\nimport { Separator } from '@/components/ui/separator'\nimport { Switch } from '@/components/ui/switch'\nimport { Textarea } from '@/components/ui/textarea'\nimport { cn } from '@/lib/utils'\n\nexport type IdpPresetId = 'okta' | 'entra' | 'google' | 'custom'\n\nexport interface IdpPreset {\n  id: IdpPresetId\n  name: string\n  subtitle: string\n  badge: string\n  defaultSsoUrl: string\n  defaultEntityId: string\n  domain: string\n  defaultCert: string\n}\n\nexport interface ClaimAttribute {\n  samlAttribute: string\n  mappedField: string\n  sampleValue: string\n}\n\nexport interface SsoIdentityProviderConfigProps {\n  initialSsoEnabled?: boolean\n  initialPreset?: IdpPresetId\n  initialEnforceDomain?: boolean\n  className?: string\n}\n\nconst idpPresets: IdpPreset[] = [\n  {\n    id: 'okta',\n    name: 'Okta',\n    subtitle: 'SAML 2.0 & OIDC Enterprise',\n    badge: 'Popular',\n    defaultSsoUrl: 'https://company.okta.com/app/sso/saml',\n    defaultEntityId: 'http://www.okta.com/exk849201',\n    domain: 'company.okta.com',\n    defaultCert: `-----BEGIN CERTIFICATE-----\nMIIDpDCCAoygAwIBAgIGAX2v5L3oMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYDVQQGEwJV\nUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsG\nA1UECgwET2t0YTEUMBIGA1UECwwLU1NPIFNlcnZpY2UxGDAWBgNVBAMMD2NvbXBhbnkub2t0\nYS5jb20xIDAeBgkqhkiG9w0BCQEWEWFkbWluQG9rdGEuY29tMB4XDTI2MDgyMTE0MzAwMFoX\nDTI4MTAyMTE0MzAwMFowgZIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh\n-----END CERTIFICATE-----`,\n  },\n  {\n    id: 'entra',\n    name: 'Microsoft Entra ID',\n    subtitle: 'Azure AD & Microsoft 365',\n    badge: 'Enterprise',\n    defaultSsoUrl: 'https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47/saml2',\n    defaultEntityId: 'https://sts.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47/',\n    domain: 'login.microsoftonline.com',\n    defaultCert: `-----BEGIN CERTIFICATE-----\nMIIDBTCCAe2gAwIBAgIQJn0zJk1vVbtJpZ0R4k0D1DANBgkqhkiG9w0BAQsFADAtMSsw\nKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4XDTI2MDgy\nMTE0MzAwMFoXDTI4MTAyMTE0MzAwMFowLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNz\nY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n-----END CERTIFICATE-----`,\n  },\n  {\n    id: 'google',\n    name: 'Google Workspace',\n    subtitle: 'Google Cloud Identity SAML',\n    badge: 'SAML 2.0',\n    defaultSsoUrl: 'https://accounts.google.com/o/saml2/idp?idpid=C0123abcd',\n    defaultEntityId: 'https://accounts.google.com/o/saml2?idpid=C0123abcd',\n    domain: 'accounts.google.com',\n    defaultCert: `-----BEGIN CERTIFICATE-----\nMIIDdDCCAlygAwIBAgIGAY7GZpBqMA0GCSqGSIb3DQEBCwUAMHQxCzAJBgNVBAYTAlVT\nMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MR8wHQYD\nVQQKExZHb29nbGUgV29ya3NwYWNlIElBTSExMB8GA1UEAxMYR29vZ2xlIElkUCBTYW1s\nIFNpZ25lcjAeFw0yNjA4MjExNDMwMDBaFw0yODEwMjExNDMwMDBaMHQxCzAJBgNVBAYT\n-----END CERTIFICATE-----`,\n  },\n  {\n    id: 'custom',\n    name: 'Custom SAML 2.0',\n    subtitle: 'PingFederate, OneLogin, Keycloak',\n    badge: 'Universal',\n    defaultSsoUrl: 'https://sso.company.com/idp/profile/SAML2/POST/SSO',\n    defaultEntityId: 'https://sso.company.com/idp/shibboleth',\n    domain: 'sso.company.com',\n    defaultCert: `-----BEGIN CERTIFICATE-----\nMIIDcDCCAligAwIBAgIJAN8FpW1mG+hBMA0GCSqGSIb3DQEBCwUAMFgxCzAJBgNVBAYT\nAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMQ8wDQYDVQQKDAZDdXN0b20xIDAeBgNVBAMM\nF2N1c3RvbS5pZHAucHJvdmlkZXIubGFiMB4XDTI2MDgyMTE0MzAwMFoXDTI4MTAyMTE0\nMzAwMFowWDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExDzANBgNVBAoM\n-----END CERTIFICATE-----`,\n  },\n]\n\nconst spAcsUrl = 'https://auth.uipkge.dev/sso/saml/callback'\nconst spEntityId = 'https://auth.uipkge.dev/sso/saml/metadata'\nconst spMetadataXmlUrl = 'https://auth.uipkge.dev/sso/saml/metadata.xml'\nconst spCertificatePem = `-----BEGIN CERTIFICATE-----\nMIIDODCCAiCgAwIBAgIUW0Qz0K7VzN8XlP4wQ6k9J1vYgLAwDQYJKoZIhvcNAQEL\nBQAwMzEXMBUGA1UEAwwNYXV0aC51aXBrZ2UuZGV2MRgwFgYDVQQKDA9VSVBLR0Ug\nQXV0aCBTU08wHhcNMjYwODIxMTQzMDAwWhcNMzEwODIxMTQzMDAwWjAzMRcwFQYD\nVQQDDA5hdXRoLnVpcGtnZS5kZXYxGDAWBgNVBAoMD1VJUEtHRSBBdXRoIFNTTzCC\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL1K9sU3FvX+7nQ6m2W4j1k9\n-----END CERTIFICATE-----`\n\nconst simulatedClaims: ClaimAttribute[] = [\n  { samlAttribute: 'urn:oid:0.9.2342.19200300.100.1.1', mappedField: 'nameID', sampleValue: 'alex.morgan@company.com' },\n  {\n    samlAttribute: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress',\n    mappedField: 'email',\n    sampleValue: 'alex.morgan@company.com',\n  },\n  {\n    samlAttribute: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname',\n    mappedField: 'firstName',\n    sampleValue: 'Alex',\n  },\n  {\n    samlAttribute: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname',\n    mappedField: 'lastName',\n    sampleValue: 'Morgan',\n  },\n  {\n    samlAttribute: 'http://schemas.xmlsoap.org/claims/Group',\n    mappedField: 'groups',\n    sampleValue: '[\"Engineering\", \"IAM-Admins\", \"SSO-Users\"]',\n  },\n  {\n    samlAttribute: 'urn:oasis:names:tc:SAML:2.0:assertion:SessionIndex',\n    mappedField: 'sessionIndex',\n    sampleValue: '_sess_8f29ab0192e47',\n  },\n]\n\nexport function SsoIdentityProviderConfig({\n  initialSsoEnabled = true,\n  initialPreset = 'okta',\n  initialEnforceDomain = true,\n  className,\n}: SsoIdentityProviderConfigProps) {\n  const [ssoEnabled, setSsoEnabled] = React.useState(initialSsoEnabled)\n  const [selectedPresetId, setSelectedPresetId] = React.useState<IdpPresetId>(initialPreset)\n  const [enforceDomain, setEnforceDomain] = React.useState(initialEnforceDomain)\n\n  const currentPreset = React.useMemo(() => {\n    return idpPresets.find((p) => p.id === selectedPresetId) ?? idpPresets[0]\n  }, [selectedPresetId])\n\n  const [idpSsoUrl, setIdpSsoUrl] = React.useState(currentPreset.defaultSsoUrl)\n  const [idpEntityId, setIdpEntityId] = React.useState(currentPreset.defaultEntityId)\n  const [idpCertPem, setIdpCertPem] = React.useState(currentPreset.defaultCert)\n\n  const [copiedKey, setCopiedKey] = React.useState<string | null>(null)\n  const [isDraggingXml, setIsDraggingXml] = React.useState(false)\n  const [xmlUploadedNotice, setXmlUploadedNotice] = React.useState(false)\n  const [isSaving, setIsSaving] = React.useState(false)\n  const [saveSuccessNotice, setSaveSuccessNotice] = React.useState(false)\n  const [testModalOpen, setTestModalOpen] = React.useState(false)\n\n  const copyTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(null)\n\n  const copyText = React.useCallback((text: string, key: string) => {\n    navigator.clipboard?.writeText(text)\n    setCopiedKey(key)\n    if (copyTimerRef.current) clearTimeout(copyTimerRef.current)\n    copyTimerRef.current = setTimeout(() => {\n      setCopiedKey((prev) => (prev === key ? null : prev))\n    }, 2000)\n  }, [])\n\n  const handleSelectPreset = React.useCallback((presetId: IdpPresetId) => {\n    setSelectedPresetId(presetId)\n    const preset = idpPresets.find((p) => p.id === presetId)\n    if (preset) {\n      setIdpSsoUrl(preset.defaultSsoUrl)\n      setIdpEntityId(preset.defaultEntityId)\n      setIdpCertPem(preset.defaultCert)\n      setXmlUploadedNotice(false)\n    }\n  }, [])\n\n  const downloadSpCertificate = React.useCallback(() => {\n    if (typeof window === 'undefined') return\n    const blob = new Blob([spCertificatePem], { type: 'application/x-pem-file' })\n    const url = URL.createObjectURL(blob)\n    const anchor = document.createElement('a')\n    anchor.href = url\n    anchor.download = 'uipkge-sp-certificate.crt'\n    document.body.appendChild(anchor)\n    anchor.click()\n    document.body.removeChild(anchor)\n    URL.revokeObjectURL(url)\n  }, [])\n\n  const simulateXmlUpload = React.useCallback(() => {\n    const preset = currentPreset\n    setIdpSsoUrl(preset.defaultSsoUrl)\n    setIdpEntityId(preset.defaultEntityId)\n    setIdpCertPem(preset.defaultCert)\n    setXmlUploadedNotice(true)\n    setTimeout(() => {\n      setXmlUploadedNotice(false)\n    }, 4000)\n  }, [currentPreset])\n\n  const handleSaveConfig = React.useCallback(() => {\n    if (isSaving) return\n    setIsSaving(true)\n    setTimeout(() => {\n      setIsSaving(false)\n      setSaveSuccessNotice(true)\n      setTimeout(() => {\n        setSaveSuccessNotice(false)\n      }, 3500)\n    }, 600)\n  }, [isSaving])\n\n  const openTestModal = React.useCallback(() => {\n    setTestModalOpen(true)\n  }, [])\n\n  return (\n    <div data-slot=\"sso-identity-provider-config\" className={cn('w-full space-y-6', className)}>\n      {/* Header Banner & Top Controls */}\n      <Card className=\"border-border bg-card/80 shadow-xs backdrop-blur-xs\">\n        <CardHeader className=\"pb-4\">\n          <div className=\"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between\">\n            <div className=\"space-y-1\">\n              <div className=\"flex flex-wrap items-center gap-2.5\">\n                <div className=\"bg-primary/10 text-primary flex size-8 items-center justify-center rounded-lg\">\n                  <KeyRound className=\"size-4\" />\n                </div>\n                <CardTitle className=\"text-base font-semibold\">Single Sign-On (SSO) & SAML 2.0 Configuration</CardTitle>\n                {ssoEnabled ? (\n                  <Badge variant=\"success\" className=\"font-mono text-xs\">\n                    <span className=\"bg-success mr-1.5 inline-block size-2 animate-pulse rounded-full\" />\n                    SSO Active\n                  </Badge>\n                ) : (\n                  <Badge variant=\"outline\" className=\"text-muted-foreground border-border font-mono text-xs\">\n                    Disabled\n                  </Badge>\n                )}\n              </div>\n              <CardDescription className=\"text-xs\">\n                Connect your enterprise IdP (Okta, Azure AD / Entra, Google Workspace, OneLogin) for federated SAML\n                authentication.\n              </CardDescription>\n            </div>\n\n            <div className=\"flex flex-wrap items-center gap-3\">\n              <div className=\"border-border bg-muted/30 flex items-center gap-3 rounded-lg border px-3 py-1.5\">\n                <div className=\"text-right\">\n                  <p className=\"text-foreground text-xs font-medium\">SSO Status</p>\n                  <p className=\"text-muted-foreground text-xs\">\n                    {ssoEnabled ? 'Enabled for @company.com' : 'Disabled'}\n                  </p>\n                </div>\n                <Switch checked={ssoEnabled} onCheckedChange={setSsoEnabled} aria-label=\"Toggle Single Sign-On\" />\n              </div>\n\n              <Button\n                variant=\"outline\"\n                size=\"sm\"\n                className=\"gap-1.5 text-xs font-medium\"\n                disabled={!ssoEnabled}\n                onClick={openTestModal}\n              >\n                <Play className=\"size-3.5\" />\n                <span>Test SAML Login</span>\n              </Button>\n            </div>\n          </div>\n        </CardHeader>\n      </Card>\n\n      {/* Save Success Banner */}\n      {saveSuccessNotice && (\n        <div\n          className=\"border-success/30 bg-success/10 text-success flex items-center justify-between rounded-lg border px-4 py-3 text-xs\"\n          role=\"status\"\n        >\n          <div className=\"flex items-center gap-2\">\n            <CheckCircle2 className=\"size-4 shrink-0\" />\n            <span>\n              SSO configuration saved successfully. All assertions will validate against {currentPreset.name}.\n            </span>\n          </div>\n          <button\n            type=\"button\"\n            className=\"text-success cursor-pointer hover:opacity-75\"\n            aria-label=\"Dismiss alert\"\n            onClick={() => setSaveSuccessNotice(false)}\n          >\n            <X className=\"size-3.5\" />\n          </button>\n        </div>\n      )}\n\n      {/* IdP Preset Picker Grid */}\n      <div className=\"space-y-3\">\n        <div className=\"flex items-center justify-between\">\n          <div className=\"space-y-0.5\">\n            <h3 className=\"text-foreground text-xs font-semibold tracking-tight uppercase\">\n              Identity Provider Presets\n            </h3>\n            <p className=\"text-muted-foreground text-xs\">\n              Choose your identity platform to load SAML endpoints and formatting defaults\n            </p>\n          </div>\n          <Badge variant=\"outline\" className=\"border-border font-mono text-xs\">\n            SAML 2.0 / Web SSO\n          </Badge>\n        </div>\n\n        <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n          {idpPresets.map((preset) => {\n            const isSelected = selectedPresetId === preset.id\n            return (\n              <button\n                key={preset.id}\n                type=\"button\"\n                className={cn(\n                  'group relative flex flex-col justify-between rounded-xl border p-4 text-left transition-colors duration-150',\n                  'focus-visible:ring-ring cursor-pointer focus-visible:ring-2 focus-visible:outline-none',\n                  isSelected\n                    ? 'border-primary bg-primary/5 ring-primary shadow-xs ring-1'\n                    : 'border-border bg-card hover:border-primary/40 hover:bg-accent/40',\n                )}\n                onClick={() => handleSelectPreset(preset.id)}\n              >\n                <div className=\"space-y-2\">\n                  <div className=\"flex items-center justify-between\">\n                    <div\n                      className={cn(\n                        'flex size-8 items-center justify-center rounded-lg text-xs font-bold transition-colors',\n                        isSelected\n                          ? 'bg-primary text-primary-foreground'\n                          : 'bg-muted text-foreground group-hover:bg-primary/10 group-hover:text-primary',\n                      )}\n                    >\n                      {preset.id === 'okta' && <span>O</span>}\n                      {preset.id === 'entra' && <span>⊞</span>}\n                      {preset.id === 'google' && <span>G</span>}\n                      {preset.id === 'custom' && <Globe className=\"size-4\" />}\n                    </div>\n                    <Badge variant={isSelected ? 'default' : 'secondary'} className=\"font-mono text-xs\">\n                      {preset.badge}\n                    </Badge>\n                  </div>\n\n                  <div>\n                    <p className=\"text-foreground text-sm font-semibold\">{preset.name}</p>\n                    <p className=\"text-muted-foreground mt-0.5 text-xs\">{preset.subtitle}</p>\n                  </div>\n                </div>\n\n                <div className=\"border-border/60 mt-4 flex items-center justify-between border-t pt-2 text-xs\">\n                  <span className=\"text-muted-foreground max-w-[140px] truncate font-mono text-xs\">\n                    {preset.domain}\n                  </span>\n                  {isSelected ? (\n                    <span className=\"text-primary flex items-center gap-1 text-xs font-medium\">\n                      <Check className=\"size-3\" />\n                      <span>Active</span>\n                    </span>\n                  ) : (\n                    <span className=\"text-muted-foreground group-hover:text-foreground text-xs\">Select →</span>\n                  )}\n                </div>\n              </button>\n            )\n          })}\n        </div>\n      </div>\n\n      {/* 2-Column Configuration Form */}\n      <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-12\">\n        {/* Left Column: Service Provider (SP) Credentials */}\n        <div className=\"space-y-6 lg:col-span-6\">\n          <Card className=\"border-border bg-card shadow-xs\">\n            <CardHeader className=\"pb-4\">\n              <div className=\"flex items-center justify-between\">\n                <div className=\"flex items-center gap-2\">\n                  <div className=\"bg-primary/10 text-primary flex size-7 items-center justify-center rounded-md\">\n                    <ShieldCheck className=\"size-4\" />\n                  </div>\n                  <div>\n                    <CardTitle className=\"text-sm font-semibold\">Service Provider (SP) Credentials</CardTitle>\n                    <CardDescription className=\"text-xs\">\n                      Copy these values into your Identity Provider's SAML setup\n                    </CardDescription>\n                  </div>\n                </div>\n                <Badge variant=\"outline\" className=\"font-mono text-xs\">\n                  Our Endpoints\n                </Badge>\n              </div>\n            </CardHeader>\n\n            <CardContent className=\"space-y-4 pt-0\">\n              {/* ACS URL */}\n              <div className=\"space-y-1.5\">\n                <div className=\"flex items-center justify-between\">\n                  <label htmlFor=\"sp-acs-url-react\" className=\"text-foreground text-xs font-medium\">\n                    Assertion Consumer Service (ACS) URL\n                  </label>\n                  <Button\n                    variant=\"ghost\"\n                    size=\"sm\"\n                    className=\"text-muted-foreground hover:text-foreground h-6 px-2 text-xs\"\n                    onClick={() => copyText(spAcsUrl, 'acs')}\n                  >\n                    {copiedKey === 'acs' ? (\n                      <Check className=\"text-success mr-1 size-3\" />\n                    ) : (\n                      <Copy className=\"mr-1 size-3\" />\n                    )}\n                    <span>{copiedKey === 'acs' ? 'Copied' : 'Copy'}</span>\n                  </Button>\n                </div>\n                <Input\n                  id=\"sp-acs-url-react\"\n                  value={spAcsUrl}\n                  readOnly\n                  className=\"bg-muted/30 font-mono text-xs select-all\"\n                />\n                <p className=\"text-muted-foreground text-xs\">\n                  The callback URL where your IdP transmits HTTP-POST SAML assertion responses.\n                </p>\n              </div>\n\n              {/* Entity ID / Audience */}\n              <div className=\"space-y-1.5\">\n                <div className=\"flex items-center justify-between\">\n                  <label htmlFor=\"sp-entity-id-react\" className=\"text-foreground text-xs font-medium\">\n                    SP Entity ID / Audience URI\n                  </label>\n                  <Button\n                    variant=\"ghost\"\n                    size=\"sm\"\n                    className=\"text-muted-foreground hover:text-foreground h-6 px-2 text-xs\"\n                    onClick={() => copyText(spEntityId, 'entity-id')}\n                  >\n                    {copiedKey === 'entity-id' ? (\n                      <Check className=\"text-success mr-1 size-3\" />\n                    ) : (\n                      <Copy className=\"mr-1 size-3\" />\n                    )}\n                    <span>{copiedKey === 'entity-id' ? 'Copied' : 'Copy'}</span>\n                  </Button>\n                </div>\n                <Input\n                  id=\"sp-entity-id-react\"\n                  value={spEntityId}\n                  readOnly\n                  className=\"bg-muted/30 font-mono text-xs select-all\"\n                />\n                <p className=\"text-muted-foreground text-xs\">\n                  The unique audience restriction URI identifying our service to your IdP.\n                </p>\n              </div>\n\n              {/* Protocol Specifications Summary */}\n              <div className=\"border-border bg-muted/20 space-y-2 rounded-lg border p-3\">\n                <p className=\"text-foreground text-xs font-medium\">Protocol & Binding Requirements</p>\n                <div className=\"grid grid-cols-2 gap-2 text-xs\">\n                  <div>\n                    <span className=\"text-muted-foreground block text-xs\">NameID Format</span>\n                    <span className=\"text-foreground font-mono text-xs font-medium\">EmailAddress (urn:oasis:...)</span>\n                  </div>\n                  <div>\n                    <span className=\"text-muted-foreground block text-xs\">SAML Binding</span>\n                    <span className=\"text-foreground font-mono text-xs font-medium\">HTTP-POST</span>\n                  </div>\n                  <div>\n                    <span className=\"text-muted-foreground block text-xs\">Signing Algorithm</span>\n                    <span className=\"text-foreground font-mono text-xs font-medium\">RSA-SHA256</span>\n                  </div>\n                  <div>\n                    <span className=\"text-muted-foreground block text-xs\">Assertion Encryption</span>\n                    <span className=\"text-foreground font-mono text-xs font-medium\">Optional (AES-256-GCM)</span>\n                  </div>\n                </div>\n              </div>\n\n              <Separator />\n\n              {/* SP Public Certificate */}\n              <div className=\"space-y-2\">\n                <div className=\"flex items-center justify-between\">\n                  <label className=\"text-foreground text-xs font-medium\">SP X.509 Public Certificate</label>\n                  <div className=\"flex items-center gap-1.5\">\n                    <Button\n                      variant=\"ghost\"\n                      size=\"sm\"\n                      className=\"text-muted-foreground hover:text-foreground h-6 px-2 text-xs\"\n                      onClick={() => copyText(spCertificatePem, 'sp-cert')}\n                    >\n                      {copiedKey === 'sp-cert' ? (\n                        <Check className=\"text-success mr-1 size-3\" />\n                      ) : (\n                        <Copy className=\"mr-1 size-3\" />\n                      )}\n                      <span>{copiedKey === 'sp-cert' ? 'Copied' : 'Copy PEM'}</span>\n                    </Button>\n                    <Button\n                      aria-label=\"Download attachment\"\n                      variant=\"outline\"\n                      size=\"sm\"\n                      className=\"h-6 gap-1 px-2 text-xs\"\n                      onClick={downloadSpCertificate}\n                    >\n                      <Download className=\"size-3\" />\n                      <span>Download .crt</span>\n                    </Button>\n                  </div>\n                </div>\n\n                <pre className=\"border-border bg-muted/40 text-foreground max-h-[140px] overflow-x-auto rounded-md border p-3 font-mono text-xs leading-relaxed select-all\">\n                  <code>{spCertificatePem}</code>\n                </pre>\n                <p className=\"text-muted-foreground text-xs\">\n                  Import this certificate into your IdP if assertion signing or encryption is required.\n                </p>\n              </div>\n            </CardContent>\n\n            <CardFooter className=\"border-border text-muted-foreground flex items-center justify-between border-t pt-3 text-xs\">\n              <span className=\"flex items-center gap-1.5\">\n                <FileCode className=\"size-3.5\" />\n                <span>SP Metadata XML Endpoint</span>\n              </span>\n              <Button\n                variant=\"ghost\"\n                size=\"sm\"\n                className=\"text-primary hover:text-primary/80 h-6 gap-1 px-2 text-xs\"\n                onClick={() => copyText(spMetadataXmlUrl, 'meta-url')}\n              >\n                <span>{copiedKey === 'meta-url' ? 'Copied URL' : 'Copy metadata.xml URL'}</span>\n                <ExternalLink className=\"size-3\" />\n              </Button>\n            </CardFooter>\n          </Card>\n        </div>\n\n        {/* Right Column: Identity Provider (IdP) Metadata Form */}\n        <div className=\"space-y-6 lg:col-span-6\">\n          <Card className=\"border-border bg-card shadow-xs\">\n            <CardHeader className=\"pb-4\">\n              <div className=\"flex items-center justify-between\">\n                <div className=\"flex items-center gap-2\">\n                  <div className=\"bg-primary/10 text-primary flex size-7 items-center justify-center rounded-md\">\n                    <Lock className=\"size-4\" />\n                  </div>\n                  <div>\n                    <CardTitle className=\"text-sm font-semibold\">Identity Provider (IdP) Metadata</CardTitle>\n                    <CardDescription className=\"text-xs\">\n                      Configure SAML endpoints and credentials provided by {currentPreset.name}\n                    </CardDescription>\n                  </div>\n                </div>\n                <Badge variant=\"secondary\" className=\"font-mono text-xs\">\n                  {currentPreset.name}\n                </Badge>\n              </div>\n            </CardHeader>\n\n            <CardContent className=\"space-y-4 pt-0\">\n              {/* XML Upload Dropzone */}\n              <div\n                className={cn(\n                  'border-border relative flex cursor-pointer flex-col items-center justify-center rounded-xl border border-dashed p-4 text-center transition-colors',\n                  isDraggingXml\n                    ? 'border-primary bg-primary/10'\n                    : 'bg-muted/20 hover:border-primary/50 hover:bg-muted/40',\n                )}\n                onDragOver={(e) => {\n                  e.preventDefault()\n                  setIsDraggingXml(true)\n                }}\n                onDragLeave={() => setIsDraggingXml(false)}\n                onDrop={(e) => {\n                  e.preventDefault()\n                  setIsDraggingXml(false)\n                  simulateXmlUpload()\n                }}\n                onClick={simulateXmlUpload}\n              >\n                <div className=\"bg-primary/10 text-primary mb-2 grid size-9 place-items-center rounded-full\">\n                  <UploadCloud className=\"size-4\" />\n                </div>\n                <p className=\"text-foreground text-xs font-semibold\">\n                  Drag & drop IdP <span className=\"font-mono\">metadata.xml</span> to auto-fill\n                </p>\n                <p className=\"text-muted-foreground mt-0.5 text-xs\">\n                  Or click here to simulate parsing your Identity Provider metadata file\n                </p>\n              </div>\n\n              {/* XML Notice */}\n              {xmlUploadedNotice && (\n                <div className=\"border-success/30 bg-success/10 text-success flex items-center gap-2 rounded-lg border p-2.5 text-xs\">\n                  <CheckCircle2 className=\"size-4 shrink-0\" />\n                  <span>Parsed SSO URL, Entity ID, and X.509 Certificate from metadata XML.</span>\n                </div>\n              )}\n\n              {/* IdP SSO URL */}\n              <div className=\"space-y-1.5\">\n                <label htmlFor=\"idp-sso-url-react\" className=\"text-foreground text-xs font-medium\">\n                  IdP Single Sign-On (SSO) URL\n                </label>\n                <Input\n                  id=\"idp-sso-url-react\"\n                  value={idpSsoUrl}\n                  onChange={(e) => setIdpSsoUrl(e.target.value)}\n                  placeholder=\"https://company.okta.com/app/sso/saml\"\n                  className=\"font-mono text-xs\"\n                />\n                <p className=\"text-muted-foreground text-xs\">\n                  The HTTP-POST endpoint at your IdP where users are redirected for authentication.\n                </p>\n              </div>\n\n              {/* IdP Entity ID / Issuer */}\n              <div className=\"space-y-1.5\">\n                <label htmlFor=\"idp-entity-id-react\" className=\"text-foreground text-xs font-medium\">\n                  IdP Entity ID / Issuer URI\n                </label>\n                <Input\n                  id=\"idp-entity-id-react\"\n                  value={idpEntityId}\n                  onChange={(e) => setIdpEntityId(e.target.value)}\n                  placeholder=\"http://www.okta.com/exk849201\"\n                  className=\"font-mono text-xs\"\n                />\n                <p className=\"text-muted-foreground text-xs\">\n                  The unique issuer string provided in your IdP metadata document.\n                </p>\n              </div>\n\n              {/* X.509 Certificate PEM Textarea */}\n              <div className=\"space-y-1.5\">\n                <div className=\"flex items-center justify-between\">\n                  <label htmlFor=\"idp-cert-pem-react\" className=\"text-foreground text-xs font-medium\">\n                    IdP X.509 Signing Certificate (PEM)\n                  </label>\n                  <Badge variant=\"outline\" className=\"border-success/40 text-success font-mono text-xs\">\n                    Valid (Expires Oct 2028)\n                  </Badge>\n                </div>\n                <Textarea\n                  id=\"idp-cert-pem-react\"\n                  value={idpCertPem}\n                  onValueChange={setIdpCertPem}\n                  rows={5}\n                  noResize\n                  className=\"border-border/70 font-mono text-xs leading-relaxed\"\n                  placeholder=\"-----BEGIN CERTIFICATE-----...\"\n                />\n                <p className=\"text-muted-foreground text-xs\">\n                  Public X.509 certificate used by our SP to verify the cryptographic signature on SAML assertions.\n                </p>\n              </div>\n\n              <Separator />\n\n              {/* Domain Enforcement Switch */}\n              <div className=\"border-border bg-muted/20 flex items-start justify-between gap-3 rounded-lg border p-3\">\n                <div className=\"space-y-0.5\">\n                  <div className=\"flex items-center gap-1.5\">\n                    <ShieldAlert className=\"text-primary size-4\" />\n                    <p className=\"text-foreground text-xs font-semibold\">Enforce SSO for all domain emails</p>\n                  </div>\n                  <p className=\"text-muted-foreground text-xs\">\n                    Require all users with <span className=\"text-foreground font-mono font-medium\">@company.com</span>{' '}\n                    email addresses to log in via SSO. Password logins will be blocked.\n                  </p>\n                </div>\n                <Switch\n                  checked={enforceDomain}\n                  onCheckedChange={setEnforceDomain}\n                  className=\"mt-1\"\n                  aria-label=\"Enforce SSO for domain\"\n                />\n              </div>\n            </CardContent>\n\n            <CardFooter className=\"border-border flex flex-wrap items-center justify-between gap-2 border-t pt-4\">\n              <Button\n                variant=\"ghost\"\n                size=\"sm\"\n                className=\"text-muted-foreground hover:text-foreground text-xs\"\n                onClick={() => handleSelectPreset(selectedPresetId)}\n              >\n                Reset to Defaults\n              </Button>\n              <Button\n                size=\"sm\"\n                className=\"gap-1.5 text-xs font-medium shadow-xs\"\n                disabled={isSaving || !idpSsoUrl.trim() || !idpEntityId.trim()}\n                onClick={handleSaveConfig}\n              >\n                {isSaving ? <RotateCw className=\"size-3.5 animate-spin\" /> : <Save className=\"size-3.5\" />}\n                <span>{isSaving ? 'Saving...' : 'Save SSO Configuration'}</span>\n              </Button>\n            </CardFooter>\n          </Card>\n        </div>\n      </div>\n\n      {/* Test SAML Login Diagnostic Dialog */}\n      <Dialog open={testModalOpen} onOpenChange={setTestModalOpen}>\n        <DialogContent className=\"sm:max-w-xl\">\n          <DialogHeader>\n            <div className=\"flex items-center gap-2\">\n              <div className=\"bg-primary/10 text-primary flex size-8 items-center justify-center rounded-lg\">\n                <UserCheck className=\"size-4\" />\n              </div>\n              <div>\n                <DialogTitle>SAML 2.0 Authentication Diagnostic</DialogTitle>\n                <DialogDescription>Live assertion handshake simulation with {currentPreset.name}</DialogDescription>\n              </div>\n            </div>\n          </DialogHeader>\n\n          <div className=\"space-y-4 py-2\">\n            {/* Handshake Status Banner */}\n            <div className=\"border-success/30 bg-success/10 text-success flex items-center justify-between rounded-lg border p-3 text-xs\">\n              <div className=\"flex items-center gap-2\">\n                <CheckCircle2 className=\"size-4 shrink-0\" />\n                <div>\n                  <p className=\"font-semibold\">HTTP 200 OK — SAML Handshake Validated</p>\n                  <p className=\"text-xs opacity-90\">All signature envelopes matched X.509 certificate</p>\n                </div>\n              </div>\n              <Badge variant=\"success\" className=\"font-mono text-xs\">\n                Success\n              </Badge>\n            </div>\n\n            {/* Step Verification Checklist */}\n            <div className=\"border-border bg-muted/20 space-y-2 rounded-lg border p-3 text-xs\">\n              <h4 className=\"text-foreground font-semibold\">Verification Pipeline</h4>\n              <div className=\"space-y-1.5\">\n                <div className=\"text-foreground flex items-center gap-2\">\n                  <Check className=\"text-success size-3.5 shrink-0\" />\n                  <span>\n                    1. AuthnRequest dispatched with SP signature to{' '}\n                    <code className=\"font-mono text-xs\">{idpSsoUrl}</code>\n                  </span>\n                </div>\n                <div className=\"text-foreground flex items-center gap-2\">\n                  <Check className=\"text-success size-3.5 shrink-0\" />\n                  <span>2. SAMLResponse assertion received and verified with RSA-SHA256 signature</span>\n                </div>\n                <div className=\"text-foreground flex items-center gap-2\">\n                  <Check className=\"text-success size-3.5 shrink-0\" />\n                  <span>\n                    3. AudienceRestriction matched <code className=\"font-mono text-xs\">{spEntityId}</code>\n                  </span>\n                </div>\n                <div className=\"text-foreground flex items-center gap-2\">\n                  <Check className=\"text-success size-3.5 shrink-0\" />\n                  <span>4. Assertion timestamp valid within 300s clock-skew tolerance window</span>\n                </div>\n              </div>\n            </div>\n\n            {/* Asserted Claims Table */}\n            <div className=\"space-y-1.5\">\n              <h4 className=\"text-foreground text-xs font-semibold\">Asserted Identity Claims & Attributes</h4>\n              <div className=\"border-border bg-muted/10 overflow-hidden rounded-md border text-xs\">\n                <table className=\"w-full\">\n                  <thead>\n                    <tr className=\"border-border bg-muted/40 text-muted-foreground border-b text-left font-medium\">\n                      <th className=\"p-2 text-xs\">Field</th>\n                      <th className=\"p-2 text-xs\">Sample Claim Value</th>\n                    </tr>\n                  </thead>\n                  <tbody className=\"divide-border divide-y font-mono text-xs\">\n                    {simulatedClaims.map((claim) => (\n                      <tr key={claim.mappedField} className=\"hover:bg-muted/20\">\n                        <td className=\"text-primary p-2 font-semibold\">{claim.mappedField}</td>\n                        <td className=\"text-foreground max-w-[240px] truncate p-2\">{claim.sampleValue}</td>\n                      </tr>\n                    ))}\n                  </tbody>\n                </table>\n              </div>\n            </div>\n          </div>\n\n          <DialogFooter>\n            <Button variant=\"outline\" size=\"sm\" onClick={() => setTestModalOpen(false)}>\n              Close\n            </Button>\n            <Button size=\"sm\" className=\"gap-1.5\" onClick={openTestModal}>\n              <RotateCw className=\"size-3.5\" />\n              <span>Re-test Handshake</span>\n            </Button>\n          </DialogFooter>\n        </DialogContent>\n      </Dialog>\n    </div>\n  )\n}\n\nexport default SsoIdentityProviderConfig\n",
      "type": "registry:block",
      "target": "~/components/blocks/SsoIdentityProviderConfig.tsx"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/dialog.json",
    "https://uipkge.dev/r/react/input.json",
    "https://uipkge.dev/r/react/separator.json",
    "https://uipkge.dev/r/react/switch.json",
    "https://uipkge.dev/r/react/textarea.json"
  ],
  "description": "Enterprise Single Sign-On (SAML 2.0 / OIDC) identity provider configuration wizard with IdP preset picker, SP credentials, XML metadata dropzone, X.509 cert PEM validator, domain enforcement switch, and interactive SAML test runner.",
  "categories": [
    "security",
    "app",
    "form",
    "dashboard"
  ]
}