@umituz/react-native-auth 3.4.32 → 3.4.34
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 +347 -348
- package/package.json +2 -3
- package/src/application/README.md +323 -442
- package/src/domain/ConfigAndErrors.md +296 -431
- package/src/domain/README.md +361 -210
- package/src/domain/entities/AuthUser.md +231 -372
- package/src/domain/entities/UserProfile.md +271 -441
- package/src/index.ts +35 -0
- package/src/infrastructure/README.md +388 -444
- package/src/infrastructure/services/README.md +386 -312
- package/src/infrastructure/utils/validation/BaseValidators.ts +35 -0
- package/src/infrastructure/utils/validation/CollectionValidators.ts +56 -0
- package/src/infrastructure/utils/validation/DateValidators.ts +63 -0
- package/src/infrastructure/utils/validation/FormValidators.ts +22 -0
- package/src/infrastructure/utils/validation/NumberValidators.ts +55 -0
- package/src/infrastructure/utils/validation/StringValidators.ts +55 -0
- package/src/infrastructure/utils/validation/sanitization.ts +98 -0
- package/src/infrastructure/utils/validation/types.ts +15 -0
- package/src/presentation/README.md +631 -563
- package/src/presentation/components/ProfileComponents.md +307 -504
- package/src/presentation/components/README.md +254 -92
- package/src/presentation/hooks/README.md +247 -83
- package/src/presentation/hooks/useAccountManagement.md +295 -344
- package/src/presentation/hooks/useAuth.md +271 -227
- package/src/presentation/hooks/useAuthBottomSheet.md +417 -367
- package/src/presentation/hooks/useAuthRequired.md +308 -194
- package/src/presentation/hooks/useProfileUpdate.md +251 -279
- package/src/presentation/hooks/useSocialLogin.md +312 -287
- package/src/presentation/hooks/useUserProfile.md +259 -192
- package/src/presentation/screens/README.md +151 -153
|
@@ -1,576 +1,520 @@
|
|
|
1
1
|
# Infrastructure Layer
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Implements application interfaces and handles external service integrations.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
infrastructure/
|
|
9
|
-
├── providers/
|
|
10
|
-
│ └── FirebaseAuthProvider.ts # Firebase auth implementation
|
|
11
|
-
├── services/
|
|
12
|
-
│ ├── AuthService.ts # Main auth service
|
|
13
|
-
│ ├── initializeAuth.ts # Auth initialization
|
|
14
|
-
│ ├── UserDocumentService.ts # User document management
|
|
15
|
-
│ ├── AnonymousModeService.ts # Anonymous user service
|
|
16
|
-
│ └── AuthEventService.ts # Event handling
|
|
17
|
-
├── adapters/
|
|
18
|
-
│ └── StorageProviderAdapter.ts # Storage adapter
|
|
19
|
-
└── utils/
|
|
20
|
-
└── AuthValidation.ts # Validation utilities
|
|
21
|
-
```
|
|
7
|
+
## Strategy
|
|
22
8
|
|
|
23
|
-
|
|
9
|
+
**Purpose**: Provides concrete implementations of domain and application layer interfaces. Handles all external dependencies and integrations.
|
|
24
10
|
|
|
25
|
-
|
|
11
|
+
**When to Use**:
|
|
12
|
+
- Understanding Firebase integration
|
|
13
|
+
- Implementing custom services
|
|
14
|
+
- Debugging infrastructure issues
|
|
15
|
+
- Learning about external dependencies
|
|
26
16
|
|
|
27
|
-
|
|
28
|
-
- **Firestore**: User document storage
|
|
29
|
-
- **Firebase Storage**: Profile photo storage
|
|
30
|
-
- **Validation**: Input validation utilities
|
|
17
|
+
**Location**: `src/infrastructure/`
|
|
31
18
|
|
|
32
19
|
---
|
|
33
20
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Firebase Authentication implementation of `IAuthProvider`.
|
|
37
|
-
|
|
38
|
-
## Features
|
|
21
|
+
## Structure
|
|
39
22
|
|
|
40
|
-
|
|
41
|
-
- Google sign-in
|
|
42
|
-
- Apple sign-in
|
|
43
|
-
- Anonymous authentication
|
|
44
|
-
- User state management
|
|
23
|
+
### Services
|
|
45
24
|
|
|
46
|
-
|
|
25
|
+
**AuthService.ts** - Main authentication service
|
|
26
|
+
**Purpose**: Orchestrates all authentication operations
|
|
47
27
|
|
|
28
|
+
**IMPORT PATH**:
|
|
48
29
|
```typescript
|
|
49
|
-
import {
|
|
50
|
-
import { getAuth } from 'firebase/auth';
|
|
51
|
-
|
|
52
|
-
const firebaseAuth = getAuth();
|
|
53
|
-
const provider = new FirebaseAuthProvider(firebaseAuth);
|
|
54
|
-
|
|
55
|
-
// Sign up
|
|
56
|
-
const user = await provider.signUp({
|
|
57
|
-
email: 'user@example.com',
|
|
58
|
-
password: 'password123',
|
|
59
|
-
displayName: 'John Doe',
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
// Sign in
|
|
63
|
-
const user = await provider.signIn({
|
|
64
|
-
email: 'user@example.com',
|
|
65
|
-
password: 'password123',
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
// Sign out
|
|
69
|
-
await provider.signOut();
|
|
70
|
-
|
|
71
|
-
// Get current user
|
|
72
|
-
const currentUser = provider.getCurrentUser();
|
|
30
|
+
import { AuthService, initializeAuth } from '@umituz/react-native-auth';
|
|
73
31
|
```
|
|
74
32
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
33
|
+
**Rules**:
|
|
34
|
+
- MUST implement IAuthService interface
|
|
35
|
+
- MUST initialize before use
|
|
36
|
+
- MUST handle Firebase errors
|
|
37
|
+
- MUST create user documents
|
|
38
|
+
- MUST not expose Firebase internals
|
|
78
39
|
|
|
79
|
-
|
|
40
|
+
**MUST NOT**:
|
|
41
|
+
- Skip initialization
|
|
42
|
+
- Expose Firebase types
|
|
43
|
+
- Ignore error handling
|
|
44
|
+
- Create multiple instances
|
|
80
45
|
|
|
81
|
-
|
|
46
|
+
---
|
|
82
47
|
|
|
83
|
-
|
|
84
|
-
- User document creation
|
|
85
|
-
- Error handling
|
|
86
|
-
- State management
|
|
48
|
+
### UserDocumentService
|
|
87
49
|
|
|
88
|
-
|
|
50
|
+
**Purpose**: Manages Firestore user documents
|
|
89
51
|
|
|
52
|
+
**IMPORT PATH**:
|
|
90
53
|
```typescript
|
|
91
54
|
import {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
resetAuthService,
|
|
55
|
+
ensureUserDocument,
|
|
56
|
+
markUserDeleted,
|
|
57
|
+
configureUserDocumentService
|
|
96
58
|
} from '@umituz/react-native-auth';
|
|
97
|
-
|
|
98
|
-
// Initialize (must be called once)
|
|
99
|
-
initializeAuthService({
|
|
100
|
-
firebaseAuth: getAuth(),
|
|
101
|
-
onAuthStateChanged: (user) => {
|
|
102
|
-
console.log('Auth state changed:', user);
|
|
103
|
-
},
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
// Get service instance
|
|
107
|
-
const authService = getAuthService();
|
|
108
|
-
|
|
109
|
-
// Sign in
|
|
110
|
-
const user = await authService.signIn({
|
|
111
|
-
email: 'user@example.com',
|
|
112
|
-
password: 'password123',
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
// Sign up
|
|
116
|
-
const user = await authService.signUp({
|
|
117
|
-
email: 'user@example.com',
|
|
118
|
-
password: 'password123',
|
|
119
|
-
displayName: 'John Doe',
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
// Sign out
|
|
123
|
-
await authService.signOut();
|
|
124
|
-
|
|
125
|
-
// Reset (testing only)
|
|
126
|
-
resetAuthService();
|
|
127
59
|
```
|
|
128
60
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
61
|
+
**OPERATIONS**:
|
|
62
|
+
- `ensureUserDocument(user, data?)` - Create/retrieve user document
|
|
63
|
+
- `markUserDeleted(userId)` - Mark user as deleted
|
|
64
|
+
- `configureUserDocumentService(config)` - Configure service
|
|
65
|
+
|
|
66
|
+
**Rules**:
|
|
67
|
+
- MUST create document on registration
|
|
68
|
+
- MUST handle document existence
|
|
69
|
+
- MUST use server timestamps
|
|
70
|
+
- MUST support custom configuration
|
|
71
|
+
- MUST not delete documents permanently
|
|
72
|
+
|
|
73
|
+
**MUST NOT**:
|
|
74
|
+
- Skip document creation
|
|
75
|
+
- Overwrite existing data
|
|
76
|
+
- Use client timestamps
|
|
77
|
+
- Hardcode collection name
|
|
78
|
+
|
|
79
|
+
**CONFIGURATION**:
|
|
80
|
+
- `collection` - Firestore collection name (default: 'users')
|
|
81
|
+
- `timestamps` - Add createdAt/updatedAt fields
|
|
82
|
+
- `userData` - Custom fields to add
|
|
140
83
|
|
|
141
84
|
---
|
|
142
85
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
Initializes the authentication system and sets up Firebase Auth state listener.
|
|
146
|
-
|
|
147
|
-
## Features
|
|
148
|
-
|
|
149
|
-
- Firebase Auth initialization
|
|
150
|
-
- Auth state listener setup
|
|
151
|
-
- Automatic user document creation
|
|
152
|
-
- Error handling
|
|
86
|
+
### AnonymousModeService
|
|
153
87
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
### Basic Initialization
|
|
88
|
+
**Purpose**: Handles anonymous user authentication and upgrade
|
|
157
89
|
|
|
90
|
+
**IMPORT PATH**:
|
|
158
91
|
```typescript
|
|
159
|
-
import {
|
|
160
|
-
|
|
161
|
-
function App() {
|
|
162
|
-
useEffect(() => {
|
|
163
|
-
const init = async () => {
|
|
164
|
-
await initializeAuth({
|
|
165
|
-
onAuthStateChanged: (user) => {
|
|
166
|
-
console.log('Auth state changed:', user);
|
|
167
|
-
},
|
|
168
|
-
});
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
init();
|
|
172
|
-
}, []);
|
|
173
|
-
|
|
174
|
-
return <AppNavigator />;
|
|
175
|
-
}
|
|
92
|
+
import { AnonymousModeService } from '@umituz/react-native-auth';
|
|
176
93
|
```
|
|
177
94
|
|
|
178
|
-
|
|
95
|
+
**OPERATIONS**:
|
|
96
|
+
- `signInAnonymously()` - Create anonymous user
|
|
97
|
+
- User upgrade via Firebase credential linking
|
|
98
|
+
|
|
99
|
+
**Rules**:
|
|
100
|
+
- MUST create temporary accounts
|
|
101
|
+
- MUST support upgrade path
|
|
102
|
+
- MUST warn about data loss
|
|
103
|
+
- MUST handle upgrade failures
|
|
104
|
+
- MUST not delete anonymous data
|
|
105
|
+
|
|
106
|
+
**MUST NOT**:
|
|
107
|
+
- Skip upgrade warnings
|
|
108
|
+
- Lose user data on upgrade
|
|
109
|
+
- Allow anonymous operations without warning
|
|
110
|
+
- Make anonymous permanent
|
|
111
|
+
|
|
112
|
+
**Constraints**:
|
|
113
|
+
- Anonymous users have limited functionality
|
|
114
|
+
- Data lost if sign out without upgrade
|
|
115
|
+
- Upgrade requires credentials
|
|
116
|
+
- Cannot revert to anonymous after upgrade
|
|
179
117
|
|
|
180
|
-
|
|
181
|
-
import { initializeAuth } from '@umituz/react-native-auth';
|
|
118
|
+
---
|
|
182
119
|
|
|
183
|
-
|
|
184
|
-
const navigation = useNavigation();
|
|
185
|
-
|
|
186
|
-
useEffect(() => {
|
|
187
|
-
initializeAuth({
|
|
188
|
-
onAuthStateChanged: (user) => {
|
|
189
|
-
if (user) {
|
|
190
|
-
navigation.reset({
|
|
191
|
-
index: 0,
|
|
192
|
-
routes: [{ name: 'Home' }],
|
|
193
|
-
});
|
|
194
|
-
} else {
|
|
195
|
-
navigation.reset({
|
|
196
|
-
index: 0,
|
|
197
|
-
routes: [{ name: 'Login' }],
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
},
|
|
201
|
-
onAuthError: (error) => {
|
|
202
|
-
console.error('Auth error:', error);
|
|
203
|
-
Alert.alert('Auth Error', error.message);
|
|
204
|
-
},
|
|
205
|
-
});
|
|
206
|
-
}, []);
|
|
207
|
-
|
|
208
|
-
return <NavigationContainer>{/* Routes */}</NavigationContainer>;
|
|
209
|
-
}
|
|
210
|
-
```
|
|
120
|
+
### AuthEventService
|
|
211
121
|
|
|
212
|
-
|
|
122
|
+
**Purpose**: Pub/sub system for authentication events
|
|
213
123
|
|
|
124
|
+
**IMPORT PATH**:
|
|
214
125
|
```typescript
|
|
215
|
-
import {
|
|
216
|
-
|
|
217
|
-
if (isAuthInitialized()) {
|
|
218
|
-
console.log('Auth is initialized');
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// Reset (testing only)
|
|
222
|
-
resetAuthInitialization();
|
|
126
|
+
import { AuthEventService } from '@umituz/react-native-auth';
|
|
223
127
|
```
|
|
224
128
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
129
|
+
**OPERATIONS**:
|
|
130
|
+
- `on(event, callback)` - Subscribe to event
|
|
131
|
+
- `emit(event, data)` - Emit event
|
|
132
|
+
- Returns unsubscribe function
|
|
133
|
+
|
|
134
|
+
**EVENTS**:
|
|
135
|
+
- `signIn` - User signed in (payload: AuthUser)
|
|
136
|
+
- `signUp` - New user registered (payload: AuthUser)
|
|
137
|
+
- `signOut` - User signed out (payload: undefined)
|
|
138
|
+
- `authStateChanged` - Auth state changed (payload: AuthUser | null)
|
|
139
|
+
|
|
140
|
+
**Rules**:
|
|
141
|
+
- MUST emit events on state changes
|
|
142
|
+
- MUST allow multiple subscribers
|
|
143
|
+
- MUST provide unsubscribe function
|
|
144
|
+
- MUST not throw in event handlers
|
|
145
|
+
- MUST handle subscriber errors
|
|
146
|
+
|
|
147
|
+
**MUST NOT**:
|
|
148
|
+
- Skip critical events
|
|
149
|
+
- Block on event handlers
|
|
150
|
+
- Throw unhandled errors
|
|
151
|
+
- Memory leak subscribers
|
|
230
152
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
- Automatic user document creation
|
|
234
|
-
- User data updates
|
|
235
|
-
- Account deletion marking
|
|
236
|
-
- Custom configuration
|
|
153
|
+
---
|
|
237
154
|
|
|
238
|
-
|
|
155
|
+
### StorageProviderAdapter
|
|
239
156
|
|
|
240
|
-
|
|
157
|
+
**Purpose**: Adapter interface for storage providers
|
|
241
158
|
|
|
159
|
+
**IMPORT PATH**:
|
|
242
160
|
```typescript
|
|
243
|
-
import {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
await ensureUserDocument(user);
|
|
161
|
+
import {
|
|
162
|
+
createStorageProvider,
|
|
163
|
+
StorageProviderAdapter
|
|
164
|
+
} from '@umituz/react-native-auth';
|
|
248
165
|
```
|
|
249
166
|
|
|
250
|
-
|
|
167
|
+
**INTERFACE METHODS**:
|
|
168
|
+
- `getItem(key)` - Retrieve value
|
|
169
|
+
- `setItem(key, value)` - Store value
|
|
170
|
+
- `removeItem(key)` - Delete value
|
|
171
|
+
|
|
172
|
+
**Rules**:
|
|
173
|
+
- MUST implement all methods
|
|
174
|
+
- MUST handle async operations
|
|
175
|
+
- MUST return null for missing keys
|
|
176
|
+
- MUST handle storage errors
|
|
177
|
+
- MUST support string values only
|
|
178
|
+
|
|
179
|
+
**MUST NOT**:
|
|
180
|
+
- Throw for missing keys
|
|
181
|
+
- Skip error handling
|
|
182
|
+
- Assume synchronous operations
|
|
183
|
+
- Store non-string values
|
|
184
|
+
|
|
185
|
+
**IMPLEMENTATIONS**:
|
|
186
|
+
- AsyncStorage
|
|
187
|
+
- MMKV
|
|
188
|
+
- SecureStorage
|
|
189
|
+
- Custom implementations
|
|
251
190
|
|
|
252
|
-
|
|
253
|
-
import { markUserDeleted } from '@umituz/react-native-auth';
|
|
191
|
+
---
|
|
254
192
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
193
|
+
## Validation Utilities
|
|
194
|
+
|
|
195
|
+
### AuthValidation
|
|
258
196
|
|
|
259
|
-
|
|
197
|
+
**Purpose**: Input validation for authentication
|
|
260
198
|
|
|
199
|
+
**IMPORT PATH**:
|
|
261
200
|
```typescript
|
|
262
|
-
import {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
},
|
|
271
|
-
});
|
|
201
|
+
import {
|
|
202
|
+
validateEmail,
|
|
203
|
+
validatePasswordForLogin,
|
|
204
|
+
validatePasswordForRegister,
|
|
205
|
+
validatePasswordConfirmation,
|
|
206
|
+
validateDisplayName,
|
|
207
|
+
DEFAULT_VAL_CONFIG
|
|
208
|
+
} from '@umituz/react-native-auth';
|
|
272
209
|
```
|
|
273
210
|
|
|
274
|
-
|
|
211
|
+
**VALIDATORS**:
|
|
212
|
+
- `validateEmail(email)` - Email format validation
|
|
213
|
+
- `validatePasswordForLogin(password)` - Login password check
|
|
214
|
+
- `validatePasswordForRegister(password)` - Registration password complexity
|
|
215
|
+
- `validatePasswordConfirmation(password, confirmation)` - Password match
|
|
216
|
+
- `validateDisplayName(name)` - Display name validation
|
|
275
217
|
|
|
218
|
+
**RETURN TYPE**:
|
|
276
219
|
```typescript
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
notifications: true,
|
|
283
|
-
},
|
|
284
|
-
});
|
|
220
|
+
{
|
|
221
|
+
isValid: boolean;
|
|
222
|
+
error?: string;
|
|
223
|
+
// Additional fields for specific validators
|
|
224
|
+
}
|
|
285
225
|
```
|
|
286
226
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
227
|
+
**Rules**:
|
|
228
|
+
- MUST return validation result object
|
|
229
|
+
- MUST provide error messages
|
|
230
|
+
- MUST use configurable rules
|
|
231
|
+
- MUST support internationalization
|
|
232
|
+
- MUST not throw for invalid input
|
|
233
|
+
|
|
234
|
+
**MUST NOT**:
|
|
235
|
+
- Return boolean only
|
|
236
|
+
- Skip error messages
|
|
237
|
+
- Hardcode validation rules
|
|
238
|
+
- Throw on validation failure
|
|
239
|
+
|
|
240
|
+
**DEFAULT CONFIG**:
|
|
241
|
+
- `password.minLength` - 8 characters
|
|
242
|
+
- `password.requireUppercase` - true
|
|
243
|
+
- `password.requireLowercase` - true
|
|
244
|
+
- `password.requireNumber` - true
|
|
245
|
+
- `password.requireSpecialChar` - true
|
|
290
246
|
|
|
291
|
-
|
|
247
|
+
---
|
|
292
248
|
|
|
293
|
-
##
|
|
249
|
+
## Firebase Integration
|
|
294
250
|
|
|
295
|
-
|
|
296
|
-
- Anonymous user upgrade to regular account
|
|
297
|
-
- Anonymous state management
|
|
251
|
+
### FirebaseAuthProvider
|
|
298
252
|
|
|
299
|
-
|
|
253
|
+
**Purpose**: Firebase Authentication implementation
|
|
300
254
|
|
|
301
|
-
|
|
302
|
-
import { AnonymousModeService } from '@umituz/react-native-auth';
|
|
255
|
+
**Location**: `providers/FirebaseAuthProvider.ts`
|
|
303
256
|
|
|
304
|
-
|
|
257
|
+
**Rules**:
|
|
258
|
+
- MUST implement IAuthProvider
|
|
259
|
+
- MUST wrap Firebase SDK
|
|
260
|
+
- MUST handle Firebase lifecycle
|
|
261
|
+
- MUST map to domain entities
|
|
262
|
+
- MUST convert Firebase errors
|
|
305
263
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
const credential = EmailAuthProvider.credential(email, password);
|
|
312
|
-
await linkWithCredential(user, credential);
|
|
313
|
-
console.log('User upgraded:', user.email);
|
|
314
|
-
```
|
|
264
|
+
**MUST NOT**:
|
|
265
|
+
- Expose Firebase types
|
|
266
|
+
- Bypass error mapping
|
|
267
|
+
- Skip Firebase initialization
|
|
268
|
+
- Ignore auth state changes
|
|
315
269
|
|
|
316
270
|
---
|
|
317
271
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
Manages authentication events and provides pub/sub functionality.
|
|
321
|
-
|
|
322
|
-
## Features
|
|
272
|
+
### Error Mapping
|
|
323
273
|
|
|
324
|
-
|
|
325
|
-
- Event subscription
|
|
326
|
-
- Type-safe events
|
|
327
|
-
|
|
328
|
-
## Usage
|
|
274
|
+
**Purpose**: Convert Firebase errors to domain errors
|
|
329
275
|
|
|
276
|
+
**IMPORT PATH**:
|
|
330
277
|
```typescript
|
|
331
|
-
import {
|
|
332
|
-
|
|
333
|
-
const eventService = new AuthEventService();
|
|
334
|
-
|
|
335
|
-
// Subscribe to events
|
|
336
|
-
const unsubscribe = eventService.on('signIn', (user) => {
|
|
337
|
-
console.log('User signed in:', user);
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
// Emit events
|
|
341
|
-
eventService.emit('signIn', user);
|
|
342
|
-
|
|
343
|
-
// Unsubscribe
|
|
344
|
-
unsubscribe();
|
|
278
|
+
import { mapFirebaseError } from '@umituz/react-native-auth';
|
|
345
279
|
```
|
|
346
280
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
281
|
+
**MAPPING**:
|
|
282
|
+
- `auth/user-not-found` → AuthUserNotFoundError
|
|
283
|
+
- `auth/wrong-password` → AuthWrongPasswordError
|
|
284
|
+
- `auth/email-already-in-use` → AuthEmailAlreadyInUseError
|
|
285
|
+
- `auth/weak-password` → AuthWeakPasswordError
|
|
286
|
+
- `auth/invalid-email` → AuthInvalidEmailError
|
|
287
|
+
- `auth/network-request-failed` → AuthNetworkError
|
|
288
|
+
|
|
289
|
+
**Rules**:
|
|
290
|
+
- MUST map all Firebase errors
|
|
291
|
+
- MUST preserve error context
|
|
292
|
+
- MUST use domain error types
|
|
293
|
+
- MUST not lose error information
|
|
294
|
+
- MUST handle unknown errors
|
|
295
|
+
|
|
296
|
+
**MUST NOT**:
|
|
297
|
+
- Throw raw Firebase errors
|
|
298
|
+
- Skip error mapping
|
|
299
|
+
- Lose error context
|
|
300
|
+
- Use generic error type
|
|
355
301
|
|
|
356
302
|
---
|
|
357
303
|
|
|
358
|
-
|
|
304
|
+
## Initialization
|
|
359
305
|
|
|
360
|
-
|
|
306
|
+
### initializeAuth
|
|
361
307
|
|
|
362
|
-
|
|
308
|
+
**Purpose**: Initialize authentication system
|
|
363
309
|
|
|
310
|
+
**IMPORT PATH**:
|
|
364
311
|
```typescript
|
|
365
|
-
import {
|
|
366
|
-
|
|
367
|
-
StorageProviderAdapter,
|
|
368
|
-
} from '@umituz/react-native-auth';
|
|
312
|
+
import { initializeAuth } from '@umituz/react-native-auth';
|
|
313
|
+
```
|
|
369
314
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
return await AsyncStorage.getItem(key);
|
|
374
|
-
}
|
|
315
|
+
**PARAMETERS**:
|
|
316
|
+
- `onAuthStateChanged` - Auth state callback
|
|
317
|
+
- `onAuthError` - Error callback (optional)
|
|
375
318
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
319
|
+
**Rules**:
|
|
320
|
+
- MUST call once at app startup
|
|
321
|
+
- MUST wait for initialization
|
|
322
|
+
- MUST handle initialization errors
|
|
323
|
+
- MUST not call multiple times
|
|
324
|
+
- MUST check initialization status
|
|
379
325
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
326
|
+
**MUST NOT**:
|
|
327
|
+
- Skip initialization
|
|
328
|
+
- Call in components
|
|
329
|
+
- Initialize multiple times
|
|
330
|
+
- Ignore initialization status
|
|
384
331
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
332
|
+
**CHECK FUNCTIONS**:
|
|
333
|
+
- `isAuthInitialized()` - Check if initialized
|
|
334
|
+
- `resetAuthInitialization()` - Reset (testing only)
|
|
388
335
|
|
|
389
336
|
---
|
|
390
337
|
|
|
391
|
-
|
|
338
|
+
## Configuration
|
|
392
339
|
|
|
393
|
-
|
|
340
|
+
### Service Configuration
|
|
394
341
|
|
|
395
|
-
|
|
342
|
+
**AuthService Configuration**:
|
|
343
|
+
- Firebase Auth instance
|
|
344
|
+
- Auth state callbacks
|
|
345
|
+
- Error handlers
|
|
396
346
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
validatePasswordForRegister,
|
|
402
|
-
validatePasswordConfirmation,
|
|
403
|
-
validateDisplayName,
|
|
404
|
-
DEFAULT_VAL_CONFIG,
|
|
405
|
-
} from '@umituz/react-native-auth';
|
|
406
|
-
```
|
|
347
|
+
**UserDocumentService Configuration**:
|
|
348
|
+
- Collection name
|
|
349
|
+
- Timestamps
|
|
350
|
+
- Custom user data
|
|
407
351
|
|
|
408
|
-
|
|
352
|
+
**Validation Configuration**:
|
|
353
|
+
- Password requirements
|
|
354
|
+
- Email validation rules
|
|
355
|
+
- Display name constraints
|
|
409
356
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
357
|
+
**Rules**:
|
|
358
|
+
- MUST configure before use
|
|
359
|
+
- MUST use valid configuration
|
|
360
|
+
- MUST handle config errors
|
|
361
|
+
- MUST not change after initialization
|
|
362
|
+
- MUST validate configuration
|
|
413
363
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
364
|
+
**MUST NOT**:
|
|
365
|
+
- Skip configuration
|
|
366
|
+
- Use invalid config
|
|
367
|
+
- Change after initialization
|
|
368
|
+
- Ignore config errors
|
|
417
369
|
|
|
418
|
-
|
|
370
|
+
---
|
|
419
371
|
|
|
420
|
-
|
|
421
|
-
const result = validatePasswordForLogin('password123');
|
|
422
|
-
// { isValid: true }
|
|
372
|
+
## Best Practices
|
|
423
373
|
|
|
424
|
-
|
|
425
|
-
// { isValid: false, error: 'Password is required' }
|
|
426
|
-
```
|
|
374
|
+
### Initialization
|
|
427
375
|
|
|
428
|
-
|
|
376
|
+
**MUST**:
|
|
377
|
+
- Initialize at app root
|
|
378
|
+
- Wait for initialization
|
|
379
|
+
- Handle initialization errors
|
|
380
|
+
- Check initialization status
|
|
381
|
+
- Configure properly
|
|
429
382
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
// hasUppercase: true,
|
|
437
|
-
// hasLowercase: true,
|
|
438
|
-
// hasNumber: true,
|
|
439
|
-
// hasSpecialChar: true
|
|
440
|
-
// }
|
|
441
|
-
// }
|
|
442
|
-
|
|
443
|
-
const result = validatePasswordForRegister('weak');
|
|
444
|
-
// {
|
|
445
|
-
// isValid: false,
|
|
446
|
-
// requirements: { ... },
|
|
447
|
-
// error: 'Password does not meet requirements'
|
|
448
|
-
// }
|
|
449
|
-
```
|
|
383
|
+
**MUST NOT**:
|
|
384
|
+
- Initialize in components
|
|
385
|
+
- Skip initialization check
|
|
386
|
+
- Ignore initialization errors
|
|
387
|
+
- Initialize multiple times
|
|
388
|
+
- Use default config blindly
|
|
450
389
|
|
|
451
|
-
|
|
390
|
+
---
|
|
452
391
|
|
|
453
|
-
|
|
454
|
-
const result = validatePasswordConfirmation('password123', 'password123');
|
|
455
|
-
// { isValid: true, matches: true }
|
|
392
|
+
### Error Handling
|
|
456
393
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
394
|
+
**MUST**:
|
|
395
|
+
- Map Firebase errors to domain
|
|
396
|
+
- Provide context
|
|
397
|
+
- Log appropriately
|
|
398
|
+
- Show user-friendly messages
|
|
399
|
+
- Handle network failures
|
|
460
400
|
|
|
461
|
-
|
|
401
|
+
**MUST NOT**:
|
|
402
|
+
- Expose Firebase errors
|
|
403
|
+
- Show technical details
|
|
404
|
+
- Skip error mapping
|
|
405
|
+
- Suppress errors
|
|
406
|
+
- Log sensitive data
|
|
462
407
|
|
|
463
|
-
|
|
464
|
-
const result = validateDisplayName('John Doe');
|
|
465
|
-
// { isValid: true }
|
|
408
|
+
---
|
|
466
409
|
|
|
467
|
-
|
|
468
|
-
// { isValid: false, error: 'Display name is required' }
|
|
469
|
-
```
|
|
410
|
+
### User Documents
|
|
470
411
|
|
|
471
|
-
|
|
412
|
+
**MUST**:
|
|
413
|
+
- Create document on registration
|
|
414
|
+
- Use server timestamps
|
|
415
|
+
- Handle existing documents
|
|
416
|
+
- Configure collection name
|
|
417
|
+
- Add custom fields
|
|
472
418
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
// password: {
|
|
480
|
-
// minLength: 8,
|
|
481
|
-
// requireUppercase: true,
|
|
482
|
-
// requireLowercase: true,
|
|
483
|
-
// requireNumber: true,
|
|
484
|
-
// requireSpecialChar: true,
|
|
485
|
-
// }
|
|
486
|
-
// }
|
|
487
|
-
```
|
|
419
|
+
**MUST NOT**:
|
|
420
|
+
- Skip document creation
|
|
421
|
+
- Overwrite data
|
|
422
|
+
- Use client timestamps
|
|
423
|
+
- Hardcode collection name
|
|
424
|
+
- Delete documents permanently
|
|
488
425
|
|
|
489
426
|
---
|
|
490
427
|
|
|
491
|
-
|
|
428
|
+
## Security
|
|
492
429
|
|
|
493
|
-
|
|
430
|
+
### Data Protection
|
|
494
431
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
432
|
+
**MUST**:
|
|
433
|
+
- Validate all inputs
|
|
434
|
+
- Use HTTPS
|
|
435
|
+
- Handle tokens properly
|
|
436
|
+
- Secure credentials
|
|
437
|
+
- Log appropriately
|
|
501
438
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
439
|
+
**MUST NOT**:
|
|
440
|
+
- Log passwords
|
|
441
|
+
- Expose tokens
|
|
442
|
+
- Skip validation
|
|
443
|
+
- Store credentials insecurely
|
|
444
|
+
- Log sensitive data
|
|
506
445
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
### Firebase Security
|
|
449
|
+
|
|
450
|
+
**MUST**:
|
|
451
|
+
- Use Firebase security rules
|
|
452
|
+
- Enable required providers
|
|
453
|
+
- Configure properly
|
|
454
|
+
- Monitor usage
|
|
455
|
+
- Handle errors
|
|
456
|
+
|
|
457
|
+
**MUST NOT**:
|
|
458
|
+
- Skip Firebase setup
|
|
459
|
+
- Ignore security rules
|
|
460
|
+
- Expose API keys
|
|
461
|
+
- Leave unconfigured
|
|
462
|
+
- Ignore Firebase errors
|
|
514
463
|
|
|
515
464
|
---
|
|
516
465
|
|
|
517
|
-
|
|
466
|
+
## Constraints
|
|
518
467
|
|
|
519
|
-
|
|
468
|
+
### Platform Limitations
|
|
520
469
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
}, []);
|
|
470
|
+
**Firebase Dependencies**:
|
|
471
|
+
- Requires Firebase project
|
|
472
|
+
- Requires Firebase SDK
|
|
473
|
+
- Requires network connection
|
|
474
|
+
- Platform-specific features
|
|
527
475
|
|
|
528
|
-
|
|
529
|
-
|
|
476
|
+
**Rules**:
|
|
477
|
+
- MUST check platform availability
|
|
478
|
+
- MUST handle platform differences
|
|
479
|
+
- MUST not crash on unsupported
|
|
480
|
+
- MUST document platform constraints
|
|
530
481
|
|
|
531
|
-
|
|
532
|
-
function LoginComponent() {
|
|
533
|
-
useEffect(() => {
|
|
534
|
-
initializeAuth(); // Too late!
|
|
535
|
-
}, []);
|
|
536
|
-
}
|
|
537
|
-
```
|
|
482
|
+
---
|
|
538
483
|
|
|
539
|
-
|
|
484
|
+
### Network Requirements
|
|
540
485
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
486
|
+
**MUST**:
|
|
487
|
+
- Handle network failures
|
|
488
|
+
- Provide offline fallback
|
|
489
|
+
- Show network errors
|
|
490
|
+
- Allow retry
|
|
491
|
+
- Check connectivity
|
|
544
492
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
493
|
+
**MUST NOT**:
|
|
494
|
+
- Assume always online
|
|
495
|
+
- Skip network errors
|
|
496
|
+
- Crash on network failure
|
|
497
|
+
- Prevent offline usage
|
|
548
498
|
|
|
549
|
-
|
|
550
|
-
return <LoadingScreen />;
|
|
551
|
-
}
|
|
499
|
+
---
|
|
552
500
|
|
|
553
|
-
|
|
554
|
-
}
|
|
555
|
-
```
|
|
501
|
+
## Related Modules
|
|
556
502
|
|
|
557
|
-
|
|
503
|
+
- **Domain** (`../domain/README.md`) - AuthUser entity, errors, config
|
|
504
|
+
- **Application** (`../application/README.md`) - Interfaces and ports
|
|
505
|
+
- **Presentation** (`../presentation/README.md`) - UI components
|
|
558
506
|
|
|
559
|
-
|
|
560
|
-
async function protectedOperation() {
|
|
561
|
-
const authService = getAuthService();
|
|
562
|
-
const user = authService.getCurrentUser();
|
|
507
|
+
---
|
|
563
508
|
|
|
564
|
-
|
|
565
|
-
throw new Error('User not authenticated');
|
|
566
|
-
}
|
|
509
|
+
## Service Documentation
|
|
567
510
|
|
|
568
|
-
|
|
569
|
-
}
|
|
570
|
-
```
|
|
511
|
+
### Detailed Service Docs
|
|
571
512
|
|
|
572
|
-
|
|
513
|
+
**See**: `services/README.md` for detailed service documentation
|
|
573
514
|
|
|
574
|
-
|
|
575
|
-
-
|
|
576
|
-
-
|
|
515
|
+
**Services Covered**:
|
|
516
|
+
- AuthService
|
|
517
|
+
- UserDocumentService
|
|
518
|
+
- AnonymousModeService
|
|
519
|
+
- AuthEventService
|
|
520
|
+
- Validation utilities
|