@umituz/react-native-auth 3.6.61 → 3.6.62

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.
Files changed (40) hide show
  1. package/package.json +1 -1
  2. package/src/application/ports/IAuthRepository.ts +3 -3
  3. package/src/index.ts +5 -18
  4. package/src/infrastructure/providers/FirebaseAuthProvider.ts +6 -2
  5. package/src/infrastructure/repositories/AuthRepository.ts +3 -3
  6. package/src/infrastructure/services/AuthEventService.ts +4 -0
  7. package/src/infrastructure/services/AuthService.ts +14 -36
  8. package/src/infrastructure/services/initializeAuth.ts +0 -15
  9. package/src/infrastructure/utils/AuthValidation.ts +5 -2
  10. package/src/infrastructure/utils/UserMapper.ts +9 -6
  11. package/src/infrastructure/utils/authStateHandler.ts +0 -7
  12. package/src/infrastructure/utils/validation/sanitization.ts +2 -89
  13. package/src/init/createAuthInitModule.ts +0 -15
  14. package/src/presentation/hooks/mutations/useAuthMutations.ts +3 -3
  15. package/src/presentation/hooks/useAuthBottomSheet.ts +10 -1
  16. package/src/presentation/hooks/useGoogleAuth.ts +43 -11
  17. package/src/presentation/stores/auth.selectors.ts +12 -6
  18. package/src/presentation/stores/authStore.ts +6 -9
  19. package/src/presentation/stores/initializeAuthListener.ts +44 -7
  20. package/src/application/ports/IAuthService.ts +0 -60
  21. package/src/domain/utils/migration.ts +0 -44
  22. package/src/infrastructure/adapters/UIProviderAdapter.ts +0 -43
  23. package/src/infrastructure/services/UserDocument.types.ts +0 -60
  24. package/src/infrastructure/services/UserDocumentService.ts +0 -86
  25. package/src/infrastructure/services/app-service-helpers.ts +0 -35
  26. package/src/infrastructure/types/UI.types.ts +0 -11
  27. package/src/infrastructure/utils/auth-tracker.util.ts +0 -23
  28. package/src/infrastructure/utils/userDocumentBuilder.util.ts +0 -114
  29. package/src/infrastructure/utils/validation/BaseValidators.ts +0 -35
  30. package/src/infrastructure/utils/validation/CollectionValidators.ts +0 -56
  31. package/src/infrastructure/utils/validation/DateValidators.ts +0 -71
  32. package/src/infrastructure/utils/validation/FormValidators.ts +0 -22
  33. package/src/infrastructure/utils/validation/NumberValidators.ts +0 -50
  34. package/src/infrastructure/utils/validation/StringValidators.ts +0 -55
  35. package/src/infrastructure/utils/validation/types.ts +0 -15
  36. package/src/presentation/screens/change-password/ChangePasswordScreen.tsx +0 -179
  37. package/src/presentation/screens/change-password/ChangePasswordScreen.types.ts +0 -77
  38. package/src/presentation/screens/change-password/RequirementItem.tsx +0 -47
  39. package/src/presentation/screens/change-password/index.ts +0 -6
  40. package/src/types/translations.types.ts +0 -89
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-auth",
3
- "version": "3.6.61",
3
+ "version": "3.6.62",
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",
@@ -1,10 +1,10 @@
1
1
 
2
2
  import type { AuthUser } from "../../domain/entities/AuthUser";
3
- import type { SignUpParams, SignInParams } from "../ports/IAuthService";
3
+ import type { AuthCredentials, SignUpCredentials } from "./IAuthProvider";
4
4
 
5
5
  export interface IAuthRepository {
6
- signUp(params: SignUpParams): Promise<AuthUser>;
7
- signIn(params: SignInParams): Promise<AuthUser>;
6
+ signUp(params: SignUpCredentials): Promise<AuthUser>;
7
+ signIn(params: AuthCredentials): Promise<AuthUser>;
8
8
  signOut(): Promise<void>;
9
9
  getCurrentUser(): AuthUser | null;
10
10
  onAuthStateChange(callback: (user: AuthUser | null) => void): () => void;
package/src/index.ts CHANGED
@@ -39,14 +39,11 @@ export {
39
39
  } from './domain/value-objects/AuthConfig';
40
40
 
41
41
  export type { UserProfile, UpdateProfileParams } from './domain/entities/UserProfile';
42
- export { migrateUserData, configureMigration } from './domain/utils/migration';
43
- export type { MigrationConfig } from './domain/utils/migration';
44
42
 
45
43
  // =============================================================================
46
44
  // APPLICATION LAYER
47
45
  // =============================================================================
48
46
 
49
- export type { IAuthService, SignUpParams, SignInParams } from './application/ports/IAuthService';
50
47
  export type {
51
48
  IAuthProvider,
52
49
  AuthCredentials,
@@ -70,17 +67,6 @@ export {
70
67
  createStorageProvider,
71
68
  StorageProviderAdapter,
72
69
  } from './infrastructure/adapters/StorageProviderAdapter';
73
- export {
74
- ensureUserDocument,
75
- markUserDeleted,
76
- configureUserDocumentService,
77
- } from './infrastructure/services/UserDocumentService';
78
- export type {
79
- UserDocumentConfig,
80
- UserDocumentExtras,
81
- UserDocumentUser,
82
- } from './infrastructure/services/UserDocumentService';
83
-
84
70
  export {
85
71
  initializeAuth,
86
72
  isAuthInitialized,
@@ -171,24 +157,24 @@ export { RegisterScreen } from './presentation/screens/RegisterScreen';
171
157
  export type { RegisterScreenProps } from './presentation/screens/RegisterScreen';
172
158
 
173
159
  export { AccountScreen } from './presentation/screens/AccountScreen';
174
- export type { AccountScreenProps } from './presentation/screens/AccountScreen';
160
+ export type { AccountScreenProps, AccountScreenConfig } from './presentation/screens/AccountScreen';
175
161
 
176
162
  export { EditProfileScreen } from './presentation/screens/EditProfileScreen';
177
163
  export type { EditProfileScreenProps } from './presentation/screens/EditProfileScreen';
178
164
 
179
- export { ChangePasswordScreen } from './presentation/screens/change-password';
180
- export type { ChangePasswordScreenProps } from './presentation/screens/change-password';
181
-
182
165
  export { AuthNavigator } from './presentation/navigation/AuthNavigator';
183
166
  export type { AuthStackParamList } from './presentation/navigation/AuthNavigator';
184
167
 
185
168
  export { AuthBottomSheet } from './presentation/components/AuthBottomSheet';
169
+ export { ProfileSection } from './presentation/components/ProfileSection';
170
+ export type { ProfileSectionProps, ProfileSectionConfig } from './presentation/components/ProfileSection';
186
171
 
187
172
  // =============================================================================
188
173
  // STORES
189
174
  // =============================================================================
190
175
 
191
176
  export { useAuthStore } from './presentation/stores/authStore';
177
+ export { useAuthModalStore } from './presentation/stores/authModalStore';
192
178
  export {
193
179
  initializeAuthListener,
194
180
  resetAuthListener,
@@ -196,6 +182,7 @@ export {
196
182
  } from './presentation/stores/initializeAuthListener';
197
183
  export type { AuthState, AuthActions, UserType } from './types/auth-store.types';
198
184
  export type { AuthListenerOptions } from './types/auth-store.types';
185
+ export * from './presentation/stores/auth.selectors';
199
186
 
200
187
  // =============================================================================
201
188
  // UTILITIES
@@ -164,10 +164,14 @@ export class FirebaseAuthProvider implements IAuthProvider {
164
164
  }
165
165
 
166
166
  getCurrentUser(): AuthUser | null {
167
- if (!this.auth?.currentUser) {
167
+ if (!this.auth) {
168
+ return null;
169
+ }
170
+ const currentUser = this.auth.currentUser;
171
+ if (!currentUser) {
168
172
  return null;
169
173
  }
170
- return mapToAuthUser(this.auth.currentUser);
174
+ return mapToAuthUser(currentUser);
171
175
  }
172
176
 
173
177
  onAuthStateChange(callback: (user: AuthUser | null) => void): () => void {
@@ -7,7 +7,7 @@
7
7
  import type { IAuthRepository } from "../../application/ports/IAuthRepository";
8
8
  import type { IAuthProvider } from "../../application/ports/IAuthProvider";
9
9
  import type { AuthUser } from "../../domain/entities/AuthUser";
10
- import type { SignUpParams, SignInParams } from "../../application/ports/IAuthService";
10
+ import type { AuthCredentials, SignUpCredentials } from "../../application/ports/IAuthProvider";
11
11
  import {
12
12
  AuthValidationError,
13
13
  AuthWeakPasswordError,
@@ -31,7 +31,7 @@ export class AuthRepository implements IAuthRepository {
31
31
  this.config = config;
32
32
  }
33
33
 
34
- async signUp(params: SignUpParams): Promise<AuthUser> {
34
+ async signUp(params: SignUpCredentials): Promise<AuthUser> {
35
35
  const email = sanitizeEmail(params.email);
36
36
  const password = sanitizePassword(params.password);
37
37
  const displayName = params.displayName ? sanitizeName(params.displayName) : undefined;
@@ -64,7 +64,7 @@ export class AuthRepository implements IAuthRepository {
64
64
  return this.provider.signUp({ email, password, displayName });
65
65
  }
66
66
 
67
- async signIn(params: SignInParams): Promise<AuthUser> {
67
+ async signIn(params: AuthCredentials): Promise<AuthUser> {
68
68
  const email = sanitizeEmail(params.email);
69
69
  const password = sanitizePassword(params.password);
70
70
 
@@ -70,6 +70,10 @@ export class AuthEventService {
70
70
  const index = eventListeners.indexOf(listener);
71
71
  if (index > -1) {
72
72
  eventListeners.splice(index, 1);
73
+ // Clean up empty arrays to prevent memory leaks
74
+ if (eventListeners.length === 0) {
75
+ this.listeners.delete(event);
76
+ }
73
77
  }
74
78
  };
75
79
  }
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import type { Auth } from "firebase/auth";
7
- import type { IAuthService, SignUpParams, SignInParams } from "../../application/ports/IAuthService";
7
+ import type { AuthCredentials, SignUpCredentials } from "../../application/ports/IAuthProvider";
8
8
  import type { IAuthProvider } from "../../application/ports/IAuthProvider";
9
9
  import { FirebaseAuthProvider } from "../providers/FirebaseAuthProvider";
10
10
  import type { AuthUser } from "../../domain/entities/AuthUser";
@@ -13,10 +13,9 @@ import { sanitizeAuthConfig } from "../../domain/value-objects/AuthConfig";
13
13
  import { AuthRepository } from "../repositories/AuthRepository";
14
14
  import { AnonymousModeService } from "./AnonymousModeService";
15
15
  import { authEventService } from "./AuthEventService";
16
- import { authTracker } from "../utils/auth-tracker.util";
17
16
  import type { IStorageProvider } from "../types/Storage.types";
18
17
 
19
- export class AuthService implements IAuthService {
18
+ export class AuthService {
20
19
  private repository!: AuthRepository;
21
20
  private anonymousModeService: AnonymousModeService;
22
21
  private storageProvider?: IStorageProvider;
@@ -62,44 +61,23 @@ export class AuthService implements IAuthService {
62
61
  return this.initialized;
63
62
  }
64
63
 
65
- async signUp(params: SignUpParams): Promise<AuthUser> {
66
- authTracker.logOperationStarted("Sign up", { email: params.email });
67
- try {
68
- const user = await this.repositoryInstance.signUp(params);
69
- await this.clearAnonymousModeIfNeeded();
70
- authTracker.logOperationSuccess("Sign up", { userId: user.uid });
71
- authEventService.emitUserAuthenticated(user.uid);
72
- return user;
73
- } catch (error) {
74
- authTracker.logOperationError("Sign up", error, { email: params.email });
75
- throw error;
76
- }
64
+ async signUp(params: SignUpCredentials): Promise<AuthUser> {
65
+ const user = await this.repositoryInstance.signUp(params);
66
+ await this.clearAnonymousModeIfNeeded();
67
+ authEventService.emitUserAuthenticated(user.uid);
68
+ return user;
77
69
  }
78
70
 
79
- async signIn(params: SignInParams): Promise<AuthUser> {
80
- authTracker.logOperationStarted("Sign in", { email: params.email });
81
- try {
82
- const user = await this.repositoryInstance.signIn(params);
83
- await this.clearAnonymousModeIfNeeded();
84
- authTracker.logOperationSuccess("Sign in", { userId: user.uid });
85
- authEventService.emitUserAuthenticated(user.uid);
86
- return user;
87
- } catch (error) {
88
- authTracker.logOperationError("Sign in", error, { email: params.email });
89
- throw error;
90
- }
71
+ async signIn(params: AuthCredentials): Promise<AuthUser> {
72
+ const user = await this.repositoryInstance.signIn(params);
73
+ await this.clearAnonymousModeIfNeeded();
74
+ authEventService.emitUserAuthenticated(user.uid);
75
+ return user;
91
76
  }
92
77
 
93
78
  async signOut(): Promise<void> {
94
- authTracker.logOperationStarted("Sign out");
95
- try {
96
- await this.repositoryInstance.signOut();
97
- await this.clearAnonymousModeIfNeeded();
98
- authTracker.logOperationSuccess("Sign out");
99
- } catch (error) {
100
- authTracker.logOperationError("Sign out", error);
101
- throw error;
102
- }
79
+ await this.repositoryInstance.signOut();
80
+ await this.clearAnonymousModeIfNeeded();
103
81
  }
104
82
 
105
83
  private async clearAnonymousModeIfNeeded(): Promise<void> {
@@ -6,9 +6,6 @@
6
6
  import type { Auth, User } from "firebase/auth";
7
7
  import { getFirebaseAuth } from "@umituz/react-native-firebase";
8
8
  import { initializeAuthService } from "./AuthService";
9
- import { configureUserDocumentService } from "./UserDocumentService";
10
- import type { UserDocumentExtras } from "./UserDocumentService";
11
- import { collectDeviceExtras } from "@umituz/react-native-design-system";
12
9
  import { initializeAuthListener } from "../../presentation/stores/initializeAuthListener";
13
10
  import { createAuthStateHandler } from "../utils/authStateHandler";
14
11
  import type { ConversionState } from "../utils/authConversionDetector";
@@ -16,9 +13,6 @@ import type { AuthConfig } from "../../domain/value-objects/AuthConfig";
16
13
  import type { IStorageProvider } from "../types/Storage.types";
17
14
 
18
15
  export interface InitializeAuthOptions {
19
- userCollection?: string;
20
- extraFields?: Record<string, unknown>;
21
- collectExtras?: () => Promise<UserDocumentExtras>;
22
16
  storageProvider?: IStorageProvider;
23
17
  autoAnonymousSignIn?: boolean;
24
18
  onUserConverted?: (anonymousId: string, authenticatedId: string) => void | Promise<void>;
@@ -58,9 +52,6 @@ async function doInitializeAuth(
58
52
  ): Promise<{ success: boolean; auth: Auth | null }> {
59
53
 
60
54
  const {
61
- userCollection = "users",
62
- extraFields,
63
- collectExtras,
64
55
  storageProvider,
65
56
  autoAnonymousSignIn = true,
66
57
  onUserConverted,
@@ -71,12 +62,6 @@ async function doInitializeAuth(
71
62
  const auth = getFirebaseAuth();
72
63
  if (!auth) return { success: false, auth: null };
73
64
 
74
- configureUserDocumentService({
75
- collectionName: userCollection,
76
- extraFields,
77
- collectExtras: collectExtras || collectDeviceExtras,
78
- });
79
-
80
65
  let authServiceInitFailed = false;
81
66
  try {
82
67
  await initializeAuthService(auth, authConfig, storageProvider);
@@ -1,7 +1,10 @@
1
1
  import type { PasswordConfig } from "../../domain/value-objects/AuthConfig";
2
- import type { ValidationResult } from "./validation/types";
3
2
 
4
- export type { ValidationResult };
3
+ export interface ValidationResult {
4
+ isValid: boolean;
5
+ error?: string;
6
+ }
7
+
5
8
  export interface PasswordStrengthResult extends ValidationResult { requirements: PasswordRequirements; }
6
9
  export interface PasswordRequirements {
7
10
  hasMinLength: boolean;
@@ -32,14 +32,17 @@ export function extractProvider(user: FirebaseUserLike): AuthProviderType {
32
32
  return "unknown";
33
33
  }
34
34
 
35
- const googleProvider = providerData.find((p) => p?.providerId === "google.com");
36
- if (googleProvider) return "google.com";
35
+ // Filter out null providers and find the first valid one
36
+ const validProviders = providerData.filter((p): p is ProviderData => p != null);
37
37
 
38
- const appleProvider = providerData.find((p) => p?.providerId === "apple.com");
39
- if (appleProvider) return "apple.com";
38
+ const googleProvider = validProviders.find((p) => p.providerId === "google.com");
39
+ if (googleProvider && googleProvider.providerId) return "google.com";
40
40
 
41
- const passwordProvider = providerData.find((p) => p?.providerId === "password");
42
- if (passwordProvider) return "password";
41
+ const appleProvider = validProviders.find((p) => p.providerId === "apple.com");
42
+ if (appleProvider && appleProvider.providerId) return "apple.com";
43
+
44
+ const passwordProvider = validProviders.find((p) => p.providerId === "password");
45
+ if (passwordProvider && passwordProvider.providerId) return "password";
43
46
 
44
47
  return "unknown";
45
48
  }
@@ -4,7 +4,6 @@
4
4
  */
5
5
 
6
6
  import type { User } from "firebase/auth";
7
- import { ensureUserDocument } from "../services/UserDocumentService";
8
7
  import { detectConversion, type ConversionState } from "./authConversionDetector";
9
8
 
10
9
  export interface AuthStateHandlerOptions {
@@ -43,12 +42,6 @@ export function createAuthStateHandler(
43
42
  }
44
43
  }
45
44
 
46
- const extras = conversion.isConversion && state.current.previousUserId
47
- ? { previousAnonymousUserId: state.current.previousUserId }
48
- : undefined;
49
-
50
- await ensureUserDocument(user, extras);
51
-
52
45
  state.current = {
53
46
  previousUserId: currentUserId,
54
47
  wasAnonymous: isCurrentlyAnonymous,
@@ -1,141 +1,54 @@
1
1
  /**
2
2
  * Sanitization Utilities
3
3
  * Secure input cleaning for user data
4
- *
5
- * @module Sanitization
6
- * @description Provides input sanitization functions to prevent XSS attacks,
7
- * injection attacks, and ensure data integrity. All user inputs should be
8
- * sanitized before storage or processing.
9
- *
10
- * Security Limits:
11
- * These constants define maximum lengths for various input fields to prevent
12
- * DoS attacks and ensure database integrity. They are based on industry standards:
13
- *
14
- * - EMAIL_MAX_LENGTH: 254 (RFC 5321 - maximum email address length)
15
- * - PASSWORD_MAX_LENGTH: 128 (NIST recommendations)
16
- * - NAME_MAX_LENGTH: 100 (Reasonable limit for display names)
17
- * - GENERAL_TEXT_MAX_LENGTH: 500 (Prevents abuse of text fields)
18
- *
19
- * @note These limits are currently hardcoded for security. If you need to
20
- * customize them for your application, you can:
21
- * 1. Create your own sanitization functions with custom limits
22
- * 2. Use the helper functions like `isWithinLengthLimit()` for validation
23
- * 3. Submit a PR to make these limits configurable via AuthConfig
24
4
  */
25
5
 
26
- /**
27
- * Security constants for input validation
28
- *
29
- * @constant
30
- * @type {readonly [key: string]: number}
31
- *
32
- * @property {number} EMAIL_MAX_LENGTH - Maximum email length per RFC 5321
33
- * @property {number} PASSWORD_MIN_LENGTH - Minimum password length (configurable via AuthConfig)
34
- * @property {number} PASSWORD_MAX_LENGTH - Maximum password length to prevent DoS
35
- * @property {number} NAME_MAX_LENGTH - Maximum display name length
36
- * @property {number} GENERAL_TEXT_MAX_LENGTH - Maximum general text input length
37
- */
38
6
  export const SECURITY_LIMITS = {
39
- EMAIL_MAX_LENGTH: 254, // RFC 5321
7
+ EMAIL_MAX_LENGTH: 254,
40
8
  PASSWORD_MIN_LENGTH: 6,
41
9
  PASSWORD_MAX_LENGTH: 128,
42
10
  NAME_MAX_LENGTH: 100,
43
11
  GENERAL_TEXT_MAX_LENGTH: 500,
44
12
  } as const;
45
13
 
46
- /**
47
- * Type for security limit keys
48
- */
49
14
  export type SecurityLimitKey = keyof typeof SECURITY_LIMITS;
50
15
 
51
- /**
52
- * Get a specific security limit value
53
- * @param key - The security limit key
54
- * @returns The security limit value
55
- * @example
56
- * ```ts
57
- * const maxEmailLength = getSecurityLimit('EMAIL_MAX_LENGTH'); // 254
58
- * ```
59
- */
60
- export function getSecurityLimit(key: SecurityLimitKey): number {
61
- return SECURITY_LIMITS[key];
62
- }
63
-
64
- /**
65
- * Trim and normalize whitespace
66
- */
67
16
  export const sanitizeWhitespace = (input: string): string => {
68
17
  return input.trim().replace(/\s+/g, ' ');
69
18
  };
70
19
 
71
- /**
72
- * Sanitize email address
73
- * - Trim whitespace
74
- * - Convert to lowercase
75
- * - Limit length
76
- */
77
20
  export const sanitizeEmail = (email: string): string => {
78
21
  const trimmed = email.trim().toLowerCase();
79
22
  return trimmed.substring(0, SECURITY_LIMITS.EMAIL_MAX_LENGTH);
80
23
  };
81
24
 
82
- /**
83
- * Sanitize password
84
- * - Trim leading/trailing whitespace to prevent login issues
85
- * - Preserve case and special chars
86
- * - Limit length to prevent DoS
87
- */
88
25
  export const sanitizePassword = (password: string): string => {
89
- // Trim leading/trailing spaces to prevent authentication issues
90
- // Internal spaces are preserved for special use cases
91
26
  return password.trim().substring(0, SECURITY_LIMITS.PASSWORD_MAX_LENGTH);
92
27
  };
93
28
 
94
- /**
95
- * Sanitize display name
96
- * - Trim whitespace
97
- * - Normalize multiple spaces
98
- * - Remove potential XSS characters
99
- * - Limit length
100
- */
101
29
  export const sanitizeName = (name: string): string => {
102
30
  const trimmed = sanitizeWhitespace(name);
103
- // Remove HTML tags and script content
104
31
  const noTags = trimmed.replace(/<[^>]*>/g, '');
105
32
  return noTags.substring(0, SECURITY_LIMITS.NAME_MAX_LENGTH);
106
33
  };
107
34
 
108
- /**
109
- * Sanitize general text input
110
- * - Trim whitespace
111
- * - Remove HTML/script tags
112
- * - Limit length
113
- */
114
35
  export const sanitizeText = (text: string): string => {
115
36
  const trimmed = sanitizeWhitespace(text);
116
37
  const noTags = trimmed.replace(/<[^>]*>/g, '');
117
38
  return noTags.substring(0, SECURITY_LIMITS.GENERAL_TEXT_MAX_LENGTH);
118
39
  };
119
40
 
120
- /**
121
- * Check if string contains potentially dangerous characters
122
- */
123
41
  export const containsDangerousChars = (input: string): boolean => {
124
- // Check for common XSS patterns
125
42
  const dangerousPatterns = [
126
43
  /<script/i,
127
44
  /javascript:/i,
128
- /on\w+\s*=/i, // onclick, onload, etc.
45
+ /on\w+\s*=/i,
129
46
  /<iframe/i,
130
47
  /eval\(/i,
131
48
  ];
132
-
133
49
  return dangerousPatterns.some(pattern => pattern.test(input));
134
50
  };
135
51
 
136
- /**
137
- * Validate string length is within bounds
138
- */
139
52
  export const isWithinLengthLimit = (
140
53
  input: string,
141
54
  maxLength: number,
@@ -8,23 +8,12 @@ import { initializeAuth } from '../infrastructure/services/initializeAuth';
8
8
  import type { InitializeAuthOptions } from '../infrastructure/services/initializeAuth';
9
9
 
10
10
  export interface AuthInitModuleConfig {
11
- /**
12
- * Firestore collection name for user documents
13
- * @default "users"
14
- */
15
- userCollection?: string;
16
-
17
11
  /**
18
12
  * Whether to auto sign-in as anonymous user
19
13
  * @default true
20
14
  */
21
15
  autoAnonymousSignIn?: boolean;
22
16
 
23
- /**
24
- * Function to collect device extras for user document
25
- */
26
- collectExtras?: InitializeAuthOptions['collectExtras'];
27
-
28
17
  /**
29
18
  * Storage provider for auth persistence
30
19
  */
@@ -80,9 +69,7 @@ export function createAuthInitModule(
80
69
  config: AuthInitModuleConfig = {}
81
70
  ): InitModule {
82
71
  const {
83
- userCollection = 'users',
84
72
  autoAnonymousSignIn = true,
85
- collectExtras,
86
73
  storageProvider,
87
74
  onRestorePurchases,
88
75
  onUserConverted,
@@ -97,9 +84,7 @@ export function createAuthInitModule(
97
84
  init: async () => {
98
85
  try {
99
86
  await initializeAuth({
100
- userCollection,
101
87
  autoAnonymousSignIn,
102
- collectExtras,
103
88
  storageProvider,
104
89
  onUserConverted: async (anonymousId: string, authenticatedId: string) => {
105
90
  if (__DEV__) {
@@ -5,12 +5,12 @@
5
5
 
6
6
  import { useMutation } from "@umituz/react-native-design-system";
7
7
  import { getAuthService } from "../../../infrastructure/services/AuthService";
8
- import type { SignUpParams, SignInParams } from "../../../application/ports/IAuthService";
8
+ import type { AuthCredentials, SignUpCredentials } from "../../../application/ports/IAuthProvider";
9
9
  import type { AuthUser } from "../../../domain/entities/AuthUser";
10
10
 
11
11
  export const useSignUpMutation = () => {
12
12
  return useMutation({
13
- mutationFn: async (params: SignUpParams): Promise<AuthUser> => {
13
+ mutationFn: async (params: SignUpCredentials): Promise<AuthUser> => {
14
14
  const service = getAuthService();
15
15
  if (!service) throw new Error("Auth Service not initialized");
16
16
  return service.signUp(params);
@@ -20,7 +20,7 @@ export const useSignUpMutation = () => {
20
20
 
21
21
  export const useSignInMutation = () => {
22
22
  return useMutation({
23
- mutationFn: async (params: SignInParams): Promise<AuthUser> => {
23
+ mutationFn: async (params: AuthCredentials): Promise<AuthUser> => {
24
24
  const service = getAuthService();
25
25
  if (!service) throw new Error("Auth Service not initialized");
26
26
  return service.signIn(params);
@@ -103,6 +103,8 @@ export function useAuthBottomSheet(params: UseAuthBottomSheetParams = {}) {
103
103
  });
104
104
  }
105
105
 
106
+ let timeoutId: NodeJS.Timeout | undefined;
107
+
106
108
  if ((justAuthenticated || justConvertedFromAnonymous) && isVisible && !isAnonymous) {
107
109
  if (__DEV__) {
108
110
  console.log("[useAuthBottomSheet] Auto-closing due to successful authentication transition", {
@@ -116,7 +118,7 @@ export function useAuthBottomSheet(params: UseAuthBottomSheetParams = {}) {
116
118
  // Notify auth success
117
119
  onAuthSuccess?.();
118
120
  // Execute callback with delay to ensure auth state has propagated
119
- setTimeout(() => {
121
+ timeoutId = setTimeout(() => {
120
122
  if (__DEV__) {
121
123
  console.log("[useAuthBottomSheet] Executing pending callback after auth");
122
124
  }
@@ -127,6 +129,13 @@ export function useAuthBottomSheet(params: UseAuthBottomSheetParams = {}) {
127
129
  prevIsAuthenticatedRef.current = isAuthenticated;
128
130
  prevIsVisibleRef.current = isVisible;
129
131
  prevIsAnonymousRef.current = isAnonymous;
132
+
133
+ // Cleanup timeout on unmount or dependency change
134
+ return () => {
135
+ if (timeoutId) {
136
+ clearTimeout(timeoutId);
137
+ }
138
+ };
130
139
  }, [isAuthenticated, isVisible, isAnonymous, executePendingCallback, hideAuthModal, onAuthSuccess]);
131
140
 
132
141
  const handleNavigateToRegister = useCallback(() => {