@dloizides/auth-web 1.22.1 → 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 +516 -101
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +510 -102
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -306,7 +306,8 @@ var DEFAULT_RESET_PASSWORD_LABELS = {
|
|
|
306
306
|
errorWeakPassword: "Use at least 8 characters with an uppercase letter, a lowercase letter and a digit.",
|
|
307
307
|
errorMismatch: "The passwords do not match.",
|
|
308
308
|
errorTokenInvalid: "This reset link is invalid or has expired. Request a new one.",
|
|
309
|
-
errorNetwork: "Something went wrong. Please try again."
|
|
309
|
+
errorNetwork: "Something went wrong. Please try again.",
|
|
310
|
+
errorRateLimited: "Too many attempts. Wait a minute and try again."
|
|
310
311
|
};
|
|
311
312
|
|
|
312
313
|
// src/components/labels/accountSettingsLabels.ts
|
|
@@ -343,6 +344,8 @@ var DEFAULT_REGISTER_LABELS = {
|
|
|
343
344
|
submitHint: "Creates your account",
|
|
344
345
|
submitting: "Creating account...",
|
|
345
346
|
fullName: field("Your name", "Enter your full name"),
|
|
347
|
+
checkEmailTitle: "Check your email",
|
|
348
|
+
checkEmailBody: "If this address can be used, a link to finish signing up is on its way.",
|
|
346
349
|
fields: {
|
|
347
350
|
firstName: field("First name", "Enter your first name"),
|
|
348
351
|
lastName: field("Last name", "Enter your last name"),
|
|
@@ -355,6 +358,19 @@ var DEFAULT_REGISTER_LABELS = {
|
|
|
355
358
|
};
|
|
356
359
|
|
|
357
360
|
// src/components/labels/verifyEmailLabels.ts
|
|
361
|
+
var DEFAULT_VERIFY_NEW_PASSWORD_LABELS = {
|
|
362
|
+
...DEFAULT_RESET_PASSWORD_LABELS,
|
|
363
|
+
title: "Set a new password",
|
|
364
|
+
description: "To finish signing in, choose a new password for your account.",
|
|
365
|
+
submit: "Save and sign in",
|
|
366
|
+
submitting: "Saving..."
|
|
367
|
+
};
|
|
368
|
+
var DEFAULT_VERIFY_SIGN_IN_LABELS = {
|
|
369
|
+
title: "Your email is verified",
|
|
370
|
+
body: "We could not sign you in automatically. Please sign in with your password.",
|
|
371
|
+
action: "Sign in",
|
|
372
|
+
actionHint: "Go to the sign in page"
|
|
373
|
+
};
|
|
358
374
|
var DEFAULT_VERIFY_EMAIL_LABELS = {
|
|
359
375
|
loadingTitle: "Verifying your email...",
|
|
360
376
|
loadingHint: "Please wait while we verify your address.",
|
|
@@ -376,7 +392,10 @@ var DEFAULT_VERIFY_EMAIL_LABELS = {
|
|
|
376
392
|
resendMissingEmail: "Enter your email address.",
|
|
377
393
|
resendSubmit: "Send link",
|
|
378
394
|
resendSubmitHint: "Sends a new verification email",
|
|
379
|
-
resendConfirmation: "If that address has an account, a new verification link is on its way."
|
|
395
|
+
resendConfirmation: "If that address has an account, a new verification link is on its way.",
|
|
396
|
+
errorRateLimited: "Too many attempts. Wait a minute and try again.",
|
|
397
|
+
newPassword: DEFAULT_VERIFY_NEW_PASSWORD_LABELS,
|
|
398
|
+
signIn: DEFAULT_VERIFY_SIGN_IN_LABELS
|
|
380
399
|
};
|
|
381
400
|
|
|
382
401
|
// src/components/testIds.ts
|
|
@@ -475,6 +494,8 @@ var AuthTestIds = {
|
|
|
475
494
|
verifyEmailSuccess: "auth-verify-email-success",
|
|
476
495
|
verifyEmailContinue: "auth-verify-email-continue",
|
|
477
496
|
verifyEmailError: "auth-verify-email-error",
|
|
497
|
+
verifyEmailSignIn: "auth-verify-email-sign-in",
|
|
498
|
+
verifyEmailSignInContinue: "auth-verify-email-sign-in-continue",
|
|
478
499
|
verifyEmailResendCta: "auth-verify-email-resend-cta",
|
|
479
500
|
verifyEmailResendForm: "auth-verify-email-resend-form",
|
|
480
501
|
verifyEmailResendEmail: "auth-verify-email-resend-email",
|
|
@@ -1275,8 +1296,107 @@ var ResetPasswordError = /* @__PURE__ */ ((ResetPasswordError2) => {
|
|
|
1275
1296
|
ResetPasswordError2["Mismatch"] = "mismatch";
|
|
1276
1297
|
ResetPasswordError2["TokenInvalid"] = "tokenInvalid";
|
|
1277
1298
|
ResetPasswordError2["Network"] = "network";
|
|
1299
|
+
ResetPasswordError2["RateLimited"] = "rateLimited";
|
|
1278
1300
|
return ResetPasswordError2;
|
|
1279
1301
|
})(ResetPasswordError || {});
|
|
1302
|
+
function errorMessage(errorKey, labels) {
|
|
1303
|
+
switch (errorKey) {
|
|
1304
|
+
case "empty" /* Empty */:
|
|
1305
|
+
return labels.errorEmpty;
|
|
1306
|
+
case "weakPassword" /* WeakPassword */:
|
|
1307
|
+
return labels.errorWeakPassword;
|
|
1308
|
+
case "mismatch" /* Mismatch */:
|
|
1309
|
+
return labels.errorMismatch;
|
|
1310
|
+
case "tokenInvalid" /* TokenInvalid */:
|
|
1311
|
+
return labels.errorTokenInvalid;
|
|
1312
|
+
case "network" /* Network */:
|
|
1313
|
+
return labels.errorNetwork;
|
|
1314
|
+
case "rateLimited" /* RateLimited */:
|
|
1315
|
+
return labels.errorRateLimited ?? labels.errorNetwork;
|
|
1316
|
+
default:
|
|
1317
|
+
return null;
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
function ResetPasswordFields({
|
|
1321
|
+
form,
|
|
1322
|
+
labels,
|
|
1323
|
+
styles: styles3,
|
|
1324
|
+
theme,
|
|
1325
|
+
testIdPrefix,
|
|
1326
|
+
newPasswordRef,
|
|
1327
|
+
onSubmitEditing
|
|
1328
|
+
}) {
|
|
1329
|
+
const message = errorMessage(form.errorKey, labels);
|
|
1330
|
+
const submitButtonStyle = form.isSubmitting ? [styles3.primaryButton, styles3.primaryButtonDisabled] : styles3.primaryButton;
|
|
1331
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1332
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.title, children: labels.title }),
|
|
1333
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.subtitle, children: labels.description }),
|
|
1334
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.fieldGroup, children: [
|
|
1335
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.label, children: labels.newPasswordLabel }),
|
|
1336
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1337
|
+
reactNative.TextInput,
|
|
1338
|
+
{
|
|
1339
|
+
ref: newPasswordRef,
|
|
1340
|
+
secureTextEntry: true,
|
|
1341
|
+
accessibilityHint: labels.newPasswordPlaceholder,
|
|
1342
|
+
accessibilityLabel: labels.newPasswordLabel,
|
|
1343
|
+
autoCapitalize: "none",
|
|
1344
|
+
autoCorrect: false,
|
|
1345
|
+
editable: !form.isSubmitting,
|
|
1346
|
+
placeholder: labels.newPasswordPlaceholder,
|
|
1347
|
+
placeholderTextColor: theme.colors.textSecondary,
|
|
1348
|
+
style: styles3.input,
|
|
1349
|
+
testID: withTestIdPrefix(AuthTestIds.resetPasswordNewInput, testIdPrefix),
|
|
1350
|
+
value: form.newPassword,
|
|
1351
|
+
onChangeText: form.setNewPassword,
|
|
1352
|
+
onSubmitEditing
|
|
1353
|
+
}
|
|
1354
|
+
)
|
|
1355
|
+
] }),
|
|
1356
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.fieldGroup, children: [
|
|
1357
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.label, children: labels.confirmPasswordLabel }),
|
|
1358
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1359
|
+
reactNative.TextInput,
|
|
1360
|
+
{
|
|
1361
|
+
secureTextEntry: true,
|
|
1362
|
+
accessibilityHint: labels.confirmPasswordPlaceholder,
|
|
1363
|
+
accessibilityLabel: labels.confirmPasswordLabel,
|
|
1364
|
+
autoCapitalize: "none",
|
|
1365
|
+
autoCorrect: false,
|
|
1366
|
+
editable: !form.isSubmitting,
|
|
1367
|
+
placeholder: labels.confirmPasswordPlaceholder,
|
|
1368
|
+
placeholderTextColor: theme.colors.textSecondary,
|
|
1369
|
+
style: styles3.input,
|
|
1370
|
+
testID: withTestIdPrefix(AuthTestIds.resetPasswordConfirmInput, testIdPrefix),
|
|
1371
|
+
value: form.confirmPassword,
|
|
1372
|
+
onChangeText: form.setConfirmPassword,
|
|
1373
|
+
onSubmitEditing
|
|
1374
|
+
}
|
|
1375
|
+
)
|
|
1376
|
+
] }),
|
|
1377
|
+
message !== null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1378
|
+
reactNative.Text,
|
|
1379
|
+
{
|
|
1380
|
+
style: styles3.errorText,
|
|
1381
|
+
testID: withTestIdPrefix(AuthTestIds.resetPasswordError, testIdPrefix),
|
|
1382
|
+
children: message
|
|
1383
|
+
}
|
|
1384
|
+
) : null,
|
|
1385
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1386
|
+
reactNative.TouchableOpacity,
|
|
1387
|
+
{
|
|
1388
|
+
accessibilityHint: labels.submit,
|
|
1389
|
+
accessibilityLabel: form.isSubmitting ? labels.submitting : labels.submit,
|
|
1390
|
+
accessibilityRole: "button",
|
|
1391
|
+
disabled: form.isSubmitting,
|
|
1392
|
+
style: submitButtonStyle,
|
|
1393
|
+
testID: withTestIdPrefix(AuthTestIds.resetPasswordSubmitButton, testIdPrefix),
|
|
1394
|
+
onPress: form.submit,
|
|
1395
|
+
children: form.isSubmitting ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.primaryButtonText, children: labels.submit })
|
|
1396
|
+
}
|
|
1397
|
+
)
|
|
1398
|
+
] });
|
|
1399
|
+
}
|
|
1280
1400
|
|
|
1281
1401
|
// src/password/PasswordPolicyError.ts
|
|
1282
1402
|
var PasswordPolicyError = /* @__PURE__ */ ((PasswordPolicyError2) => {
|
|
@@ -1415,22 +1535,6 @@ function useResetPasswordForm({
|
|
|
1415
1535
|
submit
|
|
1416
1536
|
};
|
|
1417
1537
|
}
|
|
1418
|
-
function errorMessage(errorKey, labels) {
|
|
1419
|
-
switch (errorKey) {
|
|
1420
|
-
case "empty" /* Empty */:
|
|
1421
|
-
return labels.errorEmpty;
|
|
1422
|
-
case "weakPassword" /* WeakPassword */:
|
|
1423
|
-
return labels.errorWeakPassword;
|
|
1424
|
-
case "mismatch" /* Mismatch */:
|
|
1425
|
-
return labels.errorMismatch;
|
|
1426
|
-
case "tokenInvalid" /* TokenInvalid */:
|
|
1427
|
-
return labels.errorTokenInvalid;
|
|
1428
|
-
case "network" /* Network */:
|
|
1429
|
-
return labels.errorNetwork;
|
|
1430
|
-
default:
|
|
1431
|
-
return null;
|
|
1432
|
-
}
|
|
1433
|
-
}
|
|
1434
1538
|
function ResetPasswordForm({
|
|
1435
1539
|
client,
|
|
1436
1540
|
token,
|
|
@@ -1446,78 +1550,21 @@ function ResetPasswordForm({
|
|
|
1446
1550
|
[labelsProp]
|
|
1447
1551
|
);
|
|
1448
1552
|
const form = useResetPasswordForm({ client, token, onSuccess });
|
|
1449
|
-
|
|
1450
|
-
const submitButtonStyle = form.isSubmitting ? [styles3.primaryButton, styles3.primaryButtonDisabled] : styles3.primaryButton;
|
|
1451
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles3.screen, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1553
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles3.screen, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1452
1554
|
reactNative.View,
|
|
1453
1555
|
{
|
|
1454
1556
|
style: styles3.card,
|
|
1455
1557
|
testID: withTestIdPrefix(AuthTestIds.resetPasswordForm, testIdPrefix),
|
|
1456
|
-
children:
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
accessibilityLabel: labels.newPasswordLabel,
|
|
1467
|
-
autoCapitalize: "none",
|
|
1468
|
-
autoCorrect: false,
|
|
1469
|
-
editable: !form.isSubmitting,
|
|
1470
|
-
placeholder: labels.newPasswordPlaceholder,
|
|
1471
|
-
placeholderTextColor: theme.colors.textSecondary,
|
|
1472
|
-
style: styles3.input,
|
|
1473
|
-
testID: withTestIdPrefix(AuthTestIds.resetPasswordNewInput, testIdPrefix),
|
|
1474
|
-
value: form.newPassword,
|
|
1475
|
-
onChangeText: form.setNewPassword
|
|
1476
|
-
}
|
|
1477
|
-
)
|
|
1478
|
-
] }),
|
|
1479
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.fieldGroup, children: [
|
|
1480
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.label, children: labels.confirmPasswordLabel }),
|
|
1481
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1482
|
-
reactNative.TextInput,
|
|
1483
|
-
{
|
|
1484
|
-
secureTextEntry: true,
|
|
1485
|
-
accessibilityHint: labels.confirmPasswordPlaceholder,
|
|
1486
|
-
accessibilityLabel: labels.confirmPasswordLabel,
|
|
1487
|
-
autoCapitalize: "none",
|
|
1488
|
-
autoCorrect: false,
|
|
1489
|
-
editable: !form.isSubmitting,
|
|
1490
|
-
placeholder: labels.confirmPasswordPlaceholder,
|
|
1491
|
-
placeholderTextColor: theme.colors.textSecondary,
|
|
1492
|
-
style: styles3.input,
|
|
1493
|
-
testID: withTestIdPrefix(AuthTestIds.resetPasswordConfirmInput, testIdPrefix),
|
|
1494
|
-
value: form.confirmPassword,
|
|
1495
|
-
onChangeText: form.setConfirmPassword
|
|
1496
|
-
}
|
|
1497
|
-
)
|
|
1498
|
-
] }),
|
|
1499
|
-
message !== null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1500
|
-
reactNative.Text,
|
|
1501
|
-
{
|
|
1502
|
-
style: styles3.errorText,
|
|
1503
|
-
testID: withTestIdPrefix(AuthTestIds.resetPasswordError, testIdPrefix),
|
|
1504
|
-
children: message
|
|
1505
|
-
}
|
|
1506
|
-
) : null,
|
|
1507
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1508
|
-
reactNative.TouchableOpacity,
|
|
1509
|
-
{
|
|
1510
|
-
accessibilityHint: labels.submit,
|
|
1511
|
-
accessibilityLabel: form.isSubmitting ? labels.submitting : labels.submit,
|
|
1512
|
-
accessibilityRole: "button",
|
|
1513
|
-
disabled: form.isSubmitting,
|
|
1514
|
-
style: submitButtonStyle,
|
|
1515
|
-
testID: withTestIdPrefix(AuthTestIds.resetPasswordSubmitButton, testIdPrefix),
|
|
1516
|
-
onPress: form.submit,
|
|
1517
|
-
children: form.isSubmitting ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.primaryButtonText, children: labels.submit })
|
|
1518
|
-
}
|
|
1519
|
-
)
|
|
1520
|
-
]
|
|
1558
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1559
|
+
ResetPasswordFields,
|
|
1560
|
+
{
|
|
1561
|
+
form,
|
|
1562
|
+
labels,
|
|
1563
|
+
styles: styles3,
|
|
1564
|
+
testIdPrefix,
|
|
1565
|
+
theme
|
|
1566
|
+
}
|
|
1567
|
+
)
|
|
1521
1568
|
}
|
|
1522
1569
|
) });
|
|
1523
1570
|
}
|
|
@@ -4146,7 +4193,8 @@ var RegisterTestIds = {
|
|
|
4146
4193
|
confirmPasswordInput: "register-confirm-password-input",
|
|
4147
4194
|
tenantNameInput: "register-tenant-name-input",
|
|
4148
4195
|
submitButton: "register-submit-button",
|
|
4149
|
-
websiteInput: "register-website"
|
|
4196
|
+
websiteInput: "register-website",
|
|
4197
|
+
checkEmail: "register-check-email"
|
|
4150
4198
|
};
|
|
4151
4199
|
var FIELDS = [
|
|
4152
4200
|
{ key: "firstName", testId: RegisterTestIds.firstNameInput, autoComplete: "name" },
|
|
@@ -4268,6 +4316,14 @@ function routeRegisterOutcome(outcome, handlers) {
|
|
|
4268
4316
|
}
|
|
4269
4317
|
}
|
|
4270
4318
|
|
|
4319
|
+
// src/hooks/registerAccepted.ts
|
|
4320
|
+
function isRegisterAccepted(result) {
|
|
4321
|
+
if (typeof result !== "object" || result === null) {
|
|
4322
|
+
return false;
|
|
4323
|
+
}
|
|
4324
|
+
return result.accepted === true;
|
|
4325
|
+
}
|
|
4326
|
+
|
|
4271
4327
|
// src/hooks/registerErrors.ts
|
|
4272
4328
|
var MIN_PASSWORD_LENGTH = 8;
|
|
4273
4329
|
var WHITESPACE_REGEX = /\s/;
|
|
@@ -4420,6 +4476,42 @@ function expandCompactRegisterValues(values) {
|
|
|
4420
4476
|
};
|
|
4421
4477
|
}
|
|
4422
4478
|
|
|
4479
|
+
// src/hooks/newIdempotencyKey.ts
|
|
4480
|
+
var HEX_RADIX = 16;
|
|
4481
|
+
var HEX_BYTE_LENGTH = 2;
|
|
4482
|
+
var KEY_BYTES = 16;
|
|
4483
|
+
var fallbackSequence = 0;
|
|
4484
|
+
function newIdempotencyKey() {
|
|
4485
|
+
const cryptoApi = globalThis.crypto;
|
|
4486
|
+
if (typeof cryptoApi?.randomUUID === "function") {
|
|
4487
|
+
return cryptoApi.randomUUID();
|
|
4488
|
+
}
|
|
4489
|
+
if (typeof cryptoApi?.getRandomValues === "function") {
|
|
4490
|
+
const bytes = cryptoApi.getRandomValues(new Uint8Array(KEY_BYTES));
|
|
4491
|
+
return Array.from(bytes, (byte) => byte.toString(HEX_RADIX).padStart(HEX_BYTE_LENGTH, "0")).join("");
|
|
4492
|
+
}
|
|
4493
|
+
fallbackSequence += 1;
|
|
4494
|
+
return `${Date.now().toString(HEX_RADIX)}-${String(fallbackSequence)}`;
|
|
4495
|
+
}
|
|
4496
|
+
|
|
4497
|
+
// src/hooks/useRegisterSubmitMeta.ts
|
|
4498
|
+
function useRegisterSubmitMeta() {
|
|
4499
|
+
const openedAt = react.useRef(Date.now());
|
|
4500
|
+
const key = react.useRef(null);
|
|
4501
|
+
return react.useMemo(
|
|
4502
|
+
() => ({
|
|
4503
|
+
next: () => {
|
|
4504
|
+
key.current ?? (key.current = newIdempotencyKey());
|
|
4505
|
+
return { idempotencyKey: key.current, formElapsedMs: Date.now() - openedAt.current };
|
|
4506
|
+
},
|
|
4507
|
+
resetKey: () => {
|
|
4508
|
+
key.current = null;
|
|
4509
|
+
}
|
|
4510
|
+
}),
|
|
4511
|
+
[]
|
|
4512
|
+
);
|
|
4513
|
+
}
|
|
4514
|
+
|
|
4423
4515
|
// src/hooks/useRegisterForm.ts
|
|
4424
4516
|
var EMPTY_VALUES = {
|
|
4425
4517
|
firstName: "",
|
|
@@ -4431,6 +4523,9 @@ var EMPTY_VALUES = {
|
|
|
4431
4523
|
tenantName: "",
|
|
4432
4524
|
website: ""
|
|
4433
4525
|
};
|
|
4526
|
+
function withoutPasswords(values) {
|
|
4527
|
+
return { ...values, password: "", confirmPassword: "" };
|
|
4528
|
+
}
|
|
4434
4529
|
function toSubmitValues(values) {
|
|
4435
4530
|
return {
|
|
4436
4531
|
firstName: values.firstName,
|
|
@@ -4446,15 +4541,18 @@ function useRegisterForm({
|
|
|
4446
4541
|
onSubmit,
|
|
4447
4542
|
passwordPolicy = isRegisterPasswordStrong,
|
|
4448
4543
|
onSubmitAttempt,
|
|
4449
|
-
compact = false
|
|
4544
|
+
compact = false,
|
|
4545
|
+
sharedRegistration = false
|
|
4450
4546
|
}) {
|
|
4451
4547
|
const [state, setState] = react.useState(EMPTY_VALUES);
|
|
4452
4548
|
const [isSubmitting, setIsSubmitting] = react.useState(false);
|
|
4453
4549
|
const [error, setError] = react.useState(null);
|
|
4454
4550
|
const inFlight = react.useRef(false);
|
|
4551
|
+
const submitMeta = useRegisterSubmitMeta();
|
|
4455
4552
|
const setField = react.useCallback((field2, value) => {
|
|
4553
|
+
submitMeta.resetKey();
|
|
4456
4554
|
setState((prev) => ({ ...prev, [field2]: value }));
|
|
4457
|
-
}, []);
|
|
4555
|
+
}, [submitMeta]);
|
|
4458
4556
|
const submit = react.useCallback(async () => {
|
|
4459
4557
|
if (inFlight.current) {
|
|
4460
4558
|
return { ok: false, error: "inFlight" /* InFlight */ };
|
|
@@ -4471,7 +4569,11 @@ function useRegisterForm({
|
|
|
4471
4569
|
setError(null);
|
|
4472
4570
|
setIsSubmitting(true);
|
|
4473
4571
|
try {
|
|
4474
|
-
const
|
|
4572
|
+
const values = toSubmitValues(trimmed);
|
|
4573
|
+
const result = await (sharedRegistration ? onSubmit(values, submitMeta.next()) : onSubmit(values));
|
|
4574
|
+
if (sharedRegistration && isRegisterAccepted(result)) {
|
|
4575
|
+
setState(withoutPasswords);
|
|
4576
|
+
}
|
|
4475
4577
|
return { ok: true, result };
|
|
4476
4578
|
} catch (caught) {
|
|
4477
4579
|
const code = mapRegisterErrorCode(caught);
|
|
@@ -4481,10 +4583,10 @@ function useRegisterForm({
|
|
|
4481
4583
|
inFlight.current = false;
|
|
4482
4584
|
setIsSubmitting(false);
|
|
4483
4585
|
}
|
|
4484
|
-
}, [compact, onSubmit, onSubmitAttempt, passwordPolicy, state]);
|
|
4586
|
+
}, [compact, onSubmit, onSubmitAttempt, passwordPolicy, sharedRegistration, state, submitMeta]);
|
|
4485
4587
|
return { state, setField, submit, isSubmitting, error };
|
|
4486
4588
|
}
|
|
4487
|
-
function
|
|
4589
|
+
function RegisterFormCore({
|
|
4488
4590
|
onSubmit,
|
|
4489
4591
|
onSuccess,
|
|
4490
4592
|
onError,
|
|
@@ -4494,7 +4596,8 @@ function RegisterForm({
|
|
|
4494
4596
|
theme: themeProp,
|
|
4495
4597
|
footer,
|
|
4496
4598
|
testIdPrefix,
|
|
4497
|
-
compact = false
|
|
4599
|
+
compact = false,
|
|
4600
|
+
sharedRegistration
|
|
4498
4601
|
}) {
|
|
4499
4602
|
const theme = useAuthTheme(themeProp);
|
|
4500
4603
|
const styles3 = useAuthStyles(theme);
|
|
@@ -4506,7 +4609,8 @@ function RegisterForm({
|
|
|
4506
4609
|
onSubmit,
|
|
4507
4610
|
onSubmitAttempt,
|
|
4508
4611
|
passwordPolicy,
|
|
4509
|
-
compact
|
|
4612
|
+
compact,
|
|
4613
|
+
sharedRegistration
|
|
4510
4614
|
});
|
|
4511
4615
|
const handlePress = react.useCallback(async () => {
|
|
4512
4616
|
routeRegisterOutcome(await submit(), { onSuccess, onError });
|
|
@@ -4544,6 +4648,9 @@ function RegisterForm({
|
|
|
4544
4648
|
footer
|
|
4545
4649
|
] }) });
|
|
4546
4650
|
}
|
|
4651
|
+
function RegisterForm(props) {
|
|
4652
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RegisterFormCore, { ...props, sharedRegistration: false });
|
|
4653
|
+
}
|
|
4547
4654
|
async function lazyFetchHttpClient(request) {
|
|
4548
4655
|
const fetchImpl = typeof fetch === "function" ? fetch.bind(globalThis) : void 0;
|
|
4549
4656
|
if (fetchImpl === void 0) {
|
|
@@ -4772,19 +4879,155 @@ var VerifyEmailErrorCode = /* @__PURE__ */ ((VerifyEmailErrorCode2) => {
|
|
|
4772
4879
|
VerifyEmailErrorCode2["TokenUsed"] = "TOKEN_USED";
|
|
4773
4880
|
VerifyEmailErrorCode2["KeycloakUpdateFailed"] = "KEYCLOAK_UPDATE_FAILED";
|
|
4774
4881
|
VerifyEmailErrorCode2["MissingToken"] = "MISSING_TOKEN";
|
|
4882
|
+
VerifyEmailErrorCode2["NewPasswordRequired"] = "NEW_PASSWORD_REQUIRED";
|
|
4883
|
+
VerifyEmailErrorCode2["WeakPassword"] = "WEAK_PASSWORD";
|
|
4884
|
+
VerifyEmailErrorCode2["RateLimited"] = "RATE_LIMITED";
|
|
4885
|
+
VerifyEmailErrorCode2["SignInFailed"] = "SIGN_IN_FAILED";
|
|
4775
4886
|
VerifyEmailErrorCode2["Generic"] = "GENERIC";
|
|
4776
4887
|
return VerifyEmailErrorCode2;
|
|
4777
4888
|
})(VerifyEmailErrorCode || {});
|
|
4778
4889
|
|
|
4890
|
+
// src/verify/useVerifyNewPasswordForm.ts
|
|
4891
|
+
var GENERIC_FAILURE = { success: false, errorCode: "GENERIC" /* Generic */ };
|
|
4892
|
+
var DEAD_LINK_CODES = [
|
|
4893
|
+
"TOKEN_INVALID" /* TokenInvalid */,
|
|
4894
|
+
"TOKEN_EXPIRED" /* TokenExpired */,
|
|
4895
|
+
"TOKEN_USED" /* TokenUsed */,
|
|
4896
|
+
"SIGN_IN_FAILED" /* SignInFailed */
|
|
4897
|
+
];
|
|
4898
|
+
function retryableError(code) {
|
|
4899
|
+
if (DEAD_LINK_CODES.includes(code)) {
|
|
4900
|
+
return null;
|
|
4901
|
+
}
|
|
4902
|
+
if (code === "WEAK_PASSWORD" /* WeakPassword */) {
|
|
4903
|
+
return "weakPassword" /* WeakPassword */;
|
|
4904
|
+
}
|
|
4905
|
+
return code === "RATE_LIMITED" /* RateLimited */ ? "rateLimited" /* RateLimited */ : "network" /* Network */;
|
|
4906
|
+
}
|
|
4907
|
+
function useVerifyNewPasswordForm({
|
|
4908
|
+
client,
|
|
4909
|
+
token,
|
|
4910
|
+
onSettled
|
|
4911
|
+
}) {
|
|
4912
|
+
const { state, setters } = useFormState();
|
|
4913
|
+
const [isSubmitting, setIsSubmitting] = react.useState(false);
|
|
4914
|
+
const inFlight = react.useRef(false);
|
|
4915
|
+
const send = react.useMemo(
|
|
4916
|
+
() => async (newPassword) => {
|
|
4917
|
+
if (inFlight.current) {
|
|
4918
|
+
return;
|
|
4919
|
+
}
|
|
4920
|
+
inFlight.current = true;
|
|
4921
|
+
setIsSubmitting(true);
|
|
4922
|
+
const result = await (client.setNewPassword?.(token, newPassword) ?? Promise.resolve(GENERIC_FAILURE)).catch(
|
|
4923
|
+
() => GENERIC_FAILURE
|
|
4924
|
+
);
|
|
4925
|
+
inFlight.current = false;
|
|
4926
|
+
setIsSubmitting(false);
|
|
4927
|
+
const formError = result.success ? null : retryableError(result.errorCode);
|
|
4928
|
+
if (formError === null) {
|
|
4929
|
+
onSettled(result);
|
|
4930
|
+
return;
|
|
4931
|
+
}
|
|
4932
|
+
setters.setErrorKey(formError);
|
|
4933
|
+
},
|
|
4934
|
+
[client, onSettled, setters, token]
|
|
4935
|
+
);
|
|
4936
|
+
return {
|
|
4937
|
+
...state,
|
|
4938
|
+
setNewPassword: setters.setNewPassword,
|
|
4939
|
+
setConfirmPassword: setters.setConfirmPassword,
|
|
4940
|
+
isSubmitting,
|
|
4941
|
+
submit: () => runSubmit({
|
|
4942
|
+
newPassword: state.newPassword,
|
|
4943
|
+
confirmPassword: state.confirmPassword,
|
|
4944
|
+
token,
|
|
4945
|
+
setErrorKey: setters.setErrorKey,
|
|
4946
|
+
setHasInvalidToken: setters.setHasInvalidToken,
|
|
4947
|
+
mutate: (request) => {
|
|
4948
|
+
void send(request.newPassword);
|
|
4949
|
+
}
|
|
4950
|
+
})
|
|
4951
|
+
};
|
|
4952
|
+
}
|
|
4953
|
+
function VerifyNewPasswordStep({
|
|
4954
|
+
client,
|
|
4955
|
+
token,
|
|
4956
|
+
labels: labelsProp,
|
|
4957
|
+
styles: styles3,
|
|
4958
|
+
theme,
|
|
4959
|
+
testIdPrefix,
|
|
4960
|
+
onSettled
|
|
4961
|
+
}) {
|
|
4962
|
+
const labels = react.useMemo(
|
|
4963
|
+
() => ({ ...DEFAULT_VERIFY_NEW_PASSWORD_LABELS, ...labelsProp }),
|
|
4964
|
+
[labelsProp]
|
|
4965
|
+
);
|
|
4966
|
+
const form = useVerifyNewPasswordForm({ client, token, onSettled });
|
|
4967
|
+
const handleSubmitEditing = useSubmitOnEnter(form.submit);
|
|
4968
|
+
const newPasswordRef = react.useRef(null);
|
|
4969
|
+
useFocusOnMount(newPasswordRef);
|
|
4970
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { testID: withTestIdPrefix(AuthTestIds.resetPasswordForm, testIdPrefix), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4971
|
+
ResetPasswordFields,
|
|
4972
|
+
{
|
|
4973
|
+
form,
|
|
4974
|
+
labels,
|
|
4975
|
+
newPasswordRef,
|
|
4976
|
+
styles: styles3,
|
|
4977
|
+
testIdPrefix,
|
|
4978
|
+
theme,
|
|
4979
|
+
onSubmitEditing: handleSubmitEditing
|
|
4980
|
+
}
|
|
4981
|
+
) });
|
|
4982
|
+
}
|
|
4983
|
+
function VerifySignInPrompt({
|
|
4984
|
+
labels: labelsProp,
|
|
4985
|
+
styles: styles3,
|
|
4986
|
+
testID,
|
|
4987
|
+
actionTestID,
|
|
4988
|
+
onContinue
|
|
4989
|
+
}) {
|
|
4990
|
+
const labels = react.useMemo(() => ({ ...DEFAULT_VERIFY_SIGN_IN_LABELS, ...labelsProp }), [labelsProp]);
|
|
4991
|
+
const actionRef = react.useRef(null);
|
|
4992
|
+
useFocusOnMount(actionRef);
|
|
4993
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { testID, children: [
|
|
4994
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { accessibilityRole: "header", style: styles3.title, children: labels.title }),
|
|
4995
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.subtitle, children: labels.body }),
|
|
4996
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4997
|
+
reactNative.TouchableOpacity,
|
|
4998
|
+
{
|
|
4999
|
+
ref: actionRef,
|
|
5000
|
+
accessibilityHint: labels.actionHint,
|
|
5001
|
+
accessibilityLabel: labels.action,
|
|
5002
|
+
accessibilityRole: "button",
|
|
5003
|
+
style: styles3.primaryButton,
|
|
5004
|
+
testID: actionTestID,
|
|
5005
|
+
onPress: onContinue,
|
|
5006
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.primaryButtonText, children: labels.action })
|
|
5007
|
+
}
|
|
5008
|
+
)
|
|
5009
|
+
] });
|
|
5010
|
+
}
|
|
5011
|
+
|
|
4779
5012
|
// src/verify/VerifyEmailPhase.ts
|
|
4780
5013
|
var VerifyEmailPhase = /* @__PURE__ */ ((VerifyEmailPhase2) => {
|
|
4781
5014
|
VerifyEmailPhase2["Loading"] = "loading";
|
|
4782
5015
|
VerifyEmailPhase2["Success"] = "success";
|
|
4783
5016
|
VerifyEmailPhase2["Failure"] = "failure";
|
|
5017
|
+
VerifyEmailPhase2["NewPasswordRequired"] = "newPasswordRequired";
|
|
4784
5018
|
return VerifyEmailPhase2;
|
|
4785
5019
|
})(VerifyEmailPhase || {});
|
|
4786
5020
|
|
|
4787
|
-
// src/verify/
|
|
5021
|
+
// src/verify/resolveVerifyView.ts
|
|
5022
|
+
function resolveVerifyView(verify, passwordOutcome) {
|
|
5023
|
+
if (passwordOutcome === null) {
|
|
5024
|
+
return verify;
|
|
5025
|
+
}
|
|
5026
|
+
if (passwordOutcome.success) {
|
|
5027
|
+
return { phase: "success" /* Success */, errorCode: "GENERIC" /* Generic */ };
|
|
5028
|
+
}
|
|
5029
|
+
return { phase: "failure" /* Failure */, errorCode: passwordOutcome.errorCode };
|
|
5030
|
+
}
|
|
4788
5031
|
var LOADING = {
|
|
4789
5032
|
phase: "loading" /* Loading */,
|
|
4790
5033
|
errorCode: "GENERIC" /* Generic */
|
|
@@ -4793,6 +5036,10 @@ var SUCCESS = {
|
|
|
4793
5036
|
phase: "success" /* Success */,
|
|
4794
5037
|
errorCode: "GENERIC" /* Generic */
|
|
4795
5038
|
};
|
|
5039
|
+
var NEW_PASSWORD_REQUIRED = {
|
|
5040
|
+
phase: "newPasswordRequired" /* NewPasswordRequired */,
|
|
5041
|
+
errorCode: "GENERIC" /* Generic */
|
|
5042
|
+
};
|
|
4796
5043
|
var REJECTED = { success: false, errorCode: "GENERIC" /* Generic */ };
|
|
4797
5044
|
function failure(errorCode) {
|
|
4798
5045
|
return { phase: "failure" /* Failure */, errorCode };
|
|
@@ -4818,6 +5065,10 @@ function useVerifyEmail({ client, token, onVerified, onFailed }) {
|
|
|
4818
5065
|
latest.current.onVerified?.();
|
|
4819
5066
|
return;
|
|
4820
5067
|
}
|
|
5068
|
+
if (result.errorCode === "NEW_PASSWORD_REQUIRED" /* NewPasswordRequired */) {
|
|
5069
|
+
setState(NEW_PASSWORD_REQUIRED);
|
|
5070
|
+
return;
|
|
5071
|
+
}
|
|
4821
5072
|
setState(failure(result.errorCode));
|
|
4822
5073
|
latest.current.onFailed?.(result.errorCode);
|
|
4823
5074
|
};
|
|
@@ -4843,6 +5094,12 @@ function verifyEmailErrorText(code, labels) {
|
|
|
4843
5094
|
if (code === "MISSING_TOKEN" /* MissingToken */) {
|
|
4844
5095
|
return labels.missingToken;
|
|
4845
5096
|
}
|
|
5097
|
+
if (code === "SIGN_IN_FAILED" /* SignInFailed */) {
|
|
5098
|
+
return labels.signIn?.body ?? DEFAULT_VERIFY_SIGN_IN_LABELS.body;
|
|
5099
|
+
}
|
|
5100
|
+
if (code === "RATE_LIMITED" /* RateLimited */) {
|
|
5101
|
+
return labels.errorRateLimited ?? labels.errorGeneric;
|
|
5102
|
+
}
|
|
4846
5103
|
return labels.errorGeneric;
|
|
4847
5104
|
}
|
|
4848
5105
|
function ResendCta({ label, hint, style, textStyle, testID, onPress }) {
|
|
@@ -4879,7 +5136,20 @@ function VerifyEmailScreen({
|
|
|
4879
5136
|
() => ({ ...DEFAULT_VERIFY_EMAIL_LABELS, ...labelsProp }),
|
|
4880
5137
|
[labelsProp]
|
|
4881
5138
|
);
|
|
4882
|
-
const
|
|
5139
|
+
const verify = useVerifyEmail({ client, token, onVerified, onFailed });
|
|
5140
|
+
const [passwordOutcome, setPasswordOutcome] = react.useState(null);
|
|
5141
|
+
const { phase, errorCode } = resolveVerifyView(verify, passwordOutcome);
|
|
5142
|
+
const settlePassword = react.useCallback(
|
|
5143
|
+
(result) => {
|
|
5144
|
+
setPasswordOutcome(result);
|
|
5145
|
+
if (result.success) {
|
|
5146
|
+
onVerified?.();
|
|
5147
|
+
return;
|
|
5148
|
+
}
|
|
5149
|
+
onFailed?.(result.errorCode);
|
|
5150
|
+
},
|
|
5151
|
+
[onFailed, onVerified]
|
|
5152
|
+
);
|
|
4883
5153
|
const [resendOpen, setResendOpen] = react.useState(false);
|
|
4884
5154
|
const openResend = react.useCallback(() => setResendOpen(true), []);
|
|
4885
5155
|
const id = (base) => withTestIdPrefix(base, testIdPrefix);
|
|
@@ -4889,6 +5159,18 @@ function VerifyEmailScreen({
|
|
|
4889
5159
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { accessibilityRole: "header", style: styles3.title, children: labels.loadingTitle }),
|
|
4890
5160
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.subtitle, children: labels.loadingHint })
|
|
4891
5161
|
] }) : null,
|
|
5162
|
+
phase === "newPasswordRequired" /* NewPasswordRequired */ ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5163
|
+
VerifyNewPasswordStep,
|
|
5164
|
+
{
|
|
5165
|
+
client,
|
|
5166
|
+
labels: labels.newPassword,
|
|
5167
|
+
styles: styles3,
|
|
5168
|
+
testIdPrefix,
|
|
5169
|
+
theme,
|
|
5170
|
+
token,
|
|
5171
|
+
onSettled: settlePassword
|
|
5172
|
+
}
|
|
5173
|
+
) : null,
|
|
4892
5174
|
phase === "success" /* Success */ ? /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { testID: id(AuthTestIds.verifyEmailSuccess), children: [
|
|
4893
5175
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { accessibilityRole: "header", style: styles3.title, children: labels.successTitle }),
|
|
4894
5176
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.subtitle, children: labels.successBody }),
|
|
@@ -4905,7 +5187,17 @@ function VerifyEmailScreen({
|
|
|
4905
5187
|
}
|
|
4906
5188
|
)
|
|
4907
5189
|
] }) : null,
|
|
4908
|
-
phase === "failure" /* Failure */ ? /* @__PURE__ */ jsxRuntime.
|
|
5190
|
+
phase === "failure" /* Failure */ && errorCode === "SIGN_IN_FAILED" /* SignInFailed */ ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5191
|
+
VerifySignInPrompt,
|
|
5192
|
+
{
|
|
5193
|
+
actionTestID: id(AuthTestIds.verifyEmailSignInContinue),
|
|
5194
|
+
labels: labels.signIn,
|
|
5195
|
+
styles: styles3,
|
|
5196
|
+
testID: id(AuthTestIds.verifyEmailSignIn),
|
|
5197
|
+
onContinue
|
|
5198
|
+
}
|
|
5199
|
+
) : null,
|
|
5200
|
+
phase === "failure" /* Failure */ && errorCode !== "SIGN_IN_FAILED" /* SignInFailed */ ? /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { testID: id(AuthTestIds.verifyEmailError), children: [
|
|
4909
5201
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { accessibilityRole: "header", style: styles3.title, children: labels.errorTitle }),
|
|
4910
5202
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.errorBody, children: verifyEmailErrorText(errorCode, labels) }),
|
|
4911
5203
|
resendOpen ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4943,7 +5235,7 @@ var SERVER_ERROR_CODES2 = [
|
|
|
4943
5235
|
"TOKEN_USED" /* TokenUsed */,
|
|
4944
5236
|
"KEYCLOAK_UPDATE_FAILED" /* KeycloakUpdateFailed */
|
|
4945
5237
|
];
|
|
4946
|
-
var
|
|
5238
|
+
var GENERIC_FAILURE2 = { success: false, errorCode: "GENERIC" /* Generic */ };
|
|
4947
5239
|
var INVALID_TOKEN = { success: false, errorCode: "TOKEN_INVALID" /* TokenInvalid */ };
|
|
4948
5240
|
var HTTP_BAD_REQUEST3 = 400;
|
|
4949
5241
|
var TOKEN_FIELD = "token";
|
|
@@ -4968,7 +5260,7 @@ function isTokenValidationRejection(status, body) {
|
|
|
4968
5260
|
}
|
|
4969
5261
|
function decodeVerifyResponse(status, body) {
|
|
4970
5262
|
if (!isRecord3(body)) {
|
|
4971
|
-
return
|
|
5263
|
+
return GENERIC_FAILURE2;
|
|
4972
5264
|
}
|
|
4973
5265
|
if (body.success === true) {
|
|
4974
5266
|
return { success: true };
|
|
@@ -4976,7 +5268,7 @@ function decodeVerifyResponse(status, body) {
|
|
|
4976
5268
|
if (isServerErrorCode(body.errorCode)) {
|
|
4977
5269
|
return { success: false, errorCode: body.errorCode };
|
|
4978
5270
|
}
|
|
4979
|
-
return isTokenValidationRejection(status, body) ? INVALID_TOKEN :
|
|
5271
|
+
return isTokenValidationRejection(status, body) ? INVALID_TOKEN : GENERIC_FAILURE2;
|
|
4980
5272
|
}
|
|
4981
5273
|
function createBffVerifyEmailClient(options = {}) {
|
|
4982
5274
|
const http = options.http ?? lazyFetchHttpClient3;
|
|
@@ -4994,7 +5286,7 @@ function createBffVerifyEmailClient(options = {}) {
|
|
|
4994
5286
|
const response = await post(VERIFY_EMAIL_ENDPOINT, { token });
|
|
4995
5287
|
return decodeVerifyResponse(response.status, response.data);
|
|
4996
5288
|
} catch {
|
|
4997
|
-
return
|
|
5289
|
+
return GENERIC_FAILURE2;
|
|
4998
5290
|
}
|
|
4999
5291
|
},
|
|
5000
5292
|
resendVerification: async (email, verifyUrlTemplate) => {
|
|
@@ -5034,6 +5326,122 @@ function readVerifyToken(raw) {
|
|
|
5034
5326
|
return typeof first === "string" ? first : "";
|
|
5035
5327
|
}
|
|
5036
5328
|
|
|
5329
|
+
// src/verify/sharedRegistrationClient.ts
|
|
5330
|
+
var REGISTER_ENDPOINT = "/bff/register";
|
|
5331
|
+
var VERIFY_AND_LOGIN_ENDPOINT = "/bff/verify-and-login";
|
|
5332
|
+
var HTTP_ACCEPTED = 202;
|
|
5333
|
+
var HTTP_UNAUTHORIZED2 = 401;
|
|
5334
|
+
var HTTP_TOO_MANY_REQUESTS2 = 429;
|
|
5335
|
+
var NO_MESSAGE = "";
|
|
5336
|
+
var GENERIC_FAILURE3 = { success: false, errorCode: "GENERIC" /* Generic */ };
|
|
5337
|
+
function decodeVerifyAndLogin(response) {
|
|
5338
|
+
if (response.ok) {
|
|
5339
|
+
return { success: true };
|
|
5340
|
+
}
|
|
5341
|
+
if (response.status === HTTP_TOO_MANY_REQUESTS2) {
|
|
5342
|
+
return { success: false, errorCode: "RATE_LIMITED" /* RateLimited */ };
|
|
5343
|
+
}
|
|
5344
|
+
if (response.status === HTTP_UNAUTHORIZED2) {
|
|
5345
|
+
return { success: false, errorCode: "SIGN_IN_FAILED" /* SignInFailed */ };
|
|
5346
|
+
}
|
|
5347
|
+
const body = isRecord3(response.data) ? response.data : {};
|
|
5348
|
+
if (body.errorCode === "NEW_PASSWORD_REQUIRED" /* NewPasswordRequired */ || body.errorCode === "WEAK_PASSWORD" /* WeakPassword */) {
|
|
5349
|
+
return { success: false, errorCode: body.errorCode };
|
|
5350
|
+
}
|
|
5351
|
+
return decodeVerifyResponse(response.status, response.data);
|
|
5352
|
+
}
|
|
5353
|
+
function registerFailure(response) {
|
|
5354
|
+
const body = isRecord3(response.data) ? response.data : {};
|
|
5355
|
+
const errorCode = body.errorCode ?? body.code;
|
|
5356
|
+
const message = `Registration failed with status ${String(response.status)}`;
|
|
5357
|
+
return Object.assign(new Error(message), { status: response.status, errorCode });
|
|
5358
|
+
}
|
|
5359
|
+
function createSharedRegistrationClient(options = {}) {
|
|
5360
|
+
const http = options.http ?? lazyFetchHttpClient3;
|
|
5361
|
+
const baseUrl = options.baseUrl ?? "";
|
|
5362
|
+
const post = (path, body, headers = {}) => http({
|
|
5363
|
+
url: `${baseUrl}${path}`,
|
|
5364
|
+
method: "POST",
|
|
5365
|
+
headers: { "Content-Type": "application/json", "X-BFF-Csrf": "1", ...headers },
|
|
5366
|
+
body: JSON.stringify(body),
|
|
5367
|
+
credentials: "include"
|
|
5368
|
+
});
|
|
5369
|
+
const verifyAndLogin = async (body) => {
|
|
5370
|
+
try {
|
|
5371
|
+
return decodeVerifyAndLogin(await post(VERIFY_AND_LOGIN_ENDPOINT, body));
|
|
5372
|
+
} catch {
|
|
5373
|
+
return GENERIC_FAILURE3;
|
|
5374
|
+
}
|
|
5375
|
+
};
|
|
5376
|
+
const verifyEmailClient = createBffVerifyEmailClient(options);
|
|
5377
|
+
return {
|
|
5378
|
+
register: async (request, meta) => {
|
|
5379
|
+
const body = meta === void 0 ? request : { ...request, formElapsedMs: meta.formElapsedMs };
|
|
5380
|
+
const headers = meta === void 0 ? {} : { "Idempotency-Key": meta.idempotencyKey };
|
|
5381
|
+
const response = await post(REGISTER_ENDPOINT, body, headers).catch(() => {
|
|
5382
|
+
throw new Error(NO_MESSAGE);
|
|
5383
|
+
});
|
|
5384
|
+
if (!response.ok) {
|
|
5385
|
+
throw registerFailure(response);
|
|
5386
|
+
}
|
|
5387
|
+
return { accepted: response.status === HTTP_ACCEPTED, body: response.data };
|
|
5388
|
+
},
|
|
5389
|
+
verifyEmail: (token) => verifyAndLogin({ token }),
|
|
5390
|
+
setNewPassword: (token, newPassword) => verifyAndLogin({ token, newPassword }),
|
|
5391
|
+
resendVerification: (email, verifyUrlTemplate) => verifyEmailClient.resendVerification(email, verifyUrlTemplate)
|
|
5392
|
+
};
|
|
5393
|
+
}
|
|
5394
|
+
function RegisterCheckEmail({
|
|
5395
|
+
labels,
|
|
5396
|
+
styles: styles3,
|
|
5397
|
+
footer,
|
|
5398
|
+
testIdPrefix
|
|
5399
|
+
}) {
|
|
5400
|
+
const headingRef = react.useRef(null);
|
|
5401
|
+
useFocusOnMount(headingRef);
|
|
5402
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles3.screen, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5403
|
+
reactNative.View,
|
|
5404
|
+
{
|
|
5405
|
+
accessibilityLiveRegion: "polite",
|
|
5406
|
+
style: styles3.card,
|
|
5407
|
+
testID: withTestIdPrefix(RegisterTestIds.checkEmail, testIdPrefix),
|
|
5408
|
+
children: [
|
|
5409
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { ref: headingRef, accessible: true, focusable: true, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { accessibilityRole: "header", style: styles3.title, children: labels.checkEmailTitle }) }),
|
|
5410
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.subtitle, children: labels.checkEmailBody }),
|
|
5411
|
+
footer
|
|
5412
|
+
]
|
|
5413
|
+
}
|
|
5414
|
+
) });
|
|
5415
|
+
}
|
|
5416
|
+
function SharedRegisterForm({
|
|
5417
|
+
onSuccess,
|
|
5418
|
+
onAccepted,
|
|
5419
|
+
...formProps
|
|
5420
|
+
}) {
|
|
5421
|
+
const { footer, labels: labelsProp, testIdPrefix, theme: themeProp } = formProps;
|
|
5422
|
+
const styles3 = useAuthStyles(useAuthTheme(themeProp));
|
|
5423
|
+
const labels = react.useMemo(
|
|
5424
|
+
() => ({ ...DEFAULT_REGISTER_LABELS, ...labelsProp }),
|
|
5425
|
+
[labelsProp]
|
|
5426
|
+
);
|
|
5427
|
+
const [accepted, setAccepted] = react.useState(false);
|
|
5428
|
+
const handleResult = react.useCallback(
|
|
5429
|
+
(result) => {
|
|
5430
|
+
if (!isRegisterAccepted(result)) {
|
|
5431
|
+
onSuccess(result);
|
|
5432
|
+
return;
|
|
5433
|
+
}
|
|
5434
|
+
setAccepted(true);
|
|
5435
|
+
onAccepted?.(result);
|
|
5436
|
+
},
|
|
5437
|
+
[onAccepted, onSuccess]
|
|
5438
|
+
);
|
|
5439
|
+
if (accepted) {
|
|
5440
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RegisterCheckEmail, { footer, labels, styles: styles3, testIdPrefix });
|
|
5441
|
+
}
|
|
5442
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RegisterFormCore, { ...formProps, sharedRegistration: true, onSuccess: handleResult });
|
|
5443
|
+
}
|
|
5444
|
+
|
|
5037
5445
|
Object.defineProperty(exports, "BffAuthClient", {
|
|
5038
5446
|
enumerable: true,
|
|
5039
5447
|
get: function () { return authClient.BffAuthClient; }
|
|
@@ -5068,6 +5476,8 @@ exports.DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS = DEFAULT_PREFERRED_METHOD_SETT
|
|
|
5068
5476
|
exports.DEFAULT_REGISTER_LABELS = DEFAULT_REGISTER_LABELS;
|
|
5069
5477
|
exports.DEFAULT_RESET_PASSWORD_LABELS = DEFAULT_RESET_PASSWORD_LABELS;
|
|
5070
5478
|
exports.DEFAULT_VERIFY_EMAIL_LABELS = DEFAULT_VERIFY_EMAIL_LABELS;
|
|
5479
|
+
exports.DEFAULT_VERIFY_NEW_PASSWORD_LABELS = DEFAULT_VERIFY_NEW_PASSWORD_LABELS;
|
|
5480
|
+
exports.DEFAULT_VERIFY_SIGN_IN_LABELS = DEFAULT_VERIFY_SIGN_IN_LABELS;
|
|
5071
5481
|
exports.DEVICE_PIN_ALLOWED_DIGITS = DEVICE_PIN_ALLOWED_DIGITS;
|
|
5072
5482
|
exports.DEVICE_PIN_DEFAULT_DIGITS = DEVICE_PIN_DEFAULT_DIGITS;
|
|
5073
5483
|
exports.DemoCredentialsHint = DemoCredentialsHint;
|
|
@@ -5096,12 +5506,15 @@ exports.PinForm = PinForm;
|
|
|
5096
5506
|
exports.PreferredMethodHint = PreferredMethodHint;
|
|
5097
5507
|
exports.PreferredMethodSettingsCard = PreferredMethodSettingsCard;
|
|
5098
5508
|
exports.PrefillIntent = PrefillIntent;
|
|
5509
|
+
exports.REGISTER_ENDPOINT = REGISTER_ENDPOINT;
|
|
5099
5510
|
exports.RESEND_VERIFICATION_ENDPOINT = RESEND_VERIFICATION_ENDPOINT;
|
|
5100
5511
|
exports.RegisterErrorCode = RegisterErrorCode;
|
|
5101
5512
|
exports.RegisterForm = RegisterForm;
|
|
5102
5513
|
exports.RegisterTestIds = RegisterTestIds;
|
|
5103
5514
|
exports.ResetPasswordError = ResetPasswordError;
|
|
5104
5515
|
exports.ResetPasswordForm = ResetPasswordForm;
|
|
5516
|
+
exports.SharedRegisterForm = SharedRegisterForm;
|
|
5517
|
+
exports.VERIFY_AND_LOGIN_ENDPOINT = VERIFY_AND_LOGIN_ENDPOINT;
|
|
5105
5518
|
exports.VERIFY_EMAIL_ENDPOINT = VERIFY_EMAIL_ENDPOINT;
|
|
5106
5519
|
exports.VERIFY_TOKEN_PLACEHOLDER = VERIFY_TOKEN_PLACEHOLDER;
|
|
5107
5520
|
exports.VerifyEmailErrorCode = VerifyEmailErrorCode;
|
|
@@ -5115,10 +5528,12 @@ exports.createBffAuthClient = createBffAuthClient;
|
|
|
5115
5528
|
exports.createBffChangePasswordClient = createBffChangePasswordClient;
|
|
5116
5529
|
exports.createBffVerifyEmailClient = createBffVerifyEmailClient;
|
|
5117
5530
|
exports.createPreferencesClient = createPreferencesClient;
|
|
5531
|
+
exports.createSharedRegistrationClient = createSharedRegistrationClient;
|
|
5118
5532
|
exports.defaultAuthTheme = defaultAuthTheme;
|
|
5119
5533
|
exports.deriveUsernameFromEmail = deriveUsernameFromEmail;
|
|
5120
5534
|
exports.isAllowedPinDigits = isAllowedPinDigits;
|
|
5121
5535
|
exports.isPasswordValid = isPasswordValid;
|
|
5536
|
+
exports.isRegisterAccepted = isRegisterAccepted;
|
|
5122
5537
|
exports.isRegisterPasswordStrong = isRegisterPasswordStrong;
|
|
5123
5538
|
exports.isValidForgotPasswordEmail = isValidForgotPasswordEmail;
|
|
5124
5539
|
exports.performBffLogout = performBffLogout;
|