@umituz/react-native-auth 3.4.31 → 3.4.33
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/index.ts +35 -0
- 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 +2 -2
- package/src/presentation/components/LoginForm.md +158 -267
- package/src/presentation/components/PasswordIndicators.md +199 -410
- package/src/presentation/components/ProfileComponents.md +322 -376
- package/src/presentation/components/SocialLoginButtons.md +295 -258
- package/src/presentation/hooks/useAccountManagement.md +301 -344
- package/src/presentation/hooks/useAuth.md +271 -227
- package/src/presentation/hooks/useAuthBottomSheet.md +419 -372
- package/src/presentation/hooks/useAuthRequired.md +308 -194
- package/src/presentation/hooks/useProfileUpdate.md +251 -279
- package/src/presentation/hooks/useSocialLogin.md +307 -337
- package/src/presentation/hooks/useUserProfile.md +259 -192
|
@@ -1,432 +1,378 @@
|
|
|
1
1
|
# Profile Components
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Component'ler
|
|
6
|
-
|
|
7
|
-
- **[`ProfileSection`](#profilesection)** - Profil bölümü
|
|
8
|
-
- **[`AccountActions`](#accountactions)** - Hesap işlemleri
|
|
3
|
+
Components for displaying user profile information and managing account actions.
|
|
9
4
|
|
|
10
5
|
---
|
|
11
6
|
|
|
12
7
|
## ProfileSection
|
|
13
8
|
|
|
14
|
-
|
|
9
|
+
Displays user profile information including avatar, name, and authentication status.
|
|
10
|
+
|
|
11
|
+
### Strategy
|
|
15
12
|
|
|
16
|
-
|
|
13
|
+
**Purpose**: Show user profile information with different layouts for authenticated vs anonymous users.
|
|
17
14
|
|
|
15
|
+
**When to Use**:
|
|
16
|
+
- Settings screens showing user info
|
|
17
|
+
- Profile headers in navigation
|
|
18
|
+
- Account management sections
|
|
19
|
+
- User identification in UI
|
|
20
|
+
|
|
21
|
+
**Import Path**:
|
|
18
22
|
```typescript
|
|
19
23
|
import { ProfileSection } from '@umituz/react-native-auth';
|
|
20
|
-
|
|
21
|
-
function SettingsScreen() {
|
|
22
|
-
const profile = useUserProfile({
|
|
23
|
-
accountRoute: 'AccountSettings',
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
const navigation = useNavigation();
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<View>
|
|
30
|
-
<ProfileSection
|
|
31
|
-
profile={{
|
|
32
|
-
displayName: profile?.displayName,
|
|
33
|
-
userId: profile?.userId,
|
|
34
|
-
isAnonymous: profile?.isAnonymous || false,
|
|
35
|
-
avatarUrl: profile?.avatarUrl,
|
|
36
|
-
accountSettingsRoute: profile?.accountSettingsRoute,
|
|
37
|
-
}}
|
|
38
|
-
onPress={() => navigation.navigate('EditProfile')}
|
|
39
|
-
onSignIn={() => navigation.navigate('Login')}
|
|
40
|
-
signInText="Giriş Yap"
|
|
41
|
-
anonymousText="Misafir"
|
|
42
|
-
/>
|
|
43
|
-
</View>
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
24
|
```
|
|
47
25
|
|
|
48
|
-
|
|
26
|
+
**Component Location**: `src/presentation/components/ProfileSection.tsx`
|
|
49
27
|
|
|
50
|
-
|
|
51
|
-
|------|-----|----------|----------|
|
|
52
|
-
| `profile` | `ProfileSectionConfig` | Yes | Profil konfigürasyonu |
|
|
53
|
-
| `onPress` | `() => void` | No | Press handler (authenticated kullanıcılar için) |
|
|
54
|
-
| `onSignIn` | `() => void` | No | Sign-in handler (anonymous kullanıcılar için) |
|
|
55
|
-
| `signInText` | `string` | No | "Giriş Yap" metni |
|
|
56
|
-
| `anonymousText` | `string` | No | Anonymous kullanıcı metni |
|
|
28
|
+
**Data Hook**: `src/presentation/hooks/useUserProfile.ts`
|
|
57
29
|
|
|
58
|
-
|
|
30
|
+
### Rules
|
|
59
31
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
accountSettingsRoute?: string; // Hesap ayarları route'u
|
|
67
|
-
benefits?: string[]; // Faydalar listesi
|
|
68
|
-
}
|
|
69
|
-
```
|
|
32
|
+
**MUST**:
|
|
33
|
+
- Pass profile object with required fields
|
|
34
|
+
- Provide different handlers for authenticated vs anonymous users
|
|
35
|
+
- Show avatar fallback if no photo available
|
|
36
|
+
- Display authentication status clearly
|
|
37
|
+
- Handle navigation to profile editing
|
|
70
38
|
|
|
71
|
-
|
|
39
|
+
**MUST NOT**:
|
|
40
|
+
- Show sensitive information (user ID, email publicly)
|
|
41
|
+
- Allow anonymous users to access profile editing
|
|
42
|
+
- Display generic avatar for authenticated users without photo
|
|
43
|
+
- Hardcode profile data (use useUserProfile hook)
|
|
72
44
|
|
|
73
|
-
|
|
45
|
+
### Constraints
|
|
74
46
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
displayName: user?.displayName || user?.email,
|
|
81
|
-
userId: user?.uid,
|
|
82
|
-
isAnonymous: false,
|
|
83
|
-
avatarUrl: user?.photoURL,
|
|
84
|
-
accountSettingsRoute: 'AccountSettings',
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
const navigation = useNavigation();
|
|
88
|
-
|
|
89
|
-
return (
|
|
90
|
-
<ProfileSection
|
|
91
|
-
profile={profile}
|
|
92
|
-
onPress={() => navigation.navigate('EditProfile')}
|
|
93
|
-
/>
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
```
|
|
47
|
+
**AUTHENTICATED USER DISPLAY**:
|
|
48
|
+
- Show display name or email
|
|
49
|
+
- Show avatar if available
|
|
50
|
+
- Show "Edit Profile" or settings access
|
|
51
|
+
- Hide authentication prompts
|
|
97
52
|
|
|
98
|
-
|
|
53
|
+
**ANONYMOUS USER DISPLAY**:
|
|
54
|
+
- Show "Guest" or anonymous label
|
|
55
|
+
- Show generic placeholder avatar
|
|
56
|
+
- Show "Sign In" or "Create Account" prompt
|
|
57
|
+
- Hide profile editing options
|
|
99
58
|
|
|
59
|
+
**REQUIRED PROPERTIES**:
|
|
100
60
|
```typescript
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
userId: undefined,
|
|
107
|
-
isAnonymous: true,
|
|
108
|
-
avatarUrl: undefined,
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
const navigation = useNavigation();
|
|
112
|
-
|
|
113
|
-
return (
|
|
114
|
-
<ProfileSection
|
|
115
|
-
profile={profile}
|
|
116
|
-
onSignIn={() => navigation.navigate('Login')}
|
|
117
|
-
signInText="Giriş Yap"
|
|
118
|
-
/>
|
|
119
|
-
);
|
|
61
|
+
{
|
|
62
|
+
displayName?: string;
|
|
63
|
+
isAnonymous: boolean;
|
|
64
|
+
avatarUrl?: string;
|
|
65
|
+
accountSettingsRoute?: string;
|
|
120
66
|
}
|
|
121
67
|
```
|
|
122
68
|
|
|
123
|
-
|
|
69
|
+
**PLATFORM SUPPORT**:
|
|
70
|
+
- iOS: ✅ Fully supported
|
|
71
|
+
- Android: ✅ Fully supported
|
|
72
|
+
- Web: ✅ Fully supported
|
|
124
73
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const profile = {
|
|
130
|
-
displayName: user?.displayName,
|
|
131
|
-
userId: user?.uid,
|
|
132
|
-
isAnonymous: false,
|
|
133
|
-
avatarUrl: user?.photoURL,
|
|
134
|
-
benefits: [
|
|
135
|
-
'Premium içeriklere erişim',
|
|
136
|
-
'Reklamsız deneyim',
|
|
137
|
-
'Özel indirimler',
|
|
138
|
-
],
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
return <ProfileSection profile={profile} />;
|
|
142
|
-
}
|
|
143
|
-
```
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## AccountActions
|
|
144
77
|
|
|
145
|
-
|
|
78
|
+
Provides buttons for account management operations like sign out and account deletion.
|
|
146
79
|
|
|
80
|
+
### Strategy
|
|
81
|
+
|
|
82
|
+
**Purpose**: Safe account management with proper confirmations and error handling.
|
|
83
|
+
|
|
84
|
+
**When to Use**:
|
|
85
|
+
- Account settings screens
|
|
86
|
+
- Logout functionality
|
|
87
|
+
- Account deletion flows
|
|
88
|
+
- Password change access
|
|
89
|
+
|
|
90
|
+
**Import Path**:
|
|
147
91
|
```typescript
|
|
148
|
-
|
|
149
|
-
const { user } = useAuth();
|
|
150
|
-
const navigation = useNavigation();
|
|
151
|
-
const profile = useUserProfile();
|
|
152
|
-
|
|
153
|
-
const handlePress = () => {
|
|
154
|
-
if (profile?.isAnonymous) {
|
|
155
|
-
navigation.navigate('Login');
|
|
156
|
-
} else {
|
|
157
|
-
navigation.navigate('EditProfile');
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
return (
|
|
162
|
-
<ProfileSection
|
|
163
|
-
profile={{
|
|
164
|
-
displayName: profile?.displayName,
|
|
165
|
-
userId: profile?.userId,
|
|
166
|
-
isAnonymous: profile?.isAnonymous || false,
|
|
167
|
-
avatarUrl: profile?.avatarUrl,
|
|
168
|
-
benefits: profile?.isAnonymous
|
|
169
|
-
? ['Hesap oluşturarak daha fazla özelliğe erişin']
|
|
170
|
-
: ['Premium üyelik alın', 'Ayrıcalıklı içeriklere erişin'],
|
|
171
|
-
}}
|
|
172
|
-
onPress={handlePress}
|
|
173
|
-
/>
|
|
174
|
-
);
|
|
175
|
-
}
|
|
92
|
+
import { AccountActions } from '@umituz/react-native-auth';
|
|
176
93
|
```
|
|
177
94
|
|
|
95
|
+
**Component Location**: `src/presentation/components/AccountActions.tsx`
|
|
96
|
+
|
|
97
|
+
**Management Hook**: `src/presentation/hooks/useAccountManagement.ts`
|
|
98
|
+
|
|
99
|
+
### Rules
|
|
100
|
+
|
|
101
|
+
**MUST**:
|
|
102
|
+
- Require confirmation before sign out
|
|
103
|
+
- Require confirmation before account deletion
|
|
104
|
+
- Show clear warnings for account deletion
|
|
105
|
+
- Provide error messages for failures
|
|
106
|
+
- Handle loading states during operations
|
|
107
|
+
- Hide deletion option for anonymous users
|
|
108
|
+
|
|
109
|
+
**MUST NOT**:
|
|
110
|
+
- Allow account deletion without confirmation
|
|
111
|
+
- Delete account without recent authentication
|
|
112
|
+
- Show account actions to anonymous users
|
|
113
|
+
- Allow immediate destructive actions
|
|
114
|
+
- Expose internal error messages
|
|
115
|
+
|
|
116
|
+
### Constraints
|
|
117
|
+
|
|
118
|
+
**SIGN OUT REQUIREMENTS**:
|
|
119
|
+
- Confirmation dialog required
|
|
120
|
+
- Clear sign-out message
|
|
121
|
+
- Cancel option must be available
|
|
122
|
+
- Non-destructive (can sign back in)
|
|
123
|
+
|
|
124
|
+
**ACCOUNT DELETION REQUIREMENTS**:
|
|
125
|
+
- Double confirmation required (warning + confirm)
|
|
126
|
+
- Clear warning about irreversibility
|
|
127
|
+
- Recent authentication required (Firebase requirement)
|
|
128
|
+
- Error handling for re-authentication failures
|
|
129
|
+
- Cannot delete anonymous accounts
|
|
130
|
+
|
|
131
|
+
**PASSWORD CHANGE**:
|
|
132
|
+
- Optional feature (configurable)
|
|
133
|
+
- Only for email/password users
|
|
134
|
+
- Requires current password
|
|
135
|
+
- Not available for social auth users
|
|
136
|
+
|
|
137
|
+
**OPERATION SAFETY**:
|
|
138
|
+
- Disable buttons during operation
|
|
139
|
+
- Show loading indicators
|
|
140
|
+
- Prevent concurrent operations
|
|
141
|
+
- Allow retry on failure
|
|
142
|
+
- Log security events
|
|
143
|
+
|
|
178
144
|
---
|
|
179
145
|
|
|
180
|
-
##
|
|
146
|
+
## Anonymous User Handling
|
|
181
147
|
|
|
182
|
-
|
|
148
|
+
### Strategy
|
|
183
149
|
|
|
184
|
-
|
|
150
|
+
**Purpose**: Differentiate experience between authenticated and anonymous users appropriately.
|
|
185
151
|
|
|
186
|
-
|
|
187
|
-
import { AccountActions } from '@umituz/react-native-auth';
|
|
152
|
+
### Rules
|
|
188
153
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
logoutText: 'Çıkış Yap',
|
|
195
|
-
deleteAccountText: 'Hesabı Sil',
|
|
196
|
-
changePasswordText: 'Şifre Değiştir',
|
|
197
|
-
logoutConfirmTitle: 'Çıkış Yap',
|
|
198
|
-
logoutConfirmMessage: 'Çıkış yapmak istediğinizden emin misiniz?',
|
|
199
|
-
deleteConfirmTitle: 'Hesabı Sil',
|
|
200
|
-
deleteConfirmMessage: 'Bu işlem geri alınamaz. Devam etmek istiyor musunuz?',
|
|
201
|
-
deleteErrorTitle: 'Hata',
|
|
202
|
-
deleteErrorMessage: 'Hesap silinemedi. Lütfen tekrar deneyin.',
|
|
203
|
-
onLogout: async () => {
|
|
204
|
-
await logout();
|
|
205
|
-
navigation.replace('Login');
|
|
206
|
-
},
|
|
207
|
-
onDeleteAccount: async () => {
|
|
208
|
-
await deleteAccount();
|
|
209
|
-
navigation.replace('Login');
|
|
210
|
-
},
|
|
211
|
-
showChangePassword: true,
|
|
212
|
-
onChangePassword: () => {
|
|
213
|
-
navigation.navigate('ChangePassword');
|
|
214
|
-
},
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
return (
|
|
218
|
-
<View>
|
|
219
|
-
<AccountActions config={config} />
|
|
220
|
-
</View>
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
```
|
|
154
|
+
**MUST**:
|
|
155
|
+
- Hide account deletion for anonymous users
|
|
156
|
+
- Show "Create Account" prompt instead of sign out
|
|
157
|
+
- Indicate guest status clearly
|
|
158
|
+
- Guide anonymous users toward registration
|
|
224
159
|
|
|
225
|
-
|
|
160
|
+
**MUST NOT**:
|
|
161
|
+
- Show account deletion to anonymous users
|
|
162
|
+
- Allow sign out of anonymous session (unless upgrading)
|
|
163
|
+
- Treat anonymous users as authenticated
|
|
164
|
+
- Hide anonymous status from user
|
|
226
165
|
|
|
227
|
-
|
|
228
|
-
|------|-----|----------|----------|
|
|
229
|
-
| `config` | `AccountActionsConfig` | Yes | Hesap işlemleri konfigürasyonu |
|
|
166
|
+
### Constraints
|
|
230
167
|
|
|
231
|
-
|
|
168
|
+
**ANONYMOUS USER LIMITATIONS**:
|
|
169
|
+
- Cannot delete anonymous account
|
|
170
|
+
- Cannot change password (no password set)
|
|
171
|
+
- Cannot access profile editing
|
|
172
|
+
- Limited account settings access
|
|
232
173
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
logoutConfirmTitle: string; // Çıkış onay başlığı
|
|
239
|
-
logoutConfirmMessage: string; // Çıkış onay mesajı
|
|
240
|
-
deleteConfirmTitle: string; // Silme onay başlığı
|
|
241
|
-
deleteConfirmMessage: string; // Silme onay mesajı
|
|
242
|
-
deleteErrorTitle?: string; // Silme hata başlığı
|
|
243
|
-
deleteErrorMessage?: string; // Silme hata mesajı
|
|
244
|
-
onLogout: () => Promise<void>; // Çıkış handler
|
|
245
|
-
onDeleteAccount: () => Promise<void>; // Silme handler
|
|
246
|
-
onChangePassword?: () => void; // Şifre değiştirme handler
|
|
247
|
-
showChangePassword?: boolean; // Şifre değiştirme butonu göster
|
|
248
|
-
}
|
|
249
|
-
```
|
|
174
|
+
**UPGRADE PATH**:
|
|
175
|
+
- Anonymous → Registered: Link credentials
|
|
176
|
+
- Preserves anonymous account data
|
|
177
|
+
- Requires email/password or social auth
|
|
178
|
+
- Seamless transition for user
|
|
250
179
|
|
|
251
|
-
|
|
180
|
+
---
|
|
252
181
|
|
|
253
|
-
|
|
182
|
+
## Security & Privacy
|
|
254
183
|
|
|
255
|
-
|
|
256
|
-
function SimpleAccountActions() {
|
|
257
|
-
const { logout, deleteAccount } = useAccountManagement();
|
|
258
|
-
|
|
259
|
-
const config = {
|
|
260
|
-
logoutText: 'Çıkış Yap',
|
|
261
|
-
deleteAccountText: 'Hesabı Sil',
|
|
262
|
-
logoutConfirmTitle: 'Çıkış Yap',
|
|
263
|
-
logoutConfirmMessage: 'Çıkış yapmak istiyor musunuz?',
|
|
264
|
-
deleteConfirmTitle: 'Hesabı Sil',
|
|
265
|
-
deleteConfirmMessage: 'Hesabınızı silmek istediğinizden emin misiniz?',
|
|
266
|
-
onLogout: logout,
|
|
267
|
-
onDeleteAccount: deleteAccount,
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
return <AccountActions config={config} />;
|
|
271
|
-
}
|
|
272
|
-
```
|
|
184
|
+
### Strategy
|
|
273
185
|
|
|
274
|
-
|
|
186
|
+
**Purpose**: Protect user information and prevent unauthorized account access.
|
|
275
187
|
|
|
276
|
-
|
|
277
|
-
function AccountActionsWithPasswordChange() {
|
|
278
|
-
const { logout, deleteAccount } = useAccountManagement();
|
|
279
|
-
const navigation = useNavigation();
|
|
280
|
-
|
|
281
|
-
const config = {
|
|
282
|
-
logoutText: 'Çıkış Yap',
|
|
283
|
-
deleteAccountText: 'Hesabı Sil',
|
|
284
|
-
changePasswordText: 'Şifre Değiştir',
|
|
285
|
-
logoutConfirmTitle: 'Çıkış Yap',
|
|
286
|
-
logoutConfirmMessage: 'Çıkış yapmak istiyor musunuz?',
|
|
287
|
-
deleteConfirmTitle: 'Hesabı Sil',
|
|
288
|
-
deleteConfirmMessage: 'Hesabınızı silmek istediğinizden emin misiniz?',
|
|
289
|
-
onLogout: async () => {
|
|
290
|
-
await logout();
|
|
291
|
-
navigation.replace('Login');
|
|
292
|
-
},
|
|
293
|
-
onDeleteAccount: async () => {
|
|
294
|
-
await deleteAccount();
|
|
295
|
-
navigation.replace('Login');
|
|
296
|
-
},
|
|
297
|
-
showChangePassword: true,
|
|
298
|
-
onChangePassword: () => {
|
|
299
|
-
navigation.navigate('ChangePassword');
|
|
300
|
-
},
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
return <AccountActions config={config} />;
|
|
304
|
-
}
|
|
305
|
-
```
|
|
188
|
+
### Rules
|
|
306
189
|
|
|
307
|
-
|
|
190
|
+
**MUST**:
|
|
191
|
+
- Never display full user ID in UI
|
|
192
|
+
- Never expose sensitive tokens
|
|
193
|
+
- Require recent auth for destructive actions
|
|
194
|
+
- Log account management events
|
|
195
|
+
- Validate permissions before actions
|
|
308
196
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
logoutText: 'Çıkış Yap',
|
|
316
|
-
deleteAccountText: 'Hesabı Sil',
|
|
317
|
-
logoutConfirmTitle: 'Çıkış Yap',
|
|
318
|
-
logoutConfirmMessage: 'Çıkış yapmak istiyor musunuz?',
|
|
319
|
-
deleteConfirmTitle: 'Hesabı Sil',
|
|
320
|
-
deleteConfirmMessage: 'Bu işlem geri alınamaz. Emin misiniz?',
|
|
321
|
-
deleteErrorTitle: 'Hesap Silinemedi',
|
|
322
|
-
deleteErrorMessage: 'Hesabınız silinirken bir hata oluştu. Lütfen daha sonra tekrar deneyin veya destek ile iletişime geçin.',
|
|
323
|
-
onLogout: async () => {
|
|
324
|
-
try {
|
|
325
|
-
await logout();
|
|
326
|
-
navigation.replace('Login');
|
|
327
|
-
} catch (error) {
|
|
328
|
-
Alert.alert('Hata', 'Çıkış yapılamadı');
|
|
329
|
-
}
|
|
330
|
-
},
|
|
331
|
-
onDeleteAccount: async () => {
|
|
332
|
-
try {
|
|
333
|
-
await deleteAccount();
|
|
334
|
-
Alert.alert('Başarılı', 'Hesabınız silindi');
|
|
335
|
-
navigation.replace('Login');
|
|
336
|
-
} catch (error) {
|
|
337
|
-
// Hata otomatik olarak gösterilir (deleteErrorMessage)
|
|
338
|
-
throw error;
|
|
339
|
-
}
|
|
340
|
-
},
|
|
341
|
-
};
|
|
342
|
-
|
|
343
|
-
return <AccountActions config={config} />;
|
|
344
|
-
}
|
|
345
|
-
```
|
|
197
|
+
**MUST NOT**:
|
|
198
|
+
- Show user ID or internal identifiers
|
|
199
|
+
- Display raw email publicly
|
|
200
|
+
- Allow account deletion without re-auth
|
|
201
|
+
- Skip confirmation dialogs
|
|
202
|
+
- Log sensitive data
|
|
346
203
|
|
|
347
|
-
|
|
204
|
+
### Constraints
|
|
348
205
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
return (
|
|
355
|
-
<Button onPress={() => navigation.navigate('Register')}>
|
|
356
|
-
Hesap Oluştur
|
|
357
|
-
</Button>
|
|
358
|
-
);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
const config = {
|
|
362
|
-
logoutText: 'Çıkış Yap',
|
|
363
|
-
deleteAccountText: 'Hesabı Sil',
|
|
364
|
-
logoutConfirmTitle: 'Çıkış Yap',
|
|
365
|
-
logoutConfirmMessage: 'Çıkış yapmak istiyor musunuz?',
|
|
366
|
-
deleteConfirmTitle: 'Hesabı Sil',
|
|
367
|
-
deleteConfirmMessage: 'Hesabınızı silmek istediğinizden emin misiniz?',
|
|
368
|
-
onLogout: logout,
|
|
369
|
-
onDeleteAccount: deleteAccount,
|
|
370
|
-
};
|
|
371
|
-
|
|
372
|
-
return <AccountActions config={config} />;
|
|
373
|
-
}
|
|
374
|
-
```
|
|
206
|
+
**INFORMATION DISPLAY**:
|
|
207
|
+
- Display name: OK
|
|
208
|
+
- Email: Only to account owner
|
|
209
|
+
- User ID: Never in UI
|
|
210
|
+
- Auth tokens: Never in logs
|
|
375
211
|
|
|
376
|
-
|
|
212
|
+
**RE-AUTHENTICATION**:
|
|
213
|
+
- Required for: Account deletion, password change
|
|
214
|
+
- Timeout: Usually 5 minutes in Firebase
|
|
215
|
+
- Methods: Re-sign in with existing credentials
|
|
216
|
+
- Failure: Block destructive action
|
|
377
217
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
218
|
+
**EVENT LOGGING**:
|
|
219
|
+
- Log: Account views, settings access
|
|
220
|
+
- Log: Sign out, deletion attempts
|
|
221
|
+
- Never log: Passwords, tokens, full emails
|
|
222
|
+
- Purpose: Security audit, debugging
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Navigation Integration
|
|
227
|
+
|
|
228
|
+
### Strategy
|
|
229
|
+
|
|
230
|
+
**Purpose**: Proper navigation flow for profile-related screens.
|
|
231
|
+
|
|
232
|
+
### Rules
|
|
233
|
+
|
|
234
|
+
**MUST**:
|
|
235
|
+
- Provide navigation callbacks for all actions
|
|
236
|
+
- Handle back navigation properly
|
|
237
|
+
- Pass profile data to edit screens
|
|
238
|
+
- Return to proper screen after actions
|
|
239
|
+
|
|
240
|
+
**MUST NOT**:
|
|
241
|
+
- Hardcode navigation paths
|
|
242
|
+
- Break back navigation stack
|
|
243
|
+
- Lose unsaved changes
|
|
244
|
+
- Leave modals open after actions
|
|
245
|
+
|
|
246
|
+
### Constraints
|
|
247
|
+
|
|
248
|
+
**NAVIGATION FLOWS**:
|
|
249
|
+
- Profile → Edit Profile → Back to Profile
|
|
250
|
+
- Profile → Account Settings → Back to Profile
|
|
251
|
+
- Sign Out → Login Screen (replace stack)
|
|
252
|
+
- Delete Account → Welcome/Login (replace stack)
|
|
253
|
+
|
|
254
|
+
**STACK MANAGEMENT**:
|
|
255
|
+
- Sign out: Replace entire stack
|
|
256
|
+
- Delete account: Replace entire stack
|
|
257
|
+
- Edit profile: Push onto stack
|
|
258
|
+
- Settings: Push onto stack
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Error Handling
|
|
263
|
+
|
|
264
|
+
### Strategy
|
|
265
|
+
|
|
266
|
+
**Purpose**: Clear user feedback for account action failures.
|
|
267
|
+
|
|
268
|
+
### Rules
|
|
269
|
+
|
|
270
|
+
**MUST**:
|
|
271
|
+
- Show user-friendly error messages
|
|
272
|
+
- Provide retry options after failures
|
|
273
|
+
- Distinguish error types clearly
|
|
274
|
+
- Guide users to resolution
|
|
275
|
+
- Log errors for debugging
|
|
276
|
+
|
|
277
|
+
**MUST NOT**:
|
|
278
|
+
- Show raw error codes to users
|
|
279
|
+
- Expose technical details
|
|
280
|
+
- Block retry indefinitely
|
|
281
|
+
- Crash on errors
|
|
282
|
+
|
|
283
|
+
### Constraints
|
|
284
|
+
|
|
285
|
+
**ERROR CATEGORIES**:
|
|
286
|
+
- Network errors: "Check your connection"
|
|
287
|
+
- Re-auth required: "Please sign in again"
|
|
288
|
+
- Permission denied: "You don't have permission"
|
|
289
|
+
- Rate limited: "Please try again later"
|
|
422
290
|
|
|
423
|
-
|
|
291
|
+
**RECOVERY OPTIONS**:
|
|
292
|
+
- Retry button for temporary failures
|
|
293
|
+
- Sign-in prompt for re-auth
|
|
294
|
+
- Support contact for persistent issues
|
|
295
|
+
- Graceful degradation
|
|
424
296
|
|
|
425
|
-
|
|
426
|
-
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Design System Integration
|
|
300
|
+
|
|
301
|
+
### Strategy
|
|
302
|
+
|
|
303
|
+
**Purpose**: Consistent styling with application design system.
|
|
304
|
+
|
|
305
|
+
### Rules
|
|
306
|
+
|
|
307
|
+
**MUST**:
|
|
308
|
+
- Use design system color tokens
|
|
309
|
+
- Follow design system spacing
|
|
310
|
+
- Use design system typography
|
|
311
|
+
- Match design system component styles
|
|
312
|
+
- Respect design system dark mode
|
|
313
|
+
|
|
314
|
+
**MUST NOT**:
|
|
315
|
+
- Hardcode colors or sizes
|
|
316
|
+
- Use custom styles outside system
|
|
317
|
+
- Break responsive layouts
|
|
318
|
+
- Ignore accessibility tokens
|
|
319
|
+
|
|
320
|
+
### Constraints
|
|
321
|
+
|
|
322
|
+
**STYLE TOKENS**:
|
|
323
|
+
- Colors: Primary, danger, background, text
|
|
324
|
+
- Spacing: Consistent gaps and padding
|
|
325
|
+
- Typography: System fonts and sizes
|
|
326
|
+
- Icons: Design system icon set
|
|
327
|
+
- Avatar sizes: Defined in system
|
|
328
|
+
|
|
329
|
+
**DARK MODE**:
|
|
330
|
+
- Automatically support dark mode
|
|
331
|
+
- Use system color tokens
|
|
332
|
+
- Test contrast in both modes
|
|
333
|
+
- No hardcoded colors
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Accessibility Requirements
|
|
338
|
+
|
|
339
|
+
### Strategy
|
|
340
|
+
|
|
341
|
+
**Purpose**: Ensure profile components are accessible to all users.
|
|
342
|
+
|
|
343
|
+
### Rules
|
|
344
|
+
|
|
345
|
+
**MUST**:
|
|
346
|
+
- Provide accessibility labels for buttons
|
|
347
|
+
- Announce state changes to screen readers
|
|
348
|
+
- Support keyboard navigation (web)
|
|
349
|
+
- Maintain proper focus order
|
|
350
|
+
- Use semantic HTML elements (web)
|
|
351
|
+
|
|
352
|
+
**MUST NOT**:
|
|
353
|
+
- Rely on color alone for meaning
|
|
354
|
+
- Hide important information from screen readers
|
|
355
|
+
- Break keyboard navigation
|
|
356
|
+
- Use low contrast colors
|
|
357
|
+
|
|
358
|
+
### Constraints
|
|
359
|
+
|
|
360
|
+
**SCREEN READER**:
|
|
361
|
+
- Announce user name and status
|
|
362
|
+
- Announce button actions clearly
|
|
363
|
+
- Provide hints for destructive actions
|
|
364
|
+
- Announce loading states
|
|
365
|
+
|
|
366
|
+
**VISUAL ACCESSIBILITY**:
|
|
367
|
+
- Minimum contrast: 4.5:1 for text
|
|
368
|
+
- Touch targets: 44x44px minimum
|
|
369
|
+
- Clear focus indicators
|
|
370
|
+
- Not color-dependent
|
|
371
|
+
|
|
372
|
+
---
|
|
427
373
|
|
|
428
|
-
##
|
|
374
|
+
## Related Hooks
|
|
429
375
|
|
|
430
|
-
-
|
|
431
|
-
-
|
|
432
|
-
-
|
|
376
|
+
- **`useUserProfile`** (`src/presentation/hooks/useUserProfile.ts`) - Profile data management
|
|
377
|
+
- **`useAccountManagement`** (`src/presentation/hooks/useAccountManagement.ts`) - Account operations
|
|
378
|
+
- **`useAuth`** (`src/presentation/hooks/useAuth.ts`) - Authentication state
|