@umituz/react-native-auth 3.4.36 → 3.4.38

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-auth",
3
- "version": "3.4.36",
3
+ "version": "3.4.38",
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",
package/src/index.ts CHANGED
@@ -151,8 +151,6 @@ export type { SocialAuthConfiguration } from './presentation/hooks/useAuthBottom
151
151
 
152
152
  // DOMAIN ENTITIES & UTILS
153
153
  export type { UserProfile, UpdateProfileParams } from './domain/entities/UserProfile';
154
- export { generateAnonymousName, getAnonymousDisplayName } from './domain/utils/anonymousNameGenerator';
155
- export type { AnonymousNameConfig } from './domain/utils/anonymousNameGenerator';
156
154
  export { migrateUserData, configureMigration } from './domain/utils/migration';
157
155
  export type { MigrationConfig } from './domain/utils/migration';
158
156
 
@@ -4,7 +4,7 @@ import { ValidationResult } from './types';
4
4
  * Validate required field (not null, undefined, or empty string)
5
5
  */
6
6
  export const validateRequired = (
7
- value: any,
7
+ value: unknown,
8
8
  fieldName: string = "Field",
9
9
  errorKey?: string
10
10
  ): ValidationResult => {
@@ -17,7 +17,7 @@ export const ProfileBenefitsList: React.FC<ProfileBenefitsListProps> = ({ benefi
17
17
  <View style={styles.benefitsContainer}>
18
18
  {benefits.map((benefit, index) => (
19
19
  <View key={index} style={styles.benefitItem}>
20
- <AtomicIcon name="Check" size="sm" color="primary" />
20
+ <AtomicIcon name="checkmark-circle" size="sm" color="primary" />
21
21
  <AtomicText
22
22
  type="bodyMedium"
23
23
  color="secondary"
@@ -1,59 +1,52 @@
1
1
  /**
2
2
  * useUserProfile Hook
3
- * Generic hook for user profile configuration
4
3
  * Returns profile data for display in settings or profile screens
5
4
  */
6
5
 
7
6
  import { useMemo } from "react";
8
7
  import { useAuth } from "./useAuth";
9
- import { generateAnonymousName, type AnonymousNameConfig } from "../../domain/utils/anonymousNameGenerator";
10
8
 
11
9
  export interface UserProfileData {
12
- displayName?: string;
13
- userId?: string;
14
- isAnonymous: boolean;
15
- avatarUrl?: string;
16
- accountSettingsRoute?: string;
17
- benefits?: string[];
10
+ displayName?: string;
11
+ userId?: string;
12
+ isAnonymous: boolean;
13
+ avatarUrl?: string;
14
+ accountSettingsRoute?: string;
15
+ benefits?: string[];
18
16
  }
19
17
 
20
18
  export interface UseUserProfileParams {
21
- anonymousDisplayName?: string;
22
- accountRoute?: string;
23
- anonymousNameConfig?: AnonymousNameConfig;
19
+ anonymousDisplayName?: string;
20
+ accountRoute?: string;
24
21
  }
25
22
 
26
23
  export const useUserProfile = (
27
- params?: UseUserProfileParams,
24
+ params?: UseUserProfileParams,
28
25
  ): UserProfileData | undefined => {
29
- const { user } = useAuth();
30
-
31
- const anonymousName = params?.anonymousDisplayName;
32
- const accountRoute = params?.accountRoute;
33
- const nameConfig = params?.anonymousNameConfig;
34
-
35
- return useMemo(() => {
36
- if (!user) {
37
- return undefined;
38
- }
39
-
40
- const isAnonymous = user.isAnonymous || false;
41
-
42
- if (isAnonymous) {
43
- return {
44
- displayName: generateAnonymousName(user.uid, nameConfig),
45
- userId: user.uid,
46
- isAnonymous: true,
47
- accountSettingsRoute: accountRoute,
48
- };
49
- }
50
-
51
- return {
52
- accountSettingsRoute: accountRoute,
53
- displayName: user.displayName || user.email || anonymousName,
54
- userId: user.uid,
55
- isAnonymous: false,
56
- avatarUrl: user.photoURL || undefined,
57
- };
58
- }, [user, anonymousName, accountRoute, nameConfig]);
26
+ const { user } = useAuth();
27
+ const anonymousName = params?.anonymousDisplayName ?? "Anonymous User";
28
+ const accountRoute = params?.accountRoute;
29
+
30
+ return useMemo(() => {
31
+ if (!user) return undefined;
32
+
33
+ const isAnonymous = user.isAnonymous || false;
34
+
35
+ if (isAnonymous) {
36
+ return {
37
+ displayName: anonymousName,
38
+ userId: user.uid,
39
+ isAnonymous: true,
40
+ accountSettingsRoute: accountRoute,
41
+ };
42
+ }
43
+
44
+ return {
45
+ accountSettingsRoute: accountRoute,
46
+ displayName: user.displayName || user.email || anonymousName,
47
+ userId: user.uid,
48
+ isAnonymous: false,
49
+ avatarUrl: user.photoURL || undefined,
50
+ };
51
+ }, [user, anonymousName, accountRoute]);
59
52
  };
@@ -17,6 +17,7 @@ export interface AccountScreenConfig {
17
17
  isAnonymous: boolean;
18
18
  editProfileText?: string;
19
19
  onEditProfile?: () => void;
20
+ onSignIn?: () => void;
20
21
  }
21
22
 
22
23
  export interface AccountScreenProps {
@@ -26,12 +27,6 @@ export interface AccountScreenProps {
26
27
  export const AccountScreen: React.FC<AccountScreenProps> = ({ config }) => {
27
28
  const tokens = useAppDesignTokens();
28
29
 
29
- const handleLogout = () => {
30
- if (config.accountActions?.onLogout) {
31
- void config.accountActions.onLogout();
32
- }
33
- };
34
-
35
30
  return (
36
31
  <ScreenLayout
37
32
  scrollable={true}
@@ -41,7 +36,7 @@ export const AccountScreen: React.FC<AccountScreenProps> = ({ config }) => {
41
36
  >
42
37
  <ProfileSection
43
38
  profile={config.profile}
44
- onSignIn={config.profile.isAnonymous ? handleLogout : undefined}
39
+ onSignIn={config.isAnonymous ? config.onSignIn : undefined}
45
40
  signInText="Sign In"
46
41
  />
47
42
 
@@ -1,444 +0,0 @@
1
- # Domain Layer
2
-
3
- Core business logic, domain entities, value objects, and domain rules.
4
-
5
- ---
6
-
7
- ## Strategy
8
-
9
- **Purpose**: Contains business rules and domain models independent of external dependencies. Represents the core authentication logic.
10
-
11
- **When to Use**:
12
- - Understanding business rules
13
- - Working with domain entities
14
- - Implementing validation
15
- - Learning about data structures
16
-
17
- **Location**: `src/domain/`
18
-
19
- ---
20
-
21
- ## Structure
22
-
23
- ### Entities
24
-
25
- **entities/AuthUser.ts** - Provider-agnostic user entity
26
- **entities/UserProfile.ts** - User profile for Firestore
27
-
28
- ### Value Objects
29
-
30
- **value-objects/AuthConfig.ts** - Authentication configuration
31
-
32
- ### Errors
33
-
34
- **errors/AuthError.ts** - Domain-specific error hierarchy
35
-
36
- ### Utils
37
-
38
- **utils/anonymousNameGenerator.ts** - Anonymous name generation
39
- **utils/migration.ts** - Data migration utilities
40
-
41
- ---
42
-
43
- ## Domain Entities
44
-
45
- ### AuthUser
46
-
47
- **PURPOSE**: Provider-agnostic user entity for authentication
48
-
49
- **IMPORT PATH**:
50
- ```typescript
51
- import type { AuthUser } from '@umituz/react-native-auth';
52
- ```
53
-
54
- **PROPERTIES**:
55
- - `uid: string` - Unique user identifier
56
- - `email: string | null` - Email address
57
- - `displayName: string | null` - Display name
58
- - `photoURL: string | null` - Profile photo URL
59
- - `isAnonymous: boolean` - Anonymous flag
60
- - `emailVerified: boolean` - Email verification status
61
- - `provider: AuthProviderType` - Auth provider type
62
-
63
- **Rules**:
64
- - MUST have unique uid
65
- - MUST NOT have empty uid
66
- - Anonymous users have null email
67
- - Provider indicates auth method
68
- - Email can be null for social auth
69
-
70
- **MUST NOT**:
71
- - Allow empty uid
72
- - Change uid after creation
73
- - Have anonymous user with email
74
- - Use invalid provider type
75
-
76
- **Documentation**: `entities/AuthUser.md`
77
-
78
- ---
79
-
80
- ### UserProfile
81
-
82
- **PURPOSE**: User profile entity for Firestore document storage
83
-
84
- **IMPORT PATH**:
85
- ```typescript
86
- import type { UserProfile } from '@umituz/react-native-auth';
87
- ```
88
-
89
- **PROPERTIES**:
90
- - `uid: string` - User ID
91
- - `email: string | null` - Email address
92
- - `displayName: string | null` - Display name
93
- - `photoURL: string | null` - Profile photo URL
94
- - `isAnonymous: boolean` - Anonymous flag
95
- - `createdAt: Date | null` - Account creation date
96
- - `lastLoginAt: Date | null` - Last login timestamp
97
-
98
- **Rules**:
99
- - MUST create on user registration
100
- - MUST include uid
101
- - MUST set initial timestamps
102
- - MUST validate updates
103
- - MUST handle partial updates
104
-
105
- **MUST NOT**:
106
- - Delete existing profiles
107
- - Skip validation
108
- - Use client timestamps
109
- - Overwrite without checking
110
-
111
- **Documentation**: `entities/UserProfile.md`
112
-
113
- ---
114
-
115
- ## Value Objects
116
-
117
- ### AuthConfig
118
-
119
- **PURPOSE**: Authentication configuration value object
120
-
121
- **IMPORT PATH**:
122
- ```typescript
123
- import type { AuthConfig } from '@umituz/react-native-auth';
124
- ```
125
-
126
- **COMPONENTS**:
127
- - `password: PasswordConfig` - Password requirements
128
- - `social?: SocialAuthConfig` - Social provider config
129
-
130
- **PasswordConfig**:
131
- - `minLength: number` - Minimum password length
132
- - `requireUppercase: boolean` - Require uppercase
133
- - `requireLowercase: boolean` - Require lowercase
134
- - `requireNumber: boolean` - Require number
135
- - `requireSpecialChar: boolean` - Require special character
136
-
137
- **Rules**:
138
- - MUST set minLength between 4-128
139
- - MUST validate password against config
140
- - MUST provide password config
141
- - MAY provide social config
142
-
143
- **MUST NOT**:
144
- - Set minLength < 4
145
- - Set minLength > 128
146
- - Skip validation
147
-
148
- **Documentation**: `ConfigAndErrors.md`
149
-
150
- ---
151
-
152
- ## Domain Errors
153
-
154
- ### AuthError Hierarchy
155
-
156
- **PURPOSE**: Type-safe error handling with clear error types
157
-
158
- **IMPORT PATH**:
159
- ```typescript
160
- import {
161
- AuthError,
162
- AuthUserNotFoundError,
163
- AuthWrongPasswordError,
164
- AuthEmailAlreadyInUseError,
165
- AuthWeakPasswordError,
166
- AuthInvalidEmailError,
167
- AuthNetworkError
168
- } from '@umituz/react-native-auth';
169
- ```
170
-
171
- **ERROR TYPES**:
172
- - `AuthUserNotFoundError` - User not found
173
- - `AuthWrongPasswordError` - Incorrect password
174
- - `AuthEmailAlreadyInUseError` - Email already registered
175
- - `AuthWeakPasswordError` - Password too weak
176
- - `AuthInvalidEmailError` - Invalid email format
177
- - `AuthNetworkError` - Network connection failure
178
-
179
- **Rules**:
180
- - MUST use domain errors (not Firebase)
181
- - MUST map Firebase errors to domain
182
- - MUST preserve error context
183
- - MUST show user-friendly messages
184
- - MUST not expose system details
185
-
186
- **MUST NOT**:
187
- - Throw Firebase errors directly
188
- - Expose error codes
189
- - Show stack traces
190
- - Reveal sensitive information
191
-
192
- **Documentation**: `ConfigAndErrors.md`
193
-
194
- ---
195
-
196
- ## Domain Utilities
197
-
198
- ### Anonymous Name Generator
199
-
200
- **PURPOSE**: Generate random names for anonymous users
201
-
202
- **IMPORT PATH**:
203
- ```typescript
204
- import {
205
- generateAnonymousName,
206
- getAnonymousDisplayName
207
- } from '@umituz/react-native-auth';
208
- ```
209
-
210
- **FUNCTIONS**:
211
- - `generateAnonymousName(uid, config?)` - Generate anonymous name
212
- - `getAnonymousDisplayName(uid)` - Get display name only
213
-
214
- **CONFIGURATION**:
215
- - `prefix` - Name prefix (default: 'User')
216
- - `adjectiveCount` - Number of adjectives (default: 2)
217
- - `nounCount` - Number of nouns (default: 1)
218
- - `showNumbers` - Include numbers (default: true)
219
-
220
- **Rules**:
221
- - MUST be deterministic for same uid
222
- - MUST generate unique names
223
- - MUST be human-readable
224
- - MUST not contain offensive words
225
- - MUST support custom configuration
226
-
227
- **MUST NOT**:
228
- - Generate duplicate names
229
- - Use offensive language
230
- - Be non-deterministic
231
- - Ignore configuration
232
-
233
- ---
234
-
235
- ### Migration Utilities
236
-
237
- **PURPOSE**: Migrate user data between collections
238
-
239
- **IMPORT PATH**:
240
- ```typescript
241
- import {
242
- migrateUserData,
243
- configureMigration
244
- } from '@umituz/react-native-auth';
245
- ```
246
-
247
- **FUNCTIONS**:
248
- - `configureMigration(config)` - Configure migration
249
- - `migrateUserData(userId)` - Run migration
250
-
251
- **CONFIGURATION**:
252
- - `from` - Source collection name
253
- - `to` - Target collection name
254
- - `transform` - Data transformation function
255
- - `verify` - Verification function (optional)
256
-
257
- **Rules**:
258
- - MUST configure before migrating
259
- - MUST transform data correctly
260
- - MUST handle migration errors
261
- - MUST verify migration success
262
- - MUST not delete source automatically
263
-
264
- **MUST NOT**:
265
- - Skip configuration
266
- - Lose data during migration
267
- - Assume identical schemas
268
- - Delete source without verification
269
-
270
- ---
271
-
272
- ## Type Guards
273
-
274
- ### User Type Guards
275
-
276
- **PURPOSE**: Type-safe user checking
277
-
278
- **IMPORT PATH**:
279
- ```typescript
280
- import {
281
- isAuthenticatedUser,
282
- isAnonymousUser,
283
- hasEmail
284
- } from '@umituz/react-native-auth';
285
- ```
286
-
287
- **GUARDS**:
288
- - `isAuthenticatedUser(user)` - Check if authenticated user
289
- - `isAnonymousUser(user)` - Check if anonymous user
290
- - `hasEmail(user)` - Check if has email
291
-
292
- **Rules**:
293
- - MUST use for type narrowing
294
- - MUST validate before operations
295
- - MUST check null cases
296
- - MUST return boolean
297
-
298
- **MUST NOT**:
299
- - Skip type guards
300
- - Assume user type
301
- - Skip null checks
302
- - Return non-boolean
303
-
304
- ---
305
-
306
- ## Domain Rules
307
-
308
- ### AuthUser Rules
309
-
310
- **MUST**:
311
- - Have unique uid
312
- - Validate uid not empty
313
- - Validate email format if provided
314
- - Check provider is valid
315
- - Verify required fields
316
-
317
- **MUST NOT**:
318
- - Allow empty uid
319
- - Accept invalid email
320
- - Use wrong provider type
321
- - Have anonymous user with email
322
-
323
- **Constraints**:
324
- - uid required
325
- - Email format validated
326
- - Provider must be known type
327
- - Anonymous users have null email
328
-
329
- ---
330
-
331
- ### UserProfile Rules
332
-
333
- **MUST**:
334
- - Validate display name 2-50 characters
335
- - Validate photo URL format
336
- - Use server timestamps
337
- - Handle partial updates
338
- - Preserve existing data
339
-
340
- **MUST NOT**:
341
- - Allow display name < 2 chars
342
- - Accept invalid URLs
343
- - Use client timestamps
344
- - Overwrite existing data
345
-
346
- **Constraints**:
347
- - Display name min 2, max 100 chars
348
- - Cannot be only whitespace
349
- - Valid URL required for photoURL
350
- - One profile per uid
351
-
352
- ---
353
-
354
- ### Password Rules
355
-
356
- **MUST**:
357
- - Enforce minimum length
358
- - Check uppercase if required
359
- - Check lowercase if required
360
- - Check number if required
361
- - Check special char if required
362
-
363
- **MUST NOT**:
364
- - Allow weak passwords
365
- - Skip validation checks
366
- - Accept passwords below minimum
367
-
368
- **Constraints**:
369
- - Minimum length: 4-128 chars
370
- - Requirements configurable
371
- - All requirements optional
372
- - Default min length: 6 (lenient)
373
-
374
- ---
375
-
376
- ## Best Practices
377
-
378
- ### Entity Usage
379
-
380
- **MUST**:
381
- - Use type guards for type narrowing
382
- - Validate before operations
383
- - Handle null values appropriately
384
- - Follow domain rules
385
- - Use proper error types
386
-
387
- **MUST NOT**:
388
- - Skip validation
389
- - Assume required fields present
390
- - Ignore null cases
391
- - Use generic error types
392
- - Break domain rules
393
-
394
- ---
395
-
396
- ### Error Handling
397
-
398
- **MUST**:
399
- - Use domain error types
400
- - Map provider errors to domain
401
- - Provide context
402
- - Show user-friendly messages
403
- - Preserve error information
404
-
405
- **MUST NOT**:
406
- - Throw provider errors
407
- - Expose technical details
408
- - Lose error context
409
- - Show stack traces
410
- - Reveal sensitive data
411
-
412
- ---
413
-
414
- ### Configuration
415
-
416
- **MUST**:
417
- - Validate configuration
418
- - Use appropriate defaults
419
- - Test with production config
420
- - Not use dev config in production
421
-
422
- **MUST NOT**:
423
- - Skip validation
424
- - Use invalid config
425
- - Ignore environment differences
426
- - Hardcode production values
427
-
428
- ---
429
-
430
- ## Related Modules
431
-
432
- - **Application** (`../application/README.md`) - Ports and interfaces
433
- - **Infrastructure** (`../infrastructure/README.md`) - Implementations
434
- - **Presentation** (`../presentation/README.md`) - UI components
435
-
436
- ---
437
-
438
- ## Entity Documentation
439
-
440
- ### Detailed Entity Docs
441
-
442
- **AuthUser**: `entities/AuthUser.md`
443
- **UserProfile**: `entities/UserProfile.md`
444
- **AuthConfig & AuthError**: `ConfigAndErrors.md`
@@ -1,79 +0,0 @@
1
- /**
2
- * Anonymous User Name Generator
3
- * Generates friendly, random names for anonymous users
4
- * Fully generic - no app-specific content
5
- */
6
-
7
- const DEFAULT_NAMES = [
8
- 'Alex',
9
- 'Sam',
10
- 'Jordan',
11
- 'Taylor',
12
- 'Morgan',
13
- 'Casey',
14
- 'Riley',
15
- 'Avery',
16
- 'Quinn',
17
- 'Blake',
18
- 'Charlie',
19
- 'Dakota',
20
- 'Eden',
21
- 'Finley',
22
- 'Harper',
23
- 'Sage',
24
- 'River',
25
- 'Skylar',
26
- 'Rowan',
27
- 'Phoenix',
28
- ];
29
-
30
- export interface AnonymousNameConfig {
31
- names?: string[];
32
- prefixes?: string[];
33
- usePrefixes?: boolean;
34
- }
35
-
36
- /**
37
- * Generate a random anonymous name
38
- * Uses userId to ensure consistency per user
39
- */
40
- export function generateAnonymousName(
41
- userId?: string,
42
- config?: AnonymousNameConfig,
43
- ): string {
44
- const names = config?.names || DEFAULT_NAMES;
45
- const prefixes = config?.prefixes || [];
46
- const usePrefixes = config?.usePrefixes ?? false;
47
-
48
- if (!userId) {
49
- const randomIndex = Math.floor(Math.random() * names.length);
50
- return names[randomIndex] ?? "Anonymous";
51
- }
52
-
53
- // Use userId hash for consistent name per user
54
- const hash = userId.split('').reduce((acc, char) => {
55
- return ((acc << 5) - acc + char.charCodeAt(0)) | 0;
56
- }, 0);
57
-
58
- const nameIndex = Math.abs(hash) % names.length;
59
- const name = names[nameIndex] ?? "Anonymous";
60
-
61
- if (usePrefixes && prefixes.length > 0) {
62
- const prefixIndex = Math.abs(hash >> 8) % prefixes.length;
63
- return `${prefixes[prefixIndex]} ${name}`;
64
- }
65
-
66
- return name;
67
- }
68
-
69
- /**
70
- * Get anonymous display name with fallback
71
- */
72
- export function getAnonymousDisplayName(
73
- userId?: string,
74
- fallback = 'Anonymous',
75
- config?: AnonymousNameConfig,
76
- ): string {
77
- if (!userId) return fallback;
78
- return generateAnonymousName(userId, config);
79
- }
@@ -1,297 +0,0 @@
1
- # useUserProfile
2
-
3
- Hook for fetching and displaying user profile data.
4
-
5
- ---
6
-
7
- ## Strategy
8
-
9
- **Purpose**: Provides formatted user profile data for display in UI components. Handles authenticated vs anonymous user differences automatically.
10
-
11
- **When to Use**:
12
- - Displaying user profile information
13
- - Need user display name and avatar
14
- - Showing account settings links
15
- - Differentiating authenticated vs anonymous users
16
- - Profile headers or user identification
17
-
18
- **Import Path**:
19
- ```typescript
20
- import { useUserProfile } from '@umituz/react-native-auth';
21
- ```
22
-
23
- **Hook Location**: `src/presentation/hooks/useUserProfile.ts`
24
-
25
- ---
26
-
27
- ## Return Value
28
-
29
- ### UserProfileData Structure
30
-
31
- **PROPERTIES**:
32
- - `displayName: string` - User's display name or generated name
33
- - `userId: string` - User ID (undefined for anonymous)
34
- - `isAnonymous: boolean` - Anonymous user status
35
- - `avatarUrl: string | undefined` - Profile photo URL
36
- - `accountSettingsRoute: string | undefined` - Navigation route for settings
37
-
38
- **RETURNS**: `UserProfileData | undefined`
39
- - `undefined` if no user exists
40
- - Object with above properties if user exists
41
-
42
- **Rules**:
43
- - MUST handle `undefined` return value
44
- - MUST check `isAnonymous` before showing account actions
45
- - MUST provide fallback for missing avatar
46
- - MUST NOT assume all properties exist
47
-
48
- **Constraints**:
49
- - Memoized for performance
50
- - Auto-updates on auth state changes
51
- - Generates names for anonymous users
52
- - Uses `useAuth` hook internally
53
-
54
- ---
55
-
56
- ## Parameters
57
-
58
- ### Configuration Options
59
-
60
- **anonymousDisplayName** (optional)
61
- - Type: `string`
62
- - Default: `undefined`
63
- - Purpose: Fallback name for anonymous users
64
- - Used when: Anonymous user has no custom name
65
-
66
- **accountRoute** (optional)
67
- - Type: `string`
68
- - Default: `undefined`
69
- - Purpose: Navigation route for account settings
70
- - Used when: Need to navigate to settings
71
-
72
- **anonymousNameConfig** (optional)
73
- - Type: `AnonymousNameConfig`
74
- - Default: `undefined`
75
- - Purpose: Customize anonymous name generation
76
- - Used when: Want custom anonymous naming
77
-
78
- **Rules**:
79
- - SHOULD provide `accountRoute` for profile editing
80
- - MAY provide `anonymousDisplayName` for better UX
81
- - MAY customize `anonymousNameConfig` for branding
82
-
83
- **Constraints**:
84
- - All parameters optional
85
- - Configuration affects return values
86
- - Changes trigger re-calculation
87
-
88
- ---
89
-
90
- ## Anonymous User Handling
91
-
92
- ### Strategy
93
-
94
- **Purpose**: Automatically generate appropriate names for anonymous users.
95
-
96
- **Rules**:
97
- - MUST generate random name for anonymous users
98
- - MUST indicate anonymous status clearly
99
- - SHOULD encourage account creation
100
- - MUST NOT hide anonymous nature
101
-
102
- **MUST NOT**:
103
- - Show anonymous users as authenticated
104
- - Use misleading names for anonymous users
105
- - Hide anonymous limitations
106
-
107
- ### Constraints
108
-
109
- **NAME GENERATION**:
110
- - Default format: "User_Witty_Badger_1234"
111
- - Components: Prefix + Adjectives + Noun + ID
112
- - Ensures uniqueness with user ID
113
- - Memoized per anonymous user
114
-
115
- **CUSTOMIZATION**:
116
- ```typescript
117
- anonymousNameConfig = {
118
- prefix: string; // Default: "User"
119
- adjectiveCount: number; // Default: 2
120
- nounCount: number; // Default: 1
121
- }
122
- ```
123
-
124
- **DISPLAY STRATEGY**:
125
- - Always show generated name
126
- - Indicate guest status
127
- - Offer upgrade path
128
- - Preserve name across sessions
129
-
130
- ---
131
-
132
- ## Performance Optimization
133
-
134
- ### Strategy
135
-
136
- **Purpose**: Efficient profile data computation and updates.
137
-
138
- **Rules**:
139
- - MUST memoize computed profile data
140
- - MUST minimize re-computations
141
- - MUST use dependency arrays correctly
142
- - MUST avoid unnecessary recalculations
143
-
144
- **Constraints**:
145
- - Uses `useMemo` internally
146
- - Only recalculates when dependencies change
147
- - Dependencies: user object, config params
148
- - No unnecessary re-renders
149
-
150
- **OPTIMIZATION TECHNIQUES**:
151
- - Memoized anonymous name generation
152
- - Cached avatar URL processing
153
- - Efficient auth state subscription
154
- - Minimal prop drilling
155
-
156
- ---
157
-
158
- ## Avatar Handling
159
-
160
- ### Strategy
161
-
162
- **Purpose**: Proper display of user profile photos with fallbacks.
163
-
164
- **Rules**:
165
- - MUST handle missing/invalid avatar URLs
166
- - MUST provide fallback avatar
167
- - MUST NOT break on missing photos
168
- - SHOULD show placeholder or initials
169
-
170
- **MUST NOT**:
171
- - Show broken image icons
172
- - Crash on invalid URLs
173
- - Leave avatar space empty
174
-
175
- ### Constraints
176
-
177
- **AVATAR URLS**:
178
- - From Firebase user.photoURL
179
- - May be `null` or `undefined`
180
- - May be invalid URL
181
- - Should be validated before display
182
-
183
- **FALLBACK OPTIONS**:
184
- - Show user initials
185
- - Show generic avatar icon
186
- - Use placeholder image
187
- - Generate colored placeholder with initials
188
-
189
- **DISPLAY RULES**:
190
- - Use `avatarUrl` if valid and present
191
- - Fallback to initials placeholder
192
- - Default to generic icon
193
- - Consistent sizing across app
194
-
195
- ---
196
-
197
- ## Navigation Integration
198
-
199
- ### Strategy
200
-
201
- **Purpose**: Provide navigation paths for profile-related actions.
202
-
203
- **Rules**:
204
- - SHOULD provide `accountRoute` parameter
205
- - MUST handle navigation in parent component
206
- - MUST NOT hardcode navigation paths
207
- - MUST support different navigation patterns
208
-
209
- **Constraints**:
210
-
211
- **ROUTE HANDLING**:
212
- - `accountRoute` passed through to return value
213
- - Parent component uses route for navigation
214
- - Supports string routes or navigation objects
215
- - Compatible with React Navigation
216
-
217
- **INTEGRATION PATTERNS**:
218
- - Navigate to account settings on press
219
- - Pass route to navigation component
220
- - Handle deep linking if needed
221
- - Support custom navigation handlers
222
-
223
- ---
224
-
225
- ## Security & Privacy
226
-
227
- ### Strategy
228
-
229
- **Purpose**: Protect user information while displaying profile.
230
-
231
- **Rules**:
232
- - MUST NOT display full user ID in UI
233
- - MUST NOT expose sensitive tokens
234
- - MUST handle email display appropriately
235
- - MUST respect user privacy settings
236
-
237
- **MUST NOT**:
238
- - Show internal user identifiers
239
- - Display raw email publicly
240
- - Expose authentication tokens
241
- - Log profile data with sensitive info
242
-
243
- ### Constraints
244
-
245
- **SAFE TO DISPLAY**:
246
- - Display name: ✅ Safe
247
- - Avatar: ✅ Safe
248
- - Anonymous status: ✅ Safe
249
- - Email: ⚠️ Only to account owner
250
-
251
- **NEVER DISPLAY**:
252
- - User ID (UID)
253
- - Authentication tokens
254
- - Session identifiers
255
- - Internal metadata
256
-
257
- **PRIVACY CONSIDERATIONS**:
258
- - User-controlled display name
259
- - Optional profile photo
260
- - Anonymous users have more privacy
261
- - GDPR/CCPA compliant
262
-
263
- ---
264
-
265
- ## Platform Support
266
-
267
- ### Strategy
268
-
269
- **Purpose**: Consistent behavior across all platforms.
270
-
271
- **Constraints**:
272
- - iOS: ✅ Fully supported
273
- - Android: ✅ Fully supported
274
- - Web: ✅ Fully supported
275
-
276
- **PLATFORM-SPECIFIC**:
277
- - Avatar display: Platform-appropriate components
278
- - Name formatting: Consistent across platforms
279
- - Navigation: Platform-specific patterns
280
- - Fallbacks: Platform-appropriate defaults
281
-
282
- ---
283
-
284
- ## Related Hooks
285
-
286
- - **`useAuth`** (`src/presentation/hooks/useAuth.ts`) - Core authentication state
287
- - **`useProfileUpdate`** (`src/presentation/hooks/useProfileUpdate.md`) - Profile editing
288
- - **`useAccountManagement`** (`src/presentation/hooks/useAccountManagement.md`) - Account operations
289
-
290
- ## Related Components
291
-
292
- - **`ProfileSection`** (`src/presentation/components/ProfileComponents.md`) - Profile display component
293
- - **`AccountActions`** (`src/presentation/components/ProfileComponents.md`) - Account management UI
294
-
295
- ## Related Utilities
296
-
297
- - **`generateAnonymousName`** (`src/presentation/hooks/useUserProfile.ts`) - Anonymous name generation