@umituz/react-native-auth 3.2.1 → 3.2.3

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.2.1",
3
+ "version": "3.2.3",
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",
@@ -72,7 +72,7 @@
72
72
  "@typescript-eslint/parser": "^7.0.0",
73
73
  "@umituz/react-native-design-system": "latest",
74
74
  "@umituz/react-native-design-system-theme": "*",
75
- "@umituz/react-native-firebase": "^1.13.27",
75
+ "@umituz/react-native-firebase": "latest",
76
76
  "@umituz/react-native-haptics": "*",
77
77
  "@umituz/react-native-localization": "*",
78
78
  "@umituz/react-native-sentry": "*",
package/src/index.ts CHANGED
@@ -207,6 +207,7 @@ export {
207
207
  useAuthStore,
208
208
  initializeAuthListener,
209
209
  resetAuthListener,
210
+ isAuthListenerInitialized,
210
211
  selectIsAuthenticated,
211
212
  selectUserId,
212
213
  selectIsAnonymous,
@@ -219,7 +220,8 @@ export {
219
220
  getIsAnonymous,
220
221
  } from './presentation/stores/authStore';
221
222
 
222
- export type { UserType } from './presentation/stores/authStore';
223
+ export type { UserType, AuthState, AuthActions } from './presentation/stores/authStore';
224
+ export type { AuthListenerOptions } from './types/auth-store.types';
223
225
 
224
226
  // =============================================================================
225
227
  // PRESENTATION LAYER - Utilities
@@ -146,7 +146,6 @@ export class AuthService implements IAuthService {
146
146
 
147
147
  getConfig(): AuthConfig { return this.config; }
148
148
  getGuestModeService(): GuestModeService { return this.guestModeService; }
149
- getRepository(): AuthRepository { return this.repositoryInstance; }
150
149
  }
151
150
 
152
151
  let authServiceInstance: AuthService | null = null;
@@ -13,8 +13,7 @@ export const useSignUpMutation = () => {
13
13
  mutationFn: async (params: SignUpParams): Promise<AuthUser> => {
14
14
  const service = getAuthService();
15
15
  if (!service) throw new Error("Auth Service not initialized");
16
- // Access repository directly
17
- return service.getRepository().signUp(params);
16
+ return service.signUp(params);
18
17
  },
19
18
  });
20
19
  };
@@ -24,7 +23,7 @@ export const useSignInMutation = () => {
24
23
  mutationFn: async (params: SignInParams): Promise<AuthUser> => {
25
24
  const service = getAuthService();
26
25
  if (!service) throw new Error("Auth Service not initialized");
27
- return service.getRepository().signIn(params);
26
+ return service.signIn(params);
28
27
  },
29
28
  });
30
29
  };
@@ -34,7 +33,7 @@ export const useSignOutMutation = () => {
34
33
  mutationFn: async (): Promise<void> => {
35
34
  const service = getAuthService();
36
35
  if (!service) throw new Error("Auth Service not initialized");
37
- return service.getRepository().signOut();
36
+ return service.signOut();
38
37
  },
39
38
  });
40
39
  };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Auth Store Selectors
3
+ * Pure functions for deriving state from auth store
4
+ */
5
+
6
+ import type { AuthState, UserType } from "../../types/auth-store.types";
7
+
8
+ /**
9
+ * Get current user ID
10
+ */
11
+ export const selectUserId = (state: AuthState): string | null => {
12
+ return state.firebaseUser?.uid ?? state.user?.uid ?? null;
13
+ };
14
+
15
+ /**
16
+ * Check if user is authenticated (not guest, not anonymous)
17
+ */
18
+ export const selectIsAuthenticated = (state: AuthState): boolean => {
19
+ return !!state.user && !state.isGuest && !state.user.isAnonymous;
20
+ };
21
+
22
+ /**
23
+ * Check if user is anonymous
24
+ */
25
+ export const selectIsAnonymous = (state: AuthState): boolean => {
26
+ return state.firebaseUser?.isAnonymous ?? state.user?.isAnonymous ?? false;
27
+ };
28
+
29
+ /**
30
+ * Get current user type
31
+ */
32
+ export const selectUserType = (state: AuthState): UserType => {
33
+ if (!state.firebaseUser && !state.user) {
34
+ return "none";
35
+ }
36
+
37
+ const isAnonymous =
38
+ state.firebaseUser?.isAnonymous ?? state.user?.isAnonymous ?? false;
39
+
40
+ return isAnonymous ? "anonymous" : "authenticated";
41
+ };
42
+
43
+ /**
44
+ * Check if auth is ready (initialized and not loading)
45
+ */
46
+ export const selectIsAuthReady = (state: AuthState): boolean => {
47
+ return state.initialized && !state.loading;
48
+ };
@@ -1,79 +1,50 @@
1
1
  /**
2
2
  * Auth Store
3
- * Centralized auth state management using Zustand with AsyncStorage persistence
3
+ * Centralized auth state management using Zustand with persistence
4
4
  *
5
5
  * Single source of truth for auth state across the app.
6
6
  * Firebase auth changes are synced via initializeAuthListener().
7
7
  */
8
8
 
9
9
  import { createStore } from "@umituz/react-native-storage";
10
- import { onAuthStateChanged, type User } from "firebase/auth";
11
- import { getFirebaseAuth } from "@umituz/react-native-firebase";
12
10
  import type { AuthUser } from "../../domain/entities/AuthUser";
13
11
  import { mapToAuthUser } from "../../infrastructure/utils/UserMapper";
14
- import { getAuthService } from "../../infrastructure/services/AuthService";
15
-
16
- declare const __DEV__: boolean;
17
-
18
- /**
19
- * User type classification
20
- */
21
- export type UserType = "authenticated" | "anonymous" | "none";
22
-
23
- // =============================================================================
24
- // STATE TYPES
25
- // =============================================================================
26
-
27
- interface AuthState {
28
- /** Mapped AuthUser (null if not authenticated) */
29
- user: AuthUser | null;
30
- /** Raw Firebase user reference */
31
- firebaseUser: User | null;
32
- /** Loading state during auth operations */
33
- loading: boolean;
34
- /** Guest mode (user skipped authentication) */
35
- isGuest: boolean;
36
- /** Error message from last auth operation */
37
- error: string | null;
38
- /** Whether auth listener has initialized */
39
- initialized: boolean;
40
- }
41
-
42
- interface AuthActions {
43
- /** Update user from Firebase listener */
44
- setFirebaseUser: (user: User | null) => void;
45
- /** Set loading state */
46
- setLoading: (loading: boolean) => void;
47
- /** Set guest mode */
48
- setIsGuest: (isGuest: boolean) => void;
49
- /** Set error message */
50
- setError: (error: string | null) => void;
51
- /** Mark as initialized */
52
- setInitialized: (initialized: boolean) => void;
53
- /** Reset to initial state */
54
- reset: () => void;
55
- }
56
-
57
- // =============================================================================
58
- // INITIAL STATE
59
- // =============================================================================
60
-
61
- const initialState: AuthState = {
62
- user: null,
63
- firebaseUser: null,
64
- loading: true,
65
- isGuest: false,
66
- error: null,
67
- initialized: false,
12
+ import type { AuthState, AuthActions, UserType } from "../../types/auth-store.types";
13
+ import { initialAuthState } from "../../types/auth-store.types";
14
+ import {
15
+ selectUserId,
16
+ selectIsAuthenticated,
17
+ selectIsAnonymous,
18
+ selectUserType,
19
+ selectIsAuthReady,
20
+ } from "./auth.selectors";
21
+
22
+ // Re-export types for convenience
23
+ export type { AuthState, AuthActions, UserType };
24
+
25
+ // Re-export selectors
26
+ export {
27
+ selectUserId,
28
+ selectIsAuthenticated,
29
+ selectIsAnonymous,
30
+ selectUserType,
31
+ selectIsAuthReady,
68
32
  };
69
33
 
34
+ // Re-export listener functions
35
+ export {
36
+ initializeAuthListener,
37
+ resetAuthListener,
38
+ isAuthListenerInitialized,
39
+ } from "./initializeAuthListener";
40
+
70
41
  // =============================================================================
71
42
  // STORE
72
43
  // =============================================================================
73
44
 
74
45
  export const useAuthStore = createStore<AuthState, AuthActions>({
75
46
  name: "auth-store",
76
- initialState,
47
+ initialState: initialAuthState,
77
48
  persist: true,
78
49
  version: 1,
79
50
  partialize: (state) => ({
@@ -122,56 +93,10 @@ export const useAuthStore = createStore<AuthState, AuthActions>({
122
93
 
123
94
  setInitialized: (initialized) => set({ initialized }),
124
95
 
125
- reset: () => set(initialState),
96
+ reset: () => set(initialAuthState),
126
97
  }),
127
98
  });
128
99
 
129
- // =============================================================================
130
- // SELECTORS
131
- // =============================================================================
132
-
133
- /**
134
- * Get current user ID
135
- */
136
- export const selectUserId = (state: AuthState): string | null => {
137
- return state.firebaseUser?.uid ?? state.user?.uid ?? null;
138
- };
139
-
140
- /**
141
- * Check if user is authenticated (not guest, not anonymous)
142
- */
143
- export const selectIsAuthenticated = (state: AuthState): boolean => {
144
- return !!state.user && !state.isGuest && !state.user.isAnonymous;
145
- };
146
-
147
- /**
148
- * Check if user is anonymous
149
- */
150
- export const selectIsAnonymous = (state: AuthState): boolean => {
151
- return state.firebaseUser?.isAnonymous ?? state.user?.isAnonymous ?? false;
152
- };
153
-
154
- /**
155
- * Get current user type
156
- */
157
- export const selectUserType = (state: AuthState): UserType => {
158
- if (!state.firebaseUser && !state.user) {
159
- return "none";
160
- }
161
-
162
- const isAnonymous =
163
- state.firebaseUser?.isAnonymous ?? state.user?.isAnonymous ?? false;
164
-
165
- return isAnonymous ? "anonymous" : "authenticated";
166
- };
167
-
168
- /**
169
- * Check if auth is ready (initialized and not loading)
170
- */
171
- export const selectIsAuthReady = (state: AuthState): boolean => {
172
- return state.initialized && !state.loading;
173
- };
174
-
175
100
  // =============================================================================
176
101
  // NON-HOOK GETTERS
177
102
  // =============================================================================
@@ -210,64 +135,3 @@ export function getIsGuest(): boolean {
210
135
  export function getIsAnonymous(): boolean {
211
136
  return selectIsAnonymous(useAuthStore.getState());
212
137
  }
213
-
214
- // =============================================================================
215
- // LISTENER
216
- // =============================================================================
217
-
218
- let listenerInitialized = false;
219
-
220
- /**
221
- * Initialize Firebase auth listener
222
- * Call once in app root, returns unsubscribe function
223
- */
224
- export function initializeAuthListener(): () => void {
225
- if (listenerInitialized) {
226
- return () => {};
227
- }
228
-
229
- const auth = getFirebaseAuth();
230
- const store = useAuthStore.getState();
231
-
232
- if (!auth) {
233
- store.setLoading(false);
234
- store.setInitialized(true);
235
- return () => {};
236
- }
237
-
238
- const service = getAuthService();
239
- if (service) {
240
- const isGuest = service.getIsGuestMode();
241
- if (isGuest) {
242
- store.setIsGuest(true);
243
- }
244
- }
245
-
246
- listenerInitialized = true;
247
-
248
- const unsubscribe = onAuthStateChanged(auth, (user) => {
249
- if (typeof __DEV__ !== "undefined" && __DEV__) {
250
- // eslint-disable-next-line no-console
251
- console.log("[authStore] Auth state changed:", user?.uid ?? "null");
252
- }
253
-
254
- store.setFirebaseUser(user);
255
- store.setInitialized(true);
256
-
257
- if (user && !user.isAnonymous && store.isGuest) {
258
- store.setIsGuest(false);
259
- }
260
- });
261
-
262
- return () => {
263
- unsubscribe();
264
- listenerInitialized = false;
265
- };
266
- }
267
-
268
- /**
269
- * Reset listener state (for testing)
270
- */
271
- export function resetAuthListener(): void {
272
- listenerInitialized = false;
273
- }
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Auth Listener Initialization
3
+ * Sets up Firebase auth state listener with optional auto anonymous sign-in
4
+ */
5
+
6
+ import { onAuthStateChanged } from "firebase/auth";
7
+ import {
8
+ getFirebaseAuth,
9
+ anonymousAuthService,
10
+ } from "@umituz/react-native-firebase";
11
+ import { useAuthStore } from "./authStore";
12
+ import { getAuthService } from "../../infrastructure/services/AuthService";
13
+ import type { AuthListenerOptions } from "../../types/auth-store.types";
14
+
15
+ declare const __DEV__: boolean;
16
+
17
+ let listenerInitialized = false;
18
+
19
+ /**
20
+ * Initialize Firebase auth listener
21
+ * Call once in app root, returns unsubscribe function
22
+ *
23
+ * @param options - Configuration options
24
+ * @param options.autoAnonymousSignIn - Enable auto anonymous sign-in (default: true)
25
+ * @param options.onAuthStateChange - Callback when auth state changes
26
+ */
27
+ export function initializeAuthListener(
28
+ options: AuthListenerOptions = {}
29
+ ): () => void {
30
+ const { autoAnonymousSignIn = true, onAuthStateChange } = options;
31
+
32
+ if (listenerInitialized) {
33
+ return () => {};
34
+ }
35
+
36
+ const auth = getFirebaseAuth();
37
+ const store = useAuthStore.getState();
38
+
39
+ if (!auth) {
40
+ store.setLoading(false);
41
+ store.setInitialized(true);
42
+ return () => {};
43
+ }
44
+
45
+ const service = getAuthService();
46
+ if (service) {
47
+ const isGuest = service.getIsGuestMode();
48
+ if (isGuest) {
49
+ store.setIsGuest(true);
50
+ }
51
+ }
52
+
53
+ listenerInitialized = true;
54
+
55
+ const unsubscribe = onAuthStateChanged(auth, (user) => {
56
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
57
+ // eslint-disable-next-line no-console
58
+ console.log("[authStore] Auth state changed:", user?.uid ?? "null");
59
+ }
60
+
61
+ // Auto sign-in anonymously if no user and autoAnonymousSignIn is enabled
62
+ if (!user && autoAnonymousSignIn) {
63
+ void (async () => {
64
+ try {
65
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
66
+ // eslint-disable-next-line no-console
67
+ console.log("[authStore] Auto signing in anonymously...");
68
+ }
69
+ await anonymousAuthService.signInAnonymously(auth);
70
+ // The listener will be called again with the new anonymous user
71
+ } catch (error) {
72
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
73
+ // eslint-disable-next-line no-console
74
+ console.warn("[authStore] Auto anonymous sign-in failed:", error);
75
+ }
76
+ // Continue with null user if anonymous sign-in fails
77
+ store.setFirebaseUser(null);
78
+ store.setInitialized(true);
79
+ }
80
+ })();
81
+ return;
82
+ }
83
+
84
+ store.setFirebaseUser(user);
85
+ store.setInitialized(true);
86
+
87
+ if (user && !user.isAnonymous && store.isGuest) {
88
+ store.setIsGuest(false);
89
+ }
90
+
91
+ // Call optional callback
92
+ onAuthStateChange?.(user);
93
+ });
94
+
95
+ return () => {
96
+ unsubscribe();
97
+ listenerInitialized = false;
98
+ };
99
+ }
100
+
101
+ /**
102
+ * Reset listener state (for testing)
103
+ */
104
+ export function resetAuthListener(): void {
105
+ listenerInitialized = false;
106
+ }
107
+
108
+ /**
109
+ * Check if listener is initialized
110
+ */
111
+ export function isAuthListenerInitialized(): boolean {
112
+ return listenerInitialized;
113
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Auth Store Types
3
+ * Type definitions for auth state management
4
+ */
5
+
6
+ import type { User } from "firebase/auth";
7
+ import type { AuthUser } from "../domain/entities/AuthUser";
8
+
9
+ /**
10
+ * User type classification
11
+ */
12
+ export type UserType = "authenticated" | "anonymous" | "none";
13
+
14
+ /**
15
+ * Auth state interface
16
+ */
17
+ export interface AuthState {
18
+ /** Mapped AuthUser (null if not authenticated) */
19
+ user: AuthUser | null;
20
+ /** Raw Firebase user reference */
21
+ firebaseUser: User | null;
22
+ /** Loading state during auth operations */
23
+ loading: boolean;
24
+ /** Guest mode (user skipped authentication) */
25
+ isGuest: boolean;
26
+ /** Error message from last auth operation */
27
+ error: string | null;
28
+ /** Whether auth listener has initialized */
29
+ initialized: boolean;
30
+ }
31
+
32
+ /**
33
+ * Auth store actions interface
34
+ */
35
+ export interface AuthActions {
36
+ /** Update user from Firebase listener */
37
+ setFirebaseUser: (user: User | null) => void;
38
+ /** Set loading state */
39
+ setLoading: (loading: boolean) => void;
40
+ /** Set guest mode */
41
+ setIsGuest: (isGuest: boolean) => void;
42
+ /** Set error message */
43
+ setError: (error: string | null) => void;
44
+ /** Mark as initialized */
45
+ setInitialized: (initialized: boolean) => void;
46
+ /** Reset to initial state */
47
+ reset: () => void;
48
+ }
49
+
50
+ /**
51
+ * Initial auth state
52
+ */
53
+ export const initialAuthState: AuthState = {
54
+ user: null,
55
+ firebaseUser: null,
56
+ loading: true,
57
+ isGuest: false,
58
+ error: null,
59
+ initialized: false,
60
+ };
61
+
62
+ /**
63
+ * Auth listener initialization options
64
+ */
65
+ export interface AuthListenerOptions {
66
+ /** Enable auto anonymous sign-in when no user is logged in */
67
+ autoAnonymousSignIn?: boolean;
68
+ /** Callback when auth state changes */
69
+ onAuthStateChange?: (user: User | null) => void;
70
+ }