@dloizides/auth-web 1.2.1 → 1.3.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.mjs CHANGED
@@ -18,6 +18,7 @@ var DEFAULT_LOGIN_LABELS = {
18
18
  submit: "Sign in",
19
19
  submitting: "Signing in...",
20
20
  forgotPassword: "Forgot password?",
21
+ signUp: "Create an account",
21
22
  invalidCredentials: "Incorrect username or password.",
22
23
  missingFields: "Enter both your username and password."
23
24
  };
@@ -32,6 +33,11 @@ var DEFAULT_FORGOT_PASSWORD_LABELS = {
32
33
  networkError: "Something went wrong. Please try again.",
33
34
  invalidEmail: "Enter a valid email address."
34
35
  };
36
+ var DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS = {
37
+ ...DEFAULT_FORGOT_PASSWORD_LABELS,
38
+ cancel: "Cancel",
39
+ close: "Close"
40
+ };
35
41
  var DEFAULT_OTP_LABELS = {
36
42
  requestTitle: "Sign in with a code",
37
43
  requestDescription: "Enter your email and we will send you a one-time code.",
@@ -85,10 +91,13 @@ var AuthTestIds = {
85
91
  loginPasswordInput: "auth-login-password",
86
92
  loginSubmitButton: "auth-login-submit",
87
93
  loginForgotLink: "auth-login-forgot-link",
94
+ loginSignUpLink: "auth-login-signup-link",
88
95
  loginError: "auth-login-error",
89
96
  forgotPasswordForm: "auth-forgot-form",
90
97
  forgotPasswordEmailInput: "auth-forgot-email",
91
98
  forgotPasswordSubmitButton: "auth-forgot-submit",
99
+ forgotPasswordCancelButton: "auth-forgot-cancel",
100
+ forgotPasswordCloseButton: "auth-forgot-close",
92
101
  forgotPasswordError: "auth-forgot-error",
93
102
  forgotPasswordSuccess: "auth-forgot-success",
94
103
  resetPasswordForm: "auth-reset-form",
@@ -358,6 +367,7 @@ function LoginForm({
358
367
  labels: labelsProp,
359
368
  onSuccess,
360
369
  onForgotPassword,
370
+ onSignUp,
361
371
  testIdPrefix
362
372
  }) {
363
373
  const theme = useAuthTheme(themeProp);
@@ -464,7 +474,20 @@ function LoginForm({
464
474
  onPress: handleSubmit,
465
475
  children: isSubmitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles.primaryButtonText, children: labels.submit })
466
476
  }
467
- )
477
+ ),
478
+ onSignUp !== void 0 ? /* @__PURE__ */ jsx(
479
+ TouchableOpacity,
480
+ {
481
+ accessibilityHint: labels.signUp,
482
+ accessibilityLabel: labels.signUp,
483
+ accessibilityRole: "link",
484
+ disabled: isSubmitting,
485
+ style: styles.fieldGroup,
486
+ testID: withTestIdPrefix(AuthTestIds.loginSignUpLink, testIdPrefix),
487
+ onPress: onSignUp,
488
+ children: /* @__PURE__ */ jsx(Text, { style: styles.linkText, children: labels.signUp })
489
+ }
490
+ ) : null
468
491
  ] }) });
469
492
  }
470
493
  function useBffForgotPassword(options) {
@@ -595,6 +618,182 @@ function ForgotPasswordForm({
595
618
  }
596
619
  ) });
597
620
  }
621
+ var EMAIL_REGEX2 = /^[^@\s]+@[^.\s]+\.[^\s]+$/;
622
+ function isValidForgotPasswordEmail(value) {
623
+ return EMAIL_REGEX2.test(value.trim());
624
+ }
625
+ function useForgotPasswordSubmit({
626
+ client,
627
+ resetUrlTemplate,
628
+ onSuccess
629
+ }) {
630
+ const [email, setEmail] = useState("");
631
+ const [submitted, setSubmitted] = useState(false);
632
+ const [isSubmitting, setIsSubmitting] = useState(false);
633
+ const [hasNetworkError, setHasNetworkError] = useState(false);
634
+ const canSubmit = isValidForgotPasswordEmail(email) && !isSubmitting;
635
+ const submit = useCallback(() => {
636
+ const target = email.trim();
637
+ if (!isValidForgotPasswordEmail(target) || isSubmitting) {
638
+ return;
639
+ }
640
+ setHasNetworkError(false);
641
+ setIsSubmitting(true);
642
+ const request = { email: target, resetUrlTemplate };
643
+ client.forgotPassword(request).then(() => {
644
+ setSubmitted(true);
645
+ onSuccess?.();
646
+ }).catch(() => setHasNetworkError(true)).finally(() => setIsSubmitting(false));
647
+ }, [client, email, isSubmitting, resetUrlTemplate, onSuccess]);
648
+ const reset = useCallback(() => {
649
+ setEmail("");
650
+ setSubmitted(false);
651
+ setIsSubmitting(false);
652
+ setHasNetworkError(false);
653
+ }, []);
654
+ return {
655
+ email,
656
+ setEmail,
657
+ submitted,
658
+ isSubmitting,
659
+ hasNetworkError,
660
+ canSubmit,
661
+ submit,
662
+ reset
663
+ };
664
+ }
665
+ var SECONDARY_BORDER_WIDTH = 1;
666
+ function useModalStyles(theme) {
667
+ return useMemo(
668
+ () => StyleSheet.create({
669
+ body: { padding: theme.spacing.md },
670
+ actions: {
671
+ flexDirection: "row",
672
+ justifyContent: "flex-end",
673
+ alignItems: "center",
674
+ marginTop: theme.spacing.md,
675
+ gap: theme.spacing.sm
676
+ },
677
+ secondaryButton: {
678
+ borderRadius: theme.radii.input,
679
+ paddingVertical: theme.spacing.sm,
680
+ paddingHorizontal: theme.spacing.md,
681
+ borderWidth: SECONDARY_BORDER_WIDTH,
682
+ borderColor: theme.colors.border
683
+ },
684
+ secondaryButtonText: {
685
+ fontSize: theme.typography.body,
686
+ fontWeight: "600",
687
+ color: theme.colors.text
688
+ }
689
+ }),
690
+ [theme]
691
+ );
692
+ }
693
+ function ForgotPasswordFields({
694
+ client,
695
+ theme: themeProp,
696
+ labels: labelsProp,
697
+ resetUrlTemplate,
698
+ visible = true,
699
+ onSuccess,
700
+ onCancel,
701
+ onClose,
702
+ testIdPrefix
703
+ }) {
704
+ const theme = useAuthTheme(themeProp);
705
+ const styles = useAuthStyles(theme);
706
+ const modalStyles = useModalStyles(theme);
707
+ const labels = useMemo(
708
+ () => ({ ...DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS, ...labelsProp }),
709
+ [labelsProp]
710
+ );
711
+ const form = useForgotPasswordSubmit({ client, resetUrlTemplate, onSuccess });
712
+ const { reset } = form;
713
+ useEffect(() => {
714
+ if (!visible) {
715
+ reset();
716
+ }
717
+ }, [visible, reset]);
718
+ const submitButtonStyle = form.canSubmit ? styles.primaryButton : [styles.primaryButton, styles.primaryButtonDisabled];
719
+ const handleCancel = () => {
720
+ form.reset();
721
+ onCancel?.();
722
+ };
723
+ const handleClose = () => {
724
+ form.reset();
725
+ onClose?.();
726
+ };
727
+ if (form.submitted) {
728
+ return /* @__PURE__ */ jsxs(View, { style: modalStyles.body, testID: withTestIdPrefix(AuthTestIds.forgotPasswordForm, testIdPrefix), children: [
729
+ /* @__PURE__ */ jsx(Text, { style: styles.successText, testID: withTestIdPrefix(AuthTestIds.forgotPasswordSuccess, testIdPrefix), children: labels.successMessage }),
730
+ onClose !== void 0 ? /* @__PURE__ */ jsx(View, { style: modalStyles.actions, children: /* @__PURE__ */ jsx(
731
+ TouchableOpacity,
732
+ {
733
+ accessibilityHint: labels.close,
734
+ accessibilityLabel: labels.close,
735
+ accessibilityRole: "button",
736
+ style: styles.primaryButton,
737
+ testID: withTestIdPrefix(AuthTestIds.forgotPasswordCloseButton, testIdPrefix),
738
+ onPress: handleClose,
739
+ children: /* @__PURE__ */ jsx(Text, { style: styles.primaryButtonText, children: labels.close })
740
+ }
741
+ ) }) : null
742
+ ] });
743
+ }
744
+ return /* @__PURE__ */ jsxs(View, { style: modalStyles.body, testID: withTestIdPrefix(AuthTestIds.forgotPasswordForm, testIdPrefix), children: [
745
+ /* @__PURE__ */ jsx(Text, { style: styles.subtitle, children: labels.description }),
746
+ /* @__PURE__ */ jsxs(View, { style: styles.fieldGroup, children: [
747
+ /* @__PURE__ */ jsx(Text, { style: styles.label, children: labels.emailLabel }),
748
+ /* @__PURE__ */ jsx(
749
+ TextInput,
750
+ {
751
+ accessibilityHint: labels.emailPlaceholder,
752
+ accessibilityLabel: labels.emailLabel,
753
+ autoCapitalize: "none",
754
+ autoCorrect: false,
755
+ editable: !form.isSubmitting,
756
+ keyboardType: "email-address",
757
+ placeholder: labels.emailPlaceholder,
758
+ placeholderTextColor: theme.colors.textSecondary,
759
+ style: styles.input,
760
+ testID: withTestIdPrefix(AuthTestIds.forgotPasswordEmailInput, testIdPrefix),
761
+ value: form.email,
762
+ onChangeText: form.setEmail
763
+ }
764
+ )
765
+ ] }),
766
+ form.hasNetworkError ? /* @__PURE__ */ jsx(Text, { style: styles.errorText, testID: withTestIdPrefix(AuthTestIds.forgotPasswordError, testIdPrefix), children: labels.networkError }) : null,
767
+ /* @__PURE__ */ jsxs(View, { style: modalStyles.actions, children: [
768
+ onCancel !== void 0 ? /* @__PURE__ */ jsx(
769
+ TouchableOpacity,
770
+ {
771
+ accessibilityHint: labels.cancel,
772
+ accessibilityLabel: labels.cancel,
773
+ accessibilityRole: "button",
774
+ disabled: form.isSubmitting,
775
+ style: modalStyles.secondaryButton,
776
+ testID: withTestIdPrefix(AuthTestIds.forgotPasswordCancelButton, testIdPrefix),
777
+ onPress: handleCancel,
778
+ children: /* @__PURE__ */ jsx(Text, { style: modalStyles.secondaryButtonText, children: labels.cancel })
779
+ }
780
+ ) : null,
781
+ /* @__PURE__ */ jsx(
782
+ TouchableOpacity,
783
+ {
784
+ accessibilityHint: labels.submit,
785
+ accessibilityLabel: form.isSubmitting ? labels.submitting : labels.submit,
786
+ accessibilityRole: "button",
787
+ disabled: !form.canSubmit,
788
+ style: submitButtonStyle,
789
+ testID: withTestIdPrefix(AuthTestIds.forgotPasswordSubmitButton, testIdPrefix),
790
+ onPress: form.submit,
791
+ children: form.isSubmitting ? /* @__PURE__ */ jsx(ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsx(Text, { style: styles.primaryButtonText, children: labels.submit })
792
+ }
793
+ )
794
+ ] })
795
+ ] });
796
+ }
598
797
 
599
798
  // src/hooks/ResetPasswordError.ts
600
799
  var ResetPasswordError = /* @__PURE__ */ ((ResetPasswordError2) => {
@@ -1096,9 +1295,9 @@ function useOtpLogin(options) {
1096
1295
  ]
1097
1296
  );
1098
1297
  }
1099
- var EMAIL_REGEX2 = /^[^@\s]+@[^.\s]+\.[^\s]+$/;
1298
+ var EMAIL_REGEX3 = /^[^@\s]+@[^.\s]+\.[^\s]+$/;
1100
1299
  function isValidEmail2(value) {
1101
- return EMAIL_REGEX2.test(value);
1300
+ return EMAIL_REGEX3.test(value);
1102
1301
  }
1103
1302
  function transportErrorFor(step, error, labels) {
1104
1303
  if (error === null) {
@@ -1368,6 +1567,6 @@ function resolvePostLoginRoute(user, table) {
1368
1567
  return table.fallback ?? null;
1369
1568
  }
1370
1569
 
1371
- export { AuthTestIds, AuthThemeProvider, BffAuthStatus, DEFAULT_FORGOT_PASSWORD_LABELS, DEFAULT_LOGIN_LABELS, DEFAULT_OTP_LABELS, DEFAULT_PIN_LABELS, DEFAULT_RESET_PASSWORD_LABELS, ForgotPasswordForm, LoginForm, OtpForm, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasswordPolicyError, PinForm, ResetPasswordError, ResetPasswordForm, collectUserRoles, createBffAuthClient, defaultAuthTheme, isPasswordValid, resolvePostLoginRoute, useAuthTheme, useBffAuth, useBffForgotPassword, useBffResetPassword, useOtpLogin, usePinLogin, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
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 };
1372
1571
  //# sourceMappingURL=index.mjs.map
1373
1572
  //# sourceMappingURL=index.mjs.map