@dloizides/auth-web 1.16.0 → 1.18.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 +34 -0
- package/dist/index.d.mts +212 -5
- package/dist/index.d.ts +212 -5
- package/dist/index.js +415 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +407 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -331,6 +331,27 @@ var DEFAULT_ACCOUNT_SETTINGS_LABELS = {
|
|
|
331
331
|
errorFailed: "Could not change your password. Try again later."
|
|
332
332
|
};
|
|
333
333
|
|
|
334
|
+
// src/components/labels/registerLabels.ts
|
|
335
|
+
function field(label, placeholder) {
|
|
336
|
+
return { label, placeholder, hint: placeholder, inputLabel: label };
|
|
337
|
+
}
|
|
338
|
+
var DEFAULT_REGISTER_LABELS = {
|
|
339
|
+
title: "Create account",
|
|
340
|
+
subtitle: "Sign up to get started",
|
|
341
|
+
submit: "Create account",
|
|
342
|
+
submitHint: "Creates your account",
|
|
343
|
+
submitting: "Creating account...",
|
|
344
|
+
fields: {
|
|
345
|
+
firstName: field("First name", "Enter your first name"),
|
|
346
|
+
lastName: field("Last name", "Enter your last name"),
|
|
347
|
+
username: field("Username", "Choose a username"),
|
|
348
|
+
email: field("Email", "Enter your email"),
|
|
349
|
+
password: field("Password", "Choose a password"),
|
|
350
|
+
confirmPassword: field("Confirm password", "Repeat your password"),
|
|
351
|
+
tenantName: field("Organisation name", "Enter your organisation name")
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
|
|
334
355
|
// src/components/testIds.ts
|
|
335
356
|
var AuthTestIds = {
|
|
336
357
|
loginForm: "auth-login-form",
|
|
@@ -415,6 +436,8 @@ var AuthTestIds = {
|
|
|
415
436
|
changePasswordSuccess: "auth-change-password-success",
|
|
416
437
|
// Public-demo credentials panel
|
|
417
438
|
demoCredentialsHint: "auth-demo-credentials-hint",
|
|
439
|
+
// Per-account heading, present only when >1 account is published (multi-account).
|
|
440
|
+
demoCredentialsAccountLabel: "auth-demo-credentials-account-label",
|
|
418
441
|
demoCredentialsUsername: "auth-demo-credentials-username",
|
|
419
442
|
demoCredentialsPassword: "auth-demo-credentials-password",
|
|
420
443
|
demoCredentialsUseButton: "auth-demo-credentials-use",
|
|
@@ -3571,9 +3594,21 @@ function DemoCredentialsBody({
|
|
|
3571
3594
|
styles: styles3,
|
|
3572
3595
|
authStyles,
|
|
3573
3596
|
testIdPrefix,
|
|
3597
|
+
accountLabel,
|
|
3598
|
+
testIdIndex,
|
|
3574
3599
|
onUse
|
|
3575
3600
|
}) {
|
|
3601
|
+
const testId = (base) => withTestIdPrefix(testIdIndex === void 0 ? base : `${base}-${testIdIndex}`, testIdPrefix);
|
|
3602
|
+
const hasLabel = typeof accountLabel === "string" && accountLabel.length > 0;
|
|
3576
3603
|
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { children: [
|
|
3604
|
+
hasLabel ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3605
|
+
reactNative.Text,
|
|
3606
|
+
{
|
|
3607
|
+
style: styles3.accountLabel,
|
|
3608
|
+
testID: testId(AuthTestIds.demoCredentialsAccountLabel),
|
|
3609
|
+
children: accountLabel
|
|
3610
|
+
}
|
|
3611
|
+
) : null,
|
|
3577
3612
|
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.row, children: [
|
|
3578
3613
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.rowLabel, children: labels.usernameLabel }),
|
|
3579
3614
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3581,7 +3616,7 @@ function DemoCredentialsBody({
|
|
|
3581
3616
|
{
|
|
3582
3617
|
selectable: true,
|
|
3583
3618
|
style: styles3.rowValue,
|
|
3584
|
-
testID:
|
|
3619
|
+
testID: testId(AuthTestIds.demoCredentialsUsername),
|
|
3585
3620
|
children: credentials.username
|
|
3586
3621
|
}
|
|
3587
3622
|
)
|
|
@@ -3593,7 +3628,7 @@ function DemoCredentialsBody({
|
|
|
3593
3628
|
{
|
|
3594
3629
|
selectable: true,
|
|
3595
3630
|
style: styles3.rowValue,
|
|
3596
|
-
testID:
|
|
3631
|
+
testID: testId(AuthTestIds.demoCredentialsPassword),
|
|
3597
3632
|
children: credentials.password
|
|
3598
3633
|
}
|
|
3599
3634
|
)
|
|
@@ -3605,7 +3640,7 @@ function DemoCredentialsBody({
|
|
|
3605
3640
|
accessibilityLabel: labels.useCredentials,
|
|
3606
3641
|
accessibilityRole: "button",
|
|
3607
3642
|
style: [authStyles.secondaryButton, styles3.useButton],
|
|
3608
|
-
testID:
|
|
3643
|
+
testID: testId(AuthTestIds.demoCredentialsUseButton),
|
|
3609
3644
|
onPress: onUse,
|
|
3610
3645
|
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: authStyles.secondaryButtonText, children: labels.useCredentials })
|
|
3611
3646
|
}
|
|
@@ -3658,6 +3693,15 @@ function useDemoCredentialsStyles(theme) {
|
|
|
3658
3693
|
marginBottom: spacing.sm,
|
|
3659
3694
|
color: colors.textSecondary
|
|
3660
3695
|
},
|
|
3696
|
+
accountLabel: {
|
|
3697
|
+
fontSize: typography.caption,
|
|
3698
|
+
fontWeight: "700",
|
|
3699
|
+
color: colors.text,
|
|
3700
|
+
// Separates one account block from the previous one; the first block sits
|
|
3701
|
+
// under the panel description / disclosure divider, which already spaces it.
|
|
3702
|
+
marginTop: spacing.sm,
|
|
3703
|
+
marginBottom: spacing.xs / HALF
|
|
3704
|
+
},
|
|
3661
3705
|
row: {
|
|
3662
3706
|
flexDirection: "row",
|
|
3663
3707
|
alignItems: "center",
|
|
@@ -3733,8 +3777,39 @@ function resolveDemoCredentials(credentials) {
|
|
|
3733
3777
|
}
|
|
3734
3778
|
return { username, password };
|
|
3735
3779
|
}
|
|
3780
|
+
|
|
3781
|
+
// src/demo/resolveDemoAccounts.ts
|
|
3782
|
+
function resolveAccount(account) {
|
|
3783
|
+
if (account === void 0 || account === null) {
|
|
3784
|
+
return null;
|
|
3785
|
+
}
|
|
3786
|
+
const pair = resolveDemoCredentials(account);
|
|
3787
|
+
if (pair === null) {
|
|
3788
|
+
return null;
|
|
3789
|
+
}
|
|
3790
|
+
const label = typeof account.label === "string" ? account.label : "";
|
|
3791
|
+
return { label, username: pair.username, password: pair.password };
|
|
3792
|
+
}
|
|
3793
|
+
function resolveAccountList(accounts) {
|
|
3794
|
+
if (!Array.isArray(accounts)) {
|
|
3795
|
+
return [];
|
|
3796
|
+
}
|
|
3797
|
+
return accounts.map(resolveAccount).filter((account) => account !== null);
|
|
3798
|
+
}
|
|
3799
|
+
function resolveDemoAccounts(credentials) {
|
|
3800
|
+
if (credentials === void 0 || credentials === null) {
|
|
3801
|
+
return [];
|
|
3802
|
+
}
|
|
3803
|
+
const fromList = resolveAccountList(credentials.publishedAccounts);
|
|
3804
|
+
if (fromList.length > 0) {
|
|
3805
|
+
return fromList;
|
|
3806
|
+
}
|
|
3807
|
+
const single = resolveDemoCredentials(credentials);
|
|
3808
|
+
return single === null ? [] : [{ label: "", username: single.username, password: single.password }];
|
|
3809
|
+
}
|
|
3736
3810
|
function DemoCredentialsHint({
|
|
3737
3811
|
credentials,
|
|
3812
|
+
accounts,
|
|
3738
3813
|
variant = "disclosure" /* Disclosure */,
|
|
3739
3814
|
theme: themeProp,
|
|
3740
3815
|
labels: labelsProp,
|
|
@@ -3749,29 +3824,35 @@ function DemoCredentialsHint({
|
|
|
3749
3824
|
() => ({ ...DEFAULT_DEMO_CREDENTIALS_HINT_LABELS, ...labelsProp }),
|
|
3750
3825
|
[labelsProp]
|
|
3751
3826
|
);
|
|
3752
|
-
const
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3827
|
+
const resolvedAccounts = react.useMemo(
|
|
3828
|
+
() => accounts !== void 0 && accounts.length > 0 ? resolveAccountList(accounts) : resolveDemoAccounts(credentials),
|
|
3829
|
+
[accounts, credentials]
|
|
3830
|
+
);
|
|
3831
|
+
const makeUse = react.useCallback(
|
|
3832
|
+
(account) => onUse === void 0 ? void 0 : () => onUse({ username: account.username, password: account.password }),
|
|
3833
|
+
[onUse]
|
|
3834
|
+
);
|
|
3758
3835
|
const handleToggle = react.useCallback(() => {
|
|
3759
3836
|
setExpanded((current) => !current);
|
|
3760
3837
|
}, []);
|
|
3761
|
-
if (
|
|
3838
|
+
if (resolvedAccounts.length === 0) {
|
|
3762
3839
|
return null;
|
|
3763
3840
|
}
|
|
3764
|
-
const
|
|
3841
|
+
const isSingle = resolvedAccounts.length === 1;
|
|
3842
|
+
const body = resolvedAccounts.map((account, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3765
3843
|
DemoCredentialsBody,
|
|
3766
3844
|
{
|
|
3845
|
+
accountLabel: isSingle ? void 0 : account.label,
|
|
3767
3846
|
authStyles,
|
|
3768
|
-
credentials:
|
|
3847
|
+
credentials: { username: account.username, password: account.password },
|
|
3769
3848
|
labels,
|
|
3770
3849
|
styles: styles3,
|
|
3850
|
+
testIdIndex: isSingle ? void 0 : index,
|
|
3771
3851
|
testIdPrefix,
|
|
3772
|
-
onUse:
|
|
3773
|
-
}
|
|
3774
|
-
|
|
3852
|
+
onUse: makeUse(account)
|
|
3853
|
+
},
|
|
3854
|
+
`${account.username}-${String(index)}`
|
|
3855
|
+
));
|
|
3775
3856
|
if (variant === "panel" /* Panel */) {
|
|
3776
3857
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3777
3858
|
reactNative.View,
|
|
@@ -3927,7 +4008,11 @@ function useDemoCredentials({
|
|
|
3927
4008
|
credentials,
|
|
3928
4009
|
prefillOnMount = false
|
|
3929
4010
|
} = {}) {
|
|
3930
|
-
const
|
|
4011
|
+
const accounts = react.useMemo(() => resolveDemoAccounts(credentials), [credentials]);
|
|
4012
|
+
const resolved = react.useMemo(() => {
|
|
4013
|
+
const first = accounts[0];
|
|
4014
|
+
return first === void 0 ? null : { username: first.username, password: first.password };
|
|
4015
|
+
}, [accounts]);
|
|
3931
4016
|
const [filled, setFilled] = react.useState(
|
|
3932
4017
|
prefillOnMount ? resolved : null
|
|
3933
4018
|
);
|
|
@@ -3959,13 +4044,314 @@ function useDemoCredentials({
|
|
|
3959
4044
|
prefillIntent
|
|
3960
4045
|
},
|
|
3961
4046
|
// `credentials` is passed through unresolved on purpose: the hint applies
|
|
3962
|
-
// `
|
|
3963
|
-
// standalone, without this hook.
|
|
3964
|
-
|
|
4047
|
+
// `resolveDemoAccounts` itself, so it fails closed even when it is used
|
|
4048
|
+
// standalone, without this hook. `accounts` is the already-resolved list the
|
|
4049
|
+
// hint prefers — one labelled row per entry.
|
|
4050
|
+
hintProps: { credentials, accounts, onUse: handleUse }
|
|
3965
4051
|
}),
|
|
3966
|
-
[filled, prefillNonce, prefillIntent, credentials, handleUse]
|
|
4052
|
+
[filled, prefillNonce, prefillIntent, credentials, accounts, handleUse]
|
|
3967
4053
|
);
|
|
3968
4054
|
}
|
|
4055
|
+
|
|
4056
|
+
// src/components/registerTestIds.ts
|
|
4057
|
+
var RegisterTestIds = {
|
|
4058
|
+
form: "register-form",
|
|
4059
|
+
firstNameInput: "register-first-name-input",
|
|
4060
|
+
lastNameInput: "register-last-name-input",
|
|
4061
|
+
usernameInput: "register-username-input",
|
|
4062
|
+
emailInput: "register-email-input",
|
|
4063
|
+
passwordInput: "register-password-input",
|
|
4064
|
+
confirmPasswordInput: "register-confirm-password-input",
|
|
4065
|
+
tenantNameInput: "register-tenant-name-input",
|
|
4066
|
+
submitButton: "register-submit-button",
|
|
4067
|
+
websiteInput: "register-website"
|
|
4068
|
+
};
|
|
4069
|
+
var FIELDS = [
|
|
4070
|
+
{ key: "firstName", testId: RegisterTestIds.firstNameInput, autoComplete: "name" },
|
|
4071
|
+
{ key: "lastName", testId: RegisterTestIds.lastNameInput, autoComplete: "name" },
|
|
4072
|
+
{ key: "username", testId: RegisterTestIds.usernameInput, autoComplete: "username" },
|
|
4073
|
+
{ key: "email", testId: RegisterTestIds.emailInput, autoComplete: "email", keyboardType: "email-address" },
|
|
4074
|
+
{ key: "password", testId: RegisterTestIds.passwordInput, secure: true },
|
|
4075
|
+
{ key: "confirmPassword", testId: RegisterTestIds.confirmPasswordInput, secure: true },
|
|
4076
|
+
{ key: "tenantName", testId: RegisterTestIds.tenantNameInput }
|
|
4077
|
+
];
|
|
4078
|
+
var OFF_SCREEN = -9999;
|
|
4079
|
+
var HONEYPOT_SIZE = 1;
|
|
4080
|
+
var HONEYPOT_PLACEHOLDER = "Website";
|
|
4081
|
+
var honeypotStyles = reactNative.StyleSheet.create({
|
|
4082
|
+
honeypot: {
|
|
4083
|
+
position: "absolute",
|
|
4084
|
+
left: OFF_SCREEN,
|
|
4085
|
+
top: OFF_SCREEN,
|
|
4086
|
+
width: HONEYPOT_SIZE,
|
|
4087
|
+
height: HONEYPOT_SIZE,
|
|
4088
|
+
opacity: 0
|
|
4089
|
+
}
|
|
4090
|
+
});
|
|
4091
|
+
function RegisterFormFields({
|
|
4092
|
+
values,
|
|
4093
|
+
labels,
|
|
4094
|
+
disabled,
|
|
4095
|
+
theme,
|
|
4096
|
+
styles: styles3,
|
|
4097
|
+
onChange,
|
|
4098
|
+
testIdPrefix
|
|
4099
|
+
}) {
|
|
4100
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4101
|
+
FIELDS.map((config) => {
|
|
4102
|
+
const copy = labels.fields[config.key];
|
|
4103
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.fieldGroup, children: [
|
|
4104
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.label, children: copy.label }),
|
|
4105
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4106
|
+
reactNative.TextInput,
|
|
4107
|
+
{
|
|
4108
|
+
accessibilityHint: copy.hint,
|
|
4109
|
+
accessibilityLabel: copy.inputLabel,
|
|
4110
|
+
autoCapitalize: "none",
|
|
4111
|
+
autoComplete: config.autoComplete,
|
|
4112
|
+
autoCorrect: false,
|
|
4113
|
+
editable: !disabled,
|
|
4114
|
+
keyboardType: config.keyboardType ?? "default",
|
|
4115
|
+
placeholder: copy.placeholder,
|
|
4116
|
+
placeholderTextColor: theme.colors.textSecondary,
|
|
4117
|
+
secureTextEntry: config.secure === true,
|
|
4118
|
+
style: styles3.input,
|
|
4119
|
+
testID: withTestIdPrefix(config.testId, testIdPrefix),
|
|
4120
|
+
value: values[config.key],
|
|
4121
|
+
onChangeText: (text) => onChange(config.key, text)
|
|
4122
|
+
}
|
|
4123
|
+
)
|
|
4124
|
+
] }, config.key);
|
|
4125
|
+
}),
|
|
4126
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4127
|
+
reactNative.TextInput,
|
|
4128
|
+
{
|
|
4129
|
+
accessibilityElementsHidden: true,
|
|
4130
|
+
autoComplete: "off",
|
|
4131
|
+
focusable: false,
|
|
4132
|
+
importantForAccessibility: "no-hide-descendants",
|
|
4133
|
+
placeholder: HONEYPOT_PLACEHOLDER,
|
|
4134
|
+
style: honeypotStyles.honeypot,
|
|
4135
|
+
testID: withTestIdPrefix(RegisterTestIds.websiteInput, testIdPrefix),
|
|
4136
|
+
value: values.website,
|
|
4137
|
+
onChangeText: (text) => onChange("website", text)
|
|
4138
|
+
}
|
|
4139
|
+
)
|
|
4140
|
+
] });
|
|
4141
|
+
}
|
|
4142
|
+
|
|
4143
|
+
// src/hooks/RegisterErrorCode.ts
|
|
4144
|
+
var RegisterErrorCode = /* @__PURE__ */ ((RegisterErrorCode2) => {
|
|
4145
|
+
RegisterErrorCode2["MissingFields"] = "missingFields";
|
|
4146
|
+
RegisterErrorCode2["InvalidEmail"] = "invalidEmail";
|
|
4147
|
+
RegisterErrorCode2["WeakPassword"] = "weakPassword";
|
|
4148
|
+
RegisterErrorCode2["PasswordMismatch"] = "passwordMismatch";
|
|
4149
|
+
RegisterErrorCode2["UsernameTaken"] = "usernameTaken";
|
|
4150
|
+
RegisterErrorCode2["EmailTaken"] = "emailTaken";
|
|
4151
|
+
RegisterErrorCode2["RealmInvalid"] = "realmInvalid";
|
|
4152
|
+
RegisterErrorCode2["ValidationFailed"] = "validationFailed";
|
|
4153
|
+
RegisterErrorCode2["Failed"] = "failed";
|
|
4154
|
+
RegisterErrorCode2["InFlight"] = "inFlight";
|
|
4155
|
+
return RegisterErrorCode2;
|
|
4156
|
+
})(RegisterErrorCode || {});
|
|
4157
|
+
|
|
4158
|
+
// src/hooks/registerErrors.ts
|
|
4159
|
+
var MIN_PASSWORD_LENGTH = 8;
|
|
4160
|
+
var EMAIL_REGEX4 = /^[^@\s]+@[^.\s]+\.\S+$/;
|
|
4161
|
+
var PASSWORD_LETTER_REGEX = /[a-zA-Z]/;
|
|
4162
|
+
var PASSWORD_DIGIT_REGEX = /\d/;
|
|
4163
|
+
var PASSWORD_SPECIAL_REGEX = /[^a-zA-Z0-9]/;
|
|
4164
|
+
var SERVER_ERROR_CODES = [
|
|
4165
|
+
["USERNAME_TAKEN", "usernameTaken" /* UsernameTaken */],
|
|
4166
|
+
["EMAIL_TAKEN", "emailTaken" /* EmailTaken */],
|
|
4167
|
+
["REALM_REQUIRED", "realmInvalid" /* RealmInvalid */],
|
|
4168
|
+
["REALM_INVALID", "realmInvalid" /* RealmInvalid */]
|
|
4169
|
+
];
|
|
4170
|
+
function isRegisterPasswordStrong(password) {
|
|
4171
|
+
if (password.length < MIN_PASSWORD_LENGTH) {
|
|
4172
|
+
return false;
|
|
4173
|
+
}
|
|
4174
|
+
if (!PASSWORD_LETTER_REGEX.test(password)) {
|
|
4175
|
+
return false;
|
|
4176
|
+
}
|
|
4177
|
+
if (!PASSWORD_DIGIT_REGEX.test(password)) {
|
|
4178
|
+
return false;
|
|
4179
|
+
}
|
|
4180
|
+
return PASSWORD_SPECIAL_REGEX.test(password);
|
|
4181
|
+
}
|
|
4182
|
+
function trimRegisterValues(values) {
|
|
4183
|
+
return {
|
|
4184
|
+
firstName: values.firstName.trim(),
|
|
4185
|
+
lastName: values.lastName.trim(),
|
|
4186
|
+
username: values.username.trim(),
|
|
4187
|
+
email: values.email.trim(),
|
|
4188
|
+
password: values.password,
|
|
4189
|
+
confirmPassword: values.confirmPassword,
|
|
4190
|
+
tenantName: values.tenantName.trim(),
|
|
4191
|
+
website: values.website.trim()
|
|
4192
|
+
};
|
|
4193
|
+
}
|
|
4194
|
+
function hasMissingRequiredField(values) {
|
|
4195
|
+
const required = [
|
|
4196
|
+
values.firstName,
|
|
4197
|
+
values.lastName,
|
|
4198
|
+
values.username,
|
|
4199
|
+
values.email,
|
|
4200
|
+
values.password,
|
|
4201
|
+
values.tenantName
|
|
4202
|
+
];
|
|
4203
|
+
return required.some((value) => value === "");
|
|
4204
|
+
}
|
|
4205
|
+
function validateRegisterValues(values, passwordPolicy) {
|
|
4206
|
+
if (hasMissingRequiredField(values)) {
|
|
4207
|
+
return "missingFields" /* MissingFields */;
|
|
4208
|
+
}
|
|
4209
|
+
if (!EMAIL_REGEX4.test(values.email)) {
|
|
4210
|
+
return "invalidEmail" /* InvalidEmail */;
|
|
4211
|
+
}
|
|
4212
|
+
if (!passwordPolicy(values.password)) {
|
|
4213
|
+
return "weakPassword" /* WeakPassword */;
|
|
4214
|
+
}
|
|
4215
|
+
if (values.password !== values.confirmPassword) {
|
|
4216
|
+
return "passwordMismatch" /* PasswordMismatch */;
|
|
4217
|
+
}
|
|
4218
|
+
return null;
|
|
4219
|
+
}
|
|
4220
|
+
function messageOf(error) {
|
|
4221
|
+
if (error instanceof Error) {
|
|
4222
|
+
return error.message;
|
|
4223
|
+
}
|
|
4224
|
+
return typeof error === "string" ? error : "";
|
|
4225
|
+
}
|
|
4226
|
+
function mapRegisterErrorCode(error) {
|
|
4227
|
+
const message = messageOf(error);
|
|
4228
|
+
if (message === "") {
|
|
4229
|
+
return "failed" /* Failed */;
|
|
4230
|
+
}
|
|
4231
|
+
const match = SERVER_ERROR_CODES.find(([code]) => message.includes(code));
|
|
4232
|
+
return match === void 0 ? "validationFailed" /* ValidationFailed */ : match[1];
|
|
4233
|
+
}
|
|
4234
|
+
|
|
4235
|
+
// src/hooks/useRegisterForm.ts
|
|
4236
|
+
var EMPTY_VALUES = {
|
|
4237
|
+
firstName: "",
|
|
4238
|
+
lastName: "",
|
|
4239
|
+
username: "",
|
|
4240
|
+
email: "",
|
|
4241
|
+
password: "",
|
|
4242
|
+
confirmPassword: "",
|
|
4243
|
+
tenantName: "",
|
|
4244
|
+
website: ""
|
|
4245
|
+
};
|
|
4246
|
+
function toSubmitValues(values) {
|
|
4247
|
+
return {
|
|
4248
|
+
firstName: values.firstName,
|
|
4249
|
+
lastName: values.lastName,
|
|
4250
|
+
username: values.username,
|
|
4251
|
+
email: values.email,
|
|
4252
|
+
password: values.password,
|
|
4253
|
+
tenantName: values.tenantName,
|
|
4254
|
+
website: values.website
|
|
4255
|
+
};
|
|
4256
|
+
}
|
|
4257
|
+
function useRegisterForm({
|
|
4258
|
+
onSubmit,
|
|
4259
|
+
passwordPolicy = isRegisterPasswordStrong
|
|
4260
|
+
}) {
|
|
4261
|
+
const [state, setState] = react.useState(EMPTY_VALUES);
|
|
4262
|
+
const [isSubmitting, setIsSubmitting] = react.useState(false);
|
|
4263
|
+
const [error, setError] = react.useState(null);
|
|
4264
|
+
const inFlight = react.useRef(false);
|
|
4265
|
+
const setField = react.useCallback((field2, value) => {
|
|
4266
|
+
setState((prev) => ({ ...prev, [field2]: value }));
|
|
4267
|
+
}, []);
|
|
4268
|
+
const submit = react.useCallback(async () => {
|
|
4269
|
+
if (inFlight.current) {
|
|
4270
|
+
return { ok: false, error: "inFlight" /* InFlight */ };
|
|
4271
|
+
}
|
|
4272
|
+
const trimmed = trimRegisterValues(state);
|
|
4273
|
+
const refusal = trimmed.website === "" ? validateRegisterValues(trimmed, passwordPolicy) : "failed" /* Failed */;
|
|
4274
|
+
if (refusal !== null) {
|
|
4275
|
+
setError(refusal);
|
|
4276
|
+
return { ok: false, error: refusal };
|
|
4277
|
+
}
|
|
4278
|
+
inFlight.current = true;
|
|
4279
|
+
setError(null);
|
|
4280
|
+
setIsSubmitting(true);
|
|
4281
|
+
try {
|
|
4282
|
+
const result = await onSubmit(toSubmitValues(trimmed));
|
|
4283
|
+
return { ok: true, result };
|
|
4284
|
+
} catch (caught) {
|
|
4285
|
+
const code = mapRegisterErrorCode(caught);
|
|
4286
|
+
setError(code);
|
|
4287
|
+
return { ok: false, error: code };
|
|
4288
|
+
} finally {
|
|
4289
|
+
inFlight.current = false;
|
|
4290
|
+
setIsSubmitting(false);
|
|
4291
|
+
}
|
|
4292
|
+
}, [onSubmit, passwordPolicy, state]);
|
|
4293
|
+
return { state, setField, submit, isSubmitting, error };
|
|
4294
|
+
}
|
|
4295
|
+
function RegisterForm({
|
|
4296
|
+
onSubmit,
|
|
4297
|
+
onSuccess,
|
|
4298
|
+
onError,
|
|
4299
|
+
onSubmitAttempt,
|
|
4300
|
+
passwordPolicy,
|
|
4301
|
+
labels: labelsProp,
|
|
4302
|
+
theme: themeProp,
|
|
4303
|
+
footer,
|
|
4304
|
+
testIdPrefix
|
|
4305
|
+
}) {
|
|
4306
|
+
const theme = useAuthTheme(themeProp);
|
|
4307
|
+
const styles3 = useAuthStyles(theme);
|
|
4308
|
+
const labels = react.useMemo(
|
|
4309
|
+
() => ({ ...DEFAULT_REGISTER_LABELS, ...labelsProp }),
|
|
4310
|
+
[labelsProp]
|
|
4311
|
+
);
|
|
4312
|
+
const { state, setField, submit, isSubmitting } = useRegisterForm({ onSubmit, passwordPolicy });
|
|
4313
|
+
const handlePress = react.useCallback(() => {
|
|
4314
|
+
onSubmitAttempt?.();
|
|
4315
|
+
void submit().then((outcome) => {
|
|
4316
|
+
if (outcome.ok) {
|
|
4317
|
+
onSuccess(outcome.result);
|
|
4318
|
+
} else if (outcome.error !== "inFlight" /* InFlight */) {
|
|
4319
|
+
onError?.(outcome.error);
|
|
4320
|
+
}
|
|
4321
|
+
});
|
|
4322
|
+
}, [onError, onSubmitAttempt, onSuccess, submit]);
|
|
4323
|
+
const buttonStyle = isSubmitting ? [styles3.primaryButton, styles3.primaryButtonDisabled] : styles3.primaryButton;
|
|
4324
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles3.screen, children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.card, testID: withTestIdPrefix(RegisterTestIds.form, testIdPrefix), children: [
|
|
4325
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.title, children: labels.title }),
|
|
4326
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.subtitle, children: labels.subtitle }),
|
|
4327
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4328
|
+
RegisterFormFields,
|
|
4329
|
+
{
|
|
4330
|
+
disabled: isSubmitting,
|
|
4331
|
+
labels,
|
|
4332
|
+
styles: styles3,
|
|
4333
|
+
testIdPrefix,
|
|
4334
|
+
theme,
|
|
4335
|
+
values: state,
|
|
4336
|
+
onChange: setField
|
|
4337
|
+
}
|
|
4338
|
+
),
|
|
4339
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4340
|
+
reactNative.TouchableOpacity,
|
|
4341
|
+
{
|
|
4342
|
+
accessibilityHint: labels.submitHint,
|
|
4343
|
+
accessibilityLabel: isSubmitting ? labels.submitting : labels.submit,
|
|
4344
|
+
accessibilityRole: "button",
|
|
4345
|
+
disabled: isSubmitting,
|
|
4346
|
+
style: buttonStyle,
|
|
4347
|
+
testID: withTestIdPrefix(RegisterTestIds.submitButton, testIdPrefix),
|
|
4348
|
+
onPress: handlePress,
|
|
4349
|
+
children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.primaryButtonText, children: labels.submit })
|
|
4350
|
+
}
|
|
4351
|
+
),
|
|
4352
|
+
footer
|
|
4353
|
+
] }) });
|
|
4354
|
+
}
|
|
3969
4355
|
async function lazyFetchHttpClient(request) {
|
|
3970
4356
|
const fetchImpl = typeof fetch === "function" ? fetch.bind(globalThis) : void 0;
|
|
3971
4357
|
if (fetchImpl === void 0) {
|
|
@@ -4133,6 +4519,7 @@ exports.DEFAULT_PASSKEY_SETTINGS_LABELS = DEFAULT_PASSKEY_SETTINGS_LABELS;
|
|
|
4133
4519
|
exports.DEFAULT_PIN_LABELS = DEFAULT_PIN_LABELS;
|
|
4134
4520
|
exports.DEFAULT_PREFERRED_METHOD_HINT_LABELS = DEFAULT_PREFERRED_METHOD_HINT_LABELS;
|
|
4135
4521
|
exports.DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS = DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS;
|
|
4522
|
+
exports.DEFAULT_REGISTER_LABELS = DEFAULT_REGISTER_LABELS;
|
|
4136
4523
|
exports.DEFAULT_RESET_PASSWORD_LABELS = DEFAULT_RESET_PASSWORD_LABELS;
|
|
4137
4524
|
exports.DEVICE_PIN_ALLOWED_DIGITS = DEVICE_PIN_ALLOWED_DIGITS;
|
|
4138
4525
|
exports.DEVICE_PIN_DEFAULT_DIGITS = DEVICE_PIN_DEFAULT_DIGITS;
|
|
@@ -4162,6 +4549,9 @@ exports.PinForm = PinForm;
|
|
|
4162
4549
|
exports.PreferredMethodHint = PreferredMethodHint;
|
|
4163
4550
|
exports.PreferredMethodSettingsCard = PreferredMethodSettingsCard;
|
|
4164
4551
|
exports.PrefillIntent = PrefillIntent;
|
|
4552
|
+
exports.RegisterErrorCode = RegisterErrorCode;
|
|
4553
|
+
exports.RegisterForm = RegisterForm;
|
|
4554
|
+
exports.RegisterTestIds = RegisterTestIds;
|
|
4165
4555
|
exports.ResetPasswordError = ResetPasswordError;
|
|
4166
4556
|
exports.ResetPasswordForm = ResetPasswordForm;
|
|
4167
4557
|
exports.cachePreferredMethod = cachePreferredMethod;
|
|
@@ -4173,12 +4563,16 @@ exports.createPreferencesClient = createPreferencesClient;
|
|
|
4173
4563
|
exports.defaultAuthTheme = defaultAuthTheme;
|
|
4174
4564
|
exports.isAllowedPinDigits = isAllowedPinDigits;
|
|
4175
4565
|
exports.isPasswordValid = isPasswordValid;
|
|
4566
|
+
exports.isRegisterPasswordStrong = isRegisterPasswordStrong;
|
|
4176
4567
|
exports.isValidForgotPasswordEmail = isValidForgotPasswordEmail;
|
|
4568
|
+
exports.mapRegisterErrorCode = mapRegisterErrorCode;
|
|
4177
4569
|
exports.performBffLogout = performBffLogout;
|
|
4178
4570
|
exports.readCachedPreferredMethod = readCachedPreferredMethod;
|
|
4179
4571
|
exports.readPasskeyError = readPasskeyError;
|
|
4180
4572
|
exports.readPasskeyRegistered = readPasskeyRegistered;
|
|
4181
4573
|
exports.resolveAccessibleRoutes = resolveAccessibleRoutes;
|
|
4574
|
+
exports.resolveAccountList = resolveAccountList;
|
|
4575
|
+
exports.resolveDemoAccounts = resolveDemoAccounts;
|
|
4182
4576
|
exports.resolveDemoCredentials = resolveDemoCredentials;
|
|
4183
4577
|
exports.resolvePostLoginRoute = resolvePostLoginRoute;
|
|
4184
4578
|
exports.startPasskeyLogin = startPasskeyLogin;
|
|
@@ -4199,6 +4593,7 @@ exports.useOtpLogin = useOtpLogin;
|
|
|
4199
4593
|
exports.usePasskeyCeremony = usePasskeyCeremony;
|
|
4200
4594
|
exports.usePinLogin = usePinLogin;
|
|
4201
4595
|
exports.usePreferredMethodSetting = usePreferredMethodSetting;
|
|
4596
|
+
exports.useRegisterForm = useRegisterForm;
|
|
4202
4597
|
exports.useResetPasswordForm = useResetPasswordForm;
|
|
4203
4598
|
exports.validatePasswordPolicy = validatePasswordPolicy;
|
|
4204
4599
|
exports.withTestIdPrefix = withTestIdPrefix;
|