@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.
@@ -1,377 +1,236 @@
1
1
  # AuthUser Entity
2
2
 
3
- Authentication için provider-agnostic kullanıcı entity'si. Firebase User ile uyumlu, ancak herhangi bir auth provider ile kullanılabilir.
4
-
5
- ## Tip Tanımı
6
-
7
- ```typescript
8
- import type { AuthUser, AuthProviderType } from '@umituz/react-native-auth';
9
-
10
- interface AuthUser {
11
- uid: string; // Unique kullanıcı ID'si
12
- email: string | null; // Email adresi (anonymous'da null)
13
- displayName: string | null; // Görünen ad
14
- isAnonymous: boolean; // Anonymous kullanıcı mı
15
- emailVerified: boolean; // Email doğrulanmış mı
16
- photoURL: string | null; // Profil fotoğrafı URL'si
17
- provider: AuthProviderType; // Auth provider tipi
18
- }
19
-
20
- type AuthProviderType =
21
- | "google.com" // Google ile giriş
22
- | "apple.com" // Apple ile giriş
23
- | "password" // Email/password ile giriş
24
- | "anonymous" // Anonymous kullanıcı
25
- | "unknown"; // Bilinmeyen provider
26
- ```
27
-
28
- ## Örnekler
29
-
30
- ### Email/Password Kullanıcısı
31
-
32
- ```typescript
33
- const emailUser: AuthUser = {
34
- uid: 'user-123',
35
- email: 'john@example.com',
36
- displayName: 'John Doe',
37
- isAnonymous: false,
38
- emailVerified: true,
39
- photoURL: null,
40
- provider: 'password',
41
- };
42
- ```
43
-
44
- ### Google Kullanıcısı
45
-
46
- ```typescript
47
- const googleUser: AuthUser = {
48
- uid: 'google-456',
49
- email: 'jane@gmail.com',
50
- displayName: 'Jane Smith',
51
- isAnonymous: false,
52
- emailVerified: true,
53
- photoURL: 'https://lh3.googleusercontent.com/...',
54
- provider: 'google.com',
55
- };
56
- ```
57
-
58
- ### Apple Kullanıcısı
59
-
60
- ```typescript
61
- const appleUser: AuthUser = {
62
- uid: 'apple-789',
63
- email: 'user@icloud.com',
64
- displayName: 'Apple User',
65
- isAnonymous: false,
66
- emailVerified: true,
67
- photoURL: null,
68
- provider: 'apple.com',
69
- };
70
- ```
71
-
72
- ### Anonymous Kullanıcı
73
-
74
- ```typescript
75
- const anonymousUser: AuthUser = {
76
- uid: 'anon-abc',
77
- email: null,
78
- displayName: null,
79
- isAnonymous: true,
80
- emailVerified: false,
81
- photoURL: null,
82
- provider: 'anonymous',
83
- };
84
- ```
85
-
86
- ## Kullanım
87
-
88
- ### Firebase User'dan AuthUser'a Dönüşüm
89
-
90
- ```typescript
91
- import { getAuth } from 'firebase/auth';
92
- import type { AuthUser } from '@umituz/react-native-auth';
93
-
94
- function firebaseUserToAuthUser(firebaseUser: FirebaseUser): AuthUser {
95
- return {
96
- uid: firebaseUser.uid,
97
- email: firebaseUser.email,
98
- displayName: firebaseUser.displayName,
99
- isAnonymous: firebaseUser.isAnonymous,
100
- emailVerified: firebaseUser.emailVerified,
101
- photoURL: firebaseUser.photoURL,
102
- provider: firebaseUser.providerData[0]?.providerId || 'unknown',
103
- };
104
- }
105
-
106
- // Kullanım
107
- const auth = getAuth();
108
- const firebaseUser = auth.currentUser;
109
- if (firebaseUser) {
110
- const user: AuthUser = firebaseUserToAuthUser(firebaseUser);
111
- console.log(user.displayName);
112
- }
113
- ```
114
-
115
- ### DisplayName Alma
116
-
117
- ```typescript
118
- function getUserDisplayName(user: AuthUser): string {
119
- // Önce displayName'i dene
120
- if (user.displayName) {
121
- return user.displayName;
122
- }
123
-
124
- // Yoksa email'i kullan
125
- if (user.email) {
126
- // Email'den isim çıkar
127
- const name = user.email.split('@')[0];
128
- return name.charAt(0).toUpperCase() + name.slice(1);
129
- }
130
-
131
- // Hiçbiri yoksa varsayılan
132
- return 'Kullanıcı';
133
- }
134
-
135
- // Kullanım
136
- const name = getUserDisplayName(user);
137
- console.log(name); // "John" veya "Johndoe"
138
- ```
139
-
140
- ### Provider Kontrolü
141
-
142
- ```typescript
143
- function isSocialLogin(user: AuthUser): boolean {
144
- return user.provider === 'google.com' || user.provider === 'apple.com';
145
- }
146
-
147
- function isEmailPasswordUser(user: AuthUser): boolean {
148
- return user.provider === 'password';
149
- }
150
-
151
- function canChangePassword(user: AuthUser): boolean {
152
- // Sadece email/password kullanıcıları şifre değiştirebilir
153
- return user.provider === 'password';
154
- }
155
-
156
- // Kullanım
157
- if (isSocialLogin(user)) {
158
- console.log('Social login ile giriş yaptı');
159
- }
160
-
161
- if (canChangePassword(user)) {
162
- // Şifre değiştirme butonunu göster
163
- }
164
- ```
165
-
166
- ### Email Doğrulama Kontrolü
167
-
168
- ```typescript
169
- function requireEmailVerification(user: AuthUser): void {
170
- if (user.provider === 'password' && !user.emailVerified) {
171
- throw new Error('Email doğrulanması gerekiyor');
172
- }
173
- }
174
-
175
- function shouldShowVerifyEmailBanner(user: AuthUser): boolean {
176
- return (
177
- !user.isAnonymous &&
178
- user.provider === 'password' &&
179
- !user.emailVerified
180
- );
181
- }
182
- ```
183
-
184
- ### Avatar URL Alma
185
-
186
- ```typescript
187
- function getUserAvatar(user: AuthUser): string | null {
188
- // Önce photoURL'yi dene
189
- if (user.photoURL) {
190
- return user.photoURL;
191
- }
192
-
193
- // Anonymous ise null döndür
194
- if (user.isAnonymous) {
195
- return null;
196
- }
197
-
198
- // Default avatar oluştur (örn: UI Avatars)
199
- if (user.email) {
200
- return `https://ui-avatars.com/api/?name=${encodeURIComponent(user.email)}&background=random`;
201
- }
202
-
203
- return null;
204
- }
205
- ```
206
-
207
- ### User İsim Oluşturma
208
-
209
- ```typescript
210
- function getUserInitials(user: AuthUser): string {
211
- if (user.displayName) {
212
- const names = user.displayName.trim().split(' ');
213
- if (names.length >= 2) {
214
- return (names[0][0] + names[names.length - 1][0]).toUpperCase();
215
- }
216
- return names[0][0].toUpperCase();
217
- }
218
-
219
- if (user.email) {
220
- return user.email[0].toUpperCase();
221
- }
222
-
223
- return '?';
224
- }
225
-
226
- // Kullanım
227
- const initials = getUserInitials(user);
228
- console.log(initials); // "JD" veya "J" veya "?"
229
- ```
3
+ Provider-agnostic user entity for authentication.
4
+
5
+ ---
6
+
7
+ ## Strategy
8
+
9
+ **Purpose**: Represents authenticated user with provider-agnostic design. Compatible with Firebase User but works with any auth provider.
10
+
11
+ **When to Use**:
12
+ - Type-safe user representation
13
+ - User identity management
14
+ - Authentication operations
15
+ - User profile display
16
+
17
+ **Location**: `src/domain/entities/AuthUser.ts`
18
+
19
+ ---
20
+
21
+ ## Type Definition
22
+
23
+ ### AuthUser Interface
24
+
25
+ **PROPERTIES**:
26
+ - `uid: string` - Unique user identifier
27
+ - `email: string | null` - Email address
28
+ - `displayName: string | null` - Display name
29
+ - `isAnonymous: boolean` - Anonymous user flag
30
+ - `emailVerified: boolean` - Email verification status
31
+ - `photoURL: string | null` - Profile photo URL
32
+ - `provider: AuthProviderType` - Auth provider type
33
+
34
+ ### AuthProviderType
35
+
36
+ **VALUES**:
37
+ - `"google.com"` - Google authentication
38
+ - `"apple.com"` - Apple authentication
39
+ - `"password"` - Email/password authentication
40
+ - `"anonymous"` - Anonymous user
41
+ - `"unknown"` - Unknown provider
42
+
43
+ **Rules**:
44
+ - MUST have unique uid
45
+ - MUST NOT have empty uid
46
+ - Anonymous users have null email
47
+ - Provider indicates auth method
48
+
49
+ **Constraints**:
50
+ - Immutable after creation
51
+ - uid cannot be changed
52
+ - Provider determined by auth method
53
+
54
+ ---
55
+
56
+ ## User State Management
57
+
58
+ ### Authenticated User
59
+
60
+ **CHARACTERISTICS**:
61
+ - Has valid uid
62
+ - Has email or social auth
63
+ - Not anonymous
64
+ - May have email verified flag
65
+
66
+ **Rules**:
67
+ - MUST have uid set
68
+ - MUST NOT be anonymous
69
+ - SHOULD have email if password provider
70
+
71
+ **Constraints**:
72
+ - Email can be null for social auth
73
+ - DisplayName optional
74
+ - photoURL optional
75
+
76
+ ---
77
+
78
+ ### Anonymous User
79
+
80
+ **CHARACTERISTICS**:
81
+ - Has valid uid
82
+ - No email
83
+ - isAnonymous = true
84
+ - provider = "anonymous"
85
+
86
+ **Rules**:
87
+ - MUST have isAnonymous = true
88
+ - MUST have null email
89
+ - provider MUST be "anonymous"
90
+
91
+ **Constraints**:
92
+ - Limited functionality
93
+ - Data lost on sign out
94
+ - Can be upgraded to registered account
95
+
96
+ ---
97
+
98
+ ## Provider Types
99
+
100
+ ### Google User
101
+
102
+ **PROPERTIES**:
103
+ - provider: "google.com"
104
+ - emailVerified: true (typically)
105
+ - Has Google account data
106
+
107
+ **Rules**:
108
+ - MUST use Google provider
109
+ - MUST have verified email
110
+ - Auto-verifies email
111
+
112
+ ---
113
+
114
+ ### Apple User
115
+
116
+ **PROPERTIES**:
117
+ - provider: "apple.com"
118
+ - Email may be hidden (user choice)
119
+ - iOS only
120
+
121
+ **Rules**:
122
+ - MUST use Apple provider
123
+ - iOS platform only
124
+ - Respect user privacy choices
125
+
126
+ **Constraints**:
127
+ - Email may be private relay
128
+ - Not available on Android/Web
129
+
130
+ ---
131
+
132
+ ### Email/Password User
133
+
134
+ **PROPERTIES**:
135
+ - provider: "password"
136
+ - emailVerified may be false initially
137
+ - Standard auth flow
138
+
139
+ **Rules**:
140
+ - MUST have email
141
+ - Email may require verification
142
+ - Can change password
143
+
144
+ **Constraints**:
145
+ - Email required
146
+ - Password managed by user
147
+
148
+ ---
149
+
150
+ ## User Display
151
+
152
+ ### Display Name Priority
153
+
154
+ **RULES**:
155
+ 1. Use displayName if available
156
+ 2. Fall back to email username
157
+ 3. Fall back to "User" for anonymous
158
+ 4. MUST NOT expose sensitive data
159
+
160
+ **CONSTRAINTS**:
161
+ - Display name: User-controlled
162
+ - Email: Only first part before @
163
+ - Anonymous: Generated or "Guest"
164
+
165
+ ---
166
+
167
+ ### Profile Photo
168
+
169
+ **RULES**:
170
+ - MUST provide fallback if null
171
+ - MUST handle loading state
172
+ - MUST not break if missing
173
+
174
+ **FALLBACK OPTIONS**:
175
+ - Default avatar generator
176
+ - User initials
177
+ - Placeholder icon
178
+ - Null (no avatar)
179
+
180
+ ---
230
181
 
231
182
  ## Type Guards
232
183
 
233
- ```typescript
234
- function isAuthenticatedUser(user: AuthUser | null): user is AuthUser {
235
- return user !== null && !user.isAnonymous;
236
- }
237
-
238
- function isAnonymousUser(user: AuthUser | null): user is AuthUser {
239
- return user !== null && user.isAnonymous;
240
- }
241
-
242
- function hasEmail(user: AuthUser | null): user is AuthUser {
243
- return user !== null && user.email !== null;
244
- }
245
-
246
- // Kullanım
247
- if (isAuthenticatedUser(user)) {
248
- // TypeScript burada user'ın AuthUser olduğunu bilir
249
- console.log(user.email);
250
- }
251
- ```
252
-
253
- ## Firebase ile Entegrasyon
254
-
255
- ### Auth State Değişikliği Dinleme
256
-
257
- ```typescript
258
- import { getAuth, onAuthStateChanged } from 'firebase/auth';
259
- import type { AuthUser } from '@umituz/react-native-auth';
260
-
261
- function useAuthUser() {
262
- const [user, setUser] = useState<AuthUser | null>(null);
263
-
264
- useEffect(() => {
265
- const auth = getAuth();
266
- const unsubscribe = onAuthStateChanged(auth, (firebaseUser) => {
267
- if (firebaseUser) {
268
- const authUser: AuthUser = {
269
- uid: firebaseUser.uid,
270
- email: firebaseUser.email,
271
- displayName: firebaseUser.displayName,
272
- isAnonymous: firebaseUser.isAnonymous,
273
- emailVerified: firebaseUser.emailVerified,
274
- photoURL: firebaseUser.photoURL,
275
- provider: firebaseUser.providerData[0]?.providerId || 'unknown',
276
- };
277
- setUser(authUser);
278
- } else {
279
- setUser(null);
280
- }
281
- });
282
-
283
- return unsubscribe;
284
- }, []);
285
-
286
- return user;
287
- }
288
- ```
289
-
290
- ### User Meta Verileri
291
-
292
- ```typescript
293
- interface ExtendedAuthUser extends AuthUser {
294
- createdAt?: number;
295
- lastSignInAt?: number;
296
- metadata?: {
297
- lastSignInTime?: string;
298
- creationTime?: string;
299
- };
300
- }
301
-
302
- function enrichAuthUser(user: AuthUser, firebaseUser: FirebaseUser): ExtendedAuthUser {
303
- return {
304
- ...user,
305
- metadata: {
306
- lastSignInTime: firebaseUser.metadata.lastSignInTime,
307
- creationTime: firebaseUser.metadata.creationTime,
308
- },
309
- };
310
- }
311
- ```
312
-
313
- ## Validasyon
314
-
315
- ### User Validasyonu
316
-
317
- ```typescript
318
- function validateAuthUser(user: AuthUser): { valid: boolean; errors: string[] } {
319
- const errors: string[] = [];
320
-
321
- if (!user.uid || user.uid.length === 0) {
322
- errors.push('User ID is required');
323
- }
324
-
325
- if (!user.isAnonymous && !user.email) {
326
- errors.push('Email is required for non-anonymous users');
327
- }
328
-
329
- if (user.email && !isValidEmail(user.email)) {
330
- errors.push('Invalid email format');
331
- }
332
-
333
- return {
334
- valid: errors.length === 0,
335
- errors,
336
- };
337
- }
338
-
339
- function isValidEmail(email: string): boolean {
340
- return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
341
- }
342
- ```
343
-
344
- ## Testler
345
-
346
- ### Mock User Oluşturma
347
-
348
- ```typescript
349
- function createMockAuthUser(overrides?: Partial<AuthUser>): AuthUser {
350
- return {
351
- uid: 'mock-user-123',
352
- email: 'mock@example.com',
353
- displayName: 'Mock User',
354
- isAnonymous: false,
355
- emailVerified: true,
356
- photoURL: null,
357
- provider: 'password',
358
- ...overrides,
359
- };
360
- }
361
-
362
- // Testlerde kullanım
363
- const mockUser = createMockAuthUser({
364
- provider: 'google.com',
365
- photoURL: 'https://example.com/avatar.jpg',
366
- });
367
- ```
368
-
369
- ## İlgili Entity'ler
370
-
371
- - **[`UserProfile`](./UserProfile.md)** - Kullanıcı profili entity'si
372
- - **[`AuthError`](../errors/AuthError.md)** - Auth hataları
373
-
374
- ## İlgili Type'lar
375
-
376
- - **[`AuthProviderType`](#tip-tanımı)** - Provider tipi
377
- - **[`UpdateProfileParams`](../UserProfile.md)** - Profil güncelleme parametreleri
184
+ ### User Type Checks
185
+
186
+ **isAuthenticatedUser(user)**
187
+ - Checks if user exists and not anonymous
188
+ - Type guard for TypeScript
189
+
190
+ **isAnonymousUser(user)**
191
+ - Checks if anonymous user
192
+ - Type guard for TypeScript
193
+
194
+ **hasEmail(user)**
195
+ - Checks if has email
196
+ - Type guard for TypeScript
197
+
198
+ **Rules**:
199
+ - MUST use for type narrowing
200
+ - MUST validate before operations
201
+ - MUST check null cases
202
+
203
+ ---
204
+
205
+ ## Validation
206
+
207
+ ### User Validation Rules
208
+
209
+ **MUST**:
210
+ - Validate uid is not empty
211
+ - Validate email format if provided
212
+ - Check provider is valid
213
+ - Verify required fields
214
+
215
+ **MUST NOT**:
216
+ - Allow empty uid
217
+ - Accept invalid email format
218
+ - Use wrong provider type
219
+
220
+ **Constraints**:
221
+ - uid required
222
+ - Email format validated
223
+ - Provider must be known type
224
+
225
+ ---
226
+
227
+ ## Related Entities
228
+
229
+ - **UserProfile** (`./UserProfile.md`) - User profile entity
230
+ - **AuthConfig** (`./ConfigAndErrors.md`) - Configuration
231
+ - **AuthError** (`./ConfigAndErrors.md`) - Error handling
232
+
233
+ ## Related Infrastructure
234
+
235
+ - **AuthService** (`../../infrastructure/services/AuthService.ts`) - Auth operations
236
+ - **Firebase Auth** - Firebase integration