@clerk/ui 1.34.0-snapshot.v20260921144734 → 1.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ClerkUI.js +2 -2
- package/dist/components/OAuthConsent/OAuthConsent.js +1 -1
- package/dist/components/OAuthConsent/OAuthConsent.js.map +1 -1
- package/dist/components/OAuthDeviceVerification/OAuthDeviceVerification.js +1 -1
- package/dist/components/OAuthDeviceVerification/OAuthDeviceVerification.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/no-rhc/ClerkUI.js +2 -2
- package/dist/no-rhc/components/OAuthConsent/OAuthConsent.js +1 -1
- package/dist/no-rhc/components/OAuthConsent/OAuthConsent.js.map +1 -1
- package/dist/no-rhc/components/OAuthDeviceVerification/OAuthDeviceVerification.js +1 -1
- package/dist/no-rhc/components/OAuthDeviceVerification/OAuthDeviceVerification.js.map +1 -1
- package/dist/no-rhc/index.js +1 -1
- package/dist/{oauthConsent_ui_d32e72_1.34.0-snapshot.v20260921144734.js → oauthConsent_ui_00a7e6_1.34.0.js} +1 -1
- package/dist/{oauthConsent_ui_44eded_1.34.0-snapshot.v20260921144734.js → oauthConsent_ui_ae6e8a_1.34.0.js} +1 -1
- package/dist/{oauthConsent_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → oauthConsent_ui_de828c_1.34.0.js} +1 -1
- package/dist/{oauthDeviceVerification_ui_d32e72_1.34.0-snapshot.v20260921144734.js → oauthDeviceVerification_ui_00a7e6_1.34.0.js} +1 -1
- package/dist/{oauthDeviceVerification_ui_44eded_1.34.0-snapshot.v20260921144734.js → oauthDeviceVerification_ui_ae6e8a_1.34.0.js} +1 -1
- package/dist/{oauthDeviceVerification_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → oauthDeviceVerification_ui_de828c_1.34.0.js} +1 -1
- package/dist/server.js +1 -1
- package/dist/ui.browser.js +5 -5
- package/dist/ui.legacy.browser.js +1 -1
- package/dist/ui.shared.browser.js +2 -2
- package/package.json +3 -3
- /package/dist/{3736_ui_d32e72_1.34.0-snapshot.v20260921144734.js → 3736_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{3736_ui_44eded_1.34.0-snapshot.v20260921144734.js → 3736_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{3736_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → 3736_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{4424_ui_d32e72_1.34.0-snapshot.v20260921144734.js → 4424_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{4424_ui_44eded_1.34.0-snapshot.v20260921144734.js → 4424_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{4424_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → 4424_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{6206_ui_d32e72_1.34.0-snapshot.v20260921144734.js → 6206_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{6206_ui_44eded_1.34.0-snapshot.v20260921144734.js → 6206_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{6206_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → 6206_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{6678_ui_d32e72_1.34.0-snapshot.v20260921144734.js → 6678_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{6678_ui_44eded_1.34.0-snapshot.v20260921144734.js → 6678_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{6678_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → 6678_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{8316_ui_d32e72_1.34.0-snapshot.v20260921144734.js → 8316_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{8316_ui_44eded_1.34.0-snapshot.v20260921144734.js → 8316_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{8316_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → 8316_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{8746_ui_d32e72_1.34.0-snapshot.v20260921144734.js → 8746_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{8746_ui_44eded_1.34.0-snapshot.v20260921144734.js → 8746_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{8746_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → 8746_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{9036_ui_d32e72_1.34.0-snapshot.v20260921144734.js → 9036_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{9036_ui_44eded_1.34.0-snapshot.v20260921144734.js → 9036_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{9036_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → 9036_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{9419_ui_d32e72_1.34.0-snapshot.v20260921144734.js → 9419_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{9419_ui_44eded_1.34.0-snapshot.v20260921144734.js → 9419_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{9419_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → 9419_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{980_ui_d32e72_1.34.0-snapshot.v20260921144734.js → 980_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{980_ui_44eded_1.34.0-snapshot.v20260921144734.js → 980_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{980_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → 980_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{apiKeys_ui_d32e72_1.34.0-snapshot.v20260921144734.js → apiKeys_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{apiKeys_ui_44eded_1.34.0-snapshot.v20260921144734.js → apiKeys_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{apiKeys_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → apiKeys_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{blankcaptcha_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → blankcaptcha_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{blankcaptcha_ui_44eded_1.34.0-snapshot.v20260921144734.js → blankcaptcha_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{blankcaptcha_ui_d32e72_1.34.0-snapshot.v20260921144734.js → blankcaptcha_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{checkout_ui_d32e72_1.34.0-snapshot.v20260921144734.js → checkout_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{checkout_ui_44eded_1.34.0-snapshot.v20260921144734.js → checkout_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{checkout_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → checkout_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{configureDirectorySync_ui_d32e72_1.34.0-snapshot.v20260921144734.js → configureDirectorySync_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{configureDirectorySync_ui_44eded_1.34.0-snapshot.v20260921144734.js → configureDirectorySync_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{configureDirectorySync_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → configureDirectorySync_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{configureSSO_ui_d32e72_1.34.0-snapshot.v20260921144734.js → configureSSO_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{configureSSO_ui_44eded_1.34.0-snapshot.v20260921144734.js → configureSSO_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{configureSSO_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → configureSSO_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{copy-api-key-modal_ui_d32e72_1.34.0-snapshot.v20260921144734.js → copy-api-key-modal_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{copy-api-key-modal_ui_44eded_1.34.0-snapshot.v20260921144734.js → copy-api-key-modal_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{copy-api-key-modal_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → copy-api-key-modal_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{createorganization_ui_d32e72_1.34.0-snapshot.v20260921144734.js → createorganization_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{createorganization_ui_44eded_1.34.0-snapshot.v20260921144734.js → createorganization_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{createorganization_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → createorganization_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{credit-history-page_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → credit-history-page_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{credit-history-page_ui_44eded_1.34.0-snapshot.v20260921144734.js → credit-history-page_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{credit-history-page_ui_d32e72_1.34.0-snapshot.v20260921144734.js → credit-history-page_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{enableOrganizationsPrompt_ui_d32e72_1.34.0-snapshot.v20260921144734.js → enableOrganizationsPrompt_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{enableOrganizationsPrompt_ui_44eded_1.34.0-snapshot.v20260921144734.js → enableOrganizationsPrompt_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{enableOrganizationsPrompt_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → enableOrganizationsPrompt_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{framework_ui_44eded_1.34.0-snapshot.v20260921144734.js → framework_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{framework_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → framework_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{impersonationfab_ui_d32e72_1.34.0-snapshot.v20260921144734.js → impersonationfab_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{impersonationfab_ui_44eded_1.34.0-snapshot.v20260921144734.js → impersonationfab_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{impersonationfab_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → impersonationfab_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{invitemembers_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → invitemembers_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{invitemembers_ui_44eded_1.34.0-snapshot.v20260921144734.js → invitemembers_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{invitemembers_ui_d32e72_1.34.0-snapshot.v20260921144734.js → invitemembers_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{keylessPrompt_ui_d32e72_1.34.0-snapshot.v20260921144734.js → keylessPrompt_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{keylessPrompt_ui_44eded_1.34.0-snapshot.v20260921144734.js → keylessPrompt_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{keylessPrompt_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → keylessPrompt_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{onetap_ui_d32e72_1.34.0-snapshot.v20260921144734.js → onetap_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{onetap_ui_44eded_1.34.0-snapshot.v20260921144734.js → onetap_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{onetap_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → onetap_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{op-api-keys-page_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → op-api-keys-page_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{op-api-keys-page_ui_44eded_1.34.0-snapshot.v20260921144734.js → op-api-keys-page_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{op-api-keys-page_ui_d32e72_1.34.0-snapshot.v20260921144734.js → op-api-keys-page_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{op-billing-page_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → op-billing-page_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{op-billing-page_ui_44eded_1.34.0-snapshot.v20260921144734.js → op-billing-page_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{op-billing-page_ui_d32e72_1.34.0-snapshot.v20260921144734.js → op-billing-page_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{op-plans-page_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → op-plans-page_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{op-plans-page_ui_44eded_1.34.0-snapshot.v20260921144734.js → op-plans-page_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{op-plans-page_ui_d32e72_1.34.0-snapshot.v20260921144734.js → op-plans-page_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{op-security-page_ui_d32e72_1.34.0-snapshot.v20260921144734.js → op-security-page_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{op-security-page_ui_44eded_1.34.0-snapshot.v20260921144734.js → op-security-page_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{op-security-page_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → op-security-page_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{organizationlist_ui_d32e72_1.34.0-snapshot.v20260921144734.js → organizationlist_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{organizationlist_ui_44eded_1.34.0-snapshot.v20260921144734.js → organizationlist_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{organizationlist_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → organizationlist_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{organizationprofile_ui_d32e72_1.34.0-snapshot.v20260921144734.js → organizationprofile_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{organizationprofile_ui_44eded_1.34.0-snapshot.v20260921144734.js → organizationprofile_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{organizationprofile_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → organizationprofile_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{organizationswitcher_ui_d32e72_1.34.0-snapshot.v20260921144734.js → organizationswitcher_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{organizationswitcher_ui_44eded_1.34.0-snapshot.v20260921144734.js → organizationswitcher_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{organizationswitcher_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → organizationswitcher_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{payment-attempt-page_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → payment-attempt-page_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{payment-attempt-page_ui_44eded_1.34.0-snapshot.v20260921144734.js → payment-attempt-page_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{payment-attempt-page_ui_d32e72_1.34.0-snapshot.v20260921144734.js → payment-attempt-page_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{planDetails_ui_d32e72_1.34.0-snapshot.v20260921144734.js → planDetails_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{planDetails_ui_44eded_1.34.0-snapshot.v20260921144734.js → planDetails_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{planDetails_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → planDetails_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{prefetchorganizationlist_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → prefetchorganizationlist_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{prefetchorganizationlist_ui_44eded_1.34.0-snapshot.v20260921144734.js → prefetchorganizationlist_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{prefetchorganizationlist_ui_d32e72_1.34.0-snapshot.v20260921144734.js → prefetchorganizationlist_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{pricingTable_ui_d32e72_1.34.0-snapshot.v20260921144734.js → pricingTable_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{pricingTable_ui_44eded_1.34.0-snapshot.v20260921144734.js → pricingTable_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{pricingTable_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → pricingTable_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{revoke-api-key-modal_ui_d32e72_1.34.0-snapshot.v20260921144734.js → revoke-api-key-modal_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{revoke-api-key-modal_ui_44eded_1.34.0-snapshot.v20260921144734.js → revoke-api-key-modal_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{revoke-api-key-modal_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → revoke-api-key-modal_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{sessionTasks_ui_d32e72_1.34.0-snapshot.v20260921144734.js → sessionTasks_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{sessionTasks_ui_44eded_1.34.0-snapshot.v20260921144734.js → sessionTasks_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{sessionTasks_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → sessionTasks_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{signin_ui_d32e72_1.34.0-snapshot.v20260921144734.js → signin_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{signin_ui_44eded_1.34.0-snapshot.v20260921144734.js → signin_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{signin_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → signin_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{signup_ui_d32e72_1.34.0-snapshot.v20260921144734.js → signup_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{signup_ui_44eded_1.34.0-snapshot.v20260921144734.js → signup_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{signup_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → signup_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{statement-page_ui_d32e72_1.34.0-snapshot.v20260921144734.js → statement-page_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{statement-page_ui_44eded_1.34.0-snapshot.v20260921144734.js → statement-page_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{statement-page_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → statement-page_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{subscriptionDetails_ui_d32e72_1.34.0-snapshot.v20260921144734.js → subscriptionDetails_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{subscriptionDetails_ui_44eded_1.34.0-snapshot.v20260921144734.js → subscriptionDetails_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{subscriptionDetails_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → subscriptionDetails_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{taskChooseOrganization_ui_d32e72_1.34.0-snapshot.v20260921144734.js → taskChooseOrganization_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{taskChooseOrganization_ui_44eded_1.34.0-snapshot.v20260921144734.js → taskChooseOrganization_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{taskChooseOrganization_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → taskChooseOrganization_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{taskResetPassword_ui_d32e72_1.34.0-snapshot.v20260921144734.js → taskResetPassword_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{taskResetPassword_ui_44eded_1.34.0-snapshot.v20260921144734.js → taskResetPassword_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{taskResetPassword_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → taskResetPassword_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{taskSetupMFA_ui_d32e72_1.34.0-snapshot.v20260921144734.js → taskSetupMFA_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{taskSetupMFA_ui_44eded_1.34.0-snapshot.v20260921144734.js → taskSetupMFA_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{taskSetupMFA_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → taskSetupMFA_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{ui-common_ui_d32e72_1.34.0-snapshot.v20260921144734.js → ui-common_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{ui-common_ui_44eded_1.34.0-snapshot.v20260921144734.js → ui-common_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{ui-common_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → ui-common_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{up-api-keys-page_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → up-api-keys-page_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{up-api-keys-page_ui_44eded_1.34.0-snapshot.v20260921144734.js → up-api-keys-page_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{up-api-keys-page_ui_d32e72_1.34.0-snapshot.v20260921144734.js → up-api-keys-page_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{up-billing-page_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → up-billing-page_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{up-billing-page_ui_44eded_1.34.0-snapshot.v20260921144734.js → up-billing-page_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{up-billing-page_ui_d32e72_1.34.0-snapshot.v20260921144734.js → up-billing-page_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{up-plans-page_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → up-plans-page_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{up-plans-page_ui_44eded_1.34.0-snapshot.v20260921144734.js → up-plans-page_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{up-plans-page_ui_d32e72_1.34.0-snapshot.v20260921144734.js → up-plans-page_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{useravatar_ui_d32e72_1.34.0-snapshot.v20260921144734.js → useravatar_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{useravatar_ui_44eded_1.34.0-snapshot.v20260921144734.js → useravatar_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{useravatar_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → useravatar_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{userbutton_ui_d32e72_1.34.0-snapshot.v20260921144734.js → userbutton_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{userbutton_ui_44eded_1.34.0-snapshot.v20260921144734.js → userbutton_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{userbutton_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → userbutton_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{userprofile_ui_d32e72_1.34.0-snapshot.v20260921144734.js → userprofile_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{userprofile_ui_44eded_1.34.0-snapshot.v20260921144734.js → userprofile_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{userprofile_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → userprofile_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{userverification_ui_d32e72_1.34.0-snapshot.v20260921144734.js → userverification_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{userverification_ui_44eded_1.34.0-snapshot.v20260921144734.js → userverification_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{userverification_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → userverification_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{vendors_ui_d32e72_1.34.0-snapshot.v20260921144734.js → vendors_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{vendors_ui_44eded_1.34.0-snapshot.v20260921144734.js → vendors_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{vendors_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → vendors_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{waitlist_ui_d32e72_1.34.0-snapshot.v20260921144734.js → waitlist_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{waitlist_ui_44eded_1.34.0-snapshot.v20260921144734.js → waitlist_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{waitlist_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → waitlist_ui_de828c_1.34.0.js} +0 -0
- /package/dist/{web3-solana-wallet-buttons_ui_d32e72_1.34.0-snapshot.v20260921144734.js → web3-solana-wallet-buttons_ui_00a7e6_1.34.0.js} +0 -0
- /package/dist/{web3-solana-wallet-buttons_ui_44eded_1.34.0-snapshot.v20260921144734.js → web3-solana-wallet-buttons_ui_ae6e8a_1.34.0.js} +0 -0
- /package/dist/{web3-solana-wallet-buttons_ui_30c7f0_1.34.0-snapshot.v20260921144734.js → web3-solana-wallet-buttons_ui_de828c_1.34.0.js} +0 -0
package/dist/ClerkUI.js
CHANGED
|
@@ -22,8 +22,8 @@ import { isVersionAtLeast, parseVersion } from "@clerk/shared/versionCheck";
|
|
|
22
22
|
* @public
|
|
23
23
|
*/
|
|
24
24
|
var ClerkUI = class ClerkUI {
|
|
25
|
-
static version = "1.34.0
|
|
26
|
-
version = "1.34.0
|
|
25
|
+
static version = "1.34.0";
|
|
26
|
+
version = "1.34.0";
|
|
27
27
|
#componentRenderer;
|
|
28
28
|
/**
|
|
29
29
|
* Creates a new `ClerkUI` instance and mounts the internal component renderer.
|
|
@@ -160,7 +160,7 @@ function _OAuthConsent() {
|
|
|
160
160
|
value: effectiveOrg,
|
|
161
161
|
onChange: setSelectedOrg
|
|
162
162
|
}),
|
|
163
|
-
/* @__PURE__ */ jsxs(ListGroup, { children: [/* @__PURE__ */ jsx(ListGroupHeader, { children: /* @__PURE__ */ jsx(ListGroupHeaderTitle, { localizationKey: localizationKeys("oauthConsent.scopeList.title", { applicationName: oauthApplicationName }) }) }), /* @__PURE__ */ jsx(ListGroupContent, { children: displayedScopes.map((item) => /* @__PURE__ */ jsx(ListGroupItem, { children: /* @__PURE__ */ jsx(ListGroupItemLabel, { children: item.description || item.scope || "" }) }, item.scope)) })] }),
|
|
163
|
+
displayedScopes.length > 0 && /* @__PURE__ */ jsxs(ListGroup, { children: [/* @__PURE__ */ jsx(ListGroupHeader, { children: /* @__PURE__ */ jsx(ListGroupHeaderTitle, { localizationKey: localizationKeys("oauthConsent.scopeList.title", { applicationName: oauthApplicationName }) }) }), /* @__PURE__ */ jsx(ListGroupContent, { children: displayedScopes.map((item) => /* @__PURE__ */ jsx(ListGroupItem, { children: /* @__PURE__ */ jsx(ListGroupItemLabel, { children: item.description || item.scope || "" }) }, item.scope)) })] }),
|
|
164
164
|
/* @__PURE__ */ jsx(Alert, {
|
|
165
165
|
colorScheme: "warning",
|
|
166
166
|
children: /* @__PURE__ */ jsx(Text, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OAuthConsent.js","names":[],"sources":["../../../src/components/OAuthConsent/OAuthConsent.tsx"],"sourcesContent":["import { useClerk, useOAuthConsent, useUser } from '@clerk/shared/react';\nimport { useState } from 'react';\n\nimport { useEnvironment, useOAuthConsentContext, withCoreUserGuard } from '@/ui/contexts';\nimport { Box, Button, Flow, Grid, localizationKeys, Text, useLocalizations } from '@/ui/customizables';\nimport { ApplicationLogo } from '@/ui/elements/ApplicationLogo';\nimport { Card } from '@/ui/elements/Card';\nimport { withCardStateProvider } from '@/ui/elements/contexts';\nimport { Header } from '@/ui/elements/Header';\nimport { LoadingCardContainer } from '@/ui/elements/LoadingCard';\nimport { Modal } from '@/ui/elements/Modal';\nimport { Alert, Textarea } from '@/ui/primitives';\nimport { Route, Switch } from '@/ui/router';\n\nimport { InlineAction } from './InlineAction';\nimport { getKnownOAuthClient } from './knownClients';\nimport {\n ListGroup,\n ListGroupContent,\n ListGroupHeader,\n ListGroupHeaderTitle,\n ListGroupItem,\n ListGroupItemLabel,\n} from './ListGroup';\nimport { LogoGroup, LogoGroupIcon, LogoGroupItem, LogoGroupItemContainer, LogoGroupSeparator } from './LogoGroup';\nimport { OrgSelect } from './OrgSelect';\nimport { getForwardedParams, getOAuthConsentFromSearch, getRedirectDisplay, getRedirectUriFromSearch } from './utils';\n\nconst OFFLINE_ACCESS_SCOPE = 'offline_access';\nconst PRIVATE_METADATA_SCOPE = 'private_metadata';\nconst USER_ORG_READ_SCOPE = 'user:org:read';\n\nfunction _OAuthConsent() {\n const ctx = useOAuthConsentContext();\n const clerk = useClerk();\n const { user } = useUser();\n const {\n displayConfig: { applicationName, logoImageUrl },\n organizationSettings,\n } = useEnvironment();\n const [isUriModalOpen, setIsUriModalOpen] = useState(false);\n\n const [selectedOrg, setSelectedOrg] = useState<string | null>(null);\n\n // onAllow and onDeny are always provided as a pair by the accounts portal.\n const hasContextCallbacks = Boolean(ctx.onAllow || ctx.onDeny);\n\n // Resolve oauthClientId and scope once: context overrides URL fallback.\n const fromUrl = getOAuthConsentFromSearch();\n const oauthClientId = ctx.oauthClientId ?? fromUrl.oauthClientId;\n const scope = ctx.scope ?? fromUrl.scope;\n\n // Public path: fetch via hook. Disabled on the accounts portal path\n // (which already has all data via context) to avoid a wasted FAPI request.\n const redirectUri = ctx.redirectUrl ?? getRedirectUriFromSearch();\n const { data, isLoading, error } = useOAuthConsent({\n oauthClientId,\n scope,\n redirectUri: redirectUri || undefined,\n // TODO: Remove this once account portal is refactored to use this component\n enabled: !hasContextCallbacks,\n });\n\n // Hook returns camelCase `requiresConsent`; the render logic uses snake_case.\n const mappedHookScopes = data?.scopes?.map(s => ({\n scope: s.scope,\n description: s.description,\n requires_consent: s.requiresConsent,\n }));\n\n // Context (accounts portal path) wins over hook data (public path).\n const scopes = ctx.scopes ?? mappedHookScopes ?? [];\n const oauthApplicationName = ctx.oauthApplicationName ?? data?.oauthApplicationName ?? '';\n const oauthApplicationLogoUrl = ctx.oauthApplicationLogoUrl ?? data?.oauthApplicationLogoUrl;\n const oauthApplicationUrl = ctx.oauthApplicationUrl ?? data?.oauthApplicationUrl;\n const redirectUrl = ctx.redirectUrl ?? redirectUri;\n\n const hasOrgReadScope = scopes.some(s => s.scope === USER_ORG_READ_SCOPE);\n const orgSelectionEnabled = !!(hasOrgReadScope && organizationSettings.enabled);\n const orgOptions = orgSelectionEnabled\n ? (user?.organizationMemberships ?? []).map(m => ({\n value: m.organization.id,\n label: m.organization.name,\n logoUrl: m.organization.imageUrl,\n }))\n : [];\n const lastActiveOrgId = clerk.session?.lastActiveOrganizationId;\n const defaultOrg = orgOptions.find(o => o.value === lastActiveOrgId)?.value ?? orgOptions[0]?.value ?? null;\n const effectiveOrg = selectedOrg ?? defaultOrg;\n\n const { t } = useLocalizations();\n const domainAction = data?.redirectDomain ?? getRedirectDisplay(redirectUrl);\n const viewFullUrlText = t(localizationKeys('oauthConsent.viewFullUrl'));\n\n // When the OAuth app has no uploaded logo, fall back to a recognized client's\n // brand mark (Claude, ChatGPT, ...). Keyed on the trusted redirect domain, not\n // the app-owner-set name, so a look-alike name cannot borrow the branding.\n const knownClient = oauthApplicationLogoUrl ? undefined : getKnownOAuthClient(domainAction);\n\n // Error states only apply to the public flow.\n if (!hasContextCallbacks) {\n const errorMessage = !oauthClientId\n ? 'The client ID is missing.'\n : !redirectUrl\n ? 'The redirect URI is missing.'\n : error\n ? (error.message ?? 'Failed to load consent information.')\n : undefined;\n\n if (errorMessage) {\n return (\n <Card.Root>\n <Card.Content>\n <Card.Alert>{errorMessage}</Card.Alert>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n if (isLoading) {\n return (\n <Card.Root>\n <Card.Content>\n <LoadingCardContainer />\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n }\n\n const actionUrl = clerk.oauthApplication.buildConsentActionUrl({ clientId: oauthClientId });\n const forwardedParams = getForwardedParams();\n\n // Accounts portal path delegates to context callbacks; public path lets the form submit natively.\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n if (!hasContextCallbacks) {\n return;\n }\n e.preventDefault();\n const submitter = (e.nativeEvent as SubmitEvent).submitter as HTMLButtonElement | null;\n if (submitter?.value === 'true') {\n ctx.onAllow?.();\n } else {\n ctx.onDeny?.();\n }\n };\n\n const primaryIdentifier = user?.primaryEmailAddress?.emailAddress || user?.primaryPhoneNumber?.phoneNumber;\n\n const displayedScopes = scopes\n .filter(item => item.scope !== OFFLINE_ACCESS_SCOPE)\n .map(item => ({\n ...item,\n description:\n item.scope === PRIVATE_METADATA_SCOPE\n ? t(localizationKeys('oauthConsent.scopeList.privateMetadata', { applicationName }))\n : item.description,\n }));\n const hasOfflineAccess = scopes.some(item => item.scope === OFFLINE_ACCESS_SCOPE);\n\n return (\n <>\n <form\n method='POST'\n action={actionUrl}\n onSubmit={handleSubmit}\n >\n <Card.Root>\n <Card.Content>\n <Header.Root>\n {/* both have avatars */}\n {oauthApplicationLogoUrl && logoImageUrl && (\n <LogoGroup>\n <LogoGroupItem justify='end'>\n <LogoGroupItemContainer>\n <ApplicationLogo\n src={oauthApplicationLogoUrl}\n alt={oauthApplicationName}\n href={oauthApplicationUrl}\n isExternal\n />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n <LogoGroupSeparator />\n <LogoGroupItem justify='start'>\n <LogoGroupItemContainer>\n <ApplicationLogo />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n </LogoGroup>\n )}\n {/* only OAuth app has an avatar */}\n {oauthApplicationLogoUrl && !logoImageUrl && (\n <LogoGroup>\n <Box sx={{ position: 'relative' }}>\n <LogoGroupItemContainer>\n <ApplicationLogo\n src={oauthApplicationLogoUrl}\n alt={oauthApplicationName}\n href={oauthApplicationUrl}\n isExternal\n />\n </LogoGroupItemContainer>\n <LogoGroupItemContainer\n size='sm'\n sx={t => ({\n position: 'absolute',\n bottom: `calc(${t.space.$2x5} * -1)`,\n insetInlineEnd: `calc(${t.space.$2x5} * -1)`,\n })}\n >\n <LogoGroupIcon />\n </LogoGroupItemContainer>\n </Box>\n </LogoGroup>\n )}\n {/* only Clerk application has an avatar */}\n {!oauthApplicationLogoUrl && logoImageUrl && (\n <LogoGroup>\n <LogoGroupItem justify='end'>\n <LogoGroupItemContainer>\n <LogoGroupIcon\n icon={knownClient?.icon}\n iconSx={knownClient?.iconSx}\n label={knownClient?.name}\n />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n <LogoGroupSeparator />\n <LogoGroupItem justify='start'>\n <LogoGroupItemContainer>\n <ApplicationLogo />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n </LogoGroup>\n )}\n {/* no avatars */}\n {!oauthApplicationLogoUrl && !logoImageUrl && (\n <LogoGroup>\n <LogoGroupItemContainer>\n <LogoGroupIcon\n icon={knownClient?.icon}\n iconSx={knownClient?.iconSx}\n label={knownClient?.name}\n />\n </LogoGroupItemContainer>\n </LogoGroup>\n )}\n <Header.Title localizationKey={oauthApplicationName} />\n <Header.Subtitle\n localizationKey={localizationKeys('oauthConsent.subtitle', {\n applicationName,\n identifier: primaryIdentifier || '',\n })}\n />\n </Header.Root>\n {orgSelectionEnabled && orgOptions.length > 0 && effectiveOrg && (\n <OrgSelect\n options={orgOptions}\n value={effectiveOrg}\n onChange={setSelectedOrg}\n />\n )}\n <ListGroup>\n <ListGroupHeader>\n <ListGroupHeaderTitle\n localizationKey={localizationKeys('oauthConsent.scopeList.title', {\n applicationName: oauthApplicationName,\n })}\n />\n </ListGroupHeader>\n <ListGroupContent>\n {displayedScopes.map(item => (\n <ListGroupItem key={item.scope}>\n <ListGroupItemLabel>{item.description || item.scope || ''}</ListGroupItemLabel>\n </ListGroupItem>\n ))}\n </ListGroupContent>\n </ListGroup>\n <Alert colorScheme='warning'>\n <Text\n colorScheme='warning'\n variant='caption'\n >\n <InlineAction\n text={t(\n localizationKeys('oauthConsent.warning', {\n applicationName: oauthApplicationName || applicationName,\n domainAction,\n }),\n )}\n actionText={domainAction}\n onClick={() => setIsUriModalOpen(true)}\n tooltipText={viewFullUrlText}\n />\n </Text>\n </Alert>\n <Grid\n columns={2}\n gap={3}\n >\n <Button\n type='submit'\n name='consented'\n value='false'\n colorScheme='secondary'\n variant='outline'\n localizationKey={localizationKeys('oauthConsent.action__deny')}\n />\n <Button\n type='submit'\n name='consented'\n value='true'\n localizationKey={localizationKeys('oauthConsent.action__allow')}\n />\n <Text\n sx={{ gridColumn: 'span 2' }}\n colorScheme='secondary'\n variant='caption'\n >\n <InlineAction\n text={t(localizationKeys('oauthConsent.redirectNotice', { domainAction }))}\n actionText={domainAction}\n onClick={() => setIsUriModalOpen(true)}\n tooltipText={viewFullUrlText}\n />\n {hasOfflineAccess && t(localizationKeys('oauthConsent.offlineAccessNotice'))}\n </Text>\n </Grid>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n {!hasContextCallbacks &&\n forwardedParams.map(([key, value]) => (\n <input\n key={key}\n type='hidden'\n name={key}\n value={value}\n />\n ))}\n {!hasContextCallbacks && orgSelectionEnabled && effectiveOrg && (\n <input\n type='hidden'\n name='organization_id'\n value={effectiveOrg}\n />\n )}\n </form>\n <RedirectUriModal\n isOpen={isUriModalOpen}\n onOpen={() => setIsUriModalOpen(true)}\n onClose={() => setIsUriModalOpen(false)}\n redirectUri={redirectUrl}\n oauthApplicationName={oauthApplicationName}\n />\n </>\n );\n}\n\ntype RedirectUriModalProps = {\n onOpen: () => void;\n onClose: () => void;\n isOpen: boolean;\n redirectUri: string;\n oauthApplicationName: string;\n};\n\nfunction RedirectUriModal({ onOpen, onClose, isOpen, redirectUri, oauthApplicationName }: RedirectUriModalProps) {\n if (!isOpen) {\n return null;\n }\n\n return (\n <Modal\n handleOpen={onOpen}\n handleClose={onClose}\n >\n <Card.Root>\n <Card.Content>\n <Header.Root>\n <Header.Title localizationKey={localizationKeys('oauthConsent.redirectUriModal.title')} />\n <Header.Subtitle\n localizationKey={localizationKeys('oauthConsent.redirectUriModal.subtitle', {\n applicationName: oauthApplicationName,\n })}\n />\n </Header.Root>\n <Textarea\n style={{ maxHeight: 'none' }}\n cols={50}\n rows={6}\n defaultValue={redirectUri}\n readOnly\n />\n </Card.Content>\n </Card.Root>\n </Modal>\n );\n}\n\nconst AuthenticatedRoutes = withCoreUserGuard(withCardStateProvider(_OAuthConsent));\n\nconst OAuthConsentInternal = () => {\n return (\n <Flow.Root flow='oauthConsent'>\n <Flow.Part>\n <Switch>\n <Route>\n <AuthenticatedRoutes />\n </Route>\n </Switch>\n </Flow.Part>\n </Flow.Root>\n );\n};\n\nexport const OAuthConsent = OAuthConsentInternal;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OAuthConsent.js","names":[],"sources":["../../../src/components/OAuthConsent/OAuthConsent.tsx"],"sourcesContent":["import { useClerk, useOAuthConsent, useUser } from '@clerk/shared/react';\nimport { useState } from 'react';\n\nimport { useEnvironment, useOAuthConsentContext, withCoreUserGuard } from '@/ui/contexts';\nimport { Box, Button, Flow, Grid, localizationKeys, Text, useLocalizations } from '@/ui/customizables';\nimport { ApplicationLogo } from '@/ui/elements/ApplicationLogo';\nimport { Card } from '@/ui/elements/Card';\nimport { withCardStateProvider } from '@/ui/elements/contexts';\nimport { Header } from '@/ui/elements/Header';\nimport { LoadingCardContainer } from '@/ui/elements/LoadingCard';\nimport { Modal } from '@/ui/elements/Modal';\nimport { Alert, Textarea } from '@/ui/primitives';\nimport { Route, Switch } from '@/ui/router';\n\nimport { InlineAction } from './InlineAction';\nimport { getKnownOAuthClient } from './knownClients';\nimport {\n ListGroup,\n ListGroupContent,\n ListGroupHeader,\n ListGroupHeaderTitle,\n ListGroupItem,\n ListGroupItemLabel,\n} from './ListGroup';\nimport { LogoGroup, LogoGroupIcon, LogoGroupItem, LogoGroupItemContainer, LogoGroupSeparator } from './LogoGroup';\nimport { OrgSelect } from './OrgSelect';\nimport { getForwardedParams, getOAuthConsentFromSearch, getRedirectDisplay, getRedirectUriFromSearch } from './utils';\n\nconst OFFLINE_ACCESS_SCOPE = 'offline_access';\nconst PRIVATE_METADATA_SCOPE = 'private_metadata';\nconst USER_ORG_READ_SCOPE = 'user:org:read';\n\nfunction _OAuthConsent() {\n const ctx = useOAuthConsentContext();\n const clerk = useClerk();\n const { user } = useUser();\n const {\n displayConfig: { applicationName, logoImageUrl },\n organizationSettings,\n } = useEnvironment();\n const [isUriModalOpen, setIsUriModalOpen] = useState(false);\n\n const [selectedOrg, setSelectedOrg] = useState<string | null>(null);\n\n // onAllow and onDeny are always provided as a pair by the accounts portal.\n const hasContextCallbacks = Boolean(ctx.onAllow || ctx.onDeny);\n\n // Resolve oauthClientId and scope once: context overrides URL fallback.\n const fromUrl = getOAuthConsentFromSearch();\n const oauthClientId = ctx.oauthClientId ?? fromUrl.oauthClientId;\n const scope = ctx.scope ?? fromUrl.scope;\n\n // Public path: fetch via hook. Disabled on the accounts portal path\n // (which already has all data via context) to avoid a wasted FAPI request.\n const redirectUri = ctx.redirectUrl ?? getRedirectUriFromSearch();\n const { data, isLoading, error } = useOAuthConsent({\n oauthClientId,\n scope,\n redirectUri: redirectUri || undefined,\n // TODO: Remove this once account portal is refactored to use this component\n enabled: !hasContextCallbacks,\n });\n\n // Hook returns camelCase `requiresConsent`; the render logic uses snake_case.\n const mappedHookScopes = data?.scopes?.map(s => ({\n scope: s.scope,\n description: s.description,\n requires_consent: s.requiresConsent,\n }));\n\n // Context (accounts portal path) wins over hook data (public path).\n const scopes = ctx.scopes ?? mappedHookScopes ?? [];\n const oauthApplicationName = ctx.oauthApplicationName ?? data?.oauthApplicationName ?? '';\n const oauthApplicationLogoUrl = ctx.oauthApplicationLogoUrl ?? data?.oauthApplicationLogoUrl;\n const oauthApplicationUrl = ctx.oauthApplicationUrl ?? data?.oauthApplicationUrl;\n const redirectUrl = ctx.redirectUrl ?? redirectUri;\n\n const hasOrgReadScope = scopes.some(s => s.scope === USER_ORG_READ_SCOPE);\n const orgSelectionEnabled = !!(hasOrgReadScope && organizationSettings.enabled);\n const orgOptions = orgSelectionEnabled\n ? (user?.organizationMemberships ?? []).map(m => ({\n value: m.organization.id,\n label: m.organization.name,\n logoUrl: m.organization.imageUrl,\n }))\n : [];\n const lastActiveOrgId = clerk.session?.lastActiveOrganizationId;\n const defaultOrg = orgOptions.find(o => o.value === lastActiveOrgId)?.value ?? orgOptions[0]?.value ?? null;\n const effectiveOrg = selectedOrg ?? defaultOrg;\n\n const { t } = useLocalizations();\n const domainAction = data?.redirectDomain ?? getRedirectDisplay(redirectUrl);\n const viewFullUrlText = t(localizationKeys('oauthConsent.viewFullUrl'));\n\n // When the OAuth app has no uploaded logo, fall back to a recognized client's\n // brand mark (Claude, ChatGPT, ...). Keyed on the trusted redirect domain, not\n // the app-owner-set name, so a look-alike name cannot borrow the branding.\n const knownClient = oauthApplicationLogoUrl ? undefined : getKnownOAuthClient(domainAction);\n\n // Error states only apply to the public flow.\n if (!hasContextCallbacks) {\n const errorMessage = !oauthClientId\n ? 'The client ID is missing.'\n : !redirectUrl\n ? 'The redirect URI is missing.'\n : error\n ? (error.message ?? 'Failed to load consent information.')\n : undefined;\n\n if (errorMessage) {\n return (\n <Card.Root>\n <Card.Content>\n <Card.Alert>{errorMessage}</Card.Alert>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n if (isLoading) {\n return (\n <Card.Root>\n <Card.Content>\n <LoadingCardContainer />\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n }\n\n const actionUrl = clerk.oauthApplication.buildConsentActionUrl({ clientId: oauthClientId });\n const forwardedParams = getForwardedParams();\n\n // Accounts portal path delegates to context callbacks; public path lets the form submit natively.\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n if (!hasContextCallbacks) {\n return;\n }\n e.preventDefault();\n const submitter = (e.nativeEvent as SubmitEvent).submitter as HTMLButtonElement | null;\n if (submitter?.value === 'true') {\n ctx.onAllow?.();\n } else {\n ctx.onDeny?.();\n }\n };\n\n const primaryIdentifier = user?.primaryEmailAddress?.emailAddress || user?.primaryPhoneNumber?.phoneNumber;\n\n const displayedScopes = scopes\n .filter(item => item.scope !== OFFLINE_ACCESS_SCOPE)\n .map(item => ({\n ...item,\n description:\n item.scope === PRIVATE_METADATA_SCOPE\n ? t(localizationKeys('oauthConsent.scopeList.privateMetadata', { applicationName }))\n : item.description,\n }));\n const hasOfflineAccess = scopes.some(item => item.scope === OFFLINE_ACCESS_SCOPE);\n\n return (\n <>\n <form\n method='POST'\n action={actionUrl}\n onSubmit={handleSubmit}\n >\n <Card.Root>\n <Card.Content>\n <Header.Root>\n {/* both have avatars */}\n {oauthApplicationLogoUrl && logoImageUrl && (\n <LogoGroup>\n <LogoGroupItem justify='end'>\n <LogoGroupItemContainer>\n <ApplicationLogo\n src={oauthApplicationLogoUrl}\n alt={oauthApplicationName}\n href={oauthApplicationUrl}\n isExternal\n />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n <LogoGroupSeparator />\n <LogoGroupItem justify='start'>\n <LogoGroupItemContainer>\n <ApplicationLogo />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n </LogoGroup>\n )}\n {/* only OAuth app has an avatar */}\n {oauthApplicationLogoUrl && !logoImageUrl && (\n <LogoGroup>\n <Box sx={{ position: 'relative' }}>\n <LogoGroupItemContainer>\n <ApplicationLogo\n src={oauthApplicationLogoUrl}\n alt={oauthApplicationName}\n href={oauthApplicationUrl}\n isExternal\n />\n </LogoGroupItemContainer>\n <LogoGroupItemContainer\n size='sm'\n sx={t => ({\n position: 'absolute',\n bottom: `calc(${t.space.$2x5} * -1)`,\n insetInlineEnd: `calc(${t.space.$2x5} * -1)`,\n })}\n >\n <LogoGroupIcon />\n </LogoGroupItemContainer>\n </Box>\n </LogoGroup>\n )}\n {/* only Clerk application has an avatar */}\n {!oauthApplicationLogoUrl && logoImageUrl && (\n <LogoGroup>\n <LogoGroupItem justify='end'>\n <LogoGroupItemContainer>\n <LogoGroupIcon\n icon={knownClient?.icon}\n iconSx={knownClient?.iconSx}\n label={knownClient?.name}\n />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n <LogoGroupSeparator />\n <LogoGroupItem justify='start'>\n <LogoGroupItemContainer>\n <ApplicationLogo />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n </LogoGroup>\n )}\n {/* no avatars */}\n {!oauthApplicationLogoUrl && !logoImageUrl && (\n <LogoGroup>\n <LogoGroupItemContainer>\n <LogoGroupIcon\n icon={knownClient?.icon}\n iconSx={knownClient?.iconSx}\n label={knownClient?.name}\n />\n </LogoGroupItemContainer>\n </LogoGroup>\n )}\n <Header.Title localizationKey={oauthApplicationName} />\n <Header.Subtitle\n localizationKey={localizationKeys('oauthConsent.subtitle', {\n applicationName,\n identifier: primaryIdentifier || '',\n })}\n />\n </Header.Root>\n {orgSelectionEnabled && orgOptions.length > 0 && effectiveOrg && (\n <OrgSelect\n options={orgOptions}\n value={effectiveOrg}\n onChange={setSelectedOrg}\n />\n )}\n {displayedScopes.length > 0 && (\n <ListGroup>\n <ListGroupHeader>\n <ListGroupHeaderTitle\n localizationKey={localizationKeys('oauthConsent.scopeList.title', {\n applicationName: oauthApplicationName,\n })}\n />\n </ListGroupHeader>\n <ListGroupContent>\n {displayedScopes.map(item => (\n <ListGroupItem key={item.scope}>\n <ListGroupItemLabel>{item.description || item.scope || ''}</ListGroupItemLabel>\n </ListGroupItem>\n ))}\n </ListGroupContent>\n </ListGroup>\n )}\n <Alert colorScheme='warning'>\n <Text\n colorScheme='warning'\n variant='caption'\n >\n <InlineAction\n text={t(\n localizationKeys('oauthConsent.warning', {\n applicationName: oauthApplicationName || applicationName,\n domainAction,\n }),\n )}\n actionText={domainAction}\n onClick={() => setIsUriModalOpen(true)}\n tooltipText={viewFullUrlText}\n />\n </Text>\n </Alert>\n <Grid\n columns={2}\n gap={3}\n >\n <Button\n type='submit'\n name='consented'\n value='false'\n colorScheme='secondary'\n variant='outline'\n localizationKey={localizationKeys('oauthConsent.action__deny')}\n />\n <Button\n type='submit'\n name='consented'\n value='true'\n localizationKey={localizationKeys('oauthConsent.action__allow')}\n />\n <Text\n sx={{ gridColumn: 'span 2' }}\n colorScheme='secondary'\n variant='caption'\n >\n <InlineAction\n text={t(localizationKeys('oauthConsent.redirectNotice', { domainAction }))}\n actionText={domainAction}\n onClick={() => setIsUriModalOpen(true)}\n tooltipText={viewFullUrlText}\n />\n {hasOfflineAccess && t(localizationKeys('oauthConsent.offlineAccessNotice'))}\n </Text>\n </Grid>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n {!hasContextCallbacks &&\n forwardedParams.map(([key, value]) => (\n <input\n key={key}\n type='hidden'\n name={key}\n value={value}\n />\n ))}\n {!hasContextCallbacks && orgSelectionEnabled && effectiveOrg && (\n <input\n type='hidden'\n name='organization_id'\n value={effectiveOrg}\n />\n )}\n </form>\n <RedirectUriModal\n isOpen={isUriModalOpen}\n onOpen={() => setIsUriModalOpen(true)}\n onClose={() => setIsUriModalOpen(false)}\n redirectUri={redirectUrl}\n oauthApplicationName={oauthApplicationName}\n />\n </>\n );\n}\n\ntype RedirectUriModalProps = {\n onOpen: () => void;\n onClose: () => void;\n isOpen: boolean;\n redirectUri: string;\n oauthApplicationName: string;\n};\n\nfunction RedirectUriModal({ onOpen, onClose, isOpen, redirectUri, oauthApplicationName }: RedirectUriModalProps) {\n if (!isOpen) {\n return null;\n }\n\n return (\n <Modal\n handleOpen={onOpen}\n handleClose={onClose}\n >\n <Card.Root>\n <Card.Content>\n <Header.Root>\n <Header.Title localizationKey={localizationKeys('oauthConsent.redirectUriModal.title')} />\n <Header.Subtitle\n localizationKey={localizationKeys('oauthConsent.redirectUriModal.subtitle', {\n applicationName: oauthApplicationName,\n })}\n />\n </Header.Root>\n <Textarea\n style={{ maxHeight: 'none' }}\n cols={50}\n rows={6}\n defaultValue={redirectUri}\n readOnly\n />\n </Card.Content>\n </Card.Root>\n </Modal>\n );\n}\n\nconst AuthenticatedRoutes = withCoreUserGuard(withCardStateProvider(_OAuthConsent));\n\nconst OAuthConsentInternal = () => {\n return (\n <Flow.Root flow='oauthConsent'>\n <Flow.Part>\n <Switch>\n <Route>\n <AuthenticatedRoutes />\n </Route>\n </Switch>\n </Flow.Part>\n </Flow.Root>\n );\n};\n\nexport const OAuthConsent = OAuthConsentInternal;\n"],"mappings":"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"}
|
|
@@ -220,7 +220,7 @@ function OAuthDeviceVerificationInternal() {
|
|
|
220
220
|
value: effectiveOrg,
|
|
221
221
|
onChange: setSelectedOrg
|
|
222
222
|
}),
|
|
223
|
-
/* @__PURE__ */ jsxs(ListGroup, { children: [/* @__PURE__ */ jsx(ListGroupHeader, { children: /* @__PURE__ */ jsx(ListGroupHeaderTitle, { localizationKey: localizationKeys("oauthDeviceVerification.confirmation.scopeListTitle", { applicationName: data.oauthApplicationName }) }) }), /* @__PURE__ */ jsx(ListGroupContent, { children: displayedScopes.map((scope) => /* @__PURE__ */ jsx(ListGroupItem, { children: /* @__PURE__ */ jsx(ListGroupItemLabel, { children: scope.description || scope.scope }) }, scope.scope)) })] }),
|
|
223
|
+
displayedScopes.length > 0 && /* @__PURE__ */ jsxs(ListGroup, { children: [/* @__PURE__ */ jsx(ListGroupHeader, { children: /* @__PURE__ */ jsx(ListGroupHeaderTitle, { localizationKey: localizationKeys("oauthDeviceVerification.confirmation.scopeListTitle", { applicationName: data.oauthApplicationName }) }) }), /* @__PURE__ */ jsx(ListGroupContent, { children: displayedScopes.map((scope) => /* @__PURE__ */ jsx(ListGroupItem, { children: /* @__PURE__ */ jsx(ListGroupItemLabel, { children: scope.description || scope.scope }) }, scope.scope)) })] }),
|
|
224
224
|
/* @__PURE__ */ jsx(Alert, {
|
|
225
225
|
colorScheme: "warning",
|
|
226
226
|
children: /* @__PURE__ */ jsx(Text, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OAuthDeviceVerification.js","names":[],"sources":["../../../src/components/OAuthDeviceVerification/OAuthDeviceVerification.tsx"],"sourcesContent":["import { isClerkAPIResponseError } from '@clerk/shared/error';\nimport { useClerk, useOAuthDeviceVerification, useUser } from '@clerk/shared/react';\nimport type { OAuthDeviceVerificationInfo } from '@clerk/shared/types';\nimport type { FormEventHandler } from 'react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { useEnvironment, withCoreUserGuard } from '@/ui/contexts';\nimport { Button, Col, Flow, Grid, Image, localizationKeys, Text, useLocalizations } from '@/ui/customizables';\nimport { ApplicationLogo } from '@/ui/elements/ApplicationLogo';\nimport { Card } from '@/ui/elements/Card';\nimport { withCardStateProvider } from '@/ui/elements/contexts';\nimport { Form } from '@/ui/elements/Form';\nimport { Header } from '@/ui/elements/Header';\nimport { LoadingCardContainer } from '@/ui/elements/LoadingCard';\nimport { Alert } from '@/ui/primitives';\nimport { Route, Switch } from '@/ui/router';\nimport { useFormControl } from '@/ui/utils/useFormControl';\n\nimport {\n ListGroup,\n ListGroupContent,\n ListGroupHeader,\n ListGroupHeaderTitle,\n ListGroupItem,\n ListGroupItemLabel,\n} from '../OAuthConsent/ListGroup';\nimport {\n LogoGroup,\n LogoGroupIcon,\n LogoGroupItem,\n LogoGroupItemContainer,\n LogoGroupSeparator,\n} from '../OAuthConsent/LogoGroup';\nimport { OrgSelect } from '../OAuthConsent/OrgSelect';\nimport { OAuthDeviceVerificationCodeInput } from './OAuthDeviceVerificationCodeInput';\nimport { getOAuthDeviceUserCodeFromSearch, isValidOAuthDeviceUserCode, normalizeOAuthDeviceUserCode } from './utils';\n\nconst USER_ORG_READ_SCOPE = 'user:org:read';\nconst OFFLINE_ACCESS_SCOPE = 'offline_access';\nconst PRIVATE_METADATA_SCOPE = 'private_metadata';\n\ntype View =\n | 'entry'\n | 'loading'\n | 'confirmation'\n | 'approved'\n | 'alreadyApproved'\n | 'denied'\n | 'alreadyDenied'\n | 'consumed'\n | 'expired'\n | 'rateLimited'\n | 'alreadyDecided'\n | 'error';\n\nfunction getErrorCode(error: unknown): string | undefined {\n return isClerkAPIResponseError(error) ? error.errors?.[0]?.code : undefined;\n}\n\nfunction OAuthDeviceVerificationInternal() {\n const clerk = useClerk();\n const { user } = useUser();\n const {\n displayConfig: { applicationName, logoImageUrl },\n organizationSettings,\n } = useEnvironment();\n const { t } = useLocalizations();\n const verification = useOAuthDeviceVerification();\n const [view, setView] = useState<View>('entry');\n const [selectedOrg, setSelectedOrg] = useState<string | null>(null);\n const [submittingDecision, setSubmittingDecision] = useState<'approve' | 'deny' | null>(null);\n const handledPrefill = useRef(false);\n const decisionInProgress = useRef(false);\n\n const codeControl = useFormControl('userCode', '', {\n type: 'text',\n label: localizationKeys('oauthDeviceVerification.start.userCodeLabel'),\n transformer: normalizeOAuthDeviceUserCode,\n isRequired: true,\n });\n\n const showLookupError = useCallback(\n (error: unknown) => {\n switch (getErrorCode(error)) {\n case 'resource_not_found':\n setView('entry');\n codeControl.setError(t(localizationKeys('oauthDeviceVerification.error.unknownCode')));\n break;\n case 'oauth_device_code_expired':\n setView('expired');\n break;\n case 'too_many_requests':\n setView('rateLimited');\n break;\n default:\n setView('error');\n }\n },\n [codeControl, t],\n );\n\n const showLookupResult = useCallback((info: OAuthDeviceVerificationInfo) => {\n switch (info.status) {\n case 'pending':\n setView('confirmation');\n break;\n case 'approved':\n setView('alreadyApproved');\n break;\n case 'denied':\n setView('alreadyDenied');\n break;\n case 'consumed':\n setView('consumed');\n break;\n default:\n setView('error');\n }\n }, []);\n\n const lookup = useCallback(\n async (userCode: string) => {\n codeControl.clearFeedback();\n setView('loading');\n try {\n const info = await verification.lookup({ userCode });\n showLookupResult(info);\n } catch (error) {\n showLookupError(error);\n }\n },\n [codeControl, showLookupError, showLookupResult, verification],\n );\n\n useEffect(() => {\n if (handledPrefill.current) {\n return;\n }\n handledPrefill.current = true;\n\n const userCode = getOAuthDeviceUserCodeFromSearch();\n if (!userCode) {\n return;\n }\n\n codeControl.setValue(normalizeOAuthDeviceUserCode(userCode));\n if (!isValidOAuthDeviceUserCode(userCode)) {\n codeControl.setError(t(localizationKeys('oauthDeviceVerification.error.invalidCode')));\n return;\n }\n\n void lookup(normalizeOAuthDeviceUserCode(userCode));\n }, [codeControl, lookup, t]);\n\n const handleLookup: FormEventHandler<HTMLFormElement> = event => {\n event.preventDefault();\n const userCode = normalizeOAuthDeviceUserCode(codeControl.value);\n if (!isValidOAuthDeviceUserCode(userCode)) {\n codeControl.setError(t(localizationKeys('oauthDeviceVerification.error.invalidCode')));\n return;\n }\n void lookup(userCode);\n };\n\n const data = verification.data;\n const hasOrgReadScope = data?.scopes.some(scope => scope.scope === USER_ORG_READ_SCOPE) ?? false;\n const orgSelectionEnabled = hasOrgReadScope && organizationSettings.enabled;\n const orgOptions = orgSelectionEnabled\n ? (user?.organizationMemberships ?? []).map(membership => ({\n value: membership.organization.id,\n label: membership.organization.name,\n logoUrl: membership.organization.imageUrl,\n }))\n : [];\n const lastActiveOrgId = clerk.session?.lastActiveOrganizationId;\n const defaultOrg = orgOptions.find(option => option.value === lastActiveOrgId)?.value ?? orgOptions[0]?.value ?? null;\n const effectiveOrg = selectedOrg ?? defaultOrg;\n\n const showDecisionError = (error: unknown) => {\n switch (getErrorCode(error)) {\n case 'oauth_device_code_expired':\n setView('expired');\n break;\n case 'too_many_requests':\n setView('rateLimited');\n break;\n case 'bad_request':\n setView('alreadyDecided');\n break;\n default:\n setView('error');\n }\n };\n\n const handleApprove = async () => {\n if (decisionInProgress.current) {\n return;\n }\n decisionInProgress.current = true;\n const userCode = normalizeOAuthDeviceUserCode(codeControl.value);\n setSubmittingDecision('approve');\n try {\n await verification.approve({ userCode, organizationId: effectiveOrg ?? undefined });\n setView('approved');\n } catch (error) {\n showDecisionError(error);\n } finally {\n decisionInProgress.current = false;\n setSubmittingDecision(null);\n }\n };\n\n const handleDeny = async () => {\n if (decisionInProgress.current) {\n return;\n }\n decisionInProgress.current = true;\n const userCode = normalizeOAuthDeviceUserCode(codeControl.value);\n setSubmittingDecision('deny');\n try {\n await verification.deny({ userCode });\n setView('denied');\n } catch (error) {\n showDecisionError(error);\n } finally {\n decisionInProgress.current = false;\n setSubmittingDecision(null);\n }\n };\n\n const reset = () => {\n decisionInProgress.current = false;\n verification.reset();\n codeControl.setValue('');\n codeControl.clearFeedback();\n setSelectedOrg(null);\n setView('entry');\n };\n\n if (view === 'loading') {\n return (\n <Card.Root>\n <Card.Content>\n <LoadingCardContainer />\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n if (view === 'entry') {\n return (\n <Card.Root>\n <Card.Content>\n <Header.Root showLogo>\n <Header.Title localizationKey={localizationKeys('oauthDeviceVerification.start.title')} />\n <Header.Subtitle localizationKey={localizationKeys('oauthDeviceVerification.start.subtitle')} />\n </Header.Root>\n <Form.Root onSubmit={handleLookup}>\n <Form.ControlRow elementId={codeControl.id}>\n <Form.CommonInputWrapper {...codeControl.props}>\n <OAuthDeviceVerificationCodeInput control={codeControl} />\n </Form.CommonInputWrapper>\n </Form.ControlRow>\n <Form.SubmitButton localizationKey={localizationKeys('oauthDeviceVerification.start.action__continue')} />\n </Form.Root>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n if (view === 'confirmation' && data) {\n const primaryIdentifier = user?.primaryEmailAddress?.emailAddress || user?.primaryPhoneNumber?.phoneNumber || '';\n const displayedScopes = data.scopes\n .filter(scope => scope.scope !== OFFLINE_ACCESS_SCOPE)\n .map(scope => ({\n ...scope,\n description:\n scope.scope === PRIVATE_METADATA_SCOPE\n ? t(\n localizationKeys('oauthConsent.scopeList.privateMetadata', {\n applicationName,\n }),\n )\n : scope.description,\n }));\n const hasOfflineAccess = data.scopes.some(scope => scope.scope === OFFLINE_ACCESS_SCOPE);\n return (\n <Card.Root>\n <Card.Content>\n <Header.Root>\n <DeviceLogo\n applicationName={data.oauthApplicationName}\n logoUrl={data.oauthApplicationLogoUrl}\n showClerkLogo={Boolean(logoImageUrl)}\n />\n <Header.Title\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.title', {\n applicationName: data.oauthApplicationName,\n })}\n />\n <Header.Subtitle\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.subtitle', {\n identifier: primaryIdentifier,\n })}\n />\n </Header.Root>\n {orgSelectionEnabled && orgOptions.length > 0 && effectiveOrg && (\n <OrgSelect\n options={orgOptions}\n value={effectiveOrg}\n onChange={setSelectedOrg}\n />\n )}\n <ListGroup>\n <ListGroupHeader>\n <ListGroupHeaderTitle\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.scopeListTitle', {\n applicationName: data.oauthApplicationName,\n })}\n />\n </ListGroupHeader>\n <ListGroupContent>\n {displayedScopes.map(scope => (\n <ListGroupItem key={scope.scope}>\n <ListGroupItemLabel>{scope.description || scope.scope}</ListGroupItemLabel>\n </ListGroupItem>\n ))}\n </ListGroupContent>\n </ListGroup>\n <Alert colorScheme='warning'>\n <Text\n colorScheme='warning'\n variant='caption'\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.warning')}\n />\n </Alert>\n <Grid\n columns={2}\n gap={3}\n >\n <Button\n colorScheme='secondary'\n variant='outline'\n isLoading={submittingDecision === 'deny' && verification.isSubmitting}\n isDisabled={verification.isSubmitting}\n onClick={() => void handleDeny()}\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.action__deny')}\n />\n <Button\n isLoading={submittingDecision === 'approve' && verification.isSubmitting}\n isDisabled={verification.isSubmitting}\n onClick={() => void handleApprove()}\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.action__approve')}\n />\n {hasOfflineAccess && (\n <Text\n sx={{ gridColumn: 'span 2' }}\n colorScheme='secondary'\n variant='caption'\n localizationKey={localizationKeys('oauthConsent.offlineAccessNotice')}\n />\n )}\n </Grid>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n if (view === 'confirmation') {\n return (\n <Card.Root>\n <Card.Content>\n <LoadingCardContainer />\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n const terminal = getTerminalContent(view);\n return (\n <Card.Root>\n <Card.Content>\n <Col gap={6}>\n <Header.Root showLogo>\n <Header.Title localizationKey={localizationKeys(terminal.title)} />\n <Header.Subtitle localizationKey={localizationKeys(terminal.subtitle)} />\n </Header.Root>\n {terminal.canReset && (\n <Button\n block\n onClick={reset}\n localizationKey={localizationKeys('oauthDeviceVerification.action__tryAnotherCode')}\n />\n )}\n </Col>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n}\n\nfunction DeviceLogo({\n applicationName,\n logoUrl,\n showClerkLogo,\n}: {\n applicationName: string;\n logoUrl: string | null;\n showClerkLogo: boolean;\n}) {\n const applicationMark = logoUrl ? (\n <Image\n src={logoUrl}\n alt={applicationName}\n sx={{ width: '100%', height: '100%', objectFit: 'contain' }}\n />\n ) : (\n <LogoGroupIcon label={applicationName} />\n );\n\n if (!showClerkLogo) {\n return (\n <LogoGroup>\n <LogoGroupItemContainer>{applicationMark}</LogoGroupItemContainer>\n </LogoGroup>\n );\n }\n\n return (\n <LogoGroup>\n <LogoGroupItem justify='end'>\n <LogoGroupItemContainer>{applicationMark}</LogoGroupItemContainer>\n </LogoGroupItem>\n <LogoGroupSeparator />\n <LogoGroupItem justify='start'>\n <LogoGroupItemContainer>\n <ApplicationLogo />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n </LogoGroup>\n );\n}\n\nfunction getTerminalContent(view: Exclude<View, 'entry' | 'loading' | 'confirmation'>): {\n title: Parameters<typeof localizationKeys>[0];\n subtitle: Parameters<typeof localizationKeys>[0];\n canReset: boolean;\n} {\n switch (view) {\n case 'approved':\n return {\n title: 'oauthDeviceVerification.status.approvedTitle',\n subtitle: 'oauthDeviceVerification.status.approvedSubtitle',\n canReset: false,\n };\n case 'alreadyApproved':\n return {\n title: 'oauthDeviceVerification.status.alreadyApprovedTitle',\n subtitle: 'oauthDeviceVerification.status.alreadyApprovedSubtitle',\n canReset: false,\n };\n case 'denied':\n return {\n title: 'oauthDeviceVerification.status.deniedTitle',\n subtitle: 'oauthDeviceVerification.status.deniedSubtitle',\n canReset: false,\n };\n case 'alreadyDenied':\n return {\n title: 'oauthDeviceVerification.status.alreadyDeniedTitle',\n subtitle: 'oauthDeviceVerification.status.alreadyDeniedSubtitle',\n canReset: false,\n };\n case 'consumed':\n return {\n title: 'oauthDeviceVerification.status.consumedTitle',\n subtitle: 'oauthDeviceVerification.status.consumedSubtitle',\n canReset: false,\n };\n case 'expired':\n return {\n title: 'oauthDeviceVerification.error.expiredTitle',\n subtitle: 'oauthDeviceVerification.error.expiredSubtitle',\n canReset: false,\n };\n case 'rateLimited':\n return {\n title: 'oauthDeviceVerification.error.rateLimitedTitle',\n subtitle: 'oauthDeviceVerification.error.rateLimitedSubtitle',\n canReset: false,\n };\n case 'alreadyDecided':\n return {\n title: 'oauthDeviceVerification.status.alreadyDecidedTitle',\n subtitle: 'oauthDeviceVerification.status.alreadyDecidedSubtitle',\n canReset: false,\n };\n case 'error':\n return {\n title: 'oauthDeviceVerification.error.genericTitle',\n subtitle: 'oauthDeviceVerification.error.genericSubtitle',\n canReset: true,\n };\n }\n}\n\nconst AuthenticatedRoutes = withCoreUserGuard(withCardStateProvider(OAuthDeviceVerificationInternal));\n\nexport const OAuthDeviceVerification = () => (\n <Flow.Root flow='oauthDeviceVerification'>\n <Flow.Part>\n <Switch>\n <Route>\n <AuthenticatedRoutes />\n </Route>\n </Switch>\n </Flow.Part>\n </Flow.Root>\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OAuthDeviceVerification.js","names":[],"sources":["../../../src/components/OAuthDeviceVerification/OAuthDeviceVerification.tsx"],"sourcesContent":["import { isClerkAPIResponseError } from '@clerk/shared/error';\nimport { useClerk, useOAuthDeviceVerification, useUser } from '@clerk/shared/react';\nimport type { OAuthDeviceVerificationInfo } from '@clerk/shared/types';\nimport type { FormEventHandler } from 'react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { useEnvironment, withCoreUserGuard } from '@/ui/contexts';\nimport { Button, Col, Flow, Grid, Image, localizationKeys, Text, useLocalizations } from '@/ui/customizables';\nimport { ApplicationLogo } from '@/ui/elements/ApplicationLogo';\nimport { Card } from '@/ui/elements/Card';\nimport { withCardStateProvider } from '@/ui/elements/contexts';\nimport { Form } from '@/ui/elements/Form';\nimport { Header } from '@/ui/elements/Header';\nimport { LoadingCardContainer } from '@/ui/elements/LoadingCard';\nimport { Alert } from '@/ui/primitives';\nimport { Route, Switch } from '@/ui/router';\nimport { useFormControl } from '@/ui/utils/useFormControl';\n\nimport {\n ListGroup,\n ListGroupContent,\n ListGroupHeader,\n ListGroupHeaderTitle,\n ListGroupItem,\n ListGroupItemLabel,\n} from '../OAuthConsent/ListGroup';\nimport {\n LogoGroup,\n LogoGroupIcon,\n LogoGroupItem,\n LogoGroupItemContainer,\n LogoGroupSeparator,\n} from '../OAuthConsent/LogoGroup';\nimport { OrgSelect } from '../OAuthConsent/OrgSelect';\nimport { OAuthDeviceVerificationCodeInput } from './OAuthDeviceVerificationCodeInput';\nimport { getOAuthDeviceUserCodeFromSearch, isValidOAuthDeviceUserCode, normalizeOAuthDeviceUserCode } from './utils';\n\nconst USER_ORG_READ_SCOPE = 'user:org:read';\nconst OFFLINE_ACCESS_SCOPE = 'offline_access';\nconst PRIVATE_METADATA_SCOPE = 'private_metadata';\n\ntype View =\n | 'entry'\n | 'loading'\n | 'confirmation'\n | 'approved'\n | 'alreadyApproved'\n | 'denied'\n | 'alreadyDenied'\n | 'consumed'\n | 'expired'\n | 'rateLimited'\n | 'alreadyDecided'\n | 'error';\n\nfunction getErrorCode(error: unknown): string | undefined {\n return isClerkAPIResponseError(error) ? error.errors?.[0]?.code : undefined;\n}\n\nfunction OAuthDeviceVerificationInternal() {\n const clerk = useClerk();\n const { user } = useUser();\n const {\n displayConfig: { applicationName, logoImageUrl },\n organizationSettings,\n } = useEnvironment();\n const { t } = useLocalizations();\n const verification = useOAuthDeviceVerification();\n const [view, setView] = useState<View>('entry');\n const [selectedOrg, setSelectedOrg] = useState<string | null>(null);\n const [submittingDecision, setSubmittingDecision] = useState<'approve' | 'deny' | null>(null);\n const handledPrefill = useRef(false);\n const decisionInProgress = useRef(false);\n\n const codeControl = useFormControl('userCode', '', {\n type: 'text',\n label: localizationKeys('oauthDeviceVerification.start.userCodeLabel'),\n transformer: normalizeOAuthDeviceUserCode,\n isRequired: true,\n });\n\n const showLookupError = useCallback(\n (error: unknown) => {\n switch (getErrorCode(error)) {\n case 'resource_not_found':\n setView('entry');\n codeControl.setError(t(localizationKeys('oauthDeviceVerification.error.unknownCode')));\n break;\n case 'oauth_device_code_expired':\n setView('expired');\n break;\n case 'too_many_requests':\n setView('rateLimited');\n break;\n default:\n setView('error');\n }\n },\n [codeControl, t],\n );\n\n const showLookupResult = useCallback((info: OAuthDeviceVerificationInfo) => {\n switch (info.status) {\n case 'pending':\n setView('confirmation');\n break;\n case 'approved':\n setView('alreadyApproved');\n break;\n case 'denied':\n setView('alreadyDenied');\n break;\n case 'consumed':\n setView('consumed');\n break;\n default:\n setView('error');\n }\n }, []);\n\n const lookup = useCallback(\n async (userCode: string) => {\n codeControl.clearFeedback();\n setView('loading');\n try {\n const info = await verification.lookup({ userCode });\n showLookupResult(info);\n } catch (error) {\n showLookupError(error);\n }\n },\n [codeControl, showLookupError, showLookupResult, verification],\n );\n\n useEffect(() => {\n if (handledPrefill.current) {\n return;\n }\n handledPrefill.current = true;\n\n const userCode = getOAuthDeviceUserCodeFromSearch();\n if (!userCode) {\n return;\n }\n\n codeControl.setValue(normalizeOAuthDeviceUserCode(userCode));\n if (!isValidOAuthDeviceUserCode(userCode)) {\n codeControl.setError(t(localizationKeys('oauthDeviceVerification.error.invalidCode')));\n return;\n }\n\n void lookup(normalizeOAuthDeviceUserCode(userCode));\n }, [codeControl, lookup, t]);\n\n const handleLookup: FormEventHandler<HTMLFormElement> = event => {\n event.preventDefault();\n const userCode = normalizeOAuthDeviceUserCode(codeControl.value);\n if (!isValidOAuthDeviceUserCode(userCode)) {\n codeControl.setError(t(localizationKeys('oauthDeviceVerification.error.invalidCode')));\n return;\n }\n void lookup(userCode);\n };\n\n const data = verification.data;\n const hasOrgReadScope = data?.scopes.some(scope => scope.scope === USER_ORG_READ_SCOPE) ?? false;\n const orgSelectionEnabled = hasOrgReadScope && organizationSettings.enabled;\n const orgOptions = orgSelectionEnabled\n ? (user?.organizationMemberships ?? []).map(membership => ({\n value: membership.organization.id,\n label: membership.organization.name,\n logoUrl: membership.organization.imageUrl,\n }))\n : [];\n const lastActiveOrgId = clerk.session?.lastActiveOrganizationId;\n const defaultOrg = orgOptions.find(option => option.value === lastActiveOrgId)?.value ?? orgOptions[0]?.value ?? null;\n const effectiveOrg = selectedOrg ?? defaultOrg;\n\n const showDecisionError = (error: unknown) => {\n switch (getErrorCode(error)) {\n case 'oauth_device_code_expired':\n setView('expired');\n break;\n case 'too_many_requests':\n setView('rateLimited');\n break;\n case 'bad_request':\n setView('alreadyDecided');\n break;\n default:\n setView('error');\n }\n };\n\n const handleApprove = async () => {\n if (decisionInProgress.current) {\n return;\n }\n decisionInProgress.current = true;\n const userCode = normalizeOAuthDeviceUserCode(codeControl.value);\n setSubmittingDecision('approve');\n try {\n await verification.approve({ userCode, organizationId: effectiveOrg ?? undefined });\n setView('approved');\n } catch (error) {\n showDecisionError(error);\n } finally {\n decisionInProgress.current = false;\n setSubmittingDecision(null);\n }\n };\n\n const handleDeny = async () => {\n if (decisionInProgress.current) {\n return;\n }\n decisionInProgress.current = true;\n const userCode = normalizeOAuthDeviceUserCode(codeControl.value);\n setSubmittingDecision('deny');\n try {\n await verification.deny({ userCode });\n setView('denied');\n } catch (error) {\n showDecisionError(error);\n } finally {\n decisionInProgress.current = false;\n setSubmittingDecision(null);\n }\n };\n\n const reset = () => {\n decisionInProgress.current = false;\n verification.reset();\n codeControl.setValue('');\n codeControl.clearFeedback();\n setSelectedOrg(null);\n setView('entry');\n };\n\n if (view === 'loading') {\n return (\n <Card.Root>\n <Card.Content>\n <LoadingCardContainer />\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n if (view === 'entry') {\n return (\n <Card.Root>\n <Card.Content>\n <Header.Root showLogo>\n <Header.Title localizationKey={localizationKeys('oauthDeviceVerification.start.title')} />\n <Header.Subtitle localizationKey={localizationKeys('oauthDeviceVerification.start.subtitle')} />\n </Header.Root>\n <Form.Root onSubmit={handleLookup}>\n <Form.ControlRow elementId={codeControl.id}>\n <Form.CommonInputWrapper {...codeControl.props}>\n <OAuthDeviceVerificationCodeInput control={codeControl} />\n </Form.CommonInputWrapper>\n </Form.ControlRow>\n <Form.SubmitButton localizationKey={localizationKeys('oauthDeviceVerification.start.action__continue')} />\n </Form.Root>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n if (view === 'confirmation' && data) {\n const primaryIdentifier = user?.primaryEmailAddress?.emailAddress || user?.primaryPhoneNumber?.phoneNumber || '';\n const displayedScopes = data.scopes\n .filter(scope => scope.scope !== OFFLINE_ACCESS_SCOPE)\n .map(scope => ({\n ...scope,\n description:\n scope.scope === PRIVATE_METADATA_SCOPE\n ? t(\n localizationKeys('oauthConsent.scopeList.privateMetadata', {\n applicationName,\n }),\n )\n : scope.description,\n }));\n const hasOfflineAccess = data.scopes.some(scope => scope.scope === OFFLINE_ACCESS_SCOPE);\n return (\n <Card.Root>\n <Card.Content>\n <Header.Root>\n <DeviceLogo\n applicationName={data.oauthApplicationName}\n logoUrl={data.oauthApplicationLogoUrl}\n showClerkLogo={Boolean(logoImageUrl)}\n />\n <Header.Title\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.title', {\n applicationName: data.oauthApplicationName,\n })}\n />\n <Header.Subtitle\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.subtitle', {\n identifier: primaryIdentifier,\n })}\n />\n </Header.Root>\n {orgSelectionEnabled && orgOptions.length > 0 && effectiveOrg && (\n <OrgSelect\n options={orgOptions}\n value={effectiveOrg}\n onChange={setSelectedOrg}\n />\n )}\n {displayedScopes.length > 0 && (\n <ListGroup>\n <ListGroupHeader>\n <ListGroupHeaderTitle\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.scopeListTitle', {\n applicationName: data.oauthApplicationName,\n })}\n />\n </ListGroupHeader>\n <ListGroupContent>\n {displayedScopes.map(scope => (\n <ListGroupItem key={scope.scope}>\n <ListGroupItemLabel>{scope.description || scope.scope}</ListGroupItemLabel>\n </ListGroupItem>\n ))}\n </ListGroupContent>\n </ListGroup>\n )}\n <Alert colorScheme='warning'>\n <Text\n colorScheme='warning'\n variant='caption'\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.warning')}\n />\n </Alert>\n <Grid\n columns={2}\n gap={3}\n >\n <Button\n colorScheme='secondary'\n variant='outline'\n isLoading={submittingDecision === 'deny' && verification.isSubmitting}\n isDisabled={verification.isSubmitting}\n onClick={() => void handleDeny()}\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.action__deny')}\n />\n <Button\n isLoading={submittingDecision === 'approve' && verification.isSubmitting}\n isDisabled={verification.isSubmitting}\n onClick={() => void handleApprove()}\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.action__approve')}\n />\n {hasOfflineAccess && (\n <Text\n sx={{ gridColumn: 'span 2' }}\n colorScheme='secondary'\n variant='caption'\n localizationKey={localizationKeys('oauthConsent.offlineAccessNotice')}\n />\n )}\n </Grid>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n if (view === 'confirmation') {\n return (\n <Card.Root>\n <Card.Content>\n <LoadingCardContainer />\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n const terminal = getTerminalContent(view);\n return (\n <Card.Root>\n <Card.Content>\n <Col gap={6}>\n <Header.Root showLogo>\n <Header.Title localizationKey={localizationKeys(terminal.title)} />\n <Header.Subtitle localizationKey={localizationKeys(terminal.subtitle)} />\n </Header.Root>\n {terminal.canReset && (\n <Button\n block\n onClick={reset}\n localizationKey={localizationKeys('oauthDeviceVerification.action__tryAnotherCode')}\n />\n )}\n </Col>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n}\n\nfunction DeviceLogo({\n applicationName,\n logoUrl,\n showClerkLogo,\n}: {\n applicationName: string;\n logoUrl: string | null;\n showClerkLogo: boolean;\n}) {\n const applicationMark = logoUrl ? (\n <Image\n src={logoUrl}\n alt={applicationName}\n sx={{ width: '100%', height: '100%', objectFit: 'contain' }}\n />\n ) : (\n <LogoGroupIcon label={applicationName} />\n );\n\n if (!showClerkLogo) {\n return (\n <LogoGroup>\n <LogoGroupItemContainer>{applicationMark}</LogoGroupItemContainer>\n </LogoGroup>\n );\n }\n\n return (\n <LogoGroup>\n <LogoGroupItem justify='end'>\n <LogoGroupItemContainer>{applicationMark}</LogoGroupItemContainer>\n </LogoGroupItem>\n <LogoGroupSeparator />\n <LogoGroupItem justify='start'>\n <LogoGroupItemContainer>\n <ApplicationLogo />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n </LogoGroup>\n );\n}\n\nfunction getTerminalContent(view: Exclude<View, 'entry' | 'loading' | 'confirmation'>): {\n title: Parameters<typeof localizationKeys>[0];\n subtitle: Parameters<typeof localizationKeys>[0];\n canReset: boolean;\n} {\n switch (view) {\n case 'approved':\n return {\n title: 'oauthDeviceVerification.status.approvedTitle',\n subtitle: 'oauthDeviceVerification.status.approvedSubtitle',\n canReset: false,\n };\n case 'alreadyApproved':\n return {\n title: 'oauthDeviceVerification.status.alreadyApprovedTitle',\n subtitle: 'oauthDeviceVerification.status.alreadyApprovedSubtitle',\n canReset: false,\n };\n case 'denied':\n return {\n title: 'oauthDeviceVerification.status.deniedTitle',\n subtitle: 'oauthDeviceVerification.status.deniedSubtitle',\n canReset: false,\n };\n case 'alreadyDenied':\n return {\n title: 'oauthDeviceVerification.status.alreadyDeniedTitle',\n subtitle: 'oauthDeviceVerification.status.alreadyDeniedSubtitle',\n canReset: false,\n };\n case 'consumed':\n return {\n title: 'oauthDeviceVerification.status.consumedTitle',\n subtitle: 'oauthDeviceVerification.status.consumedSubtitle',\n canReset: false,\n };\n case 'expired':\n return {\n title: 'oauthDeviceVerification.error.expiredTitle',\n subtitle: 'oauthDeviceVerification.error.expiredSubtitle',\n canReset: false,\n };\n case 'rateLimited':\n return {\n title: 'oauthDeviceVerification.error.rateLimitedTitle',\n subtitle: 'oauthDeviceVerification.error.rateLimitedSubtitle',\n canReset: false,\n };\n case 'alreadyDecided':\n return {\n title: 'oauthDeviceVerification.status.alreadyDecidedTitle',\n subtitle: 'oauthDeviceVerification.status.alreadyDecidedSubtitle',\n canReset: false,\n };\n case 'error':\n return {\n title: 'oauthDeviceVerification.error.genericTitle',\n subtitle: 'oauthDeviceVerification.error.genericSubtitle',\n canReset: true,\n };\n }\n}\n\nconst AuthenticatedRoutes = withCoreUserGuard(withCardStateProvider(OAuthDeviceVerificationInternal));\n\nexport const OAuthDeviceVerification = () => (\n <Flow.Root flow='oauthDeviceVerification'>\n <Flow.Part>\n <Switch>\n <Route>\n <AuthenticatedRoutes />\n </Route>\n </Switch>\n </Flow.Part>\n </Flow.Root>\n);\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
package/dist/no-rhc/ClerkUI.js
CHANGED
|
@@ -22,8 +22,8 @@ import { isVersionAtLeast, parseVersion } from "@clerk/shared/versionCheck";
|
|
|
22
22
|
* @public
|
|
23
23
|
*/
|
|
24
24
|
var ClerkUI = class ClerkUI {
|
|
25
|
-
static version = "1.34.0
|
|
26
|
-
version = "1.34.0
|
|
25
|
+
static version = "1.34.0";
|
|
26
|
+
version = "1.34.0";
|
|
27
27
|
#componentRenderer;
|
|
28
28
|
/**
|
|
29
29
|
* Creates a new `ClerkUI` instance and mounts the internal component renderer.
|
|
@@ -160,7 +160,7 @@ function _OAuthConsent() {
|
|
|
160
160
|
value: effectiveOrg,
|
|
161
161
|
onChange: setSelectedOrg
|
|
162
162
|
}),
|
|
163
|
-
/* @__PURE__ */ jsxs(ListGroup, { children: [/* @__PURE__ */ jsx(ListGroupHeader, { children: /* @__PURE__ */ jsx(ListGroupHeaderTitle, { localizationKey: localizationKeys("oauthConsent.scopeList.title", { applicationName: oauthApplicationName }) }) }), /* @__PURE__ */ jsx(ListGroupContent, { children: displayedScopes.map((item) => /* @__PURE__ */ jsx(ListGroupItem, { children: /* @__PURE__ */ jsx(ListGroupItemLabel, { children: item.description || item.scope || "" }) }, item.scope)) })] }),
|
|
163
|
+
displayedScopes.length > 0 && /* @__PURE__ */ jsxs(ListGroup, { children: [/* @__PURE__ */ jsx(ListGroupHeader, { children: /* @__PURE__ */ jsx(ListGroupHeaderTitle, { localizationKey: localizationKeys("oauthConsent.scopeList.title", { applicationName: oauthApplicationName }) }) }), /* @__PURE__ */ jsx(ListGroupContent, { children: displayedScopes.map((item) => /* @__PURE__ */ jsx(ListGroupItem, { children: /* @__PURE__ */ jsx(ListGroupItemLabel, { children: item.description || item.scope || "" }) }, item.scope)) })] }),
|
|
164
164
|
/* @__PURE__ */ jsx(Alert, {
|
|
165
165
|
colorScheme: "warning",
|
|
166
166
|
children: /* @__PURE__ */ jsx(Text, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OAuthConsent.js","names":[],"sources":["../../../../src/components/OAuthConsent/OAuthConsent.tsx"],"sourcesContent":["import { useClerk, useOAuthConsent, useUser } from '@clerk/shared/react';\nimport { useState } from 'react';\n\nimport { useEnvironment, useOAuthConsentContext, withCoreUserGuard } from '@/ui/contexts';\nimport { Box, Button, Flow, Grid, localizationKeys, Text, useLocalizations } from '@/ui/customizables';\nimport { ApplicationLogo } from '@/ui/elements/ApplicationLogo';\nimport { Card } from '@/ui/elements/Card';\nimport { withCardStateProvider } from '@/ui/elements/contexts';\nimport { Header } from '@/ui/elements/Header';\nimport { LoadingCardContainer } from '@/ui/elements/LoadingCard';\nimport { Modal } from '@/ui/elements/Modal';\nimport { Alert, Textarea } from '@/ui/primitives';\nimport { Route, Switch } from '@/ui/router';\n\nimport { InlineAction } from './InlineAction';\nimport { getKnownOAuthClient } from './knownClients';\nimport {\n ListGroup,\n ListGroupContent,\n ListGroupHeader,\n ListGroupHeaderTitle,\n ListGroupItem,\n ListGroupItemLabel,\n} from './ListGroup';\nimport { LogoGroup, LogoGroupIcon, LogoGroupItem, LogoGroupItemContainer, LogoGroupSeparator } from './LogoGroup';\nimport { OrgSelect } from './OrgSelect';\nimport { getForwardedParams, getOAuthConsentFromSearch, getRedirectDisplay, getRedirectUriFromSearch } from './utils';\n\nconst OFFLINE_ACCESS_SCOPE = 'offline_access';\nconst PRIVATE_METADATA_SCOPE = 'private_metadata';\nconst USER_ORG_READ_SCOPE = 'user:org:read';\n\nfunction _OAuthConsent() {\n const ctx = useOAuthConsentContext();\n const clerk = useClerk();\n const { user } = useUser();\n const {\n displayConfig: { applicationName, logoImageUrl },\n organizationSettings,\n } = useEnvironment();\n const [isUriModalOpen, setIsUriModalOpen] = useState(false);\n\n const [selectedOrg, setSelectedOrg] = useState<string | null>(null);\n\n // onAllow and onDeny are always provided as a pair by the accounts portal.\n const hasContextCallbacks = Boolean(ctx.onAllow || ctx.onDeny);\n\n // Resolve oauthClientId and scope once: context overrides URL fallback.\n const fromUrl = getOAuthConsentFromSearch();\n const oauthClientId = ctx.oauthClientId ?? fromUrl.oauthClientId;\n const scope = ctx.scope ?? fromUrl.scope;\n\n // Public path: fetch via hook. Disabled on the accounts portal path\n // (which already has all data via context) to avoid a wasted FAPI request.\n const redirectUri = ctx.redirectUrl ?? getRedirectUriFromSearch();\n const { data, isLoading, error } = useOAuthConsent({\n oauthClientId,\n scope,\n redirectUri: redirectUri || undefined,\n // TODO: Remove this once account portal is refactored to use this component\n enabled: !hasContextCallbacks,\n });\n\n // Hook returns camelCase `requiresConsent`; the render logic uses snake_case.\n const mappedHookScopes = data?.scopes?.map(s => ({\n scope: s.scope,\n description: s.description,\n requires_consent: s.requiresConsent,\n }));\n\n // Context (accounts portal path) wins over hook data (public path).\n const scopes = ctx.scopes ?? mappedHookScopes ?? [];\n const oauthApplicationName = ctx.oauthApplicationName ?? data?.oauthApplicationName ?? '';\n const oauthApplicationLogoUrl = ctx.oauthApplicationLogoUrl ?? data?.oauthApplicationLogoUrl;\n const oauthApplicationUrl = ctx.oauthApplicationUrl ?? data?.oauthApplicationUrl;\n const redirectUrl = ctx.redirectUrl ?? redirectUri;\n\n const hasOrgReadScope = scopes.some(s => s.scope === USER_ORG_READ_SCOPE);\n const orgSelectionEnabled = !!(hasOrgReadScope && organizationSettings.enabled);\n const orgOptions = orgSelectionEnabled\n ? (user?.organizationMemberships ?? []).map(m => ({\n value: m.organization.id,\n label: m.organization.name,\n logoUrl: m.organization.imageUrl,\n }))\n : [];\n const lastActiveOrgId = clerk.session?.lastActiveOrganizationId;\n const defaultOrg = orgOptions.find(o => o.value === lastActiveOrgId)?.value ?? orgOptions[0]?.value ?? null;\n const effectiveOrg = selectedOrg ?? defaultOrg;\n\n const { t } = useLocalizations();\n const domainAction = data?.redirectDomain ?? getRedirectDisplay(redirectUrl);\n const viewFullUrlText = t(localizationKeys('oauthConsent.viewFullUrl'));\n\n // When the OAuth app has no uploaded logo, fall back to a recognized client's\n // brand mark (Claude, ChatGPT, ...). Keyed on the trusted redirect domain, not\n // the app-owner-set name, so a look-alike name cannot borrow the branding.\n const knownClient = oauthApplicationLogoUrl ? undefined : getKnownOAuthClient(domainAction);\n\n // Error states only apply to the public flow.\n if (!hasContextCallbacks) {\n const errorMessage = !oauthClientId\n ? 'The client ID is missing.'\n : !redirectUrl\n ? 'The redirect URI is missing.'\n : error\n ? (error.message ?? 'Failed to load consent information.')\n : undefined;\n\n if (errorMessage) {\n return (\n <Card.Root>\n <Card.Content>\n <Card.Alert>{errorMessage}</Card.Alert>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n if (isLoading) {\n return (\n <Card.Root>\n <Card.Content>\n <LoadingCardContainer />\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n }\n\n const actionUrl = clerk.oauthApplication.buildConsentActionUrl({ clientId: oauthClientId });\n const forwardedParams = getForwardedParams();\n\n // Accounts portal path delegates to context callbacks; public path lets the form submit natively.\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n if (!hasContextCallbacks) {\n return;\n }\n e.preventDefault();\n const submitter = (e.nativeEvent as SubmitEvent).submitter as HTMLButtonElement | null;\n if (submitter?.value === 'true') {\n ctx.onAllow?.();\n } else {\n ctx.onDeny?.();\n }\n };\n\n const primaryIdentifier = user?.primaryEmailAddress?.emailAddress || user?.primaryPhoneNumber?.phoneNumber;\n\n const displayedScopes = scopes\n .filter(item => item.scope !== OFFLINE_ACCESS_SCOPE)\n .map(item => ({\n ...item,\n description:\n item.scope === PRIVATE_METADATA_SCOPE\n ? t(localizationKeys('oauthConsent.scopeList.privateMetadata', { applicationName }))\n : item.description,\n }));\n const hasOfflineAccess = scopes.some(item => item.scope === OFFLINE_ACCESS_SCOPE);\n\n return (\n <>\n <form\n method='POST'\n action={actionUrl}\n onSubmit={handleSubmit}\n >\n <Card.Root>\n <Card.Content>\n <Header.Root>\n {/* both have avatars */}\n {oauthApplicationLogoUrl && logoImageUrl && (\n <LogoGroup>\n <LogoGroupItem justify='end'>\n <LogoGroupItemContainer>\n <ApplicationLogo\n src={oauthApplicationLogoUrl}\n alt={oauthApplicationName}\n href={oauthApplicationUrl}\n isExternal\n />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n <LogoGroupSeparator />\n <LogoGroupItem justify='start'>\n <LogoGroupItemContainer>\n <ApplicationLogo />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n </LogoGroup>\n )}\n {/* only OAuth app has an avatar */}\n {oauthApplicationLogoUrl && !logoImageUrl && (\n <LogoGroup>\n <Box sx={{ position: 'relative' }}>\n <LogoGroupItemContainer>\n <ApplicationLogo\n src={oauthApplicationLogoUrl}\n alt={oauthApplicationName}\n href={oauthApplicationUrl}\n isExternal\n />\n </LogoGroupItemContainer>\n <LogoGroupItemContainer\n size='sm'\n sx={t => ({\n position: 'absolute',\n bottom: `calc(${t.space.$2x5} * -1)`,\n insetInlineEnd: `calc(${t.space.$2x5} * -1)`,\n })}\n >\n <LogoGroupIcon />\n </LogoGroupItemContainer>\n </Box>\n </LogoGroup>\n )}\n {/* only Clerk application has an avatar */}\n {!oauthApplicationLogoUrl && logoImageUrl && (\n <LogoGroup>\n <LogoGroupItem justify='end'>\n <LogoGroupItemContainer>\n <LogoGroupIcon\n icon={knownClient?.icon}\n iconSx={knownClient?.iconSx}\n label={knownClient?.name}\n />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n <LogoGroupSeparator />\n <LogoGroupItem justify='start'>\n <LogoGroupItemContainer>\n <ApplicationLogo />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n </LogoGroup>\n )}\n {/* no avatars */}\n {!oauthApplicationLogoUrl && !logoImageUrl && (\n <LogoGroup>\n <LogoGroupItemContainer>\n <LogoGroupIcon\n icon={knownClient?.icon}\n iconSx={knownClient?.iconSx}\n label={knownClient?.name}\n />\n </LogoGroupItemContainer>\n </LogoGroup>\n )}\n <Header.Title localizationKey={oauthApplicationName} />\n <Header.Subtitle\n localizationKey={localizationKeys('oauthConsent.subtitle', {\n applicationName,\n identifier: primaryIdentifier || '',\n })}\n />\n </Header.Root>\n {orgSelectionEnabled && orgOptions.length > 0 && effectiveOrg && (\n <OrgSelect\n options={orgOptions}\n value={effectiveOrg}\n onChange={setSelectedOrg}\n />\n )}\n <ListGroup>\n <ListGroupHeader>\n <ListGroupHeaderTitle\n localizationKey={localizationKeys('oauthConsent.scopeList.title', {\n applicationName: oauthApplicationName,\n })}\n />\n </ListGroupHeader>\n <ListGroupContent>\n {displayedScopes.map(item => (\n <ListGroupItem key={item.scope}>\n <ListGroupItemLabel>{item.description || item.scope || ''}</ListGroupItemLabel>\n </ListGroupItem>\n ))}\n </ListGroupContent>\n </ListGroup>\n <Alert colorScheme='warning'>\n <Text\n colorScheme='warning'\n variant='caption'\n >\n <InlineAction\n text={t(\n localizationKeys('oauthConsent.warning', {\n applicationName: oauthApplicationName || applicationName,\n domainAction,\n }),\n )}\n actionText={domainAction}\n onClick={() => setIsUriModalOpen(true)}\n tooltipText={viewFullUrlText}\n />\n </Text>\n </Alert>\n <Grid\n columns={2}\n gap={3}\n >\n <Button\n type='submit'\n name='consented'\n value='false'\n colorScheme='secondary'\n variant='outline'\n localizationKey={localizationKeys('oauthConsent.action__deny')}\n />\n <Button\n type='submit'\n name='consented'\n value='true'\n localizationKey={localizationKeys('oauthConsent.action__allow')}\n />\n <Text\n sx={{ gridColumn: 'span 2' }}\n colorScheme='secondary'\n variant='caption'\n >\n <InlineAction\n text={t(localizationKeys('oauthConsent.redirectNotice', { domainAction }))}\n actionText={domainAction}\n onClick={() => setIsUriModalOpen(true)}\n tooltipText={viewFullUrlText}\n />\n {hasOfflineAccess && t(localizationKeys('oauthConsent.offlineAccessNotice'))}\n </Text>\n </Grid>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n {!hasContextCallbacks &&\n forwardedParams.map(([key, value]) => (\n <input\n key={key}\n type='hidden'\n name={key}\n value={value}\n />\n ))}\n {!hasContextCallbacks && orgSelectionEnabled && effectiveOrg && (\n <input\n type='hidden'\n name='organization_id'\n value={effectiveOrg}\n />\n )}\n </form>\n <RedirectUriModal\n isOpen={isUriModalOpen}\n onOpen={() => setIsUriModalOpen(true)}\n onClose={() => setIsUriModalOpen(false)}\n redirectUri={redirectUrl}\n oauthApplicationName={oauthApplicationName}\n />\n </>\n );\n}\n\ntype RedirectUriModalProps = {\n onOpen: () => void;\n onClose: () => void;\n isOpen: boolean;\n redirectUri: string;\n oauthApplicationName: string;\n};\n\nfunction RedirectUriModal({ onOpen, onClose, isOpen, redirectUri, oauthApplicationName }: RedirectUriModalProps) {\n if (!isOpen) {\n return null;\n }\n\n return (\n <Modal\n handleOpen={onOpen}\n handleClose={onClose}\n >\n <Card.Root>\n <Card.Content>\n <Header.Root>\n <Header.Title localizationKey={localizationKeys('oauthConsent.redirectUriModal.title')} />\n <Header.Subtitle\n localizationKey={localizationKeys('oauthConsent.redirectUriModal.subtitle', {\n applicationName: oauthApplicationName,\n })}\n />\n </Header.Root>\n <Textarea\n style={{ maxHeight: 'none' }}\n cols={50}\n rows={6}\n defaultValue={redirectUri}\n readOnly\n />\n </Card.Content>\n </Card.Root>\n </Modal>\n );\n}\n\nconst AuthenticatedRoutes = withCoreUserGuard(withCardStateProvider(_OAuthConsent));\n\nconst OAuthConsentInternal = () => {\n return (\n <Flow.Root flow='oauthConsent'>\n <Flow.Part>\n <Switch>\n <Route>\n <AuthenticatedRoutes />\n </Route>\n </Switch>\n </Flow.Part>\n </Flow.Root>\n );\n};\n\nexport const OAuthConsent = OAuthConsentInternal;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OAuthConsent.js","names":[],"sources":["../../../../src/components/OAuthConsent/OAuthConsent.tsx"],"sourcesContent":["import { useClerk, useOAuthConsent, useUser } from '@clerk/shared/react';\nimport { useState } from 'react';\n\nimport { useEnvironment, useOAuthConsentContext, withCoreUserGuard } from '@/ui/contexts';\nimport { Box, Button, Flow, Grid, localizationKeys, Text, useLocalizations } from '@/ui/customizables';\nimport { ApplicationLogo } from '@/ui/elements/ApplicationLogo';\nimport { Card } from '@/ui/elements/Card';\nimport { withCardStateProvider } from '@/ui/elements/contexts';\nimport { Header } from '@/ui/elements/Header';\nimport { LoadingCardContainer } from '@/ui/elements/LoadingCard';\nimport { Modal } from '@/ui/elements/Modal';\nimport { Alert, Textarea } from '@/ui/primitives';\nimport { Route, Switch } from '@/ui/router';\n\nimport { InlineAction } from './InlineAction';\nimport { getKnownOAuthClient } from './knownClients';\nimport {\n ListGroup,\n ListGroupContent,\n ListGroupHeader,\n ListGroupHeaderTitle,\n ListGroupItem,\n ListGroupItemLabel,\n} from './ListGroup';\nimport { LogoGroup, LogoGroupIcon, LogoGroupItem, LogoGroupItemContainer, LogoGroupSeparator } from './LogoGroup';\nimport { OrgSelect } from './OrgSelect';\nimport { getForwardedParams, getOAuthConsentFromSearch, getRedirectDisplay, getRedirectUriFromSearch } from './utils';\n\nconst OFFLINE_ACCESS_SCOPE = 'offline_access';\nconst PRIVATE_METADATA_SCOPE = 'private_metadata';\nconst USER_ORG_READ_SCOPE = 'user:org:read';\n\nfunction _OAuthConsent() {\n const ctx = useOAuthConsentContext();\n const clerk = useClerk();\n const { user } = useUser();\n const {\n displayConfig: { applicationName, logoImageUrl },\n organizationSettings,\n } = useEnvironment();\n const [isUriModalOpen, setIsUriModalOpen] = useState(false);\n\n const [selectedOrg, setSelectedOrg] = useState<string | null>(null);\n\n // onAllow and onDeny are always provided as a pair by the accounts portal.\n const hasContextCallbacks = Boolean(ctx.onAllow || ctx.onDeny);\n\n // Resolve oauthClientId and scope once: context overrides URL fallback.\n const fromUrl = getOAuthConsentFromSearch();\n const oauthClientId = ctx.oauthClientId ?? fromUrl.oauthClientId;\n const scope = ctx.scope ?? fromUrl.scope;\n\n // Public path: fetch via hook. Disabled on the accounts portal path\n // (which already has all data via context) to avoid a wasted FAPI request.\n const redirectUri = ctx.redirectUrl ?? getRedirectUriFromSearch();\n const { data, isLoading, error } = useOAuthConsent({\n oauthClientId,\n scope,\n redirectUri: redirectUri || undefined,\n // TODO: Remove this once account portal is refactored to use this component\n enabled: !hasContextCallbacks,\n });\n\n // Hook returns camelCase `requiresConsent`; the render logic uses snake_case.\n const mappedHookScopes = data?.scopes?.map(s => ({\n scope: s.scope,\n description: s.description,\n requires_consent: s.requiresConsent,\n }));\n\n // Context (accounts portal path) wins over hook data (public path).\n const scopes = ctx.scopes ?? mappedHookScopes ?? [];\n const oauthApplicationName = ctx.oauthApplicationName ?? data?.oauthApplicationName ?? '';\n const oauthApplicationLogoUrl = ctx.oauthApplicationLogoUrl ?? data?.oauthApplicationLogoUrl;\n const oauthApplicationUrl = ctx.oauthApplicationUrl ?? data?.oauthApplicationUrl;\n const redirectUrl = ctx.redirectUrl ?? redirectUri;\n\n const hasOrgReadScope = scopes.some(s => s.scope === USER_ORG_READ_SCOPE);\n const orgSelectionEnabled = !!(hasOrgReadScope && organizationSettings.enabled);\n const orgOptions = orgSelectionEnabled\n ? (user?.organizationMemberships ?? []).map(m => ({\n value: m.organization.id,\n label: m.organization.name,\n logoUrl: m.organization.imageUrl,\n }))\n : [];\n const lastActiveOrgId = clerk.session?.lastActiveOrganizationId;\n const defaultOrg = orgOptions.find(o => o.value === lastActiveOrgId)?.value ?? orgOptions[0]?.value ?? null;\n const effectiveOrg = selectedOrg ?? defaultOrg;\n\n const { t } = useLocalizations();\n const domainAction = data?.redirectDomain ?? getRedirectDisplay(redirectUrl);\n const viewFullUrlText = t(localizationKeys('oauthConsent.viewFullUrl'));\n\n // When the OAuth app has no uploaded logo, fall back to a recognized client's\n // brand mark (Claude, ChatGPT, ...). Keyed on the trusted redirect domain, not\n // the app-owner-set name, so a look-alike name cannot borrow the branding.\n const knownClient = oauthApplicationLogoUrl ? undefined : getKnownOAuthClient(domainAction);\n\n // Error states only apply to the public flow.\n if (!hasContextCallbacks) {\n const errorMessage = !oauthClientId\n ? 'The client ID is missing.'\n : !redirectUrl\n ? 'The redirect URI is missing.'\n : error\n ? (error.message ?? 'Failed to load consent information.')\n : undefined;\n\n if (errorMessage) {\n return (\n <Card.Root>\n <Card.Content>\n <Card.Alert>{errorMessage}</Card.Alert>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n if (isLoading) {\n return (\n <Card.Root>\n <Card.Content>\n <LoadingCardContainer />\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n }\n\n const actionUrl = clerk.oauthApplication.buildConsentActionUrl({ clientId: oauthClientId });\n const forwardedParams = getForwardedParams();\n\n // Accounts portal path delegates to context callbacks; public path lets the form submit natively.\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n if (!hasContextCallbacks) {\n return;\n }\n e.preventDefault();\n const submitter = (e.nativeEvent as SubmitEvent).submitter as HTMLButtonElement | null;\n if (submitter?.value === 'true') {\n ctx.onAllow?.();\n } else {\n ctx.onDeny?.();\n }\n };\n\n const primaryIdentifier = user?.primaryEmailAddress?.emailAddress || user?.primaryPhoneNumber?.phoneNumber;\n\n const displayedScopes = scopes\n .filter(item => item.scope !== OFFLINE_ACCESS_SCOPE)\n .map(item => ({\n ...item,\n description:\n item.scope === PRIVATE_METADATA_SCOPE\n ? t(localizationKeys('oauthConsent.scopeList.privateMetadata', { applicationName }))\n : item.description,\n }));\n const hasOfflineAccess = scopes.some(item => item.scope === OFFLINE_ACCESS_SCOPE);\n\n return (\n <>\n <form\n method='POST'\n action={actionUrl}\n onSubmit={handleSubmit}\n >\n <Card.Root>\n <Card.Content>\n <Header.Root>\n {/* both have avatars */}\n {oauthApplicationLogoUrl && logoImageUrl && (\n <LogoGroup>\n <LogoGroupItem justify='end'>\n <LogoGroupItemContainer>\n <ApplicationLogo\n src={oauthApplicationLogoUrl}\n alt={oauthApplicationName}\n href={oauthApplicationUrl}\n isExternal\n />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n <LogoGroupSeparator />\n <LogoGroupItem justify='start'>\n <LogoGroupItemContainer>\n <ApplicationLogo />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n </LogoGroup>\n )}\n {/* only OAuth app has an avatar */}\n {oauthApplicationLogoUrl && !logoImageUrl && (\n <LogoGroup>\n <Box sx={{ position: 'relative' }}>\n <LogoGroupItemContainer>\n <ApplicationLogo\n src={oauthApplicationLogoUrl}\n alt={oauthApplicationName}\n href={oauthApplicationUrl}\n isExternal\n />\n </LogoGroupItemContainer>\n <LogoGroupItemContainer\n size='sm'\n sx={t => ({\n position: 'absolute',\n bottom: `calc(${t.space.$2x5} * -1)`,\n insetInlineEnd: `calc(${t.space.$2x5} * -1)`,\n })}\n >\n <LogoGroupIcon />\n </LogoGroupItemContainer>\n </Box>\n </LogoGroup>\n )}\n {/* only Clerk application has an avatar */}\n {!oauthApplicationLogoUrl && logoImageUrl && (\n <LogoGroup>\n <LogoGroupItem justify='end'>\n <LogoGroupItemContainer>\n <LogoGroupIcon\n icon={knownClient?.icon}\n iconSx={knownClient?.iconSx}\n label={knownClient?.name}\n />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n <LogoGroupSeparator />\n <LogoGroupItem justify='start'>\n <LogoGroupItemContainer>\n <ApplicationLogo />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n </LogoGroup>\n )}\n {/* no avatars */}\n {!oauthApplicationLogoUrl && !logoImageUrl && (\n <LogoGroup>\n <LogoGroupItemContainer>\n <LogoGroupIcon\n icon={knownClient?.icon}\n iconSx={knownClient?.iconSx}\n label={knownClient?.name}\n />\n </LogoGroupItemContainer>\n </LogoGroup>\n )}\n <Header.Title localizationKey={oauthApplicationName} />\n <Header.Subtitle\n localizationKey={localizationKeys('oauthConsent.subtitle', {\n applicationName,\n identifier: primaryIdentifier || '',\n })}\n />\n </Header.Root>\n {orgSelectionEnabled && orgOptions.length > 0 && effectiveOrg && (\n <OrgSelect\n options={orgOptions}\n value={effectiveOrg}\n onChange={setSelectedOrg}\n />\n )}\n {displayedScopes.length > 0 && (\n <ListGroup>\n <ListGroupHeader>\n <ListGroupHeaderTitle\n localizationKey={localizationKeys('oauthConsent.scopeList.title', {\n applicationName: oauthApplicationName,\n })}\n />\n </ListGroupHeader>\n <ListGroupContent>\n {displayedScopes.map(item => (\n <ListGroupItem key={item.scope}>\n <ListGroupItemLabel>{item.description || item.scope || ''}</ListGroupItemLabel>\n </ListGroupItem>\n ))}\n </ListGroupContent>\n </ListGroup>\n )}\n <Alert colorScheme='warning'>\n <Text\n colorScheme='warning'\n variant='caption'\n >\n <InlineAction\n text={t(\n localizationKeys('oauthConsent.warning', {\n applicationName: oauthApplicationName || applicationName,\n domainAction,\n }),\n )}\n actionText={domainAction}\n onClick={() => setIsUriModalOpen(true)}\n tooltipText={viewFullUrlText}\n />\n </Text>\n </Alert>\n <Grid\n columns={2}\n gap={3}\n >\n <Button\n type='submit'\n name='consented'\n value='false'\n colorScheme='secondary'\n variant='outline'\n localizationKey={localizationKeys('oauthConsent.action__deny')}\n />\n <Button\n type='submit'\n name='consented'\n value='true'\n localizationKey={localizationKeys('oauthConsent.action__allow')}\n />\n <Text\n sx={{ gridColumn: 'span 2' }}\n colorScheme='secondary'\n variant='caption'\n >\n <InlineAction\n text={t(localizationKeys('oauthConsent.redirectNotice', { domainAction }))}\n actionText={domainAction}\n onClick={() => setIsUriModalOpen(true)}\n tooltipText={viewFullUrlText}\n />\n {hasOfflineAccess && t(localizationKeys('oauthConsent.offlineAccessNotice'))}\n </Text>\n </Grid>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n {!hasContextCallbacks &&\n forwardedParams.map(([key, value]) => (\n <input\n key={key}\n type='hidden'\n name={key}\n value={value}\n />\n ))}\n {!hasContextCallbacks && orgSelectionEnabled && effectiveOrg && (\n <input\n type='hidden'\n name='organization_id'\n value={effectiveOrg}\n />\n )}\n </form>\n <RedirectUriModal\n isOpen={isUriModalOpen}\n onOpen={() => setIsUriModalOpen(true)}\n onClose={() => setIsUriModalOpen(false)}\n redirectUri={redirectUrl}\n oauthApplicationName={oauthApplicationName}\n />\n </>\n );\n}\n\ntype RedirectUriModalProps = {\n onOpen: () => void;\n onClose: () => void;\n isOpen: boolean;\n redirectUri: string;\n oauthApplicationName: string;\n};\n\nfunction RedirectUriModal({ onOpen, onClose, isOpen, redirectUri, oauthApplicationName }: RedirectUriModalProps) {\n if (!isOpen) {\n return null;\n }\n\n return (\n <Modal\n handleOpen={onOpen}\n handleClose={onClose}\n >\n <Card.Root>\n <Card.Content>\n <Header.Root>\n <Header.Title localizationKey={localizationKeys('oauthConsent.redirectUriModal.title')} />\n <Header.Subtitle\n localizationKey={localizationKeys('oauthConsent.redirectUriModal.subtitle', {\n applicationName: oauthApplicationName,\n })}\n />\n </Header.Root>\n <Textarea\n style={{ maxHeight: 'none' }}\n cols={50}\n rows={6}\n defaultValue={redirectUri}\n readOnly\n />\n </Card.Content>\n </Card.Root>\n </Modal>\n );\n}\n\nconst AuthenticatedRoutes = withCoreUserGuard(withCardStateProvider(_OAuthConsent));\n\nconst OAuthConsentInternal = () => {\n return (\n <Flow.Root flow='oauthConsent'>\n <Flow.Part>\n <Switch>\n <Route>\n <AuthenticatedRoutes />\n </Route>\n </Switch>\n </Flow.Part>\n </Flow.Root>\n );\n};\n\nexport const OAuthConsent = OAuthConsentInternal;\n"],"mappings":"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"}
|
|
@@ -220,7 +220,7 @@ function OAuthDeviceVerificationInternal() {
|
|
|
220
220
|
value: effectiveOrg,
|
|
221
221
|
onChange: setSelectedOrg
|
|
222
222
|
}),
|
|
223
|
-
/* @__PURE__ */ jsxs(ListGroup, { children: [/* @__PURE__ */ jsx(ListGroupHeader, { children: /* @__PURE__ */ jsx(ListGroupHeaderTitle, { localizationKey: localizationKeys("oauthDeviceVerification.confirmation.scopeListTitle", { applicationName: data.oauthApplicationName }) }) }), /* @__PURE__ */ jsx(ListGroupContent, { children: displayedScopes.map((scope) => /* @__PURE__ */ jsx(ListGroupItem, { children: /* @__PURE__ */ jsx(ListGroupItemLabel, { children: scope.description || scope.scope }) }, scope.scope)) })] }),
|
|
223
|
+
displayedScopes.length > 0 && /* @__PURE__ */ jsxs(ListGroup, { children: [/* @__PURE__ */ jsx(ListGroupHeader, { children: /* @__PURE__ */ jsx(ListGroupHeaderTitle, { localizationKey: localizationKeys("oauthDeviceVerification.confirmation.scopeListTitle", { applicationName: data.oauthApplicationName }) }) }), /* @__PURE__ */ jsx(ListGroupContent, { children: displayedScopes.map((scope) => /* @__PURE__ */ jsx(ListGroupItem, { children: /* @__PURE__ */ jsx(ListGroupItemLabel, { children: scope.description || scope.scope }) }, scope.scope)) })] }),
|
|
224
224
|
/* @__PURE__ */ jsx(Alert, {
|
|
225
225
|
colorScheme: "warning",
|
|
226
226
|
children: /* @__PURE__ */ jsx(Text, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OAuthDeviceVerification.js","names":[],"sources":["../../../../src/components/OAuthDeviceVerification/OAuthDeviceVerification.tsx"],"sourcesContent":["import { isClerkAPIResponseError } from '@clerk/shared/error';\nimport { useClerk, useOAuthDeviceVerification, useUser } from '@clerk/shared/react';\nimport type { OAuthDeviceVerificationInfo } from '@clerk/shared/types';\nimport type { FormEventHandler } from 'react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { useEnvironment, withCoreUserGuard } from '@/ui/contexts';\nimport { Button, Col, Flow, Grid, Image, localizationKeys, Text, useLocalizations } from '@/ui/customizables';\nimport { ApplicationLogo } from '@/ui/elements/ApplicationLogo';\nimport { Card } from '@/ui/elements/Card';\nimport { withCardStateProvider } from '@/ui/elements/contexts';\nimport { Form } from '@/ui/elements/Form';\nimport { Header } from '@/ui/elements/Header';\nimport { LoadingCardContainer } from '@/ui/elements/LoadingCard';\nimport { Alert } from '@/ui/primitives';\nimport { Route, Switch } from '@/ui/router';\nimport { useFormControl } from '@/ui/utils/useFormControl';\n\nimport {\n ListGroup,\n ListGroupContent,\n ListGroupHeader,\n ListGroupHeaderTitle,\n ListGroupItem,\n ListGroupItemLabel,\n} from '../OAuthConsent/ListGroup';\nimport {\n LogoGroup,\n LogoGroupIcon,\n LogoGroupItem,\n LogoGroupItemContainer,\n LogoGroupSeparator,\n} from '../OAuthConsent/LogoGroup';\nimport { OrgSelect } from '../OAuthConsent/OrgSelect';\nimport { OAuthDeviceVerificationCodeInput } from './OAuthDeviceVerificationCodeInput';\nimport { getOAuthDeviceUserCodeFromSearch, isValidOAuthDeviceUserCode, normalizeOAuthDeviceUserCode } from './utils';\n\nconst USER_ORG_READ_SCOPE = 'user:org:read';\nconst OFFLINE_ACCESS_SCOPE = 'offline_access';\nconst PRIVATE_METADATA_SCOPE = 'private_metadata';\n\ntype View =\n | 'entry'\n | 'loading'\n | 'confirmation'\n | 'approved'\n | 'alreadyApproved'\n | 'denied'\n | 'alreadyDenied'\n | 'consumed'\n | 'expired'\n | 'rateLimited'\n | 'alreadyDecided'\n | 'error';\n\nfunction getErrorCode(error: unknown): string | undefined {\n return isClerkAPIResponseError(error) ? error.errors?.[0]?.code : undefined;\n}\n\nfunction OAuthDeviceVerificationInternal() {\n const clerk = useClerk();\n const { user } = useUser();\n const {\n displayConfig: { applicationName, logoImageUrl },\n organizationSettings,\n } = useEnvironment();\n const { t } = useLocalizations();\n const verification = useOAuthDeviceVerification();\n const [view, setView] = useState<View>('entry');\n const [selectedOrg, setSelectedOrg] = useState<string | null>(null);\n const [submittingDecision, setSubmittingDecision] = useState<'approve' | 'deny' | null>(null);\n const handledPrefill = useRef(false);\n const decisionInProgress = useRef(false);\n\n const codeControl = useFormControl('userCode', '', {\n type: 'text',\n label: localizationKeys('oauthDeviceVerification.start.userCodeLabel'),\n transformer: normalizeOAuthDeviceUserCode,\n isRequired: true,\n });\n\n const showLookupError = useCallback(\n (error: unknown) => {\n switch (getErrorCode(error)) {\n case 'resource_not_found':\n setView('entry');\n codeControl.setError(t(localizationKeys('oauthDeviceVerification.error.unknownCode')));\n break;\n case 'oauth_device_code_expired':\n setView('expired');\n break;\n case 'too_many_requests':\n setView('rateLimited');\n break;\n default:\n setView('error');\n }\n },\n [codeControl, t],\n );\n\n const showLookupResult = useCallback((info: OAuthDeviceVerificationInfo) => {\n switch (info.status) {\n case 'pending':\n setView('confirmation');\n break;\n case 'approved':\n setView('alreadyApproved');\n break;\n case 'denied':\n setView('alreadyDenied');\n break;\n case 'consumed':\n setView('consumed');\n break;\n default:\n setView('error');\n }\n }, []);\n\n const lookup = useCallback(\n async (userCode: string) => {\n codeControl.clearFeedback();\n setView('loading');\n try {\n const info = await verification.lookup({ userCode });\n showLookupResult(info);\n } catch (error) {\n showLookupError(error);\n }\n },\n [codeControl, showLookupError, showLookupResult, verification],\n );\n\n useEffect(() => {\n if (handledPrefill.current) {\n return;\n }\n handledPrefill.current = true;\n\n const userCode = getOAuthDeviceUserCodeFromSearch();\n if (!userCode) {\n return;\n }\n\n codeControl.setValue(normalizeOAuthDeviceUserCode(userCode));\n if (!isValidOAuthDeviceUserCode(userCode)) {\n codeControl.setError(t(localizationKeys('oauthDeviceVerification.error.invalidCode')));\n return;\n }\n\n void lookup(normalizeOAuthDeviceUserCode(userCode));\n }, [codeControl, lookup, t]);\n\n const handleLookup: FormEventHandler<HTMLFormElement> = event => {\n event.preventDefault();\n const userCode = normalizeOAuthDeviceUserCode(codeControl.value);\n if (!isValidOAuthDeviceUserCode(userCode)) {\n codeControl.setError(t(localizationKeys('oauthDeviceVerification.error.invalidCode')));\n return;\n }\n void lookup(userCode);\n };\n\n const data = verification.data;\n const hasOrgReadScope = data?.scopes.some(scope => scope.scope === USER_ORG_READ_SCOPE) ?? false;\n const orgSelectionEnabled = hasOrgReadScope && organizationSettings.enabled;\n const orgOptions = orgSelectionEnabled\n ? (user?.organizationMemberships ?? []).map(membership => ({\n value: membership.organization.id,\n label: membership.organization.name,\n logoUrl: membership.organization.imageUrl,\n }))\n : [];\n const lastActiveOrgId = clerk.session?.lastActiveOrganizationId;\n const defaultOrg = orgOptions.find(option => option.value === lastActiveOrgId)?.value ?? orgOptions[0]?.value ?? null;\n const effectiveOrg = selectedOrg ?? defaultOrg;\n\n const showDecisionError = (error: unknown) => {\n switch (getErrorCode(error)) {\n case 'oauth_device_code_expired':\n setView('expired');\n break;\n case 'too_many_requests':\n setView('rateLimited');\n break;\n case 'bad_request':\n setView('alreadyDecided');\n break;\n default:\n setView('error');\n }\n };\n\n const handleApprove = async () => {\n if (decisionInProgress.current) {\n return;\n }\n decisionInProgress.current = true;\n const userCode = normalizeOAuthDeviceUserCode(codeControl.value);\n setSubmittingDecision('approve');\n try {\n await verification.approve({ userCode, organizationId: effectiveOrg ?? undefined });\n setView('approved');\n } catch (error) {\n showDecisionError(error);\n } finally {\n decisionInProgress.current = false;\n setSubmittingDecision(null);\n }\n };\n\n const handleDeny = async () => {\n if (decisionInProgress.current) {\n return;\n }\n decisionInProgress.current = true;\n const userCode = normalizeOAuthDeviceUserCode(codeControl.value);\n setSubmittingDecision('deny');\n try {\n await verification.deny({ userCode });\n setView('denied');\n } catch (error) {\n showDecisionError(error);\n } finally {\n decisionInProgress.current = false;\n setSubmittingDecision(null);\n }\n };\n\n const reset = () => {\n decisionInProgress.current = false;\n verification.reset();\n codeControl.setValue('');\n codeControl.clearFeedback();\n setSelectedOrg(null);\n setView('entry');\n };\n\n if (view === 'loading') {\n return (\n <Card.Root>\n <Card.Content>\n <LoadingCardContainer />\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n if (view === 'entry') {\n return (\n <Card.Root>\n <Card.Content>\n <Header.Root showLogo>\n <Header.Title localizationKey={localizationKeys('oauthDeviceVerification.start.title')} />\n <Header.Subtitle localizationKey={localizationKeys('oauthDeviceVerification.start.subtitle')} />\n </Header.Root>\n <Form.Root onSubmit={handleLookup}>\n <Form.ControlRow elementId={codeControl.id}>\n <Form.CommonInputWrapper {...codeControl.props}>\n <OAuthDeviceVerificationCodeInput control={codeControl} />\n </Form.CommonInputWrapper>\n </Form.ControlRow>\n <Form.SubmitButton localizationKey={localizationKeys('oauthDeviceVerification.start.action__continue')} />\n </Form.Root>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n if (view === 'confirmation' && data) {\n const primaryIdentifier = user?.primaryEmailAddress?.emailAddress || user?.primaryPhoneNumber?.phoneNumber || '';\n const displayedScopes = data.scopes\n .filter(scope => scope.scope !== OFFLINE_ACCESS_SCOPE)\n .map(scope => ({\n ...scope,\n description:\n scope.scope === PRIVATE_METADATA_SCOPE\n ? t(\n localizationKeys('oauthConsent.scopeList.privateMetadata', {\n applicationName,\n }),\n )\n : scope.description,\n }));\n const hasOfflineAccess = data.scopes.some(scope => scope.scope === OFFLINE_ACCESS_SCOPE);\n return (\n <Card.Root>\n <Card.Content>\n <Header.Root>\n <DeviceLogo\n applicationName={data.oauthApplicationName}\n logoUrl={data.oauthApplicationLogoUrl}\n showClerkLogo={Boolean(logoImageUrl)}\n />\n <Header.Title\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.title', {\n applicationName: data.oauthApplicationName,\n })}\n />\n <Header.Subtitle\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.subtitle', {\n identifier: primaryIdentifier,\n })}\n />\n </Header.Root>\n {orgSelectionEnabled && orgOptions.length > 0 && effectiveOrg && (\n <OrgSelect\n options={orgOptions}\n value={effectiveOrg}\n onChange={setSelectedOrg}\n />\n )}\n <ListGroup>\n <ListGroupHeader>\n <ListGroupHeaderTitle\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.scopeListTitle', {\n applicationName: data.oauthApplicationName,\n })}\n />\n </ListGroupHeader>\n <ListGroupContent>\n {displayedScopes.map(scope => (\n <ListGroupItem key={scope.scope}>\n <ListGroupItemLabel>{scope.description || scope.scope}</ListGroupItemLabel>\n </ListGroupItem>\n ))}\n </ListGroupContent>\n </ListGroup>\n <Alert colorScheme='warning'>\n <Text\n colorScheme='warning'\n variant='caption'\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.warning')}\n />\n </Alert>\n <Grid\n columns={2}\n gap={3}\n >\n <Button\n colorScheme='secondary'\n variant='outline'\n isLoading={submittingDecision === 'deny' && verification.isSubmitting}\n isDisabled={verification.isSubmitting}\n onClick={() => void handleDeny()}\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.action__deny')}\n />\n <Button\n isLoading={submittingDecision === 'approve' && verification.isSubmitting}\n isDisabled={verification.isSubmitting}\n onClick={() => void handleApprove()}\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.action__approve')}\n />\n {hasOfflineAccess && (\n <Text\n sx={{ gridColumn: 'span 2' }}\n colorScheme='secondary'\n variant='caption'\n localizationKey={localizationKeys('oauthConsent.offlineAccessNotice')}\n />\n )}\n </Grid>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n if (view === 'confirmation') {\n return (\n <Card.Root>\n <Card.Content>\n <LoadingCardContainer />\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n const terminal = getTerminalContent(view);\n return (\n <Card.Root>\n <Card.Content>\n <Col gap={6}>\n <Header.Root showLogo>\n <Header.Title localizationKey={localizationKeys(terminal.title)} />\n <Header.Subtitle localizationKey={localizationKeys(terminal.subtitle)} />\n </Header.Root>\n {terminal.canReset && (\n <Button\n block\n onClick={reset}\n localizationKey={localizationKeys('oauthDeviceVerification.action__tryAnotherCode')}\n />\n )}\n </Col>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n}\n\nfunction DeviceLogo({\n applicationName,\n logoUrl,\n showClerkLogo,\n}: {\n applicationName: string;\n logoUrl: string | null;\n showClerkLogo: boolean;\n}) {\n const applicationMark = logoUrl ? (\n <Image\n src={logoUrl}\n alt={applicationName}\n sx={{ width: '100%', height: '100%', objectFit: 'contain' }}\n />\n ) : (\n <LogoGroupIcon label={applicationName} />\n );\n\n if (!showClerkLogo) {\n return (\n <LogoGroup>\n <LogoGroupItemContainer>{applicationMark}</LogoGroupItemContainer>\n </LogoGroup>\n );\n }\n\n return (\n <LogoGroup>\n <LogoGroupItem justify='end'>\n <LogoGroupItemContainer>{applicationMark}</LogoGroupItemContainer>\n </LogoGroupItem>\n <LogoGroupSeparator />\n <LogoGroupItem justify='start'>\n <LogoGroupItemContainer>\n <ApplicationLogo />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n </LogoGroup>\n );\n}\n\nfunction getTerminalContent(view: Exclude<View, 'entry' | 'loading' | 'confirmation'>): {\n title: Parameters<typeof localizationKeys>[0];\n subtitle: Parameters<typeof localizationKeys>[0];\n canReset: boolean;\n} {\n switch (view) {\n case 'approved':\n return {\n title: 'oauthDeviceVerification.status.approvedTitle',\n subtitle: 'oauthDeviceVerification.status.approvedSubtitle',\n canReset: false,\n };\n case 'alreadyApproved':\n return {\n title: 'oauthDeviceVerification.status.alreadyApprovedTitle',\n subtitle: 'oauthDeviceVerification.status.alreadyApprovedSubtitle',\n canReset: false,\n };\n case 'denied':\n return {\n title: 'oauthDeviceVerification.status.deniedTitle',\n subtitle: 'oauthDeviceVerification.status.deniedSubtitle',\n canReset: false,\n };\n case 'alreadyDenied':\n return {\n title: 'oauthDeviceVerification.status.alreadyDeniedTitle',\n subtitle: 'oauthDeviceVerification.status.alreadyDeniedSubtitle',\n canReset: false,\n };\n case 'consumed':\n return {\n title: 'oauthDeviceVerification.status.consumedTitle',\n subtitle: 'oauthDeviceVerification.status.consumedSubtitle',\n canReset: false,\n };\n case 'expired':\n return {\n title: 'oauthDeviceVerification.error.expiredTitle',\n subtitle: 'oauthDeviceVerification.error.expiredSubtitle',\n canReset: false,\n };\n case 'rateLimited':\n return {\n title: 'oauthDeviceVerification.error.rateLimitedTitle',\n subtitle: 'oauthDeviceVerification.error.rateLimitedSubtitle',\n canReset: false,\n };\n case 'alreadyDecided':\n return {\n title: 'oauthDeviceVerification.status.alreadyDecidedTitle',\n subtitle: 'oauthDeviceVerification.status.alreadyDecidedSubtitle',\n canReset: false,\n };\n case 'error':\n return {\n title: 'oauthDeviceVerification.error.genericTitle',\n subtitle: 'oauthDeviceVerification.error.genericSubtitle',\n canReset: true,\n };\n }\n}\n\nconst AuthenticatedRoutes = withCoreUserGuard(withCardStateProvider(OAuthDeviceVerificationInternal));\n\nexport const OAuthDeviceVerification = () => (\n <Flow.Root flow='oauthDeviceVerification'>\n <Flow.Part>\n <Switch>\n <Route>\n <AuthenticatedRoutes />\n </Route>\n </Switch>\n </Flow.Part>\n </Flow.Root>\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OAuthDeviceVerification.js","names":[],"sources":["../../../../src/components/OAuthDeviceVerification/OAuthDeviceVerification.tsx"],"sourcesContent":["import { isClerkAPIResponseError } from '@clerk/shared/error';\nimport { useClerk, useOAuthDeviceVerification, useUser } from '@clerk/shared/react';\nimport type { OAuthDeviceVerificationInfo } from '@clerk/shared/types';\nimport type { FormEventHandler } from 'react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { useEnvironment, withCoreUserGuard } from '@/ui/contexts';\nimport { Button, Col, Flow, Grid, Image, localizationKeys, Text, useLocalizations } from '@/ui/customizables';\nimport { ApplicationLogo } from '@/ui/elements/ApplicationLogo';\nimport { Card } from '@/ui/elements/Card';\nimport { withCardStateProvider } from '@/ui/elements/contexts';\nimport { Form } from '@/ui/elements/Form';\nimport { Header } from '@/ui/elements/Header';\nimport { LoadingCardContainer } from '@/ui/elements/LoadingCard';\nimport { Alert } from '@/ui/primitives';\nimport { Route, Switch } from '@/ui/router';\nimport { useFormControl } from '@/ui/utils/useFormControl';\n\nimport {\n ListGroup,\n ListGroupContent,\n ListGroupHeader,\n ListGroupHeaderTitle,\n ListGroupItem,\n ListGroupItemLabel,\n} from '../OAuthConsent/ListGroup';\nimport {\n LogoGroup,\n LogoGroupIcon,\n LogoGroupItem,\n LogoGroupItemContainer,\n LogoGroupSeparator,\n} from '../OAuthConsent/LogoGroup';\nimport { OrgSelect } from '../OAuthConsent/OrgSelect';\nimport { OAuthDeviceVerificationCodeInput } from './OAuthDeviceVerificationCodeInput';\nimport { getOAuthDeviceUserCodeFromSearch, isValidOAuthDeviceUserCode, normalizeOAuthDeviceUserCode } from './utils';\n\nconst USER_ORG_READ_SCOPE = 'user:org:read';\nconst OFFLINE_ACCESS_SCOPE = 'offline_access';\nconst PRIVATE_METADATA_SCOPE = 'private_metadata';\n\ntype View =\n | 'entry'\n | 'loading'\n | 'confirmation'\n | 'approved'\n | 'alreadyApproved'\n | 'denied'\n | 'alreadyDenied'\n | 'consumed'\n | 'expired'\n | 'rateLimited'\n | 'alreadyDecided'\n | 'error';\n\nfunction getErrorCode(error: unknown): string | undefined {\n return isClerkAPIResponseError(error) ? error.errors?.[0]?.code : undefined;\n}\n\nfunction OAuthDeviceVerificationInternal() {\n const clerk = useClerk();\n const { user } = useUser();\n const {\n displayConfig: { applicationName, logoImageUrl },\n organizationSettings,\n } = useEnvironment();\n const { t } = useLocalizations();\n const verification = useOAuthDeviceVerification();\n const [view, setView] = useState<View>('entry');\n const [selectedOrg, setSelectedOrg] = useState<string | null>(null);\n const [submittingDecision, setSubmittingDecision] = useState<'approve' | 'deny' | null>(null);\n const handledPrefill = useRef(false);\n const decisionInProgress = useRef(false);\n\n const codeControl = useFormControl('userCode', '', {\n type: 'text',\n label: localizationKeys('oauthDeviceVerification.start.userCodeLabel'),\n transformer: normalizeOAuthDeviceUserCode,\n isRequired: true,\n });\n\n const showLookupError = useCallback(\n (error: unknown) => {\n switch (getErrorCode(error)) {\n case 'resource_not_found':\n setView('entry');\n codeControl.setError(t(localizationKeys('oauthDeviceVerification.error.unknownCode')));\n break;\n case 'oauth_device_code_expired':\n setView('expired');\n break;\n case 'too_many_requests':\n setView('rateLimited');\n break;\n default:\n setView('error');\n }\n },\n [codeControl, t],\n );\n\n const showLookupResult = useCallback((info: OAuthDeviceVerificationInfo) => {\n switch (info.status) {\n case 'pending':\n setView('confirmation');\n break;\n case 'approved':\n setView('alreadyApproved');\n break;\n case 'denied':\n setView('alreadyDenied');\n break;\n case 'consumed':\n setView('consumed');\n break;\n default:\n setView('error');\n }\n }, []);\n\n const lookup = useCallback(\n async (userCode: string) => {\n codeControl.clearFeedback();\n setView('loading');\n try {\n const info = await verification.lookup({ userCode });\n showLookupResult(info);\n } catch (error) {\n showLookupError(error);\n }\n },\n [codeControl, showLookupError, showLookupResult, verification],\n );\n\n useEffect(() => {\n if (handledPrefill.current) {\n return;\n }\n handledPrefill.current = true;\n\n const userCode = getOAuthDeviceUserCodeFromSearch();\n if (!userCode) {\n return;\n }\n\n codeControl.setValue(normalizeOAuthDeviceUserCode(userCode));\n if (!isValidOAuthDeviceUserCode(userCode)) {\n codeControl.setError(t(localizationKeys('oauthDeviceVerification.error.invalidCode')));\n return;\n }\n\n void lookup(normalizeOAuthDeviceUserCode(userCode));\n }, [codeControl, lookup, t]);\n\n const handleLookup: FormEventHandler<HTMLFormElement> = event => {\n event.preventDefault();\n const userCode = normalizeOAuthDeviceUserCode(codeControl.value);\n if (!isValidOAuthDeviceUserCode(userCode)) {\n codeControl.setError(t(localizationKeys('oauthDeviceVerification.error.invalidCode')));\n return;\n }\n void lookup(userCode);\n };\n\n const data = verification.data;\n const hasOrgReadScope = data?.scopes.some(scope => scope.scope === USER_ORG_READ_SCOPE) ?? false;\n const orgSelectionEnabled = hasOrgReadScope && organizationSettings.enabled;\n const orgOptions = orgSelectionEnabled\n ? (user?.organizationMemberships ?? []).map(membership => ({\n value: membership.organization.id,\n label: membership.organization.name,\n logoUrl: membership.organization.imageUrl,\n }))\n : [];\n const lastActiveOrgId = clerk.session?.lastActiveOrganizationId;\n const defaultOrg = orgOptions.find(option => option.value === lastActiveOrgId)?.value ?? orgOptions[0]?.value ?? null;\n const effectiveOrg = selectedOrg ?? defaultOrg;\n\n const showDecisionError = (error: unknown) => {\n switch (getErrorCode(error)) {\n case 'oauth_device_code_expired':\n setView('expired');\n break;\n case 'too_many_requests':\n setView('rateLimited');\n break;\n case 'bad_request':\n setView('alreadyDecided');\n break;\n default:\n setView('error');\n }\n };\n\n const handleApprove = async () => {\n if (decisionInProgress.current) {\n return;\n }\n decisionInProgress.current = true;\n const userCode = normalizeOAuthDeviceUserCode(codeControl.value);\n setSubmittingDecision('approve');\n try {\n await verification.approve({ userCode, organizationId: effectiveOrg ?? undefined });\n setView('approved');\n } catch (error) {\n showDecisionError(error);\n } finally {\n decisionInProgress.current = false;\n setSubmittingDecision(null);\n }\n };\n\n const handleDeny = async () => {\n if (decisionInProgress.current) {\n return;\n }\n decisionInProgress.current = true;\n const userCode = normalizeOAuthDeviceUserCode(codeControl.value);\n setSubmittingDecision('deny');\n try {\n await verification.deny({ userCode });\n setView('denied');\n } catch (error) {\n showDecisionError(error);\n } finally {\n decisionInProgress.current = false;\n setSubmittingDecision(null);\n }\n };\n\n const reset = () => {\n decisionInProgress.current = false;\n verification.reset();\n codeControl.setValue('');\n codeControl.clearFeedback();\n setSelectedOrg(null);\n setView('entry');\n };\n\n if (view === 'loading') {\n return (\n <Card.Root>\n <Card.Content>\n <LoadingCardContainer />\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n if (view === 'entry') {\n return (\n <Card.Root>\n <Card.Content>\n <Header.Root showLogo>\n <Header.Title localizationKey={localizationKeys('oauthDeviceVerification.start.title')} />\n <Header.Subtitle localizationKey={localizationKeys('oauthDeviceVerification.start.subtitle')} />\n </Header.Root>\n <Form.Root onSubmit={handleLookup}>\n <Form.ControlRow elementId={codeControl.id}>\n <Form.CommonInputWrapper {...codeControl.props}>\n <OAuthDeviceVerificationCodeInput control={codeControl} />\n </Form.CommonInputWrapper>\n </Form.ControlRow>\n <Form.SubmitButton localizationKey={localizationKeys('oauthDeviceVerification.start.action__continue')} />\n </Form.Root>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n if (view === 'confirmation' && data) {\n const primaryIdentifier = user?.primaryEmailAddress?.emailAddress || user?.primaryPhoneNumber?.phoneNumber || '';\n const displayedScopes = data.scopes\n .filter(scope => scope.scope !== OFFLINE_ACCESS_SCOPE)\n .map(scope => ({\n ...scope,\n description:\n scope.scope === PRIVATE_METADATA_SCOPE\n ? t(\n localizationKeys('oauthConsent.scopeList.privateMetadata', {\n applicationName,\n }),\n )\n : scope.description,\n }));\n const hasOfflineAccess = data.scopes.some(scope => scope.scope === OFFLINE_ACCESS_SCOPE);\n return (\n <Card.Root>\n <Card.Content>\n <Header.Root>\n <DeviceLogo\n applicationName={data.oauthApplicationName}\n logoUrl={data.oauthApplicationLogoUrl}\n showClerkLogo={Boolean(logoImageUrl)}\n />\n <Header.Title\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.title', {\n applicationName: data.oauthApplicationName,\n })}\n />\n <Header.Subtitle\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.subtitle', {\n identifier: primaryIdentifier,\n })}\n />\n </Header.Root>\n {orgSelectionEnabled && orgOptions.length > 0 && effectiveOrg && (\n <OrgSelect\n options={orgOptions}\n value={effectiveOrg}\n onChange={setSelectedOrg}\n />\n )}\n {displayedScopes.length > 0 && (\n <ListGroup>\n <ListGroupHeader>\n <ListGroupHeaderTitle\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.scopeListTitle', {\n applicationName: data.oauthApplicationName,\n })}\n />\n </ListGroupHeader>\n <ListGroupContent>\n {displayedScopes.map(scope => (\n <ListGroupItem key={scope.scope}>\n <ListGroupItemLabel>{scope.description || scope.scope}</ListGroupItemLabel>\n </ListGroupItem>\n ))}\n </ListGroupContent>\n </ListGroup>\n )}\n <Alert colorScheme='warning'>\n <Text\n colorScheme='warning'\n variant='caption'\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.warning')}\n />\n </Alert>\n <Grid\n columns={2}\n gap={3}\n >\n <Button\n colorScheme='secondary'\n variant='outline'\n isLoading={submittingDecision === 'deny' && verification.isSubmitting}\n isDisabled={verification.isSubmitting}\n onClick={() => void handleDeny()}\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.action__deny')}\n />\n <Button\n isLoading={submittingDecision === 'approve' && verification.isSubmitting}\n isDisabled={verification.isSubmitting}\n onClick={() => void handleApprove()}\n localizationKey={localizationKeys('oauthDeviceVerification.confirmation.action__approve')}\n />\n {hasOfflineAccess && (\n <Text\n sx={{ gridColumn: 'span 2' }}\n colorScheme='secondary'\n variant='caption'\n localizationKey={localizationKeys('oauthConsent.offlineAccessNotice')}\n />\n )}\n </Grid>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n if (view === 'confirmation') {\n return (\n <Card.Root>\n <Card.Content>\n <LoadingCardContainer />\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n }\n\n const terminal = getTerminalContent(view);\n return (\n <Card.Root>\n <Card.Content>\n <Col gap={6}>\n <Header.Root showLogo>\n <Header.Title localizationKey={localizationKeys(terminal.title)} />\n <Header.Subtitle localizationKey={localizationKeys(terminal.subtitle)} />\n </Header.Root>\n {terminal.canReset && (\n <Button\n block\n onClick={reset}\n localizationKey={localizationKeys('oauthDeviceVerification.action__tryAnotherCode')}\n />\n )}\n </Col>\n </Card.Content>\n <Card.Footer />\n </Card.Root>\n );\n}\n\nfunction DeviceLogo({\n applicationName,\n logoUrl,\n showClerkLogo,\n}: {\n applicationName: string;\n logoUrl: string | null;\n showClerkLogo: boolean;\n}) {\n const applicationMark = logoUrl ? (\n <Image\n src={logoUrl}\n alt={applicationName}\n sx={{ width: '100%', height: '100%', objectFit: 'contain' }}\n />\n ) : (\n <LogoGroupIcon label={applicationName} />\n );\n\n if (!showClerkLogo) {\n return (\n <LogoGroup>\n <LogoGroupItemContainer>{applicationMark}</LogoGroupItemContainer>\n </LogoGroup>\n );\n }\n\n return (\n <LogoGroup>\n <LogoGroupItem justify='end'>\n <LogoGroupItemContainer>{applicationMark}</LogoGroupItemContainer>\n </LogoGroupItem>\n <LogoGroupSeparator />\n <LogoGroupItem justify='start'>\n <LogoGroupItemContainer>\n <ApplicationLogo />\n </LogoGroupItemContainer>\n </LogoGroupItem>\n </LogoGroup>\n );\n}\n\nfunction getTerminalContent(view: Exclude<View, 'entry' | 'loading' | 'confirmation'>): {\n title: Parameters<typeof localizationKeys>[0];\n subtitle: Parameters<typeof localizationKeys>[0];\n canReset: boolean;\n} {\n switch (view) {\n case 'approved':\n return {\n title: 'oauthDeviceVerification.status.approvedTitle',\n subtitle: 'oauthDeviceVerification.status.approvedSubtitle',\n canReset: false,\n };\n case 'alreadyApproved':\n return {\n title: 'oauthDeviceVerification.status.alreadyApprovedTitle',\n subtitle: 'oauthDeviceVerification.status.alreadyApprovedSubtitle',\n canReset: false,\n };\n case 'denied':\n return {\n title: 'oauthDeviceVerification.status.deniedTitle',\n subtitle: 'oauthDeviceVerification.status.deniedSubtitle',\n canReset: false,\n };\n case 'alreadyDenied':\n return {\n title: 'oauthDeviceVerification.status.alreadyDeniedTitle',\n subtitle: 'oauthDeviceVerification.status.alreadyDeniedSubtitle',\n canReset: false,\n };\n case 'consumed':\n return {\n title: 'oauthDeviceVerification.status.consumedTitle',\n subtitle: 'oauthDeviceVerification.status.consumedSubtitle',\n canReset: false,\n };\n case 'expired':\n return {\n title: 'oauthDeviceVerification.error.expiredTitle',\n subtitle: 'oauthDeviceVerification.error.expiredSubtitle',\n canReset: false,\n };\n case 'rateLimited':\n return {\n title: 'oauthDeviceVerification.error.rateLimitedTitle',\n subtitle: 'oauthDeviceVerification.error.rateLimitedSubtitle',\n canReset: false,\n };\n case 'alreadyDecided':\n return {\n title: 'oauthDeviceVerification.status.alreadyDecidedTitle',\n subtitle: 'oauthDeviceVerification.status.alreadyDecidedSubtitle',\n canReset: false,\n };\n case 'error':\n return {\n title: 'oauthDeviceVerification.error.genericTitle',\n subtitle: 'oauthDeviceVerification.error.genericSubtitle',\n canReset: true,\n };\n }\n}\n\nconst AuthenticatedRoutes = withCoreUserGuard(withCardStateProvider(OAuthDeviceVerificationInternal));\n\nexport const OAuthDeviceVerification = () => (\n <Flow.Root flow='oauthDeviceVerification'>\n <Flow.Part>\n <Switch>\n <Route>\n <AuthenticatedRoutes />\n </Route>\n </Switch>\n </Flow.Part>\n </Flow.Root>\n);\n"],"mappings":"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"}
|