@dloizides/auth-web 1.17.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 +14 -0
- package/dist/index.d.mts +178 -1
- package/dist/index.d.ts +178 -1
- package/dist/index.js +328 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +322 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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",
|
|
@@ -4031,6 +4052,306 @@ function useDemoCredentials({
|
|
|
4031
4052
|
[filled, prefillNonce, prefillIntent, credentials, accounts, handleUse]
|
|
4032
4053
|
);
|
|
4033
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
|
+
}
|
|
4034
4355
|
async function lazyFetchHttpClient(request) {
|
|
4035
4356
|
const fetchImpl = typeof fetch === "function" ? fetch.bind(globalThis) : void 0;
|
|
4036
4357
|
if (fetchImpl === void 0) {
|
|
@@ -4198,6 +4519,7 @@ exports.DEFAULT_PASSKEY_SETTINGS_LABELS = DEFAULT_PASSKEY_SETTINGS_LABELS;
|
|
|
4198
4519
|
exports.DEFAULT_PIN_LABELS = DEFAULT_PIN_LABELS;
|
|
4199
4520
|
exports.DEFAULT_PREFERRED_METHOD_HINT_LABELS = DEFAULT_PREFERRED_METHOD_HINT_LABELS;
|
|
4200
4521
|
exports.DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS = DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS;
|
|
4522
|
+
exports.DEFAULT_REGISTER_LABELS = DEFAULT_REGISTER_LABELS;
|
|
4201
4523
|
exports.DEFAULT_RESET_PASSWORD_LABELS = DEFAULT_RESET_PASSWORD_LABELS;
|
|
4202
4524
|
exports.DEVICE_PIN_ALLOWED_DIGITS = DEVICE_PIN_ALLOWED_DIGITS;
|
|
4203
4525
|
exports.DEVICE_PIN_DEFAULT_DIGITS = DEVICE_PIN_DEFAULT_DIGITS;
|
|
@@ -4227,6 +4549,9 @@ exports.PinForm = PinForm;
|
|
|
4227
4549
|
exports.PreferredMethodHint = PreferredMethodHint;
|
|
4228
4550
|
exports.PreferredMethodSettingsCard = PreferredMethodSettingsCard;
|
|
4229
4551
|
exports.PrefillIntent = PrefillIntent;
|
|
4552
|
+
exports.RegisterErrorCode = RegisterErrorCode;
|
|
4553
|
+
exports.RegisterForm = RegisterForm;
|
|
4554
|
+
exports.RegisterTestIds = RegisterTestIds;
|
|
4230
4555
|
exports.ResetPasswordError = ResetPasswordError;
|
|
4231
4556
|
exports.ResetPasswordForm = ResetPasswordForm;
|
|
4232
4557
|
exports.cachePreferredMethod = cachePreferredMethod;
|
|
@@ -4238,7 +4563,9 @@ exports.createPreferencesClient = createPreferencesClient;
|
|
|
4238
4563
|
exports.defaultAuthTheme = defaultAuthTheme;
|
|
4239
4564
|
exports.isAllowedPinDigits = isAllowedPinDigits;
|
|
4240
4565
|
exports.isPasswordValid = isPasswordValid;
|
|
4566
|
+
exports.isRegisterPasswordStrong = isRegisterPasswordStrong;
|
|
4241
4567
|
exports.isValidForgotPasswordEmail = isValidForgotPasswordEmail;
|
|
4568
|
+
exports.mapRegisterErrorCode = mapRegisterErrorCode;
|
|
4242
4569
|
exports.performBffLogout = performBffLogout;
|
|
4243
4570
|
exports.readCachedPreferredMethod = readCachedPreferredMethod;
|
|
4244
4571
|
exports.readPasskeyError = readPasskeyError;
|
|
@@ -4266,6 +4593,7 @@ exports.useOtpLogin = useOtpLogin;
|
|
|
4266
4593
|
exports.usePasskeyCeremony = usePasskeyCeremony;
|
|
4267
4594
|
exports.usePinLogin = usePinLogin;
|
|
4268
4595
|
exports.usePreferredMethodSetting = usePreferredMethodSetting;
|
|
4596
|
+
exports.useRegisterForm = useRegisterForm;
|
|
4269
4597
|
exports.useResetPasswordForm = useResetPasswordForm;
|
|
4270
4598
|
exports.validatePasswordPolicy = validatePasswordPolicy;
|
|
4271
4599
|
exports.withTestIdPrefix = withTestIdPrefix;
|