@umituz/react-native-auth 1.5.1 → 1.6.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/package.json +1 -1
- package/src/domain/value-objects/AuthConfig.ts +1 -15
- package/src/index.ts +9 -0
- package/src/infrastructure/services/AuthService.ts +19 -37
- package/src/presentation/components/AuthContainer.tsx +5 -0
- package/src/presentation/components/AuthDivider.tsx +5 -0
- package/src/presentation/components/AuthErrorDisplay.tsx +5 -0
- package/src/presentation/components/AuthFormCard.tsx +5 -0
- package/src/presentation/components/AuthGradientBackground.tsx +5 -0
- package/src/presentation/components/AuthHeader.tsx +5 -0
- package/src/presentation/components/AuthLegalLinks.tsx +6 -1
- package/src/presentation/components/AuthLink.tsx +6 -1
- package/src/presentation/components/LoginForm.tsx +1 -1
- package/src/presentation/components/RegisterForm.tsx +1 -1
- package/src/presentation/hooks/useAuth.ts +14 -0
- package/src/presentation/utils/getAuthErrorMessage.ts +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-auth",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Authentication service for React Native apps - Secure, type-safe, and production-ready. Provider-agnostic design supports Firebase Auth and can be adapted for Supabase or other providers.",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -14,23 +14,9 @@ export interface AuthConfig {
|
|
|
14
14
|
requireNumbers?: boolean;
|
|
15
15
|
/** Require special characters in password */
|
|
16
16
|
requireSpecialChars?: boolean;
|
|
17
|
-
/** Callback for user profile creation after signup */
|
|
18
|
-
onUserCreated?: (user: any) => Promise<void> | void;
|
|
19
|
-
/** Callback for user profile update */
|
|
20
|
-
onUserUpdated?: (user: any) => Promise<void> | void;
|
|
21
|
-
/** Callback for sign out cleanup */
|
|
22
|
-
onSignOut?: () => Promise<void> | void;
|
|
23
|
-
/** Callback for analytics logging on sign in */
|
|
24
|
-
onSignIn?: (method: string) => Promise<void> | void;
|
|
25
|
-
/** Callback for analytics logging on guest mode */
|
|
26
|
-
onGuestModeEnabled?: () => Promise<void> | void;
|
|
27
|
-
/** Callback for analytics initialization when user authenticates */
|
|
28
|
-
onAnalyticsInit?: (userId: string) => Promise<void> | void;
|
|
29
|
-
/** Callback for analytics initialization when guest mode enabled */
|
|
30
|
-
onAnalyticsInitGuest?: () => Promise<void> | void;
|
|
31
17
|
}
|
|
32
18
|
|
|
33
|
-
export const DEFAULT_AUTH_CONFIG: Required<
|
|
19
|
+
export const DEFAULT_AUTH_CONFIG: Required<AuthConfig> = {
|
|
34
20
|
minPasswordLength: 6,
|
|
35
21
|
requireUppercase: false,
|
|
36
22
|
requireLowercase: false,
|
package/src/index.ts
CHANGED
|
@@ -71,6 +71,15 @@ export type {
|
|
|
71
71
|
AuthStackParamList,
|
|
72
72
|
AuthNavigatorProps,
|
|
73
73
|
} from './presentation/navigation/AuthNavigator';
|
|
74
|
+
|
|
75
|
+
// PRESENTATION LAYER - Components
|
|
76
|
+
// =============================================================================
|
|
77
|
+
|
|
78
|
+
export { AuthContainer } from './presentation/components/AuthContainer';
|
|
79
|
+
export { AuthHeader } from './presentation/components/AuthHeader';
|
|
80
|
+
export { AuthFormCard } from './presentation/components/AuthFormCard';
|
|
81
|
+
export { LoginForm } from './presentation/components/LoginForm';
|
|
82
|
+
export { RegisterForm } from './presentation/components/RegisterForm';
|
|
74
83
|
export { AuthLegalLinks } from './presentation/components/AuthLegalLinks';
|
|
75
84
|
export type { AuthLegalLinksProps } from './presentation/components/AuthLegalLinks';
|
|
76
85
|
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
} from "../../domain/errors/AuthError";
|
|
28
28
|
import type { AuthConfig } from "../../domain/value-objects/AuthConfig";
|
|
29
29
|
import { DEFAULT_AUTH_CONFIG } from "../../domain/value-objects/AuthConfig";
|
|
30
|
+
import { DeviceEventEmitter } from "react-native";
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* Validate email format
|
|
@@ -203,15 +204,8 @@ export class AuthService implements IAuthService {
|
|
|
203
204
|
}
|
|
204
205
|
}
|
|
205
206
|
|
|
206
|
-
//
|
|
207
|
-
|
|
208
|
-
if (this.config.onUserCreated) {
|
|
209
|
-
try {
|
|
210
|
-
await this.config.onUserCreated(userCredential.user);
|
|
211
|
-
} catch (callbackError) {
|
|
212
|
-
// Don't fail signup if callback fails
|
|
213
|
-
}
|
|
214
|
-
}
|
|
207
|
+
// Emit event for AppNavigator to handle navigation
|
|
208
|
+
DeviceEventEmitter.emit("user-authenticated", { userId: userCredential.user.uid });
|
|
215
209
|
|
|
216
210
|
return userCredential.user;
|
|
217
211
|
} catch (error: any) {
|
|
@@ -247,15 +241,8 @@ export class AuthService implements IAuthService {
|
|
|
247
241
|
|
|
248
242
|
this.isGuestMode = false;
|
|
249
243
|
|
|
250
|
-
//
|
|
251
|
-
|
|
252
|
-
if (this.config.onSignIn) {
|
|
253
|
-
try {
|
|
254
|
-
await this.config.onSignIn("email");
|
|
255
|
-
} catch (callbackError) {
|
|
256
|
-
// Don't fail signin if analytics callback fails
|
|
257
|
-
}
|
|
258
|
-
}
|
|
244
|
+
// Emit event for AppNavigator to handle navigation
|
|
245
|
+
DeviceEventEmitter.emit("user-authenticated", { userId: userCredential.user.uid });
|
|
259
246
|
|
|
260
247
|
return userCredential.user;
|
|
261
248
|
} catch (error: any) {
|
|
@@ -278,15 +265,6 @@ export class AuthService implements IAuthService {
|
|
|
278
265
|
await firebaseSignOut(auth);
|
|
279
266
|
this.isGuestMode = false;
|
|
280
267
|
|
|
281
|
-
// Call sign out callback if provided
|
|
282
|
-
// User state is managed by Firebase Auth's onAuthStateChanged
|
|
283
|
-
if (this.config.onSignOut) {
|
|
284
|
-
try {
|
|
285
|
-
await this.config.onSignOut();
|
|
286
|
-
} catch (callbackError) {
|
|
287
|
-
// Don't fail signout if callback fails
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
268
|
} catch (error: any) {
|
|
291
269
|
throw mapFirebaseAuthError(error);
|
|
292
270
|
}
|
|
@@ -309,15 +287,6 @@ export class AuthService implements IAuthService {
|
|
|
309
287
|
|
|
310
288
|
this.isGuestMode = true;
|
|
311
289
|
|
|
312
|
-
// Call analytics callback if provided
|
|
313
|
-
// Guest mode state is managed by useAuth hook
|
|
314
|
-
if (this.config.onGuestModeEnabled) {
|
|
315
|
-
try {
|
|
316
|
-
await this.config.onGuestModeEnabled();
|
|
317
|
-
} catch (callbackError) {
|
|
318
|
-
// Don't fail guest mode if analytics callback fails
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
290
|
}
|
|
322
291
|
|
|
323
292
|
/**
|
|
@@ -368,13 +337,26 @@ let authServiceInstance: AuthService | null = null;
|
|
|
368
337
|
/**
|
|
369
338
|
* Initialize auth service with Firebase Auth instance
|
|
370
339
|
* Must be called before using any auth methods
|
|
340
|
+
*
|
|
341
|
+
* Uses DEFAULT_AUTH_CONFIG if no config is provided:
|
|
342
|
+
* - minPasswordLength: 6
|
|
343
|
+
* - requireUppercase: false
|
|
344
|
+
* - requireLowercase: false
|
|
345
|
+
* - requireNumbers: false
|
|
346
|
+
* - requireSpecialChars: false
|
|
347
|
+
*
|
|
348
|
+
* @param auth - Firebase Auth instance
|
|
349
|
+
* @param config - Optional auth configuration (defaults to permissive settings)
|
|
371
350
|
*/
|
|
372
351
|
export function initializeAuthService(
|
|
373
352
|
auth: Auth,
|
|
374
353
|
config?: AuthConfig
|
|
375
354
|
): AuthService {
|
|
355
|
+
// Use default config if not provided (permissive settings for better UX)
|
|
356
|
+
const finalConfig = config || DEFAULT_AUTH_CONFIG;
|
|
357
|
+
|
|
376
358
|
if (!authServiceInstance) {
|
|
377
|
-
authServiceInstance = new AuthService(
|
|
359
|
+
authServiceInstance = new AuthService(finalConfig);
|
|
378
360
|
}
|
|
379
361
|
authServiceInstance.initialize(auth);
|
|
380
362
|
return authServiceInstance;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import React from "react";
|
|
7
7
|
import { View, StyleSheet, Linking } from "react-native";
|
|
8
|
-
import { AtomicButton, AtomicText } from "@umituz/react-native-design-system";
|
|
8
|
+
import { AtomicButton, AtomicText } from "@umituz/react-native-design-system-atoms";
|
|
9
9
|
import { useAppDesignTokens } from "@umituz/react-native-design-system-theme";
|
|
10
10
|
import { useLocalization } from "@umituz/react-native-localization";
|
|
11
11
|
|
|
@@ -138,3 +138,8 @@ const styles = StyleSheet.create({
|
|
|
138
138
|
|
|
139
139
|
|
|
140
140
|
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import React from "react";
|
|
7
7
|
import { View, Text, StyleSheet } from "react-native";
|
|
8
|
-
import { AtomicButton } from "@umituz/react-native-design-system";
|
|
8
|
+
import { AtomicButton } from "@umituz/react-native-design-system-atoms";
|
|
9
9
|
import { useAppDesignTokens } from "@umituz/react-native-design-system-theme";
|
|
10
10
|
|
|
11
11
|
interface AuthLinkProps {
|
|
@@ -67,3 +67,8 @@ const styles = StyleSheet.create({
|
|
|
67
67
|
|
|
68
68
|
|
|
69
69
|
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import React, { useState } from "react";
|
|
7
7
|
import { View, StyleSheet } from "react-native";
|
|
8
|
-
import { AtomicInput, AtomicButton } from "@umituz/react-native-design-system";
|
|
8
|
+
import { AtomicInput, AtomicButton } from "@umituz/react-native-design-system-atoms";
|
|
9
9
|
import { useLocalization } from "@umituz/react-native-localization";
|
|
10
10
|
import { useAuth } from "../hooks/useAuth";
|
|
11
11
|
import { AuthErrorDisplay } from "./AuthErrorDisplay";
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import React, { useState } from "react";
|
|
7
7
|
import { View, StyleSheet } from "react-native";
|
|
8
|
-
import { AtomicInput, AtomicButton } from "@umituz/react-native-design-system";
|
|
8
|
+
import { AtomicInput, AtomicButton } from "@umituz/react-native-design-system-atoms";
|
|
9
9
|
import { useLocalization } from "@umituz/react-native-localization";
|
|
10
10
|
import {
|
|
11
11
|
validateEmail,
|
|
@@ -61,6 +61,19 @@ export function useAuth(): UseAuthResult {
|
|
|
61
61
|
const user = isGuest ? null : firebaseUser;
|
|
62
62
|
const isAuthenticated = !!user && !isGuest;
|
|
63
63
|
|
|
64
|
+
// Update authStatus whenever authentication state changes
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (firebaseLoading || loading) {
|
|
67
|
+
// setAuthStatus('loading'); // This line is removed
|
|
68
|
+
} else if (isAuthenticated) {
|
|
69
|
+
// setAuthStatus('authenticated'); // This line is removed
|
|
70
|
+
} else if (isGuest) {
|
|
71
|
+
// setAuthStatus('guest'); // This line is removed
|
|
72
|
+
} else {
|
|
73
|
+
// setAuthStatus('unauthenticated'); // This line is removed
|
|
74
|
+
}
|
|
75
|
+
}, [isAuthenticated, isGuest, firebaseLoading, loading]);
|
|
76
|
+
|
|
64
77
|
// Handle analytics initialization (if callbacks are provided in config)
|
|
65
78
|
useEffect(() => {
|
|
66
79
|
const authChanged =
|
|
@@ -161,6 +174,7 @@ export function useAuth(): UseAuthResult {
|
|
|
161
174
|
loading: loading || firebaseLoading,
|
|
162
175
|
isGuest,
|
|
163
176
|
isAuthenticated,
|
|
177
|
+
// authStatus, // This line is removed
|
|
164
178
|
error,
|
|
165
179
|
signUp,
|
|
166
180
|
signIn,
|