@clerk/ui 1.0.0-snapshot.v20251203203405 → 1.0.0-snapshot.v20251204143242

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.
Files changed (140) hide show
  1. package/dist/{browser/207_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → 207_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +1 -1
  2. package/dist/{browser/360_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → 360_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +1 -1
  3. package/dist/573_ui_87d4d5_1.0.0-snapshot.v20251204143242.js +1 -0
  4. package/dist/{browser/970_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → 970_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +1 -1
  5. package/dist/ClerkUi.js +2 -2
  6. package/dist/Components.js.map +1 -1
  7. package/dist/{browser/blankcaptcha_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → blankcaptcha_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +1 -1
  8. package/dist/{browser/checkout_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → checkout_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +2 -2
  9. package/dist/components/OrganizationProfile/InviteMembersScreen.js +4 -11
  10. package/dist/components/OrganizationProfile/InviteMembersScreen.js.map +1 -1
  11. package/dist/components/OrganizationProfile/OrganizationMembers.js +3 -6
  12. package/dist/components/OrganizationProfile/OrganizationMembers.js.map +1 -1
  13. package/dist/components/OrganizationProfile/OrganizationMembersTabInvitations.js +51 -56
  14. package/dist/components/OrganizationProfile/OrganizationMembersTabInvitations.js.map +1 -1
  15. package/dist/components/OrganizationProfile/OrganizationMembersTabRequests.js +51 -56
  16. package/dist/components/OrganizationProfile/OrganizationMembersTabRequests.js.map +1 -1
  17. package/dist/components/OrganizationSwitcher/OrganizationSwitcherPopover.js +4 -39
  18. package/dist/components/OrganizationSwitcher/OrganizationSwitcherPopover.js.map +1 -1
  19. package/dist/components/SignIn/AlternativeMethods.js +4 -1
  20. package/dist/components/SignIn/AlternativeMethods.js.map +1 -1
  21. package/dist/components/SignIn/SignInFactorOne.js +11 -5
  22. package/dist/components/SignIn/SignInFactorOne.js.map +1 -1
  23. package/dist/components/SignIn/SignInFactorOnePasswordCard.js +24 -14
  24. package/dist/components/SignIn/SignInFactorOnePasswordCard.js.map +1 -1
  25. package/dist/components/SignIn/SignInFactorTwoCodeForm.js +8 -3
  26. package/dist/components/SignIn/SignInFactorTwoCodeForm.js.map +1 -1
  27. package/dist/components/SignIn/SignInSocialButtons.js +18 -2
  28. package/dist/components/SignIn/SignInSocialButtons.js.map +1 -1
  29. package/dist/components/SignIn/SignInStart.js +10 -0
  30. package/dist/components/SignIn/SignInStart.js.map +1 -1
  31. package/dist/components/devPrompts/KeylessPrompt/use-revalidate-environment.js +1 -1
  32. package/dist/components/devPrompts/KeylessPrompt/use-revalidate-environment.js.map +1 -1
  33. package/dist/{browser/createorganization_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → createorganization_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +1 -1
  34. package/dist/customizables/parseAppearance.d.ts +1 -1
  35. package/dist/customizables/parseAppearance.d.ts.map +1 -1
  36. package/dist/customizables/parseAppearance.js +5 -5
  37. package/dist/customizables/parseAppearance.js.map +1 -1
  38. package/dist/customizables/parseVariables.js +10 -13
  39. package/dist/customizables/parseVariables.js.map +1 -1
  40. package/dist/elements/ClipboardInput.js +0 -1
  41. package/dist/elements/ClipboardInput.js.map +1 -1
  42. package/dist/elements/PasswordInput.js +3 -2
  43. package/dist/elements/PasswordInput.js.map +1 -1
  44. package/dist/elements/contexts/index.js.map +1 -1
  45. package/dist/foundations/colors.js +2 -2
  46. package/dist/foundations/colors.js.map +1 -1
  47. package/dist/foundations/defaultFoundations.d.ts +157 -157
  48. package/dist/foundations/typography.js +4 -4
  49. package/dist/foundations/typography.js.map +1 -1
  50. package/dist/hooks/useFetch.js +1 -0
  51. package/dist/hooks/useFetch.js.map +1 -1
  52. package/dist/{browser/impersonationfab_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → impersonationfab_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +1 -1
  53. package/dist/index.js +1 -1
  54. package/dist/internal/appearance.d.ts +3 -63
  55. package/dist/internal/appearance.d.ts.map +1 -1
  56. package/dist/internal/index.js +1 -1
  57. package/dist/{browser/keylessPrompt_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → keylessPrompt_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +1 -1
  58. package/dist/lazyModules/components.d.ts +20 -20
  59. package/dist/{browser/organizationlist_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → organizationlist_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +1 -1
  60. package/dist/organizationprofile_ui_87d4d5_1.0.0-snapshot.v20251204143242.js +1 -0
  61. package/dist/organizationswitcher_ui_87d4d5_1.0.0-snapshot.v20251204143242.js +1 -0
  62. package/dist/signin_ui_87d4d5_1.0.0-snapshot.v20251204143242.js +1 -0
  63. package/dist/signup_ui_87d4d5_1.0.0-snapshot.v20251204143242.js +1 -0
  64. package/dist/{browser/taskChooseOrganization_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → taskChooseOrganization_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +1 -1
  65. package/dist/themes/createTheme.d.ts +2 -3
  66. package/dist/themes/createTheme.d.ts.map +1 -1
  67. package/dist/themes/createTheme.js +2 -2
  68. package/dist/themes/createTheme.js.map +1 -1
  69. package/dist/themes/dark.d.ts +0 -1
  70. package/dist/themes/dark.d.ts.map +1 -1
  71. package/dist/themes/dark.js +3 -2
  72. package/dist/themes/dark.js.map +1 -1
  73. package/dist/themes/experimental.d.ts +3 -0
  74. package/dist/themes/experimental.js +4 -0
  75. package/dist/themes/index.d.ts +1 -3
  76. package/dist/themes/index.js +1 -3
  77. package/dist/themes/neobrutalism.d.ts +0 -1
  78. package/dist/themes/neobrutalism.js +2 -2
  79. package/dist/themes/neobrutalism.js.map +1 -1
  80. package/dist/themes/shadcn.d.ts +0 -1
  81. package/dist/themes/shadcn.d.ts.map +1 -1
  82. package/dist/themes/shadcn.js +4 -3
  83. package/dist/themes/shadcn.js.map +1 -1
  84. package/dist/themes/shadesOfPurple.d.ts +0 -1
  85. package/dist/themes/shadesOfPurple.js +3 -3
  86. package/dist/themes/shadesOfPurple.js.map +1 -1
  87. package/dist/themes/simple.d.ts +2 -3
  88. package/dist/themes/simple.d.ts.map +1 -1
  89. package/dist/themes/simple.js +3 -3
  90. package/dist/themes/simple.js.map +1 -1
  91. package/dist/ui-common_ui_87d4d5_1.0.0-snapshot.v20251204143242.js +139 -0
  92. package/dist/ui.browser.js +3 -0
  93. package/dist/utils/extractCssLayerNameFromAppearance.js +4 -6
  94. package/dist/utils/extractCssLayerNameFromAppearance.js.map +1 -1
  95. package/dist/utils/usernameUtils.js +2 -0
  96. package/dist/utils/usernameUtils.js.map +1 -1
  97. package/package.json +8 -3
  98. package/dist/browser/646_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js +0 -1
  99. package/dist/browser/organizationprofile_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js +0 -1
  100. package/dist/browser/organizationswitcher_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js +0 -1
  101. package/dist/browser/signin_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js +0 -1
  102. package/dist/browser/signup_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js +0 -1
  103. package/dist/browser/ui-common_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js +0 -139
  104. package/dist/browser/ui.browser.js +0 -3
  105. package/dist/components/OrganizationProfile/BillingWidget.js +0 -39
  106. package/dist/components/OrganizationProfile/BillingWidget.js.map +0 -1
  107. package/dist/components/OrganizationProfile/MembershipWidget.js +0 -58
  108. package/dist/components/OrganizationProfile/MembershipWidget.js.map +0 -1
  109. package/dist/elements/Gauge.js +0 -82
  110. package/dist/elements/Gauge.js.map +0 -1
  111. package/dist/icons/billing.js +0 -35
  112. package/dist/icons/billing.js.map +0 -1
  113. /package/dist/{browser/217_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → 217_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  114. /package/dist/{browser/444_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → 444_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  115. /package/dist/{browser/apiKeys_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → apiKeys_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  116. /package/dist/{browser/copy-api-key-modal_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → copy-api-key-modal_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  117. /package/dist/{browser/enableOrganizationsPrompt_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → enableOrganizationsPrompt_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  118. /package/dist/{browser/framework_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → framework_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  119. /package/dist/{browser/oauthConsent_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → oauthConsent_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  120. /package/dist/{browser/onetap_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → onetap_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  121. /package/dist/{browser/op-api-keys-page_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → op-api-keys-page_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  122. /package/dist/{browser/op-billing-page_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → op-billing-page_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  123. /package/dist/{browser/op-plans-page_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → op-plans-page_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  124. /package/dist/{browser/payment-attempt-page_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → payment-attempt-page_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  125. /package/dist/{browser/planDetails_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → planDetails_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  126. /package/dist/{browser/prefetchorganizationlist_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → prefetchorganizationlist_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  127. /package/dist/{browser/pricingTable_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → pricingTable_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  128. /package/dist/{browser/revoke-api-key-modal_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → revoke-api-key-modal_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  129. /package/dist/{browser/sessionTasks_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → sessionTasks_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  130. /package/dist/{browser/statement-page_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → statement-page_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  131. /package/dist/{browser/subscriptionDetails_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → subscriptionDetails_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  132. /package/dist/{browser/up-api-keys-page_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → up-api-keys-page_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  133. /package/dist/{browser/up-billing-page_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → up-billing-page_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  134. /package/dist/{browser/up-plans-page_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → up-plans-page_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  135. /package/dist/{browser/useravatar_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → useravatar_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  136. /package/dist/{browser/userbutton_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → userbutton_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  137. /package/dist/{browser/userprofile_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → userprofile_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  138. /package/dist/{browser/userverification_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → userverification_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  139. /package/dist/{browser/vendors_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → vendors_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
  140. /package/dist/{browser/waitlist_ui_9c3cc3_1.0.0-snapshot.v20251203203405.js → waitlist_ui_87d4d5_1.0.0-snapshot.v20251204143242.js} +0 -0
@@ -1,7 +1,5 @@
1
- import { useRouter } from "../../router/RouteContext.js";
2
1
  import { useEnvironment } from "../../contexts/EnvironmentContext.js";
3
2
  import { localizationKeys } from "../../localization/localizationKeys.js";
4
- import billing_default from "../../icons/billing.js";
5
3
  import cog_filled_default from "../../icons/cog-filled.js";
6
4
  import { withProtect } from "../../common/Gate.js";
7
5
  import { useOrganizationSwitcherContext } from "../../contexts/components/OrganizationSwitcher.js";
@@ -15,9 +13,8 @@ import { PersonalWorkspacePreview } from "../../elements/PersonalWorkspacePrevie
15
13
  import { PopoverCard } from "../../elements/PopoverCard.js";
16
14
  import { RootBox } from "../../elements/RootBox.js";
17
15
  import { OrganizationActionList } from "./OtherOrganizationActions.js";
18
- import { runIfFunctionOrReturn } from "@clerk/shared/utils";
19
16
  import React from "react";
20
- import { Fragment as Fragment$1, jsx, jsxs } from "@emotion/react/jsx-runtime";
17
+ import { jsx, jsxs } from "@emotion/react/jsx-runtime";
21
18
  import { useClerk, useOrganization, useOrganizationList, useUser } from "@clerk/shared/react";
22
19
 
23
20
  //#region src/components/OrganizationSwitcher/OrganizationSwitcherPopover.tsx
@@ -29,8 +26,7 @@ const OrganizationSwitcherPopover = React.forwardRef((props, ref) => {
29
26
  const { openOrganizationProfile, openCreateOrganization } = useClerk();
30
27
  const { organization: currentOrg } = useOrganization();
31
28
  const { isLoaded, setActive } = useOrganizationList();
32
- const router = useRouter();
33
- const { hidePersonal, __unstable_manageBillingUrl, __unstable_manageBillingLabel, __unstable_manageBillingMembersLimit, createOrganizationMode, organizationProfileMode, afterLeaveOrganizationUrl, afterCreateOrganizationUrl, navigateCreateOrganization, navigateOrganizationProfile, afterSelectOrganizationUrl, afterSelectPersonalUrl, organizationProfileProps, skipInvitationScreen } = useOrganizationSwitcherContext();
29
+ const { hidePersonal, createOrganizationMode, organizationProfileMode, afterLeaveOrganizationUrl, afterCreateOrganizationUrl, navigateCreateOrganization, navigateOrganizationProfile, afterSelectOrganizationUrl, afterSelectPersonalUrl, organizationProfileProps, skipInvitationScreen } = useOrganizationSwitcherContext();
34
30
  const { user } = useUser();
35
31
  if (!user) return null;
36
32
  const { username, primaryEmailAddress, primaryPhoneNumber,...userWithoutIdentifiers } = user;
@@ -60,10 +56,7 @@ const OrganizationSwitcherPopover = React.forwardRef((props, ref) => {
60
56
  if (organizationProfileMode === "navigation") return navigateOrganizationProfile();
61
57
  return openOrganizationProfile({
62
58
  ...organizationProfileProps,
63
- afterLeaveOrganizationUrl,
64
- __unstable_manageBillingUrl,
65
- __unstable_manageBillingLabel,
66
- __unstable_manageBillingMembersLimit
59
+ afterLeaveOrganizationUrl
67
60
  });
68
61
  };
69
62
  const manageOrganizationButton = /* @__PURE__ */ jsx(SmallAction, {
@@ -79,35 +72,7 @@ const OrganizationSwitcherPopover = React.forwardRef((props, ref) => {
79
72
  trailing: /* @__PURE__ */ jsx(NotificationCountBadgeManageButton, {}),
80
73
  focusRing: true
81
74
  });
82
- const billingOrganizationButton = /* @__PURE__ */ jsx(SmallAction, {
83
- icon: billing_default,
84
- label: runIfFunctionOrReturn(__unstable_manageBillingLabel) || "Upgrade",
85
- onClick: () => router.navigate(runIfFunctionOrReturn(__unstable_manageBillingUrl)),
86
- focusRing: true
87
- });
88
- const selectedOrganizationPreview = (currentOrg$1) => __unstable_manageBillingUrl ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(OrganizationPreview, {
89
- elementId: "organizationSwitcherActiveOrganization",
90
- organization: currentOrg$1,
91
- user,
92
- mainIdentifierVariant: "buttonLarge",
93
- sx: (t) => ({ padding: `${t.space.$4} ${t.space.$5}` })
94
- }), /* @__PURE__ */ jsx(Actions, {
95
- role: "menu",
96
- sx: (t) => ({
97
- borderBottomWidth: t.borderWidths.$normal,
98
- borderBottomStyle: t.borderStyles.$solid,
99
- borderBottomColor: t.colors.$borderAlpha100
100
- }),
101
- children: /* @__PURE__ */ jsxs(Flex, {
102
- justify: "between",
103
- sx: (t) => ({
104
- marginLeft: t.space.$12,
105
- padding: `0 ${t.space.$5} ${t.space.$4}`,
106
- gap: t.space.$2
107
- }),
108
- children: [manageOrganizationButton, billingOrganizationButton]
109
- })
110
- })] }) : /* @__PURE__ */ jsxs(Flex, {
75
+ const selectedOrganizationPreview = (currentOrg$1) => /* @__PURE__ */ jsxs(Flex, {
111
76
  justify: "between",
112
77
  align: "center",
113
78
  sx: (t) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"OrganizationSwitcherPopover.js","names":["CogFilled","Billing","currentOrg"],"sources":["../../../src/components/OrganizationSwitcher/OrganizationSwitcherPopover.tsx"],"sourcesContent":["import { useClerk, useOrganization, useOrganizationList, useUser } from '@clerk/shared/react';\nimport type { OrganizationResource } from '@clerk/shared/types';\nimport { runIfFunctionOrReturn } from '@clerk/shared/utils';\nimport React from 'react';\n\nimport { Actions, SmallAction } from '@/ui/elements/Actions';\nimport { useCardState } from '@/ui/elements/contexts';\nimport { OrganizationPreview } from '@/ui/elements/OrganizationPreview';\nimport { PersonalWorkspacePreview } from '@/ui/elements/PersonalWorkspacePreview';\nimport { PopoverCard } from '@/ui/elements/PopoverCard';\n\nimport { NotificationCountBadge, withProtect } from '../../common';\nimport { useEnvironment, useOrganizationSwitcherContext } from '../../contexts';\nimport { descriptors, Flex, localizationKeys } from '../../customizables';\nimport { RootBox } from '../../elements/RootBox';\nimport { Billing, CogFilled } from '../../icons';\nimport { useRouter } from '../../router';\nimport type { PropsOfComponent, ThemableCssProp } from '../../styledSystem';\nimport { OrganizationActionList } from './OtherOrganizationActions';\n\ntype OrganizationSwitcherPopoverProps = { close?: (open: boolean) => void } & PropsOfComponent<typeof PopoverCard.Root>;\n\nexport const OrganizationSwitcherPopover = React.forwardRef<HTMLDivElement, OrganizationSwitcherPopoverProps>(\n (props, ref) => {\n const { close: unsafeClose, ...rest } = props;\n const close = () => unsafeClose?.(false);\n const card = useCardState();\n const { __experimental_asStandalone } = useOrganizationSwitcherContext();\n const { openOrganizationProfile, openCreateOrganization } = useClerk();\n const { organization: currentOrg } = useOrganization();\n const { isLoaded, setActive } = useOrganizationList();\n const router = useRouter();\n const {\n hidePersonal,\n //@ts-expect-error\n __unstable_manageBillingUrl,\n //@ts-expect-error\n __unstable_manageBillingLabel,\n //@ts-expect-error\n __unstable_manageBillingMembersLimit,\n createOrganizationMode,\n organizationProfileMode,\n afterLeaveOrganizationUrl,\n afterCreateOrganizationUrl,\n navigateCreateOrganization,\n navigateOrganizationProfile,\n afterSelectOrganizationUrl,\n afterSelectPersonalUrl,\n\n organizationProfileProps,\n skipInvitationScreen,\n } = useOrganizationSwitcherContext();\n\n const { user } = useUser();\n\n if (!user) {\n return null;\n }\n\n const { username, primaryEmailAddress, primaryPhoneNumber, ...userWithoutIdentifiers } = user;\n\n if (!isLoaded) {\n return null;\n }\n\n const handleOrganizationClicked = (organization: OrganizationResource) => {\n return card\n .runAsync(() =>\n setActive({\n organization,\n redirectUrl: afterSelectOrganizationUrl(organization),\n }),\n )\n .then(close);\n };\n\n const handlePersonalWorkspaceClicked = () => {\n return card\n .runAsync(() => setActive({ organization: null, redirectUrl: afterSelectPersonalUrl(user) }))\n .then(close);\n };\n\n const handleCreateOrganizationClicked = () => {\n close();\n if (createOrganizationMode === 'navigation') {\n return navigateCreateOrganization();\n }\n return openCreateOrganization({ afterCreateOrganizationUrl, skipInvitationScreen });\n };\n\n const handleItemClick = () => {\n close();\n if (organizationProfileMode === 'navigation') {\n return navigateOrganizationProfile();\n }\n\n return openOrganizationProfile({\n ...organizationProfileProps,\n afterLeaveOrganizationUrl,\n //@ts-expect-error\n __unstable_manageBillingUrl,\n __unstable_manageBillingLabel,\n __unstable_manageBillingMembersLimit,\n });\n };\n\n const manageOrganizationButton = (\n <SmallAction\n elementDescriptor={descriptors.organizationSwitcherPopoverActionButton}\n elementId={descriptors.organizationSwitcherPopoverActionButton.setId('manageOrganization')}\n iconBoxElementDescriptor={descriptors.organizationSwitcherPopoverActionButtonIconBox}\n iconBoxElementId={descriptors.organizationSwitcherPopoverActionButtonIconBox.setId('manageOrganization')}\n iconElementDescriptor={descriptors.organizationSwitcherPopoverActionButtonIcon}\n iconElementId={descriptors.organizationSwitcherPopoverActionButtonIcon.setId('manageOrganization')}\n icon={CogFilled}\n label={localizationKeys('organizationSwitcher.action__manageOrganization')}\n onClick={() => handleItemClick()}\n trailing={<NotificationCountBadgeManageButton />}\n focusRing\n />\n );\n\n const billingOrganizationButton = (\n <SmallAction\n icon={Billing}\n label={runIfFunctionOrReturn(__unstable_manageBillingLabel) || 'Upgrade'}\n onClick={() => router.navigate(runIfFunctionOrReturn(__unstable_manageBillingUrl))}\n focusRing\n />\n );\n\n const selectedOrganizationPreview = (currentOrg: OrganizationResource) =>\n __unstable_manageBillingUrl ? (\n <>\n <OrganizationPreview\n elementId={'organizationSwitcherActiveOrganization'}\n organization={currentOrg}\n user={user}\n mainIdentifierVariant='buttonLarge'\n sx={t => ({\n padding: `${t.space.$4} ${t.space.$5}`,\n })}\n />\n <Actions\n role='menu'\n sx={t => ({\n borderBottomWidth: t.borderWidths.$normal,\n borderBottomStyle: t.borderStyles.$solid,\n borderBottomColor: t.colors.$borderAlpha100,\n })}\n >\n <Flex\n justify='between'\n sx={t => ({\n marginLeft: t.space.$12,\n padding: `0 ${t.space.$5} ${t.space.$4}`,\n gap: t.space.$2,\n })}\n >\n {manageOrganizationButton}\n {billingOrganizationButton}\n </Flex>\n </Actions>\n </>\n ) : (\n <Flex\n justify='between'\n align='center'\n sx={t => ({\n width: '100%',\n paddingRight: t.space.$5,\n })}\n >\n <OrganizationPreview\n elementId={'organizationSwitcherActiveOrganization'}\n organization={currentOrg}\n user={user}\n mainIdentifierVariant='buttonLarge'\n sx={t => ({\n padding: `${t.space.$4} ${t.space.$5}`,\n })}\n />\n <Actions role='menu'>{manageOrganizationButton}</Actions>\n </Flex>\n );\n\n return (\n <RootBox elementDescriptor={descriptors.organizationSwitcherPopoverRootBox}>\n <PopoverCard.Root\n elementDescriptor={descriptors.organizationSwitcherPopoverCard}\n ref={ref}\n role='dialog'\n aria-label={`${currentOrg?.name} is active`}\n shouldEntryAnimate={!__experimental_asStandalone}\n {...rest}\n >\n <PopoverCard.Content elementDescriptor={descriptors.organizationSwitcherPopoverMain}>\n <Actions\n elementDescriptor={descriptors.organizationSwitcherPopoverActions}\n role='menu'\n >\n {currentOrg\n ? selectedOrganizationPreview(currentOrg)\n : !hidePersonal && (\n <PersonalWorkspacePreview\n user={userWithoutIdentifiers}\n sx={t => ({\n padding: `${t.space.$4} ${t.space.$5}`,\n width: '100%',\n })}\n title={localizationKeys('organizationSwitcher.personalWorkspace')}\n />\n )}\n <OrganizationActionList\n onCreateOrganizationClick={handleCreateOrganizationClicked}\n onPersonalWorkspaceClick={handlePersonalWorkspaceClicked}\n onOrganizationClick={handleOrganizationClicked}\n />\n </Actions>\n </PopoverCard.Content>\n <PopoverCard.Footer elementDescriptor={descriptors.organizationSwitcherPopoverFooter} />\n </PopoverCard.Root>\n </RootBox>\n );\n },\n);\n\nconst NotificationCountBadgeManageButton = withProtect(\n ({ sx }: { sx?: ThemableCssProp }) => {\n const { organizationSettings } = useEnvironment();\n\n const isDomainsEnabled = organizationSettings?.domains?.enabled;\n\n const { membershipRequests } = useOrganization({\n membershipRequests: isDomainsEnabled || undefined,\n });\n\n if (!membershipRequests?.count) {\n return null;\n }\n\n return (\n <NotificationCountBadge\n notificationCount={membershipRequests.count}\n containerSx={sx}\n />\n );\n },\n {\n // if the user is not able to accept a request we should not notify them\n permission: 'org:sys_memberships:manage',\n },\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,8BAA8B,MAAM,YAC9C,OAAO,QAAQ;CACd,MAAM,EAAE,OAAO,YAAa,GAAG,SAAS;CACxC,MAAM,cAAc,cAAc,MAAM;CACxC,MAAM,OAAO,cAAc;CAC3B,MAAM,EAAE,gCAAgC,gCAAgC;CACxE,MAAM,EAAE,yBAAyB,2BAA2B,UAAU;CACtE,MAAM,EAAE,cAAc,eAAe,iBAAiB;CACtD,MAAM,EAAE,UAAU,cAAc,qBAAqB;CACrD,MAAM,SAAS,WAAW;CAC1B,MAAM,EACJ,cAEA,6BAEA,+BAEA,sCACA,wBACA,yBACA,2BACA,4BACA,4BACA,6BACA,4BACA,wBAEA,0BACA,yBACE,gCAAgC;CAEpC,MAAM,EAAE,SAAS,SAAS;AAE1B,KAAI,CAAC,KACH,QAAO;CAGT,MAAM,EAAE,UAAU,qBAAqB,mBAAoB,GAAG,2BAA2B;AAEzF,KAAI,CAAC,SACH,QAAO;CAGT,MAAM,6BAA6B,iBAAuC;AACxE,SAAO,KACJ,eACC,UAAU;GACR;GACA,aAAa,2BAA2B,aAAa;GACtD,CAAC,CACH,CACA,KAAK,MAAM;;CAGhB,MAAM,uCAAuC;AAC3C,SAAO,KACJ,eAAe,UAAU;GAAE,cAAc;GAAM,aAAa,uBAAuB,KAAK;GAAE,CAAC,CAAC,CAC5F,KAAK,MAAM;;CAGhB,MAAM,wCAAwC;AAC5C,SAAO;AACP,MAAI,2BAA2B,aAC7B,QAAO,4BAA4B;AAErC,SAAO,uBAAuB;GAAE;GAA4B;GAAsB,CAAC;;CAGrF,MAAM,wBAAwB;AAC5B,SAAO;AACP,MAAI,4BAA4B,aAC9B,QAAO,6BAA6B;AAGtC,SAAO,wBAAwB;GAC7B,GAAG;GACH;GAEA;GACA;GACA;GACD,CAAC;;CAGJ,MAAM,2BACJ,oBAAC;EACC,mBAAmB,YAAY;EAC/B,WAAW,YAAY,wCAAwC,MAAM,qBAAqB;EAC1F,0BAA0B,YAAY;EACtC,kBAAkB,YAAY,+CAA+C,MAAM,qBAAqB;EACxG,uBAAuB,YAAY;EACnC,eAAe,YAAY,4CAA4C,MAAM,qBAAqB;EAClG,MAAMA;EACN,OAAO,iBAAiB,kDAAkD;EAC1E,eAAe,iBAAiB;EAChC,UAAU,oBAAC,uCAAqC;EAChD;GACA;CAGJ,MAAM,4BACJ,oBAAC;EACC,MAAMC;EACN,OAAO,sBAAsB,8BAA8B,IAAI;EAC/D,eAAe,OAAO,SAAS,sBAAsB,4BAA4B,CAAC;EAClF;GACA;CAGJ,MAAM,+BAA+B,iBACnC,8BACE,8CACE,oBAAC;EACC,WAAW;EACX,cAAcC;EACR;EACN,uBAAsB;EACtB,KAAI,OAAM,EACR,SAAS,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,MAAM,MACnC;GACD,EACF,oBAAC;EACC,MAAK;EACL,KAAI,OAAM;GACR,mBAAmB,EAAE,aAAa;GAClC,mBAAmB,EAAE,aAAa;GAClC,mBAAmB,EAAE,OAAO;GAC7B;YAED,qBAAC;GACC,SAAQ;GACR,KAAI,OAAM;IACR,YAAY,EAAE,MAAM;IACpB,SAAS,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,MAAM;IACpC,KAAK,EAAE,MAAM;IACd;cAEA,0BACA;IACI;GACC,IACT,GAEH,qBAAC;EACC,SAAQ;EACR,OAAM;EACN,KAAI,OAAM;GACR,OAAO;GACP,cAAc,EAAE,MAAM;GACvB;aAED,oBAAC;GACC,WAAW;GACX,cAAcA;GACR;GACN,uBAAsB;GACtB,KAAI,OAAM,EACR,SAAS,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,MAAM,MACnC;IACD,EACF,oBAAC;GAAQ,MAAK;aAAQ;IAAmC;GACpD;AAGX,QACE,oBAAC;EAAQ,mBAAmB,YAAY;YACtC,qBAAC,YAAY;GACX,mBAAmB,YAAY;GAC1B;GACL,MAAK;GACL,cAAY,GAAG,YAAY,KAAK;GAChC,oBAAoB,CAAC;GACrB,GAAI;cAEJ,oBAAC,YAAY;IAAQ,mBAAmB,YAAY;cAClD,qBAAC;KACC,mBAAmB,YAAY;KAC/B,MAAK;gBAEJ,aACG,4BAA4B,WAAW,GACvC,CAAC,gBACC,oBAAC;MACC,MAAM;MACN,KAAI,OAAM;OACR,SAAS,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,MAAM;OAClC,OAAO;OACR;MACD,OAAO,iBAAiB,yCAAyC;OACjE,EAER,oBAAC;MACC,2BAA2B;MAC3B,0BAA0B;MAC1B,qBAAqB;OACrB;MACM;KACU,EACtB,oBAAC,YAAY,UAAO,mBAAmB,YAAY,oCAAqC;IACvE;GACX;EAGf;AAED,MAAM,qCAAqC,aACxC,EAAE,SAAmC;CACpC,MAAM,EAAE,yBAAyB,gBAAgB;CAEjD,MAAM,mBAAmB,sBAAsB,SAAS;CAExD,MAAM,EAAE,uBAAuB,gBAAgB,EAC7C,oBAAoB,oBAAoB,QACzC,CAAC;AAEF,KAAI,CAAC,oBAAoB,MACvB,QAAO;AAGT,QACE,oBAAC;EACC,mBAAmB,mBAAmB;EACtC,aAAa;GACb;GAGN,EAEE,YAAY,8BACb,CACF"}
1
+ {"version":3,"file":"OrganizationSwitcherPopover.js","names":["CogFilled","currentOrg"],"sources":["../../../src/components/OrganizationSwitcher/OrganizationSwitcherPopover.tsx"],"sourcesContent":["import { useClerk, useOrganization, useOrganizationList, useUser } from '@clerk/shared/react';\nimport type { OrganizationResource } from '@clerk/shared/types';\nimport React from 'react';\n\nimport { Actions, SmallAction } from '@/ui/elements/Actions';\nimport { useCardState } from '@/ui/elements/contexts';\nimport { OrganizationPreview } from '@/ui/elements/OrganizationPreview';\nimport { PersonalWorkspacePreview } from '@/ui/elements/PersonalWorkspacePreview';\nimport { PopoverCard } from '@/ui/elements/PopoverCard';\n\nimport { NotificationCountBadge, withProtect } from '../../common';\nimport { useEnvironment, useOrganizationSwitcherContext } from '../../contexts';\nimport { descriptors, Flex, localizationKeys } from '../../customizables';\nimport { RootBox } from '../../elements/RootBox';\nimport { CogFilled } from '../../icons';\nimport type { PropsOfComponent, ThemableCssProp } from '../../styledSystem';\nimport { OrganizationActionList } from './OtherOrganizationActions';\n\ntype OrganizationSwitcherPopoverProps = { close?: (open: boolean) => void } & PropsOfComponent<typeof PopoverCard.Root>;\n\nexport const OrganizationSwitcherPopover = React.forwardRef<HTMLDivElement, OrganizationSwitcherPopoverProps>(\n (props, ref) => {\n const { close: unsafeClose, ...rest } = props;\n const close = () => unsafeClose?.(false);\n const card = useCardState();\n const { __experimental_asStandalone } = useOrganizationSwitcherContext();\n const { openOrganizationProfile, openCreateOrganization } = useClerk();\n const { organization: currentOrg } = useOrganization();\n const { isLoaded, setActive } = useOrganizationList();\n const {\n hidePersonal,\n createOrganizationMode,\n organizationProfileMode,\n afterLeaveOrganizationUrl,\n afterCreateOrganizationUrl,\n navigateCreateOrganization,\n navigateOrganizationProfile,\n afterSelectOrganizationUrl,\n afterSelectPersonalUrl,\n\n organizationProfileProps,\n skipInvitationScreen,\n } = useOrganizationSwitcherContext();\n\n const { user } = useUser();\n\n if (!user) {\n return null;\n }\n\n const { username, primaryEmailAddress, primaryPhoneNumber, ...userWithoutIdentifiers } = user;\n\n if (!isLoaded) {\n return null;\n }\n\n const handleOrganizationClicked = (organization: OrganizationResource) => {\n return card\n .runAsync(() =>\n setActive({\n organization,\n redirectUrl: afterSelectOrganizationUrl(organization),\n }),\n )\n .then(close);\n };\n\n const handlePersonalWorkspaceClicked = () => {\n return card\n .runAsync(() => setActive({ organization: null, redirectUrl: afterSelectPersonalUrl(user) }))\n .then(close);\n };\n\n const handleCreateOrganizationClicked = () => {\n close();\n if (createOrganizationMode === 'navigation') {\n return navigateCreateOrganization();\n }\n return openCreateOrganization({ afterCreateOrganizationUrl, skipInvitationScreen });\n };\n\n const handleItemClick = () => {\n close();\n if (organizationProfileMode === 'navigation') {\n return navigateOrganizationProfile();\n }\n\n return openOrganizationProfile({\n ...organizationProfileProps,\n afterLeaveOrganizationUrl,\n });\n };\n\n const manageOrganizationButton = (\n <SmallAction\n elementDescriptor={descriptors.organizationSwitcherPopoverActionButton}\n elementId={descriptors.organizationSwitcherPopoverActionButton.setId('manageOrganization')}\n iconBoxElementDescriptor={descriptors.organizationSwitcherPopoverActionButtonIconBox}\n iconBoxElementId={descriptors.organizationSwitcherPopoverActionButtonIconBox.setId('manageOrganization')}\n iconElementDescriptor={descriptors.organizationSwitcherPopoverActionButtonIcon}\n iconElementId={descriptors.organizationSwitcherPopoverActionButtonIcon.setId('manageOrganization')}\n icon={CogFilled}\n label={localizationKeys('organizationSwitcher.action__manageOrganization')}\n onClick={() => handleItemClick()}\n trailing={<NotificationCountBadgeManageButton />}\n focusRing\n />\n );\n\n const selectedOrganizationPreview = (currentOrg: OrganizationResource) => (\n <Flex\n justify='between'\n align='center'\n sx={t => ({\n width: '100%',\n paddingRight: t.space.$5,\n })}\n >\n <OrganizationPreview\n elementId={'organizationSwitcherActiveOrganization'}\n organization={currentOrg}\n user={user}\n mainIdentifierVariant='buttonLarge'\n sx={t => ({\n padding: `${t.space.$4} ${t.space.$5}`,\n })}\n />\n <Actions role='menu'>{manageOrganizationButton}</Actions>\n </Flex>\n );\n\n return (\n <RootBox elementDescriptor={descriptors.organizationSwitcherPopoverRootBox}>\n <PopoverCard.Root\n elementDescriptor={descriptors.organizationSwitcherPopoverCard}\n ref={ref}\n role='dialog'\n aria-label={`${currentOrg?.name} is active`}\n shouldEntryAnimate={!__experimental_asStandalone}\n {...rest}\n >\n <PopoverCard.Content elementDescriptor={descriptors.organizationSwitcherPopoverMain}>\n <Actions\n elementDescriptor={descriptors.organizationSwitcherPopoverActions}\n role='menu'\n >\n {currentOrg\n ? selectedOrganizationPreview(currentOrg)\n : !hidePersonal && (\n <PersonalWorkspacePreview\n user={userWithoutIdentifiers}\n sx={t => ({\n padding: `${t.space.$4} ${t.space.$5}`,\n width: '100%',\n })}\n title={localizationKeys('organizationSwitcher.personalWorkspace')}\n />\n )}\n <OrganizationActionList\n onCreateOrganizationClick={handleCreateOrganizationClicked}\n onPersonalWorkspaceClick={handlePersonalWorkspaceClicked}\n onOrganizationClick={handleOrganizationClicked}\n />\n </Actions>\n </PopoverCard.Content>\n <PopoverCard.Footer elementDescriptor={descriptors.organizationSwitcherPopoverFooter} />\n </PopoverCard.Root>\n </RootBox>\n );\n },\n);\n\nconst NotificationCountBadgeManageButton = withProtect(\n ({ sx }: { sx?: ThemableCssProp }) => {\n const { organizationSettings } = useEnvironment();\n\n const isDomainsEnabled = organizationSettings?.domains?.enabled;\n\n const { membershipRequests } = useOrganization({\n membershipRequests: isDomainsEnabled || undefined,\n });\n\n if (!membershipRequests?.count) {\n return null;\n }\n\n return (\n <NotificationCountBadge\n notificationCount={membershipRequests.count}\n containerSx={sx}\n />\n );\n },\n {\n // if the user is not able to accept a request we should not notify them\n permission: 'org:sys_memberships:manage',\n },\n);\n"],"mappings":"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"}
@@ -44,7 +44,7 @@ const AlternativeMethodsList = (props) => {
44
44
  children: /* @__PURE__ */ jsxs(Card.Root, { children: [/* @__PURE__ */ jsxs(Card.Content, { children: [
45
45
  /* @__PURE__ */ jsxs(Header.Root, {
46
46
  showLogo: true,
47
- children: [/* @__PURE__ */ jsx(Header.Title, { localizationKey: cardTitleKey }), !isReset && /* @__PURE__ */ jsx(Header.Subtitle, { localizationKey: localizationKeys("signIn.alternativeMethods.subtitle") })]
47
+ children: [/* @__PURE__ */ jsx(Header.Title, { localizationKey: cardTitleKey }), !isReset && mode !== "passwordCompromised" && /* @__PURE__ */ jsx(Header.Subtitle, { localizationKey: localizationKeys("signIn.alternativeMethods.subtitle") })]
48
48
  }),
49
49
  /* @__PURE__ */ jsx(Card.Alert, { children: card.error }),
50
50
  /* @__PURE__ */ jsxs(Flex, {
@@ -129,6 +129,7 @@ function determineFlowPart(mode) {
129
129
  switch (mode) {
130
130
  case "forgot": return "forgotPasswordMethods";
131
131
  case "pwned": return "passwordPwnedMethods";
132
+ case "passwordCompromised": return "passwordCompromisedMethods";
132
133
  default: return "alternativeMethods";
133
134
  }
134
135
  }
@@ -136,6 +137,7 @@ function determineTitle(mode) {
136
137
  switch (mode) {
137
138
  case "forgot": return localizationKeys("signIn.forgotPasswordAlternativeMethods.title");
138
139
  case "pwned": return localizationKeys("signIn.passwordPwned.title");
140
+ case "passwordCompromised": return localizationKeys("signIn.passwordCompromised.title");
139
141
  default: return localizationKeys("signIn.alternativeMethods.title");
140
142
  }
141
143
  }
@@ -143,6 +145,7 @@ function determineIsReset(mode) {
143
145
  switch (mode) {
144
146
  case "forgot":
145
147
  case "pwned": return true;
148
+ case "passwordCompromised": return false;
146
149
  default: return false;
147
150
  }
148
151
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AlternativeMethods.js","names":["LinkIcon","Email","ChatAltIcon","RequestAuthIcon","LockClosedIcon","Fingerprint"],"sources":["../../../src/components/SignIn/AlternativeMethods.tsx"],"sourcesContent":["import type { SignInFactor } from '@clerk/shared/types';\nimport React from 'react';\n\nimport { ArrowBlockButton } from '@/ui/elements/ArrowBlockButton';\nimport { BackLink } from '@/ui/elements/BackLink';\nimport { Card } from '@/ui/elements/Card';\nimport { Divider } from '@/ui/elements/Divider';\nimport { Header } from '@/ui/elements/Header';\nimport { formatSafeIdentifier } from '@/ui/utils/formatSafeIdentifier';\n\nimport { useCoreSignIn } from '../../contexts';\nimport type { LocalizationKey } from '../../customizables';\nimport { Button, Col, descriptors, Flex, Flow, localizationKeys } from '../../customizables';\nimport { useCardState } from '../../elements/contexts';\nimport { useAlternativeStrategies } from '../../hooks/useAlternativeStrategies';\nimport { ChatAltIcon, Email, Fingerprint, LinkIcon, LockClosedIcon, RequestAuthIcon } from '../../icons';\nimport { SignInSocialButtons } from './SignInSocialButtons';\nimport { useResetPasswordFactor } from './useResetPasswordFactor';\nimport { withHavingTrouble } from './withHavingTrouble';\n\ntype AlternativeMethodsMode = 'forgot' | 'pwned' | 'default';\n\nexport type AlternativeMethodsProps = {\n onBackLinkClick: React.MouseEventHandler | undefined;\n onFactorSelected: (factor: SignInFactor) => void;\n currentFactor: SignInFactor | undefined | null;\n mode?: AlternativeMethodsMode;\n};\n\nexport type AlternativeMethodListProps = AlternativeMethodsProps & { onHavingTroubleClick: React.MouseEventHandler };\n\nexport const AlternativeMethods = (props: AlternativeMethodsProps) => {\n return withHavingTrouble(AlternativeMethodsList, {\n ...props,\n });\n};\n\nconst AlternativeMethodsList = (props: AlternativeMethodListProps) => {\n const { onBackLinkClick, onHavingTroubleClick, onFactorSelected, mode = 'default' } = props;\n const card = useCardState();\n const resetPasswordFactor = useResetPasswordFactor();\n const { supportedFirstFactors } = useCoreSignIn();\n const { firstPartyFactors, hasAnyStrategy } = useAlternativeStrategies({\n filterOutFactor: props?.currentFactor,\n supportedFirstFactors: supportedFirstFactors,\n });\n\n const flowPart = determineFlowPart(mode);\n const cardTitleKey = determineTitle(mode);\n const isReset = determineIsReset(mode);\n\n return (\n <Flow.Part part={flowPart}>\n <Card.Root>\n <Card.Content>\n <Header.Root showLogo>\n <Header.Title localizationKey={cardTitleKey} />\n {!isReset && <Header.Subtitle localizationKey={localizationKeys('signIn.alternativeMethods.subtitle')} />}\n </Header.Root>\n <Card.Alert>{card.error}</Card.Alert>\n {/*TODO: extract main in its own component */}\n <Flex\n direction='col'\n elementDescriptor={descriptors.main}\n gap={6}\n >\n {isReset && resetPasswordFactor && (\n <Button\n localizationKey={getButtonLabel(resetPasswordFactor)}\n elementDescriptor={descriptors.alternativeMethodsBlockButton}\n isDisabled={card.isLoading}\n onClick={() => {\n card.setError(undefined);\n onFactorSelected(resetPasswordFactor);\n }}\n />\n )}\n {isReset && hasAnyStrategy && (\n <Divider\n dividerText={localizationKeys('signIn.forgotPasswordAlternativeMethods.label__alternativeMethods')}\n />\n )}\n <Col gap={4}>\n {hasAnyStrategy && (\n <Flex\n elementDescriptor={descriptors.alternativeMethods}\n direction='col'\n gap={2}\n >\n <SignInSocialButtons\n enableWeb3Providers\n enableOAuthProviders\n enableAlternativePhoneCodeProviders={false}\n />\n {firstPartyFactors &&\n firstPartyFactors.map((factor, i) => (\n <ArrowBlockButton\n leftIcon={getButtonIcon(factor)}\n textLocalizationKey={getButtonLabel(factor)}\n elementDescriptor={descriptors.alternativeMethodsBlockButton}\n textElementDescriptor={descriptors.alternativeMethodsBlockButtonText}\n arrowElementDescriptor={descriptors.alternativeMethodsBlockButtonArrow}\n key={i}\n textVariant='buttonLarge'\n isDisabled={card.isLoading}\n onClick={() => {\n card.setError(undefined);\n onFactorSelected(factor);\n }}\n />\n ))}\n </Flex>\n )}\n {onBackLinkClick && (\n <BackLink\n boxElementDescriptor={descriptors.backRow}\n linkElementDescriptor={descriptors.backLink}\n onClick={onBackLinkClick}\n />\n )}\n </Col>\n </Flex>\n </Card.Content>\n\n <Card.Footer>\n <Card.Action elementId='havingTrouble'>\n <Card.ActionText localizationKey={localizationKeys('signIn.alternativeMethods.actionText')} />\n <Card.ActionLink\n localizationKey={localizationKeys('signIn.alternativeMethods.actionLink')}\n onClick={onHavingTroubleClick}\n />\n </Card.Action>\n </Card.Footer>\n </Card.Root>\n </Flow.Part>\n );\n};\n\nexport function getButtonLabel(factor: SignInFactor): LocalizationKey {\n switch (factor.strategy) {\n case 'email_link':\n return localizationKeys('signIn.alternativeMethods.blockButton__emailLink', {\n identifier: formatSafeIdentifier(factor.safeIdentifier) || '',\n });\n case 'email_code':\n return localizationKeys('signIn.alternativeMethods.blockButton__emailCode', {\n identifier: formatSafeIdentifier(factor.safeIdentifier) || '',\n });\n case 'phone_code':\n return localizationKeys('signIn.alternativeMethods.blockButton__phoneCode', {\n identifier: formatSafeIdentifier(factor.safeIdentifier) || '',\n });\n case 'password':\n return localizationKeys('signIn.alternativeMethods.blockButton__password');\n case 'passkey':\n return localizationKeys('signIn.alternativeMethods.blockButton__passkey');\n case 'reset_password_email_code':\n return localizationKeys('signIn.forgotPasswordAlternativeMethods.blockButton__resetPassword');\n case 'reset_password_phone_code':\n return localizationKeys('signIn.forgotPasswordAlternativeMethods.blockButton__resetPassword');\n default:\n throw new Error(`Invalid sign in strategy: \"${factor.strategy}\"`);\n }\n}\n\nexport function getButtonIcon(factor: SignInFactor) {\n const icons = {\n email_link: LinkIcon,\n email_code: Email,\n phone_code: ChatAltIcon,\n reset_password_email_code: RequestAuthIcon,\n reset_password_phone_code: RequestAuthIcon,\n password: LockClosedIcon,\n passkey: Fingerprint,\n } as const;\n\n return icons[factor.strategy as keyof typeof icons];\n}\n\nfunction determineFlowPart(mode: AlternativeMethodsMode) {\n switch (mode) {\n case 'forgot':\n return 'forgotPasswordMethods';\n case 'pwned':\n return 'passwordPwnedMethods';\n default:\n return 'alternativeMethods';\n }\n}\n\nfunction determineTitle(mode: AlternativeMethodsMode): LocalizationKey {\n switch (mode) {\n case 'forgot':\n return localizationKeys('signIn.forgotPasswordAlternativeMethods.title');\n case 'pwned':\n return localizationKeys('signIn.passwordPwned.title');\n default:\n return localizationKeys('signIn.alternativeMethods.title');\n }\n}\n\nfunction determineIsReset(mode: AlternativeMethodsMode): boolean {\n switch (mode) {\n case 'forgot':\n case 'pwned':\n return true;\n default:\n return false;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AlternativeMethods.js","names":["LinkIcon","Email","ChatAltIcon","RequestAuthIcon","LockClosedIcon","Fingerprint"],"sources":["../../../src/components/SignIn/AlternativeMethods.tsx"],"sourcesContent":["import type { SignInFactor } from '@clerk/shared/types';\nimport React from 'react';\n\nimport { ArrowBlockButton } from '@/ui/elements/ArrowBlockButton';\nimport { BackLink } from '@/ui/elements/BackLink';\nimport { Card } from '@/ui/elements/Card';\nimport { Divider } from '@/ui/elements/Divider';\nimport { Header } from '@/ui/elements/Header';\nimport { formatSafeIdentifier } from '@/ui/utils/formatSafeIdentifier';\n\nimport { useCoreSignIn } from '../../contexts';\nimport type { LocalizationKey } from '../../customizables';\nimport { Button, Col, descriptors, Flex, Flow, localizationKeys } from '../../customizables';\nimport { useCardState } from '../../elements/contexts';\nimport { useAlternativeStrategies } from '../../hooks/useAlternativeStrategies';\nimport { ChatAltIcon, Email, Fingerprint, LinkIcon, LockClosedIcon, RequestAuthIcon } from '../../icons';\nimport { SignInSocialButtons } from './SignInSocialButtons';\nimport { useResetPasswordFactor } from './useResetPasswordFactor';\nimport { withHavingTrouble } from './withHavingTrouble';\n\nexport type AlternativeMethodsMode = 'forgot' | 'pwned' | 'passwordCompromised' | 'default';\n\nexport type AlternativeMethodsProps = {\n onBackLinkClick: React.MouseEventHandler | undefined;\n onFactorSelected: (factor: SignInFactor) => void;\n currentFactor: SignInFactor | undefined | null;\n mode?: AlternativeMethodsMode;\n};\n\nexport type AlternativeMethodListProps = AlternativeMethodsProps & { onHavingTroubleClick: React.MouseEventHandler };\n\nexport const AlternativeMethods = (props: AlternativeMethodsProps) => {\n return withHavingTrouble(AlternativeMethodsList, {\n ...props,\n });\n};\n\nconst AlternativeMethodsList = (props: AlternativeMethodListProps) => {\n const { onBackLinkClick, onHavingTroubleClick, onFactorSelected, mode = 'default' } = props;\n const card = useCardState();\n const resetPasswordFactor = useResetPasswordFactor();\n const { supportedFirstFactors } = useCoreSignIn();\n const { firstPartyFactors, hasAnyStrategy } = useAlternativeStrategies({\n filterOutFactor: props?.currentFactor,\n supportedFirstFactors: supportedFirstFactors,\n });\n\n const flowPart = determineFlowPart(mode);\n const cardTitleKey = determineTitle(mode);\n const isReset = determineIsReset(mode);\n\n return (\n <Flow.Part part={flowPart}>\n <Card.Root>\n <Card.Content>\n <Header.Root showLogo>\n <Header.Title localizationKey={cardTitleKey} />\n {!isReset && mode !== 'passwordCompromised' && (\n <Header.Subtitle localizationKey={localizationKeys('signIn.alternativeMethods.subtitle')} />\n )}\n </Header.Root>\n <Card.Alert>{card.error}</Card.Alert>\n {/*TODO: extract main in its own component */}\n <Flex\n direction='col'\n elementDescriptor={descriptors.main}\n gap={6}\n >\n {isReset && resetPasswordFactor && (\n <Button\n localizationKey={getButtonLabel(resetPasswordFactor)}\n elementDescriptor={descriptors.alternativeMethodsBlockButton}\n isDisabled={card.isLoading}\n onClick={() => {\n card.setError(undefined);\n onFactorSelected(resetPasswordFactor);\n }}\n />\n )}\n {isReset && hasAnyStrategy && (\n <Divider\n dividerText={localizationKeys('signIn.forgotPasswordAlternativeMethods.label__alternativeMethods')}\n />\n )}\n <Col gap={4}>\n {hasAnyStrategy && (\n <Flex\n elementDescriptor={descriptors.alternativeMethods}\n direction='col'\n gap={2}\n >\n <SignInSocialButtons\n enableWeb3Providers\n enableOAuthProviders\n enableAlternativePhoneCodeProviders={false}\n />\n {firstPartyFactors &&\n firstPartyFactors.map((factor, i) => (\n <ArrowBlockButton\n leftIcon={getButtonIcon(factor)}\n textLocalizationKey={getButtonLabel(factor)}\n elementDescriptor={descriptors.alternativeMethodsBlockButton}\n textElementDescriptor={descriptors.alternativeMethodsBlockButtonText}\n arrowElementDescriptor={descriptors.alternativeMethodsBlockButtonArrow}\n key={i}\n textVariant='buttonLarge'\n isDisabled={card.isLoading}\n onClick={() => {\n card.setError(undefined);\n onFactorSelected(factor);\n }}\n />\n ))}\n </Flex>\n )}\n {onBackLinkClick && (\n <BackLink\n boxElementDescriptor={descriptors.backRow}\n linkElementDescriptor={descriptors.backLink}\n onClick={onBackLinkClick}\n />\n )}\n </Col>\n </Flex>\n </Card.Content>\n\n <Card.Footer>\n <Card.Action elementId='havingTrouble'>\n <Card.ActionText localizationKey={localizationKeys('signIn.alternativeMethods.actionText')} />\n <Card.ActionLink\n localizationKey={localizationKeys('signIn.alternativeMethods.actionLink')}\n onClick={onHavingTroubleClick}\n />\n </Card.Action>\n </Card.Footer>\n </Card.Root>\n </Flow.Part>\n );\n};\n\nexport function getButtonLabel(factor: SignInFactor): LocalizationKey {\n switch (factor.strategy) {\n case 'email_link':\n return localizationKeys('signIn.alternativeMethods.blockButton__emailLink', {\n identifier: formatSafeIdentifier(factor.safeIdentifier) || '',\n });\n case 'email_code':\n return localizationKeys('signIn.alternativeMethods.blockButton__emailCode', {\n identifier: formatSafeIdentifier(factor.safeIdentifier) || '',\n });\n case 'phone_code':\n return localizationKeys('signIn.alternativeMethods.blockButton__phoneCode', {\n identifier: formatSafeIdentifier(factor.safeIdentifier) || '',\n });\n case 'password':\n return localizationKeys('signIn.alternativeMethods.blockButton__password');\n case 'passkey':\n return localizationKeys('signIn.alternativeMethods.blockButton__passkey');\n case 'reset_password_email_code':\n return localizationKeys('signIn.forgotPasswordAlternativeMethods.blockButton__resetPassword');\n case 'reset_password_phone_code':\n return localizationKeys('signIn.forgotPasswordAlternativeMethods.blockButton__resetPassword');\n default:\n throw new Error(`Invalid sign in strategy: \"${factor.strategy}\"`);\n }\n}\n\nexport function getButtonIcon(factor: SignInFactor) {\n const icons = {\n email_link: LinkIcon,\n email_code: Email,\n phone_code: ChatAltIcon,\n reset_password_email_code: RequestAuthIcon,\n reset_password_phone_code: RequestAuthIcon,\n password: LockClosedIcon,\n passkey: Fingerprint,\n } as const;\n\n return icons[factor.strategy as keyof typeof icons];\n}\n\nfunction determineFlowPart(mode: AlternativeMethodsMode) {\n switch (mode) {\n case 'forgot':\n return 'forgotPasswordMethods';\n case 'pwned':\n return 'passwordPwnedMethods';\n case 'passwordCompromised':\n return 'passwordCompromisedMethods';\n default:\n return 'alternativeMethods';\n }\n}\n\nfunction determineTitle(mode: AlternativeMethodsMode): LocalizationKey {\n switch (mode) {\n case 'forgot':\n return localizationKeys('signIn.forgotPasswordAlternativeMethods.title');\n case 'pwned':\n return localizationKeys('signIn.passwordPwned.title');\n case 'passwordCompromised':\n return localizationKeys('signIn.passwordCompromised.title');\n default:\n return localizationKeys('signIn.alternativeMethods.title');\n }\n}\n\nfunction determineIsReset(mode: AlternativeMethodsMode): boolean {\n switch (mode) {\n case 'forgot':\n case 'pwned':\n return true;\n case 'passwordCompromised':\n return false;\n default:\n return false;\n }\n}\n"],"mappings":"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"}
@@ -32,6 +32,12 @@ const factorKey = (factor) => {
32
32
  if ("channel" in factor) key += factor.channel;
33
33
  return key;
34
34
  };
35
+ function determineAlternativeMethodsMode(showForgotPasswordStrategies, passwordErrorCode) {
36
+ if (!showForgotPasswordStrategies) return "default";
37
+ if (passwordErrorCode === "pwned") return "pwned";
38
+ if (passwordErrorCode === "compromised") return "passwordCompromised";
39
+ return "forgot";
40
+ }
35
41
  function SignInFactorOneInternal() {
36
42
  const { __internal_setActiveInProgress } = useClerk();
37
43
  const signIn = useCoreSignIn();
@@ -56,7 +62,7 @@ function SignInFactorOneInternal() {
56
62
  const [showAllStrategies, setShowAllStrategies] = React.useState(() => !currentFactor || !factorHasLocalStrategy(currentFactor));
57
63
  const resetPasswordFactor = useResetPasswordFactor();
58
64
  const [showForgotPasswordStrategies, setShowForgotPasswordStrategies] = React.useState(false);
59
- const [isPasswordPwned, setIsPasswordPwned] = React.useState(false);
65
+ const [passwordErrorCode, setPasswordErrorCode] = React.useState(null);
60
66
  React.useEffect(() => {
61
67
  if (__internal_setActiveInProgress) return;
62
68
  if (signIn.status === "needs_identifier" || signIn.status === null) router.navigate("../");
@@ -87,11 +93,11 @@ function SignInFactorOneInternal() {
87
93
  const toggle = showAllStrategies ? toggleAllStrategies : toggleForgotPasswordStrategies;
88
94
  const backHandler = () => {
89
95
  card.setError(void 0);
90
- setIsPasswordPwned(false);
96
+ setPasswordErrorCode(null);
91
97
  toggle?.();
92
98
  };
93
99
  return /* @__PURE__ */ jsx(AlternativeMethods, {
94
- mode: showForgotPasswordStrategies ? isPasswordPwned ? "pwned" : "forgot" : "default",
100
+ mode: determineAlternativeMethodsMode(showForgotPasswordStrategies, passwordErrorCode),
95
101
  onBackLinkClick: canGoBack ? backHandler : void 0,
96
102
  onFactorSelected: (f) => {
97
103
  selectFactor(f);
@@ -109,8 +115,8 @@ function SignInFactorOneInternal() {
109
115
  case "password": return /* @__PURE__ */ jsx(SignInFactorOnePasswordCard, {
110
116
  onForgotPasswordMethodClick: resetPasswordFactor ? toggleForgotPasswordStrategies : toggleAllStrategies,
111
117
  onShowAlternativeMethodsClick: toggleAllStrategies,
112
- onPasswordPwned: () => {
113
- setIsPasswordPwned(true);
118
+ onPasswordError: (errorCode) => {
119
+ setPasswordErrorCode(errorCode);
114
120
  toggleForgotPasswordStrategies();
115
121
  }
116
122
  });
@@ -1 +1 @@
1
- {"version":3,"file":"SignInFactorOne.js","names":[],"sources":["../../../src/components/SignIn/SignInFactorOne.tsx"],"sourcesContent":["import { useClerk } from '@clerk/shared/react';\nimport type { SignInFactor } from '@clerk/shared/types';\nimport React from 'react';\n\nimport { useCardState, withCardStateProvider } from '@/ui/elements/contexts';\nimport { ErrorCard } from '@/ui/elements/ErrorCard';\nimport { LoadingCard } from '@/ui/elements/LoadingCard';\n\nimport { withRedirectToAfterSignIn, withRedirectToSignInTask } from '../../common';\nimport { useCoreSignIn, useEnvironment } from '../../contexts';\nimport { useAlternativeStrategies } from '../../hooks/useAlternativeStrategies';\nimport { localizationKeys } from '../../localization';\nimport { useRouter } from '../../router';\nimport { AlternativeMethods } from './AlternativeMethods';\nimport { hasMultipleEnterpriseConnections } from './shared';\nimport { SignInFactorOneAlternativePhoneCodeCard } from './SignInFactorOneAlternativePhoneCodeCard';\nimport { SignInFactorOneEmailCodeCard } from './SignInFactorOneEmailCodeCard';\nimport { SignInFactorOneEmailLinkCard } from './SignInFactorOneEmailLinkCard';\nimport { SignInFactorOneEnterpriseConnections } from './SignInFactorOneEnterpriseConnections';\nimport { SignInFactorOneForgotPasswordCard } from './SignInFactorOneForgotPasswordCard';\nimport { SignInFactorOnePasskey } from './SignInFactorOnePasskey';\nimport { SignInFactorOnePasswordCard } from './SignInFactorOnePasswordCard';\nimport { SignInFactorOnePhoneCodeCard } from './SignInFactorOnePhoneCodeCard';\nimport { useResetPasswordFactor } from './useResetPasswordFactor';\nimport { determineStartingSignInFactor, factorHasLocalStrategy } from './utils';\n\nconst factorKey = (factor: SignInFactor | null | undefined) => {\n if (!factor) {\n return '';\n }\n let key = factor.strategy;\n if ('emailAddressId' in factor) {\n key += factor.emailAddressId;\n }\n if ('phoneNumberId' in factor) {\n key += factor.phoneNumberId;\n }\n if ('channel' in factor) {\n key += factor.channel;\n }\n return key;\n};\n\nfunction SignInFactorOneInternal(): JSX.Element {\n const { __internal_setActiveInProgress } = useClerk();\n const signIn = useCoreSignIn();\n const { preferredSignInStrategy } = useEnvironment().displayConfig;\n const availableFactors = signIn.supportedFirstFactors;\n const router = useRouter();\n const card = useCardState();\n const { supportedFirstFactors, firstFactorVerification } = useCoreSignIn();\n\n const lastPreparedFactorKeyRef = React.useRef('');\n const [{ currentFactor }, setFactor] = React.useState<{\n currentFactor: SignInFactor | undefined | null;\n prevCurrentFactor: SignInFactor | undefined | null;\n }>(() => {\n const factor = determineStartingSignInFactor(availableFactors, signIn.identifier, preferredSignInStrategy);\n if (\n factor?.strategy === 'phone_code' &&\n !!firstFactorVerification.channel &&\n firstFactorVerification.channel !== 'sms'\n ) {\n // This is only applied to phone_code with channel that is not 'sms'\n // because we don't want to send the channel parameter when its value is 'sms'\n factor.channel = firstFactorVerification.channel;\n }\n return {\n currentFactor: factor,\n prevCurrentFactor: undefined,\n };\n });\n\n const { hasAnyStrategy } = useAlternativeStrategies({\n filterOutFactor: currentFactor,\n supportedFirstFactors,\n });\n\n const [showAllStrategies, setShowAllStrategies] = React.useState<boolean>(\n () => !currentFactor || !factorHasLocalStrategy(currentFactor),\n );\n\n const resetPasswordFactor = useResetPasswordFactor();\n\n const [showForgotPasswordStrategies, setShowForgotPasswordStrategies] = React.useState(false);\n\n const [isPasswordPwned, setIsPasswordPwned] = React.useState(false);\n\n React.useEffect(() => {\n if (__internal_setActiveInProgress) {\n return;\n }\n\n // Handle the case where a user lands on alternative methods screen,\n // clicks a social button but then navigates back to sign in.\n // SignIn status resets to 'needs_identifier'\n if (signIn.status === 'needs_identifier' || signIn.status === null) {\n void router.navigate('../');\n }\n }, [__internal_setActiveInProgress]);\n\n if (!currentFactor) {\n return signIn.status ? (\n <ErrorCard\n cardTitle={localizationKeys('signIn.noAvailableMethods.title')}\n cardSubtitle={localizationKeys('signIn.noAvailableMethods.subtitle')}\n message={localizationKeys('signIn.noAvailableMethods.message')}\n />\n ) : (\n <LoadingCard />\n );\n }\n\n const toggleAllStrategies = hasAnyStrategy ? () => setShowAllStrategies(s => !s) : undefined;\n\n const toggleForgotPasswordStrategies = () => setShowForgotPasswordStrategies(s => !s);\n\n const handleFactorPrepare = () => {\n lastPreparedFactorKeyRef.current = factorKey(currentFactor);\n };\n const selectFactor = (factor: SignInFactor) => {\n setFactor(prev => ({\n currentFactor: factor,\n prevCurrentFactor: prev.currentFactor,\n }));\n };\n\n /**\n * Prompt to choose between a list of enterprise connections as supported first factors\n * @experimental\n */\n if (hasMultipleEnterpriseConnections(signIn.supportedFirstFactors)) {\n return <SignInFactorOneEnterpriseConnections />;\n }\n\n if (showAllStrategies || showForgotPasswordStrategies) {\n const canGoBack = factorHasLocalStrategy(currentFactor);\n\n const toggle = showAllStrategies ? toggleAllStrategies : toggleForgotPasswordStrategies;\n const backHandler = () => {\n card.setError(undefined);\n setIsPasswordPwned(false);\n toggle?.();\n };\n\n const mode = showForgotPasswordStrategies ? (isPasswordPwned ? 'pwned' : 'forgot') : 'default';\n\n return (\n <AlternativeMethods\n mode={mode}\n onBackLinkClick={canGoBack ? backHandler : undefined}\n onFactorSelected={f => {\n selectFactor(f);\n toggle?.();\n }}\n currentFactor={currentFactor}\n />\n );\n }\n\n if (!currentFactor) {\n return <LoadingCard />;\n }\n\n switch (currentFactor?.strategy) {\n case 'passkey':\n return (\n <SignInFactorOnePasskey\n onFactorPrepare={handleFactorPrepare}\n onShowAlternativeMethodsClick={toggleAllStrategies}\n />\n );\n case 'password':\n return (\n <SignInFactorOnePasswordCard\n onForgotPasswordMethodClick={resetPasswordFactor ? toggleForgotPasswordStrategies : toggleAllStrategies}\n onShowAlternativeMethodsClick={toggleAllStrategies}\n onPasswordPwned={() => {\n setIsPasswordPwned(true);\n toggleForgotPasswordStrategies();\n }}\n />\n );\n case 'email_code':\n return (\n <SignInFactorOneEmailCodeCard\n factorAlreadyPrepared={lastPreparedFactorKeyRef.current === factorKey(currentFactor)}\n onFactorPrepare={handleFactorPrepare}\n factor={currentFactor}\n onShowAlternativeMethodsClicked={toggleAllStrategies}\n />\n );\n case 'phone_code':\n if (currentFactor.channel && currentFactor.channel !== 'sms') {\n // Alternative phone code provider (e.g. WhatsApp)\n return (\n <SignInFactorOneAlternativePhoneCodeCard\n factorAlreadyPrepared={lastPreparedFactorKeyRef.current === factorKey(currentFactor)}\n onFactorPrepare={handleFactorPrepare}\n factor={currentFactor}\n onChangePhoneCodeChannel={selectFactor}\n />\n );\n } else {\n // SMS\n return (\n <SignInFactorOnePhoneCodeCard\n factorAlreadyPrepared={lastPreparedFactorKeyRef.current === factorKey(currentFactor)}\n onFactorPrepare={handleFactorPrepare}\n factor={currentFactor}\n onShowAlternativeMethodsClicked={toggleAllStrategies}\n />\n );\n }\n\n case 'email_link':\n return (\n <SignInFactorOneEmailLinkCard\n factorAlreadyPrepared={lastPreparedFactorKeyRef.current === factorKey(currentFactor)}\n onFactorPrepare={handleFactorPrepare}\n factor={currentFactor}\n onShowAlternativeMethodsClicked={toggleAllStrategies}\n />\n );\n case 'reset_password_phone_code':\n return (\n <SignInFactorOneForgotPasswordCard\n factorAlreadyPrepared={lastPreparedFactorKeyRef.current === factorKey(currentFactor)}\n onFactorPrepare={handleFactorPrepare}\n factor={currentFactor}\n onShowAlternativeMethodsClicked={toggleAllStrategies}\n onBackLinkClicked={() => {\n setFactor(prev => ({\n currentFactor: prev.prevCurrentFactor,\n prevCurrentFactor: prev.currentFactor,\n }));\n toggleForgotPasswordStrategies();\n }}\n cardSubtitle={localizationKeys('signIn.forgotPassword.subtitle_phone')}\n />\n );\n\n case 'reset_password_email_code':\n return (\n <SignInFactorOneForgotPasswordCard\n factorAlreadyPrepared={lastPreparedFactorKeyRef.current === factorKey(currentFactor)}\n onFactorPrepare={handleFactorPrepare}\n factor={currentFactor}\n onShowAlternativeMethodsClicked={toggleAllStrategies}\n onBackLinkClicked={() => {\n setFactor(prev => ({\n currentFactor: prev.prevCurrentFactor,\n prevCurrentFactor: prev.currentFactor,\n }));\n toggleForgotPasswordStrategies();\n }}\n cardSubtitle={localizationKeys('signIn.forgotPassword.subtitle_email')}\n />\n );\n default:\n return <LoadingCard />;\n }\n}\n\nexport const SignInFactorOne = withRedirectToSignInTask(\n withRedirectToAfterSignIn(withCardStateProvider(SignInFactorOneInternal)),\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"SignInFactorOne.js","names":[],"sources":["../../../src/components/SignIn/SignInFactorOne.tsx"],"sourcesContent":["import { useClerk } from '@clerk/shared/react';\nimport type { SignInFactor } from '@clerk/shared/types';\nimport React from 'react';\n\nimport { useCardState, withCardStateProvider } from '@/ui/elements/contexts';\nimport { ErrorCard } from '@/ui/elements/ErrorCard';\nimport { LoadingCard } from '@/ui/elements/LoadingCard';\n\nimport { withRedirectToAfterSignIn, withRedirectToSignInTask } from '../../common';\nimport { useCoreSignIn, useEnvironment } from '../../contexts';\nimport { useAlternativeStrategies } from '../../hooks/useAlternativeStrategies';\nimport { localizationKeys } from '../../localization';\nimport { useRouter } from '../../router';\nimport type { AlternativeMethodsMode } from './AlternativeMethods';\nimport { AlternativeMethods } from './AlternativeMethods';\nimport { hasMultipleEnterpriseConnections } from './shared';\nimport { SignInFactorOneAlternativePhoneCodeCard } from './SignInFactorOneAlternativePhoneCodeCard';\nimport { SignInFactorOneEmailCodeCard } from './SignInFactorOneEmailCodeCard';\nimport { SignInFactorOneEmailLinkCard } from './SignInFactorOneEmailLinkCard';\nimport { SignInFactorOneEnterpriseConnections } from './SignInFactorOneEnterpriseConnections';\nimport { SignInFactorOneForgotPasswordCard } from './SignInFactorOneForgotPasswordCard';\nimport { SignInFactorOnePasskey } from './SignInFactorOnePasskey';\nimport type { PasswordErrorCode } from './SignInFactorOnePasswordCard';\nimport { SignInFactorOnePasswordCard } from './SignInFactorOnePasswordCard';\nimport { SignInFactorOnePhoneCodeCard } from './SignInFactorOnePhoneCodeCard';\nimport { useResetPasswordFactor } from './useResetPasswordFactor';\nimport { determineStartingSignInFactor, factorHasLocalStrategy } from './utils';\n\nconst factorKey = (factor: SignInFactor | null | undefined) => {\n if (!factor) {\n return '';\n }\n let key = factor.strategy;\n if ('emailAddressId' in factor) {\n key += factor.emailAddressId;\n }\n if ('phoneNumberId' in factor) {\n key += factor.phoneNumberId;\n }\n if ('channel' in factor) {\n key += factor.channel;\n }\n return key;\n};\n\nfunction determineAlternativeMethodsMode(\n showForgotPasswordStrategies: boolean,\n passwordErrorCode: PasswordErrorCode | null,\n): AlternativeMethodsMode {\n if (!showForgotPasswordStrategies) {\n return 'default';\n }\n\n if (passwordErrorCode === 'pwned') {\n return 'pwned';\n }\n\n if (passwordErrorCode === 'compromised') {\n return 'passwordCompromised';\n }\n\n return 'forgot';\n}\n\nfunction SignInFactorOneInternal(): JSX.Element {\n const { __internal_setActiveInProgress } = useClerk();\n const signIn = useCoreSignIn();\n const { preferredSignInStrategy } = useEnvironment().displayConfig;\n const availableFactors = signIn.supportedFirstFactors;\n const router = useRouter();\n const card = useCardState();\n const { supportedFirstFactors, firstFactorVerification } = useCoreSignIn();\n\n const lastPreparedFactorKeyRef = React.useRef('');\n const [{ currentFactor }, setFactor] = React.useState<{\n currentFactor: SignInFactor | undefined | null;\n prevCurrentFactor: SignInFactor | undefined | null;\n }>(() => {\n const factor = determineStartingSignInFactor(availableFactors, signIn.identifier, preferredSignInStrategy);\n if (\n factor?.strategy === 'phone_code' &&\n !!firstFactorVerification.channel &&\n firstFactorVerification.channel !== 'sms'\n ) {\n // This is only applied to phone_code with channel that is not 'sms'\n // because we don't want to send the channel parameter when its value is 'sms'\n factor.channel = firstFactorVerification.channel;\n }\n return {\n currentFactor: factor,\n prevCurrentFactor: undefined,\n };\n });\n\n const { hasAnyStrategy } = useAlternativeStrategies({\n filterOutFactor: currentFactor,\n supportedFirstFactors,\n });\n\n const [showAllStrategies, setShowAllStrategies] = React.useState<boolean>(\n () => !currentFactor || !factorHasLocalStrategy(currentFactor),\n );\n\n const resetPasswordFactor = useResetPasswordFactor();\n\n const [showForgotPasswordStrategies, setShowForgotPasswordStrategies] = React.useState(false);\n\n const [passwordErrorCode, setPasswordErrorCode] = React.useState<PasswordErrorCode | null>(null);\n\n React.useEffect(() => {\n if (__internal_setActiveInProgress) {\n return;\n }\n\n // Handle the case where a user lands on alternative methods screen,\n // clicks a social button but then navigates back to sign in.\n // SignIn status resets to 'needs_identifier'\n if (signIn.status === 'needs_identifier' || signIn.status === null) {\n void router.navigate('../');\n }\n }, [__internal_setActiveInProgress]);\n\n if (!currentFactor) {\n return signIn.status ? (\n <ErrorCard\n cardTitle={localizationKeys('signIn.noAvailableMethods.title')}\n cardSubtitle={localizationKeys('signIn.noAvailableMethods.subtitle')}\n message={localizationKeys('signIn.noAvailableMethods.message')}\n />\n ) : (\n <LoadingCard />\n );\n }\n\n const toggleAllStrategies = hasAnyStrategy ? () => setShowAllStrategies(s => !s) : undefined;\n\n const toggleForgotPasswordStrategies = () => setShowForgotPasswordStrategies(s => !s);\n\n const handleFactorPrepare = () => {\n lastPreparedFactorKeyRef.current = factorKey(currentFactor);\n };\n const selectFactor = (factor: SignInFactor) => {\n setFactor(prev => ({\n currentFactor: factor,\n prevCurrentFactor: prev.currentFactor,\n }));\n };\n\n /**\n * Prompt to choose between a list of enterprise connections as supported first factors\n * @experimental\n */\n if (hasMultipleEnterpriseConnections(signIn.supportedFirstFactors)) {\n return <SignInFactorOneEnterpriseConnections />;\n }\n\n if (showAllStrategies || showForgotPasswordStrategies) {\n const canGoBack = factorHasLocalStrategy(currentFactor);\n\n const toggle = showAllStrategies ? toggleAllStrategies : toggleForgotPasswordStrategies;\n const backHandler = () => {\n card.setError(undefined);\n setPasswordErrorCode(null);\n toggle?.();\n };\n\n const mode = determineAlternativeMethodsMode(showForgotPasswordStrategies, passwordErrorCode);\n\n return (\n <AlternativeMethods\n mode={mode}\n onBackLinkClick={canGoBack ? backHandler : undefined}\n onFactorSelected={f => {\n selectFactor(f);\n toggle?.();\n }}\n currentFactor={currentFactor}\n />\n );\n }\n\n if (!currentFactor) {\n return <LoadingCard />;\n }\n\n switch (currentFactor?.strategy) {\n case 'passkey':\n return (\n <SignInFactorOnePasskey\n onFactorPrepare={handleFactorPrepare}\n onShowAlternativeMethodsClick={toggleAllStrategies}\n />\n );\n case 'password':\n return (\n <SignInFactorOnePasswordCard\n onForgotPasswordMethodClick={resetPasswordFactor ? toggleForgotPasswordStrategies : toggleAllStrategies}\n onShowAlternativeMethodsClick={toggleAllStrategies}\n onPasswordError={errorCode => {\n setPasswordErrorCode(errorCode);\n toggleForgotPasswordStrategies();\n }}\n />\n );\n case 'email_code':\n return (\n <SignInFactorOneEmailCodeCard\n factorAlreadyPrepared={lastPreparedFactorKeyRef.current === factorKey(currentFactor)}\n onFactorPrepare={handleFactorPrepare}\n factor={currentFactor}\n onShowAlternativeMethodsClicked={toggleAllStrategies}\n />\n );\n case 'phone_code':\n if (currentFactor.channel && currentFactor.channel !== 'sms') {\n // Alternative phone code provider (e.g. WhatsApp)\n return (\n <SignInFactorOneAlternativePhoneCodeCard\n factorAlreadyPrepared={lastPreparedFactorKeyRef.current === factorKey(currentFactor)}\n onFactorPrepare={handleFactorPrepare}\n factor={currentFactor}\n onChangePhoneCodeChannel={selectFactor}\n />\n );\n } else {\n // SMS\n return (\n <SignInFactorOnePhoneCodeCard\n factorAlreadyPrepared={lastPreparedFactorKeyRef.current === factorKey(currentFactor)}\n onFactorPrepare={handleFactorPrepare}\n factor={currentFactor}\n onShowAlternativeMethodsClicked={toggleAllStrategies}\n />\n );\n }\n\n case 'email_link':\n return (\n <SignInFactorOneEmailLinkCard\n factorAlreadyPrepared={lastPreparedFactorKeyRef.current === factorKey(currentFactor)}\n onFactorPrepare={handleFactorPrepare}\n factor={currentFactor}\n onShowAlternativeMethodsClicked={toggleAllStrategies}\n />\n );\n case 'reset_password_phone_code':\n return (\n <SignInFactorOneForgotPasswordCard\n factorAlreadyPrepared={lastPreparedFactorKeyRef.current === factorKey(currentFactor)}\n onFactorPrepare={handleFactorPrepare}\n factor={currentFactor}\n onShowAlternativeMethodsClicked={toggleAllStrategies}\n onBackLinkClicked={() => {\n setFactor(prev => ({\n currentFactor: prev.prevCurrentFactor,\n prevCurrentFactor: prev.currentFactor,\n }));\n toggleForgotPasswordStrategies();\n }}\n cardSubtitle={localizationKeys('signIn.forgotPassword.subtitle_phone')}\n />\n );\n\n case 'reset_password_email_code':\n return (\n <SignInFactorOneForgotPasswordCard\n factorAlreadyPrepared={lastPreparedFactorKeyRef.current === factorKey(currentFactor)}\n onFactorPrepare={handleFactorPrepare}\n factor={currentFactor}\n onShowAlternativeMethodsClicked={toggleAllStrategies}\n onBackLinkClicked={() => {\n setFactor(prev => ({\n currentFactor: prev.prevCurrentFactor,\n prevCurrentFactor: prev.currentFactor,\n }));\n toggleForgotPasswordStrategies();\n }}\n cardSubtitle={localizationKeys('signIn.forgotPassword.subtitle_email')}\n />\n );\n default:\n return <LoadingCard />;\n }\n}\n\nexport const SignInFactorOne = withRedirectToSignInTask(\n withRedirectToAfterSignIn(withCardStateProvider(SignInFactorOneInternal)),\n);\n"],"mappings":"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"}
@@ -18,7 +18,7 @@ import { HavingTrouble } from "./HavingTrouble.js";
18
18
  import { clerkInvalidFAPIResponse } from "@clerk/shared/internal/clerk-js/errors";
19
19
  import React from "react";
20
20
  import { jsx, jsxs } from "@emotion/react/jsx-runtime";
21
- import { isPasswordPwnedError, isUserLockedError } from "@clerk/shared/error";
21
+ import { isPasswordCompromisedError, isPasswordPwnedError, isUserLockedError } from "@clerk/shared/error";
22
22
  import { useClerk } from "@clerk/shared/react";
23
23
 
24
24
  //#region src/components/SignIn/SignInFactorOnePasswordCard.tsx
@@ -40,7 +40,7 @@ const usePasswordControl = (props) => {
40
40
  };
41
41
  };
42
42
  const SignInFactorOnePasswordCard = (props) => {
43
- const { onShowAlternativeMethodsClick, onPasswordPwned } = props;
43
+ const { onShowAlternativeMethodsClick, onPasswordError } = props;
44
44
  const passwordInputRef = React.useRef(null);
45
45
  const card = useCardState();
46
46
  const { setActive } = useClerk();
@@ -53,19 +53,19 @@ const SignInFactorOnePasswordCard = (props) => {
53
53
  const toggleHavingTrouble = React.useCallback(() => setShowHavingTrouble((s) => !s), [setShowHavingTrouble]);
54
54
  const clerk = useClerk();
55
55
  const goBack = () => {
56
- return navigate("../");
56
+ navigate("../");
57
57
  };
58
- const handlePasswordSubmit = async (e) => {
58
+ const handlePasswordSubmit = (e) => {
59
59
  e.preventDefault();
60
- return signIn.attemptFirstFactor({
60
+ signIn.attemptFirstFactor({
61
61
  strategy: "password",
62
62
  password: passwordControl.value
63
63
  }).then((res) => {
64
64
  switch (res.status) {
65
65
  case "complete": return setActive({
66
66
  session: res.createdSessionId,
67
- navigate: async ({ session }) => {
68
- await navigateOnSetActive({
67
+ navigate: ({ session }) => {
68
+ navigateOnSetActive({
69
69
  session,
70
70
  redirectUrl: afterSignInUrl
71
71
  });
@@ -76,13 +76,23 @@ const SignInFactorOnePasswordCard = (props) => {
76
76
  }
77
77
  }).catch((err) => {
78
78
  if (isUserLockedError(err)) return clerk.__internal_navigateWithError("..", err.errors[0]);
79
- if (isPasswordPwnedError(err) && onPasswordPwned) {
80
- card.setError({
81
- ...err.errors[0],
82
- code: "form_password_pwned__sign_in"
83
- });
84
- onPasswordPwned();
85
- return;
79
+ if (onPasswordError) {
80
+ if (isPasswordPwnedError(err)) {
81
+ card.setError({
82
+ ...err.errors[0],
83
+ code: "form_password_pwned__sign_in"
84
+ });
85
+ onPasswordError("pwned");
86
+ return;
87
+ }
88
+ if (isPasswordCompromisedError(err)) {
89
+ card.setError({
90
+ ...err.errors[0],
91
+ code: "form_password_compromised__sign_in"
92
+ });
93
+ onPasswordError("compromised");
94
+ return;
95
+ }
86
96
  }
87
97
  handleError(err, [passwordControl], card.setError);
88
98
  setTimeout(() => passwordInputRef.current?.focus(), 0);
@@ -1 +1 @@
1
- {"version":3,"file":"SignInFactorOnePasswordCard.js","names":["handlePasswordSubmit: React.FormEventHandler"],"sources":["../../../src/components/SignIn/SignInFactorOnePasswordCard.tsx"],"sourcesContent":["import { isPasswordPwnedError, isUserLockedError } from '@clerk/shared/error';\nimport { clerkInvalidFAPIResponse } from '@clerk/shared/internal/clerk-js/errors';\nimport { useClerk } from '@clerk/shared/react';\nimport React from 'react';\n\nimport { Card } from '@/ui/elements/Card';\nimport { useCardState } from '@/ui/elements/contexts';\nimport { Form } from '@/ui/elements/Form';\nimport { Header } from '@/ui/elements/Header';\nimport { IdentityPreview } from '@/ui/elements/IdentityPreview';\nimport { handleError } from '@/ui/utils/errorHandler';\nimport { useFormControl } from '@/ui/utils/useFormControl';\n\nimport { useCoreSignIn, useSignInContext } from '../../contexts';\nimport { descriptors, Flex, Flow, localizationKeys } from '../../customizables';\nimport { useSupportEmail } from '../../hooks/useSupportEmail';\nimport { useRouter } from '../../router/RouteContext';\nimport { HavingTrouble } from './HavingTrouble';\nimport { useResetPasswordFactor } from './useResetPasswordFactor';\n\ntype SignInFactorOnePasswordProps = {\n onForgotPasswordMethodClick: React.MouseEventHandler | undefined;\n onShowAlternativeMethodsClick: React.MouseEventHandler | undefined;\n onPasswordPwned?: () => void;\n};\n\nconst usePasswordControl = (props: SignInFactorOnePasswordProps) => {\n const { onForgotPasswordMethodClick, onShowAlternativeMethodsClick } = props;\n const resetPasswordFactor = useResetPasswordFactor();\n\n const passwordControl = useFormControl('password', '', {\n type: 'password',\n label: localizationKeys('formFieldLabel__password'),\n placeholder: localizationKeys('formFieldInputPlaceholder__password'),\n });\n\n return {\n ...passwordControl,\n props: {\n ...passwordControl.props,\n actionLabel:\n resetPasswordFactor || onShowAlternativeMethodsClick ? localizationKeys('formFieldAction__forgotPassword') : '',\n onActionClicked: onForgotPasswordMethodClick\n ? onForgotPasswordMethodClick\n : onShowAlternativeMethodsClick\n ? onShowAlternativeMethodsClick\n : () => null,\n },\n };\n};\n\nexport const SignInFactorOnePasswordCard = (props: SignInFactorOnePasswordProps) => {\n const { onShowAlternativeMethodsClick, onPasswordPwned } = props;\n const passwordInputRef = React.useRef<HTMLInputElement>(null);\n const card = useCardState();\n const { setActive } = useClerk();\n const signIn = useCoreSignIn();\n const { afterSignInUrl, navigateOnSetActive } = useSignInContext();\n const supportEmail = useSupportEmail();\n const passwordControl = usePasswordControl(props);\n const { navigate } = useRouter();\n const [showHavingTrouble, setShowHavingTrouble] = React.useState(false);\n const toggleHavingTrouble = React.useCallback(() => setShowHavingTrouble(s => !s), [setShowHavingTrouble]);\n const clerk = useClerk();\n\n const goBack = () => {\n return navigate('../');\n };\n\n const handlePasswordSubmit: React.FormEventHandler = async e => {\n e.preventDefault();\n return signIn\n .attemptFirstFactor({ strategy: 'password', password: passwordControl.value })\n .then(res => {\n switch (res.status) {\n case 'complete':\n return setActive({\n session: res.createdSessionId,\n navigate: async ({ session }) => {\n await navigateOnSetActive({ session, redirectUrl: afterSignInUrl });\n },\n });\n case 'needs_second_factor':\n return navigate('../factor-two');\n default:\n return console.error(clerkInvalidFAPIResponse(res.status, supportEmail));\n }\n })\n .catch(err => {\n if (isUserLockedError(err)) {\n // @ts-expect-error -- private method for the time being\n return clerk.__internal_navigateWithError('..', err.errors[0]);\n }\n\n if (isPasswordPwnedError(err) && onPasswordPwned) {\n card.setError({ ...err.errors[0], code: 'form_password_pwned__sign_in' });\n onPasswordPwned();\n return;\n }\n\n handleError(err, [passwordControl], card.setError);\n\n setTimeout(() => passwordInputRef.current?.focus(), 0);\n });\n };\n\n if (showHavingTrouble) {\n return <HavingTrouble onBackLinkClick={toggleHavingTrouble} />;\n }\n\n return (\n <Flow.Part part='password'>\n <Card.Root>\n <Card.Content>\n <Header.Root showLogo>\n <Header.Title localizationKey={localizationKeys('signIn.password.title')} />\n <Header.Subtitle localizationKey={localizationKeys('signIn.password.subtitle')} />\n <IdentityPreview\n identifier={signIn.identifier}\n avatarUrl={signIn.userData.imageUrl}\n onClick={goBack}\n />\n </Header.Root>\n <Card.Alert>{card.error}</Card.Alert>\n {/*TODO: extract main in its own component */}\n <Flex\n direction='col'\n elementDescriptor={descriptors.main}\n gap={4}\n >\n <Form.Root\n onSubmit={handlePasswordSubmit}\n gap={8}\n >\n {/* For password managers */}\n <input\n readOnly\n id='identifier-field'\n name='identifier'\n value={signIn.identifier || ''}\n style={{ display: 'none' }}\n />\n <Form.ControlRow elementId={passwordControl.id}>\n <Form.PasswordInput\n {...passwordControl.props}\n ref={passwordInputRef}\n autoFocus\n />\n </Form.ControlRow>\n <Form.SubmitButton hasArrow />\n </Form.Root>\n <Card.Action elementId={onShowAlternativeMethodsClick ? 'alternativeMethods' : 'havingTrouble'}>\n <Card.ActionLink\n localizationKey={localizationKeys(\n onShowAlternativeMethodsClick ? 'signIn.password.actionLink' : 'signIn.alternativeMethods.actionLink',\n )}\n onClick={onShowAlternativeMethodsClick || toggleHavingTrouble}\n />\n </Card.Action>\n </Flex>\n </Card.Content>\n\n <Card.Footer />\n </Card.Root>\n </Flow.Part>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA0BA,MAAM,sBAAsB,UAAwC;CAClE,MAAM,EAAE,6BAA6B,kCAAkC;CACvE,MAAM,sBAAsB,wBAAwB;CAEpD,MAAM,kBAAkB,eAAe,YAAY,IAAI;EACrD,MAAM;EACN,OAAO,iBAAiB,2BAA2B;EACnD,aAAa,iBAAiB,sCAAsC;EACrE,CAAC;AAEF,QAAO;EACL,GAAG;EACH,OAAO;GACL,GAAG,gBAAgB;GACnB,aACE,uBAAuB,gCAAgC,iBAAiB,kCAAkC,GAAG;GAC/G,iBAAiB,8BACb,8BACA,gCACE,sCACM;GACb;EACF;;AAGH,MAAa,+BAA+B,UAAwC;CAClF,MAAM,EAAE,+BAA+B,oBAAoB;CAC3D,MAAM,mBAAmB,MAAM,OAAyB,KAAK;CAC7D,MAAM,OAAO,cAAc;CAC3B,MAAM,EAAE,cAAc,UAAU;CAChC,MAAM,SAAS,eAAe;CAC9B,MAAM,EAAE,gBAAgB,wBAAwB,kBAAkB;CAClE,MAAM,eAAe,iBAAiB;CACtC,MAAM,kBAAkB,mBAAmB,MAAM;CACjD,MAAM,EAAE,aAAa,WAAW;CAChC,MAAM,CAAC,mBAAmB,wBAAwB,MAAM,SAAS,MAAM;CACvE,MAAM,sBAAsB,MAAM,kBAAkB,sBAAqB,MAAK,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC;CAC1G,MAAM,QAAQ,UAAU;CAExB,MAAM,eAAe;AACnB,SAAO,SAAS,MAAM;;CAGxB,MAAMA,uBAA+C,OAAM,MAAK;AAC9D,IAAE,gBAAgB;AAClB,SAAO,OACJ,mBAAmB;GAAE,UAAU;GAAY,UAAU,gBAAgB;GAAO,CAAC,CAC7E,MAAK,QAAO;AACX,WAAQ,IAAI,QAAZ;IACE,KAAK,WACH,QAAO,UAAU;KACf,SAAS,IAAI;KACb,UAAU,OAAO,EAAE,cAAc;AAC/B,YAAM,oBAAoB;OAAE;OAAS,aAAa;OAAgB,CAAC;;KAEtE,CAAC;IACJ,KAAK,sBACH,QAAO,SAAS,gBAAgB;IAClC,QACE,QAAO,QAAQ,MAAM,yBAAyB,IAAI,QAAQ,aAAa,CAAC;;IAE5E,CACD,OAAM,QAAO;AACZ,OAAI,kBAAkB,IAAI,CAExB,QAAO,MAAM,6BAA6B,MAAM,IAAI,OAAO,GAAG;AAGhE,OAAI,qBAAqB,IAAI,IAAI,iBAAiB;AAChD,SAAK,SAAS;KAAE,GAAG,IAAI,OAAO;KAAI,MAAM;KAAgC,CAAC;AACzE,qBAAiB;AACjB;;AAGF,eAAY,KAAK,CAAC,gBAAgB,EAAE,KAAK,SAAS;AAElD,oBAAiB,iBAAiB,SAAS,OAAO,EAAE,EAAE;IACtD;;AAGN,KAAI,kBACF,QAAO,oBAAC,iBAAc,iBAAiB,sBAAuB;AAGhE,QACE,oBAAC,KAAK;EAAK,MAAK;YACd,qBAAC,KAAK,mBACJ,qBAAC,KAAK;GACJ,qBAAC,OAAO;IAAK;;KACX,oBAAC,OAAO,SAAM,iBAAiB,iBAAiB,wBAAwB,GAAI;KAC5E,oBAAC,OAAO,YAAS,iBAAiB,iBAAiB,2BAA2B,GAAI;KAClF,oBAAC;MACC,YAAY,OAAO;MACnB,WAAW,OAAO,SAAS;MAC3B,SAAS;OACT;;KACU;GACd,oBAAC,KAAK,mBAAO,KAAK,QAAmB;GAErC,qBAAC;IACC,WAAU;IACV,mBAAmB,YAAY;IAC/B,KAAK;eAEL,qBAAC,KAAK;KACJ,UAAU;KACV,KAAK;;MAGL,oBAAC;OACC;OACA,IAAG;OACH,MAAK;OACL,OAAO,OAAO,cAAc;OAC5B,OAAO,EAAE,SAAS,QAAQ;QAC1B;MACF,oBAAC,KAAK;OAAW,WAAW,gBAAgB;iBAC1C,oBAAC,KAAK;QACJ,GAAI,gBAAgB;QACpB,KAAK;QACL;SACA;QACc;MAClB,oBAAC,KAAK,gBAAa,iBAAW;;MACpB,EACZ,oBAAC,KAAK;KAAO,WAAW,gCAAgC,uBAAuB;eAC7E,oBAAC,KAAK;MACJ,iBAAiB,iBACf,gCAAgC,+BAA+B,uCAChE;MACD,SAAS,iCAAiC;OAC1C;MACU;KACT;MACM,EAEf,oBAAC,KAAK,WAAS,IACL;GACF"}
1
+ {"version":3,"file":"SignInFactorOnePasswordCard.js","names":["handlePasswordSubmit: React.FormEventHandler<HTMLFormElement>"],"sources":["../../../src/components/SignIn/SignInFactorOnePasswordCard.tsx"],"sourcesContent":["import { isPasswordCompromisedError, isPasswordPwnedError, isUserLockedError } from '@clerk/shared/error';\nimport { clerkInvalidFAPIResponse } from '@clerk/shared/internal/clerk-js/errors';\nimport { useClerk } from '@clerk/shared/react';\nimport React from 'react';\n\nimport { Card } from '@/ui/elements/Card';\nimport { useCardState } from '@/ui/elements/contexts';\nimport { Form } from '@/ui/elements/Form';\nimport { Header } from '@/ui/elements/Header';\nimport { IdentityPreview } from '@/ui/elements/IdentityPreview';\nimport { handleError } from '@/ui/utils/errorHandler';\nimport { useFormControl } from '@/ui/utils/useFormControl';\n\nimport { useCoreSignIn, useSignInContext } from '../../contexts';\nimport { descriptors, Flex, Flow, localizationKeys } from '../../customizables';\nimport { useSupportEmail } from '../../hooks/useSupportEmail';\nimport { useRouter } from '../../router/RouteContext';\nimport { HavingTrouble } from './HavingTrouble';\nimport { useResetPasswordFactor } from './useResetPasswordFactor';\n\nexport type PasswordErrorCode = 'compromised' | 'pwned';\n\ntype SignInFactorOnePasswordProps = {\n onForgotPasswordMethodClick: React.MouseEventHandler | undefined;\n onShowAlternativeMethodsClick: React.MouseEventHandler | undefined;\n onPasswordError?: (errorCode: PasswordErrorCode) => void;\n};\n\nconst usePasswordControl = (props: SignInFactorOnePasswordProps) => {\n const { onForgotPasswordMethodClick, onShowAlternativeMethodsClick } = props;\n const resetPasswordFactor = useResetPasswordFactor();\n\n const passwordControl = useFormControl('password', '', {\n type: 'password',\n label: localizationKeys('formFieldLabel__password'),\n placeholder: localizationKeys('formFieldInputPlaceholder__password'),\n });\n\n return {\n ...passwordControl,\n props: {\n ...passwordControl.props,\n actionLabel:\n resetPasswordFactor || onShowAlternativeMethodsClick ? localizationKeys('formFieldAction__forgotPassword') : '',\n onActionClicked: onForgotPasswordMethodClick\n ? onForgotPasswordMethodClick\n : onShowAlternativeMethodsClick\n ? onShowAlternativeMethodsClick\n : () => null,\n },\n };\n};\n\nexport const SignInFactorOnePasswordCard = (props: SignInFactorOnePasswordProps) => {\n const { onShowAlternativeMethodsClick, onPasswordError } = props;\n const passwordInputRef = React.useRef<HTMLInputElement>(null);\n const card = useCardState();\n const { setActive } = useClerk();\n const signIn = useCoreSignIn();\n const { afterSignInUrl, navigateOnSetActive } = useSignInContext();\n const supportEmail = useSupportEmail();\n const passwordControl = usePasswordControl(props);\n const { navigate } = useRouter();\n const [showHavingTrouble, setShowHavingTrouble] = React.useState(false);\n const toggleHavingTrouble = React.useCallback(() => setShowHavingTrouble(s => !s), [setShowHavingTrouble]);\n const clerk = useClerk();\n\n const goBack = () => {\n void navigate('../');\n };\n\n const handlePasswordSubmit: React.FormEventHandler<HTMLFormElement> = e => {\n e.preventDefault();\n void signIn\n .attemptFirstFactor({ strategy: 'password', password: passwordControl.value })\n .then(res => {\n switch (res.status) {\n case 'complete':\n return setActive({\n session: res.createdSessionId,\n navigate: ({ session }) => {\n void navigateOnSetActive({ session, redirectUrl: afterSignInUrl });\n },\n });\n case 'needs_second_factor':\n return navigate('../factor-two');\n default:\n return console.error(clerkInvalidFAPIResponse(res.status, supportEmail));\n }\n })\n .catch(err => {\n if (isUserLockedError(err)) {\n // @ts-expect-error -- private method for the time being\n return clerk.__internal_navigateWithError('..', err.errors[0]);\n }\n\n if (onPasswordError) {\n if (isPasswordPwnedError(err)) {\n card.setError({ ...err.errors[0], code: 'form_password_pwned__sign_in' });\n onPasswordError('pwned');\n return;\n }\n\n if (isPasswordCompromisedError(err)) {\n card.setError({ ...err.errors[0], code: 'form_password_compromised__sign_in' });\n onPasswordError('compromised');\n return;\n }\n }\n\n handleError(err, [passwordControl], card.setError);\n\n setTimeout(() => passwordInputRef.current?.focus(), 0);\n });\n };\n\n if (showHavingTrouble) {\n return <HavingTrouble onBackLinkClick={toggleHavingTrouble} />;\n }\n\n return (\n <Flow.Part part='password'>\n <Card.Root>\n <Card.Content>\n <Header.Root showLogo>\n <Header.Title localizationKey={localizationKeys('signIn.password.title')} />\n <Header.Subtitle localizationKey={localizationKeys('signIn.password.subtitle')} />\n <IdentityPreview\n identifier={signIn.identifier}\n avatarUrl={signIn.userData.imageUrl}\n onClick={goBack}\n />\n </Header.Root>\n <Card.Alert>{card.error}</Card.Alert>\n {/*TODO: extract main in its own component */}\n <Flex\n direction='col'\n elementDescriptor={descriptors.main}\n gap={4}\n >\n <Form.Root\n onSubmit={handlePasswordSubmit}\n gap={8}\n >\n {/* For password managers */}\n <input\n readOnly\n id='identifier-field'\n name='identifier'\n value={signIn.identifier || ''}\n style={{ display: 'none' }}\n />\n <Form.ControlRow elementId={passwordControl.id}>\n <Form.PasswordInput\n {...passwordControl.props}\n ref={passwordInputRef}\n autoFocus\n />\n </Form.ControlRow>\n <Form.SubmitButton hasArrow />\n </Form.Root>\n <Card.Action elementId={onShowAlternativeMethodsClick ? 'alternativeMethods' : 'havingTrouble'}>\n <Card.ActionLink\n localizationKey={localizationKeys(\n onShowAlternativeMethodsClick ? 'signIn.password.actionLink' : 'signIn.alternativeMethods.actionLink',\n )}\n onClick={onShowAlternativeMethodsClick || toggleHavingTrouble}\n />\n </Card.Action>\n </Flex>\n </Card.Content>\n\n <Card.Footer />\n </Card.Root>\n </Flow.Part>\n );\n};\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { useRouter } from "../../router/RouteContext.js";
2
+ import { useEnvironment } from "../../contexts/EnvironmentContext.js";
2
3
  import { localizationKeys } from "../../localization/localizationKeys.js";
3
4
  import { useSignInContext } from "../../contexts/components/SignIn.js";
4
5
  import { useCoreSignIn } from "../../contexts/CoreClientContext.js";
@@ -9,15 +10,15 @@ import { useSupportEmail } from "../../hooks/useSupportEmail.js";
9
10
  import { isResetPasswordStrategy } from "./utils.js";
10
11
  import { VerificationCodeCard } from "../../elements/VerificationCodeCard.js";
11
12
  import { clerkInvalidFAPIResponse } from "@clerk/shared/internal/clerk-js/errors";
12
- import React from "react";
13
+ import React, { useMemo } from "react";
13
14
  import { jsx } from "@emotion/react/jsx-runtime";
14
15
  import { isUserLockedError } from "@clerk/shared/error";
15
16
  import { useClerk } from "@clerk/shared/react";
16
17
 
17
18
  //#region src/components/SignIn/SignInFactorTwoCodeForm.tsx
18
19
  const isResettingPassword = (resource) => isResetPasswordStrategy(resource.firstFactorVerification?.strategy) && resource.firstFactorVerification?.status === "verified";
19
- const isNewDevice = (resource) => resource.clientTrustState === "new";
20
20
  const SignInFactorTwoCodeForm = (props) => {
21
+ const env = useEnvironment();
21
22
  const signIn = useCoreSignIn();
22
23
  const card = useCardState();
23
24
  const { afterSignInUrl, navigateOnSetActive } = useSignInContext();
@@ -25,6 +26,10 @@ const SignInFactorTwoCodeForm = (props) => {
25
26
  const { navigate } = useRouter();
26
27
  const supportEmail = useSupportEmail();
27
28
  const clerk = useClerk();
29
+ const showNewDeviceVerificationNotice = useMemo(() => {
30
+ const anyAttributeUsedForSecondFactor = Object.values(env.userSettings.attributes).some((attr) => attr.used_for_second_factor);
31
+ return signIn.clientTrustState === "new" && !anyAttributeUsedForSecondFactor;
32
+ }, [signIn.clientTrustState, env.userSettings.attributes]);
28
33
  React.useEffect(() => {
29
34
  if (props.factorAlreadyPrepared) return;
30
35
  prepare?.();
@@ -67,7 +72,7 @@ const SignInFactorTwoCodeForm = (props) => {
67
72
  return /* @__PURE__ */ jsx(VerificationCodeCard, {
68
73
  cardTitle: props.cardTitle,
69
74
  cardSubtitle: isResettingPassword(signIn) ? localizationKeys("signIn.forgotPassword.subtitle") : props.cardSubtitle,
70
- cardNotice: isNewDevice(signIn) ? localizationKeys("signIn.newDeviceVerificationNotice") : void 0,
75
+ cardNotice: showNewDeviceVerificationNotice ? localizationKeys("signIn.newDeviceVerificationNotice") : void 0,
71
76
  resendButton: props.resendButton,
72
77
  inputLabel: props.inputLabel,
73
78
  onCodeEntryFinishedAction: action,
@@ -1 +1 @@
1
- {"version":3,"file":"SignInFactorTwoCodeForm.js","names":["action: VerificationCodeCardProps['onCodeEntryFinishedAction']"],"sources":["../../../src/components/SignIn/SignInFactorTwoCodeForm.tsx"],"sourcesContent":["import { isUserLockedError } from '@clerk/shared/error';\nimport { clerkInvalidFAPIResponse } from '@clerk/shared/internal/clerk-js/errors';\nimport { useClerk } from '@clerk/shared/react';\nimport type { EmailCodeFactor, PhoneCodeFactor, SignInResource, TOTPFactor } from '@clerk/shared/types';\nimport React from 'react';\n\nimport { useCardState } from '@/ui/elements/contexts';\nimport type { VerificationCodeCardProps } from '@/ui/elements/VerificationCodeCard';\nimport { VerificationCodeCard } from '@/ui/elements/VerificationCodeCard';\nimport { handleError } from '@/ui/utils/errorHandler';\n\nimport { useCoreSignIn, useSignInContext } from '../../contexts';\nimport { localizationKeys, Text } from '../../customizables';\nimport { useSupportEmail } from '../../hooks/useSupportEmail';\nimport type { LocalizationKey } from '../../localization';\nimport { useRouter } from '../../router';\nimport { isResetPasswordStrategy } from './utils';\n\nexport type SignInFactorTwoCodeCard = Pick<VerificationCodeCardProps, 'onShowAlternativeMethodsClicked'> & {\n factor: EmailCodeFactor | PhoneCodeFactor | TOTPFactor;\n factorAlreadyPrepared: boolean;\n onFactorPrepare: () => void;\n prepare?: () => Promise<SignInResource>;\n};\n\ntype SignInFactorTwoCodeFormProps = SignInFactorTwoCodeCard & {\n cardTitle: LocalizationKey;\n cardSubtitle: LocalizationKey;\n inputLabel: LocalizationKey;\n resendButton?: LocalizationKey;\n};\n\nconst isResettingPassword = (resource: SignInResource) =>\n isResetPasswordStrategy(resource.firstFactorVerification?.strategy) &&\n resource.firstFactorVerification?.status === 'verified';\n\nconst isNewDevice = (resource: SignInResource) => resource.clientTrustState === 'new';\n\nexport const SignInFactorTwoCodeForm = (props: SignInFactorTwoCodeFormProps) => {\n const signIn = useCoreSignIn();\n const card = useCardState();\n const { afterSignInUrl, navigateOnSetActive } = useSignInContext();\n const { setActive } = useClerk();\n const { navigate } = useRouter();\n const supportEmail = useSupportEmail();\n const clerk = useClerk();\n\n React.useEffect(() => {\n if (props.factorAlreadyPrepared) {\n return;\n }\n\n void prepare?.();\n }, []);\n\n const prepare = props.prepare\n ? () => {\n return props\n .prepare?.()\n .then(() => props.onFactorPrepare())\n .catch(err => {\n if (isUserLockedError(err)) {\n // @ts-expect-error -- private method for the time being\n return clerk.__internal_navigateWithError('..', err.errors[0]);\n }\n\n handleError(err, [], card.setError);\n });\n }\n : undefined;\n\n const action: VerificationCodeCardProps['onCodeEntryFinishedAction'] = (code, resolve, reject) => {\n signIn\n .attemptSecondFactor({ strategy: props.factor.strategy, code })\n .then(async res => {\n await resolve();\n switch (res.status) {\n case 'complete':\n if (isResettingPassword(res) && res.createdSessionId) {\n const queryParams = new URLSearchParams();\n queryParams.set('createdSessionId', res.createdSessionId);\n return navigate(`../reset-password-success?${queryParams.toString()}`);\n }\n return setActive({\n session: res.createdSessionId,\n navigate: async ({ session }) => {\n await navigateOnSetActive({ session, redirectUrl: afterSignInUrl });\n },\n });\n default:\n return console.error(clerkInvalidFAPIResponse(res.status, supportEmail));\n }\n })\n .catch(err => {\n if (isUserLockedError(err)) {\n // @ts-expect-error -- private method for the time being\n return clerk.__internal_navigateWithError('..', err.errors[0]);\n }\n\n return reject(err);\n });\n };\n\n return (\n <VerificationCodeCard\n cardTitle={props.cardTitle}\n cardSubtitle={\n isResettingPassword(signIn) ? localizationKeys('signIn.forgotPassword.subtitle') : props.cardSubtitle\n }\n cardNotice={isNewDevice(signIn) ? localizationKeys('signIn.newDeviceVerificationNotice') : undefined}\n resendButton={props.resendButton}\n inputLabel={props.inputLabel}\n onCodeEntryFinishedAction={action}\n onResendCodeClicked={prepare}\n safeIdentifier={'safeIdentifier' in props.factor ? props.factor.safeIdentifier : undefined}\n profileImageUrl={signIn.userData.imageUrl}\n onShowAlternativeMethodsClicked={props.onShowAlternativeMethodsClicked}\n >\n {isResettingPassword(signIn) && (\n <Text\n localizationKey={localizationKeys('signIn.resetPasswordMfa.detailsLabel')}\n colorScheme='secondary'\n />\n )}\n </VerificationCodeCard>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AAgCA,MAAM,uBAAuB,aAC3B,wBAAwB,SAAS,yBAAyB,SAAS,IACnE,SAAS,yBAAyB,WAAW;AAE/C,MAAM,eAAe,aAA6B,SAAS,qBAAqB;AAEhF,MAAa,2BAA2B,UAAwC;CAC9E,MAAM,SAAS,eAAe;CAC9B,MAAM,OAAO,cAAc;CAC3B,MAAM,EAAE,gBAAgB,wBAAwB,kBAAkB;CAClE,MAAM,EAAE,cAAc,UAAU;CAChC,MAAM,EAAE,aAAa,WAAW;CAChC,MAAM,eAAe,iBAAiB;CACtC,MAAM,QAAQ,UAAU;AAExB,OAAM,gBAAgB;AACpB,MAAI,MAAM,sBACR;AAGF,EAAK,WAAW;IACf,EAAE,CAAC;CAEN,MAAM,UAAU,MAAM,gBACZ;AACJ,SAAO,MACJ,WAAW,CACX,WAAW,MAAM,iBAAiB,CAAC,CACnC,OAAM,QAAO;AACZ,OAAI,kBAAkB,IAAI,CAExB,QAAO,MAAM,6BAA6B,MAAM,IAAI,OAAO,GAAG;AAGhE,eAAY,KAAK,EAAE,EAAE,KAAK,SAAS;IACnC;KAEN;CAEJ,MAAMA,UAAkE,MAAM,SAAS,WAAW;AAChG,SACG,oBAAoB;GAAE,UAAU,MAAM,OAAO;GAAU;GAAM,CAAC,CAC9D,KAAK,OAAM,QAAO;AACjB,SAAM,SAAS;AACf,WAAQ,IAAI,QAAZ;IACE,KAAK;AACH,SAAI,oBAAoB,IAAI,IAAI,IAAI,kBAAkB;MACpD,MAAM,cAAc,IAAI,iBAAiB;AACzC,kBAAY,IAAI,oBAAoB,IAAI,iBAAiB;AACzD,aAAO,SAAS,6BAA6B,YAAY,UAAU,GAAG;;AAExE,YAAO,UAAU;MACf,SAAS,IAAI;MACb,UAAU,OAAO,EAAE,cAAc;AAC/B,aAAM,oBAAoB;QAAE;QAAS,aAAa;QAAgB,CAAC;;MAEtE,CAAC;IACJ,QACE,QAAO,QAAQ,MAAM,yBAAyB,IAAI,QAAQ,aAAa,CAAC;;IAE5E,CACD,OAAM,QAAO;AACZ,OAAI,kBAAkB,IAAI,CAExB,QAAO,MAAM,6BAA6B,MAAM,IAAI,OAAO,GAAG;AAGhE,UAAO,OAAO,IAAI;IAClB;;AAGN,QACE,oBAAC;EACC,WAAW,MAAM;EACjB,cACE,oBAAoB,OAAO,GAAG,iBAAiB,iCAAiC,GAAG,MAAM;EAE3F,YAAY,YAAY,OAAO,GAAG,iBAAiB,qCAAqC,GAAG;EAC3F,cAAc,MAAM;EACpB,YAAY,MAAM;EAClB,2BAA2B;EAC3B,qBAAqB;EACrB,gBAAgB,oBAAoB,MAAM,SAAS,MAAM,OAAO,iBAAiB;EACjF,iBAAiB,OAAO,SAAS;EACjC,iCAAiC,MAAM;YAEtC,oBAAoB,OAAO,IAC1B,oBAAC;GACC,iBAAiB,iBAAiB,uCAAuC;GACzE,aAAY;IACZ;GAEiB"}
1
+ {"version":3,"file":"SignInFactorTwoCodeForm.js","names":["action: VerificationCodeCardProps['onCodeEntryFinishedAction']"],"sources":["../../../src/components/SignIn/SignInFactorTwoCodeForm.tsx"],"sourcesContent":["import { isUserLockedError } from '@clerk/shared/error';\nimport { clerkInvalidFAPIResponse } from '@clerk/shared/internal/clerk-js/errors';\nimport { useClerk } from '@clerk/shared/react';\nimport type { EmailCodeFactor, PhoneCodeFactor, SignInResource, TOTPFactor } from '@clerk/shared/types';\nimport React, { useMemo } from 'react';\n\nimport { useCardState } from '@/ui/elements/contexts';\nimport type { VerificationCodeCardProps } from '@/ui/elements/VerificationCodeCard';\nimport { VerificationCodeCard } from '@/ui/elements/VerificationCodeCard';\nimport { handleError } from '@/ui/utils/errorHandler';\n\nimport { useCoreSignIn, useEnvironment, useSignInContext } from '../../contexts';\nimport { localizationKeys, Text } from '../../customizables';\nimport { useSupportEmail } from '../../hooks/useSupportEmail';\nimport type { LocalizationKey } from '../../localization';\nimport { useRouter } from '../../router';\nimport { isResetPasswordStrategy } from './utils';\n\nexport type SignInFactorTwoCodeCard = Pick<VerificationCodeCardProps, 'onShowAlternativeMethodsClicked'> & {\n factor: EmailCodeFactor | PhoneCodeFactor | TOTPFactor;\n factorAlreadyPrepared: boolean;\n onFactorPrepare: () => void;\n prepare?: () => Promise<SignInResource>;\n};\n\ntype SignInFactorTwoCodeFormProps = SignInFactorTwoCodeCard & {\n cardTitle: LocalizationKey;\n cardSubtitle: LocalizationKey;\n inputLabel: LocalizationKey;\n resendButton?: LocalizationKey;\n};\n\nconst isResettingPassword = (resource: SignInResource) =>\n isResetPasswordStrategy(resource.firstFactorVerification?.strategy) &&\n resource.firstFactorVerification?.status === 'verified';\n\nexport const SignInFactorTwoCodeForm = (props: SignInFactorTwoCodeFormProps) => {\n const env = useEnvironment();\n const signIn = useCoreSignIn();\n const card = useCardState();\n const { afterSignInUrl, navigateOnSetActive } = useSignInContext();\n const { setActive } = useClerk();\n const { navigate } = useRouter();\n const supportEmail = useSupportEmail();\n const clerk = useClerk();\n\n // Only show the new device verification notice if the user is new\n // and no attributes are explicitly used for second factor.\n const showNewDeviceVerificationNotice = useMemo(() => {\n const anyAttributeUsedForSecondFactor = Object.values(env.userSettings.attributes).some(\n attr => attr.used_for_second_factor,\n );\n return signIn.clientTrustState === 'new' && !anyAttributeUsedForSecondFactor;\n }, [signIn.clientTrustState, env.userSettings.attributes]);\n\n React.useEffect(() => {\n if (props.factorAlreadyPrepared) {\n return;\n }\n\n void prepare?.();\n }, []);\n\n const prepare = props.prepare\n ? () => {\n return props\n .prepare?.()\n .then(() => props.onFactorPrepare())\n .catch(err => {\n if (isUserLockedError(err)) {\n // @ts-expect-error -- private method for the time being\n return clerk.__internal_navigateWithError('..', err.errors[0]);\n }\n\n handleError(err, [], card.setError);\n });\n }\n : undefined;\n\n const action: VerificationCodeCardProps['onCodeEntryFinishedAction'] = (code, resolve, reject) => {\n signIn\n .attemptSecondFactor({ strategy: props.factor.strategy, code })\n .then(async res => {\n await resolve();\n switch (res.status) {\n case 'complete':\n if (isResettingPassword(res) && res.createdSessionId) {\n const queryParams = new URLSearchParams();\n queryParams.set('createdSessionId', res.createdSessionId);\n return navigate(`../reset-password-success?${queryParams.toString()}`);\n }\n return setActive({\n session: res.createdSessionId,\n navigate: async ({ session }) => {\n await navigateOnSetActive({ session, redirectUrl: afterSignInUrl });\n },\n });\n default:\n return console.error(clerkInvalidFAPIResponse(res.status, supportEmail));\n }\n })\n .catch(err => {\n if (isUserLockedError(err)) {\n // @ts-expect-error -- private method for the time being\n return clerk.__internal_navigateWithError('..', err.errors[0]);\n }\n\n return reject(err);\n });\n };\n\n return (\n <VerificationCodeCard\n cardTitle={props.cardTitle}\n cardSubtitle={\n isResettingPassword(signIn) ? localizationKeys('signIn.forgotPassword.subtitle') : props.cardSubtitle\n }\n cardNotice={showNewDeviceVerificationNotice ? localizationKeys('signIn.newDeviceVerificationNotice') : undefined}\n resendButton={props.resendButton}\n inputLabel={props.inputLabel}\n onCodeEntryFinishedAction={action}\n onResendCodeClicked={prepare}\n safeIdentifier={'safeIdentifier' in props.factor ? props.factor.safeIdentifier : undefined}\n profileImageUrl={signIn.userData.imageUrl}\n onShowAlternativeMethodsClicked={props.onShowAlternativeMethodsClicked}\n >\n {isResettingPassword(signIn) && (\n <Text\n localizationKey={localizationKeys('signIn.resetPasswordMfa.detailsLabel')}\n colorScheme='secondary'\n />\n )}\n </VerificationCodeCard>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAgCA,MAAM,uBAAuB,aAC3B,wBAAwB,SAAS,yBAAyB,SAAS,IACnE,SAAS,yBAAyB,WAAW;AAE/C,MAAa,2BAA2B,UAAwC;CAC9E,MAAM,MAAM,gBAAgB;CAC5B,MAAM,SAAS,eAAe;CAC9B,MAAM,OAAO,cAAc;CAC3B,MAAM,EAAE,gBAAgB,wBAAwB,kBAAkB;CAClE,MAAM,EAAE,cAAc,UAAU;CAChC,MAAM,EAAE,aAAa,WAAW;CAChC,MAAM,eAAe,iBAAiB;CACtC,MAAM,QAAQ,UAAU;CAIxB,MAAM,kCAAkC,cAAc;EACpD,MAAM,kCAAkC,OAAO,OAAO,IAAI,aAAa,WAAW,CAAC,MACjF,SAAQ,KAAK,uBACd;AACD,SAAO,OAAO,qBAAqB,SAAS,CAAC;IAC5C,CAAC,OAAO,kBAAkB,IAAI,aAAa,WAAW,CAAC;AAE1D,OAAM,gBAAgB;AACpB,MAAI,MAAM,sBACR;AAGF,EAAK,WAAW;IACf,EAAE,CAAC;CAEN,MAAM,UAAU,MAAM,gBACZ;AACJ,SAAO,MACJ,WAAW,CACX,WAAW,MAAM,iBAAiB,CAAC,CACnC,OAAM,QAAO;AACZ,OAAI,kBAAkB,IAAI,CAExB,QAAO,MAAM,6BAA6B,MAAM,IAAI,OAAO,GAAG;AAGhE,eAAY,KAAK,EAAE,EAAE,KAAK,SAAS;IACnC;KAEN;CAEJ,MAAMA,UAAkE,MAAM,SAAS,WAAW;AAChG,SACG,oBAAoB;GAAE,UAAU,MAAM,OAAO;GAAU;GAAM,CAAC,CAC9D,KAAK,OAAM,QAAO;AACjB,SAAM,SAAS;AACf,WAAQ,IAAI,QAAZ;IACE,KAAK;AACH,SAAI,oBAAoB,IAAI,IAAI,IAAI,kBAAkB;MACpD,MAAM,cAAc,IAAI,iBAAiB;AACzC,kBAAY,IAAI,oBAAoB,IAAI,iBAAiB;AACzD,aAAO,SAAS,6BAA6B,YAAY,UAAU,GAAG;;AAExE,YAAO,UAAU;MACf,SAAS,IAAI;MACb,UAAU,OAAO,EAAE,cAAc;AAC/B,aAAM,oBAAoB;QAAE;QAAS,aAAa;QAAgB,CAAC;;MAEtE,CAAC;IACJ,QACE,QAAO,QAAQ,MAAM,yBAAyB,IAAI,QAAQ,aAAa,CAAC;;IAE5E,CACD,OAAM,QAAO;AACZ,OAAI,kBAAkB,IAAI,CAExB,QAAO,MAAM,6BAA6B,MAAM,IAAI,OAAO,GAAG;AAGhE,UAAO,OAAO,IAAI;IAClB;;AAGN,QACE,oBAAC;EACC,WAAW,MAAM;EACjB,cACE,oBAAoB,OAAO,GAAG,iBAAiB,iCAAiC,GAAG,MAAM;EAE3F,YAAY,kCAAkC,iBAAiB,qCAAqC,GAAG;EACvG,cAAc,MAAM;EACpB,YAAY,MAAM;EAClB,2BAA2B;EAC3B,qBAAqB;EACrB,gBAAgB,oBAAoB,MAAM,SAAS,MAAM,OAAO,iBAAiB;EACjF,iBAAiB,OAAO,SAAS;EACjC,iCAAiC,MAAM;YAEtC,oBAAoB,OAAO,IAC1B,oBAAC;GACC,iBAAiB,iBAAiB,uCAAuC;GACzE,aAAY;IACZ;GAEiB"}
@@ -9,7 +9,9 @@ import { originPrefersPopup } from "../../utils/originPrefersPopup.js";
9
9
  import { web3CallbackErrorHandler } from "../../utils/web3CallbackErrorHandler.js";
10
10
  import { SocialButtons } from "../../elements/SocialButtons.js";
11
11
  import React from "react";
12
+ import { ERROR_CODES } from "@clerk/shared/internal/clerk-js/constants";
12
13
  import { jsx } from "@emotion/react/jsx-runtime";
14
+ import { isClerkAPIResponseError } from "@clerk/shared/error";
13
15
  import { useClerk } from "@clerk/shared/react";
14
16
 
15
17
  //#region src/components/SignIn/SignInSocialButtons.tsx
@@ -24,6 +26,20 @@ const SignInSocialButtons = React.memo((props) => {
24
26
  const redirectUrlComplete = ctx.afterSignInUrl || "/";
25
27
  const shouldUsePopup = ctx.oauthFlow === "popup" || ctx.oauthFlow === "auto" && originPrefersPopup();
26
28
  const { onAlternativePhoneCodeProviderClick,...rest } = props;
29
+ const handleError$1 = (err) => {
30
+ if (isClerkAPIResponseError(err)) {
31
+ if (err.errors.find((e) => e.code === ERROR_CODES.SESSION_EXISTS)) return clerk.setActive({
32
+ session: clerk.client.lastActiveSessionId,
33
+ navigate: async ({ session }) => {
34
+ await ctx.navigateOnSetActive({
35
+ session,
36
+ redirectUrl: ctx.afterSignInUrl
37
+ });
38
+ }
39
+ });
40
+ }
41
+ return handleError(err, [], card.setError);
42
+ };
27
43
  return /* @__PURE__ */ jsx(SocialButtons, {
28
44
  ...rest,
29
45
  showLastAuthenticationStrategy: true,
@@ -43,14 +59,14 @@ const SignInSocialButtons = React.memo((props) => {
43
59
  redirectUrlComplete,
44
60
  popup,
45
61
  oidcPrompt: ctx.oidcPrompt
46
- }).catch((err) => handleError(err, [], card.setError));
62
+ }).catch((err) => handleError$1(err));
47
63
  }
48
64
  return signIn.authenticateWithRedirect({
49
65
  strategy,
50
66
  redirectUrl,
51
67
  redirectUrlComplete,
52
68
  oidcPrompt: ctx.oidcPrompt
53
- }).catch((err) => handleError(err, [], card.setError));
69
+ }).catch((err) => handleError$1(err));
54
70
  },
55
71
  web3Callback: (strategy) => {
56
72
  return clerk.authenticateWithWeb3({