@auth0/auth0-acul-react 1.0.0-alpha.0 → 1.0.0-alpha.2

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 (42) hide show
  1. package/README.md +220 -19
  2. package/dist/export/getting-started.d.ts +9 -63
  3. package/dist/export/hooks.d.ts +1 -1
  4. package/dist/hooks/common/errors.d.ts +11 -11
  5. package/dist/hooks/common/errors.js +1 -1
  6. package/dist/hooks/common/errors.js.map +1 -1
  7. package/dist/hooks/index.d.ts +1 -0
  8. package/dist/hooks/utility/passkey-autofill.d.ts +86 -0
  9. package/dist/hooks/utility/passkey-autofill.js +2 -0
  10. package/dist/hooks/utility/passkey-autofill.js.map +1 -0
  11. package/dist/hooks/utility/polling-manager.d.ts +1 -0
  12. package/dist/hooks/utility/polling-manager.js.map +1 -1
  13. package/dist/hooks/utility/validate-password.js +1 -1
  14. package/dist/hooks/utility/validate-password.js.map +1 -1
  15. package/dist/hooks/utility/validate-username.js +1 -1
  16. package/dist/hooks/utility/validate-username.js.map +1 -1
  17. package/dist/screens/login-id.d.ts +1 -0
  18. package/dist/screens/login-id.js +1 -1
  19. package/dist/screens/login-id.js.map +1 -1
  20. package/dist/screens/login-password.d.ts +2 -1
  21. package/dist/screens/login-password.js +1 -1
  22. package/dist/screens/login-password.js.map +1 -1
  23. package/dist/screens/mfa-email-challenge.d.ts +2 -1
  24. package/dist/screens/mfa-email-challenge.js +1 -1
  25. package/dist/screens/mfa-email-challenge.js.map +1 -1
  26. package/dist/screens/mfa-login-options.d.ts +2 -1
  27. package/dist/screens/mfa-login-options.js +1 -1
  28. package/dist/screens/mfa-login-options.js.map +1 -1
  29. package/dist/screens/mfa-push-enrollment-qr.d.ts +1 -0
  30. package/dist/screens/mfa-push-enrollment-qr.js +1 -1
  31. package/dist/screens/mfa-push-enrollment-qr.js.map +1 -1
  32. package/dist/screens/phone-identifier-challenge.d.ts +2 -0
  33. package/dist/screens/phone-identifier-challenge.js +1 -1
  34. package/dist/screens/phone-identifier-challenge.js.map +1 -1
  35. package/dist/screens/signup-password.d.ts +2 -1
  36. package/dist/screens/signup-password.js +1 -1
  37. package/dist/screens/signup-password.js.map +1 -1
  38. package/dist/state/error-store.d.ts +4 -4
  39. package/dist/state/error-store.js +1 -1
  40. package/dist/state/error-store.js.map +1 -1
  41. package/dist/telemetry.js +1 -1
  42. package/package.json +9 -6
package/README.md CHANGED
@@ -1,5 +1,6 @@
1
- # @auth0/auth0-acul-react
2
- Developers using Auth0’s Universal Login can use this React SDK to customize screens like login, signup, or reset password. It provides hooks, context, and utilities to build flexible, type-safe experiences that match your brand and deliver a seamless user experience.
1
+ # Auth0 ACUL React SDK
2
+
3
+ ![ACUL React SDK](https://cdn.auth0.com/website/sdks/banners/auth0-acul-react-banner.png)
3
4
 
4
5
  <div align="center">
5
6
 
@@ -12,20 +13,36 @@ Developers using Auth0’s Universal Login can use this React SDK to customize s
12
13
 
13
14
  <div align='center'>
14
15
 
15
- 📚 [Documentation](#-documentation) | 🚀 [Getting Started](#-getting-started) | 💻 [API Reference](#-api-reference) | 💬 [Feedback](#-feedback)
16
+ 📚 [Documentation](#documentation) | 🚀 [Getting Started](#getting-started) | 💻 [API Reference](#api-reference) | 🪝 [Hooks](#hooks) | [Examples](#examples) | 💬 [Feedback](#feedback)
16
17
 
17
18
  </div>
18
19
 
19
- ## Table of Contents
20
- - [Installation](#installation)
21
- - [Importing the SDK](#importing-the-sdk)
22
- - [Partial Imports](#partial-imports)
23
- - [Root Imports](#root-imports)
24
- - [Types / Interfaces](#types--interfaces)
25
- - [Examples](#examples)
20
+ Developers using Auth0’s Universal Login can use this React SDK to customize screens like login, signup, or reset password. It provides hooks, context, and utilities to build flexible, type-safe experiences that match your brand and deliver a seamless user experience.
21
+
26
22
  ---
27
23
 
28
- ## Installation
24
+ > [!CAUTION]
25
+ >
26
+ > This feature is still in **Early Access**.
27
+
28
+ <a id="documentation"></a>
29
+ ## 📚 Documentation
30
+
31
+ - [Quickstart](https://auth0.com/docs/customize/login-pages/advanced-customizations/getting-started/sdk-quickstart) - our guide for setting up the SDK on your app.
32
+ - [Guides](https://auth0.com/docs/customize/login-pages/advanced-customizations/screens) - more guides for common use cases
33
+ - [Examples](https://github.com/auth0/universal-login/tree/master/packages/auth0-acul-react/examples) - code snippets for different customization use cases.
34
+
35
+ <a id="getting-started"></a>
36
+ ## 🚀 Getting started
37
+
38
+ ### Prerequisites
39
+ Before starting, ensure that you have the following setup:
40
+
41
+ 1. **Custom Domain**: Ensure that a custom domain is configured for your Auth0 tenant.
42
+ 2. **Screen Configuration**: Set up the required authentication screens within your Auth0 flow.
43
+ For detailed steps, refer to the [Configure ACUL Screens](https://auth0.com/docs/customize/login-pages/advanced-customizations/getting-started/configure-acul-screens).
44
+
45
+ ### Installation
29
46
 
30
47
  ```bash
31
48
  npm install @auth0/auth0-acul-react
@@ -35,11 +52,13 @@ Peer dependency:
35
52
  ```bash
36
53
  npm install react
37
54
  ```
38
- ---
39
- ## Importing the SDK
40
- The SDK supports `partial imports` for each screen, allowing you to include only the code you need for your specific use case. This helps keep your bundle size small and improves performance.
41
- Also, you can use a `root import` to load all screens from a single bundle if your app requires it.
42
- ### Partial Imports
55
+
56
+ ### Importing the SDK
57
+ The SDK supports `partial imports` for each screen, allowing you to include only the code you need for your specific use case. This helps keep your bundle size small and improves performance.
58
+
59
+ Also, you can use a `root import` to load all screens from a single bundle if your app requires it.
60
+
61
+ #### Partial Imports
43
62
  Each screen has its own set of hooks and methods. You can import only what you need for the screen you're building.
44
63
 
45
64
  The following example shows how to import and use SDK to build `login-id` screen.
@@ -73,7 +92,7 @@ import {
73
92
 
74
93
  ---
75
94
 
76
- ### Root Imports
95
+ #### Root Imports
77
96
 
78
97
  The SDK also supports a root import, which lets you load all screens from a single bundle.
79
98
  This is useful if your app dynamically renders different screens at runtime based on the current Auth0 flow, for example, when you want one unified build that can handle all possible screens.
@@ -96,7 +115,7 @@ import {
96
115
  ```
97
116
  ---
98
117
 
99
- ### Types / Interfaces
118
+ #### Types / Interfaces
100
119
  Typescript types and interfaces can be imported from `@auth0/auth0-acul-react/types` for type safety and better DX.
101
120
  ```tsx
102
121
  import type {
@@ -112,10 +131,192 @@ Refer to our [API Reference](#-api-reference) for the full list of available typ
112
131
 
113
132
  ---
114
133
 
134
+ <a id="api-reference"></a>
135
+ ## 💻 API Reference
136
+ ### Screens
137
+
138
+ | No. | Prompt | Screen Name | Documentation Link |
139
+ |--------|--------------------|-------------------|--------------------------------------------------------------------------------------------|
140
+ | 1 | login | login | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.Login) |
141
+ | 2 | loginId | login-id | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.LoginId) |
142
+ | 3 | login-password | login-password | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.LoginPassword) |
143
+ | 4 | signup-id | signup-id | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.SignupId) |
144
+ | 5 | signup-password | signup-password | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.SignupPassword) |
145
+
146
+ <details>
147
+ <summary>Explore more screens...</summary>
148
+
149
+ | No. | Prompt | Screen Name | Documentation Link |
150
+ |--------|--------------------------------|-------------------------------------------|-------------------------------------------------------------------------------------------------------|
151
+ | 6 | login-passwordless | login-passwordless-email-code | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.LoginPasswordlessEmailCode) |
152
+ | 7 | login-passwordless | login-passwordless-sms-otp | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.LoginPasswordlessSmsOtp) |
153
+ | 8 | passkeys | passkey-enrollment | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.PasskeyEnrollment) |
154
+ | 9 | passkeys | passkey-enrollment-local | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.PasskeyEnrollmentLocal) |
155
+ | 10 | phone-identifier-enrollment | phone-identifier-enrollment | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.PhoneIdentifierEnrollment) |
156
+ | 11 | phone-identifier-challenge | phone-identifier-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.PhoneIdentifierChallenge) |
157
+ | 12 | email-identifier-challenge | email-identifier-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.EmailIdentifierChallenge) |
158
+ | 13 | captcha | interstitial-captcha | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.InterstitialCaptcha) |
159
+ | 14 | reset-password | reset-password-email | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.ResetPasswordEmail) |
160
+ | 15 | reset-password | reset-password-request | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.ResetPasswordRequest) |
161
+ | 16 | reset-password | reset-password | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.ResetPassword) |
162
+ | 17 | reset-password | reset-password-error | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.ResetPasswordError) |
163
+ | 18 | reset-password | reset-password-success | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.ResetPasswordSuccess) |
164
+ | 19 | signup | signup | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.Signup) |
165
+ | 20 | mfa | mfa-detect-browser-capabilities | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaDetectBrowserCapabilities) |
166
+ | 21 | mfa | mfa-enroll-result | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaEnrollResult) |
167
+ | 22 | mfa | mfa-begin-enroll-options | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaBeginEnrollOptions) |
168
+ | 23 | mfa | mfa-login-options | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaLoginOptions) |
169
+ | 24 | mfa-push | mfa-push-enrollment-qr | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaPushEnrollmentQr) |
170
+ | 25 | mfa-push | mfa-push-welcome | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaPushWelcome) |
171
+ | 26 | mfa-push | mfa-push-challenge-push | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaPushChallengePush) |
172
+ | 27 | mfa-push | mfa-push-list | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaPushList) |
173
+ | 28 | mfa-sms | mfa-country-codes | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaCountryCodes) |
174
+ | 29 | mfa-sms | mfa-sms-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaSmsChallenge) |
175
+ | 30 | mfa-sms | mfa-sms-enrollment | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaSmsEnrollment) |
176
+ | 31 | mfa-sms | mfa-sms-list | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaSmsList) |
177
+ | 32 | mfa-email | mfa-email-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaEmailChallenge) |
178
+ | 33 | mfa-email | mfa-email-list | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaEmailList) |
179
+ | 34 | invitatino | accept-invitation | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.AcceptInvitation) |
180
+ | 35 | organizations | organization-picker | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.OrganizationPicker) |
181
+ | 36 | organizations | organization-selection | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.OrganizationSelection) |
182
+ | 37 | reset-password | mfa-otp-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaOtpChallenge) |
183
+ | 38 | mfa-otp | mfa-otp-enrollment-code | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaOtpEnrollmentCode) |
184
+ | 39 | mfa-otp | mfa-otp-enrollment-qr | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaOtpEnrollmentQr) |
185
+ | 40 | reset-password | reset-password-mfa-email-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.ResetPasswordMfaEmailChallenge) |
186
+ | 41 | reset-password | reset-password-mfa-push-challenge-push | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.ResetPasswordMfaPushChallengePush)|
187
+ | 42 | reset-password | mfa-sms-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.ResetPasswordMfaSmsChallenge) |
188
+ | 43 | reset-password | reset-password-mfa-otp-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.OrganizationSelection) |
189
+ | 44 | mfa-phone | mfa-phone-enrollment | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaPhoneEnrollment) |
190
+ | 45 | mfa-voice | mfa-voice-enrollment | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaVoiceEnrollment) |
191
+ | 46 | mfa-recovery-code | mfa-recovery-code-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaRecoveryCodeChallenge) |
192
+ | 47 | device-flow | device-code-activation-allowed | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.DeviceCodeActivationAllowed) |
193
+ | 48 | device-flow | device-code-activation-denied | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.DeviceCodeActivationDenied) |
194
+ | 49 | device-flow | device-code-activation | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.DeviceCodeActivation) |
195
+ | 50 | reset-password | reset-password-mfa-recovery-code-challenge | [Link](https://auth0.github.io/universallogin/classes/Classes.ResetPasswordMfaRecoveryCodeChallenge) |
196
+ | 51 | reset-password | reset-password-mfa-voice | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.ResetPasswordMfaVoiceChallenge) |
197
+ | 52 | common | redeem-ticket | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.RedeemTicket) |
198
+ | 53 | device-flow | device-code-confirmation | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.DeviceCodeConfirmation) |
199
+ | 54 | mfa-phone | mfa-phone-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaPhoneChallenge) |
200
+ | 55 | mfa-voice | mfa-voice-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaVoiceChallenge) |
201
+ | 56 | mfa-recovery-code | mfa-recovery-code-enrollment | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaRecoveryCodeEnrollment) |
202
+ | 57 | reset-password | reset-password-mfa-phone-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.ResetPasswordMfaPhoneChallenge) |
203
+ | 58 | mfa-recovery-code | mfa-recovery-code-challenge-new-code | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaRecoveryCodeChallengeNewCode) |
204
+ | 59 | logout | logout | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.Logout) |
205
+ | 60 | logout | logout-aborted | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.LogoutAborted) |
206
+ | 61 | logout | logout-complete | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.LogoutComplete) |
207
+ | 62 | email-verification | email-verification-result | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.EmailVerificationResult) |
208
+ | 63 | login-email-verification | login-email-verification | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.LoginEmailVerification) |
209
+ | 64 |mfa-webauthn | mfa-webauthn-platform-enrollment | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaWebAuthnPlatformEnrollment) |
210
+ | 65 |mfa-webauthn | mfa-webauthn-error | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaWebAuthnError) |
211
+ | 66 |mfa-webauthn | mfa-webauthn-roaming-enrollment | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaWebAuthnRoamingEnrollment) |
212
+ | 67 |mfa-webauthn | mfa-webauthn-roaming-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaWebAuthnRoamingChallenge) |
213
+ | 68 |mfa-webauthn | mfa-webauthn-platform-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaWebAuthnPlatformChallenge) |
214
+ | 69 |mfa-webauthn | mfa-webauthn-enrollment-success | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaWebAuthnEnrollmentSuccess) |
215
+ | 70 |mfa-webauthn | mfa-webauthn-change-key-nickname | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaWebAuthnChangeKeyNickname) |
216
+ | 71 |mfa-webauthn | mfa-webauthn-not-available-error | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.MfaWebAuthnNotAvailableError) |
217
+ | 72 |reset-password | reset-password-mfa-webauthn-platform-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.ResetPasswordMfaWebAuthnPlatformChallenge) |
218
+ | 73 |reset-password | reset-password-mfa-webauthn-roaming-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.ResetPasswordMfaWebAuthnRoamingChallenge) |
219
+ | 74 |consent | consent | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.consent) |
220
+ | 75 |customized-consent | customized-consent | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.CustomizedConsent) |
221
+ | 76 |email-otp-challenge | email-otp-challenge | [Link](https://acul-docs.netlify.app/auth0-acul-react/modules/Screens.EmailOTPChallenge) |
222
+ </details>
223
+
224
+ ---
225
+
226
+ ## Hooks
227
+ ### Context Hooks (Available in all screens)
228
+ - `useUser()` - Current user information
229
+ - `useTenant()` - Tenant configuration
230
+ - `useClient()` - Application client information
231
+ - `useScreen()` - Current screen data and configuration
232
+ - `useTransaction()` - Transaction state and methods
233
+ - `useBranding()` - Tenant branding and theme
234
+ - `useOrganization()` - Organization context (if applicable)
235
+ - `usePrompt()` - Current authentication prompt
236
+ - `useUntrustedData()` - Untrusted data from the authentication flow
237
+
238
+ ### Utility Hooks
239
+ Specialized hooks for form validation, polling, and identifier management:
240
+
241
+ #### Identifier Management
242
+ - `useLoginIdentifiers()` - Get available login identifier types (email, phone, username)
243
+ - `useSignupIdentifiers()` - Get available signup identifier types, each with its `required` status
244
+
245
+ #### Form Validation
246
+ - `usePasswordValidation(password, rules)` - Real-time password strength validation
247
+ - `useUsernameValidation(username)` - Username format and availability validation
248
+
249
+ #### MFA & Polling
250
+ - `useMfaPolling(options)` - Manage MFA push notification polling lifecycle
251
+ - `useResend(options)` - Handle resend operations with cooldown timers
252
+
253
+ ### Common Hooks
254
+ General-purpose hooks available across all screens:
255
+
256
+ #### Screen Management
257
+ - `useCurrentScreen()` - Get complete current screen context data
258
+ - `useAuth0Themes()` - Access tenant branding and theme configuration
259
+
260
+ #### Error Handling
261
+ - `useErrors(options)` - Comprehensive error management with categorization
262
+ - Filter by error kind: `'validation'`, `'auth0'`, `'configuration'`
263
+ - Filter by field name for form-specific errors
264
+ - Dismiss individual or all errors
265
+
266
+ ### Screen-Specific Action Methods
267
+ Each screen module exports methods for screen actions:
268
+
269
+ ```tsx
270
+ // Login ID Screen
271
+ import {
272
+ loginMethod,
273
+ continueWithFederatedLogin
274
+ } from '@auth0/auth0-acul-react/login-id';
275
+
276
+ // Password Screen
277
+ import {
278
+ loginMethod,
279
+ forgotPasswordMethod
280
+ } from '@auth0/auth0-acul-react/login-password';
281
+
282
+ // MFA Push Challenge
283
+ import {
284
+ continueMethod,
285
+ resendPushNotification,
286
+ useMfaPolling
287
+ } from '@auth0/auth0-acul-react/mfa-push-challenge-push';
288
+ ```
289
+
115
290
  ## Examples
116
- Check out the [`examples/`](https://github.com/auth0/universal-login/tree/main/packages/auth0-acul-react/examples) directory for complete, working examples of how to use this SDK to build custom Universal Login screens.
291
+ - [React Examples](https://github.com/auth0/universal-login/tree/master/packages/auth0-acul-react/examples) - Complete React component examples
292
+ - [React Boilerplate](https://github.com/auth0/auth0-acul-react-boilerplate) - Full React application template
117
293
 
118
294
  ---
295
+
296
+ <a id="feedback"></a>
297
+ ## 💬 Feedback
298
+
299
+ ### Contributing
300
+
301
+ We appreciate feedback and contribution to this repo! Before you get started, please see the following:
302
+
303
+ - [Auth0's general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)
304
+ - [Auth0's code of conduct guidelines](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
305
+
306
+ ### Raise an issue
307
+
308
+ To provide feedback or report a bug, please [raise an issue on our issue tracker](https://github.com/auth0/universal-login/issues).
309
+
310
+ ### Vulnerability Reporting
311
+
312
+ Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/responsible-disclosure-policy) details the procedure for disclosing security issues.
313
+
314
+ ### Legal
315
+
316
+ **Early Access.** This SDK and its associated product are made available only in Early Access ("EA") format and are governed by the Free Trial terms of the [Okta Master Subscription Agreement](https://www.okta.com/agreements/#mastersubscriptionagreement). If Okta elects to make a version of this SDK and its associated product Generally Available ("GA"), such GA version may have different pricing, product and feature configurations, and use of the GA product and SDK will be subject to the standard terms of the Agreement (or other such titled written or electronic agreement addressing the same subject matter) between Okta and Customer."
317
+
318
+ ---
319
+
119
320
  <p align="center">
120
321
  <picture>
121
322
  <source media="(prefers-color-scheme: light)" srcset="https://cdn.auth0.com/website/sdks/logos/auth0_light_mode.png" width="150">
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @module Getting Started
3
- * @description This module provides an overview of how to get started with the Auth0 SDK.
3
+ * @description This module provides an overview of how to get started with the Auth0 ACUL React SDK.
4
4
  *
5
5
  * # Auth0 ACUL React SDK
6
6
  *
@@ -104,7 +104,7 @@
104
104
  * import {
105
105
  * useScreen,
106
106
  * useTransaction,
107
- * useMfaPollingManager,
107
+ * useMfaPolling,
108
108
  * continueMethod,
109
109
  * resendPushNotification
110
110
  * } from '@auth0/auth0-acul-react/mfa-push-challenge-push';
@@ -114,7 +114,7 @@
114
114
  * const transaction = useTransaction();
115
115
  * const [status, setStatus] = useState('waiting');
116
116
  *
117
- * const { isRunning, startPolling, stopPolling } = useMfaPollingManager({
117
+ * const { isRunning, startPolling, stopPolling } = useMfaPolling({
118
118
  * intervalMs: 5000,
119
119
  * onComplete: async () => {
120
120
  * setStatus('approved');
@@ -171,7 +171,7 @@
171
171
  * }
172
172
  * ```
173
173
  *
174
- * ## Available Hooks by Screen
174
+ * ## Available Hooks
175
175
  *
176
176
  * ### Context Hooks (Available in all screens)
177
177
  * - `useUser()` - Current user information
@@ -208,7 +208,7 @@
208
208
  *
209
209
  * #### Error Handling
210
210
  * - `useErrors(options)` - Comprehensive error management with categorization
211
- * - Filter by error kind: `'client'`, `'server'`, `'dev'`
211
+ * - Filter by error kind: `'validation'`, `'auth0'`, `'configuration'`
212
212
  * - Filter by field name for form-specific errors
213
213
  * - Dismiss individual or all errors
214
214
  *
@@ -232,71 +232,17 @@
232
232
  * import {
233
233
  * continueMethod,
234
234
  * resendPushNotification,
235
- * useMfaPollingManager
235
+ * useMfaPolling
236
236
  * } from '@auth0/auth0-acul-react/mfa-push-challenge-push';
237
237
  * ```
238
238
  *
239
- * ## Import Patterns
240
- *
241
- * ### Screen-Specific Imports (Recommended)
242
- * ```tsx
243
- * // Import from specific screen modules
244
- * import { useUser, loginMethod } from '@auth0/auth0-acul-react/login-id';
245
- * import { useMfaPollingManager } from '@auth0/auth0-acul-react/mfa-push-challenge-push';
246
- * ```
247
- * ## Available Screen Modules
248
- *
249
- * | Screen Module | Import Path | Description |
250
- * |---------------|-------------|-------------|
251
- * | Login ID | `@auth0/auth0-acul-react/login-id` | Username/email identification |
252
- * | Login Password | `@auth0/auth0-acul-react/login-password` | Password entry screen |
253
- * | MFA Push Challenge | `@auth0/auth0-acul-react/mfa-push-challenge-push` | Push notification MFA |
254
- * | Reset Password MFA Push | `@auth0/auth0-acul-react/reset-password-mfa-push-challenge-push` | Reset password with MFA |
255
- * | Signup ID | `@auth0/auth0-acul-react/signup-id` | User registration |
256
- * | Signup Password | `@auth0/auth0-acul-react/signup-password` | Password setup during registration |
257
- *
258
239
  * ## Best Practices
259
240
  *
260
- * ### 1. **Use Screen-Specific Imports**
261
- * ```tsx
262
- * // Partial import - recommended
263
- * import { useSignup } from '@auth0/auth0-acul-react/signup';
264
- * // Root import
265
- * import * as Auth0React from '@auth0/auth0-acul-react';
266
- *
267
- * const MyComponent = () => {
268
- * const signupInstance = useSignup();
269
- * // Use methods or other properties using the instance
270
- * return (
271
- * <button onClick={() => signupInstance.signup({ username: 'user', password: 'pass' })}>
272
- * Sign Up
273
- * </button>
274
- * );
275
- * };
241
+ * - Use **screen-specific modules**
242
+ * - Handle errors using `useErrors()`
243
+ * - Use context hooks (like `useTenant`, `useScreen`) for dynamic branding, layout, or behavior
276
244
  *
277
- * ```
278
245
  *
279
- * ### 2. **Handle Loading States**
280
- * ```tsx
281
- * function LoginForm() {
282
- * const [isLoading, setIsLoading] = useState(false);
283
- *
284
- * const handleSubmit = async (data) => {
285
- * setIsLoading(true);
286
- * try {
287
- * await loginMethod(data);
288
- * } finally {
289
- * setIsLoading(false);
290
- * }
291
- * };
292
- *
293
- * return (
294
- * <button disabled={isLoading}>
295
- * {isLoading ? 'Signing in...' : 'Sign In'}
296
- * </button>
297
- * );
298
- * }
299
- * ```
300
246
  *
301
247
  * ## Examples and Resources
302
248
  *
@@ -1 +1 @@
1
- export { usePasswordValidation, useUsernameValidation, useResend, useMfaPolling, useErrors, useAuth0Themes, useCurrentScreen, useLoginIdentifiers, useSignupIdentifiers, } from '../hooks';
1
+ export { usePasswordValidation, useUsernameValidation, useResend, useMfaPolling, useErrors, useAuth0Themes, useCurrentScreen, useLoginIdentifiers, useSignupIdentifiers, usePasskeyAutofill, } from '../hooks';
@@ -19,14 +19,14 @@ export interface UseErrorsResult {
19
19
  /**
20
20
  * React hook for reading and managing errors in ACUL (Advanced Customization of Universal Login).
21
21
  * With all validation and server-side errors. It groups errors into three kinds:
22
- * - `server` — errors returned by Auth0 or your own backend.
23
- * - `client` — errors from client-side validation (e.g., invalid form input).
24
- * - `developer` — errors caused by incorrect integration or SDK misuse.
22
+ * - `auth0` — errors returned by Auth0 or your own backend.
23
+ * - `validation` — errors from client-side validation (e.g., invalid form input).
24
+ * - `configuration` — errors caused by incorrect integration or SDK misuse.
25
25
  *
26
26
  * @supportedScreens
27
27
  * - The `useErrors` hook is available on every ACUL screen.
28
28
  *
29
- * @param options.includeDevErrors - When `true`, developer errors are included in
29
+ * @param options.includeDevErrors - When `true`, configuration errors are included in
30
30
  * the returned list. Defaults to `false`.
31
31
  *
32
32
  * @returns An object of type {@link UseErrorsResult}, containing:
@@ -51,7 +51,7 @@ export interface UseErrorsResult {
51
51
  * <div>
52
52
  * {hasError && (
53
53
  * <div className="mb-4">
54
- * {errors.byKind("server").map(err => (
54
+ * {errors.byKind("auth0").map(err => (
55
55
  * <div key={err.id} className="text-red-600">
56
56
  * {err.message}
57
57
  * <button onClick={() => dismiss(err.id)}>Dismiss</button>
@@ -68,10 +68,10 @@ export interface UseErrorsResult {
68
68
  *
69
69
  * In addition to rendering messages, you can filter by field or kind:
70
70
  * ```ts
71
- * console.log(errors.byKind('client')); // all client errors
72
- * console.log(errors.byKind('client', { field: 'username' })); // client errors for field 'username'
71
+ * console.log(errors.byKind('validation')); // all validation errors
72
+ * console.log(errors.byKind('validation', { field: 'username' })); // validation errors for field 'username'
73
73
  * console.log(errors.byField('username')); // all errors for field 'username'
74
- * console.log(errors.byField('username', { kind: 'server' })); // server errors for field 'username'
74
+ * console.log(errors.byField('username', { kind: 'auth0' })); // auth0 errors for field 'username'
75
75
  * ```
76
76
  */
77
77
  export declare function useErrors(options?: UseErrorOptions): UseErrorsResult;
@@ -83,11 +83,11 @@ declare function withError<T>(actionOrPromise: (() => T | Promise<T>) | Promise<
83
83
  */
84
84
  export declare const errorManager: {
85
85
  withError: typeof withError;
86
- replaceClientErrors(list: Array<Omit<ErrorItem, "id">>, opts?: {
86
+ replaceValidationErrors(list: Array<Omit<ErrorItem, "id">>, opts?: {
87
87
  byField?: string;
88
88
  }): void;
89
- clearClientErrors(): void;
90
- pushClientErrors(list: Omit<ErrorItem, "id"> | Array<Omit<ErrorItem, "id">>): void;
89
+ clearValidationErrors(): void;
90
+ pushValidationErrors(list: Omit<ErrorItem, "id"> | Array<Omit<ErrorItem, "id">>): void;
91
91
  replaceDeveloperErrors(list: Array<Omit<ErrorItem, "id">>, opts?: {
92
92
  byField?: string;
93
93
  }): void;
@@ -1,2 +1,2 @@
1
- import{getErrors as e,UserInputError as r,SDKUsageError as t,Auth0ServerError as n}from"@auth0/auth0-acul-js";import{useSyncExternalStore as c,useRef as o,useEffect as l,useMemo as s,useCallback as i}from"react";import{errorStore as a,ERROR_KINDS as p}from"../../state/error-store.js";function d(e,r){return r?e.filter(e=>e.field===r):e}const u=new WeakMap,v=new WeakMap,f=new WeakMap,h=(e,r)=>{const t="server"===e?u:"client"===e?v:f,n=t.get(r);if(n)return n;const c=Object.freeze(r.map(r=>Object.freeze({...r,kind:e})));return t.set(r,c),c};function b(r={}){const{includeDevErrors:t=!1}=r,n=c(e=>a.subscribe(e),()=>a.snapshot()),u=o(!1);l(()=>{if(u.current)return;u.current=!0;const r=e?.()??[];a.replace("server",r)},[]);const v=s(()=>h("server",n.server),[n.server]),f=s(()=>h("client",n.client),[n.client]),b=s(()=>h("developer",n.developer),[n.developer]),E=s(()=>Object.freeze([...t?b:[],...f,...v]),[t,b,f,v]),y=s(()=>{const e=Object.assign([...E],{byKind(e,r){const t="client"===e?f:"developer"===e?b:v;return r?.field?Object.freeze(d(t,r.field)):t},byField:(r,t)=>t?.kind?e.byKind(t.kind,{field:r}):Object.freeze(d(E,r))});return Object.freeze(e)},[E,f,b,v]),m=E.length>0,k=i(e=>{a.remove(p,e)},[]),w=i(()=>{a.clear(p)},[]);return s(()=>({errors:y,hasError:m,dismiss:k,dismissAll:w}),[y,m,k,w])}const E={withError:function(e){const c=e=>{const c=function(e){return e instanceof r?"client":e instanceof t?"developer":e instanceof n?"server":null}(e),o=function(e){return{code:e?.code??(e instanceof Error?e.name:void 0)??"unknown_error",message:e?.message??"Unknown error",field:e?.field}}(e);switch(c){case"client":E.replaceClientErrors([o]);break;case"developer":E.replaceDeveloperErrors([o]);break;case"server":E.replaceServerErrors([o]);break;default:throw console.error("[auth0-acul-react] Unhandled error:",e),e}};if("function"==typeof e)try{const r=e();return"object"==typeof(o=r)&&null!==o&&"then"in o&&"function"==typeof o.then?r.catch(e=>{throw c(e),e}):r}catch(e){throw c(e),e}var o;return e.catch(e=>{throw c(e),e})},replaceClientErrors(e,r){r?.byField?a.replacePartial("client",e,r.byField):a.replace("client",e)},clearClientErrors(){a.clear(["client"])},pushClientErrors(e){a.push("client",e)},replaceDeveloperErrors(e,r){r?.byField?a.replacePartial("developer",e,r.byField):a.replace("developer",e)},clearDeveloperErrors(){a.clear(["developer"])},pushDeveloperErrors(e){a.push("developer",e)},replaceServerErrors(e,r){r?.byField?a.replacePartial("server",e,r.byField):a.replace("server",e)},clearServerErrors(){a.clear(["server"])},pushServerErrors(e){a.push("server",e)},syncServerErrors(){const r=e?.()??[];a.replace("server",r)}};export{E as errorManager,b as useErrors};
1
+ import{getErrors as r,ValidationError as e,ConfigurationError as t,Auth0Error as a}from"@auth0/auth0-acul-js";import{useSyncExternalStore as n,useRef as o,useEffect as i,useMemo as c,useCallback as l}from"react";import{errorStore as s,ERROR_KINDS as u}from"../../state/error-store.js";function f(r,e){return e?r.filter(r=>r.field===e):r}const d=new WeakMap,h=new WeakMap,p=new WeakMap,v=(r,e)=>{const t="auth0"===r?d:"validation"===r?h:p,a=t.get(e);if(a)return a;const n=Object.freeze(e.map(e=>Object.freeze({...e,kind:r})));return t.set(e,n),n};function b(e={}){const{includeDevErrors:t=!1}=e,a=n(r=>s.subscribe(r),()=>s.snapshot()),d=o(!1);i(()=>{if(d.current)return;d.current=!0;const e=r?.()??[];s.replace("auth0",e)},[]);const h=c(()=>v("auth0",a.auth0),[a.auth0]),p=c(()=>v("validation",a.validation),[a.validation]),b=c(()=>v("configuration",a.configuration),[a.configuration]),E=c(()=>Object.freeze([...t?b:[],...p,...h]),[t,b,p,h]),g=c(()=>{const r=Object.assign([...E],{byKind(r,e){let t;return t="validation"===r?p:"configuration"===r?b:h,e?.field?Object.freeze(f(t,e.field)):t},byField:(e,t)=>t?.kind?r.byKind(t.kind,{field:e}):Object.freeze(f(E,e))});return Object.freeze(r)},[E,p,b,h]),y=E.length>0,m=l(r=>{s.remove(u,r)},[]),k=l(()=>{s.clear(u)},[]);return c(()=>({errors:g,hasError:y,dismiss:m,dismissAll:k}),[g,y,m,k])}const E={withError:function(r){const n=r=>{const n=function(r){return r instanceof e?"validation":r instanceof t?"configuration":r instanceof a?"auth0":null}(r),o=function(r){return{code:r?.code??(r instanceof Error?r.name:void 0)??"unknown_error",message:r?.message??"Unknown error",field:r?.field}}(r);switch(n){case"validation":E.replaceValidationErrors([o]);break;case"configuration":E.replaceDeveloperErrors([o]);break;case"auth0":E.replaceServerErrors([o]);break;default:throw console.error("[auth0-acul-react] Unhandled error:",r),r}};if("function"==typeof r)try{const e=r();return"object"==typeof(o=e)&&null!==o&&"then"in o&&"function"==typeof o.then?e.catch(r=>{throw n(r),r}):e}catch(r){throw n(r),r}var o;return r.catch(r=>{throw n(r),r})},replaceValidationErrors(r,e){e?.byField?s.replacePartial("validation",r,e.byField):s.replace("validation",r)},clearValidationErrors(){s.clear(["validation"])},pushValidationErrors(r){s.push("validation",r)},replaceDeveloperErrors(r,e){e?.byField?s.replacePartial("configuration",r,e.byField):s.replace("configuration",r)},clearDeveloperErrors(){s.clear(["configuration"])},pushDeveloperErrors(r){s.push("configuration",r)},replaceServerErrors(r,e){e?.byField?s.replacePartial("auth0",r,e.byField):s.replace("auth0",r)},clearServerErrors(){s.clear(["auth0"])},pushServerErrors(r){s.push("auth0",r)},syncServerErrors(){const e=r?.()??[];s.replace("auth0",e)}};export{E as errorManager,b as useErrors};
2
2
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sources":["../../../src/hooks/common/errors.ts"],"sourcesContent":["import {\n SDKUsageError,\n UserInputError,\n Auth0ServerError,\n getErrors as getServerErrors,\n type Error as Auth0Error,\n} from '@auth0/auth0-acul-js';\nimport { useEffect, useMemo, useRef, useSyncExternalStore, useCallback } from 'react';\n\nimport { errorStore, ERROR_KINDS, type ErrorItem, type ErrorKind } from '../../state/error-store';\n\nexport interface ErrorsResult extends ReadonlyArray<ErrorItem> {\n byKind(kind: ErrorKind, opts?: { field?: string }): ReadonlyArray<ErrorItem>;\n byField(field: string, opts?: { kind?: ErrorKind }): ReadonlyArray<ErrorItem>;\n}\n\nexport interface UseErrorOptions {\n includeDevErrors?: boolean;\n}\n\nexport interface UseErrorsResult {\n errors: ErrorsResult;\n hasError: boolean;\n dismiss: (id: string) => void;\n dismissAll: () => void;\n}\n\nfunction classifyKind(e: unknown): ErrorKind | null {\n if (e instanceof UserInputError) {\n return 'client';\n }\n if (e instanceof SDKUsageError) {\n return 'developer';\n }\n if (e instanceof Auth0ServerError) {\n return 'server';\n }\n return null;\n}\n\nfunction toErrorObject(e: unknown): Omit<ErrorItem, 'id'> {\n return {\n code: (e as Auth0Error)?.code ?? (e instanceof Error ? e.name : undefined) ?? 'unknown_error',\n message: (e as Auth0Error)?.message ?? 'Unknown error',\n field: (e as Auth0Error)?.field,\n };\n}\n\nfunction filterByField<T extends { field?: string }>(\n list: ReadonlyArray<T>,\n field?: string\n): ReadonlyArray<T> {\n if (!field) {\n return list;\n }\n return list.filter((e) => e.field === field);\n}\n\n// caches for tagging\nconst cacheServer = new WeakMap<ReadonlyArray<ErrorItem>, ReadonlyArray<ErrorItem>>();\nconst cacheClient = new WeakMap<ReadonlyArray<ErrorItem>, ReadonlyArray<ErrorItem>>();\nconst cacheDev = new WeakMap<ReadonlyArray<ErrorItem>, ReadonlyArray<ErrorItem>>();\n\nconst tag = (kind: ErrorKind, arr: ReadonlyArray<ErrorItem>): ReadonlyArray<ErrorItem> => {\n const cache = kind === 'server' ? cacheServer : kind === 'client' ? cacheClient : cacheDev;\n const hit = cache.get(arr);\n if (hit) {\n return hit;\n }\n const out = Object.freeze(arr.map((e) => Object.freeze({ ...e, kind })));\n cache.set(arr, out);\n return out;\n};\n\n/**\n * React hook for reading and managing errors in ACUL (Advanced Customization of Universal Login).\n * With all validation and server-side errors. It groups errors into three kinds:\n * - `server` — errors returned by Auth0 or your own backend.\n * - `client` — errors from client-side validation (e.g., invalid form input).\n * - `developer` — errors caused by incorrect integration or SDK misuse.\n *\n * @supportedScreens\n * - The `useErrors` hook is available on every ACUL screen.\n *\n * @param options.includeDevErrors - When `true`, developer errors are included in\n * the returned list. Defaults to `false`.\n *\n * @returns An object of type {@link UseErrorsResult}, containing:\n * - `errors` — the full error list of type {@link ErrorsResult}, with helpers:\n * - `errors.byKind(kind, filter?)` — filter by error kind and optionally by field.\n * - `errors.byField(field, filter?)` — filter by field and optionally by kind.\n * - `hasError` — `true` if any error is currently present.\n * - `dismiss(id)` — remove a specific error by its ID.\n * - `dismissAll()` — clear all tracked errors.\n *\n * Typical usage is inside a form or screen component where you need to\n * reactively display errors and provide ways to dismiss them:\n *\n * @example\n * ```tsx\n * import { useErrors } from \"@auth0/auth0-acul-react\";\n *\n * export function SignupForm() {\n * const { errors, hasError, dismiss, dismissAll } = useErrors();\n *\n * return (\n * <div>\n * {hasError && (\n * <div className=\"mb-4\">\n * {errors.byKind(\"server\").map(err => (\n * <div key={err.id} className=\"text-red-600\">\n * {err.message}\n * <button onClick={() => dismiss(err.id)}>Dismiss</button>\n * </div>\n * ))}\n * </div>\n * )}\n *\n * <button onClick={dismissAll}>Clear All Errors</button>\n * </div>\n * );\n * }\n * ```\n *\n * In addition to rendering messages, you can filter by field or kind:\n * ```ts\n * console.log(errors.byKind('client')); // all client errors\n * console.log(errors.byKind('client', { field: 'username' })); // client errors for field 'username'\n * console.log(errors.byField('username')); // all errors for field 'username'\n * console.log(errors.byField('username', { kind: 'server' })); // server errors for field 'username'\n * ```\n */\n\nexport function useErrors(options: UseErrorOptions = {}): UseErrorsResult {\n const { includeDevErrors = false } = options;\n\n const snap = useSyncExternalStore(\n (cb) => errorStore.subscribe(cb),\n () => errorStore.snapshot()\n );\n\n const didInit = useRef(false);\n useEffect(() => {\n if (didInit.current) {\n return;\n }\n didInit.current = true;\n\n // Get server errors directly from TS SDK on first render.\n const server = (getServerErrors?.() ?? []) as Array<Omit<ErrorItem, 'id'>>;\n errorStore.replace('server', server);\n }, []);\n\n const serverTagged = useMemo(() => tag('server', snap.server), [snap.server]);\n const clientTagged = useMemo(() => tag('client', snap.client), [snap.client]);\n const devTagged = useMemo(() => tag('developer', snap.developer), [snap.developer]);\n\n const all = useMemo<ReadonlyArray<ErrorItem>>(\n () => Object.freeze([...(includeDevErrors ? devTagged : []), ...clientTagged, ...serverTagged]),\n [includeDevErrors, devTagged, clientTagged, serverTagged]\n );\n\n const errors: ErrorsResult = useMemo(() => {\n const arr = Object.assign([...all], {\n byKind(kind: ErrorKind, opts?: { field?: string }): ReadonlyArray<ErrorItem> {\n const base =\n kind === 'client' ? clientTagged : kind === 'developer' ? devTagged : serverTagged;\n return opts?.field ? Object.freeze(filterByField(base, opts.field)) : base;\n },\n byField(field: string, opts?: { kind?: ErrorKind }): ReadonlyArray<ErrorItem> {\n if (opts?.kind) {\n return arr.byKind(opts.kind, { field });\n }\n return Object.freeze(filterByField(all, field));\n },\n });\n return Object.freeze(arr);\n }, [all, clientTagged, devTagged, serverTagged]);\n\n const hasError = all.length > 0;\n\n const dismiss = useCallback((id: string) => {\n errorStore.remove(ERROR_KINDS, id);\n }, []);\n\n const dismissAll = useCallback(() => {\n errorStore.clear(ERROR_KINDS);\n }, []);\n\n return useMemo(\n () => ({ errors, hasError, dismiss, dismissAll }),\n [errors, hasError, dismiss, dismissAll]\n );\n}\n\n// ---------------- INTERNAL (SDK-only) ----------------\nconst isPromise = (v: unknown): v is Promise<unknown> =>\n typeof v === 'object' &&\n v !== null &&\n 'then' in v &&\n typeof (v as { then: unknown }).then === 'function';\n\nfunction withError<T>(actionOrPromise: (() => T | Promise<T>) | Promise<T>): T | Promise<T> {\n const handle = (e: unknown) => {\n const kind = classifyKind(e);\n const normalized = toErrorObject(e);\n switch (kind) {\n case 'client':\n errorManager.replaceClientErrors([normalized]);\n break;\n case 'developer':\n errorManager.replaceDeveloperErrors([normalized]);\n break;\n case 'server':\n errorManager.replaceServerErrors([normalized]);\n break;\n default: {\n console.error('[auth0-acul-react] Unhandled error:', e);\n throw e;\n }\n }\n };\n\n if (typeof actionOrPromise === 'function') {\n try {\n const result = (actionOrPromise as () => T | Promise<T>)();\n return isPromise(result)\n ? result.catch((e) => {\n handle(e);\n throw e;\n })\n : result;\n } catch (e) {\n handle(e);\n throw e;\n }\n }\n\n return actionOrPromise.catch((e) => {\n handle(e);\n throw e;\n });\n}\n\n/**\n * @hidden\n * Internal error manager for use by SDK methods.\n * Use the `useErrors` hook in React components instead.\n */\nexport const errorManager = {\n withError,\n\n replaceClientErrors(list: Array<Omit<ErrorItem, 'id'>>, opts?: { byField?: string }) {\n if (opts?.byField) {\n errorStore.replacePartial('client', list, opts.byField);\n } else {\n errorStore.replace('client', list);\n }\n },\n clearClientErrors() {\n errorStore.clear(['client']);\n },\n pushClientErrors(list: Omit<ErrorItem, 'id'> | Array<Omit<ErrorItem, 'id'>>) {\n errorStore.push('client', list);\n },\n\n replaceDeveloperErrors(list: Array<Omit<ErrorItem, 'id'>>, opts?: { byField?: string }) {\n if (opts?.byField) {\n errorStore.replacePartial('developer', list, opts.byField);\n } else {\n errorStore.replace('developer', list);\n }\n },\n clearDeveloperErrors() {\n errorStore.clear(['developer']);\n },\n pushDeveloperErrors(list: Omit<ErrorItem, 'id'> | Array<Omit<ErrorItem, 'id'>>) {\n errorStore.push('developer', list);\n },\n\n replaceServerErrors(list: Array<Omit<ErrorItem, 'id'>>, opts?: { byField?: string }) {\n if (opts?.byField) {\n errorStore.replacePartial('server', list, opts.byField);\n } else {\n errorStore.replace('server', list);\n }\n },\n clearServerErrors() {\n errorStore.clear(['server']);\n },\n pushServerErrors(list: Omit<ErrorItem, 'id'> | Array<Omit<ErrorItem, 'id'>>) {\n errorStore.push('server', list);\n },\n\n syncServerErrors() {\n const server = (getServerErrors?.() ?? []) as Array<Omit<ErrorItem, 'id'>>;\n errorStore.replace('server', server);\n },\n};\n\nexport { ErrorItem, ErrorKind };\n"],"names":["filterByField","list","field","filter","e","cacheServer","WeakMap","cacheClient","cacheDev","tag","kind","arr","cache","hit","get","out","Object","freeze","map","set","useErrors","options","includeDevErrors","snap","useSyncExternalStore","cb","errorStore","subscribe","snapshot","didInit","useRef","useEffect","current","server","getServerErrors","replace","serverTagged","useMemo","clientTagged","client","devTagged","developer","all","errors","assign","byKind","opts","base","byField","hasError","length","dismiss","useCallback","id","remove","ERROR_KINDS","dismissAll","clear","errorManager","withError","actionOrPromise","handle","UserInputError","SDKUsageError","Auth0ServerError","classifyKind","normalized","code","Error","name","undefined","message","toErrorObject","replaceClientErrors","replaceDeveloperErrors","replaceServerErrors","console","error","result","v","then","catch","replacePartial","clearClientErrors","pushClientErrors","push","clearDeveloperErrors","pushDeveloperErrors","clearServerErrors","pushServerErrors","syncServerErrors"],"mappings":"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"}
1
+ {"version":3,"file":"errors.js","sources":["../../../src/hooks/common/errors.ts"],"sourcesContent":["import {\n ConfigurationError,\n ValidationError,\n Auth0Error as Auth0ServerError,\n getErrors as getServerErrors,\n type Error as Auth0Error,\n} from '@auth0/auth0-acul-js';\nimport { useEffect, useMemo, useRef, useSyncExternalStore, useCallback } from 'react';\n\nimport { errorStore, ERROR_KINDS, type ErrorItem, type ErrorKind } from '../../state/error-store';\n\nexport interface ErrorsResult extends ReadonlyArray<ErrorItem> {\n byKind(kind: ErrorKind, opts?: { field?: string }): ReadonlyArray<ErrorItem>;\n byField(field: string, opts?: { kind?: ErrorKind }): ReadonlyArray<ErrorItem>;\n}\n\nexport interface UseErrorOptions {\n includeDevErrors?: boolean;\n}\n\nexport interface UseErrorsResult {\n errors: ErrorsResult;\n hasError: boolean;\n dismiss: (id: string) => void;\n dismissAll: () => void;\n}\n\nfunction classifyKind(e: unknown): ErrorKind | null {\n if (e instanceof ValidationError) {\n return 'validation';\n }\n if (e instanceof ConfigurationError) {\n return 'configuration';\n }\n if (e instanceof Auth0ServerError) {\n return 'auth0';\n }\n return null;\n}\n\nfunction toErrorObject(e: unknown): Omit<ErrorItem, 'id'> {\n return {\n code: (e as Auth0Error)?.code ?? (e instanceof Error ? e.name : undefined) ?? 'unknown_error',\n message: (e as Auth0Error)?.message ?? 'Unknown error',\n field: (e as Auth0Error)?.field,\n };\n}\n\nfunction filterByField<T extends { field?: string }>(\n list: ReadonlyArray<T>,\n field?: string\n): ReadonlyArray<T> {\n if (!field) {\n return list;\n }\n return list.filter((e) => e.field === field);\n}\n\n// caches for tagging\nconst cacheServer = new WeakMap<ReadonlyArray<ErrorItem>, ReadonlyArray<ErrorItem>>();\nconst cacheValidation = new WeakMap<ReadonlyArray<ErrorItem>, ReadonlyArray<ErrorItem>>();\nconst cacheDev = new WeakMap<ReadonlyArray<ErrorItem>, ReadonlyArray<ErrorItem>>();\n\nconst tag = (kind: ErrorKind, arr: ReadonlyArray<ErrorItem>): ReadonlyArray<ErrorItem> => {\n const cache = kind === 'auth0' ? cacheServer : kind === 'validation' ? cacheValidation : cacheDev;\n const hit = cache.get(arr);\n if (hit) {\n return hit;\n }\n const out = Object.freeze(arr.map((e) => Object.freeze({ ...e, kind })));\n cache.set(arr, out);\n return out;\n};\n\n/**\n * React hook for reading and managing errors in ACUL (Advanced Customization of Universal Login).\n * With all validation and server-side errors. It groups errors into three kinds:\n * - `auth0` — errors returned by Auth0 or your own backend.\n * - `validation` — errors from client-side validation (e.g., invalid form input).\n * - `configuration` — errors caused by incorrect integration or SDK misuse.\n *\n * @supportedScreens\n * - The `useErrors` hook is available on every ACUL screen.\n *\n * @param options.includeDevErrors - When `true`, configuration errors are included in\n * the returned list. Defaults to `false`.\n *\n * @returns An object of type {@link UseErrorsResult}, containing:\n * - `errors` — the full error list of type {@link ErrorsResult}, with helpers:\n * - `errors.byKind(kind, filter?)` — filter by error kind and optionally by field.\n * - `errors.byField(field, filter?)` — filter by field and optionally by kind.\n * - `hasError` — `true` if any error is currently present.\n * - `dismiss(id)` — remove a specific error by its ID.\n * - `dismissAll()` — clear all tracked errors.\n *\n * Typical usage is inside a form or screen component where you need to\n * reactively display errors and provide ways to dismiss them:\n *\n * @example\n * ```tsx\n * import { useErrors } from \"@auth0/auth0-acul-react\";\n *\n * export function SignupForm() {\n * const { errors, hasError, dismiss, dismissAll } = useErrors();\n *\n * return (\n * <div>\n * {hasError && (\n * <div className=\"mb-4\">\n * {errors.byKind(\"auth0\").map(err => (\n * <div key={err.id} className=\"text-red-600\">\n * {err.message}\n * <button onClick={() => dismiss(err.id)}>Dismiss</button>\n * </div>\n * ))}\n * </div>\n * )}\n *\n * <button onClick={dismissAll}>Clear All Errors</button>\n * </div>\n * );\n * }\n * ```\n *\n * In addition to rendering messages, you can filter by field or kind:\n * ```ts\n * console.log(errors.byKind('validation')); // all validation errors\n * console.log(errors.byKind('validation', { field: 'username' })); // validation errors for field 'username'\n * console.log(errors.byField('username')); // all errors for field 'username'\n * console.log(errors.byField('username', { kind: 'auth0' })); // auth0 errors for field 'username'\n * ```\n */\n\nexport function useErrors(options: UseErrorOptions = {}): UseErrorsResult {\n const { includeDevErrors = false } = options;\n\n const snap = useSyncExternalStore(\n (cb) => errorStore.subscribe(cb),\n () => errorStore.snapshot()\n );\n\n const didInit = useRef(false);\n useEffect(() => {\n if (didInit.current) {\n return;\n }\n didInit.current = true;\n\n // Get server errors directly from TS SDK on first render.\n const server = (getServerErrors?.() ?? []) as Array<Omit<ErrorItem, 'id'>>;\n errorStore.replace('auth0', server);\n }, []);\n\n const serverTagged = useMemo(() => tag('auth0', snap.auth0), [snap.auth0]);\n const clientTagged = useMemo(() => tag('validation', snap.validation), [snap.validation]);\n const devTagged = useMemo(() => tag('configuration', snap.configuration), [snap.configuration]);\n\n const all = useMemo<ReadonlyArray<ErrorItem>>(\n () => Object.freeze([...(includeDevErrors ? devTagged : []), ...clientTagged, ...serverTagged]),\n [includeDevErrors, devTagged, clientTagged, serverTagged]\n );\n\n const errors: ErrorsResult = useMemo(() => {\n const arr = Object.assign([...all], {\n byKind(kind: ErrorKind, opts?: { field?: string }): ReadonlyArray<ErrorItem> {\n let base: ReadonlyArray<ErrorItem>;\n if (kind === 'validation') {\n base = clientTagged;\n } else if (kind === 'configuration') {\n base = devTagged;\n } else {\n base = serverTagged;\n }\n if (opts?.field) {\n return Object.freeze(filterByField(base, opts.field));\n }\n return base;\n },\n byField(field: string, opts?: { kind?: ErrorKind }): ReadonlyArray<ErrorItem> {\n if (opts?.kind) {\n return arr.byKind(opts.kind, { field });\n }\n return Object.freeze(filterByField(all, field));\n },\n });\n return Object.freeze(arr);\n }, [all, clientTagged, devTagged, serverTagged]);\n\n const hasError = all.length > 0;\n\n const dismiss = useCallback((id: string) => {\n errorStore.remove(ERROR_KINDS, id);\n }, []);\n\n const dismissAll = useCallback(() => {\n errorStore.clear(ERROR_KINDS);\n }, []);\n\n return useMemo(\n () => ({ errors, hasError, dismiss, dismissAll }),\n [errors, hasError, dismiss, dismissAll]\n );\n}\n\n// ---------------- INTERNAL (SDK-only) ----------------\nconst isPromise = (v: unknown): v is Promise<unknown> =>\n typeof v === 'object' &&\n v !== null &&\n 'then' in v &&\n typeof (v as { then: unknown }).then === 'function';\n\nfunction withError<T>(actionOrPromise: (() => T | Promise<T>) | Promise<T>): T | Promise<T> {\n const handle = (e: unknown) => {\n const kind = classifyKind(e);\n const normalized = toErrorObject(e);\n switch (kind) {\n case 'validation':\n errorManager.replaceValidationErrors([normalized]);\n break;\n case 'configuration':\n errorManager.replaceDeveloperErrors([normalized]);\n break;\n case 'auth0':\n errorManager.replaceServerErrors([normalized]);\n break;\n default: {\n console.error('[auth0-acul-react] Unhandled error:', e);\n throw e;\n }\n }\n };\n\n if (typeof actionOrPromise === 'function') {\n try {\n const result = (actionOrPromise as () => T | Promise<T>)();\n return isPromise(result)\n ? result.catch((e) => {\n handle(e);\n throw e;\n })\n : result;\n } catch (e) {\n handle(e);\n throw e;\n }\n }\n\n return actionOrPromise.catch((e) => {\n handle(e);\n throw e;\n });\n}\n\n/**\n * @hidden\n * Internal error manager for use by SDK methods.\n * Use the `useErrors` hook in React components instead.\n */\nexport const errorManager = {\n withError,\n\n replaceValidationErrors(list: Array<Omit<ErrorItem, 'id'>>, opts?: { byField?: string }) {\n if (opts?.byField) {\n errorStore.replacePartial('validation', list, opts.byField);\n } else {\n errorStore.replace('validation', list);\n }\n },\n clearValidationErrors() {\n errorStore.clear(['validation']);\n },\n pushValidationErrors(list: Omit<ErrorItem, 'id'> | Array<Omit<ErrorItem, 'id'>>) {\n errorStore.push('validation', list);\n },\n\n replaceDeveloperErrors(list: Array<Omit<ErrorItem, 'id'>>, opts?: { byField?: string }) {\n if (opts?.byField) {\n errorStore.replacePartial('configuration', list, opts.byField);\n } else {\n errorStore.replace('configuration', list);\n }\n },\n clearDeveloperErrors() {\n errorStore.clear(['configuration']);\n },\n pushDeveloperErrors(list: Omit<ErrorItem, 'id'> | Array<Omit<ErrorItem, 'id'>>) {\n errorStore.push('configuration', list);\n },\n\n replaceServerErrors(list: Array<Omit<ErrorItem, 'id'>>, opts?: { byField?: string }) {\n if (opts?.byField) {\n errorStore.replacePartial('auth0', list, opts.byField);\n } else {\n errorStore.replace('auth0', list);\n }\n },\n clearServerErrors() {\n errorStore.clear(['auth0']);\n },\n pushServerErrors(list: Omit<ErrorItem, 'id'> | Array<Omit<ErrorItem, 'id'>>) {\n errorStore.push('auth0', list);\n },\n\n syncServerErrors() {\n const server = (getServerErrors?.() ?? []) as Array<Omit<ErrorItem, 'id'>>;\n errorStore.replace('auth0', server);\n },\n};\n\nexport { ErrorItem, ErrorKind };\n"],"names":["filterByField","list","field","filter","e","cacheServer","WeakMap","cacheValidation","cacheDev","tag","kind","arr","cache","hit","get","out","Object","freeze","map","set","useErrors","options","includeDevErrors","snap","useSyncExternalStore","cb","errorStore","subscribe","snapshot","didInit","useRef","useEffect","current","server","getServerErrors","replace","serverTagged","useMemo","auth0","clientTagged","validation","devTagged","configuration","all","errors","assign","byKind","opts","base","byField","hasError","length","dismiss","useCallback","id","remove","ERROR_KINDS","dismissAll","clear","errorManager","withError","actionOrPromise","handle","ValidationError","ConfigurationError","Auth0ServerError","classifyKind","normalized","code","Error","name","undefined","message","toErrorObject","replaceValidationErrors","replaceDeveloperErrors","replaceServerErrors","console","error","result","v","then","catch","replacePartial","clearValidationErrors","pushValidationErrors","push","clearDeveloperErrors","pushDeveloperErrors","clearServerErrors","pushServerErrors","syncServerErrors"],"mappings":"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"}
@@ -8,3 +8,4 @@ export { useMfaPolling, type MfaPollingResult, type ULError } from './utility/po
8
8
  export { useResend, type UseResendReturn, type UseResendOptions } from './utility/resend-manager';
9
9
  export { usePasswordValidation, type PasswordValidationResult, type PasswordComplexityRule, } from './utility/validate-password';
10
10
  export { useUsernameValidation, type UsernameValidationResult, type UsernameValidationError, } from './utility/validate-username';
11
+ export { usePasskeyAutofill, type UsePasskeyAutofillResult } from './utility/passkey-autofill';