@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/CHANGELOG.md +14 -0
- package/dist/index.d.mts +73 -10
- package/dist/index.d.ts +73 -10
- package/dist/index.js +571 -112
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +565 -113
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
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
|
-
|
|
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
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
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
|
|
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
|
|
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(
|
|
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.
|
|
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/
|
|
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
|
|
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__ */
|
|
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.
|
|
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
|
-
|
|
5213
|
+
ResendCta,
|
|
4889
5214
|
{
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
accessibilityRole: "button",
|
|
5215
|
+
hint: labels.resendCtaHint,
|
|
5216
|
+
label: labels.resendCta,
|
|
4893
5217
|
style: styles3.primaryButton,
|
|
4894
5218
|
testID: id(AuthTestIds.verifyEmailResendCta),
|
|
4895
|
-
|
|
4896
|
-
|
|
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
|
|
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
|
|
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
|
|
5262
|
+
return GENERIC_FAILURE2;
|
|
4930
5263
|
}
|
|
4931
5264
|
if (body.success === true) {
|
|
4932
5265
|
return { success: true };
|
|
4933
5266
|
}
|
|
4934
|
-
|
|
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
|
|
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
|
-
|
|
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
|