@dloizides/auth-web 1.18.2 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.19.0
4
+
5
+ **`<RegisterForm compact>` (AUTH-REG-1 "Compact register form").** Opt-in; the default seven-field form is unchanged.
6
+ Shows only "Your name", Email, Password and the tenant name. The name is split into firstName/lastName (one word
7
+ fills both, since Keycloak needs a last name), the username is derived from the whole email (lower-cased, chars
8
+ outside `[a-z0-9._-]` become `_`), and there is no confirm-password field. New optional `labels.fullName`.
9
+ `splitFullName` and `deriveUsernameFromEmail` are exported. `useRegisterForm({ compact })` for headless use.
10
+
11
+ ## 1.18.3
12
+
13
+ - `useLoginSubmit` has an in-flight ref guard, like `useRegisterForm`. A focused field stays read-only (not
14
+ disabled) during a pending login and RN-web still fires `onSubmitEditing` there, so a second Enter sent a
15
+ second `/bff/login`. jsdom tests now cover a pending submit + a second non-repeat Enter for both forms,
16
+ a valid register submitted by Enter, and an IME-composition Enter not submitting.
17
+
3
18
  ## 1.18.2
4
19
 
5
20
  **Enter in a text field submits `<RegisterForm>` and `<LoginForm>`.**
package/dist/index.d.mts CHANGED
@@ -592,6 +592,8 @@ interface RegisterFormLabels {
592
592
  /** `accessibilityLabel` for the submit button while the request runs. */
593
593
  submitting: string;
594
594
  fields: Record<RegisterInputField, RegisterFieldLabels>;
595
+ /** Copy for the single "Your name" input of the compact form. Defaults to English. */
596
+ fullName?: RegisterFieldLabels;
595
597
  }
596
598
  declare const DEFAULT_REGISTER_LABELS: RegisterFormLabels;
597
599
 
@@ -2472,9 +2474,15 @@ interface RegisterFormProps<TResult> {
2472
2474
  footer?: ReactNode;
2473
2475
  /** Prefix applied to every `testID`. */
2474
2476
  testIdPrefix?: string;
2477
+ /**
2478
+ * Opt-in compact form (AUTH-REG-1): only "Your name", Email, Password and the
2479
+ * tenant name. First/last name are split from the name (one word fills both),
2480
+ * the username is derived from the email, and there is no confirm-password field.
2481
+ */
2482
+ compact?: boolean;
2475
2483
  }
2476
2484
  /** Themeable registration form built on `useRegisterForm`. */
2477
- declare function RegisterForm<TResult>({ onSubmit, onSuccess, onError, onSubmitAttempt, passwordPolicy, labels: labelsProp, theme: themeProp, footer, testIdPrefix, }: Readonly<RegisterFormProps<TResult>>): ReactElement;
2485
+ declare function RegisterForm<TResult>({ onSubmit, onSuccess, onError, onSubmitAttempt, passwordPolicy, labels: labelsProp, theme: themeProp, footer, testIdPrefix, compact, }: Readonly<RegisterFormProps<TResult>>): ReactElement;
2478
2486
 
2479
2487
  /**
2480
2488
  * `testID` values for `<RegisterForm>`.
@@ -2511,6 +2519,11 @@ interface UseRegisterFormArgs<TResult> {
2511
2519
  * event). A press ignored because a submit is already in flight does not call it.
2512
2520
  */
2513
2521
  onSubmitAttempt?: () => void;
2522
+ /**
2523
+ * Compact mode (AUTH-REG-1): `firstName` holds the full name; last name, username
2524
+ * (from the email) and the password confirmation are derived before validation.
2525
+ */
2526
+ compact?: boolean;
2514
2527
  }
2515
2528
  interface UseRegisterFormResult<TResult> {
2516
2529
  state: RegisterFormValues;
@@ -2521,7 +2534,7 @@ interface UseRegisterFormResult<TResult> {
2521
2534
  error: RegisterErrorCode | null;
2522
2535
  }
2523
2536
  /** Headless registration form logic. */
2524
- declare function useRegisterForm<TResult>({ onSubmit, passwordPolicy, onSubmitAttempt, }: UseRegisterFormArgs<TResult>): UseRegisterFormResult<TResult>;
2537
+ declare function useRegisterForm<TResult>({ onSubmit, passwordPolicy, onSubmitAttempt, compact, }: UseRegisterFormArgs<TResult>): UseRegisterFormResult<TResult>;
2525
2538
 
2526
2539
  /**
2527
2540
  * Pure registration helpers: trimming, client-side validation and decoding of a
@@ -2535,6 +2548,30 @@ declare function useRegisterForm<TResult>({ onSubmit, passwordPolicy, onSubmitAt
2535
2548
  /** The default password rule: 8+ characters with a letter, a digit and a special character. */
2536
2549
  declare function isRegisterPasswordStrong(password: string): boolean;
2537
2550
 
2551
+ /**
2552
+ * Compact registration (AUTH-REG-1 "Compact register form"): the form shows only
2553
+ * "Your name", Email, Password (+ tenant name). Keycloak still needs a username,
2554
+ * a first name AND a last name, so they are derived here before validation.
2555
+ *
2556
+ * In compact mode the single "Your name" input is stored in `firstName`.
2557
+ */
2558
+
2559
+ interface SplitName {
2560
+ firstName: string;
2561
+ lastName: string;
2562
+ }
2563
+ /**
2564
+ * Split a full name on whitespace: the first word is the first name, the rest the
2565
+ * last name. A single word is used for both (Keycloak requires a last name).
2566
+ */
2567
+ declare function splitFullName(fullName: string): SplitName;
2568
+ /**
2569
+ * A username derived from the whole email (so two people with the same local part
2570
+ * on different domains never collide): lower-cased, every char outside
2571
+ * `[a-z0-9._-]` replaced by `_`. `Ada+shop@Example.com` becomes `ada_shop_example.com`.
2572
+ */
2573
+ declare function deriveUsernameFromEmail(email: string): string;
2574
+
2538
2575
  /**
2539
2576
  * `createBffAuthClient` — the one-line wiring of a same-origin `BffAuthClient`.
2540
2577
  *
@@ -2824,4 +2861,4 @@ interface UseChangePasswordResult {
2824
2861
  }
2825
2862
  declare function useChangePassword({ client, onChanged, }: UseChangePasswordArgs): UseChangePasswordResult;
2826
2863
 
2827
- export { type AccountSettingsChangePasswordConfig, type AccountSettingsDevicePinConfig, type AccountSettingsLabels, type AccountSettingsPasskeysConfig, type AccountSettingsPreferredMethodConfig, AccountSettingsScreen, type AccountSettingsScreenProps, AuthScreen, type AuthScreenProps, AuthTestIds, type AuthTheme, type AuthThemeColors, AuthThemeProvider, type AuthThemeProviderProps, type AuthThemeRadii, type AuthThemeSpacing, type AuthThemeTypography, BffAuthStatus, type BffDeviceState, type BffLoginConfig, type BffLogoutClient, CHANGE_PASSWORD_ENDPOINT, type ChangePasswordCapableClient, ChangePasswordCard, type ChangePasswordCardProps, ChangePasswordErrorKey, type ChangePasswordRequest, type ChangePasswordResult, type CreateBffAuthClientOptions, type CreateBffChangePasswordClientOptions, DEFAULT_ACCOUNT_SETTINGS_LABELS, DEFAULT_AUTH_CARD_MAX_WIDTH, DEFAULT_DEMO_CREDENTIALS_HINT_LABELS, DEFAULT_DEVICE_PIN_ENROLL_LABELS, DEFAULT_DEVICE_PIN_SETTINGS_LABELS, DEFAULT_DEVICE_PIN_UNLOCK_LABELS, DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS, DEFAULT_FORGOT_PASSWORD_LABELS, DEFAULT_LOGIN_LABELS, DEFAULT_OTP_LABELS, DEFAULT_PASSKEY_LOGIN_LABELS, DEFAULT_PASSKEY_SETTINGS_LABELS, DEFAULT_PIN_LABELS, DEFAULT_PREFERRED_METHOD_HINT_LABELS, DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS, DEFAULT_REGISTER_LABELS, DEFAULT_RESET_PASSWORD_LABELS, DEVICE_PIN_ALLOWED_DIGITS, DEVICE_PIN_DEFAULT_DIGITS, DemoCredentialsHint, type DemoCredentialsHintLabels, type DemoCredentialsHintProps, DemoCredentialsHintVariant, type DemoCredentialsHintWiring, type DemoCredentialsLoginFormProps, type DevicePinCapableClient, type DevicePinDisableCapableClient, type DevicePinEnrollCapableClient, DevicePinEnrollErrorKey, DevicePinEnrollForm, type DevicePinEnrollFormProps, type DevicePinEnrollLabels, type DevicePinEnrollResult, DevicePinErrorKey, DevicePinInput, type DevicePinInputProps, DevicePinLengthPicker, type DevicePinLengthPickerProps, DevicePinOffer, type DevicePinOfferProps, DevicePinSettingsCard, type DevicePinSettingsCardProps, type DevicePinSettingsLabels, type DevicePinUnlockCapableClient, type DevicePinUnlockLabels, type DevicePinUnlockResult, DevicePinUnlockScreen, type DevicePinUnlockScreenProps, type DevicePinUnlockedUser, ForgotPasswordFields, type ForgotPasswordFieldsLabels, type ForgotPasswordFieldsProps, ForgotPasswordForm, type ForgotPasswordFormLabels, type ForgotPasswordFormProps, type LoginConfigCapableClient, LoginForm, type LoginFormLabels, type LoginFormProps, OtpForm, type OtpFormLabels, type OtpFormProps, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasskeyCeremonyMode, PasskeyCeremonyStatus, type PasskeyErrorCode, PasskeyLoginButton, type PasskeyLoginButtonProps, type PasskeyLoginLabels, PasskeySettingsCard, type PasskeySettingsCardProps, type PasskeySettingsLabels, PasswordPolicyError, type PerformBffLogoutOptions, PinForm, type PinFormLabels, type PinFormProps, type PreferencesClientOptions, type PreferredMethodClient, PreferredMethodHint, type PreferredMethodHintLabels, type PreferredMethodHintProps, PreferredMethodSettingsCard, type PreferredMethodSettingsCardProps, type PreferredMethodSettingsLabels, PrefillIntent, RegisterErrorCode, type RegisterField, type RegisterFieldLabels, RegisterForm, type RegisterFormLabels, type RegisterFormProps, type RegisterFormValues, type RegisterInputField, type RegisterPasswordPolicy, type RegisterSubmitOutcome, type RegisterSubmitValues, RegisterTestIds, ResetPasswordError, ResetPasswordForm, type ResetPasswordFormLabels, type ResetPasswordFormProps, type RoleRoute, type RoleRouteTable, type UseBffAuthOptions, type UseBffAuthResult, type UseBffForgotPasswordOptions, type UseBffLoginConfigResult, type UseBffResetPasswordOptions, type UseChangePasswordArgs, type UseChangePasswordResult, type UseDemoCredentialsOptions, type UseDemoCredentialsResult, type UseDevicePinDisableArgs, type UseDevicePinDisableResult, type UseDevicePinEnrollArgs, type UseDevicePinEnrollResult, type UseDevicePinUnlockArgs, type UseDevicePinUnlockResult, type UseForgotPasswordSubmitArgs, type UseForgotPasswordSubmitResult, type UseOtpLoginOptions, type UseOtpLoginResult, type UsePasskeyCeremonyOptions, type UsePasskeyCeremonyResult, type UsePinLoginOptions, type UsePinLoginResult, type UsePreferredMethodSettingArgs, type UsePreferredMethodSettingResult, type UseRegisterFormArgs, type UseRegisterFormResult, type UseResetPasswordFormArgs, type UseResetPasswordFormResult, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createBffChangePasswordClient, createPreferencesClient, defaultAuthTheme, isAllowedPinDigits, isPasswordValid, isRegisterPasswordStrong, isValidForgotPasswordEmail, performBffLogout, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolveAccountList, resolveDemoAccounts, resolveDemoCredentials, resolvePostLoginRoute, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useChangePassword, useDemoCredentials, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePasskeyCeremony, usePinLogin, usePreferredMethodSetting, useRegisterForm, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
2864
+ export { type AccountSettingsChangePasswordConfig, type AccountSettingsDevicePinConfig, type AccountSettingsLabels, type AccountSettingsPasskeysConfig, type AccountSettingsPreferredMethodConfig, AccountSettingsScreen, type AccountSettingsScreenProps, AuthScreen, type AuthScreenProps, AuthTestIds, type AuthTheme, type AuthThemeColors, AuthThemeProvider, type AuthThemeProviderProps, type AuthThemeRadii, type AuthThemeSpacing, type AuthThemeTypography, BffAuthStatus, type BffDeviceState, type BffLoginConfig, type BffLogoutClient, CHANGE_PASSWORD_ENDPOINT, type ChangePasswordCapableClient, ChangePasswordCard, type ChangePasswordCardProps, ChangePasswordErrorKey, type ChangePasswordRequest, type ChangePasswordResult, type CreateBffAuthClientOptions, type CreateBffChangePasswordClientOptions, DEFAULT_ACCOUNT_SETTINGS_LABELS, DEFAULT_AUTH_CARD_MAX_WIDTH, DEFAULT_DEMO_CREDENTIALS_HINT_LABELS, DEFAULT_DEVICE_PIN_ENROLL_LABELS, DEFAULT_DEVICE_PIN_SETTINGS_LABELS, DEFAULT_DEVICE_PIN_UNLOCK_LABELS, DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS, DEFAULT_FORGOT_PASSWORD_LABELS, DEFAULT_LOGIN_LABELS, DEFAULT_OTP_LABELS, DEFAULT_PASSKEY_LOGIN_LABELS, DEFAULT_PASSKEY_SETTINGS_LABELS, DEFAULT_PIN_LABELS, DEFAULT_PREFERRED_METHOD_HINT_LABELS, DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS, DEFAULT_REGISTER_LABELS, DEFAULT_RESET_PASSWORD_LABELS, DEVICE_PIN_ALLOWED_DIGITS, DEVICE_PIN_DEFAULT_DIGITS, DemoCredentialsHint, type DemoCredentialsHintLabels, type DemoCredentialsHintProps, DemoCredentialsHintVariant, type DemoCredentialsHintWiring, type DemoCredentialsLoginFormProps, type DevicePinCapableClient, type DevicePinDisableCapableClient, type DevicePinEnrollCapableClient, DevicePinEnrollErrorKey, DevicePinEnrollForm, type DevicePinEnrollFormProps, type DevicePinEnrollLabels, type DevicePinEnrollResult, DevicePinErrorKey, DevicePinInput, type DevicePinInputProps, DevicePinLengthPicker, type DevicePinLengthPickerProps, DevicePinOffer, type DevicePinOfferProps, DevicePinSettingsCard, type DevicePinSettingsCardProps, type DevicePinSettingsLabels, type DevicePinUnlockCapableClient, type DevicePinUnlockLabels, type DevicePinUnlockResult, DevicePinUnlockScreen, type DevicePinUnlockScreenProps, type DevicePinUnlockedUser, ForgotPasswordFields, type ForgotPasswordFieldsLabels, type ForgotPasswordFieldsProps, ForgotPasswordForm, type ForgotPasswordFormLabels, type ForgotPasswordFormProps, type LoginConfigCapableClient, LoginForm, type LoginFormLabels, type LoginFormProps, OtpForm, type OtpFormLabels, type OtpFormProps, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasskeyCeremonyMode, PasskeyCeremonyStatus, type PasskeyErrorCode, PasskeyLoginButton, type PasskeyLoginButtonProps, type PasskeyLoginLabels, PasskeySettingsCard, type PasskeySettingsCardProps, type PasskeySettingsLabels, PasswordPolicyError, type PerformBffLogoutOptions, PinForm, type PinFormLabels, type PinFormProps, type PreferencesClientOptions, type PreferredMethodClient, PreferredMethodHint, type PreferredMethodHintLabels, type PreferredMethodHintProps, PreferredMethodSettingsCard, type PreferredMethodSettingsCardProps, type PreferredMethodSettingsLabels, PrefillIntent, RegisterErrorCode, type RegisterField, type RegisterFieldLabels, RegisterForm, type RegisterFormLabels, type RegisterFormProps, type RegisterFormValues, type RegisterInputField, type RegisterPasswordPolicy, type RegisterSubmitOutcome, type RegisterSubmitValues, RegisterTestIds, ResetPasswordError, ResetPasswordForm, type ResetPasswordFormLabels, type ResetPasswordFormProps, type RoleRoute, type RoleRouteTable, type SplitName, type UseBffAuthOptions, type UseBffAuthResult, type UseBffForgotPasswordOptions, type UseBffLoginConfigResult, type UseBffResetPasswordOptions, type UseChangePasswordArgs, type UseChangePasswordResult, type UseDemoCredentialsOptions, type UseDemoCredentialsResult, type UseDevicePinDisableArgs, type UseDevicePinDisableResult, type UseDevicePinEnrollArgs, type UseDevicePinEnrollResult, type UseDevicePinUnlockArgs, type UseDevicePinUnlockResult, type UseForgotPasswordSubmitArgs, type UseForgotPasswordSubmitResult, type UseOtpLoginOptions, type UseOtpLoginResult, type UsePasskeyCeremonyOptions, type UsePasskeyCeremonyResult, type UsePinLoginOptions, type UsePinLoginResult, type UsePreferredMethodSettingArgs, type UsePreferredMethodSettingResult, type UseRegisterFormArgs, type UseRegisterFormResult, type UseResetPasswordFormArgs, type UseResetPasswordFormResult, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createBffChangePasswordClient, createPreferencesClient, defaultAuthTheme, deriveUsernameFromEmail, isAllowedPinDigits, isPasswordValid, isRegisterPasswordStrong, isValidForgotPasswordEmail, performBffLogout, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolveAccountList, resolveDemoAccounts, resolveDemoCredentials, resolvePostLoginRoute, splitFullName, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useChangePassword, useDemoCredentials, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePasskeyCeremony, usePinLogin, usePreferredMethodSetting, useRegisterForm, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
package/dist/index.d.ts CHANGED
@@ -592,6 +592,8 @@ interface RegisterFormLabels {
592
592
  /** `accessibilityLabel` for the submit button while the request runs. */
593
593
  submitting: string;
594
594
  fields: Record<RegisterInputField, RegisterFieldLabels>;
595
+ /** Copy for the single "Your name" input of the compact form. Defaults to English. */
596
+ fullName?: RegisterFieldLabels;
595
597
  }
596
598
  declare const DEFAULT_REGISTER_LABELS: RegisterFormLabels;
597
599
 
@@ -2472,9 +2474,15 @@ interface RegisterFormProps<TResult> {
2472
2474
  footer?: ReactNode;
2473
2475
  /** Prefix applied to every `testID`. */
2474
2476
  testIdPrefix?: string;
2477
+ /**
2478
+ * Opt-in compact form (AUTH-REG-1): only "Your name", Email, Password and the
2479
+ * tenant name. First/last name are split from the name (one word fills both),
2480
+ * the username is derived from the email, and there is no confirm-password field.
2481
+ */
2482
+ compact?: boolean;
2475
2483
  }
2476
2484
  /** Themeable registration form built on `useRegisterForm`. */
2477
- declare function RegisterForm<TResult>({ onSubmit, onSuccess, onError, onSubmitAttempt, passwordPolicy, labels: labelsProp, theme: themeProp, footer, testIdPrefix, }: Readonly<RegisterFormProps<TResult>>): ReactElement;
2485
+ declare function RegisterForm<TResult>({ onSubmit, onSuccess, onError, onSubmitAttempt, passwordPolicy, labels: labelsProp, theme: themeProp, footer, testIdPrefix, compact, }: Readonly<RegisterFormProps<TResult>>): ReactElement;
2478
2486
 
2479
2487
  /**
2480
2488
  * `testID` values for `<RegisterForm>`.
@@ -2511,6 +2519,11 @@ interface UseRegisterFormArgs<TResult> {
2511
2519
  * event). A press ignored because a submit is already in flight does not call it.
2512
2520
  */
2513
2521
  onSubmitAttempt?: () => void;
2522
+ /**
2523
+ * Compact mode (AUTH-REG-1): `firstName` holds the full name; last name, username
2524
+ * (from the email) and the password confirmation are derived before validation.
2525
+ */
2526
+ compact?: boolean;
2514
2527
  }
2515
2528
  interface UseRegisterFormResult<TResult> {
2516
2529
  state: RegisterFormValues;
@@ -2521,7 +2534,7 @@ interface UseRegisterFormResult<TResult> {
2521
2534
  error: RegisterErrorCode | null;
2522
2535
  }
2523
2536
  /** Headless registration form logic. */
2524
- declare function useRegisterForm<TResult>({ onSubmit, passwordPolicy, onSubmitAttempt, }: UseRegisterFormArgs<TResult>): UseRegisterFormResult<TResult>;
2537
+ declare function useRegisterForm<TResult>({ onSubmit, passwordPolicy, onSubmitAttempt, compact, }: UseRegisterFormArgs<TResult>): UseRegisterFormResult<TResult>;
2525
2538
 
2526
2539
  /**
2527
2540
  * Pure registration helpers: trimming, client-side validation and decoding of a
@@ -2535,6 +2548,30 @@ declare function useRegisterForm<TResult>({ onSubmit, passwordPolicy, onSubmitAt
2535
2548
  /** The default password rule: 8+ characters with a letter, a digit and a special character. */
2536
2549
  declare function isRegisterPasswordStrong(password: string): boolean;
2537
2550
 
2551
+ /**
2552
+ * Compact registration (AUTH-REG-1 "Compact register form"): the form shows only
2553
+ * "Your name", Email, Password (+ tenant name). Keycloak still needs a username,
2554
+ * a first name AND a last name, so they are derived here before validation.
2555
+ *
2556
+ * In compact mode the single "Your name" input is stored in `firstName`.
2557
+ */
2558
+
2559
+ interface SplitName {
2560
+ firstName: string;
2561
+ lastName: string;
2562
+ }
2563
+ /**
2564
+ * Split a full name on whitespace: the first word is the first name, the rest the
2565
+ * last name. A single word is used for both (Keycloak requires a last name).
2566
+ */
2567
+ declare function splitFullName(fullName: string): SplitName;
2568
+ /**
2569
+ * A username derived from the whole email (so two people with the same local part
2570
+ * on different domains never collide): lower-cased, every char outside
2571
+ * `[a-z0-9._-]` replaced by `_`. `Ada+shop@Example.com` becomes `ada_shop_example.com`.
2572
+ */
2573
+ declare function deriveUsernameFromEmail(email: string): string;
2574
+
2538
2575
  /**
2539
2576
  * `createBffAuthClient` — the one-line wiring of a same-origin `BffAuthClient`.
2540
2577
  *
@@ -2824,4 +2861,4 @@ interface UseChangePasswordResult {
2824
2861
  }
2825
2862
  declare function useChangePassword({ client, onChanged, }: UseChangePasswordArgs): UseChangePasswordResult;
2826
2863
 
2827
- export { type AccountSettingsChangePasswordConfig, type AccountSettingsDevicePinConfig, type AccountSettingsLabels, type AccountSettingsPasskeysConfig, type AccountSettingsPreferredMethodConfig, AccountSettingsScreen, type AccountSettingsScreenProps, AuthScreen, type AuthScreenProps, AuthTestIds, type AuthTheme, type AuthThemeColors, AuthThemeProvider, type AuthThemeProviderProps, type AuthThemeRadii, type AuthThemeSpacing, type AuthThemeTypography, BffAuthStatus, type BffDeviceState, type BffLoginConfig, type BffLogoutClient, CHANGE_PASSWORD_ENDPOINT, type ChangePasswordCapableClient, ChangePasswordCard, type ChangePasswordCardProps, ChangePasswordErrorKey, type ChangePasswordRequest, type ChangePasswordResult, type CreateBffAuthClientOptions, type CreateBffChangePasswordClientOptions, DEFAULT_ACCOUNT_SETTINGS_LABELS, DEFAULT_AUTH_CARD_MAX_WIDTH, DEFAULT_DEMO_CREDENTIALS_HINT_LABELS, DEFAULT_DEVICE_PIN_ENROLL_LABELS, DEFAULT_DEVICE_PIN_SETTINGS_LABELS, DEFAULT_DEVICE_PIN_UNLOCK_LABELS, DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS, DEFAULT_FORGOT_PASSWORD_LABELS, DEFAULT_LOGIN_LABELS, DEFAULT_OTP_LABELS, DEFAULT_PASSKEY_LOGIN_LABELS, DEFAULT_PASSKEY_SETTINGS_LABELS, DEFAULT_PIN_LABELS, DEFAULT_PREFERRED_METHOD_HINT_LABELS, DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS, DEFAULT_REGISTER_LABELS, DEFAULT_RESET_PASSWORD_LABELS, DEVICE_PIN_ALLOWED_DIGITS, DEVICE_PIN_DEFAULT_DIGITS, DemoCredentialsHint, type DemoCredentialsHintLabels, type DemoCredentialsHintProps, DemoCredentialsHintVariant, type DemoCredentialsHintWiring, type DemoCredentialsLoginFormProps, type DevicePinCapableClient, type DevicePinDisableCapableClient, type DevicePinEnrollCapableClient, DevicePinEnrollErrorKey, DevicePinEnrollForm, type DevicePinEnrollFormProps, type DevicePinEnrollLabels, type DevicePinEnrollResult, DevicePinErrorKey, DevicePinInput, type DevicePinInputProps, DevicePinLengthPicker, type DevicePinLengthPickerProps, DevicePinOffer, type DevicePinOfferProps, DevicePinSettingsCard, type DevicePinSettingsCardProps, type DevicePinSettingsLabels, type DevicePinUnlockCapableClient, type DevicePinUnlockLabels, type DevicePinUnlockResult, DevicePinUnlockScreen, type DevicePinUnlockScreenProps, type DevicePinUnlockedUser, ForgotPasswordFields, type ForgotPasswordFieldsLabels, type ForgotPasswordFieldsProps, ForgotPasswordForm, type ForgotPasswordFormLabels, type ForgotPasswordFormProps, type LoginConfigCapableClient, LoginForm, type LoginFormLabels, type LoginFormProps, OtpForm, type OtpFormLabels, type OtpFormProps, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasskeyCeremonyMode, PasskeyCeremonyStatus, type PasskeyErrorCode, PasskeyLoginButton, type PasskeyLoginButtonProps, type PasskeyLoginLabels, PasskeySettingsCard, type PasskeySettingsCardProps, type PasskeySettingsLabels, PasswordPolicyError, type PerformBffLogoutOptions, PinForm, type PinFormLabels, type PinFormProps, type PreferencesClientOptions, type PreferredMethodClient, PreferredMethodHint, type PreferredMethodHintLabels, type PreferredMethodHintProps, PreferredMethodSettingsCard, type PreferredMethodSettingsCardProps, type PreferredMethodSettingsLabels, PrefillIntent, RegisterErrorCode, type RegisterField, type RegisterFieldLabels, RegisterForm, type RegisterFormLabels, type RegisterFormProps, type RegisterFormValues, type RegisterInputField, type RegisterPasswordPolicy, type RegisterSubmitOutcome, type RegisterSubmitValues, RegisterTestIds, ResetPasswordError, ResetPasswordForm, type ResetPasswordFormLabels, type ResetPasswordFormProps, type RoleRoute, type RoleRouteTable, type UseBffAuthOptions, type UseBffAuthResult, type UseBffForgotPasswordOptions, type UseBffLoginConfigResult, type UseBffResetPasswordOptions, type UseChangePasswordArgs, type UseChangePasswordResult, type UseDemoCredentialsOptions, type UseDemoCredentialsResult, type UseDevicePinDisableArgs, type UseDevicePinDisableResult, type UseDevicePinEnrollArgs, type UseDevicePinEnrollResult, type UseDevicePinUnlockArgs, type UseDevicePinUnlockResult, type UseForgotPasswordSubmitArgs, type UseForgotPasswordSubmitResult, type UseOtpLoginOptions, type UseOtpLoginResult, type UsePasskeyCeremonyOptions, type UsePasskeyCeremonyResult, type UsePinLoginOptions, type UsePinLoginResult, type UsePreferredMethodSettingArgs, type UsePreferredMethodSettingResult, type UseRegisterFormArgs, type UseRegisterFormResult, type UseResetPasswordFormArgs, type UseResetPasswordFormResult, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createBffChangePasswordClient, createPreferencesClient, defaultAuthTheme, isAllowedPinDigits, isPasswordValid, isRegisterPasswordStrong, isValidForgotPasswordEmail, performBffLogout, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolveAccountList, resolveDemoAccounts, resolveDemoCredentials, resolvePostLoginRoute, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useChangePassword, useDemoCredentials, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePasskeyCeremony, usePinLogin, usePreferredMethodSetting, useRegisterForm, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
2864
+ export { type AccountSettingsChangePasswordConfig, type AccountSettingsDevicePinConfig, type AccountSettingsLabels, type AccountSettingsPasskeysConfig, type AccountSettingsPreferredMethodConfig, AccountSettingsScreen, type AccountSettingsScreenProps, AuthScreen, type AuthScreenProps, AuthTestIds, type AuthTheme, type AuthThemeColors, AuthThemeProvider, type AuthThemeProviderProps, type AuthThemeRadii, type AuthThemeSpacing, type AuthThemeTypography, BffAuthStatus, type BffDeviceState, type BffLoginConfig, type BffLogoutClient, CHANGE_PASSWORD_ENDPOINT, type ChangePasswordCapableClient, ChangePasswordCard, type ChangePasswordCardProps, ChangePasswordErrorKey, type ChangePasswordRequest, type ChangePasswordResult, type CreateBffAuthClientOptions, type CreateBffChangePasswordClientOptions, DEFAULT_ACCOUNT_SETTINGS_LABELS, DEFAULT_AUTH_CARD_MAX_WIDTH, DEFAULT_DEMO_CREDENTIALS_HINT_LABELS, DEFAULT_DEVICE_PIN_ENROLL_LABELS, DEFAULT_DEVICE_PIN_SETTINGS_LABELS, DEFAULT_DEVICE_PIN_UNLOCK_LABELS, DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS, DEFAULT_FORGOT_PASSWORD_LABELS, DEFAULT_LOGIN_LABELS, DEFAULT_OTP_LABELS, DEFAULT_PASSKEY_LOGIN_LABELS, DEFAULT_PASSKEY_SETTINGS_LABELS, DEFAULT_PIN_LABELS, DEFAULT_PREFERRED_METHOD_HINT_LABELS, DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS, DEFAULT_REGISTER_LABELS, DEFAULT_RESET_PASSWORD_LABELS, DEVICE_PIN_ALLOWED_DIGITS, DEVICE_PIN_DEFAULT_DIGITS, DemoCredentialsHint, type DemoCredentialsHintLabels, type DemoCredentialsHintProps, DemoCredentialsHintVariant, type DemoCredentialsHintWiring, type DemoCredentialsLoginFormProps, type DevicePinCapableClient, type DevicePinDisableCapableClient, type DevicePinEnrollCapableClient, DevicePinEnrollErrorKey, DevicePinEnrollForm, type DevicePinEnrollFormProps, type DevicePinEnrollLabels, type DevicePinEnrollResult, DevicePinErrorKey, DevicePinInput, type DevicePinInputProps, DevicePinLengthPicker, type DevicePinLengthPickerProps, DevicePinOffer, type DevicePinOfferProps, DevicePinSettingsCard, type DevicePinSettingsCardProps, type DevicePinSettingsLabels, type DevicePinUnlockCapableClient, type DevicePinUnlockLabels, type DevicePinUnlockResult, DevicePinUnlockScreen, type DevicePinUnlockScreenProps, type DevicePinUnlockedUser, ForgotPasswordFields, type ForgotPasswordFieldsLabels, type ForgotPasswordFieldsProps, ForgotPasswordForm, type ForgotPasswordFormLabels, type ForgotPasswordFormProps, type LoginConfigCapableClient, LoginForm, type LoginFormLabels, type LoginFormProps, OtpForm, type OtpFormLabels, type OtpFormProps, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasskeyCeremonyMode, PasskeyCeremonyStatus, type PasskeyErrorCode, PasskeyLoginButton, type PasskeyLoginButtonProps, type PasskeyLoginLabels, PasskeySettingsCard, type PasskeySettingsCardProps, type PasskeySettingsLabels, PasswordPolicyError, type PerformBffLogoutOptions, PinForm, type PinFormLabels, type PinFormProps, type PreferencesClientOptions, type PreferredMethodClient, PreferredMethodHint, type PreferredMethodHintLabels, type PreferredMethodHintProps, PreferredMethodSettingsCard, type PreferredMethodSettingsCardProps, type PreferredMethodSettingsLabels, PrefillIntent, RegisterErrorCode, type RegisterField, type RegisterFieldLabels, RegisterForm, type RegisterFormLabels, type RegisterFormProps, type RegisterFormValues, type RegisterInputField, type RegisterPasswordPolicy, type RegisterSubmitOutcome, type RegisterSubmitValues, RegisterTestIds, ResetPasswordError, ResetPasswordForm, type ResetPasswordFormLabels, type ResetPasswordFormProps, type RoleRoute, type RoleRouteTable, type SplitName, type UseBffAuthOptions, type UseBffAuthResult, type UseBffForgotPasswordOptions, type UseBffLoginConfigResult, type UseBffResetPasswordOptions, type UseChangePasswordArgs, type UseChangePasswordResult, type UseDemoCredentialsOptions, type UseDemoCredentialsResult, type UseDevicePinDisableArgs, type UseDevicePinDisableResult, type UseDevicePinEnrollArgs, type UseDevicePinEnrollResult, type UseDevicePinUnlockArgs, type UseDevicePinUnlockResult, type UseForgotPasswordSubmitArgs, type UseForgotPasswordSubmitResult, type UseOtpLoginOptions, type UseOtpLoginResult, type UsePasskeyCeremonyOptions, type UsePasskeyCeremonyResult, type UsePinLoginOptions, type UsePinLoginResult, type UsePreferredMethodSettingArgs, type UsePreferredMethodSettingResult, type UseRegisterFormArgs, type UseRegisterFormResult, type UseResetPasswordFormArgs, type UseResetPasswordFormResult, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createBffChangePasswordClient, createPreferencesClient, defaultAuthTheme, deriveUsernameFromEmail, isAllowedPinDigits, isPasswordValid, isRegisterPasswordStrong, isValidForgotPasswordEmail, performBffLogout, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolveAccountList, resolveDemoAccounts, resolveDemoCredentials, resolvePostLoginRoute, splitFullName, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useChangePassword, useDemoCredentials, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePasskeyCeremony, usePinLogin, usePreferredMethodSetting, useRegisterForm, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
package/dist/index.js CHANGED
@@ -342,6 +342,7 @@ var DEFAULT_REGISTER_LABELS = {
342
342
  submit: "Create account",
343
343
  submitHint: "Creates your account",
344
344
  submitting: "Creating account...",
345
+ fullName: field("Your name", "Enter your full name"),
345
346
  fields: {
346
347
  firstName: field("First name", "Enter your first name"),
347
348
  lastName: field("Last name", "Enter your last name"),
@@ -618,7 +619,11 @@ function useLoginSubmit({
618
619
  invalidCredentialsLabel
619
620
  }) {
620
621
  const [errorText, setErrorText] = react.useState(null);
622
+ const inFlight = react.useRef(false);
621
623
  const runLogin = react.useCallback(async () => {
624
+ if (inFlight.current) {
625
+ return;
626
+ }
622
627
  setErrorText(null);
623
628
  const trimmedUsername = username.trim();
624
629
  const hasMissingField = trimmedUsername.length === 0 || password.length === 0;
@@ -626,11 +631,14 @@ function useLoginSubmit({
626
631
  setErrorText(missingFieldsLabel);
627
632
  return;
628
633
  }
634
+ inFlight.current = true;
629
635
  try {
630
636
  const user = await login({ username: trimmedUsername, password });
631
637
  onSuccess(user);
632
638
  } catch {
633
639
  setErrorText(invalidCredentialsLabel);
640
+ } finally {
641
+ inFlight.current = false;
634
642
  }
635
643
  }, [username, password, login, onSuccess, missingFieldsLabel, invalidCredentialsLabel]);
636
644
  const handleSubmit = react.useCallback(() => {
@@ -4094,6 +4102,18 @@ var FIELDS = [
4094
4102
  { key: "confirmPassword", testId: RegisterTestIds.confirmPasswordInput, secure: true },
4095
4103
  { key: "tenantName", testId: RegisterTestIds.tenantNameInput }
4096
4104
  ];
4105
+ var COMPACT_FIELDS = [
4106
+ { key: "firstName", testId: RegisterTestIds.firstNameInput, autoComplete: "name" },
4107
+ { key: "email", testId: RegisterTestIds.emailInput, autoComplete: "email", keyboardType: "email-address" },
4108
+ { key: "password", testId: RegisterTestIds.passwordInput, secure: true },
4109
+ { key: "tenantName", testId: RegisterTestIds.tenantNameInput }
4110
+ ];
4111
+ function copyFor(key, labels, compact) {
4112
+ if (compact && key === "firstName" && labels.fullName !== void 0) {
4113
+ return labels.fullName;
4114
+ }
4115
+ return labels.fields[key];
4116
+ }
4097
4117
  var OFF_SCREEN = -9999;
4098
4118
  var HONEYPOT_SIZE = 1;
4099
4119
  var HONEYPOT_PLACEHOLDER = "Website";
@@ -4115,11 +4135,12 @@ function RegisterFormFields({
4115
4135
  styles: styles3,
4116
4136
  onChange,
4117
4137
  onSubmitEditing,
4118
- testIdPrefix
4138
+ testIdPrefix,
4139
+ compact = false
4119
4140
  }) {
4120
4141
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4121
- FIELDS.map((config) => {
4122
- const copy = labels.fields[config.key];
4142
+ (compact ? COMPACT_FIELDS : FIELDS).map((config) => {
4143
+ const copy = copyFor(config.key, labels, compact);
4123
4144
  return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.fieldGroup, children: [
4124
4145
  /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.label, children: copy.label }),
4125
4146
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -4278,6 +4299,29 @@ function mapRegisterErrorCode(error) {
4278
4299
  return match === void 0 ? "validationFailed" /* ValidationFailed */ : match[1];
4279
4300
  }
4280
4301
 
4302
+ // src/hooks/registerCompact.ts
4303
+ var WHITESPACE_RUN = /\s+/;
4304
+ var UNSAFE_USERNAME_CHARS = /[^a-z0-9._-]/g;
4305
+ var USERNAME_REPLACEMENT = "_";
4306
+ function splitFullName(fullName) {
4307
+ const words = fullName.trim().split(WHITESPACE_RUN).filter((word) => word !== "");
4308
+ const [first = "", ...rest] = words;
4309
+ return { firstName: first, lastName: rest.length > 0 ? rest.join(" ") : first };
4310
+ }
4311
+ function deriveUsernameFromEmail(email) {
4312
+ return email.trim().toLowerCase().replace(UNSAFE_USERNAME_CHARS, USERNAME_REPLACEMENT);
4313
+ }
4314
+ function expandCompactRegisterValues(values) {
4315
+ const { firstName, lastName } = splitFullName(values.firstName);
4316
+ return {
4317
+ ...values,
4318
+ firstName,
4319
+ lastName,
4320
+ username: deriveUsernameFromEmail(values.email),
4321
+ confirmPassword: values.password
4322
+ };
4323
+ }
4324
+
4281
4325
  // src/hooks/useRegisterForm.ts
4282
4326
  var EMPTY_VALUES = {
4283
4327
  firstName: "",
@@ -4303,7 +4347,8 @@ function toSubmitValues(values) {
4303
4347
  function useRegisterForm({
4304
4348
  onSubmit,
4305
4349
  passwordPolicy = isRegisterPasswordStrong,
4306
- onSubmitAttempt
4350
+ onSubmitAttempt,
4351
+ compact = false
4307
4352
  }) {
4308
4353
  const [state, setState] = react.useState(EMPTY_VALUES);
4309
4354
  const [isSubmitting, setIsSubmitting] = react.useState(false);
@@ -4317,7 +4362,8 @@ function useRegisterForm({
4317
4362
  return { ok: false, error: "inFlight" /* InFlight */ };
4318
4363
  }
4319
4364
  onSubmitAttempt?.();
4320
- const trimmed = trimRegisterValues(state);
4365
+ const trimmedRaw = trimRegisterValues(state);
4366
+ const trimmed = compact ? expandCompactRegisterValues(trimmedRaw) : trimmedRaw;
4321
4367
  const refusal = trimmed.website === "" ? validateRegisterValues(trimmed, passwordPolicy) : "failed" /* Failed */;
4322
4368
  if (refusal !== null) {
4323
4369
  setError(refusal);
@@ -4337,7 +4383,7 @@ function useRegisterForm({
4337
4383
  inFlight.current = false;
4338
4384
  setIsSubmitting(false);
4339
4385
  }
4340
- }, [onSubmit, onSubmitAttempt, passwordPolicy, state]);
4386
+ }, [compact, onSubmit, onSubmitAttempt, passwordPolicy, state]);
4341
4387
  return { state, setField, submit, isSubmitting, error };
4342
4388
  }
4343
4389
  function RegisterForm({
@@ -4349,7 +4395,8 @@ function RegisterForm({
4349
4395
  labels: labelsProp,
4350
4396
  theme: themeProp,
4351
4397
  footer,
4352
- testIdPrefix
4398
+ testIdPrefix,
4399
+ compact = false
4353
4400
  }) {
4354
4401
  const theme = useAuthTheme(themeProp);
4355
4402
  const styles3 = useAuthStyles(theme);
@@ -4360,7 +4407,8 @@ function RegisterForm({
4360
4407
  const { state, setField, submit, isSubmitting } = useRegisterForm({
4361
4408
  onSubmit,
4362
4409
  onSubmitAttempt,
4363
- passwordPolicy
4410
+ passwordPolicy,
4411
+ compact
4364
4412
  });
4365
4413
  const handlePress = react.useCallback(async () => {
4366
4414
  routeRegisterOutcome(await submit(), { onSuccess, onError });
@@ -4372,6 +4420,7 @@ function RegisterForm({
4372
4420
  /* @__PURE__ */ jsxRuntime.jsx(
4373
4421
  RegisterFormFields,
4374
4422
  {
4423
+ compact,
4375
4424
  disabled: isSubmitting,
4376
4425
  labels,
4377
4426
  styles: styles3,
@@ -4606,6 +4655,7 @@ exports.createBffAuthClient = createBffAuthClient;
4606
4655
  exports.createBffChangePasswordClient = createBffChangePasswordClient;
4607
4656
  exports.createPreferencesClient = createPreferencesClient;
4608
4657
  exports.defaultAuthTheme = defaultAuthTheme;
4658
+ exports.deriveUsernameFromEmail = deriveUsernameFromEmail;
4609
4659
  exports.isAllowedPinDigits = isAllowedPinDigits;
4610
4660
  exports.isPasswordValid = isPasswordValid;
4611
4661
  exports.isRegisterPasswordStrong = isRegisterPasswordStrong;
@@ -4619,6 +4669,7 @@ exports.resolveAccountList = resolveAccountList;
4619
4669
  exports.resolveDemoAccounts = resolveDemoAccounts;
4620
4670
  exports.resolveDemoCredentials = resolveDemoCredentials;
4621
4671
  exports.resolvePostLoginRoute = resolvePostLoginRoute;
4672
+ exports.splitFullName = splitFullName;
4622
4673
  exports.startPasskeyLogin = startPasskeyLogin;
4623
4674
  exports.startPasskeyRegistration = startPasskeyRegistration;
4624
4675
  exports.syncPreferredMethodFromServer = syncPreferredMethodFromServer;