@umituz/react-native-auth 3.4.30 β 3.4.32
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/README.md +426 -0
- package/package.json +1 -3
- package/src/application/README.md +513 -0
- package/src/domain/ConfigAndErrors.md +545 -0
- package/src/domain/README.md +293 -0
- package/src/domain/entities/AuthUser.md +377 -0
- package/src/domain/entities/UserProfile.md +443 -0
- package/src/infrastructure/README.md +576 -0
- package/src/infrastructure/services/README.md +417 -0
- package/src/presentation/README.md +770 -0
- package/src/presentation/components/AuthBackground.tsx +21 -0
- package/src/presentation/components/AuthContainer.tsx +3 -3
- package/src/presentation/components/LoginForm.md +222 -0
- package/src/presentation/components/PasswordIndicators.md +260 -0
- package/src/presentation/components/ProfileComponents.md +575 -0
- package/src/presentation/components/README.md +117 -0
- package/src/presentation/components/SocialLoginButtons.md +340 -0
- package/src/presentation/hooks/README.md +122 -0
- package/src/presentation/hooks/useAccountManagement.md +386 -0
- package/src/presentation/hooks/useAuth.md +255 -0
- package/src/presentation/hooks/useAuthBottomSheet.md +414 -0
- package/src/presentation/hooks/useAuthRequired.md +248 -0
- package/src/presentation/hooks/useProfileUpdate.md +327 -0
- package/src/presentation/hooks/useSocialLogin.md +356 -0
- package/src/presentation/hooks/useUserProfile.md +230 -0
- package/src/presentation/screens/README.md +198 -0
- package/src/presentation/components/AuthGradientBackground.tsx +0 -33
package/README.md
ADDED
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
# @umituz/react-native-auth
|
|
2
|
+
|
|
3
|
+
> Authentication service for React Native apps - Secure, type-safe, and production-ready. Provider-agnostic design with dependency injection, configurable validation, and comprehensive error handling.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@umituz/react-native-auth)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- π **Multiple Auth Methods** - Email/Password, Google, Apple, Anonymous
|
|
11
|
+
- π― **Type-Safe** - Written in TypeScript with full type definitions
|
|
12
|
+
- ποΈ **DDD Architecture** - Domain-Driven Design with clean separation of concerns
|
|
13
|
+
- π **Provider Agnostic** - Easy to swap auth providers (Firebase, custom backend, etc.)
|
|
14
|
+
- β‘ **React Hooks** - Simple and intuitive React hooks for auth operations
|
|
15
|
+
- π¨ **UI Components** - Pre-built authentication screens and components
|
|
16
|
+
- π± **React Native Ready** - Optimized for iOS and Android
|
|
17
|
+
- π **Secure** - Built-in validation and error handling
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @umituz/react-native-auth
|
|
23
|
+
# or
|
|
24
|
+
yarn add @umituz/react-native-auth
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Peer Dependencies
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"firebase": ">=11.0.0",
|
|
32
|
+
"react": ">=18.2.0",
|
|
33
|
+
"react-native": ">=0.74.0",
|
|
34
|
+
"@tanstack/react-query": ">=5.0.0",
|
|
35
|
+
"zustand": ">=4.0.0"
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
### 1. Initialize Auth
|
|
42
|
+
|
|
43
|
+
Wrap your app with `AuthProvider` and initialize auth:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import React, { useEffect } from 'react';
|
|
47
|
+
import { AuthProvider, initializeAuth } from '@umituz/react-native-auth';
|
|
48
|
+
import { getAuth } from 'firebase/auth';
|
|
49
|
+
import { NavigationContainer } from '@react-navigation/native';
|
|
50
|
+
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
|
51
|
+
|
|
52
|
+
// Initialize auth (call once in app root)
|
|
53
|
+
initializeAuth({
|
|
54
|
+
onAuthStateChanged: (user) => {
|
|
55
|
+
console.log('Auth state changed:', user);
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
function App() {
|
|
60
|
+
return (
|
|
61
|
+
<AuthProvider>
|
|
62
|
+
<NavigationContainer>
|
|
63
|
+
<Stack.Navigator>
|
|
64
|
+
<Stack.Screen name="Login" component={LoginScreen} />
|
|
65
|
+
<Stack.Screen name="Home" component={HomeScreen} />
|
|
66
|
+
</Stack.Navigator>
|
|
67
|
+
</NavigationContainer>
|
|
68
|
+
</AuthProvider>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 2. Use Auth Hook
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { useAuth } from '@umituz/react-native-auth';
|
|
77
|
+
import { View, Text, Button } from 'react-native';
|
|
78
|
+
|
|
79
|
+
function LoginScreen() {
|
|
80
|
+
const { signIn, loading, error } = useAuth();
|
|
81
|
+
|
|
82
|
+
const handleLogin = async () => {
|
|
83
|
+
try {
|
|
84
|
+
await signIn('user@example.com', 'password123');
|
|
85
|
+
// Navigate to home
|
|
86
|
+
} catch (err) {
|
|
87
|
+
// Error is automatically set in error state
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<View>
|
|
93
|
+
<Button onPress={handleLogin} disabled={loading}>
|
|
94
|
+
{loading ? 'Signing in...' : 'Sign In'}
|
|
95
|
+
</Button>
|
|
96
|
+
{error && <Text>{error}</Text>}
|
|
97
|
+
</View>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 3. Protect Routes
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import { useAuthRequired } from '@umituz/react-native-auth';
|
|
106
|
+
|
|
107
|
+
function ProtectedComponent() {
|
|
108
|
+
const { isAllowed, checkAndRequireAuth } = useAuthRequired();
|
|
109
|
+
|
|
110
|
+
const handleAction = () => {
|
|
111
|
+
if (checkAndRequireAuth()) {
|
|
112
|
+
// User is authenticated, proceed with action
|
|
113
|
+
console.log('Action performed');
|
|
114
|
+
}
|
|
115
|
+
// If not authenticated, auth modal is shown automatically
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<Button onPress={handleAction}>
|
|
120
|
+
{isAllowed ? 'Perform Action' : 'Sign In to Continue'}
|
|
121
|
+
</Button>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Social Login
|
|
127
|
+
|
|
128
|
+
### Google Sign-In
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
import { useGoogleAuth } from '@umituz/react-native-auth';
|
|
132
|
+
|
|
133
|
+
function GoogleLoginButton() {
|
|
134
|
+
const { signInWithGoogle, googleLoading } = useGoogleAuth({
|
|
135
|
+
iosClientId: 'your-ios-client-id.apps.googleusercontent.com',
|
|
136
|
+
webClientId: 'your-web-client-id.apps.googleusercontent.com',
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
return (
|
|
140
|
+
<Button onPress={signInWithGoogle} disabled={googleLoading}>
|
|
141
|
+
Sign in with Google
|
|
142
|
+
</Button>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Apple Sign-In
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import { useAppleAuth } from '@umituz/react-native-auth';
|
|
151
|
+
|
|
152
|
+
function AppleLoginButton() {
|
|
153
|
+
const { signInWithApple, appleLoading, appleAvailable } = useAppleAuth();
|
|
154
|
+
|
|
155
|
+
if (!appleAvailable) return null;
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<Button onPress={signInWithApple} disabled={appleLoading}>
|
|
159
|
+
Sign in with Apple
|
|
160
|
+
</Button>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Pre-built Screens
|
|
166
|
+
|
|
167
|
+
Use pre-built authentication screens:
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { LoginScreen, RegisterScreen, AccountScreen } from '@umituz/react-native-auth';
|
|
171
|
+
|
|
172
|
+
<Stack.Screen
|
|
173
|
+
name="Login"
|
|
174
|
+
component={LoginScreen}
|
|
175
|
+
options={{ headerShown: false }}
|
|
176
|
+
/>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## User Profile
|
|
180
|
+
|
|
181
|
+
### Display Profile
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import { useUserProfile } from '@umituz/react-native-auth';
|
|
185
|
+
|
|
186
|
+
function ProfileHeader() {
|
|
187
|
+
const profile = useUserProfile({
|
|
188
|
+
accountRoute: '/account',
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
if (!profile) return <LoadingSpinner />;
|
|
192
|
+
|
|
193
|
+
return (
|
|
194
|
+
<View>
|
|
195
|
+
<Avatar source={{ uri: profile.avatarUrl }} />
|
|
196
|
+
<Text>{profile.displayName}</Text>
|
|
197
|
+
{profile.isAnonymous && <Badge>Guest</Badge>}
|
|
198
|
+
</View>
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Update Profile
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
import { useProfileUpdate } from '@umituz/react-native-auth';
|
|
207
|
+
|
|
208
|
+
function EditProfileScreen() {
|
|
209
|
+
const { updateProfile, isUpdating } = useProfileUpdate();
|
|
210
|
+
|
|
211
|
+
const handleSave = async (data) => {
|
|
212
|
+
try {
|
|
213
|
+
await updateProfile({
|
|
214
|
+
displayName: data.name,
|
|
215
|
+
photoURL: data.avatarUrl,
|
|
216
|
+
});
|
|
217
|
+
} catch (error) {
|
|
218
|
+
Alert.alert('Error', 'Failed to update profile');
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
return <ProfileForm onSave={handleSave} loading={isUpdating} />;
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Account Management
|
|
227
|
+
|
|
228
|
+
### Delete Account
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
import { useAccountManagement } from '@umituz/react-native-auth';
|
|
232
|
+
|
|
233
|
+
function AccountSettings() {
|
|
234
|
+
const { deleteAccount, logout } = useAccountManagement({
|
|
235
|
+
onReauthRequired: async () => {
|
|
236
|
+
// Show re-authentication UI
|
|
237
|
+
const result = await showReauthDialog();
|
|
238
|
+
return result.success;
|
|
239
|
+
},
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
return (
|
|
243
|
+
<View>
|
|
244
|
+
<Button onPress={logout}>Sign Out</Button>
|
|
245
|
+
<Button onPress={deleteAccount}>Delete Account</Button>
|
|
246
|
+
</View>
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Validation
|
|
252
|
+
|
|
253
|
+
### Password Validation
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
import {
|
|
257
|
+
validatePasswordForRegister,
|
|
258
|
+
validatePasswordConfirmation,
|
|
259
|
+
} from '@umituz/react-native-auth';
|
|
260
|
+
|
|
261
|
+
// Validate password
|
|
262
|
+
const result = validatePasswordForRegister('MyPass123!');
|
|
263
|
+
|
|
264
|
+
if (result.isValid) {
|
|
265
|
+
console.log('Password is strong');
|
|
266
|
+
} else {
|
|
267
|
+
console.log('Requirements:', result.requirements);
|
|
268
|
+
// {
|
|
269
|
+
// hasMinLength: true,
|
|
270
|
+
// hasUppercase: true,
|
|
271
|
+
// hasLowercase: true,
|
|
272
|
+
// hasNumber: true,
|
|
273
|
+
// hasSpecialChar: true
|
|
274
|
+
// }
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Validate password confirmation
|
|
278
|
+
const matchResult = validatePasswordConfirmation('pass123', 'pass123');
|
|
279
|
+
// { isValid: true, matches: true }
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Email Validation
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
import { validateEmail } from '@umituz/react-native-auth';
|
|
286
|
+
|
|
287
|
+
const result = validateEmail('user@example.com');
|
|
288
|
+
// { isValid: true }
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## Configuration
|
|
292
|
+
|
|
293
|
+
### Auth Config
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
import { DEFAULT_AUTH_CONFIG } from '@umituz/react-native-auth';
|
|
297
|
+
|
|
298
|
+
const customConfig: AuthConfig = {
|
|
299
|
+
password: {
|
|
300
|
+
minLength: 12,
|
|
301
|
+
requireUppercase: true,
|
|
302
|
+
requireLowercase: true,
|
|
303
|
+
requireNumber: true,
|
|
304
|
+
requireSpecialChar: true,
|
|
305
|
+
},
|
|
306
|
+
social: {
|
|
307
|
+
google: {
|
|
308
|
+
enabled: true,
|
|
309
|
+
webClientId: Config.GOOGLE_WEB_CLIENT_ID,
|
|
310
|
+
iosClientId: Config.GOOGLE_IOS_CLIENT_ID,
|
|
311
|
+
},
|
|
312
|
+
apple: {
|
|
313
|
+
enabled: Platform.OS === 'ios',
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
};
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## Architecture
|
|
320
|
+
|
|
321
|
+
This package follows **Domain-Driven Design (DDD)** principles with clean architecture:
|
|
322
|
+
|
|
323
|
+
```
|
|
324
|
+
src/
|
|
325
|
+
βββ domain/ # Business logic and entities
|
|
326
|
+
β βββ entities/ # AuthUser, UserProfile
|
|
327
|
+
β βββ value-objects/# AuthConfig, PasswordConfig
|
|
328
|
+
β βββ errors/ # AuthError classes
|
|
329
|
+
β βββ utils/ # Domain utilities
|
|
330
|
+
βββ application/ # Interfaces and ports
|
|
331
|
+
β βββ ports/ # IAuthService, IAuthProvider
|
|
332
|
+
βββ infrastructure/ # External integrations
|
|
333
|
+
β βββ providers/ # Firebase implementation
|
|
334
|
+
β βββ services/ # AuthService, UserDocumentService
|
|
335
|
+
β βββ utils/ # Validation, storage adapters
|
|
336
|
+
βββ presentation/ # UI layer
|
|
337
|
+
βββ hooks/ # React hooks
|
|
338
|
+
βββ components/ # React components
|
|
339
|
+
βββ screens/ # Full screens
|
|
340
|
+
βββ stores/ # State management (Zustand)
|
|
341
|
+
βββ navigation/ # Navigation setup
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## API Reference
|
|
345
|
+
|
|
346
|
+
### Hooks
|
|
347
|
+
|
|
348
|
+
| Hook | Description |
|
|
349
|
+
|------|-------------|
|
|
350
|
+
| `useAuth` | Main auth state and operations |
|
|
351
|
+
| `useAuthRequired` | Check auth requirements |
|
|
352
|
+
| `useRequireAuth` | Get userId or throw |
|
|
353
|
+
| `useUserProfile` | Fetch user profile |
|
|
354
|
+
| `useProfileUpdate` | Update profile |
|
|
355
|
+
| `useProfileEdit` | Profile editing form state |
|
|
356
|
+
| `useAccountManagement` | Account operations |
|
|
357
|
+
| `useSocialLogin` | Social login management |
|
|
358
|
+
| `useGoogleAuth` | Google authentication |
|
|
359
|
+
| `useAppleAuth` | Apple authentication |
|
|
360
|
+
| `useAuthBottomSheet` | Auth bottom sheet management |
|
|
361
|
+
|
|
362
|
+
### Components
|
|
363
|
+
|
|
364
|
+
| Component | Description |
|
|
365
|
+
|-----------|-------------|
|
|
366
|
+
| `LoginForm` | Login form |
|
|
367
|
+
| `RegisterForm` | Registration form |
|
|
368
|
+
| `SocialLoginButtons` | Social login buttons |
|
|
369
|
+
| `PasswordStrengthIndicator` | Password strength visualizer |
|
|
370
|
+
| `PasswordMatchIndicator` | Password match indicator |
|
|
371
|
+
| `ProfileSection` | User profile display |
|
|
372
|
+
| `AccountActions` | Account action buttons |
|
|
373
|
+
|
|
374
|
+
### Services
|
|
375
|
+
|
|
376
|
+
| Service | Description |
|
|
377
|
+
|---------|-------------|
|
|
378
|
+
| `AuthService` | Main auth service |
|
|
379
|
+
| `initializeAuth` | Auth initialization |
|
|
380
|
+
| `UserDocumentService` | Firestore user documents |
|
|
381
|
+
| `AnonymousModeService` | Anonymous authentication |
|
|
382
|
+
|
|
383
|
+
## Documentation
|
|
384
|
+
|
|
385
|
+
- [Domain Layer](./src/domain/README.md) - Business logic and entities
|
|
386
|
+
- [Application Layer](./src/application/README.md) - Interfaces and ports
|
|
387
|
+
- [Infrastructure Layer](./src/infrastructure/README.md) - External integrations
|
|
388
|
+
- [Presentation Layer](./src/presentation/README.md) - UI components and hooks
|
|
389
|
+
- [Hooks Documentation](./src/presentation/hooks/README.md) - All hooks
|
|
390
|
+
- [Components Documentation](./src/presentation/components/README.md) - All components
|
|
391
|
+
- [Screens Documentation](./src/presentation/screens/README.md) - Pre-built screens
|
|
392
|
+
- [Services Documentation](./src/infrastructure/services/README.md) - Core services
|
|
393
|
+
|
|
394
|
+
## Examples
|
|
395
|
+
|
|
396
|
+
Check out the [examples](./examples) directory for complete implementations:
|
|
397
|
+
|
|
398
|
+
- [Basic Auth](./examples/basic-auth) - Simple email/password auth
|
|
399
|
+
- [Social Auth](./examples/social-auth) - Google and Apple sign-in
|
|
400
|
+
- [Protected Routes](./examples/protected-routes) - Route protection
|
|
401
|
+
- [Profile Management](./examples/profile-management) - User profile operations
|
|
402
|
+
|
|
403
|
+
## Contributing
|
|
404
|
+
|
|
405
|
+
Contributions are welcome! Please read our [Contributing Guide](./CONTRIBUTING.md) for details.
|
|
406
|
+
|
|
407
|
+
## License
|
|
408
|
+
|
|
409
|
+
MIT Β© [Γmit UZ](https://github.com/umituz)
|
|
410
|
+
|
|
411
|
+
## Support
|
|
412
|
+
|
|
413
|
+
- π§ Email: umit@umituz.com
|
|
414
|
+
- π¦ Twitter: [@umituz](https://twitter.com/umituz)
|
|
415
|
+
- π» GitHub: [umituz/react-native-auth](https://github.com/umituz/react-native-auth)
|
|
416
|
+
|
|
417
|
+
## Related Packages
|
|
418
|
+
|
|
419
|
+
- [@umituz/react-native-firebase](https://github.com/umituz/react-native-firebase) - Firebase integration
|
|
420
|
+
- [@umituz/react-native-localization](https://github.com/umituz/react-native-localization) - Localization
|
|
421
|
+
- [@umituz/react-native-storage](https://github.com/umituz/react-native-storage) - Storage abstraction
|
|
422
|
+
- [@umituz/react-native-tanstack](https://github.com/umituz/react-native-tanstack) - TanStack Query integration
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
Made with β€οΈ by [Γmit UZ](https://umituz.com)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-auth",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.32",
|
|
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",
|
|
@@ -43,7 +43,6 @@
|
|
|
43
43
|
"@react-navigation/stack": ">=6.0.0",
|
|
44
44
|
"@tanstack/react-query": ">=5.0.0",
|
|
45
45
|
"expo-auth-session": ">=5.0.0",
|
|
46
|
-
"expo-linear-gradient": ">=13.0.0",
|
|
47
46
|
"expo-web-browser": ">=12.0.0",
|
|
48
47
|
"firebase": ">=11.0.0",
|
|
49
48
|
"react": ">=18.2.0",
|
|
@@ -79,7 +78,6 @@
|
|
|
79
78
|
"expo-device": "^8.0.10",
|
|
80
79
|
"expo-file-system": "^19.0.21",
|
|
81
80
|
"expo-haptics": "^15.0.8",
|
|
82
|
-
"expo-linear-gradient": "^13.0.0",
|
|
83
81
|
"expo-sharing": "^14.0.8",
|
|
84
82
|
"expo-web-browser": "^12.0.0",
|
|
85
83
|
"firebase": "^11.0.0",
|