@umituz/react-native-auth 3.4.14 → 3.4.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-auth",
3
- "version": "3.4.14",
3
+ "version": "3.4.18",
4
4
  "description": "Authentication service for React Native apps - Secure, type-safe, and production-ready. Provider-agnostic design with dependency injection, configurable validation, and comprehensive error handling.",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -36,7 +36,7 @@
36
36
  "@umituz/react-native-localization": "latest",
37
37
  "@umituz/react-native-storage": "latest",
38
38
  "@umituz/react-native-tanstack": "latest",
39
- "@umituz/react-native-validation": "latest"
39
+ "@umituz/react-native-validation": "^1.4.7"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "@gorhom/bottom-sheet": ">=4.0.0",
@@ -58,7 +58,7 @@
58
58
  "devDependencies": {
59
59
  "@expo/vector-icons": "^15.0.3",
60
60
  "@gorhom/bottom-sheet": "^5.0.0",
61
- "@react-native-async-storage/async-storage": "^1.24.0",
61
+ "@react-native-async-storage/async-storage": "^2.2.0",
62
62
  "@react-native-community/datetimepicker": "^8.5.1",
63
63
  "@react-navigation/bottom-tabs": "^7.9.0",
64
64
  "@react-navigation/native": "^7.1.26",
@@ -68,15 +68,11 @@
68
68
  "@types/react": "~19.1.0",
69
69
  "@typescript-eslint/eslint-plugin": "^7.0.0",
70
70
  "@typescript-eslint/parser": "^7.0.0",
71
- "@umituz/react-native-design-system": "^2.6.33",
71
+ "@umituz/react-native-design-system": "latest",
72
72
  "@umituz/react-native-design-system-theme": "latest",
73
- "@umituz/react-native-firebase": "latest",
73
+ "@umituz/react-native-filesystem": "latest",
74
74
  "@umituz/react-native-haptics": "latest",
75
- "@umituz/react-native-localization": "latest",
76
- "@umituz/react-native-storage": "latest",
77
- "@umituz/react-native-tanstack": "latest",
78
75
  "@umituz/react-native-uuid": "latest",
79
- "@umituz/react-native-validation": "latest",
80
76
  "eslint": "^8.57.0",
81
77
  "expo-apple-authentication": "^6.0.0",
82
78
  "expo-application": "^7.0.8",
@@ -18,6 +18,8 @@ import { collectDeviceExtras } from "@umituz/react-native-design-system";
18
18
  import { initializeAuthListener } from "../../presentation/stores/initializeAuthListener";
19
19
  import type { AuthConfig } from "../../domain/value-objects/AuthConfig";
20
20
 
21
+ import type { IStorageProvider } from "./AuthPackage";
22
+
21
23
  /**
22
24
  * Unified auth initialization options
23
25
  */
@@ -31,6 +33,9 @@ export interface InitializeAuthOptions {
31
33
  /** Callback to collect device/app info for user documents */
32
34
  collectExtras?: () => Promise<Record<string, unknown>>;
33
35
 
36
+ /** Storage provider for persisting auth state (e.g. anonymous mode) */
37
+ storageProvider?: IStorageProvider;
38
+
34
39
  /** Enable auto anonymous sign-in (default: true) */
35
40
  autoAnonymousSignIn?: boolean;
36
41
 
@@ -91,6 +96,7 @@ export async function initializeAuth(
91
96
  userCollection = "users",
92
97
  extraFields,
93
98
  collectExtras,
99
+ storageProvider,
94
100
  autoAnonymousSignIn = true,
95
101
  onUserConverted,
96
102
  onAuthStateChange,
@@ -115,7 +121,7 @@ export async function initializeAuth(
115
121
 
116
122
  // 3. Initialize AuthService (for email/password auth)
117
123
  try {
118
- await initializeAuthService(auth, authConfig);
124
+ await initializeAuthService(auth, authConfig, storageProvider);
119
125
  } catch {
120
126
  // AuthService initialization failed, but we can continue
121
127
  // Email/password auth won't work, but social/anonymous will
@@ -12,7 +12,7 @@ export const styles = StyleSheet.create({
12
12
  },
13
13
  scrollContent: {
14
14
  paddingHorizontal: 24,
15
- paddingBottom: 40,
15
+ paddingBottom: 80,
16
16
  },
17
17
  closeButton: {
18
18
  position: "absolute",
@@ -11,7 +11,7 @@ import {
11
11
  BottomSheetScrollView,
12
12
  } from "@gorhom/bottom-sheet";
13
13
  import type { BottomSheetBackdropProps } from "@gorhom/bottom-sheet";
14
- import { useAppDesignTokens, AtomicText, AtomicIcon } from "@umituz/react-native-design-system";
14
+ import { useAppDesignTokens, AtomicText, AtomicIcon, AtomicKeyboardAvoidingView } from "@umituz/react-native-design-system";
15
15
  import { useLocalization } from "@umituz/react-native-localization";
16
16
  import { useAuthModalStore } from "../stores/authModalStore";
17
17
  import { useAuth } from "../hooks/useAuth";
@@ -124,16 +124,19 @@ export const AuthBottomSheet: React.FC<AuthBottomSheetProps> = ({
124
124
  backdropComponent={renderBackdrop}
125
125
  onDismiss={handleDismiss}
126
126
  enablePanDownToClose
127
- keyboardBehavior="interactive"
127
+ keyboardBehavior="extend"
128
128
  keyboardBlurBehavior="restore"
129
129
  backgroundStyle={[styles.background, { backgroundColor: tokens.colors.backgroundPrimary }]}
130
130
  handleIndicatorStyle={[styles.handleIndicator, { backgroundColor: tokens.colors.border }]}
131
131
  >
132
- <BottomSheetScrollView
133
- contentContainerStyle={styles.scrollContent}
134
- showsVerticalScrollIndicator={false}
135
- keyboardShouldPersistTaps="handled"
132
+ <AtomicKeyboardAvoidingView
133
+ style={{ flex: 1 }}
136
134
  >
135
+ <BottomSheetScrollView
136
+ contentContainerStyle={styles.scrollContent}
137
+ showsVerticalScrollIndicator={false}
138
+ keyboardShouldPersistTaps="handled"
139
+ >
137
140
  <TouchableOpacity
138
141
  style={styles.closeButton}
139
142
  onPress={handleClose}
@@ -177,6 +180,7 @@ export const AuthBottomSheet: React.FC<AuthBottomSheetProps> = ({
177
180
  )}
178
181
  </View>
179
182
  </BottomSheetScrollView>
183
+ </AtomicKeyboardAvoidingView>
180
184
  </BottomSheetModal>
181
185
  );
182
186
  };
@@ -3,8 +3,8 @@
3
3
  * Single Responsibility: Render login form UI
4
4
  */
5
5
 
6
- import React from "react";
7
- import { View, StyleSheet } from "react-native";
6
+ import React, { useRef } from "react";
7
+ import { View, StyleSheet, TextInput } from "react-native";
8
8
  import { AtomicInput, AtomicButton } from "@umituz/react-native-design-system";
9
9
  import { useLocalization } from "@umituz/react-native-localization";
10
10
  import { useLoginForm } from "../hooks/useLoginForm";
@@ -17,6 +17,7 @@ interface LoginFormProps {
17
17
 
18
18
  export const LoginForm: React.FC<LoginFormProps> = ({ onNavigateToRegister }) => {
19
19
  const { t } = useLocalization();
20
+ const passwordRef = useRef<TextInput>(null);
20
21
  const {
21
22
  email,
22
23
  password,
@@ -42,20 +43,27 @@ export const LoginForm: React.FC<LoginFormProps> = ({ onNavigateToRegister }) =>
42
43
  disabled={loading}
43
44
  state={emailError ? "error" : "default"}
44
45
  helperText={emailError || undefined}
46
+ returnKeyType="next"
47
+ onSubmitEditing={() => passwordRef.current?.focus()}
48
+ blurOnSubmit={false}
45
49
  />
46
50
  </View>
47
51
 
48
52
  <View style={styles.inputContainer}>
49
53
  <AtomicInput
54
+ ref={passwordRef}
50
55
  label={t("auth.password")}
51
56
  value={password}
52
57
  onChangeText={handlePasswordChange}
53
58
  placeholder={t("auth.passwordPlaceholder")}
54
59
  secureTextEntry
60
+ showPasswordToggle
55
61
  autoCapitalize="none"
56
62
  disabled={loading}
57
63
  state={passwordError ? "error" : "default"}
58
64
  helperText={passwordError || undefined}
65
+ returnKeyType="done"
66
+ onSubmitEditing={() => { void handleSignIn(); }}
59
67
  />
60
68
  </View>
61
69
 
@@ -3,8 +3,8 @@
3
3
  * Single Responsibility: Render register form UI
4
4
  */
5
5
 
6
- import React from "react";
7
- import { View, StyleSheet } from "react-native";
6
+ import React, { useRef } from "react";
7
+ import { View, StyleSheet, TextInput } from "react-native";
8
8
  import { AtomicInput, AtomicButton } from "@umituz/react-native-design-system";
9
9
  import { useLocalization } from "@umituz/react-native-localization";
10
10
  import { useRegisterForm } from "../hooks/useRegisterForm";
@@ -30,6 +30,10 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
30
30
  onPrivacyPress,
31
31
  }) => {
32
32
  const { t } = useLocalization();
33
+ const emailRef = useRef<TextInput>(null);
34
+ const passwordRef = useRef<TextInput>(null);
35
+ const confirmPasswordRef = useRef<TextInput>(null);
36
+
33
37
  const {
34
38
  displayName,
35
39
  email,
@@ -61,11 +65,15 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
61
65
  disabled={loading}
62
66
  state={fieldErrors.displayName ? "error" : "default"}
63
67
  helperText={fieldErrors.displayName || undefined}
68
+ returnKeyType="next"
69
+ onSubmitEditing={() => emailRef.current?.focus()}
70
+ blurOnSubmit={false}
64
71
  />
65
72
  </View>
66
73
 
67
74
  <View style={styles.inputContainer}>
68
75
  <AtomicInput
76
+ ref={emailRef}
69
77
  label={t("auth.email")}
70
78
  value={email}
71
79
  onChangeText={handleEmailChange}
@@ -75,20 +83,28 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
75
83
  disabled={loading}
76
84
  state={fieldErrors.email ? "error" : "default"}
77
85
  helperText={fieldErrors.email || undefined}
86
+ returnKeyType="next"
87
+ onSubmitEditing={() => passwordRef.current?.focus()}
88
+ blurOnSubmit={false}
78
89
  />
79
90
  </View>
80
91
 
81
92
  <View style={styles.inputContainer}>
82
93
  <AtomicInput
94
+ ref={passwordRef}
83
95
  label={t("auth.password")}
84
96
  value={password}
85
97
  onChangeText={handlePasswordChange}
86
98
  placeholder={t("auth.passwordPlaceholder")}
87
99
  secureTextEntry
100
+ showPasswordToggle
88
101
  autoCapitalize="none"
89
102
  disabled={loading}
90
103
  state={fieldErrors.password ? "error" : "default"}
91
104
  helperText={fieldErrors.password || undefined}
105
+ returnKeyType="next"
106
+ onSubmitEditing={() => confirmPasswordRef.current?.focus()}
107
+ blurOnSubmit={false}
92
108
  />
93
109
  {password.length > 0 && (
94
110
  <PasswordStrengthIndicator requirements={passwordRequirements} />
@@ -97,6 +113,7 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
97
113
 
98
114
  <View style={styles.inputContainer}>
99
115
  <AtomicInput
116
+ ref={confirmPasswordRef}
100
117
  label={t("auth.confirmPassword")}
101
118
  value={confirmPassword}
102
119
  onChangeText={handleConfirmPasswordChange}
@@ -104,10 +121,13 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
104
121
  t("auth.confirmPasswordPlaceholder")
105
122
  }
106
123
  secureTextEntry
124
+ showPasswordToggle
107
125
  autoCapitalize="none"
108
126
  disabled={loading}
109
127
  state={fieldErrors.confirmPassword ? "error" : "default"}
110
128
  helperText={fieldErrors.confirmPassword || undefined}
129
+ returnKeyType="done"
130
+ onSubmitEditing={() => { void handleSignUp(); }}
111
131
  />
112
132
  {confirmPassword.length > 0 && (
113
133
  <PasswordMatchIndicator isMatch={passwordsMatch} />