@dloizides/auth-web 1.22.0 → 1.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -305,7 +305,8 @@ var DEFAULT_RESET_PASSWORD_LABELS = {
305
305
  errorWeakPassword: "Use at least 8 characters with an uppercase letter, a lowercase letter and a digit.",
306
306
  errorMismatch: "The passwords do not match.",
307
307
  errorTokenInvalid: "This reset link is invalid or has expired. Request a new one.",
308
- errorNetwork: "Something went wrong. Please try again."
308
+ errorNetwork: "Something went wrong. Please try again.",
309
+ errorRateLimited: "Too many attempts. Wait a minute and try again."
309
310
  };
310
311
 
311
312
  // src/components/labels/accountSettingsLabels.ts
@@ -342,6 +343,8 @@ var DEFAULT_REGISTER_LABELS = {
342
343
  submitHint: "Creates your account",
343
344
  submitting: "Creating account...",
344
345
  fullName: field("Your name", "Enter your full name"),
346
+ checkEmailTitle: "Check your email",
347
+ checkEmailBody: "If this address can be used, a link to finish signing up is on its way.",
345
348
  fields: {
346
349
  firstName: field("First name", "Enter your first name"),
347
350
  lastName: field("Last name", "Enter your last name"),
@@ -354,6 +357,19 @@ var DEFAULT_REGISTER_LABELS = {
354
357
  };
355
358
 
356
359
  // src/components/labels/verifyEmailLabels.ts
360
+ var DEFAULT_VERIFY_NEW_PASSWORD_LABELS = {
361
+ ...DEFAULT_RESET_PASSWORD_LABELS,
362
+ title: "Set a new password",
363
+ description: "To finish signing in, choose a new password for your account.",
364
+ submit: "Save and sign in",
365
+ submitting: "Saving..."
366
+ };
367
+ var DEFAULT_VERIFY_SIGN_IN_LABELS = {
368
+ title: "Your email is verified",
369
+ body: "We could not sign you in automatically. Please sign in with your password.",
370
+ action: "Sign in",
371
+ actionHint: "Go to the sign in page"
372
+ };
357
373
  var DEFAULT_VERIFY_EMAIL_LABELS = {
358
374
  loadingTitle: "Verifying your email...",
359
375
  loadingHint: "Please wait while we verify your address.",
@@ -375,7 +391,10 @@ var DEFAULT_VERIFY_EMAIL_LABELS = {
375
391
  resendMissingEmail: "Enter your email address.",
376
392
  resendSubmit: "Send link",
377
393
  resendSubmitHint: "Sends a new verification email",
378
- resendConfirmation: "If that address has an account, a new verification link is on its way."
394
+ resendConfirmation: "If that address has an account, a new verification link is on its way.",
395
+ errorRateLimited: "Too many attempts. Wait a minute and try again.",
396
+ newPassword: DEFAULT_VERIFY_NEW_PASSWORD_LABELS,
397
+ signIn: DEFAULT_VERIFY_SIGN_IN_LABELS
379
398
  };
380
399
 
381
400
  // src/components/testIds.ts
@@ -474,6 +493,8 @@ var AuthTestIds = {
474
493
  verifyEmailSuccess: "auth-verify-email-success",
475
494
  verifyEmailContinue: "auth-verify-email-continue",
476
495
  verifyEmailError: "auth-verify-email-error",
496
+ verifyEmailSignIn: "auth-verify-email-sign-in",
497
+ verifyEmailSignInContinue: "auth-verify-email-sign-in-continue",
477
498
  verifyEmailResendCta: "auth-verify-email-resend-cta",
478
499
  verifyEmailResendForm: "auth-verify-email-resend-form",
479
500
  verifyEmailResendEmail: "auth-verify-email-resend-email",
@@ -575,6 +596,12 @@ function useAuthStyles(theme) {
575
596
  marginTop: spacing.xs,
576
597
  color: colors.danger
577
598
  },
599
+ errorBody: {
600
+ fontSize: typography.body,
601
+ marginTop: spacing.xs,
602
+ marginBottom: spacing.md,
603
+ color: colors.danger
604
+ },
578
605
  successText: {
579
606
  fontSize: typography.body,
580
607
  lineHeight: typography.body * 1.4,
@@ -1268,8 +1295,107 @@ var ResetPasswordError = /* @__PURE__ */ ((ResetPasswordError2) => {
1268
1295
  ResetPasswordError2["Mismatch"] = "mismatch";
1269
1296
  ResetPasswordError2["TokenInvalid"] = "tokenInvalid";
1270
1297
  ResetPasswordError2["Network"] = "network";
1298
+ ResetPasswordError2["RateLimited"] = "rateLimited";
1271
1299
  return ResetPasswordError2;
1272
1300
  })(ResetPasswordError || {});
1301
+ function errorMessage(errorKey, labels) {
1302
+ switch (errorKey) {
1303
+ case "empty" /* Empty */:
1304
+ return labels.errorEmpty;
1305
+ case "weakPassword" /* WeakPassword */:
1306
+ return labels.errorWeakPassword;
1307
+ case "mismatch" /* Mismatch */:
1308
+ return labels.errorMismatch;
1309
+ case "tokenInvalid" /* TokenInvalid */:
1310
+ return labels.errorTokenInvalid;
1311
+ case "network" /* Network */:
1312
+ return labels.errorNetwork;
1313
+ case "rateLimited" /* RateLimited */:
1314
+ return labels.errorRateLimited ?? labels.errorNetwork;
1315
+ default:
1316
+ return null;
1317
+ }
1318
+ }
1319
+ function ResetPasswordFields({
1320
+ form,
1321
+ labels,
1322
+ styles: styles3,
1323
+ theme,
1324
+ testIdPrefix,
1325
+ newPasswordRef,
1326
+ onSubmitEditing
1327
+ }) {
1328
+ const message = errorMessage(form.errorKey, labels);
1329
+ const submitButtonStyle = form.isSubmitting ? [styles3.primaryButton, styles3.primaryButtonDisabled] : styles3.primaryButton;
1330
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1331
+ /* @__PURE__ */ jsx(Text, { style: styles3.title, children: labels.title }),
1332
+ /* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: labels.description }),
1333
+ /* @__PURE__ */ jsxs(View, { style: styles3.fieldGroup, children: [
1334
+ /* @__PURE__ */ jsx(Text, { style: styles3.label, children: labels.newPasswordLabel }),
1335
+ /* @__PURE__ */ jsx(
1336
+ TextInput,
1337
+ {
1338
+ ref: newPasswordRef,
1339
+ secureTextEntry: true,
1340
+ accessibilityHint: labels.newPasswordPlaceholder,
1341
+ accessibilityLabel: labels.newPasswordLabel,
1342
+ autoCapitalize: "none",
1343
+ autoCorrect: false,
1344
+ editable: !form.isSubmitting,
1345
+ placeholder: labels.newPasswordPlaceholder,
1346
+ placeholderTextColor: theme.colors.textSecondary,
1347
+ style: styles3.input,
1348
+ testID: withTestIdPrefix(AuthTestIds.resetPasswordNewInput, testIdPrefix),
1349
+ value: form.newPassword,
1350
+ onChangeText: form.setNewPassword,
1351
+ onSubmitEditing
1352
+ }
1353
+ )
1354
+ ] }),
1355
+ /* @__PURE__ */ jsxs(View, { style: styles3.fieldGroup, children: [
1356
+ /* @__PURE__ */ jsx(Text, { style: styles3.label, children: labels.confirmPasswordLabel }),
1357
+ /* @__PURE__ */ jsx(
1358
+ TextInput,
1359
+ {
1360
+ secureTextEntry: true,
1361
+ accessibilityHint: labels.confirmPasswordPlaceholder,
1362
+ accessibilityLabel: labels.confirmPasswordLabel,
1363
+ autoCapitalize: "none",
1364
+ autoCorrect: false,
1365
+ editable: !form.isSubmitting,
1366
+ placeholder: labels.confirmPasswordPlaceholder,
1367
+ placeholderTextColor: theme.colors.textSecondary,
1368
+ style: styles3.input,
1369
+ testID: withTestIdPrefix(AuthTestIds.resetPasswordConfirmInput, testIdPrefix),
1370
+ value: form.confirmPassword,
1371
+ onChangeText: form.setConfirmPassword,
1372
+ onSubmitEditing
1373
+ }
1374
+ )
1375
+ ] }),
1376
+ message !== null ? /* @__PURE__ */ jsx(
1377
+ Text,
1378
+ {
1379
+ style: styles3.errorText,
1380
+ testID: withTestIdPrefix(AuthTestIds.resetPasswordError, testIdPrefix),
1381
+ children: message
1382
+ }
1383
+ ) : null,
1384
+ /* @__PURE__ */ jsx(
1385
+ TouchableOpacity,
1386
+ {
1387
+ accessibilityHint: labels.submit,
1388
+ accessibilityLabel: form.isSubmitting ? labels.submitting : labels.submit,
1389
+ accessibilityRole: "button",
1390
+ disabled: form.isSubmitting,
1391
+ style: submitButtonStyle,
1392
+ testID: withTestIdPrefix(AuthTestIds.resetPasswordSubmitButton, testIdPrefix),
1393
+ onPress: form.submit,
1394
+ children: form.isSubmitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.submit })
1395
+ }
1396
+ )
1397
+ ] });
1398
+ }
1273
1399
 
1274
1400
  // src/password/PasswordPolicyError.ts
1275
1401
  var PasswordPolicyError = /* @__PURE__ */ ((PasswordPolicyError2) => {
@@ -1408,22 +1534,6 @@ function useResetPasswordForm({
1408
1534
  submit
1409
1535
  };
1410
1536
  }
1411
- function errorMessage(errorKey, labels) {
1412
- switch (errorKey) {
1413
- case "empty" /* Empty */:
1414
- return labels.errorEmpty;
1415
- case "weakPassword" /* WeakPassword */:
1416
- return labels.errorWeakPassword;
1417
- case "mismatch" /* Mismatch */:
1418
- return labels.errorMismatch;
1419
- case "tokenInvalid" /* TokenInvalid */:
1420
- return labels.errorTokenInvalid;
1421
- case "network" /* Network */:
1422
- return labels.errorNetwork;
1423
- default:
1424
- return null;
1425
- }
1426
- }
1427
1537
  function ResetPasswordForm({
1428
1538
  client,
1429
1539
  token,
@@ -1439,78 +1549,21 @@ function ResetPasswordForm({
1439
1549
  [labelsProp]
1440
1550
  );
1441
1551
  const form = useResetPasswordForm({ client, token, onSuccess });
1442
- const message = errorMessage(form.errorKey, labels);
1443
- const submitButtonStyle = form.isSubmitting ? [styles3.primaryButton, styles3.primaryButtonDisabled] : styles3.primaryButton;
1444
- return /* @__PURE__ */ jsx(View, { style: styles3.screen, children: /* @__PURE__ */ jsxs(
1552
+ return /* @__PURE__ */ jsx(View, { style: styles3.screen, children: /* @__PURE__ */ jsx(
1445
1553
  View,
1446
1554
  {
1447
1555
  style: styles3.card,
1448
1556
  testID: withTestIdPrefix(AuthTestIds.resetPasswordForm, testIdPrefix),
1449
- children: [
1450
- /* @__PURE__ */ jsx(Text, { style: styles3.title, children: labels.title }),
1451
- /* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: labels.description }),
1452
- /* @__PURE__ */ jsxs(View, { style: styles3.fieldGroup, children: [
1453
- /* @__PURE__ */ jsx(Text, { style: styles3.label, children: labels.newPasswordLabel }),
1454
- /* @__PURE__ */ jsx(
1455
- TextInput,
1456
- {
1457
- secureTextEntry: true,
1458
- accessibilityHint: labels.newPasswordPlaceholder,
1459
- accessibilityLabel: labels.newPasswordLabel,
1460
- autoCapitalize: "none",
1461
- autoCorrect: false,
1462
- editable: !form.isSubmitting,
1463
- placeholder: labels.newPasswordPlaceholder,
1464
- placeholderTextColor: theme.colors.textSecondary,
1465
- style: styles3.input,
1466
- testID: withTestIdPrefix(AuthTestIds.resetPasswordNewInput, testIdPrefix),
1467
- value: form.newPassword,
1468
- onChangeText: form.setNewPassword
1469
- }
1470
- )
1471
- ] }),
1472
- /* @__PURE__ */ jsxs(View, { style: styles3.fieldGroup, children: [
1473
- /* @__PURE__ */ jsx(Text, { style: styles3.label, children: labels.confirmPasswordLabel }),
1474
- /* @__PURE__ */ jsx(
1475
- TextInput,
1476
- {
1477
- secureTextEntry: true,
1478
- accessibilityHint: labels.confirmPasswordPlaceholder,
1479
- accessibilityLabel: labels.confirmPasswordLabel,
1480
- autoCapitalize: "none",
1481
- autoCorrect: false,
1482
- editable: !form.isSubmitting,
1483
- placeholder: labels.confirmPasswordPlaceholder,
1484
- placeholderTextColor: theme.colors.textSecondary,
1485
- style: styles3.input,
1486
- testID: withTestIdPrefix(AuthTestIds.resetPasswordConfirmInput, testIdPrefix),
1487
- value: form.confirmPassword,
1488
- onChangeText: form.setConfirmPassword
1489
- }
1490
- )
1491
- ] }),
1492
- message !== null ? /* @__PURE__ */ jsx(
1493
- Text,
1494
- {
1495
- style: styles3.errorText,
1496
- testID: withTestIdPrefix(AuthTestIds.resetPasswordError, testIdPrefix),
1497
- children: message
1498
- }
1499
- ) : null,
1500
- /* @__PURE__ */ jsx(
1501
- TouchableOpacity,
1502
- {
1503
- accessibilityHint: labels.submit,
1504
- accessibilityLabel: form.isSubmitting ? labels.submitting : labels.submit,
1505
- accessibilityRole: "button",
1506
- disabled: form.isSubmitting,
1507
- style: submitButtonStyle,
1508
- testID: withTestIdPrefix(AuthTestIds.resetPasswordSubmitButton, testIdPrefix),
1509
- onPress: form.submit,
1510
- children: form.isSubmitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.submit })
1511
- }
1512
- )
1513
- ]
1557
+ children: /* @__PURE__ */ jsx(
1558
+ ResetPasswordFields,
1559
+ {
1560
+ form,
1561
+ labels,
1562
+ styles: styles3,
1563
+ testIdPrefix,
1564
+ theme
1565
+ }
1566
+ )
1514
1567
  }
1515
1568
  ) });
1516
1569
  }
@@ -4139,7 +4192,8 @@ var RegisterTestIds = {
4139
4192
  confirmPasswordInput: "register-confirm-password-input",
4140
4193
  tenantNameInput: "register-tenant-name-input",
4141
4194
  submitButton: "register-submit-button",
4142
- websiteInput: "register-website"
4195
+ websiteInput: "register-website",
4196
+ checkEmail: "register-check-email"
4143
4197
  };
4144
4198
  var FIELDS = [
4145
4199
  { key: "firstName", testId: RegisterTestIds.firstNameInput, autoComplete: "name" },
@@ -4261,6 +4315,14 @@ function routeRegisterOutcome(outcome, handlers) {
4261
4315
  }
4262
4316
  }
4263
4317
 
4318
+ // src/hooks/registerAccepted.ts
4319
+ function isRegisterAccepted(result) {
4320
+ if (typeof result !== "object" || result === null) {
4321
+ return false;
4322
+ }
4323
+ return result.accepted === true;
4324
+ }
4325
+
4264
4326
  // src/hooks/registerErrors.ts
4265
4327
  var MIN_PASSWORD_LENGTH = 8;
4266
4328
  var WHITESPACE_REGEX = /\s/;
@@ -4413,6 +4475,42 @@ function expandCompactRegisterValues(values) {
4413
4475
  };
4414
4476
  }
4415
4477
 
4478
+ // src/hooks/newIdempotencyKey.ts
4479
+ var HEX_RADIX = 16;
4480
+ var HEX_BYTE_LENGTH = 2;
4481
+ var KEY_BYTES = 16;
4482
+ var fallbackSequence = 0;
4483
+ function newIdempotencyKey() {
4484
+ const cryptoApi = globalThis.crypto;
4485
+ if (typeof cryptoApi?.randomUUID === "function") {
4486
+ return cryptoApi.randomUUID();
4487
+ }
4488
+ if (typeof cryptoApi?.getRandomValues === "function") {
4489
+ const bytes = cryptoApi.getRandomValues(new Uint8Array(KEY_BYTES));
4490
+ return Array.from(bytes, (byte) => byte.toString(HEX_RADIX).padStart(HEX_BYTE_LENGTH, "0")).join("");
4491
+ }
4492
+ fallbackSequence += 1;
4493
+ return `${Date.now().toString(HEX_RADIX)}-${String(fallbackSequence)}`;
4494
+ }
4495
+
4496
+ // src/hooks/useRegisterSubmitMeta.ts
4497
+ function useRegisterSubmitMeta() {
4498
+ const openedAt = useRef(Date.now());
4499
+ const key = useRef(null);
4500
+ return useMemo(
4501
+ () => ({
4502
+ next: () => {
4503
+ key.current ?? (key.current = newIdempotencyKey());
4504
+ return { idempotencyKey: key.current, formElapsedMs: Date.now() - openedAt.current };
4505
+ },
4506
+ resetKey: () => {
4507
+ key.current = null;
4508
+ }
4509
+ }),
4510
+ []
4511
+ );
4512
+ }
4513
+
4416
4514
  // src/hooks/useRegisterForm.ts
4417
4515
  var EMPTY_VALUES = {
4418
4516
  firstName: "",
@@ -4424,6 +4522,9 @@ var EMPTY_VALUES = {
4424
4522
  tenantName: "",
4425
4523
  website: ""
4426
4524
  };
4525
+ function withoutPasswords(values) {
4526
+ return { ...values, password: "", confirmPassword: "" };
4527
+ }
4427
4528
  function toSubmitValues(values) {
4428
4529
  return {
4429
4530
  firstName: values.firstName,
@@ -4439,15 +4540,18 @@ function useRegisterForm({
4439
4540
  onSubmit,
4440
4541
  passwordPolicy = isRegisterPasswordStrong,
4441
4542
  onSubmitAttempt,
4442
- compact = false
4543
+ compact = false,
4544
+ sharedRegistration = false
4443
4545
  }) {
4444
4546
  const [state, setState] = useState(EMPTY_VALUES);
4445
4547
  const [isSubmitting, setIsSubmitting] = useState(false);
4446
4548
  const [error, setError] = useState(null);
4447
4549
  const inFlight = useRef(false);
4550
+ const submitMeta = useRegisterSubmitMeta();
4448
4551
  const setField = useCallback((field2, value) => {
4552
+ submitMeta.resetKey();
4449
4553
  setState((prev) => ({ ...prev, [field2]: value }));
4450
- }, []);
4554
+ }, [submitMeta]);
4451
4555
  const submit = useCallback(async () => {
4452
4556
  if (inFlight.current) {
4453
4557
  return { ok: false, error: "inFlight" /* InFlight */ };
@@ -4464,7 +4568,11 @@ function useRegisterForm({
4464
4568
  setError(null);
4465
4569
  setIsSubmitting(true);
4466
4570
  try {
4467
- const result = await onSubmit(toSubmitValues(trimmed));
4571
+ const values = toSubmitValues(trimmed);
4572
+ const result = await (sharedRegistration ? onSubmit(values, submitMeta.next()) : onSubmit(values));
4573
+ if (sharedRegistration && isRegisterAccepted(result)) {
4574
+ setState(withoutPasswords);
4575
+ }
4468
4576
  return { ok: true, result };
4469
4577
  } catch (caught) {
4470
4578
  const code = mapRegisterErrorCode(caught);
@@ -4474,10 +4582,10 @@ function useRegisterForm({
4474
4582
  inFlight.current = false;
4475
4583
  setIsSubmitting(false);
4476
4584
  }
4477
- }, [compact, onSubmit, onSubmitAttempt, passwordPolicy, state]);
4585
+ }, [compact, onSubmit, onSubmitAttempt, passwordPolicy, sharedRegistration, state, submitMeta]);
4478
4586
  return { state, setField, submit, isSubmitting, error };
4479
4587
  }
4480
- function RegisterForm({
4588
+ function RegisterFormCore({
4481
4589
  onSubmit,
4482
4590
  onSuccess,
4483
4591
  onError,
@@ -4487,7 +4595,8 @@ function RegisterForm({
4487
4595
  theme: themeProp,
4488
4596
  footer,
4489
4597
  testIdPrefix,
4490
- compact = false
4598
+ compact = false,
4599
+ sharedRegistration
4491
4600
  }) {
4492
4601
  const theme = useAuthTheme(themeProp);
4493
4602
  const styles3 = useAuthStyles(theme);
@@ -4499,7 +4608,8 @@ function RegisterForm({
4499
4608
  onSubmit,
4500
4609
  onSubmitAttempt,
4501
4610
  passwordPolicy,
4502
- compact
4611
+ compact,
4612
+ sharedRegistration
4503
4613
  });
4504
4614
  const handlePress = useCallback(async () => {
4505
4615
  routeRegisterOutcome(await submit(), { onSuccess, onError });
@@ -4537,6 +4647,9 @@ function RegisterForm({
4537
4647
  footer
4538
4648
  ] }) });
4539
4649
  }
4650
+ function RegisterForm(props) {
4651
+ return /* @__PURE__ */ jsx(RegisterFormCore, { ...props, sharedRegistration: false });
4652
+ }
4540
4653
  async function lazyFetchHttpClient(request) {
4541
4654
  const fetchImpl = typeof fetch === "function" ? fetch.bind(globalThis) : void 0;
4542
4655
  if (fetchImpl === void 0) {
@@ -4672,6 +4785,11 @@ function createBffChangePasswordClient(options = {}) {
4672
4785
  }
4673
4786
  };
4674
4787
  }
4788
+ function useFocusOnMount(ref) {
4789
+ useEffect(() => {
4790
+ ref.current?.focus();
4791
+ }, [ref]);
4792
+ }
4675
4793
  function useResendVerification({ client, verifyUrlTemplate }) {
4676
4794
  const [email, setEmail] = useState("");
4677
4795
  const [missingEmail, setMissingEmail] = useState(false);
@@ -4691,6 +4809,11 @@ function useResendVerification({ client, verifyUrlTemplate }) {
4691
4809
  }, [client, email, verifyUrlTemplate]);
4692
4810
  return { email, setEmail, missingEmail, submitting, confirmed, submit };
4693
4811
  }
4812
+ function ResendConfirmation({ style, testID, text }) {
4813
+ const ref = useRef(null);
4814
+ useFocusOnMount(ref);
4815
+ return /* @__PURE__ */ jsx(View, { ref, accessible: true, accessibilityLiveRegion: "polite", focusable: true, testID, children: /* @__PURE__ */ jsx(Text, { style, children: text }) });
4816
+ }
4694
4817
  function VerifyEmailResendForm({
4695
4818
  client,
4696
4819
  labels,
@@ -4702,7 +4825,7 @@ function VerifyEmailResendForm({
4702
4825
  const resend = useResendVerification({ client, verifyUrlTemplate });
4703
4826
  const id = (base) => withTestIdPrefix(base, testIdPrefix);
4704
4827
  if (resend.confirmed) {
4705
- return /* @__PURE__ */ jsx(Text, { style: styles3.successText, testID: id(AuthTestIds.verifyEmailResendConfirmation), children: labels.resendConfirmation });
4828
+ return /* @__PURE__ */ jsx(ResendConfirmation, { style: styles3.successText, testID: id(AuthTestIds.verifyEmailResendConfirmation), text: labels.resendConfirmation });
4706
4829
  }
4707
4830
  const submit = () => {
4708
4831
  void resend.submit();
@@ -4731,7 +4854,7 @@ function VerifyEmailResendForm({
4731
4854
  }
4732
4855
  )
4733
4856
  ] }),
4734
- resend.missingEmail ? /* @__PURE__ */ jsx(Text, { style: styles3.errorText, children: labels.resendMissingEmail }) : null,
4857
+ resend.missingEmail ? /* @__PURE__ */ jsx(Text, { style: styles3.errorBody, children: labels.resendMissingEmail }) : null,
4735
4858
  /* @__PURE__ */ jsx(
4736
4859
  TouchableOpacity,
4737
4860
  {
@@ -4755,19 +4878,155 @@ var VerifyEmailErrorCode = /* @__PURE__ */ ((VerifyEmailErrorCode2) => {
4755
4878
  VerifyEmailErrorCode2["TokenUsed"] = "TOKEN_USED";
4756
4879
  VerifyEmailErrorCode2["KeycloakUpdateFailed"] = "KEYCLOAK_UPDATE_FAILED";
4757
4880
  VerifyEmailErrorCode2["MissingToken"] = "MISSING_TOKEN";
4881
+ VerifyEmailErrorCode2["NewPasswordRequired"] = "NEW_PASSWORD_REQUIRED";
4882
+ VerifyEmailErrorCode2["WeakPassword"] = "WEAK_PASSWORD";
4883
+ VerifyEmailErrorCode2["RateLimited"] = "RATE_LIMITED";
4884
+ VerifyEmailErrorCode2["SignInFailed"] = "SIGN_IN_FAILED";
4758
4885
  VerifyEmailErrorCode2["Generic"] = "GENERIC";
4759
4886
  return VerifyEmailErrorCode2;
4760
4887
  })(VerifyEmailErrorCode || {});
4761
4888
 
4889
+ // src/verify/useVerifyNewPasswordForm.ts
4890
+ var GENERIC_FAILURE = { success: false, errorCode: "GENERIC" /* Generic */ };
4891
+ var DEAD_LINK_CODES = [
4892
+ "TOKEN_INVALID" /* TokenInvalid */,
4893
+ "TOKEN_EXPIRED" /* TokenExpired */,
4894
+ "TOKEN_USED" /* TokenUsed */,
4895
+ "SIGN_IN_FAILED" /* SignInFailed */
4896
+ ];
4897
+ function retryableError(code) {
4898
+ if (DEAD_LINK_CODES.includes(code)) {
4899
+ return null;
4900
+ }
4901
+ if (code === "WEAK_PASSWORD" /* WeakPassword */) {
4902
+ return "weakPassword" /* WeakPassword */;
4903
+ }
4904
+ return code === "RATE_LIMITED" /* RateLimited */ ? "rateLimited" /* RateLimited */ : "network" /* Network */;
4905
+ }
4906
+ function useVerifyNewPasswordForm({
4907
+ client,
4908
+ token,
4909
+ onSettled
4910
+ }) {
4911
+ const { state, setters } = useFormState();
4912
+ const [isSubmitting, setIsSubmitting] = useState(false);
4913
+ const inFlight = useRef(false);
4914
+ const send = useMemo(
4915
+ () => async (newPassword) => {
4916
+ if (inFlight.current) {
4917
+ return;
4918
+ }
4919
+ inFlight.current = true;
4920
+ setIsSubmitting(true);
4921
+ const result = await (client.setNewPassword?.(token, newPassword) ?? Promise.resolve(GENERIC_FAILURE)).catch(
4922
+ () => GENERIC_FAILURE
4923
+ );
4924
+ inFlight.current = false;
4925
+ setIsSubmitting(false);
4926
+ const formError = result.success ? null : retryableError(result.errorCode);
4927
+ if (formError === null) {
4928
+ onSettled(result);
4929
+ return;
4930
+ }
4931
+ setters.setErrorKey(formError);
4932
+ },
4933
+ [client, onSettled, setters, token]
4934
+ );
4935
+ return {
4936
+ ...state,
4937
+ setNewPassword: setters.setNewPassword,
4938
+ setConfirmPassword: setters.setConfirmPassword,
4939
+ isSubmitting,
4940
+ submit: () => runSubmit({
4941
+ newPassword: state.newPassword,
4942
+ confirmPassword: state.confirmPassword,
4943
+ token,
4944
+ setErrorKey: setters.setErrorKey,
4945
+ setHasInvalidToken: setters.setHasInvalidToken,
4946
+ mutate: (request) => {
4947
+ void send(request.newPassword);
4948
+ }
4949
+ })
4950
+ };
4951
+ }
4952
+ function VerifyNewPasswordStep({
4953
+ client,
4954
+ token,
4955
+ labels: labelsProp,
4956
+ styles: styles3,
4957
+ theme,
4958
+ testIdPrefix,
4959
+ onSettled
4960
+ }) {
4961
+ const labels = useMemo(
4962
+ () => ({ ...DEFAULT_VERIFY_NEW_PASSWORD_LABELS, ...labelsProp }),
4963
+ [labelsProp]
4964
+ );
4965
+ const form = useVerifyNewPasswordForm({ client, token, onSettled });
4966
+ const handleSubmitEditing = useSubmitOnEnter(form.submit);
4967
+ const newPasswordRef = useRef(null);
4968
+ useFocusOnMount(newPasswordRef);
4969
+ return /* @__PURE__ */ jsx(View, { testID: withTestIdPrefix(AuthTestIds.resetPasswordForm, testIdPrefix), children: /* @__PURE__ */ jsx(
4970
+ ResetPasswordFields,
4971
+ {
4972
+ form,
4973
+ labels,
4974
+ newPasswordRef,
4975
+ styles: styles3,
4976
+ testIdPrefix,
4977
+ theme,
4978
+ onSubmitEditing: handleSubmitEditing
4979
+ }
4980
+ ) });
4981
+ }
4982
+ function VerifySignInPrompt({
4983
+ labels: labelsProp,
4984
+ styles: styles3,
4985
+ testID,
4986
+ actionTestID,
4987
+ onContinue
4988
+ }) {
4989
+ const labels = useMemo(() => ({ ...DEFAULT_VERIFY_SIGN_IN_LABELS, ...labelsProp }), [labelsProp]);
4990
+ const actionRef = useRef(null);
4991
+ useFocusOnMount(actionRef);
4992
+ return /* @__PURE__ */ jsxs(View, { testID, children: [
4993
+ /* @__PURE__ */ jsx(Text, { accessibilityRole: "header", style: styles3.title, children: labels.title }),
4994
+ /* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: labels.body }),
4995
+ /* @__PURE__ */ jsx(
4996
+ TouchableOpacity,
4997
+ {
4998
+ ref: actionRef,
4999
+ accessibilityHint: labels.actionHint,
5000
+ accessibilityLabel: labels.action,
5001
+ accessibilityRole: "button",
5002
+ style: styles3.primaryButton,
5003
+ testID: actionTestID,
5004
+ onPress: onContinue,
5005
+ children: /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.action })
5006
+ }
5007
+ )
5008
+ ] });
5009
+ }
5010
+
4762
5011
  // src/verify/VerifyEmailPhase.ts
4763
5012
  var VerifyEmailPhase = /* @__PURE__ */ ((VerifyEmailPhase2) => {
4764
5013
  VerifyEmailPhase2["Loading"] = "loading";
4765
5014
  VerifyEmailPhase2["Success"] = "success";
4766
5015
  VerifyEmailPhase2["Failure"] = "failure";
5016
+ VerifyEmailPhase2["NewPasswordRequired"] = "newPasswordRequired";
4767
5017
  return VerifyEmailPhase2;
4768
5018
  })(VerifyEmailPhase || {});
4769
5019
 
4770
- // src/verify/useVerifyEmail.ts
5020
+ // src/verify/resolveVerifyView.ts
5021
+ function resolveVerifyView(verify, passwordOutcome) {
5022
+ if (passwordOutcome === null) {
5023
+ return verify;
5024
+ }
5025
+ if (passwordOutcome.success) {
5026
+ return { phase: "success" /* Success */, errorCode: "GENERIC" /* Generic */ };
5027
+ }
5028
+ return { phase: "failure" /* Failure */, errorCode: passwordOutcome.errorCode };
5029
+ }
4771
5030
  var LOADING = {
4772
5031
  phase: "loading" /* Loading */,
4773
5032
  errorCode: "GENERIC" /* Generic */
@@ -4776,6 +5035,10 @@ var SUCCESS = {
4776
5035
  phase: "success" /* Success */,
4777
5036
  errorCode: "GENERIC" /* Generic */
4778
5037
  };
5038
+ var NEW_PASSWORD_REQUIRED = {
5039
+ phase: "newPasswordRequired" /* NewPasswordRequired */,
5040
+ errorCode: "GENERIC" /* Generic */
5041
+ };
4779
5042
  var REJECTED = { success: false, errorCode: "GENERIC" /* Generic */ };
4780
5043
  function failure(errorCode) {
4781
5044
  return { phase: "failure" /* Failure */, errorCode };
@@ -4801,6 +5064,10 @@ function useVerifyEmail({ client, token, onVerified, onFailed }) {
4801
5064
  latest.current.onVerified?.();
4802
5065
  return;
4803
5066
  }
5067
+ if (result.errorCode === "NEW_PASSWORD_REQUIRED" /* NewPasswordRequired */) {
5068
+ setState(NEW_PASSWORD_REQUIRED);
5069
+ return;
5070
+ }
4804
5071
  setState(failure(result.errorCode));
4805
5072
  latest.current.onFailed?.(result.errorCode);
4806
5073
  };
@@ -4826,8 +5093,31 @@ function verifyEmailErrorText(code, labels) {
4826
5093
  if (code === "MISSING_TOKEN" /* MissingToken */) {
4827
5094
  return labels.missingToken;
4828
5095
  }
5096
+ if (code === "SIGN_IN_FAILED" /* SignInFailed */) {
5097
+ return labels.signIn?.body ?? DEFAULT_VERIFY_SIGN_IN_LABELS.body;
5098
+ }
5099
+ if (code === "RATE_LIMITED" /* RateLimited */) {
5100
+ return labels.errorRateLimited ?? labels.errorGeneric;
5101
+ }
4829
5102
  return labels.errorGeneric;
4830
5103
  }
5104
+ function ResendCta({ label, hint, style, textStyle, testID, onPress }) {
5105
+ const ref = useRef(null);
5106
+ useFocusOnMount(ref);
5107
+ return /* @__PURE__ */ jsx(
5108
+ TouchableOpacity,
5109
+ {
5110
+ ref,
5111
+ accessibilityHint: hint,
5112
+ accessibilityLabel: label,
5113
+ accessibilityRole: "button",
5114
+ style,
5115
+ testID,
5116
+ onPress,
5117
+ children: /* @__PURE__ */ jsx(Text, { style: textStyle, children: label })
5118
+ }
5119
+ );
5120
+ }
4831
5121
  function VerifyEmailScreen({
4832
5122
  client,
4833
5123
  token,
@@ -4845,7 +5135,20 @@ function VerifyEmailScreen({
4845
5135
  () => ({ ...DEFAULT_VERIFY_EMAIL_LABELS, ...labelsProp }),
4846
5136
  [labelsProp]
4847
5137
  );
4848
- const { phase, errorCode } = useVerifyEmail({ client, token, onVerified, onFailed });
5138
+ const verify = useVerifyEmail({ client, token, onVerified, onFailed });
5139
+ const [passwordOutcome, setPasswordOutcome] = useState(null);
5140
+ const { phase, errorCode } = resolveVerifyView(verify, passwordOutcome);
5141
+ const settlePassword = useCallback(
5142
+ (result) => {
5143
+ setPasswordOutcome(result);
5144
+ if (result.success) {
5145
+ onVerified?.();
5146
+ return;
5147
+ }
5148
+ onFailed?.(result.errorCode);
5149
+ },
5150
+ [onFailed, onVerified]
5151
+ );
4849
5152
  const [resendOpen, setResendOpen] = useState(false);
4850
5153
  const openResend = useCallback(() => setResendOpen(true), []);
4851
5154
  const id = (base) => withTestIdPrefix(base, testIdPrefix);
@@ -4855,6 +5158,18 @@ function VerifyEmailScreen({
4855
5158
  /* @__PURE__ */ jsx(Text, { accessibilityRole: "header", style: styles3.title, children: labels.loadingTitle }),
4856
5159
  /* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: labels.loadingHint })
4857
5160
  ] }) : null,
5161
+ phase === "newPasswordRequired" /* NewPasswordRequired */ ? /* @__PURE__ */ jsx(
5162
+ VerifyNewPasswordStep,
5163
+ {
5164
+ client,
5165
+ labels: labels.newPassword,
5166
+ styles: styles3,
5167
+ testIdPrefix,
5168
+ theme,
5169
+ token,
5170
+ onSettled: settlePassword
5171
+ }
5172
+ ) : null,
4858
5173
  phase === "success" /* Success */ ? /* @__PURE__ */ jsxs(View, { testID: id(AuthTestIds.verifyEmailSuccess), children: [
4859
5174
  /* @__PURE__ */ jsx(Text, { accessibilityRole: "header", style: styles3.title, children: labels.successTitle }),
4860
5175
  /* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: labels.successBody }),
@@ -4871,9 +5186,19 @@ function VerifyEmailScreen({
4871
5186
  }
4872
5187
  )
4873
5188
  ] }) : null,
4874
- phase === "failure" /* Failure */ ? /* @__PURE__ */ jsxs(View, { testID: id(AuthTestIds.verifyEmailError), children: [
5189
+ phase === "failure" /* Failure */ && errorCode === "SIGN_IN_FAILED" /* SignInFailed */ ? /* @__PURE__ */ jsx(
5190
+ VerifySignInPrompt,
5191
+ {
5192
+ actionTestID: id(AuthTestIds.verifyEmailSignInContinue),
5193
+ labels: labels.signIn,
5194
+ styles: styles3,
5195
+ testID: id(AuthTestIds.verifyEmailSignIn),
5196
+ onContinue
5197
+ }
5198
+ ) : null,
5199
+ phase === "failure" /* Failure */ && errorCode !== "SIGN_IN_FAILED" /* SignInFailed */ ? /* @__PURE__ */ jsxs(View, { testID: id(AuthTestIds.verifyEmailError), children: [
4875
5200
  /* @__PURE__ */ jsx(Text, { accessibilityRole: "header", style: styles3.title, children: labels.errorTitle }),
4876
- /* @__PURE__ */ jsx(Text, { style: styles3.errorText, children: verifyEmailErrorText(errorCode, labels) }),
5201
+ /* @__PURE__ */ jsx(Text, { style: styles3.errorBody, children: verifyEmailErrorText(errorCode, labels) }),
4877
5202
  resendOpen ? /* @__PURE__ */ jsx(
4878
5203
  VerifyEmailResendForm,
4879
5204
  {
@@ -4885,15 +5210,14 @@ function VerifyEmailScreen({
4885
5210
  verifyUrlTemplate
4886
5211
  }
4887
5212
  ) : /* @__PURE__ */ jsx(
4888
- TouchableOpacity,
5213
+ ResendCta,
4889
5214
  {
4890
- accessibilityHint: labels.resendCtaHint,
4891
- accessibilityLabel: labels.resendCta,
4892
- accessibilityRole: "button",
5215
+ hint: labels.resendCtaHint,
5216
+ label: labels.resendCta,
4893
5217
  style: styles3.primaryButton,
4894
5218
  testID: id(AuthTestIds.verifyEmailResendCta),
4895
- onPress: openResend,
4896
- children: /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.resendCta })
5219
+ textStyle: styles3.primaryButtonText,
5220
+ onPress: openResend
4897
5221
  }
4898
5222
  )
4899
5223
  ] }) : null
@@ -4910,7 +5234,10 @@ var SERVER_ERROR_CODES2 = [
4910
5234
  "TOKEN_USED" /* TokenUsed */,
4911
5235
  "KEYCLOAK_UPDATE_FAILED" /* KeycloakUpdateFailed */
4912
5236
  ];
4913
- var GENERIC_FAILURE = { success: false, errorCode: "GENERIC" /* Generic */ };
5237
+ var GENERIC_FAILURE2 = { success: false, errorCode: "GENERIC" /* Generic */ };
5238
+ var INVALID_TOKEN = { success: false, errorCode: "TOKEN_INVALID" /* TokenInvalid */ };
5239
+ var HTTP_BAD_REQUEST3 = 400;
5240
+ var TOKEN_FIELD = "token";
4914
5241
  async function lazyFetchHttpClient3(request) {
4915
5242
  const fetchImpl = typeof fetch === "function" ? fetch.bind(globalThis) : void 0;
4916
5243
  if (fetchImpl === void 0) {
@@ -4924,14 +5251,23 @@ function isServerErrorCode(value) {
4924
5251
  function isRecord3(value) {
4925
5252
  return typeof value === "object" && value !== null;
4926
5253
  }
4927
- function decodeVerifyResponse(body) {
5254
+ function isTokenValidationRejection(status, body) {
5255
+ if (status !== HTTP_BAD_REQUEST3 || !isRecord3(body.errors)) {
5256
+ return false;
5257
+ }
5258
+ return Object.keys(body.errors).some((field2) => field2.toLowerCase() === TOKEN_FIELD);
5259
+ }
5260
+ function decodeVerifyResponse(status, body) {
4928
5261
  if (!isRecord3(body)) {
4929
- return GENERIC_FAILURE;
5262
+ return GENERIC_FAILURE2;
4930
5263
  }
4931
5264
  if (body.success === true) {
4932
5265
  return { success: true };
4933
5266
  }
4934
- return isServerErrorCode(body.errorCode) ? { success: false, errorCode: body.errorCode } : GENERIC_FAILURE;
5267
+ if (isServerErrorCode(body.errorCode)) {
5268
+ return { success: false, errorCode: body.errorCode };
5269
+ }
5270
+ return isTokenValidationRejection(status, body) ? INVALID_TOKEN : GENERIC_FAILURE2;
4935
5271
  }
4936
5272
  function createBffVerifyEmailClient(options = {}) {
4937
5273
  const http = options.http ?? lazyFetchHttpClient3;
@@ -4947,9 +5283,9 @@ function createBffVerifyEmailClient(options = {}) {
4947
5283
  verifyEmail: async (token) => {
4948
5284
  try {
4949
5285
  const response = await post(VERIFY_EMAIL_ENDPOINT, { token });
4950
- return decodeVerifyResponse(response.data);
5286
+ return decodeVerifyResponse(response.status, response.data);
4951
5287
  } catch {
4952
- return GENERIC_FAILURE;
5288
+ return GENERIC_FAILURE2;
4953
5289
  }
4954
5290
  },
4955
5291
  resendVerification: async (email, verifyUrlTemplate) => {
@@ -4989,6 +5325,122 @@ function readVerifyToken(raw) {
4989
5325
  return typeof first === "string" ? first : "";
4990
5326
  }
4991
5327
 
4992
- export { AccountSettingsScreen, AuthScreen, AuthTestIds, AuthThemeProvider, BffAuthStatus, CHANGE_PASSWORD_ENDPOINT, ChangePasswordCard, ChangePasswordErrorKey, 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, DEFAULT_VERIFY_EMAIL_LABELS, DEVICE_PIN_ALLOWED_DIGITS, DEVICE_PIN_DEFAULT_DIGITS, DemoCredentialsHint, DemoCredentialsHintVariant, DevicePinEnrollErrorKey, DevicePinEnrollForm, DevicePinErrorKey, DevicePinInput, DevicePinLengthPicker, DevicePinOffer, DevicePinSettingsCard, DevicePinUnlockScreen, ForgotPasswordFields, ForgotPasswordForm, LoginForm, OtpForm, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasskeyCeremonyMode, PasskeyCeremonyStatus, PasskeyLoginButton, PasskeySettingsCard, PasswordPolicyError, PinForm, PreferredMethodHint, PreferredMethodSettingsCard, PrefillIntent, RESEND_VERIFICATION_ENDPOINT, RegisterErrorCode, RegisterForm, RegisterTestIds, ResetPasswordError, ResetPasswordForm, VERIFY_EMAIL_ENDPOINT, VERIFY_TOKEN_PLACEHOLDER, VerifyEmailErrorCode, VerifyEmailPhase, VerifyEmailScreen, buildVerifyUrlTemplate, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createBffChangePasswordClient, createBffVerifyEmailClient, createPreferencesClient, defaultAuthTheme, deriveUsernameFromEmail, isAllowedPinDigits, isPasswordValid, isRegisterPasswordStrong, isValidForgotPasswordEmail, performBffLogout, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, readVerifyToken, 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, useResendVerification, useResetPasswordForm, useVerifyEmail, validatePasswordPolicy, verifyEmailErrorText, withTestIdPrefix };
5328
+ // src/verify/sharedRegistrationClient.ts
5329
+ var REGISTER_ENDPOINT = "/bff/register";
5330
+ var VERIFY_AND_LOGIN_ENDPOINT = "/bff/verify-and-login";
5331
+ var HTTP_ACCEPTED = 202;
5332
+ var HTTP_UNAUTHORIZED2 = 401;
5333
+ var HTTP_TOO_MANY_REQUESTS2 = 429;
5334
+ var NO_MESSAGE = "";
5335
+ var GENERIC_FAILURE3 = { success: false, errorCode: "GENERIC" /* Generic */ };
5336
+ function decodeVerifyAndLogin(response) {
5337
+ if (response.ok) {
5338
+ return { success: true };
5339
+ }
5340
+ if (response.status === HTTP_TOO_MANY_REQUESTS2) {
5341
+ return { success: false, errorCode: "RATE_LIMITED" /* RateLimited */ };
5342
+ }
5343
+ if (response.status === HTTP_UNAUTHORIZED2) {
5344
+ return { success: false, errorCode: "SIGN_IN_FAILED" /* SignInFailed */ };
5345
+ }
5346
+ const body = isRecord3(response.data) ? response.data : {};
5347
+ if (body.errorCode === "NEW_PASSWORD_REQUIRED" /* NewPasswordRequired */ || body.errorCode === "WEAK_PASSWORD" /* WeakPassword */) {
5348
+ return { success: false, errorCode: body.errorCode };
5349
+ }
5350
+ return decodeVerifyResponse(response.status, response.data);
5351
+ }
5352
+ function registerFailure(response) {
5353
+ const body = isRecord3(response.data) ? response.data : {};
5354
+ const errorCode = body.errorCode ?? body.code;
5355
+ const message = `Registration failed with status ${String(response.status)}`;
5356
+ return Object.assign(new Error(message), { status: response.status, errorCode });
5357
+ }
5358
+ function createSharedRegistrationClient(options = {}) {
5359
+ const http = options.http ?? lazyFetchHttpClient3;
5360
+ const baseUrl = options.baseUrl ?? "";
5361
+ const post = (path, body, headers = {}) => http({
5362
+ url: `${baseUrl}${path}`,
5363
+ method: "POST",
5364
+ headers: { "Content-Type": "application/json", "X-BFF-Csrf": "1", ...headers },
5365
+ body: JSON.stringify(body),
5366
+ credentials: "include"
5367
+ });
5368
+ const verifyAndLogin = async (body) => {
5369
+ try {
5370
+ return decodeVerifyAndLogin(await post(VERIFY_AND_LOGIN_ENDPOINT, body));
5371
+ } catch {
5372
+ return GENERIC_FAILURE3;
5373
+ }
5374
+ };
5375
+ const verifyEmailClient = createBffVerifyEmailClient(options);
5376
+ return {
5377
+ register: async (request, meta) => {
5378
+ const body = meta === void 0 ? request : { ...request, formElapsedMs: meta.formElapsedMs };
5379
+ const headers = meta === void 0 ? {} : { "Idempotency-Key": meta.idempotencyKey };
5380
+ const response = await post(REGISTER_ENDPOINT, body, headers).catch(() => {
5381
+ throw new Error(NO_MESSAGE);
5382
+ });
5383
+ if (!response.ok) {
5384
+ throw registerFailure(response);
5385
+ }
5386
+ return { accepted: response.status === HTTP_ACCEPTED, body: response.data };
5387
+ },
5388
+ verifyEmail: (token) => verifyAndLogin({ token }),
5389
+ setNewPassword: (token, newPassword) => verifyAndLogin({ token, newPassword }),
5390
+ resendVerification: (email, verifyUrlTemplate) => verifyEmailClient.resendVerification(email, verifyUrlTemplate)
5391
+ };
5392
+ }
5393
+ function RegisterCheckEmail({
5394
+ labels,
5395
+ styles: styles3,
5396
+ footer,
5397
+ testIdPrefix
5398
+ }) {
5399
+ const headingRef = useRef(null);
5400
+ useFocusOnMount(headingRef);
5401
+ return /* @__PURE__ */ jsx(View, { style: styles3.screen, children: /* @__PURE__ */ jsxs(
5402
+ View,
5403
+ {
5404
+ accessibilityLiveRegion: "polite",
5405
+ style: styles3.card,
5406
+ testID: withTestIdPrefix(RegisterTestIds.checkEmail, testIdPrefix),
5407
+ children: [
5408
+ /* @__PURE__ */ jsx(View, { ref: headingRef, accessible: true, focusable: true, children: /* @__PURE__ */ jsx(Text, { accessibilityRole: "header", style: styles3.title, children: labels.checkEmailTitle }) }),
5409
+ /* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: labels.checkEmailBody }),
5410
+ footer
5411
+ ]
5412
+ }
5413
+ ) });
5414
+ }
5415
+ function SharedRegisterForm({
5416
+ onSuccess,
5417
+ onAccepted,
5418
+ ...formProps
5419
+ }) {
5420
+ const { footer, labels: labelsProp, testIdPrefix, theme: themeProp } = formProps;
5421
+ const styles3 = useAuthStyles(useAuthTheme(themeProp));
5422
+ const labels = useMemo(
5423
+ () => ({ ...DEFAULT_REGISTER_LABELS, ...labelsProp }),
5424
+ [labelsProp]
5425
+ );
5426
+ const [accepted, setAccepted] = useState(false);
5427
+ const handleResult = useCallback(
5428
+ (result) => {
5429
+ if (!isRegisterAccepted(result)) {
5430
+ onSuccess(result);
5431
+ return;
5432
+ }
5433
+ setAccepted(true);
5434
+ onAccepted?.(result);
5435
+ },
5436
+ [onAccepted, onSuccess]
5437
+ );
5438
+ if (accepted) {
5439
+ return /* @__PURE__ */ jsx(RegisterCheckEmail, { footer, labels, styles: styles3, testIdPrefix });
5440
+ }
5441
+ return /* @__PURE__ */ jsx(RegisterFormCore, { ...formProps, sharedRegistration: true, onSuccess: handleResult });
5442
+ }
5443
+
5444
+ export { AccountSettingsScreen, AuthScreen, AuthTestIds, AuthThemeProvider, BffAuthStatus, CHANGE_PASSWORD_ENDPOINT, ChangePasswordCard, ChangePasswordErrorKey, 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, DEFAULT_VERIFY_EMAIL_LABELS, DEFAULT_VERIFY_NEW_PASSWORD_LABELS, DEFAULT_VERIFY_SIGN_IN_LABELS, DEVICE_PIN_ALLOWED_DIGITS, DEVICE_PIN_DEFAULT_DIGITS, DemoCredentialsHint, DemoCredentialsHintVariant, DevicePinEnrollErrorKey, DevicePinEnrollForm, DevicePinErrorKey, DevicePinInput, DevicePinLengthPicker, DevicePinOffer, DevicePinSettingsCard, DevicePinUnlockScreen, ForgotPasswordFields, ForgotPasswordForm, LoginForm, OtpForm, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasskeyCeremonyMode, PasskeyCeremonyStatus, PasskeyLoginButton, PasskeySettingsCard, PasswordPolicyError, PinForm, PreferredMethodHint, PreferredMethodSettingsCard, PrefillIntent, REGISTER_ENDPOINT, RESEND_VERIFICATION_ENDPOINT, RegisterErrorCode, RegisterForm, RegisterTestIds, ResetPasswordError, ResetPasswordForm, SharedRegisterForm, VERIFY_AND_LOGIN_ENDPOINT, VERIFY_EMAIL_ENDPOINT, VERIFY_TOKEN_PLACEHOLDER, VerifyEmailErrorCode, VerifyEmailPhase, VerifyEmailScreen, buildVerifyUrlTemplate, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createBffChangePasswordClient, createBffVerifyEmailClient, createPreferencesClient, createSharedRegistrationClient, defaultAuthTheme, deriveUsernameFromEmail, isAllowedPinDigits, isPasswordValid, isRegisterAccepted, isRegisterPasswordStrong, isValidForgotPasswordEmail, performBffLogout, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, readVerifyToken, 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, useResendVerification, useResetPasswordForm, useVerifyEmail, validatePasswordPolicy, verifyEmailErrorText, withTestIdPrefix };
4993
5445
  //# sourceMappingURL=index.mjs.map
4994
5446
  //# sourceMappingURL=index.mjs.map