@umituz/react-native-auth 3.4.33 → 3.4.35
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/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/infrastructure/README.md +388 -444
- package/src/infrastructure/services/README.md +386 -312
- package/src/presentation/README.md +631 -563
- package/src/presentation/components/ProfileSection.tsx +3 -1
- package/src/presentation/components/README.md +254 -92
- package/src/presentation/hooks/README.md +247 -83
- package/src/presentation/hooks/useUserProfile.ts +1 -0
- package/src/presentation/screens/README.md +151 -153
|
@@ -1,242 +1,193 @@
|
|
|
1
1
|
# AuthConfig & AuthError
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Configuration value objects and domain error classes.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## AuthConfig
|
|
8
8
|
|
|
9
|
-
Authentication configuration value object
|
|
9
|
+
Authentication configuration value object.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
### Strategy
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
import type {
|
|
15
|
-
AuthConfig,
|
|
16
|
-
PasswordConfig,
|
|
17
|
-
SocialAuthConfig,
|
|
18
|
-
GoogleAuthConfig,
|
|
19
|
-
AppleAuthConfig,
|
|
20
|
-
SocialAuthProvider,
|
|
21
|
-
DEFAULT_AUTH_CONFIG,
|
|
22
|
-
DEFAULT_PASSWORD_CONFIG,
|
|
23
|
-
DEFAULT_SOCIAL_CONFIG,
|
|
24
|
-
} from '@umituz/react-native-auth';
|
|
25
|
-
|
|
26
|
-
interface PasswordConfig {
|
|
27
|
-
minLength: number; // Minimum password length
|
|
28
|
-
requireUppercase: boolean; // Require uppercase letter
|
|
29
|
-
requireLowercase: boolean; // Require lowercase letter
|
|
30
|
-
requireNumber: boolean; // Require number
|
|
31
|
-
requireSpecialChar: boolean; // Require special character
|
|
32
|
-
}
|
|
13
|
+
**Purpose**: Centralized configuration for password requirements and social auth providers.
|
|
33
14
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
15
|
+
**When to Use**:
|
|
16
|
+
- Configuring auth behavior
|
|
17
|
+
- Setting password policies
|
|
18
|
+
- Enabling social providers
|
|
19
|
+
- Environment-specific config
|
|
40
20
|
|
|
41
|
-
|
|
42
|
-
enabled?: boolean; // Is enabled (iOS only)
|
|
43
|
-
}
|
|
21
|
+
**Location**: `src/domain/valueObjects/AuthConfig.ts`
|
|
44
22
|
|
|
45
|
-
|
|
46
|
-
google?: GoogleAuthConfig;
|
|
47
|
-
apple?: AppleAuthConfig;
|
|
48
|
-
}
|
|
23
|
+
---
|
|
49
24
|
|
|
50
|
-
|
|
51
|
-
password: PasswordConfig;
|
|
52
|
-
social?: SocialAuthConfig;
|
|
53
|
-
}
|
|
25
|
+
## Configuration Types
|
|
54
26
|
|
|
55
|
-
|
|
56
|
-
```
|
|
27
|
+
### PasswordConfig
|
|
57
28
|
|
|
58
|
-
|
|
29
|
+
**PURPOSE**: Password validation requirements
|
|
59
30
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// Default password configuration
|
|
68
|
-
DEFAULT_PASSWORD_CONFIG;
|
|
69
|
-
// {
|
|
70
|
-
// minLength: 6,
|
|
71
|
-
// requireUppercase: false,
|
|
72
|
-
// requireLowercase: false,
|
|
73
|
-
// requireNumber: false,
|
|
74
|
-
// requireSpecialChar: false,
|
|
75
|
-
// }
|
|
76
|
-
|
|
77
|
-
// Default social configuration
|
|
78
|
-
DEFAULT_SOCIAL_CONFIG;
|
|
79
|
-
// {
|
|
80
|
-
// google: { enabled: false },
|
|
81
|
-
// apple: { enabled: false },
|
|
82
|
-
// }
|
|
83
|
-
|
|
84
|
-
// Default auth configuration
|
|
85
|
-
DEFAULT_AUTH_CONFIG;
|
|
86
|
-
// {
|
|
87
|
-
// password: DEFAULT_PASSWORD_CONFIG,
|
|
88
|
-
// social: DEFAULT_SOCIAL_CONFIG,
|
|
89
|
-
// }
|
|
90
|
-
```
|
|
31
|
+
**PROPERTIES**:
|
|
32
|
+
- `minLength: number` - Minimum password length
|
|
33
|
+
- `requireUppercase: boolean` - Require uppercase letter
|
|
34
|
+
- `requireLowercase: boolean` - Require lowercase letter
|
|
35
|
+
- `requireNumber: boolean` - Require number
|
|
36
|
+
- `requireSpecialChar: boolean` - Require special character
|
|
91
37
|
|
|
92
|
-
|
|
38
|
+
**DEFAULT VALUES**:
|
|
39
|
+
- minLength: 6
|
|
40
|
+
- All requirements: false (lenient)
|
|
93
41
|
|
|
94
|
-
|
|
42
|
+
**Rules**:
|
|
43
|
+
- MUST set minLength between 4-128
|
|
44
|
+
- SHOULD enable requirements in production
|
|
45
|
+
- MUST validate password against config
|
|
46
|
+
- MUST NOT allow minLength < 4
|
|
95
47
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
requireLowercase: true,
|
|
101
|
-
requireNumber: true,
|
|
102
|
-
requireSpecialChar: true,
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
const authConfig: AuthConfig = {
|
|
106
|
-
password: strictPasswordConfig,
|
|
107
|
-
};
|
|
108
|
-
```
|
|
48
|
+
**MUST NOT**:
|
|
49
|
+
- Set minLength < 4 (too weak)
|
|
50
|
+
- Set minLength > 128 (too long)
|
|
51
|
+
- Enable all requirements without UX consideration
|
|
109
52
|
|
|
110
|
-
|
|
53
|
+
---
|
|
111
54
|
|
|
112
|
-
|
|
113
|
-
const socialAuthConfig: SocialAuthConfig = {
|
|
114
|
-
google: {
|
|
115
|
-
enabled: true,
|
|
116
|
-
webClientId: 'your-web-client-id.apps.googleusercontent.com',
|
|
117
|
-
iosClientId: 'your-ios-client-id.apps.googleusercontent.com',
|
|
118
|
-
androidClientId: 'your-android-client-id.apps.googleusercontent.com',
|
|
119
|
-
},
|
|
120
|
-
apple: {
|
|
121
|
-
enabled: Platform.OS === 'ios',
|
|
122
|
-
},
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
const authConfig: AuthConfig = {
|
|
126
|
-
password: DEFAULT_PASSWORD_CONFIG,
|
|
127
|
-
social: socialAuthConfig,
|
|
128
|
-
};
|
|
129
|
-
```
|
|
55
|
+
### GoogleAuthConfig
|
|
130
56
|
|
|
131
|
-
|
|
57
|
+
**PURPOSE**: Google OAuth configuration
|
|
132
58
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
requireLowercase: true,
|
|
139
|
-
requireNumber: true,
|
|
140
|
-
requireSpecialChar: true,
|
|
141
|
-
},
|
|
142
|
-
social: {
|
|
143
|
-
google: {
|
|
144
|
-
enabled: true,
|
|
145
|
-
webClientId: Config.GOOGLE_WEB_CLIENT_ID,
|
|
146
|
-
iosClientId: Config.GOOGLE_IOS_CLIENT_ID,
|
|
147
|
-
androidClientId: Config.GOOGLE_ANDROID_CLIENT_ID,
|
|
148
|
-
},
|
|
149
|
-
apple: {
|
|
150
|
-
enabled: Platform.OS === 'ios',
|
|
151
|
-
},
|
|
152
|
-
},
|
|
153
|
-
};
|
|
154
|
-
```
|
|
59
|
+
**PROPERTIES**:
|
|
60
|
+
- `enabled?: boolean` - Enable Google auth
|
|
61
|
+
- `webClientId?: string` - Web client ID
|
|
62
|
+
- `iosClientId?: string` - iOS client ID
|
|
63
|
+
- `androidClientId?: string` - Android client ID
|
|
155
64
|
|
|
156
|
-
|
|
65
|
+
**RULES**:
|
|
66
|
+
- MUST provide at least one client ID if enabled
|
|
67
|
+
- MUST use valid OAuth client IDs
|
|
68
|
+
- MUST match Firebase console
|
|
69
|
+
- MUST test before production
|
|
70
|
+
|
|
71
|
+
**MUST NOT**:
|
|
72
|
+
- Enable without client ID
|
|
73
|
+
- Use production keys in development
|
|
74
|
+
- Share client IDs across environments
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
### AppleAuthConfig
|
|
79
|
+
|
|
80
|
+
**PURPOSE**: Apple Sign-In configuration
|
|
81
|
+
|
|
82
|
+
**PROPERTIES**:
|
|
83
|
+
- `enabled?: boolean` - Enable Apple auth
|
|
84
|
+
|
|
85
|
+
**RULES**:
|
|
86
|
+
- MUST only enable on iOS
|
|
87
|
+
- MUST have Apple Developer account
|
|
88
|
+
- MUST configure in Firebase
|
|
89
|
+
- MUST follow Apple guidelines
|
|
90
|
+
|
|
91
|
+
**MUST NOT**:
|
|
92
|
+
- Enable on Android
|
|
93
|
+
- Enable on Web
|
|
94
|
+
- Require as only auth method (Apple rule)
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
### SocialAuthConfig
|
|
99
|
+
|
|
100
|
+
**PURPOSE**: Social auth provider configuration
|
|
101
|
+
|
|
102
|
+
**PROPERTIES**:
|
|
103
|
+
- `google?: GoogleAuthConfig` - Google settings
|
|
104
|
+
- `apple?: AppleAuthConfig` - Apple settings
|
|
105
|
+
|
|
106
|
+
**RULES**:
|
|
107
|
+
- MUST check platform availability
|
|
108
|
+
- MUST configure each provider separately
|
|
109
|
+
- MUST handle provider errors
|
|
110
|
+
- MUST respect platform constraints
|
|
111
|
+
|
|
112
|
+
**PLATFORM CONSTRAINTS**:
|
|
113
|
+
- Google: All platforms
|
|
114
|
+
- Apple: iOS only
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
### AuthConfig
|
|
157
119
|
|
|
120
|
+
**COMPLETE CONFIGURATION**:
|
|
158
121
|
```typescript
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if (__DEV__) {
|
|
163
|
-
// Development: Weak password requirements
|
|
164
|
-
return {
|
|
165
|
-
password: {
|
|
166
|
-
minLength: 6,
|
|
167
|
-
requireUppercase: false,
|
|
168
|
-
requireLowercase: false,
|
|
169
|
-
requireNumber: false,
|
|
170
|
-
requireSpecialChar: false,
|
|
171
|
-
},
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// Production: Strict password requirements
|
|
176
|
-
return {
|
|
177
|
-
password: {
|
|
178
|
-
minLength: 12,
|
|
179
|
-
requireUppercase: true,
|
|
180
|
-
requireLowercase: true,
|
|
181
|
-
requireNumber: true,
|
|
182
|
-
requireSpecialChar: true,
|
|
183
|
-
},
|
|
184
|
-
social: {
|
|
185
|
-
google: {
|
|
186
|
-
enabled: true,
|
|
187
|
-
webClientId: Config.GOOGLE_WEB_CLIENT_ID,
|
|
188
|
-
},
|
|
189
|
-
},
|
|
190
|
-
};
|
|
122
|
+
{
|
|
123
|
+
password: PasswordConfig;
|
|
124
|
+
social?: SocialAuthConfig;
|
|
191
125
|
}
|
|
192
126
|
```
|
|
193
127
|
|
|
128
|
+
**RULES**:
|
|
129
|
+
- MUST provide password config
|
|
130
|
+
- MAY provide social config
|
|
131
|
+
- MUST validate configuration
|
|
132
|
+
- MUST handle missing providers
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Configuration Strategy
|
|
137
|
+
|
|
138
|
+
### Environment-Based Config
|
|
139
|
+
|
|
140
|
+
**DEVELOPMENT**:
|
|
141
|
+
- Lenient password requirements
|
|
142
|
+
- May disable social auth
|
|
143
|
+
- Faster iterations
|
|
144
|
+
|
|
145
|
+
**PRODUCTION**:
|
|
146
|
+
- Strict password requirements
|
|
147
|
+
- Social auth enabled
|
|
148
|
+
- Security-focused
|
|
149
|
+
|
|
150
|
+
**Rules**:
|
|
151
|
+
- MUST use stricter config in production
|
|
152
|
+
- MUST test with production config
|
|
153
|
+
- MUST not use dev config in production
|
|
154
|
+
- MUST validate config on startup
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
194
158
|
### Config Validation
|
|
195
159
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
if (config.minLength > 128) {
|
|
204
|
-
console.error('Minimum length must be at most 128');
|
|
205
|
-
return false;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
return true;
|
|
209
|
-
}
|
|
160
|
+
**VALIDATION RULES**:
|
|
161
|
+
- MUST check password config validity
|
|
162
|
+
- MUST verify social provider IDs
|
|
163
|
+
- MUST ensure platform compatibility
|
|
164
|
+
- MUST throw on invalid config
|
|
210
165
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const errors: string[] = [];
|
|
216
|
-
|
|
217
|
-
if (!validatePasswordConfig(config.password)) {
|
|
218
|
-
errors.push('Invalid password config');
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (config.social?.google?.enabled) {
|
|
222
|
-
if (!config.social.google.webClientId) {
|
|
223
|
-
errors.push('Google webClientId is required when enabled');
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
return {
|
|
228
|
-
valid: errors.length === 0,
|
|
229
|
-
errors,
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
```
|
|
166
|
+
**ERRORS**:
|
|
167
|
+
- Invalid password config
|
|
168
|
+
- Missing required client IDs
|
|
169
|
+
- Platform incompatibility
|
|
233
170
|
|
|
234
171
|
---
|
|
235
172
|
|
|
236
|
-
|
|
173
|
+
## AuthError
|
|
237
174
|
|
|
238
175
|
Domain-specific error classes for authentication.
|
|
239
176
|
|
|
177
|
+
### Strategy
|
|
178
|
+
|
|
179
|
+
**Purpose**: Type-safe error handling with clear error types and user-friendly messages.
|
|
180
|
+
|
|
181
|
+
**When to Use**:
|
|
182
|
+
- Authentication failures
|
|
183
|
+
- Validation errors
|
|
184
|
+
- Network issues
|
|
185
|
+
- Configuration problems
|
|
186
|
+
|
|
187
|
+
**Location**: `src/domain/errors/AuthError.ts`
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
240
191
|
## Error Hierarchy
|
|
241
192
|
|
|
242
193
|
```
|
|
@@ -249,297 +200,211 @@ AuthError (base)
|
|
|
249
200
|
├── AuthWrongPasswordError
|
|
250
201
|
├── AuthEmailAlreadyInUseError
|
|
251
202
|
├── AuthWeakPasswordError
|
|
252
|
-
|
|
203
|
+
�── AuthInvalidEmailError
|
|
253
204
|
```
|
|
254
205
|
|
|
255
|
-
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Error Types
|
|
256
209
|
|
|
257
210
|
### AuthError (Base)
|
|
258
211
|
|
|
259
|
-
|
|
260
|
-
import { AuthError } from '@umituz/react-native-auth';
|
|
212
|
+
**PURPOSE**: Base authentication error
|
|
261
213
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
214
|
+
**RULES**:
|
|
215
|
+
- MUST extend for specific errors
|
|
216
|
+
- MUST include error message
|
|
217
|
+
- MUST have error code
|
|
218
|
+
- MUST be catchable
|
|
219
|
+
|
|
220
|
+
**PROPERTIES**:
|
|
221
|
+
- `message: string` - Error message
|
|
222
|
+
- `code: string` - Error code
|
|
223
|
+
- `name: string` - Error name
|
|
265
224
|
|
|
266
|
-
|
|
225
|
+
---
|
|
267
226
|
|
|
268
|
-
|
|
227
|
+
### AuthUserNotFoundError
|
|
269
228
|
|
|
270
|
-
|
|
271
|
-
import { AuthInitializationError } from '@umituz/react-native-auth';
|
|
229
|
+
**PURPOSE**: User not found error
|
|
272
230
|
|
|
273
|
-
|
|
274
|
-
throw new AuthInitializationError('Auth service not initialized');
|
|
275
|
-
}
|
|
276
|
-
```
|
|
231
|
+
**WHEN THROWN**: Email not found during sign in
|
|
277
232
|
|
|
278
|
-
|
|
233
|
+
**Rules**:
|
|
234
|
+
- MUST indicate user not found
|
|
235
|
+
- MUST not reveal if email exists
|
|
236
|
+
- MUST suggest registration
|
|
279
237
|
|
|
280
|
-
|
|
238
|
+
**USER MESSAGE**: "No user found with this email"
|
|
281
239
|
|
|
282
|
-
|
|
283
|
-
import { AuthConfigurationError } from '@umituz/react-native-auth';
|
|
240
|
+
---
|
|
284
241
|
|
|
285
|
-
|
|
286
|
-
throw new AuthConfigurationError('Google webClientId is required');
|
|
287
|
-
}
|
|
288
|
-
```
|
|
242
|
+
### AuthWrongPasswordError
|
|
289
243
|
|
|
290
|
-
|
|
244
|
+
**PURPOSE**: Incorrect password error
|
|
291
245
|
|
|
292
|
-
|
|
246
|
+
**WHEN THROWN**: Wrong password during sign in
|
|
293
247
|
|
|
294
|
-
|
|
295
|
-
|
|
248
|
+
**Rules**:
|
|
249
|
+
- MUST indicate wrong password
|
|
250
|
+
- MUST not reveal password
|
|
251
|
+
- MUST allow retry
|
|
296
252
|
|
|
297
|
-
|
|
298
|
-
throw new AuthValidationError('Email is required', 'email');
|
|
299
|
-
}
|
|
253
|
+
**USER MESSAGE**: "Incorrect password"
|
|
300
254
|
|
|
301
|
-
|
|
302
|
-
throw new AuthValidationError('Password too short', 'password');
|
|
303
|
-
}
|
|
304
|
-
```
|
|
255
|
+
---
|
|
305
256
|
|
|
306
|
-
###
|
|
257
|
+
### AuthEmailAlreadyInUseError
|
|
307
258
|
|
|
308
|
-
|
|
259
|
+
**PURPOSE**: Email already registered
|
|
309
260
|
|
|
310
|
-
|
|
311
|
-
import { AuthNetworkError } from '@umituz/react-native-auth';
|
|
312
|
-
|
|
313
|
-
try {
|
|
314
|
-
await signIn({ email, password });
|
|
315
|
-
} catch (error) {
|
|
316
|
-
if (error.code === 'auth/network-request-failed') {
|
|
317
|
-
throw new AuthNetworkError('No internet connection');
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
```
|
|
261
|
+
**WHEN THROWN**: Email exists during sign up
|
|
321
262
|
|
|
322
|
-
|
|
263
|
+
**Rules**:
|
|
264
|
+
- MUST indicate email taken
|
|
265
|
+
- MUST suggest sign in
|
|
266
|
+
- MUST offer password reset
|
|
323
267
|
|
|
324
|
-
|
|
268
|
+
**USER MESSAGE**: "Email already registered"
|
|
325
269
|
|
|
326
|
-
|
|
327
|
-
import { AuthUserNotFoundError } from '@umituz/react-native-auth';
|
|
328
|
-
|
|
329
|
-
try {
|
|
330
|
-
await signIn({ email, password });
|
|
331
|
-
} catch (error) {
|
|
332
|
-
if (error.code === 'auth/user-not-found') {
|
|
333
|
-
throw new AuthUserNotFoundError('No user found with this email');
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
```
|
|
270
|
+
---
|
|
337
271
|
|
|
338
|
-
###
|
|
272
|
+
### AuthWeakPasswordError
|
|
339
273
|
|
|
340
|
-
|
|
274
|
+
**PURPOSE**: Password too weak
|
|
341
275
|
|
|
342
|
-
|
|
343
|
-
import { AuthWrongPasswordError } from '@umituz/react-native-auth';
|
|
344
|
-
|
|
345
|
-
try {
|
|
346
|
-
await signIn({ email, password });
|
|
347
|
-
} catch (error) {
|
|
348
|
-
if (error.code === 'auth/wrong-password') {
|
|
349
|
-
throw new AuthWrongPasswordError('Incorrect password');
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
```
|
|
276
|
+
**WHEN THROWN**: Password doesn't meet requirements
|
|
353
277
|
|
|
354
|
-
|
|
278
|
+
**Rules**:
|
|
279
|
+
- MUST indicate weak password
|
|
280
|
+
- MUST show requirements
|
|
281
|
+
- MUST suggest stronger password
|
|
355
282
|
|
|
356
|
-
|
|
283
|
+
**USER MESSAGE**: "Password does not meet requirements"
|
|
357
284
|
|
|
358
|
-
|
|
359
|
-
import { AuthEmailAlreadyInUseError } from '@umituz/react-native-auth';
|
|
360
|
-
|
|
361
|
-
try {
|
|
362
|
-
await signUp({ email, password });
|
|
363
|
-
} catch (error) {
|
|
364
|
-
if (error.code === 'auth/email-already-in-use') {
|
|
365
|
-
throw new AuthEmailAlreadyInUseError('Email already registered');
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
```
|
|
285
|
+
---
|
|
369
286
|
|
|
370
|
-
###
|
|
287
|
+
### AuthInvalidEmailError
|
|
371
288
|
|
|
372
|
-
|
|
289
|
+
**PURPOSE**: Invalid email format
|
|
373
290
|
|
|
374
|
-
|
|
375
|
-
import { AuthWeakPasswordError } from '@umituz/react-native-auth';
|
|
376
|
-
|
|
377
|
-
try {
|
|
378
|
-
await signUp({ email, password });
|
|
379
|
-
} catch (error) {
|
|
380
|
-
if (error.code === 'auth/weak-password') {
|
|
381
|
-
throw new AuthWeakPasswordError('Password is too weak');
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
```
|
|
291
|
+
**WHEN THROWN**: Email validation fails
|
|
385
292
|
|
|
386
|
-
|
|
293
|
+
**Rules**:
|
|
294
|
+
- MUST indicate invalid email
|
|
295
|
+
- MUST suggest valid format
|
|
296
|
+
- MUST not accept malformed email
|
|
387
297
|
|
|
388
|
-
Invalid email
|
|
298
|
+
**USER MESSAGE**: "Invalid email format"
|
|
389
299
|
|
|
390
|
-
|
|
391
|
-
import { AuthInvalidEmailError } from '@umituz/react-native-auth';
|
|
392
|
-
|
|
393
|
-
try {
|
|
394
|
-
await signUp({ email, password });
|
|
395
|
-
} catch (error) {
|
|
396
|
-
if (error.code === 'auth/invalid-email') {
|
|
397
|
-
throw new AuthInvalidEmailError('Invalid email format');
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
```
|
|
300
|
+
---
|
|
401
301
|
|
|
402
|
-
|
|
302
|
+
### AuthNetworkError
|
|
403
303
|
|
|
404
|
-
|
|
405
|
-
import {
|
|
406
|
-
AuthError,
|
|
407
|
-
AuthUserNotFoundError,
|
|
408
|
-
AuthWrongPasswordError,
|
|
409
|
-
AuthEmailAlreadyInUseError,
|
|
410
|
-
AuthWeakPasswordError,
|
|
411
|
-
AuthInvalidEmailError,
|
|
412
|
-
AuthNetworkError,
|
|
413
|
-
} from '@umituz/react-native-auth';
|
|
304
|
+
**PURPOSE**: Network connection failure
|
|
414
305
|
|
|
415
|
-
|
|
416
|
-
const code = error.code;
|
|
306
|
+
**WHEN THROWN**: Network request fails
|
|
417
307
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
308
|
+
**Rules**:
|
|
309
|
+
- MUST indicate network problem
|
|
310
|
+
- MUST suggest checking connection
|
|
311
|
+
- MUST allow retry
|
|
421
312
|
|
|
422
|
-
|
|
423
|
-
return new AuthWrongPasswordError('Incorrect password');
|
|
313
|
+
**USER MESSAGE**: "Network error. Please check your connection"
|
|
424
314
|
|
|
425
|
-
|
|
426
|
-
return new AuthEmailAlreadyInUseError('Email already registered');
|
|
315
|
+
---
|
|
427
316
|
|
|
428
|
-
|
|
429
|
-
return new AuthWeakPasswordError('Password is too weak');
|
|
317
|
+
## Error Handling
|
|
430
318
|
|
|
431
|
-
|
|
432
|
-
return new AuthInvalidEmailError('Invalid email format');
|
|
319
|
+
### Error Mapping
|
|
433
320
|
|
|
434
|
-
|
|
435
|
-
|
|
321
|
+
**FIREBASE TO DOMAIN ERRORS**:
|
|
322
|
+
- `auth/user-not-found` → AuthUserNotFoundError
|
|
323
|
+
- `auth/wrong-password` → AuthWrongPasswordError
|
|
324
|
+
- `auth/email-already-in-use` → AuthEmailAlreadyInUseError
|
|
325
|
+
- `auth/weak-password` → AuthWeakPasswordError
|
|
326
|
+
- `auth/invalid-email` → AuthInvalidEmailError
|
|
327
|
+
- `auth/network-request-failed` → AuthNetworkError
|
|
436
328
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
329
|
+
**RULES**:
|
|
330
|
+
- MUST map Firebase errors to domain errors
|
|
331
|
+
- MUST preserve error context
|
|
332
|
+
- MUST throw domain errors (not Firebase)
|
|
333
|
+
- MUST handle unknown errors
|
|
441
334
|
|
|
442
|
-
|
|
443
|
-
try {
|
|
444
|
-
await signInWithEmailAndPassword(auth, email, password);
|
|
445
|
-
} catch (error) {
|
|
446
|
-
const authError = mapFirebaseError(error);
|
|
447
|
-
throw authError;
|
|
448
|
-
}
|
|
449
|
-
```
|
|
335
|
+
---
|
|
450
336
|
|
|
451
|
-
|
|
337
|
+
### Error Type Guards
|
|
452
338
|
|
|
453
|
-
|
|
454
|
-
async function handleSignIn(email: string, password: string) {
|
|
455
|
-
try {
|
|
456
|
-
await signIn({ email, password });
|
|
457
|
-
} catch (error) {
|
|
458
|
-
if (error instanceof AuthUserNotFoundError) {
|
|
459
|
-
Alert.alert('Error', 'No user found with this email');
|
|
460
|
-
} else if (error instanceof AuthWrongPasswordError) {
|
|
461
|
-
Alert.alert('Error', 'Incorrect password');
|
|
462
|
-
} else if (error instanceof AuthNetworkError) {
|
|
463
|
-
Alert.alert('Error', 'Check your internet connection');
|
|
464
|
-
} else if (error instanceof AuthError) {
|
|
465
|
-
Alert.alert('Error', error.message);
|
|
466
|
-
} else {
|
|
467
|
-
Alert.alert('Error', 'An unexpected error occurred');
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
```
|
|
339
|
+
**PURPOSE**: Type-safe error checking
|
|
472
340
|
|
|
473
|
-
|
|
341
|
+
**FUNCTIONS**:
|
|
342
|
+
- `isAuthError(error)` - Check if AuthError
|
|
343
|
+
- `isValidationError(error)` - Check if validation error
|
|
474
344
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
345
|
+
**RULES**:
|
|
346
|
+
- MUST use for type narrowing
|
|
347
|
+
- MUST check before error handling
|
|
348
|
+
- MUST use in catch blocks
|
|
479
349
|
|
|
480
|
-
|
|
481
|
-
return error instanceof AuthValidationError;
|
|
482
|
-
}
|
|
350
|
+
---
|
|
483
351
|
|
|
484
|
-
|
|
485
|
-
try {
|
|
486
|
-
await signUp({ email, password });
|
|
487
|
-
} catch (error) {
|
|
488
|
-
if (isValidationError(error)) {
|
|
489
|
-
console.log('Field:', error.field);
|
|
490
|
-
console.log('Message:', error.message);
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
```
|
|
352
|
+
### User Messages
|
|
494
353
|
|
|
495
|
-
|
|
354
|
+
**STRATEGY**: User-friendly error messages
|
|
496
355
|
|
|
497
|
-
|
|
498
|
-
|
|
356
|
+
**RULES**:
|
|
357
|
+
- MUST be clear and simple
|
|
358
|
+
- MUST avoid technical jargon
|
|
359
|
+
- MUST suggest resolution
|
|
360
|
+
- MUST not expose system details
|
|
499
361
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
362
|
+
**MUST NOT**:
|
|
363
|
+
- Expose error codes
|
|
364
|
+
- Show stack traces
|
|
365
|
+
- Reveal sensitive information
|
|
366
|
+
- Use technical language
|
|
504
367
|
|
|
505
|
-
|
|
506
|
-
try {
|
|
507
|
-
await signIn({ email, password });
|
|
508
|
-
} catch (error) {
|
|
509
|
-
if (error instanceof AuthError) {
|
|
510
|
-
const message = getErrorMessage(error);
|
|
511
|
-
Alert.alert('Error', message);
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
```
|
|
368
|
+
---
|
|
515
369
|
|
|
516
|
-
##
|
|
370
|
+
## Configuration Defaults
|
|
517
371
|
|
|
518
|
-
|
|
519
|
-
import { AuthError } from '@umituz/react-native-auth';
|
|
372
|
+
### Default Password Config
|
|
520
373
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
this.name = 'AuthTooManyAttemptsError';
|
|
525
|
-
}
|
|
526
|
-
}
|
|
374
|
+
**MINIMAL SECURITY**:
|
|
375
|
+
- minLength: 6
|
|
376
|
+
- All requirements: false
|
|
527
377
|
|
|
528
|
-
|
|
529
|
-
constructor(message = 'Account is locked') {
|
|
530
|
-
super(message, 'AUTH_ACCOUNT_LOCKED');
|
|
531
|
-
this.name = 'AuthAccountLockedError';
|
|
532
|
-
}
|
|
533
|
-
}
|
|
378
|
+
**USE CASE**: Development/testing only
|
|
534
379
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
### Default Social Config
|
|
383
|
+
|
|
384
|
+
**DISABLED BY DEFAULT**:
|
|
385
|
+
- google: { enabled: false }
|
|
386
|
+
- apple: { enabled: false }
|
|
387
|
+
|
|
388
|
+
**USE CASE**: Explicit enable required
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
### Default Auth Config
|
|
393
|
+
|
|
394
|
+
**COMBINATION**:
|
|
395
|
+
- password: DEFAULT_PASSWORD_CONFIG
|
|
396
|
+
- social: DEFAULT_SOCIAL_CONFIG
|
|
397
|
+
|
|
398
|
+
**USE CASE**: Starting configuration
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
## Related Entities
|
|
403
|
+
|
|
404
|
+
- **AuthUser** (`./entities/AuthUser.md`) - User entity
|
|
405
|
+
- **UserProfile** (`./entities/UserProfile.md`) - Profile entity
|
|
540
406
|
|
|
541
|
-
## Related
|
|
407
|
+
## Related Infrastructure
|
|
542
408
|
|
|
543
|
-
- **
|
|
544
|
-
- **
|
|
545
|
-
- **[Validation Utils](../../infrastructure/utils/AuthValidation.ts)** - Validation utilities
|
|
409
|
+
- **AuthValidation** (`../../infrastructure/utils/AuthValidation.ts`) - Validation utilities
|
|
410
|
+
- **AuthService** (`../../infrastructure/services/AuthService.ts`) - Auth operations
|