@dloizides/auth-web 1.3.0 → 1.4.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.d.mts +706 -1
- package/dist/index.d.ts +706 -1
- package/dist/index.js +1152 -90
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1128 -92
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, useState, useRef, useEffect, useCallback, useMemo, useContext } from 'react';
|
|
2
|
-
import { View, Text, TextInput, TouchableOpacity, ActivityIndicator,
|
|
2
|
+
import { StyleSheet, View, Text, TextInput, TouchableOpacity, ActivityIndicator, Pressable } from 'react-native';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import { useMutation } from '@tanstack/react-query';
|
|
5
5
|
import { BffAuthClient, createFetchHttpClient } from '@dloizides/auth-client';
|
|
@@ -68,6 +68,77 @@ var DEFAULT_PIN_LABELS = {
|
|
|
68
68
|
missingPin: "Enter your event PIN.",
|
|
69
69
|
invalidPin: "That PIN is incorrect, has expired, or is locked out."
|
|
70
70
|
};
|
|
71
|
+
var DEFAULT_DEVICE_PIN_UNLOCK_LABELS = {
|
|
72
|
+
title: "Welcome back, {name}",
|
|
73
|
+
titleNoName: "Welcome back",
|
|
74
|
+
description: "Enter your {count}-digit PIN to sign in on this device.",
|
|
75
|
+
pinLabel: "PIN",
|
|
76
|
+
pinPlaceholder: "Enter your PIN",
|
|
77
|
+
submit: "Unlock",
|
|
78
|
+
submitting: "Signing in...",
|
|
79
|
+
usePasswordInstead: "Sign in with password instead",
|
|
80
|
+
usePasswordHint: "Switch to signing in with your username and password",
|
|
81
|
+
errorIncomplete: "Enter all {count} digits of your PIN.",
|
|
82
|
+
errorInvalid: "That PIN is incorrect. Try again.",
|
|
83
|
+
errorLockedOut: "Too many attempts. Try again later.",
|
|
84
|
+
errorLockedOutRetry: "Too many attempts. Try again in {count} seconds.",
|
|
85
|
+
errorRateLimited: "Too many requests. Try again later.",
|
|
86
|
+
errorRateLimitedRetry: "Too many requests. Try again in {count} seconds.",
|
|
87
|
+
errorGeneric: "Something went wrong. Try again, or sign in with your password.",
|
|
88
|
+
digitFilledHint: "PIN digit entered",
|
|
89
|
+
digitEmptyHint: "PIN digit not yet entered"
|
|
90
|
+
};
|
|
91
|
+
var DEFAULT_DEVICE_PIN_ENROLL_LABELS = {
|
|
92
|
+
offerTitle: "Set a PIN for faster sign-in?",
|
|
93
|
+
offerDescription: "Next time, sign in on this device with a short PIN instead of your full password.",
|
|
94
|
+
offerAccept: "Set up a PIN",
|
|
95
|
+
offerAcceptHint: "Open the form to choose a quick sign-in PIN",
|
|
96
|
+
offerSkip: "Not now",
|
|
97
|
+
offerSkipHint: "Dismiss the PIN setup offer",
|
|
98
|
+
formTitle: "Choose your PIN",
|
|
99
|
+
formDescription: "Pick a {count}-digit PIN you will remember. You will use it to sign in on this device.",
|
|
100
|
+
lengthLabel: "PIN length",
|
|
101
|
+
lengthOptionHint: "Use a {count}-digit PIN",
|
|
102
|
+
pinLabel: "New PIN",
|
|
103
|
+
pinPlaceholder: "Enter a new PIN",
|
|
104
|
+
confirmLabel: "Confirm PIN",
|
|
105
|
+
confirmPlaceholder: "Re-enter your PIN",
|
|
106
|
+
submit: "Save PIN",
|
|
107
|
+
submitting: "Saving...",
|
|
108
|
+
cancel: "Cancel",
|
|
109
|
+
cancelHint: "Close the PIN setup form without saving",
|
|
110
|
+
errorMismatch: "The PINs must match and be exactly {count} digits.",
|
|
111
|
+
errorUnauthorized: "Your session has expired. Sign in again to set a PIN.",
|
|
112
|
+
errorForbidden: "A PIN is already set for this session.",
|
|
113
|
+
errorInvalidPin: "That PIN is not allowed. Choose a different one.",
|
|
114
|
+
errorFailed: "Could not set your PIN. Try again later."
|
|
115
|
+
};
|
|
116
|
+
var DEFAULT_DEVICE_PIN_SETTINGS_LABELS = {
|
|
117
|
+
title: "Quick PIN sign-in",
|
|
118
|
+
description: "Sign in on this device with a short PIN instead of your full password.",
|
|
119
|
+
statusEnabled: "Quick PIN sign-in is enabled on this device.",
|
|
120
|
+
statusDisabled: "Quick PIN sign-in is off.",
|
|
121
|
+
enable: "Enable quick PIN sign-in",
|
|
122
|
+
enableHint: "Set a PIN so you can sign in faster on this device",
|
|
123
|
+
disable: "Disable",
|
|
124
|
+
disableHint: "Remove the PIN sign-in from this device",
|
|
125
|
+
disabling: "Disabling...",
|
|
126
|
+
disableFailed: "Could not disable PIN sign-in. Try again later."
|
|
127
|
+
};
|
|
128
|
+
var DEFAULT_PASSKEY_LOGIN_LABELS = {
|
|
129
|
+
signInButton: "Sign in with a passkey",
|
|
130
|
+
signInHint: "Use your fingerprint, face, or security key to sign in",
|
|
131
|
+
errorCancelled: "Passkey sign-in was cancelled. You can try again or sign in another way.",
|
|
132
|
+
errorFailed: "Passkey sign-in didn't work. Try again, or sign in another way."
|
|
133
|
+
};
|
|
134
|
+
var DEFAULT_PASSKEY_SETTINGS_LABELS = {
|
|
135
|
+
title: "Passkeys",
|
|
136
|
+
description: "Add a passkey to sign in with your fingerprint, face, or a security key instead of a password.",
|
|
137
|
+
reauthHint: "You'll be asked to confirm your password before adding a passkey.",
|
|
138
|
+
addButton: "Add a passkey",
|
|
139
|
+
addHint: "Start setting up a passkey for this account",
|
|
140
|
+
registeredSuccess: "Your passkey was added. You can now use it to sign in."
|
|
141
|
+
};
|
|
71
142
|
var DEFAULT_RESET_PASSWORD_LABELS = {
|
|
72
143
|
title: "Reset password",
|
|
73
144
|
description: "Choose a new password for your account.",
|
|
@@ -116,7 +187,39 @@ var AuthTestIds = {
|
|
|
116
187
|
pinForm: "auth-pin-form",
|
|
117
188
|
pinInput: "auth-pin-input",
|
|
118
189
|
pinSubmitButton: "auth-pin-submit",
|
|
119
|
-
pinError: "auth-pin-error"
|
|
190
|
+
pinError: "auth-pin-error",
|
|
191
|
+
// Device-PIN unlock gate
|
|
192
|
+
devicePinUnlock: "auth-device-pin-unlock",
|
|
193
|
+
devicePinUnlockInput: "auth-device-pin-unlock-input",
|
|
194
|
+
devicePinUnlockSubmit: "auth-device-pin-unlock-submit",
|
|
195
|
+
devicePinUnlockUsePassword: "auth-device-pin-unlock-use-password",
|
|
196
|
+
devicePinUnlockError: "auth-device-pin-unlock-error",
|
|
197
|
+
// Device-PIN enrol form + length picker
|
|
198
|
+
devicePinEnrollForm: "auth-device-pin-enroll-form",
|
|
199
|
+
devicePinEnrollLength: "auth-device-pin-enroll-length",
|
|
200
|
+
devicePinEnrollPin: "auth-device-pin-enroll-pin",
|
|
201
|
+
devicePinEnrollConfirm: "auth-device-pin-enroll-confirm",
|
|
202
|
+
devicePinEnrollSubmit: "auth-device-pin-enroll-submit",
|
|
203
|
+
devicePinEnrollCancel: "auth-device-pin-enroll-cancel",
|
|
204
|
+
devicePinEnrollError: "auth-device-pin-enroll-error",
|
|
205
|
+
// Device-PIN offer (post-login)
|
|
206
|
+
devicePinOffer: "auth-device-pin-offer",
|
|
207
|
+
devicePinOfferAccept: "auth-device-pin-offer-accept",
|
|
208
|
+
devicePinOfferSkip: "auth-device-pin-offer-skip",
|
|
209
|
+
// Device-PIN settings card
|
|
210
|
+
devicePinSettings: "auth-device-pin-settings",
|
|
211
|
+
devicePinSettingsStatus: "auth-device-pin-settings-status",
|
|
212
|
+
devicePinSettingsEnable: "auth-device-pin-settings-enable",
|
|
213
|
+
devicePinSettingsDisable: "auth-device-pin-settings-disable",
|
|
214
|
+
devicePinSettingsError: "auth-device-pin-settings-error",
|
|
215
|
+
// Passkey login button
|
|
216
|
+
passkeyLogin: "auth-passkey-login",
|
|
217
|
+
passkeyLoginButton: "auth-passkey-login-button",
|
|
218
|
+
passkeyLoginError: "auth-passkey-login-error",
|
|
219
|
+
// Passkey settings card
|
|
220
|
+
passkeySettings: "auth-passkey-settings",
|
|
221
|
+
passkeySettingsAdd: "auth-passkey-settings-add",
|
|
222
|
+
passkeySettingsSuccess: "auth-passkey-settings-success"
|
|
120
223
|
};
|
|
121
224
|
function withTestIdPrefix(baseId, prefix) {
|
|
122
225
|
return prefix === void 0 || prefix === "" ? baseId : `${prefix}-${baseId}`;
|
|
@@ -210,6 +313,32 @@ function useAuthStyles(theme) {
|
|
|
210
313
|
helperText: {
|
|
211
314
|
fontSize: typography.caption,
|
|
212
315
|
color: colors.textSecondary
|
|
316
|
+
},
|
|
317
|
+
escapeLink: {
|
|
318
|
+
alignSelf: "center",
|
|
319
|
+
marginTop: spacing.md,
|
|
320
|
+
paddingVertical: spacing.xs / 2
|
|
321
|
+
},
|
|
322
|
+
secondaryButton: {
|
|
323
|
+
borderRadius: radii.input,
|
|
324
|
+
borderWidth: 1,
|
|
325
|
+
borderColor: colors.primary,
|
|
326
|
+
paddingVertical: BUTTON_VERTICAL_PADDING,
|
|
327
|
+
alignItems: "center",
|
|
328
|
+
justifyContent: "center",
|
|
329
|
+
marginTop: spacing.sm,
|
|
330
|
+
backgroundColor: colors.surface
|
|
331
|
+
},
|
|
332
|
+
secondaryButtonText: {
|
|
333
|
+
fontSize: typography.body,
|
|
334
|
+
fontWeight: "600",
|
|
335
|
+
color: colors.primary
|
|
336
|
+
},
|
|
337
|
+
statusText: {
|
|
338
|
+
fontSize: typography.label,
|
|
339
|
+
fontWeight: "600",
|
|
340
|
+
marginTop: spacing.sm,
|
|
341
|
+
color: colors.text
|
|
213
342
|
}
|
|
214
343
|
});
|
|
215
344
|
}, [theme]);
|
|
@@ -371,7 +500,7 @@ function LoginForm({
|
|
|
371
500
|
testIdPrefix
|
|
372
501
|
}) {
|
|
373
502
|
const theme = useAuthTheme(themeProp);
|
|
374
|
-
const
|
|
503
|
+
const styles3 = useAuthStyles(theme);
|
|
375
504
|
const labels = useMemo(
|
|
376
505
|
() => ({ ...DEFAULT_LOGIN_LABELS, ...labelsProp }),
|
|
377
506
|
[labelsProp]
|
|
@@ -398,12 +527,12 @@ function LoginForm({
|
|
|
398
527
|
const handleSubmit = useCallback(() => {
|
|
399
528
|
void runLogin();
|
|
400
529
|
}, [runLogin]);
|
|
401
|
-
const submitButtonStyle = isSubmitting ? [
|
|
402
|
-
return /* @__PURE__ */ jsx(View, { style:
|
|
403
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
404
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
405
|
-
/* @__PURE__ */ jsxs(View, { style:
|
|
406
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
530
|
+
const submitButtonStyle = isSubmitting ? [styles3.primaryButton, styles3.primaryButtonDisabled] : styles3.primaryButton;
|
|
531
|
+
return /* @__PURE__ */ jsx(View, { style: styles3.screen, children: /* @__PURE__ */ jsxs(View, { style: styles3.card, testID: withTestIdPrefix(AuthTestIds.loginForm, testIdPrefix), children: [
|
|
532
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.title, children: labels.title }),
|
|
533
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: labels.subtitle }),
|
|
534
|
+
/* @__PURE__ */ jsxs(View, { style: styles3.fieldGroup, children: [
|
|
535
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.label, children: labels.usernameLabel }),
|
|
407
536
|
/* @__PURE__ */ jsx(
|
|
408
537
|
TextInput,
|
|
409
538
|
{
|
|
@@ -414,15 +543,15 @@ function LoginForm({
|
|
|
414
543
|
editable: !isSubmitting,
|
|
415
544
|
placeholder: labels.usernamePlaceholder,
|
|
416
545
|
placeholderTextColor: theme.colors.textSecondary,
|
|
417
|
-
style:
|
|
546
|
+
style: styles3.input,
|
|
418
547
|
testID: withTestIdPrefix(AuthTestIds.loginUsernameInput, testIdPrefix),
|
|
419
548
|
value: username,
|
|
420
549
|
onChangeText: setUsername
|
|
421
550
|
}
|
|
422
551
|
)
|
|
423
552
|
] }),
|
|
424
|
-
/* @__PURE__ */ jsxs(View, { style:
|
|
425
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
553
|
+
/* @__PURE__ */ jsxs(View, { style: styles3.fieldGroup, children: [
|
|
554
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.label, children: labels.passwordLabel }),
|
|
426
555
|
/* @__PURE__ */ jsx(
|
|
427
556
|
TextInput,
|
|
428
557
|
{
|
|
@@ -434,7 +563,7 @@ function LoginForm({
|
|
|
434
563
|
editable: !isSubmitting,
|
|
435
564
|
placeholder: labels.passwordPlaceholder,
|
|
436
565
|
placeholderTextColor: theme.colors.textSecondary,
|
|
437
|
-
style:
|
|
566
|
+
style: styles3.input,
|
|
438
567
|
testID: withTestIdPrefix(AuthTestIds.loginPasswordInput, testIdPrefix),
|
|
439
568
|
value: password,
|
|
440
569
|
onChangeText: setPassword
|
|
@@ -444,7 +573,7 @@ function LoginForm({
|
|
|
444
573
|
errorText !== null ? /* @__PURE__ */ jsx(
|
|
445
574
|
Text,
|
|
446
575
|
{
|
|
447
|
-
style:
|
|
576
|
+
style: styles3.errorText,
|
|
448
577
|
testID: withTestIdPrefix(AuthTestIds.loginError, testIdPrefix),
|
|
449
578
|
children: errorText
|
|
450
579
|
}
|
|
@@ -456,10 +585,10 @@ function LoginForm({
|
|
|
456
585
|
accessibilityLabel: labels.forgotPassword,
|
|
457
586
|
accessibilityRole: "link",
|
|
458
587
|
disabled: isSubmitting,
|
|
459
|
-
style:
|
|
588
|
+
style: styles3.fieldGroup,
|
|
460
589
|
testID: withTestIdPrefix(AuthTestIds.loginForgotLink, testIdPrefix),
|
|
461
590
|
onPress: onForgotPassword,
|
|
462
|
-
children: /* @__PURE__ */ jsx(Text, { style:
|
|
591
|
+
children: /* @__PURE__ */ jsx(Text, { style: styles3.linkText, children: labels.forgotPassword })
|
|
463
592
|
}
|
|
464
593
|
) : null,
|
|
465
594
|
/* @__PURE__ */ jsx(
|
|
@@ -472,7 +601,7 @@ function LoginForm({
|
|
|
472
601
|
style: submitButtonStyle,
|
|
473
602
|
testID: withTestIdPrefix(AuthTestIds.loginSubmitButton, testIdPrefix),
|
|
474
603
|
onPress: handleSubmit,
|
|
475
|
-
children: isSubmitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style:
|
|
604
|
+
children: isSubmitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.submit })
|
|
476
605
|
}
|
|
477
606
|
),
|
|
478
607
|
onSignUp !== void 0 ? /* @__PURE__ */ jsx(
|
|
@@ -482,10 +611,10 @@ function LoginForm({
|
|
|
482
611
|
accessibilityLabel: labels.signUp,
|
|
483
612
|
accessibilityRole: "link",
|
|
484
613
|
disabled: isSubmitting,
|
|
485
|
-
style:
|
|
614
|
+
style: styles3.fieldGroup,
|
|
486
615
|
testID: withTestIdPrefix(AuthTestIds.loginSignUpLink, testIdPrefix),
|
|
487
616
|
onPress: onSignUp,
|
|
488
|
-
children: /* @__PURE__ */ jsx(Text, { style:
|
|
617
|
+
children: /* @__PURE__ */ jsx(Text, { style: styles3.linkText, children: labels.signUp })
|
|
489
618
|
}
|
|
490
619
|
) : null
|
|
491
620
|
] }) });
|
|
@@ -523,7 +652,7 @@ function ForgotPasswordForm({
|
|
|
523
652
|
testIdPrefix
|
|
524
653
|
}) {
|
|
525
654
|
const theme = useAuthTheme(themeProp);
|
|
526
|
-
const
|
|
655
|
+
const styles3 = useAuthStyles(theme);
|
|
527
656
|
const labels = useMemo(
|
|
528
657
|
() => ({ ...DEFAULT_FORGOT_PASSWORD_LABELS, ...labelsProp }),
|
|
529
658
|
[labelsProp]
|
|
@@ -555,25 +684,25 @@ function ForgotPasswordForm({
|
|
|
555
684
|
}
|
|
556
685
|
mutation.mutate({ email: trimmedEmail, resetUrlTemplate });
|
|
557
686
|
}, [email, mutation, resetUrlTemplate, labels.invalidEmail]);
|
|
558
|
-
const submitButtonStyle = isPending ? [
|
|
559
|
-
return /* @__PURE__ */ jsx(View, { style:
|
|
687
|
+
const submitButtonStyle = isPending ? [styles3.primaryButton, styles3.primaryButtonDisabled] : styles3.primaryButton;
|
|
688
|
+
return /* @__PURE__ */ jsx(View, { style: styles3.screen, children: /* @__PURE__ */ jsxs(
|
|
560
689
|
View,
|
|
561
690
|
{
|
|
562
|
-
style:
|
|
691
|
+
style: styles3.card,
|
|
563
692
|
testID: withTestIdPrefix(AuthTestIds.forgotPasswordForm, testIdPrefix),
|
|
564
693
|
children: [
|
|
565
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
694
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.title, children: labels.title }),
|
|
566
695
|
submitted ? /* @__PURE__ */ jsx(
|
|
567
696
|
Text,
|
|
568
697
|
{
|
|
569
|
-
style:
|
|
698
|
+
style: styles3.successText,
|
|
570
699
|
testID: withTestIdPrefix(AuthTestIds.forgotPasswordSuccess, testIdPrefix),
|
|
571
700
|
children: labels.successMessage
|
|
572
701
|
}
|
|
573
702
|
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
574
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
575
|
-
/* @__PURE__ */ jsxs(View, { style:
|
|
576
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
703
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: labels.description }),
|
|
704
|
+
/* @__PURE__ */ jsxs(View, { style: styles3.fieldGroup, children: [
|
|
705
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.label, children: labels.emailLabel }),
|
|
577
706
|
/* @__PURE__ */ jsx(
|
|
578
707
|
TextInput,
|
|
579
708
|
{
|
|
@@ -585,7 +714,7 @@ function ForgotPasswordForm({
|
|
|
585
714
|
keyboardType: "email-address",
|
|
586
715
|
placeholder: labels.emailPlaceholder,
|
|
587
716
|
placeholderTextColor: theme.colors.textSecondary,
|
|
588
|
-
style:
|
|
717
|
+
style: styles3.input,
|
|
589
718
|
testID: withTestIdPrefix(AuthTestIds.forgotPasswordEmailInput, testIdPrefix),
|
|
590
719
|
value: email,
|
|
591
720
|
onChangeText: setEmail
|
|
@@ -595,7 +724,7 @@ function ForgotPasswordForm({
|
|
|
595
724
|
errorText !== null ? /* @__PURE__ */ jsx(
|
|
596
725
|
Text,
|
|
597
726
|
{
|
|
598
|
-
style:
|
|
727
|
+
style: styles3.errorText,
|
|
599
728
|
testID: withTestIdPrefix(AuthTestIds.forgotPasswordError, testIdPrefix),
|
|
600
729
|
children: errorText
|
|
601
730
|
}
|
|
@@ -610,7 +739,7 @@ function ForgotPasswordForm({
|
|
|
610
739
|
style: submitButtonStyle,
|
|
611
740
|
testID: withTestIdPrefix(AuthTestIds.forgotPasswordSubmitButton, testIdPrefix),
|
|
612
741
|
onPress: handleSubmit,
|
|
613
|
-
children: isPending ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style:
|
|
742
|
+
children: isPending ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.submit })
|
|
614
743
|
}
|
|
615
744
|
)
|
|
616
745
|
] })
|
|
@@ -702,7 +831,7 @@ function ForgotPasswordFields({
|
|
|
702
831
|
testIdPrefix
|
|
703
832
|
}) {
|
|
704
833
|
const theme = useAuthTheme(themeProp);
|
|
705
|
-
const
|
|
834
|
+
const styles3 = useAuthStyles(theme);
|
|
706
835
|
const modalStyles = useModalStyles(theme);
|
|
707
836
|
const labels = useMemo(
|
|
708
837
|
() => ({ ...DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS, ...labelsProp }),
|
|
@@ -715,7 +844,7 @@ function ForgotPasswordFields({
|
|
|
715
844
|
reset();
|
|
716
845
|
}
|
|
717
846
|
}, [visible, reset]);
|
|
718
|
-
const submitButtonStyle = form.canSubmit ?
|
|
847
|
+
const submitButtonStyle = form.canSubmit ? styles3.primaryButton : [styles3.primaryButton, styles3.primaryButtonDisabled];
|
|
719
848
|
const handleCancel = () => {
|
|
720
849
|
form.reset();
|
|
721
850
|
onCancel?.();
|
|
@@ -726,25 +855,25 @@ function ForgotPasswordFields({
|
|
|
726
855
|
};
|
|
727
856
|
if (form.submitted) {
|
|
728
857
|
return /* @__PURE__ */ jsxs(View, { style: modalStyles.body, testID: withTestIdPrefix(AuthTestIds.forgotPasswordForm, testIdPrefix), children: [
|
|
729
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
858
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.successText, testID: withTestIdPrefix(AuthTestIds.forgotPasswordSuccess, testIdPrefix), children: labels.successMessage }),
|
|
730
859
|
onClose !== void 0 ? /* @__PURE__ */ jsx(View, { style: modalStyles.actions, children: /* @__PURE__ */ jsx(
|
|
731
860
|
TouchableOpacity,
|
|
732
861
|
{
|
|
733
862
|
accessibilityHint: labels.close,
|
|
734
863
|
accessibilityLabel: labels.close,
|
|
735
864
|
accessibilityRole: "button",
|
|
736
|
-
style:
|
|
865
|
+
style: styles3.primaryButton,
|
|
737
866
|
testID: withTestIdPrefix(AuthTestIds.forgotPasswordCloseButton, testIdPrefix),
|
|
738
867
|
onPress: handleClose,
|
|
739
|
-
children: /* @__PURE__ */ jsx(Text, { style:
|
|
868
|
+
children: /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.close })
|
|
740
869
|
}
|
|
741
870
|
) }) : null
|
|
742
871
|
] });
|
|
743
872
|
}
|
|
744
873
|
return /* @__PURE__ */ jsxs(View, { style: modalStyles.body, testID: withTestIdPrefix(AuthTestIds.forgotPasswordForm, testIdPrefix), children: [
|
|
745
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
746
|
-
/* @__PURE__ */ jsxs(View, { style:
|
|
747
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
874
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: labels.description }),
|
|
875
|
+
/* @__PURE__ */ jsxs(View, { style: styles3.fieldGroup, children: [
|
|
876
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.label, children: labels.emailLabel }),
|
|
748
877
|
/* @__PURE__ */ jsx(
|
|
749
878
|
TextInput,
|
|
750
879
|
{
|
|
@@ -756,14 +885,14 @@ function ForgotPasswordFields({
|
|
|
756
885
|
keyboardType: "email-address",
|
|
757
886
|
placeholder: labels.emailPlaceholder,
|
|
758
887
|
placeholderTextColor: theme.colors.textSecondary,
|
|
759
|
-
style:
|
|
888
|
+
style: styles3.input,
|
|
760
889
|
testID: withTestIdPrefix(AuthTestIds.forgotPasswordEmailInput, testIdPrefix),
|
|
761
890
|
value: form.email,
|
|
762
891
|
onChangeText: form.setEmail
|
|
763
892
|
}
|
|
764
893
|
)
|
|
765
894
|
] }),
|
|
766
|
-
form.hasNetworkError ? /* @__PURE__ */ jsx(Text, { style:
|
|
895
|
+
form.hasNetworkError ? /* @__PURE__ */ jsx(Text, { style: styles3.errorText, testID: withTestIdPrefix(AuthTestIds.forgotPasswordError, testIdPrefix), children: labels.networkError }) : null,
|
|
767
896
|
/* @__PURE__ */ jsxs(View, { style: modalStyles.actions, children: [
|
|
768
897
|
onCancel !== void 0 ? /* @__PURE__ */ jsx(
|
|
769
898
|
TouchableOpacity,
|
|
@@ -788,7 +917,7 @@ function ForgotPasswordFields({
|
|
|
788
917
|
style: submitButtonStyle,
|
|
789
918
|
testID: withTestIdPrefix(AuthTestIds.forgotPasswordSubmitButton, testIdPrefix),
|
|
790
919
|
onPress: form.submit,
|
|
791
|
-
children: form.isSubmitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style:
|
|
920
|
+
children: form.isSubmitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.submit })
|
|
792
921
|
}
|
|
793
922
|
)
|
|
794
923
|
] })
|
|
@@ -967,24 +1096,24 @@ function ResetPasswordForm({
|
|
|
967
1096
|
testIdPrefix
|
|
968
1097
|
}) {
|
|
969
1098
|
const theme = useAuthTheme(themeProp);
|
|
970
|
-
const
|
|
1099
|
+
const styles3 = useAuthStyles(theme);
|
|
971
1100
|
const labels = useMemo(
|
|
972
1101
|
() => ({ ...DEFAULT_RESET_PASSWORD_LABELS, ...labelsProp }),
|
|
973
1102
|
[labelsProp]
|
|
974
1103
|
);
|
|
975
1104
|
const form = useResetPasswordForm({ client, token, onSuccess });
|
|
976
1105
|
const message = errorMessage(form.errorKey, labels);
|
|
977
|
-
const submitButtonStyle = form.isSubmitting ? [
|
|
978
|
-
return /* @__PURE__ */ jsx(View, { style:
|
|
1106
|
+
const submitButtonStyle = form.isSubmitting ? [styles3.primaryButton, styles3.primaryButtonDisabled] : styles3.primaryButton;
|
|
1107
|
+
return /* @__PURE__ */ jsx(View, { style: styles3.screen, children: /* @__PURE__ */ jsxs(
|
|
979
1108
|
View,
|
|
980
1109
|
{
|
|
981
|
-
style:
|
|
1110
|
+
style: styles3.card,
|
|
982
1111
|
testID: withTestIdPrefix(AuthTestIds.resetPasswordForm, testIdPrefix),
|
|
983
1112
|
children: [
|
|
984
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
985
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
986
|
-
/* @__PURE__ */ jsxs(View, { style:
|
|
987
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
1113
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.title, children: labels.title }),
|
|
1114
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: labels.description }),
|
|
1115
|
+
/* @__PURE__ */ jsxs(View, { style: styles3.fieldGroup, children: [
|
|
1116
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.label, children: labels.newPasswordLabel }),
|
|
988
1117
|
/* @__PURE__ */ jsx(
|
|
989
1118
|
TextInput,
|
|
990
1119
|
{
|
|
@@ -996,15 +1125,15 @@ function ResetPasswordForm({
|
|
|
996
1125
|
editable: !form.isSubmitting,
|
|
997
1126
|
placeholder: labels.newPasswordPlaceholder,
|
|
998
1127
|
placeholderTextColor: theme.colors.textSecondary,
|
|
999
|
-
style:
|
|
1128
|
+
style: styles3.input,
|
|
1000
1129
|
testID: withTestIdPrefix(AuthTestIds.resetPasswordNewInput, testIdPrefix),
|
|
1001
1130
|
value: form.newPassword,
|
|
1002
1131
|
onChangeText: form.setNewPassword
|
|
1003
1132
|
}
|
|
1004
1133
|
)
|
|
1005
1134
|
] }),
|
|
1006
|
-
/* @__PURE__ */ jsxs(View, { style:
|
|
1007
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
1135
|
+
/* @__PURE__ */ jsxs(View, { style: styles3.fieldGroup, children: [
|
|
1136
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.label, children: labels.confirmPasswordLabel }),
|
|
1008
1137
|
/* @__PURE__ */ jsx(
|
|
1009
1138
|
TextInput,
|
|
1010
1139
|
{
|
|
@@ -1016,7 +1145,7 @@ function ResetPasswordForm({
|
|
|
1016
1145
|
editable: !form.isSubmitting,
|
|
1017
1146
|
placeholder: labels.confirmPasswordPlaceholder,
|
|
1018
1147
|
placeholderTextColor: theme.colors.textSecondary,
|
|
1019
|
-
style:
|
|
1148
|
+
style: styles3.input,
|
|
1020
1149
|
testID: withTestIdPrefix(AuthTestIds.resetPasswordConfirmInput, testIdPrefix),
|
|
1021
1150
|
value: form.confirmPassword,
|
|
1022
1151
|
onChangeText: form.setConfirmPassword
|
|
@@ -1026,7 +1155,7 @@ function ResetPasswordForm({
|
|
|
1026
1155
|
message !== null ? /* @__PURE__ */ jsx(
|
|
1027
1156
|
Text,
|
|
1028
1157
|
{
|
|
1029
|
-
style:
|
|
1158
|
+
style: styles3.errorText,
|
|
1030
1159
|
testID: withTestIdPrefix(AuthTestIds.resetPasswordError, testIdPrefix),
|
|
1031
1160
|
children: message
|
|
1032
1161
|
}
|
|
@@ -1041,7 +1170,7 @@ function ResetPasswordForm({
|
|
|
1041
1170
|
style: submitButtonStyle,
|
|
1042
1171
|
testID: withTestIdPrefix(AuthTestIds.resetPasswordSubmitButton, testIdPrefix),
|
|
1043
1172
|
onPress: form.submit,
|
|
1044
|
-
children: form.isSubmitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style:
|
|
1173
|
+
children: form.isSubmitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.submit })
|
|
1045
1174
|
}
|
|
1046
1175
|
)
|
|
1047
1176
|
]
|
|
@@ -1049,7 +1178,7 @@ function ResetPasswordForm({
|
|
|
1049
1178
|
) });
|
|
1050
1179
|
}
|
|
1051
1180
|
function OtpRequestStep({
|
|
1052
|
-
styles,
|
|
1181
|
+
styles: styles3,
|
|
1053
1182
|
theme,
|
|
1054
1183
|
labels,
|
|
1055
1184
|
testIdPrefix,
|
|
@@ -1058,12 +1187,12 @@ function OtpRequestStep({
|
|
|
1058
1187
|
onSubmit
|
|
1059
1188
|
}) {
|
|
1060
1189
|
const [email, setEmail] = useState("");
|
|
1061
|
-
const buttonStyle = isSubmitting ? [
|
|
1190
|
+
const buttonStyle = isSubmitting ? [styles3.primaryButton, styles3.primaryButtonDisabled] : styles3.primaryButton;
|
|
1062
1191
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1063
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
1064
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
1065
|
-
/* @__PURE__ */ jsxs(View, { style:
|
|
1066
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
1192
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.title, children: labels.requestTitle }),
|
|
1193
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: labels.requestDescription }),
|
|
1194
|
+
/* @__PURE__ */ jsxs(View, { style: styles3.fieldGroup, children: [
|
|
1195
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.label, children: labels.emailLabel }),
|
|
1067
1196
|
/* @__PURE__ */ jsx(
|
|
1068
1197
|
TextInput,
|
|
1069
1198
|
{
|
|
@@ -1075,14 +1204,14 @@ function OtpRequestStep({
|
|
|
1075
1204
|
keyboardType: "email-address",
|
|
1076
1205
|
placeholder: labels.emailPlaceholder,
|
|
1077
1206
|
placeholderTextColor: theme.colors.textSecondary,
|
|
1078
|
-
style:
|
|
1207
|
+
style: styles3.input,
|
|
1079
1208
|
testID: withTestIdPrefix(AuthTestIds.otpEmailInput, testIdPrefix),
|
|
1080
1209
|
value: email,
|
|
1081
1210
|
onChangeText: setEmail
|
|
1082
1211
|
}
|
|
1083
1212
|
)
|
|
1084
1213
|
] }),
|
|
1085
|
-
errorText !== null ? /* @__PURE__ */ jsx(Text, { style:
|
|
1214
|
+
errorText !== null ? /* @__PURE__ */ jsx(Text, { style: styles3.errorText, testID: withTestIdPrefix(AuthTestIds.otpError, testIdPrefix), children: errorText }) : null,
|
|
1086
1215
|
/* @__PURE__ */ jsx(
|
|
1087
1216
|
TouchableOpacity,
|
|
1088
1217
|
{
|
|
@@ -1093,13 +1222,13 @@ function OtpRequestStep({
|
|
|
1093
1222
|
style: buttonStyle,
|
|
1094
1223
|
testID: withTestIdPrefix(AuthTestIds.otpRequestButton, testIdPrefix),
|
|
1095
1224
|
onPress: () => onSubmit(email.trim()),
|
|
1096
|
-
children: isSubmitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style:
|
|
1225
|
+
children: isSubmitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.requestSubmit })
|
|
1097
1226
|
}
|
|
1098
1227
|
)
|
|
1099
1228
|
] });
|
|
1100
1229
|
}
|
|
1101
1230
|
function OtpVerifyStep({
|
|
1102
|
-
styles,
|
|
1231
|
+
styles: styles3,
|
|
1103
1232
|
theme,
|
|
1104
1233
|
labels,
|
|
1105
1234
|
testIdPrefix,
|
|
@@ -1111,13 +1240,13 @@ function OtpVerifyStep({
|
|
|
1111
1240
|
onChangeEmail
|
|
1112
1241
|
}) {
|
|
1113
1242
|
const [code, setCode] = useState("");
|
|
1114
|
-
const buttonStyle = isSubmitting ? [
|
|
1243
|
+
const buttonStyle = isSubmitting ? [styles3.primaryButton, styles3.primaryButtonDisabled] : styles3.primaryButton;
|
|
1115
1244
|
const description = labels.verifyDescription.replace("{identifier}", identifier);
|
|
1116
1245
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1117
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
1118
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
1119
|
-
/* @__PURE__ */ jsxs(View, { style:
|
|
1120
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
1246
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.title, children: labels.verifyTitle }),
|
|
1247
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: description }),
|
|
1248
|
+
/* @__PURE__ */ jsxs(View, { style: styles3.fieldGroup, children: [
|
|
1249
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.label, children: labels.codeLabel }),
|
|
1121
1250
|
/* @__PURE__ */ jsx(
|
|
1122
1251
|
TextInput,
|
|
1123
1252
|
{
|
|
@@ -1129,14 +1258,14 @@ function OtpVerifyStep({
|
|
|
1129
1258
|
keyboardType: "number-pad",
|
|
1130
1259
|
placeholder: labels.codePlaceholder,
|
|
1131
1260
|
placeholderTextColor: theme.colors.textSecondary,
|
|
1132
|
-
style:
|
|
1261
|
+
style: styles3.input,
|
|
1133
1262
|
testID: withTestIdPrefix(AuthTestIds.otpCodeInput, testIdPrefix),
|
|
1134
1263
|
value: code,
|
|
1135
1264
|
onChangeText: setCode
|
|
1136
1265
|
}
|
|
1137
1266
|
)
|
|
1138
1267
|
] }),
|
|
1139
|
-
errorText !== null ? /* @__PURE__ */ jsx(Text, { style:
|
|
1268
|
+
errorText !== null ? /* @__PURE__ */ jsx(Text, { style: styles3.errorText, testID: withTestIdPrefix(AuthTestIds.otpError, testIdPrefix), children: errorText }) : null,
|
|
1140
1269
|
/* @__PURE__ */ jsx(
|
|
1141
1270
|
TouchableOpacity,
|
|
1142
1271
|
{
|
|
@@ -1147,7 +1276,7 @@ function OtpVerifyStep({
|
|
|
1147
1276
|
style: buttonStyle,
|
|
1148
1277
|
testID: withTestIdPrefix(AuthTestIds.otpVerifyButton, testIdPrefix),
|
|
1149
1278
|
onPress: () => onSubmit(code.trim()),
|
|
1150
|
-
children: isSubmitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style:
|
|
1279
|
+
children: isSubmitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.verifySubmit })
|
|
1151
1280
|
}
|
|
1152
1281
|
),
|
|
1153
1282
|
/* @__PURE__ */ jsx(
|
|
@@ -1157,10 +1286,10 @@ function OtpVerifyStep({
|
|
|
1157
1286
|
accessibilityLabel: isSubmitting ? labels.resending : labels.resend,
|
|
1158
1287
|
accessibilityRole: "link",
|
|
1159
1288
|
disabled: isSubmitting,
|
|
1160
|
-
style:
|
|
1289
|
+
style: styles3.fieldGroup,
|
|
1161
1290
|
testID: withTestIdPrefix(AuthTestIds.otpResendButton, testIdPrefix),
|
|
1162
1291
|
onPress: onResend,
|
|
1163
|
-
children: /* @__PURE__ */ jsx(Text, { style:
|
|
1292
|
+
children: /* @__PURE__ */ jsx(Text, { style: styles3.linkText, children: isSubmitting ? labels.resending : labels.resend })
|
|
1164
1293
|
}
|
|
1165
1294
|
),
|
|
1166
1295
|
/* @__PURE__ */ jsx(
|
|
@@ -1172,7 +1301,7 @@ function OtpVerifyStep({
|
|
|
1172
1301
|
disabled: isSubmitting,
|
|
1173
1302
|
testID: withTestIdPrefix(AuthTestIds.otpChangeEmailButton, testIdPrefix),
|
|
1174
1303
|
onPress: onChangeEmail,
|
|
1175
|
-
children: /* @__PURE__ */ jsx(Text, { style:
|
|
1304
|
+
children: /* @__PURE__ */ jsx(Text, { style: styles3.linkText, children: labels.changeEmail })
|
|
1176
1305
|
}
|
|
1177
1306
|
)
|
|
1178
1307
|
] });
|
|
@@ -1341,7 +1470,7 @@ function OtpForm({
|
|
|
1341
1470
|
testIdPrefix
|
|
1342
1471
|
}) {
|
|
1343
1472
|
const theme = useAuthTheme(themeProp);
|
|
1344
|
-
const
|
|
1473
|
+
const styles3 = useAuthStyles(theme);
|
|
1345
1474
|
const labels = useMemo(
|
|
1346
1475
|
() => ({ ...DEFAULT_OTP_LABELS, ...labelsProp }),
|
|
1347
1476
|
[labelsProp]
|
|
@@ -1359,13 +1488,13 @@ function OtpForm({
|
|
|
1359
1488
|
otp.reset();
|
|
1360
1489
|
}, [otp]);
|
|
1361
1490
|
const errorText = localError ?? transportErrorFor(otp.step, otp.error, labels);
|
|
1362
|
-
return /* @__PURE__ */ jsx(View, { style:
|
|
1491
|
+
return /* @__PURE__ */ jsx(View, { style: styles3.screen, children: /* @__PURE__ */ jsx(View, { style: styles3.card, testID: withTestIdPrefix(AuthTestIds.otpForm, testIdPrefix), children: otp.step === "requestCode" /* RequestCode */ ? /* @__PURE__ */ jsx(
|
|
1363
1492
|
OtpRequestStep,
|
|
1364
1493
|
{
|
|
1365
1494
|
errorText,
|
|
1366
1495
|
isSubmitting: otp.isSubmitting,
|
|
1367
1496
|
labels,
|
|
1368
|
-
styles,
|
|
1497
|
+
styles: styles3,
|
|
1369
1498
|
testIdPrefix,
|
|
1370
1499
|
theme,
|
|
1371
1500
|
onSubmit: handleRequest
|
|
@@ -1377,7 +1506,7 @@ function OtpForm({
|
|
|
1377
1506
|
identifier: otp.identifier,
|
|
1378
1507
|
isSubmitting: otp.isSubmitting,
|
|
1379
1508
|
labels,
|
|
1380
|
-
styles,
|
|
1509
|
+
styles: styles3,
|
|
1381
1510
|
testIdPrefix,
|
|
1382
1511
|
theme,
|
|
1383
1512
|
onChangeEmail: handleChangeEmail,
|
|
@@ -1466,7 +1595,7 @@ function PinForm({
|
|
|
1466
1595
|
testIdPrefix
|
|
1467
1596
|
}) {
|
|
1468
1597
|
const theme = useAuthTheme(themeProp);
|
|
1469
|
-
const
|
|
1598
|
+
const styles3 = useAuthStyles(theme);
|
|
1470
1599
|
const labels = useMemo(
|
|
1471
1600
|
() => ({ ...DEFAULT_PIN_LABELS, ...labelsProp }),
|
|
1472
1601
|
[labelsProp]
|
|
@@ -1476,12 +1605,12 @@ function PinForm({
|
|
|
1476
1605
|
const [pinValue, setPinValue] = useState("");
|
|
1477
1606
|
const handleSubmit = useSubmitHandler(pin, labels, setLocalError, onSuccess);
|
|
1478
1607
|
const errorText = localError ?? transportErrorFor2(pin.error, labels);
|
|
1479
|
-
const buttonStyle = pin.isSubmitting ? [
|
|
1480
|
-
return /* @__PURE__ */ jsx(View, { style:
|
|
1481
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
1482
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
1483
|
-
/* @__PURE__ */ jsxs(View, { style:
|
|
1484
|
-
/* @__PURE__ */ jsx(Text, { style:
|
|
1608
|
+
const buttonStyle = pin.isSubmitting ? [styles3.primaryButton, styles3.primaryButtonDisabled] : styles3.primaryButton;
|
|
1609
|
+
return /* @__PURE__ */ jsx(View, { style: styles3.screen, children: /* @__PURE__ */ jsxs(View, { style: styles3.card, testID: withTestIdPrefix(AuthTestIds.pinForm, testIdPrefix), children: [
|
|
1610
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.title, children: labels.title }),
|
|
1611
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: labels.description }),
|
|
1612
|
+
/* @__PURE__ */ jsxs(View, { style: styles3.fieldGroup, children: [
|
|
1613
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.label, children: labels.pinLabel }),
|
|
1485
1614
|
/* @__PURE__ */ jsx(
|
|
1486
1615
|
TextInput,
|
|
1487
1616
|
{
|
|
@@ -1494,7 +1623,7 @@ function PinForm({
|
|
|
1494
1623
|
placeholder: labels.pinPlaceholder,
|
|
1495
1624
|
placeholderTextColor: theme.colors.textSecondary,
|
|
1496
1625
|
secureTextEntry: true,
|
|
1497
|
-
style:
|
|
1626
|
+
style: styles3.input,
|
|
1498
1627
|
testID: withTestIdPrefix(AuthTestIds.pinInput, testIdPrefix),
|
|
1499
1628
|
value: pinValue,
|
|
1500
1629
|
onChangeText: setPinValue
|
|
@@ -1504,7 +1633,7 @@ function PinForm({
|
|
|
1504
1633
|
errorText !== null ? /* @__PURE__ */ jsx(
|
|
1505
1634
|
Text,
|
|
1506
1635
|
{
|
|
1507
|
-
style:
|
|
1636
|
+
style: styles3.errorText,
|
|
1508
1637
|
testID: withTestIdPrefix(AuthTestIds.pinError, testIdPrefix),
|
|
1509
1638
|
children: errorText
|
|
1510
1639
|
}
|
|
@@ -1519,11 +1648,918 @@ function PinForm({
|
|
|
1519
1648
|
style: buttonStyle,
|
|
1520
1649
|
testID: withTestIdPrefix(AuthTestIds.pinSubmitButton, testIdPrefix),
|
|
1521
1650
|
onPress: () => handleSubmit(pinValue.trim()),
|
|
1522
|
-
children: pin.isSubmitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style:
|
|
1651
|
+
children: pin.isSubmitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.submit })
|
|
1523
1652
|
}
|
|
1524
1653
|
)
|
|
1525
1654
|
] }) });
|
|
1526
1655
|
}
|
|
1656
|
+
var DOT_SIZE = 18;
|
|
1657
|
+
var DOT_BORDER_WIDTH = 2;
|
|
1658
|
+
var DOT_RADIUS = 9;
|
|
1659
|
+
var ROW_GAP = 12;
|
|
1660
|
+
var ROW_MIN_HEIGHT = 44;
|
|
1661
|
+
var ROW_VERTICAL_MARGIN = 16;
|
|
1662
|
+
var HIDDEN_SIZE = 1;
|
|
1663
|
+
function sanitise(raw, length) {
|
|
1664
|
+
return raw.replace(/\D/g, "").slice(0, length);
|
|
1665
|
+
}
|
|
1666
|
+
function useDotStyles(theme) {
|
|
1667
|
+
return useMemo(
|
|
1668
|
+
() => ({
|
|
1669
|
+
filled: { backgroundColor: theme.colors.primary, borderColor: theme.colors.primary },
|
|
1670
|
+
empty: { backgroundColor: theme.colors.background, borderColor: theme.colors.border }
|
|
1671
|
+
}),
|
|
1672
|
+
[theme]
|
|
1673
|
+
);
|
|
1674
|
+
}
|
|
1675
|
+
function DevicePinInput({
|
|
1676
|
+
value,
|
|
1677
|
+
length,
|
|
1678
|
+
disabled,
|
|
1679
|
+
testID,
|
|
1680
|
+
testIdPrefix,
|
|
1681
|
+
accessibilityLabel,
|
|
1682
|
+
accessibilityHint,
|
|
1683
|
+
filledHint,
|
|
1684
|
+
emptyHint,
|
|
1685
|
+
theme: themeProp,
|
|
1686
|
+
onChange
|
|
1687
|
+
}) {
|
|
1688
|
+
const theme = useAuthTheme(themeProp);
|
|
1689
|
+
const inputRef = useRef(null);
|
|
1690
|
+
const dotStyles = useDotStyles(theme);
|
|
1691
|
+
const cells = Array.from({ length }, (_unused, index) => index);
|
|
1692
|
+
const baseId = withTestIdPrefix(testID, testIdPrefix);
|
|
1693
|
+
return /* @__PURE__ */ jsxs(
|
|
1694
|
+
Pressable,
|
|
1695
|
+
{
|
|
1696
|
+
accessibilityHint,
|
|
1697
|
+
accessibilityLabel,
|
|
1698
|
+
accessibilityRole: "button",
|
|
1699
|
+
disabled,
|
|
1700
|
+
style: styles.row,
|
|
1701
|
+
testID: `${baseId}-row`,
|
|
1702
|
+
onPress: () => inputRef.current?.focus(),
|
|
1703
|
+
children: [
|
|
1704
|
+
cells.map((index) => {
|
|
1705
|
+
const filled = index < value.length;
|
|
1706
|
+
return /* @__PURE__ */ jsx(
|
|
1707
|
+
View,
|
|
1708
|
+
{
|
|
1709
|
+
accessibilityLabel: filled ? filledHint : emptyHint,
|
|
1710
|
+
style: [styles.dot, filled ? dotStyles.filled : dotStyles.empty],
|
|
1711
|
+
testID: `${baseId}-dot-${String(index)}`
|
|
1712
|
+
},
|
|
1713
|
+
index
|
|
1714
|
+
);
|
|
1715
|
+
}),
|
|
1716
|
+
/* @__PURE__ */ jsx(
|
|
1717
|
+
TextInput,
|
|
1718
|
+
{
|
|
1719
|
+
ref: inputRef,
|
|
1720
|
+
accessibilityHint,
|
|
1721
|
+
accessibilityLabel,
|
|
1722
|
+
autoFocus: true,
|
|
1723
|
+
caretHidden: true,
|
|
1724
|
+
editable: !disabled,
|
|
1725
|
+
keyboardType: "number-pad",
|
|
1726
|
+
maxLength: length,
|
|
1727
|
+
secureTextEntry: true,
|
|
1728
|
+
style: styles.hiddenInput,
|
|
1729
|
+
testID: baseId,
|
|
1730
|
+
value,
|
|
1731
|
+
onChangeText: (raw) => onChange(sanitise(raw, length))
|
|
1732
|
+
}
|
|
1733
|
+
)
|
|
1734
|
+
]
|
|
1735
|
+
}
|
|
1736
|
+
);
|
|
1737
|
+
}
|
|
1738
|
+
var styles = StyleSheet.create({
|
|
1739
|
+
dot: {
|
|
1740
|
+
borderRadius: DOT_RADIUS,
|
|
1741
|
+
borderWidth: DOT_BORDER_WIDTH,
|
|
1742
|
+
height: DOT_SIZE,
|
|
1743
|
+
width: DOT_SIZE
|
|
1744
|
+
},
|
|
1745
|
+
hiddenInput: {
|
|
1746
|
+
height: HIDDEN_SIZE,
|
|
1747
|
+
opacity: 0,
|
|
1748
|
+
position: "absolute",
|
|
1749
|
+
width: HIDDEN_SIZE
|
|
1750
|
+
},
|
|
1751
|
+
row: {
|
|
1752
|
+
alignItems: "center",
|
|
1753
|
+
flexDirection: "row",
|
|
1754
|
+
gap: ROW_GAP,
|
|
1755
|
+
justifyContent: "center",
|
|
1756
|
+
marginVertical: ROW_VERTICAL_MARGIN,
|
|
1757
|
+
minHeight: ROW_MIN_HEIGHT
|
|
1758
|
+
}
|
|
1759
|
+
});
|
|
1760
|
+
|
|
1761
|
+
// src/components/interpolate.ts
|
|
1762
|
+
function interpolate(template, values) {
|
|
1763
|
+
return template.replace(/\{(\w+)\}/g, (match, key) => {
|
|
1764
|
+
const value = values[key];
|
|
1765
|
+
return value === void 0 ? match : String(value);
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
// src/devicePin/devicePinConstants.ts
|
|
1770
|
+
var DEVICE_PIN_ALLOWED_DIGITS = [4, 6, 8];
|
|
1771
|
+
var DEVICE_PIN_DEFAULT_DIGITS = 4;
|
|
1772
|
+
function isAllowedPinDigits(value) {
|
|
1773
|
+
return DEVICE_PIN_ALLOWED_DIGITS.includes(value);
|
|
1774
|
+
}
|
|
1775
|
+
var PILL_VERTICAL_PADDING = 10;
|
|
1776
|
+
var PILL_FONT_SIZE = 15;
|
|
1777
|
+
function usePickerStyles(theme) {
|
|
1778
|
+
return useMemo(
|
|
1779
|
+
() => ({
|
|
1780
|
+
pill: { borderColor: theme.colors.border },
|
|
1781
|
+
active: { backgroundColor: theme.colors.primary, borderColor: theme.colors.primary },
|
|
1782
|
+
text: { color: theme.colors.text },
|
|
1783
|
+
textActive: { color: theme.colors.onPrimary }
|
|
1784
|
+
}),
|
|
1785
|
+
[theme]
|
|
1786
|
+
);
|
|
1787
|
+
}
|
|
1788
|
+
function DevicePinLengthPicker({
|
|
1789
|
+
selected,
|
|
1790
|
+
disabled,
|
|
1791
|
+
optionHint,
|
|
1792
|
+
testIdPrefix,
|
|
1793
|
+
theme: themeProp,
|
|
1794
|
+
onSelect
|
|
1795
|
+
}) {
|
|
1796
|
+
const theme = useAuthTheme(themeProp);
|
|
1797
|
+
const dynamic = usePickerStyles(theme);
|
|
1798
|
+
const baseId = withTestIdPrefix(AuthTestIds.devicePinEnrollLength, testIdPrefix);
|
|
1799
|
+
return /* @__PURE__ */ jsx(View, { style: styles2.row, children: DEVICE_PIN_ALLOWED_DIGITS.map((option) => {
|
|
1800
|
+
const active = option === selected;
|
|
1801
|
+
return /* @__PURE__ */ jsx(
|
|
1802
|
+
Pressable,
|
|
1803
|
+
{
|
|
1804
|
+
accessibilityHint: interpolate(optionHint, { count: option }),
|
|
1805
|
+
accessibilityLabel: String(option),
|
|
1806
|
+
accessibilityRole: "button",
|
|
1807
|
+
accessibilityState: { selected: active },
|
|
1808
|
+
disabled,
|
|
1809
|
+
style: [styles2.pill, dynamic.pill, active ? dynamic.active : null],
|
|
1810
|
+
testID: `${baseId}-${String(option)}`,
|
|
1811
|
+
onPress: () => onSelect(option),
|
|
1812
|
+
children: /* @__PURE__ */ jsx(Text, { style: [styles2.text, dynamic.text, active ? dynamic.textActive : null], children: String(option) })
|
|
1813
|
+
},
|
|
1814
|
+
option
|
|
1815
|
+
);
|
|
1816
|
+
}) });
|
|
1817
|
+
}
|
|
1818
|
+
var styles2 = StyleSheet.create({
|
|
1819
|
+
pill: {
|
|
1820
|
+
alignItems: "center",
|
|
1821
|
+
borderRadius: 8,
|
|
1822
|
+
borderWidth: 1,
|
|
1823
|
+
flex: 1,
|
|
1824
|
+
paddingVertical: PILL_VERTICAL_PADDING
|
|
1825
|
+
},
|
|
1826
|
+
row: {
|
|
1827
|
+
flexDirection: "row",
|
|
1828
|
+
gap: 8,
|
|
1829
|
+
marginBottom: 8
|
|
1830
|
+
},
|
|
1831
|
+
text: {
|
|
1832
|
+
fontSize: PILL_FONT_SIZE,
|
|
1833
|
+
fontWeight: "700"
|
|
1834
|
+
}
|
|
1835
|
+
});
|
|
1836
|
+
|
|
1837
|
+
// src/devicePin/DevicePinErrorKey.ts
|
|
1838
|
+
var DevicePinErrorKey = /* @__PURE__ */ ((DevicePinErrorKey2) => {
|
|
1839
|
+
DevicePinErrorKey2["Incomplete"] = "incomplete";
|
|
1840
|
+
DevicePinErrorKey2["Invalid"] = "invalid";
|
|
1841
|
+
DevicePinErrorKey2["LockedOut"] = "locked_out";
|
|
1842
|
+
DevicePinErrorKey2["RateLimited"] = "rate_limited";
|
|
1843
|
+
DevicePinErrorKey2["Generic"] = "generic";
|
|
1844
|
+
return DevicePinErrorKey2;
|
|
1845
|
+
})(DevicePinErrorKey || {});
|
|
1846
|
+
function useDevicePinUnlock({
|
|
1847
|
+
client,
|
|
1848
|
+
digits,
|
|
1849
|
+
onSignedIn
|
|
1850
|
+
}) {
|
|
1851
|
+
const [pin, setPinState] = useState("");
|
|
1852
|
+
const [submitting, setSubmitting] = useState(false);
|
|
1853
|
+
const [errorKey, setErrorKey] = useState(null);
|
|
1854
|
+
const [retryAfterSeconds, setRetryAfterSeconds] = useState(null);
|
|
1855
|
+
const setPin = useCallback((next) => {
|
|
1856
|
+
setPinState(next);
|
|
1857
|
+
setErrorKey(null);
|
|
1858
|
+
setRetryAfterSeconds(null);
|
|
1859
|
+
}, []);
|
|
1860
|
+
const submit = useCallback(() => {
|
|
1861
|
+
setErrorKey(null);
|
|
1862
|
+
setRetryAfterSeconds(null);
|
|
1863
|
+
if (pin.length < digits) {
|
|
1864
|
+
setErrorKey("incomplete" /* Incomplete */);
|
|
1865
|
+
return;
|
|
1866
|
+
}
|
|
1867
|
+
setSubmitting(true);
|
|
1868
|
+
client.unlockWithDevicePin({ pin }).then((result) => {
|
|
1869
|
+
if (result.status === "success") {
|
|
1870
|
+
onSignedIn(result.user);
|
|
1871
|
+
return;
|
|
1872
|
+
}
|
|
1873
|
+
if (result.status === "invalid") {
|
|
1874
|
+
setErrorKey("invalid" /* Invalid */);
|
|
1875
|
+
return;
|
|
1876
|
+
}
|
|
1877
|
+
if (result.status === "locked") {
|
|
1878
|
+
setRetryAfterSeconds(result.retryAfterSeconds);
|
|
1879
|
+
setErrorKey("locked_out" /* LockedOut */);
|
|
1880
|
+
return;
|
|
1881
|
+
}
|
|
1882
|
+
if (result.status === "rateLimited") {
|
|
1883
|
+
setRetryAfterSeconds(result.retryAfterSeconds);
|
|
1884
|
+
setErrorKey("rate_limited" /* RateLimited */);
|
|
1885
|
+
return;
|
|
1886
|
+
}
|
|
1887
|
+
setErrorKey("generic" /* Generic */);
|
|
1888
|
+
}).catch(() => {
|
|
1889
|
+
setErrorKey("generic" /* Generic */);
|
|
1890
|
+
}).finally(() => {
|
|
1891
|
+
setSubmitting(false);
|
|
1892
|
+
});
|
|
1893
|
+
}, [client, pin, digits, onSignedIn]);
|
|
1894
|
+
return { pin, submitting, errorKey, retryAfterSeconds, setPin, submit };
|
|
1895
|
+
}
|
|
1896
|
+
function resolveErrorText(errorKey, digits, retryAfter, labels) {
|
|
1897
|
+
if (errorKey === null) {
|
|
1898
|
+
return null;
|
|
1899
|
+
}
|
|
1900
|
+
if (errorKey === "incomplete" /* Incomplete */) {
|
|
1901
|
+
return interpolate(labels.errorIncomplete, { count: digits });
|
|
1902
|
+
}
|
|
1903
|
+
if (errorKey === "invalid" /* Invalid */) {
|
|
1904
|
+
return labels.errorInvalid;
|
|
1905
|
+
}
|
|
1906
|
+
if (errorKey === "locked_out" /* LockedOut */) {
|
|
1907
|
+
return retryAfter !== null ? interpolate(labels.errorLockedOutRetry, { count: retryAfter }) : labels.errorLockedOut;
|
|
1908
|
+
}
|
|
1909
|
+
if (errorKey === "rate_limited" /* RateLimited */) {
|
|
1910
|
+
return retryAfter !== null ? interpolate(labels.errorRateLimitedRetry, { count: retryAfter }) : labels.errorRateLimited;
|
|
1911
|
+
}
|
|
1912
|
+
return labels.errorGeneric;
|
|
1913
|
+
}
|
|
1914
|
+
function DevicePinUnlockScreen({
|
|
1915
|
+
client,
|
|
1916
|
+
digits,
|
|
1917
|
+
rememberedUsername,
|
|
1918
|
+
theme: themeProp,
|
|
1919
|
+
labels: labelsProp,
|
|
1920
|
+
testIdPrefix,
|
|
1921
|
+
onSignedIn,
|
|
1922
|
+
onUsePassword
|
|
1923
|
+
}) {
|
|
1924
|
+
const theme = useAuthTheme(themeProp);
|
|
1925
|
+
const styles3 = useAuthStyles(theme);
|
|
1926
|
+
const labels = useMemo(
|
|
1927
|
+
() => ({ ...DEFAULT_DEVICE_PIN_UNLOCK_LABELS, ...labelsProp }),
|
|
1928
|
+
[labelsProp]
|
|
1929
|
+
);
|
|
1930
|
+
const { pin, submitting, errorKey, retryAfterSeconds, setPin, submit } = useDevicePinUnlock({
|
|
1931
|
+
client,
|
|
1932
|
+
digits,
|
|
1933
|
+
onSignedIn
|
|
1934
|
+
});
|
|
1935
|
+
const hasName = rememberedUsername !== "";
|
|
1936
|
+
const title = hasName ? interpolate(labels.title, { name: rememberedUsername }) : labels.titleNoName;
|
|
1937
|
+
const error = resolveErrorText(errorKey, digits, retryAfterSeconds, labels);
|
|
1938
|
+
const buttonStyle = submitting ? [styles3.primaryButton, styles3.primaryButtonDisabled] : styles3.primaryButton;
|
|
1939
|
+
return /* @__PURE__ */ jsx(View, { style: styles3.screen, children: /* @__PURE__ */ jsxs(
|
|
1940
|
+
View,
|
|
1941
|
+
{
|
|
1942
|
+
style: styles3.card,
|
|
1943
|
+
testID: withTestIdPrefix(AuthTestIds.devicePinUnlock, testIdPrefix),
|
|
1944
|
+
children: [
|
|
1945
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.title, children: title }),
|
|
1946
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: interpolate(labels.description, { count: digits }) }),
|
|
1947
|
+
/* @__PURE__ */ jsx(
|
|
1948
|
+
DevicePinInput,
|
|
1949
|
+
{
|
|
1950
|
+
accessibilityHint: labels.pinPlaceholder,
|
|
1951
|
+
accessibilityLabel: labels.pinLabel,
|
|
1952
|
+
disabled: submitting,
|
|
1953
|
+
emptyHint: labels.digitEmptyHint,
|
|
1954
|
+
filledHint: labels.digitFilledHint,
|
|
1955
|
+
length: digits,
|
|
1956
|
+
testID: AuthTestIds.devicePinUnlockInput,
|
|
1957
|
+
testIdPrefix,
|
|
1958
|
+
theme,
|
|
1959
|
+
value: pin,
|
|
1960
|
+
onChange: setPin
|
|
1961
|
+
}
|
|
1962
|
+
),
|
|
1963
|
+
error !== null ? /* @__PURE__ */ jsx(
|
|
1964
|
+
Text,
|
|
1965
|
+
{
|
|
1966
|
+
style: styles3.errorText,
|
|
1967
|
+
testID: withTestIdPrefix(AuthTestIds.devicePinUnlockError, testIdPrefix),
|
|
1968
|
+
children: error
|
|
1969
|
+
}
|
|
1970
|
+
) : null,
|
|
1971
|
+
/* @__PURE__ */ jsx(
|
|
1972
|
+
TouchableOpacity,
|
|
1973
|
+
{
|
|
1974
|
+
accessibilityHint: labels.submit,
|
|
1975
|
+
accessibilityLabel: submitting ? labels.submitting : labels.submit,
|
|
1976
|
+
accessibilityRole: "button",
|
|
1977
|
+
disabled: submitting,
|
|
1978
|
+
style: buttonStyle,
|
|
1979
|
+
testID: withTestIdPrefix(AuthTestIds.devicePinUnlockSubmit, testIdPrefix),
|
|
1980
|
+
onPress: submit,
|
|
1981
|
+
children: submitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.submit })
|
|
1982
|
+
}
|
|
1983
|
+
),
|
|
1984
|
+
/* @__PURE__ */ jsx(
|
|
1985
|
+
TouchableOpacity,
|
|
1986
|
+
{
|
|
1987
|
+
accessibilityHint: labels.usePasswordHint,
|
|
1988
|
+
accessibilityLabel: labels.usePasswordInstead,
|
|
1989
|
+
accessibilityRole: "button",
|
|
1990
|
+
disabled: submitting,
|
|
1991
|
+
style: styles3.escapeLink,
|
|
1992
|
+
testID: withTestIdPrefix(AuthTestIds.devicePinUnlockUsePassword, testIdPrefix),
|
|
1993
|
+
onPress: onUsePassword,
|
|
1994
|
+
children: /* @__PURE__ */ jsx(Text, { style: styles3.linkText, children: labels.usePasswordInstead })
|
|
1995
|
+
}
|
|
1996
|
+
)
|
|
1997
|
+
]
|
|
1998
|
+
}
|
|
1999
|
+
) });
|
|
2000
|
+
}
|
|
2001
|
+
|
|
2002
|
+
// src/devicePin/DevicePinEnrollErrorKey.ts
|
|
2003
|
+
var DevicePinEnrollErrorKey = /* @__PURE__ */ ((DevicePinEnrollErrorKey2) => {
|
|
2004
|
+
DevicePinEnrollErrorKey2["Mismatch"] = "mismatch";
|
|
2005
|
+
DevicePinEnrollErrorKey2["Unauthorized"] = "unauthorized";
|
|
2006
|
+
DevicePinEnrollErrorKey2["Forbidden"] = "forbidden";
|
|
2007
|
+
DevicePinEnrollErrorKey2["InvalidPin"] = "invalid_pin";
|
|
2008
|
+
DevicePinEnrollErrorKey2["Failed"] = "failed";
|
|
2009
|
+
return DevicePinEnrollErrorKey2;
|
|
2010
|
+
})(DevicePinEnrollErrorKey || {});
|
|
2011
|
+
function errorKeyFor(result) {
|
|
2012
|
+
if (result.status === "unauthorized") {
|
|
2013
|
+
return "unauthorized" /* Unauthorized */;
|
|
2014
|
+
}
|
|
2015
|
+
if (result.status === "forbidden") {
|
|
2016
|
+
return "forbidden" /* Forbidden */;
|
|
2017
|
+
}
|
|
2018
|
+
if (result.status === "invalidPin") {
|
|
2019
|
+
return "invalid_pin" /* InvalidPin */;
|
|
2020
|
+
}
|
|
2021
|
+
return "failed" /* Failed */;
|
|
2022
|
+
}
|
|
2023
|
+
function useDevicePinEnroll({
|
|
2024
|
+
client,
|
|
2025
|
+
digits,
|
|
2026
|
+
onEnrolled
|
|
2027
|
+
}) {
|
|
2028
|
+
const [pin, setPinState] = useState("");
|
|
2029
|
+
const [confirmPin, setConfirmState] = useState("");
|
|
2030
|
+
const [submitting, setSubmitting] = useState(false);
|
|
2031
|
+
const [errorKey, setErrorKey] = useState(null);
|
|
2032
|
+
const setPin = useCallback((next) => {
|
|
2033
|
+
setPinState(next);
|
|
2034
|
+
setErrorKey(null);
|
|
2035
|
+
}, []);
|
|
2036
|
+
const setConfirmPin = useCallback((next) => {
|
|
2037
|
+
setConfirmState(next);
|
|
2038
|
+
setErrorKey(null);
|
|
2039
|
+
}, []);
|
|
2040
|
+
const submit = useCallback(() => {
|
|
2041
|
+
setErrorKey(null);
|
|
2042
|
+
const wrongLength = pin.length !== digits;
|
|
2043
|
+
const mismatched = pin !== confirmPin;
|
|
2044
|
+
if (wrongLength || mismatched) {
|
|
2045
|
+
setErrorKey("mismatch" /* Mismatch */);
|
|
2046
|
+
return;
|
|
2047
|
+
}
|
|
2048
|
+
setSubmitting(true);
|
|
2049
|
+
client.enrollDevicePin({ pin, digits }).then((result) => {
|
|
2050
|
+
if (result.status === "success") {
|
|
2051
|
+
onEnrolled();
|
|
2052
|
+
return;
|
|
2053
|
+
}
|
|
2054
|
+
setErrorKey(errorKeyFor(result));
|
|
2055
|
+
}).catch(() => {
|
|
2056
|
+
setErrorKey("failed" /* Failed */);
|
|
2057
|
+
}).finally(() => {
|
|
2058
|
+
setSubmitting(false);
|
|
2059
|
+
});
|
|
2060
|
+
}, [client, pin, confirmPin, digits, onEnrolled]);
|
|
2061
|
+
return { pin, confirmPin, submitting, errorKey, setPin, setConfirmPin, submit };
|
|
2062
|
+
}
|
|
2063
|
+
function resolveErrorText2(errorKey, digits, labels) {
|
|
2064
|
+
if (errorKey === null) {
|
|
2065
|
+
return null;
|
|
2066
|
+
}
|
|
2067
|
+
if (errorKey === "mismatch" /* Mismatch */) {
|
|
2068
|
+
return interpolate(labels.errorMismatch, { count: digits });
|
|
2069
|
+
}
|
|
2070
|
+
if (errorKey === "unauthorized" /* Unauthorized */) {
|
|
2071
|
+
return labels.errorUnauthorized;
|
|
2072
|
+
}
|
|
2073
|
+
if (errorKey === "forbidden" /* Forbidden */) {
|
|
2074
|
+
return labels.errorForbidden;
|
|
2075
|
+
}
|
|
2076
|
+
if (errorKey === "invalid_pin" /* InvalidPin */) {
|
|
2077
|
+
return labels.errorInvalidPin;
|
|
2078
|
+
}
|
|
2079
|
+
return labels.errorFailed;
|
|
2080
|
+
}
|
|
2081
|
+
function DevicePinEnrollForm({
|
|
2082
|
+
client,
|
|
2083
|
+
initialDigits = DEVICE_PIN_DEFAULT_DIGITS,
|
|
2084
|
+
theme: themeProp,
|
|
2085
|
+
labels: labelsProp,
|
|
2086
|
+
testIdPrefix,
|
|
2087
|
+
onEnrolled,
|
|
2088
|
+
onCancel
|
|
2089
|
+
}) {
|
|
2090
|
+
const theme = useAuthTheme(themeProp);
|
|
2091
|
+
const styles3 = useAuthStyles(theme);
|
|
2092
|
+
const labels = useMemo(
|
|
2093
|
+
() => ({ ...DEFAULT_DEVICE_PIN_ENROLL_LABELS, ...labelsProp }),
|
|
2094
|
+
[labelsProp]
|
|
2095
|
+
);
|
|
2096
|
+
const [digits, setDigits] = useState(initialDigits);
|
|
2097
|
+
const { pin, confirmPin, submitting, errorKey, setPin, setConfirmPin, submit } = useDevicePinEnroll({ client, digits, onEnrolled });
|
|
2098
|
+
const error = resolveErrorText2(errorKey, digits, labels);
|
|
2099
|
+
const buttonStyle = submitting ? [styles3.primaryButton, styles3.primaryButtonDisabled] : styles3.primaryButton;
|
|
2100
|
+
return /* @__PURE__ */ jsxs(
|
|
2101
|
+
View,
|
|
2102
|
+
{
|
|
2103
|
+
style: styles3.card,
|
|
2104
|
+
testID: withTestIdPrefix(AuthTestIds.devicePinEnrollForm, testIdPrefix),
|
|
2105
|
+
children: [
|
|
2106
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.title, children: labels.formTitle }),
|
|
2107
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: interpolate(labels.formDescription, { count: digits }) }),
|
|
2108
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.label, children: labels.lengthLabel }),
|
|
2109
|
+
/* @__PURE__ */ jsx(
|
|
2110
|
+
DevicePinLengthPicker,
|
|
2111
|
+
{
|
|
2112
|
+
disabled: submitting,
|
|
2113
|
+
optionHint: labels.lengthOptionHint,
|
|
2114
|
+
selected: digits,
|
|
2115
|
+
testIdPrefix,
|
|
2116
|
+
theme,
|
|
2117
|
+
onSelect: (option) => {
|
|
2118
|
+
setDigits(option);
|
|
2119
|
+
setPin("");
|
|
2120
|
+
setConfirmPin("");
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
),
|
|
2124
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.label, children: labels.pinLabel }),
|
|
2125
|
+
/* @__PURE__ */ jsx(
|
|
2126
|
+
DevicePinInput,
|
|
2127
|
+
{
|
|
2128
|
+
accessibilityHint: labels.pinPlaceholder,
|
|
2129
|
+
accessibilityLabel: labels.pinLabel,
|
|
2130
|
+
disabled: submitting,
|
|
2131
|
+
emptyHint: labels.pinPlaceholder,
|
|
2132
|
+
filledHint: labels.pinLabel,
|
|
2133
|
+
length: digits,
|
|
2134
|
+
testID: AuthTestIds.devicePinEnrollPin,
|
|
2135
|
+
testIdPrefix,
|
|
2136
|
+
theme,
|
|
2137
|
+
value: pin,
|
|
2138
|
+
onChange: setPin
|
|
2139
|
+
}
|
|
2140
|
+
),
|
|
2141
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.label, children: labels.confirmLabel }),
|
|
2142
|
+
/* @__PURE__ */ jsx(
|
|
2143
|
+
DevicePinInput,
|
|
2144
|
+
{
|
|
2145
|
+
accessibilityHint: labels.confirmPlaceholder,
|
|
2146
|
+
accessibilityLabel: labels.confirmLabel,
|
|
2147
|
+
disabled: submitting,
|
|
2148
|
+
emptyHint: labels.confirmPlaceholder,
|
|
2149
|
+
filledHint: labels.confirmLabel,
|
|
2150
|
+
length: digits,
|
|
2151
|
+
testID: AuthTestIds.devicePinEnrollConfirm,
|
|
2152
|
+
testIdPrefix,
|
|
2153
|
+
theme,
|
|
2154
|
+
value: confirmPin,
|
|
2155
|
+
onChange: setConfirmPin
|
|
2156
|
+
}
|
|
2157
|
+
),
|
|
2158
|
+
error !== null ? /* @__PURE__ */ jsx(
|
|
2159
|
+
Text,
|
|
2160
|
+
{
|
|
2161
|
+
style: styles3.errorText,
|
|
2162
|
+
testID: withTestIdPrefix(AuthTestIds.devicePinEnrollError, testIdPrefix),
|
|
2163
|
+
children: error
|
|
2164
|
+
}
|
|
2165
|
+
) : null,
|
|
2166
|
+
/* @__PURE__ */ jsx(
|
|
2167
|
+
TouchableOpacity,
|
|
2168
|
+
{
|
|
2169
|
+
accessibilityHint: labels.submit,
|
|
2170
|
+
accessibilityLabel: submitting ? labels.submitting : labels.submit,
|
|
2171
|
+
accessibilityRole: "button",
|
|
2172
|
+
disabled: submitting,
|
|
2173
|
+
style: buttonStyle,
|
|
2174
|
+
testID: withTestIdPrefix(AuthTestIds.devicePinEnrollSubmit, testIdPrefix),
|
|
2175
|
+
onPress: submit,
|
|
2176
|
+
children: submitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.submit })
|
|
2177
|
+
}
|
|
2178
|
+
),
|
|
2179
|
+
/* @__PURE__ */ jsx(
|
|
2180
|
+
TouchableOpacity,
|
|
2181
|
+
{
|
|
2182
|
+
accessibilityHint: labels.cancelHint,
|
|
2183
|
+
accessibilityLabel: labels.cancel,
|
|
2184
|
+
accessibilityRole: "button",
|
|
2185
|
+
disabled: submitting,
|
|
2186
|
+
style: styles3.escapeLink,
|
|
2187
|
+
testID: withTestIdPrefix(AuthTestIds.devicePinEnrollCancel, testIdPrefix),
|
|
2188
|
+
onPress: onCancel,
|
|
2189
|
+
children: /* @__PURE__ */ jsx(Text, { style: styles3.linkText, children: labels.cancel })
|
|
2190
|
+
}
|
|
2191
|
+
)
|
|
2192
|
+
]
|
|
2193
|
+
}
|
|
2194
|
+
);
|
|
2195
|
+
}
|
|
2196
|
+
function DevicePinOffer({
|
|
2197
|
+
client,
|
|
2198
|
+
initialDigits,
|
|
2199
|
+
theme: themeProp,
|
|
2200
|
+
labels: labelsProp,
|
|
2201
|
+
testIdPrefix,
|
|
2202
|
+
onDismiss
|
|
2203
|
+
}) {
|
|
2204
|
+
const theme = useAuthTheme(themeProp);
|
|
2205
|
+
const styles3 = useAuthStyles(theme);
|
|
2206
|
+
const labels = useMemo(
|
|
2207
|
+
() => ({ ...DEFAULT_DEVICE_PIN_ENROLL_LABELS, ...labelsProp }),
|
|
2208
|
+
[labelsProp]
|
|
2209
|
+
);
|
|
2210
|
+
const [expanded, setExpanded] = useState(false);
|
|
2211
|
+
const cardTestId = withTestIdPrefix(AuthTestIds.devicePinOffer, testIdPrefix);
|
|
2212
|
+
if (expanded) {
|
|
2213
|
+
return /* @__PURE__ */ jsx(View, { style: styles3.card, testID: cardTestId, children: /* @__PURE__ */ jsx(
|
|
2214
|
+
DevicePinEnrollForm,
|
|
2215
|
+
{
|
|
2216
|
+
client,
|
|
2217
|
+
initialDigits,
|
|
2218
|
+
labels: labelsProp,
|
|
2219
|
+
testIdPrefix,
|
|
2220
|
+
theme,
|
|
2221
|
+
onCancel: onDismiss,
|
|
2222
|
+
onEnrolled: onDismiss
|
|
2223
|
+
}
|
|
2224
|
+
) });
|
|
2225
|
+
}
|
|
2226
|
+
return /* @__PURE__ */ jsxs(View, { style: styles3.card, testID: cardTestId, children: [
|
|
2227
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.title, children: labels.offerTitle }),
|
|
2228
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: labels.offerDescription }),
|
|
2229
|
+
/* @__PURE__ */ jsx(
|
|
2230
|
+
TouchableOpacity,
|
|
2231
|
+
{
|
|
2232
|
+
accessibilityHint: labels.offerAcceptHint,
|
|
2233
|
+
accessibilityLabel: labels.offerAccept,
|
|
2234
|
+
accessibilityRole: "button",
|
|
2235
|
+
style: styles3.primaryButton,
|
|
2236
|
+
testID: withTestIdPrefix(AuthTestIds.devicePinOfferAccept, testIdPrefix),
|
|
2237
|
+
onPress: () => setExpanded(true),
|
|
2238
|
+
children: /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.offerAccept })
|
|
2239
|
+
}
|
|
2240
|
+
),
|
|
2241
|
+
/* @__PURE__ */ jsx(
|
|
2242
|
+
TouchableOpacity,
|
|
2243
|
+
{
|
|
2244
|
+
accessibilityHint: labels.offerSkipHint,
|
|
2245
|
+
accessibilityLabel: labels.offerSkip,
|
|
2246
|
+
accessibilityRole: "button",
|
|
2247
|
+
style: styles3.secondaryButton,
|
|
2248
|
+
testID: withTestIdPrefix(AuthTestIds.devicePinOfferSkip, testIdPrefix),
|
|
2249
|
+
onPress: onDismiss,
|
|
2250
|
+
children: /* @__PURE__ */ jsx(Text, { style: styles3.secondaryButtonText, children: labels.offerSkip })
|
|
2251
|
+
}
|
|
2252
|
+
)
|
|
2253
|
+
] });
|
|
2254
|
+
}
|
|
2255
|
+
function useDevicePinDisable({
|
|
2256
|
+
client,
|
|
2257
|
+
initialHasPin,
|
|
2258
|
+
onChanged
|
|
2259
|
+
}) {
|
|
2260
|
+
const [hasPin, setHasPin] = useState(initialHasPin);
|
|
2261
|
+
const [disabling, setDisabling] = useState(false);
|
|
2262
|
+
const [failed, setFailed] = useState(false);
|
|
2263
|
+
const disable = useCallback(() => {
|
|
2264
|
+
setFailed(false);
|
|
2265
|
+
setDisabling(true);
|
|
2266
|
+
client.disableDevicePin().then((ok) => {
|
|
2267
|
+
if (ok) {
|
|
2268
|
+
setHasPin(false);
|
|
2269
|
+
onChanged?.(false);
|
|
2270
|
+
return;
|
|
2271
|
+
}
|
|
2272
|
+
setFailed(true);
|
|
2273
|
+
}).catch(() => {
|
|
2274
|
+
setFailed(true);
|
|
2275
|
+
}).finally(() => {
|
|
2276
|
+
setDisabling(false);
|
|
2277
|
+
});
|
|
2278
|
+
}, [client, onChanged]);
|
|
2279
|
+
const markEnabled = useCallback(() => {
|
|
2280
|
+
setHasPin(true);
|
|
2281
|
+
onChanged?.(true);
|
|
2282
|
+
}, [onChanged]);
|
|
2283
|
+
return { hasPin, disabling, failed, disable, markEnabled };
|
|
2284
|
+
}
|
|
2285
|
+
function DevicePinSettingsCard({
|
|
2286
|
+
client,
|
|
2287
|
+
initialHasPin,
|
|
2288
|
+
theme: themeProp,
|
|
2289
|
+
labels: labelsProp,
|
|
2290
|
+
enrollLabels,
|
|
2291
|
+
testIdPrefix,
|
|
2292
|
+
onChanged
|
|
2293
|
+
}) {
|
|
2294
|
+
const theme = useAuthTheme(themeProp);
|
|
2295
|
+
const styles3 = useAuthStyles(theme);
|
|
2296
|
+
const labels = useMemo(
|
|
2297
|
+
() => ({ ...DEFAULT_DEVICE_PIN_SETTINGS_LABELS, ...labelsProp }),
|
|
2298
|
+
[labelsProp]
|
|
2299
|
+
);
|
|
2300
|
+
const resolvedEnrollLabels = useMemo(
|
|
2301
|
+
() => ({ ...DEFAULT_DEVICE_PIN_ENROLL_LABELS, ...enrollLabels }),
|
|
2302
|
+
[enrollLabels]
|
|
2303
|
+
);
|
|
2304
|
+
const [enrolling, setEnrolling] = useState(false);
|
|
2305
|
+
const { hasPin, disabling, failed, disable, markEnabled } = useDevicePinDisable({
|
|
2306
|
+
client,
|
|
2307
|
+
initialHasPin,
|
|
2308
|
+
onChanged
|
|
2309
|
+
});
|
|
2310
|
+
const handleEnrolled = () => {
|
|
2311
|
+
setEnrolling(false);
|
|
2312
|
+
markEnabled();
|
|
2313
|
+
};
|
|
2314
|
+
const disableButtonStyle = disabling ? [styles3.secondaryButton, styles3.primaryButtonDisabled] : styles3.secondaryButton;
|
|
2315
|
+
return /* @__PURE__ */ jsxs(
|
|
2316
|
+
View,
|
|
2317
|
+
{
|
|
2318
|
+
style: styles3.card,
|
|
2319
|
+
testID: withTestIdPrefix(AuthTestIds.devicePinSettings, testIdPrefix),
|
|
2320
|
+
children: [
|
|
2321
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.title, children: labels.title }),
|
|
2322
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: labels.description }),
|
|
2323
|
+
/* @__PURE__ */ jsx(
|
|
2324
|
+
Text,
|
|
2325
|
+
{
|
|
2326
|
+
style: styles3.statusText,
|
|
2327
|
+
testID: withTestIdPrefix(AuthTestIds.devicePinSettingsStatus, testIdPrefix),
|
|
2328
|
+
children: hasPin ? labels.statusEnabled : labels.statusDisabled
|
|
2329
|
+
}
|
|
2330
|
+
),
|
|
2331
|
+
failed ? /* @__PURE__ */ jsx(
|
|
2332
|
+
Text,
|
|
2333
|
+
{
|
|
2334
|
+
style: styles3.errorText,
|
|
2335
|
+
testID: withTestIdPrefix(AuthTestIds.devicePinSettingsError, testIdPrefix),
|
|
2336
|
+
children: labels.disableFailed
|
|
2337
|
+
}
|
|
2338
|
+
) : null,
|
|
2339
|
+
renderAction()
|
|
2340
|
+
]
|
|
2341
|
+
}
|
|
2342
|
+
);
|
|
2343
|
+
function renderAction() {
|
|
2344
|
+
if (enrolling) {
|
|
2345
|
+
return /* @__PURE__ */ jsx(
|
|
2346
|
+
DevicePinEnrollForm,
|
|
2347
|
+
{
|
|
2348
|
+
client,
|
|
2349
|
+
labels: resolvedEnrollLabels,
|
|
2350
|
+
testIdPrefix,
|
|
2351
|
+
theme,
|
|
2352
|
+
onCancel: () => setEnrolling(false),
|
|
2353
|
+
onEnrolled: handleEnrolled
|
|
2354
|
+
}
|
|
2355
|
+
);
|
|
2356
|
+
}
|
|
2357
|
+
if (hasPin) {
|
|
2358
|
+
return /* @__PURE__ */ jsx(
|
|
2359
|
+
TouchableOpacity,
|
|
2360
|
+
{
|
|
2361
|
+
accessibilityHint: labels.disableHint,
|
|
2362
|
+
accessibilityLabel: disabling ? labels.disabling : labels.disable,
|
|
2363
|
+
accessibilityRole: "button",
|
|
2364
|
+
disabled: disabling,
|
|
2365
|
+
style: disableButtonStyle,
|
|
2366
|
+
testID: withTestIdPrefix(AuthTestIds.devicePinSettingsDisable, testIdPrefix),
|
|
2367
|
+
onPress: disable,
|
|
2368
|
+
children: disabling ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.primary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles3.secondaryButtonText, children: labels.disable })
|
|
2369
|
+
}
|
|
2370
|
+
);
|
|
2371
|
+
}
|
|
2372
|
+
return /* @__PURE__ */ jsx(
|
|
2373
|
+
TouchableOpacity,
|
|
2374
|
+
{
|
|
2375
|
+
accessibilityHint: labels.enableHint,
|
|
2376
|
+
accessibilityLabel: labels.enable,
|
|
2377
|
+
accessibilityRole: "button",
|
|
2378
|
+
style: styles3.primaryButton,
|
|
2379
|
+
testID: withTestIdPrefix(AuthTestIds.devicePinSettingsEnable, testIdPrefix),
|
|
2380
|
+
onPress: () => setEnrolling(true),
|
|
2381
|
+
children: /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.enable })
|
|
2382
|
+
}
|
|
2383
|
+
);
|
|
2384
|
+
}
|
|
2385
|
+
}
|
|
2386
|
+
|
|
2387
|
+
// src/passkey/passkeyNavigation.ts
|
|
2388
|
+
var PASSKEY_LOGIN_ENDPOINT = "/bff/passkey/login";
|
|
2389
|
+
var PASSKEY_REGISTER_ENDPOINT = "/bff/passkey/register";
|
|
2390
|
+
var RETURN_URL_PARAM = "returnUrl";
|
|
2391
|
+
var PASSKEY_ERROR_PARAM = "passkeyError";
|
|
2392
|
+
var PASSKEY_PARAM = "passkey";
|
|
2393
|
+
var PASSKEY_REGISTERED_VALUE = "registered";
|
|
2394
|
+
var PASSKEY_ERROR_CANCELLED = "cancelled";
|
|
2395
|
+
var PASSKEY_ERROR_FAILED = "failed";
|
|
2396
|
+
function buildNavigationUrl(endpoint, returnUrl) {
|
|
2397
|
+
return `${endpoint}?${RETURN_URL_PARAM}=${encodeURIComponent(returnUrl)}`;
|
|
2398
|
+
}
|
|
2399
|
+
function readSearchParams() {
|
|
2400
|
+
if (typeof window === "undefined") {
|
|
2401
|
+
return null;
|
|
2402
|
+
}
|
|
2403
|
+
return new URLSearchParams(window.location.search);
|
|
2404
|
+
}
|
|
2405
|
+
function startPasskeyLogin(returnUrl) {
|
|
2406
|
+
if (typeof window === "undefined") {
|
|
2407
|
+
return;
|
|
2408
|
+
}
|
|
2409
|
+
window.location.assign(buildNavigationUrl(PASSKEY_LOGIN_ENDPOINT, returnUrl));
|
|
2410
|
+
}
|
|
2411
|
+
function startPasskeyRegistration(returnUrl) {
|
|
2412
|
+
if (typeof window === "undefined") {
|
|
2413
|
+
return;
|
|
2414
|
+
}
|
|
2415
|
+
window.location.assign(buildNavigationUrl(PASSKEY_REGISTER_ENDPOINT, returnUrl));
|
|
2416
|
+
}
|
|
2417
|
+
function readPasskeyError() {
|
|
2418
|
+
const params = readSearchParams();
|
|
2419
|
+
if (params === null) {
|
|
2420
|
+
return null;
|
|
2421
|
+
}
|
|
2422
|
+
const value = params.get(PASSKEY_ERROR_PARAM);
|
|
2423
|
+
if (value === PASSKEY_ERROR_CANCELLED) {
|
|
2424
|
+
return PASSKEY_ERROR_CANCELLED;
|
|
2425
|
+
}
|
|
2426
|
+
if (value === PASSKEY_ERROR_FAILED) {
|
|
2427
|
+
return PASSKEY_ERROR_FAILED;
|
|
2428
|
+
}
|
|
2429
|
+
return null;
|
|
2430
|
+
}
|
|
2431
|
+
function readPasskeyRegistered() {
|
|
2432
|
+
const params = readSearchParams();
|
|
2433
|
+
if (params === null) {
|
|
2434
|
+
return false;
|
|
2435
|
+
}
|
|
2436
|
+
return params.get(PASSKEY_PARAM) === PASSKEY_REGISTERED_VALUE;
|
|
2437
|
+
}
|
|
2438
|
+
var DEFAULT_RETURN_URL = "/";
|
|
2439
|
+
function PasskeyLoginButton({
|
|
2440
|
+
returnUrl = DEFAULT_RETURN_URL,
|
|
2441
|
+
theme: themeProp,
|
|
2442
|
+
labels: labelsProp,
|
|
2443
|
+
testIdPrefix
|
|
2444
|
+
}) {
|
|
2445
|
+
const theme = useAuthTheme(themeProp);
|
|
2446
|
+
const styles3 = useAuthStyles(theme);
|
|
2447
|
+
const labels = useMemo(
|
|
2448
|
+
() => ({ ...DEFAULT_PASSKEY_LOGIN_LABELS, ...labelsProp }),
|
|
2449
|
+
[labelsProp]
|
|
2450
|
+
);
|
|
2451
|
+
const error = readPasskeyError();
|
|
2452
|
+
return /* @__PURE__ */ jsxs(View, { testID: withTestIdPrefix(AuthTestIds.passkeyLogin, testIdPrefix), children: [
|
|
2453
|
+
error !== null ? /* @__PURE__ */ jsx(
|
|
2454
|
+
Text,
|
|
2455
|
+
{
|
|
2456
|
+
style: styles3.errorText,
|
|
2457
|
+
testID: withTestIdPrefix(AuthTestIds.passkeyLoginError, testIdPrefix),
|
|
2458
|
+
children: error === "cancelled" ? labels.errorCancelled : labels.errorFailed
|
|
2459
|
+
}
|
|
2460
|
+
) : null,
|
|
2461
|
+
/* @__PURE__ */ jsx(
|
|
2462
|
+
TouchableOpacity,
|
|
2463
|
+
{
|
|
2464
|
+
accessibilityHint: labels.signInHint,
|
|
2465
|
+
accessibilityLabel: labels.signInButton,
|
|
2466
|
+
accessibilityRole: "button",
|
|
2467
|
+
style: styles3.secondaryButton,
|
|
2468
|
+
testID: withTestIdPrefix(AuthTestIds.passkeyLoginButton, testIdPrefix),
|
|
2469
|
+
onPress: () => startPasskeyLogin(returnUrl),
|
|
2470
|
+
children: /* @__PURE__ */ jsx(Text, { style: styles3.secondaryButtonText, children: labels.signInButton })
|
|
2471
|
+
}
|
|
2472
|
+
)
|
|
2473
|
+
] });
|
|
2474
|
+
}
|
|
2475
|
+
var DEFAULT_RETURN_PATH = "/";
|
|
2476
|
+
function readCurrentPath() {
|
|
2477
|
+
if (typeof window === "undefined") {
|
|
2478
|
+
return DEFAULT_RETURN_PATH;
|
|
2479
|
+
}
|
|
2480
|
+
return window.location.pathname;
|
|
2481
|
+
}
|
|
2482
|
+
function PasskeySettingsCard({
|
|
2483
|
+
returnUrl,
|
|
2484
|
+
theme: themeProp,
|
|
2485
|
+
labels: labelsProp,
|
|
2486
|
+
testIdPrefix
|
|
2487
|
+
}) {
|
|
2488
|
+
const theme = useAuthTheme(themeProp);
|
|
2489
|
+
const styles3 = useAuthStyles(theme);
|
|
2490
|
+
const labels = useMemo(
|
|
2491
|
+
() => ({ ...DEFAULT_PASSKEY_SETTINGS_LABELS, ...labelsProp }),
|
|
2492
|
+
[labelsProp]
|
|
2493
|
+
);
|
|
2494
|
+
const justRegistered = readPasskeyRegistered();
|
|
2495
|
+
const target = returnUrl ?? readCurrentPath();
|
|
2496
|
+
return /* @__PURE__ */ jsxs(
|
|
2497
|
+
View,
|
|
2498
|
+
{
|
|
2499
|
+
style: styles3.card,
|
|
2500
|
+
testID: withTestIdPrefix(AuthTestIds.passkeySettings, testIdPrefix),
|
|
2501
|
+
children: [
|
|
2502
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.title, children: labels.title }),
|
|
2503
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.subtitle, children: labels.description }),
|
|
2504
|
+
/* @__PURE__ */ jsx(Text, { style: styles3.helperText, children: labels.reauthHint }),
|
|
2505
|
+
justRegistered ? /* @__PURE__ */ jsx(
|
|
2506
|
+
Text,
|
|
2507
|
+
{
|
|
2508
|
+
style: styles3.successText,
|
|
2509
|
+
testID: withTestIdPrefix(AuthTestIds.passkeySettingsSuccess, testIdPrefix),
|
|
2510
|
+
children: labels.registeredSuccess
|
|
2511
|
+
}
|
|
2512
|
+
) : null,
|
|
2513
|
+
/* @__PURE__ */ jsx(
|
|
2514
|
+
TouchableOpacity,
|
|
2515
|
+
{
|
|
2516
|
+
accessibilityHint: labels.addHint,
|
|
2517
|
+
accessibilityLabel: labels.addButton,
|
|
2518
|
+
accessibilityRole: "button",
|
|
2519
|
+
style: styles3.primaryButton,
|
|
2520
|
+
testID: withTestIdPrefix(AuthTestIds.passkeySettingsAdd, testIdPrefix),
|
|
2521
|
+
onPress: () => startPasskeyRegistration(target),
|
|
2522
|
+
children: /* @__PURE__ */ jsx(Text, { style: styles3.primaryButtonText, children: labels.addButton })
|
|
2523
|
+
}
|
|
2524
|
+
)
|
|
2525
|
+
]
|
|
2526
|
+
}
|
|
2527
|
+
);
|
|
2528
|
+
}
|
|
2529
|
+
var EMPTY_CONFIG = {
|
|
2530
|
+
methods: [],
|
|
2531
|
+
registrationEnabled: false,
|
|
2532
|
+
deviceState: {
|
|
2533
|
+
rememberedUsername: null,
|
|
2534
|
+
hasPin: false,
|
|
2535
|
+
pinDigits: null,
|
|
2536
|
+
preferredMethod: null
|
|
2537
|
+
}
|
|
2538
|
+
};
|
|
2539
|
+
function useBffLoginConfig(client) {
|
|
2540
|
+
const [config, setConfig] = useState(EMPTY_CONFIG);
|
|
2541
|
+
const [loading, setLoading] = useState(true);
|
|
2542
|
+
useEffect(() => {
|
|
2543
|
+
let active = true;
|
|
2544
|
+
client.getLoginConfig().then((next) => {
|
|
2545
|
+
if (active) {
|
|
2546
|
+
setConfig(next);
|
|
2547
|
+
}
|
|
2548
|
+
}).catch(() => {
|
|
2549
|
+
if (active) {
|
|
2550
|
+
setConfig(EMPTY_CONFIG);
|
|
2551
|
+
}
|
|
2552
|
+
}).finally(() => {
|
|
2553
|
+
if (active) {
|
|
2554
|
+
setLoading(false);
|
|
2555
|
+
}
|
|
2556
|
+
});
|
|
2557
|
+
return () => {
|
|
2558
|
+
active = false;
|
|
2559
|
+
};
|
|
2560
|
+
}, [client]);
|
|
2561
|
+
return { config, loading };
|
|
2562
|
+
}
|
|
1527
2563
|
async function lazyFetchHttpClient(request) {
|
|
1528
2564
|
const fetchImpl = typeof fetch === "function" ? fetch.bind(globalThis) : void 0;
|
|
1529
2565
|
if (fetchImpl === void 0) {
|
|
@@ -1567,6 +2603,6 @@ function resolvePostLoginRoute(user, table) {
|
|
|
1567
2603
|
return table.fallback ?? null;
|
|
1568
2604
|
}
|
|
1569
2605
|
|
|
1570
|
-
export { AuthTestIds, AuthThemeProvider, BffAuthStatus, DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS, DEFAULT_FORGOT_PASSWORD_LABELS, DEFAULT_LOGIN_LABELS, DEFAULT_OTP_LABELS, DEFAULT_PIN_LABELS, DEFAULT_RESET_PASSWORD_LABELS, ForgotPasswordFields, ForgotPasswordForm, LoginForm, OtpForm, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasswordPolicyError, PinForm, ResetPasswordError, ResetPasswordForm, collectUserRoles, createBffAuthClient, defaultAuthTheme, isPasswordValid, isValidForgotPasswordEmail, resolvePostLoginRoute, useAuthTheme, useBffAuth, useBffForgotPassword, useBffResetPassword, useForgotPasswordSubmit, useOtpLogin, usePinLogin, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
|
|
2606
|
+
export { AuthTestIds, AuthThemeProvider, BffAuthStatus, 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_RESET_PASSWORD_LABELS, DEVICE_PIN_ALLOWED_DIGITS, DEVICE_PIN_DEFAULT_DIGITS, DevicePinEnrollErrorKey, DevicePinEnrollForm, DevicePinErrorKey, DevicePinInput, DevicePinLengthPicker, DevicePinOffer, DevicePinSettingsCard, DevicePinUnlockScreen, ForgotPasswordFields, ForgotPasswordForm, LoginForm, OtpForm, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasskeyLoginButton, PasskeySettingsCard, PasswordPolicyError, PinForm, ResetPasswordError, ResetPasswordForm, collectUserRoles, createBffAuthClient, defaultAuthTheme, isAllowedPinDigits, isPasswordValid, isValidForgotPasswordEmail, readPasskeyError, readPasskeyRegistered, resolvePostLoginRoute, startPasskeyLogin, startPasskeyRegistration, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePinLogin, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
|
|
1571
2607
|
//# sourceMappingURL=index.mjs.map
|
|
1572
2608
|
//# sourceMappingURL=index.mjs.map
|