@umituz/react-native-firebase 2.6.2 → 2.6.4

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.
Files changed (101) hide show
  1. package/package.json +1 -1
  2. package/src/application/auth/index.ts +2 -34
  3. package/src/application/auth/use-cases/index.ts +1 -21
  4. package/src/domains/account-deletion/domain/index.ts +1 -8
  5. package/src/domains/account-deletion/index.ts +0 -42
  6. package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor.ts +79 -0
  7. package/src/domains/account-deletion/infrastructure/services/AccountDeletionTypes.ts +0 -1
  8. package/src/domains/account-deletion/infrastructure/services/account-deletion.service.ts +2 -14
  9. package/src/domains/auth/index.ts +3 -12
  10. package/src/domains/auth/infrastructure.ts +11 -0
  11. package/src/domains/firestore/domain/entities/Collection.ts +0 -2
  12. package/src/domains/firestore/domain/index.ts +8 -12
  13. package/src/domains/firestore/domain/value-objects/{QueryOptions.ts.bak → QueryOptions.ts} +20 -68
  14. package/src/domains/firestore/domain/value-objects/QueryOptionsFactory.ts +95 -0
  15. package/src/domains/firestore/domain/value-objects/QueryOptionsHelpers.ts +110 -0
  16. package/src/domains/firestore/domain/value-objects/WhereClause.ts +115 -0
  17. package/src/domains/firestore/domain/value-objects/WhereClauseFactory.ts +101 -0
  18. package/src/domains/firestore/domain/value-objects/WhereClauseHelpers.ts +123 -0
  19. package/src/domains/firestore/domain/value-objects/WhereClauseValidation.ts +83 -0
  20. package/src/domains/firestore/presentation/hooks/useFirestoreMutation.ts +1 -1
  21. package/src/domains/firestore/presentation/hooks/useFirestoreQuery.ts +1 -1
  22. package/src/shared/infrastructure/config/base/ServiceClientSingleton.ts +29 -0
  23. package/src/application/auth/ports/AuthPort.ts.bak +0 -164
  24. package/src/application/auth/ports/AuthPort_part_aa +0 -150
  25. package/src/application/auth/ports/AuthPort_part_ab +0 -14
  26. package/src/application/auth/use-cases/SignInUseCase.ts.bak +0 -253
  27. package/src/application/auth/use-cases/SignInUseCaseHelpers.ts +0 -0
  28. package/src/application/auth/use-cases/SignInUseCaseMain.ts +0 -0
  29. package/src/application/auth/use-cases/SignInUseCase_part_aa +0 -150
  30. package/src/application/auth/use-cases/SignInUseCase_part_ab +0 -103
  31. package/src/application/auth/use-cases/SignOutUseCase.ts.bak +0 -288
  32. package/src/application/auth/use-cases/SignOutUseCaseCleanup.ts +0 -0
  33. package/src/application/auth/use-cases/SignOutUseCaseMain.ts +0 -0
  34. package/src/application/auth/use-cases/SignOutUseCase_part_aa +0 -150
  35. package/src/application/auth/use-cases/SignOutUseCase_part_ab +0 -138
  36. package/src/domains/account-deletion/domain/services/UserValidationHelpers.ts.bak +0 -181
  37. package/src/domains/account-deletion/domain/services/UserValidationHelpers_part_aa +0 -150
  38. package/src/domains/account-deletion/domain/services/UserValidationHelpers_part_ab +0 -31
  39. package/src/domains/account-deletion/domain/services/UserValidationService.ts.bak +0 -286
  40. package/src/domains/account-deletion/domain/services/UserValidationService_part_aa +0 -150
  41. package/src/domains/account-deletion/domain/services/UserValidationService_part_ab +0 -136
  42. package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor.ts.bak +0 -230
  43. package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor_part_aa +0 -150
  44. package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor_part_ab +0 -80
  45. package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler.ts.bak +0 -174
  46. package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler_part_aa +0 -150
  47. package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler_part_ab +0 -24
  48. package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository.ts.bak +0 -266
  49. package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository_part_aa +0 -150
  50. package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository_part_ab +0 -116
  51. package/src/domains/account-deletion/infrastructure/services/reauthentication.service.ts.bak +0 -160
  52. package/src/domains/account-deletion/infrastructure/services/reauthentication.service_part_aa +0 -150
  53. package/src/domains/account-deletion/infrastructure/services/reauthentication.service_part_ab +0 -10
  54. package/src/domains/auth/infrastructure.ts.bak +0 -156
  55. package/src/domains/auth/infrastructure_part_aa +0 -150
  56. package/src/domains/auth/infrastructure_part_ab +0 -6
  57. package/src/domains/auth/presentation/hooks/GoogleOAuthHelpers.ts +0 -0
  58. package/src/domains/auth/presentation/hooks/GoogleOAuthHookService.ts.bak +0 -247
  59. package/src/domains/auth/presentation/hooks/GoogleOAuthHookService_part_aa +0 -150
  60. package/src/domains/auth/presentation/hooks/GoogleOAuthHookService_part_ab +0 -97
  61. package/src/domains/auth/presentation/hooks/GoogleOAuthService.ts +0 -0
  62. package/src/domains/firestore/domain/entities/Collection.ts.bak +0 -288
  63. package/src/domains/firestore/domain/entities/Collection_part_aa +0 -150
  64. package/src/domains/firestore/domain/entities/Collection_part_ab +0 -138
  65. package/src/domains/firestore/domain/entities/Document.ts.bak +0 -233
  66. package/src/domains/firestore/domain/entities/DocumentHelpers.ts +0 -0
  67. package/src/domains/firestore/domain/entities/DocumentMain.ts +0 -0
  68. package/src/domains/firestore/domain/entities/Document_part_aa +0 -150
  69. package/src/domains/firestore/domain/entities/Document_part_ab +0 -83
  70. package/src/domains/firestore/domain/services/QueryService.ts.bak +0 -182
  71. package/src/domains/firestore/domain/services/QueryServiceAnalysis.ts.bak +0 -169
  72. package/src/domains/firestore/domain/services/QueryServiceAnalysis_part_aa +0 -150
  73. package/src/domains/firestore/domain/services/QueryServiceAnalysis_part_ab +0 -19
  74. package/src/domains/firestore/domain/services/QueryServiceHelpers.ts.bak +0 -151
  75. package/src/domains/firestore/domain/services/QueryServiceHelpers_part_aa +0 -150
  76. package/src/domains/firestore/domain/services/QueryServiceHelpers_part_ab +0 -1
  77. package/src/domains/firestore/domain/services/QueryService_part_aa +0 -150
  78. package/src/domains/firestore/domain/services/QueryService_part_ab +0 -32
  79. package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization.ts.bak +0 -207
  80. package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization_part_aa +0 -150
  81. package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization_part_ab +0 -57
  82. package/src/domains/firestore/domain/value-objects/QueryOptionsValidation.ts.bak +0 -182
  83. package/src/domains/firestore/domain/value-objects/QueryOptionsValidation_part_aa +0 -150
  84. package/src/domains/firestore/domain/value-objects/QueryOptionsValidation_part_ab +0 -32
  85. package/src/domains/firestore/domain/value-objects/QueryOptions_part_aa +0 -150
  86. package/src/domains/firestore/domain/value-objects/QueryOptions_part_ab +0 -41
  87. package/src/domains/firestore/domain/value-objects/WhereClause.ts.bak +0 -299
  88. package/src/domains/firestore/domain/value-objects/WhereClauseFactory.ts.bak +0 -207
  89. package/src/domains/firestore/domain/value-objects/WhereClauseFactory_part_aa +0 -150
  90. package/src/domains/firestore/domain/value-objects/WhereClauseFactory_part_ab +0 -57
  91. package/src/domains/firestore/domain/value-objects/WhereClause_part_aa +0 -150
  92. package/src/domains/firestore/domain/value-objects/WhereClause_part_ab +0 -149
  93. package/src/shared/infrastructure/base/ErrorHandler.ts.bak +0 -189
  94. package/src/shared/infrastructure/base/ErrorHandler_part_aa +0 -150
  95. package/src/shared/infrastructure/base/ErrorHandler_part_ab +0 -39
  96. package/src/shared/infrastructure/base/ServiceBase.ts.bak +0 -220
  97. package/src/shared/infrastructure/base/ServiceBase_part_aa +0 -150
  98. package/src/shared/infrastructure/base/ServiceBase_part_ab +0 -70
  99. package/src/shared/infrastructure/config/base/ServiceClientSingleton.ts.bak +0 -155
  100. package/src/shared/infrastructure/config/base/ServiceClientSingleton_part_aa +0 -150
  101. package/src/shared/infrastructure/config/base/ServiceClientSingleton_part_ab +0 -5
@@ -1,150 +0,0 @@
1
- /**
2
- * Account Deletion Reauthentication Handler
3
- * Single Responsibility: Handle reauthentication during account deletion
4
- *
5
- * Max lines: 150 (enforced for maintainability)
6
- */
7
-
8
- import type { User } from 'firebase/auth';
9
- import { getFirebaseAuth } from '../../../auth/infrastructure/config/FirebaseAuthClient';
10
- import { userValidationService } from '../../domain/services/UserValidationService';
11
- import type { Result } from '../../../../shared/domain/utils';
12
- import type { AccountDeletionOptions } from '../../application/ports/reauthentication.types';
13
- import type { AccountDeletionResult, ReauthenticationContext } from './AccountDeletionTypes';
14
-
15
- /**
16
- * Handle reauthentication during account deletion
17
- * Coordinates reauthentication flow with credential management
18
- */
19
- export async function handleReauthentication(
20
- user: User,
21
- options: AccountDeletionOptions,
22
- originalUserId: string | undefined,
23
- repository: any
24
- ): Promise<AccountDeletionResult | null> {
25
- // Validate user hasn't changed before reauthentication
26
- if (originalUserId) {
27
- const auth = getFirebaseAuth();
28
- const validation = userValidationService.validateUserUnchanged(auth, originalUserId);
29
- if (!validation.success) {
30
- return {
31
- success: false,
32
- error: validation.error!,
33
- requiresReauth: false,
34
- };
35
- }
36
- }
37
-
38
- // Import reauthentication functions
39
- const {
40
- getUserAuthProvider,
41
- reauthenticateWithApple,
42
- reauthenticateWithPassword,
43
- reauthenticateWithGoogle,
44
- } = await import('./reauthentication.service');
45
-
46
- const provider = getUserAuthProvider(user);
47
-
48
- // Attempt reauthentication based on provider
49
- let reauthResult: { success: boolean; error?: { code?: string; message?: string } } | null = null;
50
-
51
- if (provider === 'apple.com') {
52
- reauthResult = await reauthenticateWithApple(user);
53
- } else if (provider === 'google.com') {
54
- const googleToken = await getGoogleToken(options);
55
- if (!googleToken) {
56
- return {
57
- success: false,
58
- error: { code: 'auth/google-reauth', message: 'Google reauthentication required' },
59
- requiresReauth: true,
60
- };
61
- }
62
- reauthResult = await reauthenticateWithGoogle(user, googleToken);
63
- } else if (provider === 'password') {
64
- const password = await getPassword(options);
65
- if (!password) {
66
- return {
67
- success: false,
68
- error: { code: 'auth/password-reauth', message: 'Password required' },
69
- requiresReauth: true,
70
- };
71
- }
72
- reauthResult = await reauthenticateWithPassword(user, password);
73
- } else {
74
- return null;
75
- }
76
-
77
- // If reauthentication successful, retry deletion
78
- if (reauthResult.success) {
79
- return await retryDeletionAfterReauth(originalUserId, repository);
80
- }
81
-
82
- return {
83
- success: false,
84
- error: {
85
- code: reauthResult.error?.code || 'auth/reauth-failed',
86
- message: reauthResult.error?.message || 'Reauthentication failed',
87
- },
88
- requiresReauth: true,
89
- };
90
- }
91
-
92
- /**
93
- * Get Google ID token from options or callback
94
- */
95
- async function getGoogleToken(options: AccountDeletionOptions): Promise<string | undefined> {
96
- if (options.googleIdToken) {
97
- return options.googleIdToken;
98
- }
99
-
100
- if (options.onGoogleReauthRequired) {
101
- return await options.onGoogleReauthRequired();
102
- }
103
-
104
- return undefined;
105
- }
106
-
107
- /**
108
- * Get password from options or callback
109
- */
110
- async function getPassword(options: AccountDeletionOptions): Promise<string | undefined> {
111
- if (options.password) {
112
- return options.password;
113
- }
114
-
115
- if (options.onPasswordRequired) {
116
- return await options.onPasswordRequired();
117
- }
118
-
119
- return undefined;
120
- }
121
-
122
- /**
123
- * Retry deletion after successful reauthentication
124
- */
125
- async function retryDeletionAfterReauth(
126
- originalUserId: string | undefined,
127
- repository: any
128
- ): Promise<AccountDeletionResult> {
129
- try {
130
- const auth = getFirebaseAuth();
131
- const user = auth?.currentUser;
132
-
133
- if (!user) {
134
- return {
135
- success: false,
136
- error: { code: 'auth/not-ready', message: 'User not found after reauthentication' },
137
- requiresReauth: false,
138
- };
139
- }
140
-
141
- // Validate user hasn't changed after reauthentication
142
- if (originalUserId) {
143
- const validation = userValidationService.validateUserUnchanged(auth, originalUserId);
144
- if (!validation.success) {
145
- return {
146
- success: false,
147
- error: validation.error!,
148
- requiresReauth: false,
149
- };
150
- }
@@ -1,24 +0,0 @@
1
- }
2
-
3
- // Delete account
4
- const result = await repository.deleteAccount(user);
5
- if (result.success) {
6
- return { success: true };
7
- }
8
-
9
- return {
10
- success: false,
11
- error: result.error,
12
- requiresReauth: false,
13
- };
14
- } catch (error: unknown) {
15
- return {
16
- success: false,
17
- error: {
18
- code: 'auth/failed',
19
- message: error instanceof Error ? error.message : 'Unknown error',
20
- },
21
- requiresReauth: false,
22
- };
23
- }
24
- }
@@ -1,266 +0,0 @@
1
- /**
2
- * Account Deletion Repository
3
- * Single Responsibility: Handle account deletion persistence
4
- *
5
- * Infrastructure repository that manages account deletion operations.
6
- * Uses ServiceBase for error handling and initialization.
7
- *
8
- * Max lines: 150 (enforced for maintainability)
9
- */
10
-
11
- import { deleteUser, type User } from 'firebase/auth';
12
- import { ServiceBase } from '../../../../shared/infrastructure/base/ServiceBase';
13
- import type { Result } from '../../../../shared/domain/utils';
14
- import { successResult } from '../../../../shared/domain/utils';
15
- import { markUserDeleted } from '../../../auth/infrastructure/services/user-document.service';
16
-
17
- /**
18
- * Account deletion repository
19
- * Manages account deletion operations and user document cleanup
20
- */
21
- export class AccountDeletionRepository extends ServiceBase {
22
- constructor() {
23
- super({
24
- serviceName: 'AccountDeletionRepository',
25
- autoInitialize: true,
26
- });
27
- }
28
-
29
- /**
30
- * Delete user account from Firebase Auth
31
- * Marks user document as deleted before account removal
32
- */
33
- async deleteAccount(user: User): Promise<Result<void>> {
34
- return this.execute(async () => {
35
- this.log('Deleting account', { userId: user.uid });
36
-
37
- // Mark user document as deleted
38
- const marked = await markUserDeleted(user.uid);
39
- if (!marked && __DEV__) {
40
- this.logError('Failed to mark user document as deleted');
41
- }
42
-
43
- // Delete user account
44
- await deleteUser(user);
45
-
46
- this.log('Account deleted successfully', { userId: user.uid });
47
- }, 'account-deletion/delete-failed');
48
- }
49
-
50
- /**
51
- * Validate user can be deleted
52
- * Checks user is not anonymous and has valid provider
53
- */
54
- async validateForDeletion(user: User | null): Promise<Result<{ userId: string; provider: string }>> {
55
- return this.executeSync(() => {
56
- if (!user) {
57
- return {
58
- success: false,
59
- error: {
60
- code: 'auth/not-ready',
61
- message: 'No authenticated user',
62
- },
63
- };
64
- }
65
-
66
- if (user.isAnonymous) {
67
- return {
68
- success: false,
69
- error: {
70
- code: 'auth/anonymous',
71
- message: 'Cannot delete anonymous account',
72
- },
73
- };
74
- }
75
-
76
- const provider = this.getUserAuthProvider(user);
77
- if (!provider) {
78
- return {
79
- success: false,
80
- error: {
81
- code: 'auth/unsupported',
82
- message: 'Unsupported auth provider',
83
- },
84
- };
85
- }
86
-
87
- return successResult({
88
- userId: user.uid,
89
- provider,
90
- });
91
- }, 'account-deletion/validation-failed');
92
- }
93
-
94
- /**
95
- * Get user's auth provider
96
- */
97
- private getUserAuthProvider(user: User): string | null {
98
- if (!user.providerData || user.providerData.length === 0) {
99
- return null;
100
- }
101
-
102
- for (const userInfo of user.providerData) {
103
- if (userInfo.providerId) {
104
- return userInfo.providerId;
105
- }
106
- }
107
-
108
- return null;
109
- }
110
-
111
- /**
112
- * Check if user is email/password user
113
- */
114
- isEmailPasswordUser(user: User): boolean {
115
- return this.getUserAuthProvider(user) === 'password';
116
- }
117
-
118
- /**
119
- * Check if user is Google user
120
- */
121
- isGoogleUser(user: User): boolean {
122
- return this.getUserAuthProvider(user) === 'google.com';
123
- }
124
-
125
- /**
126
- * Check if user is Apple user
127
- */
128
- isAppleUser(user: User): boolean {
129
- return this.getUserAuthProvider(user) === 'apple.com';
130
- }
131
-
132
- /**
133
- * Get user ID from user object
134
- */
135
- getUserId(user: User): string {
136
- return user.uid;
137
- }
138
-
139
- /**
140
- * Check if user email is verified
141
- */
142
- isEmailVerified(user: User): boolean {
143
- return user.emailVerified || false;
144
- }
145
-
146
- /**
147
- * Get user email
148
- */
149
- getEmail(user: User): string | null {
150
- return user.email || null;
151
- }
152
-
153
- /**
154
- * Get account creation time
155
- */
156
- getCreationTime(user: User): Date | null {
157
- if (!user.metadata.creationTime) {
158
- return null;
159
- }
160
- return new Date(user.metadata.creationTime);
161
- }
162
-
163
- /**
164
- * Get last sign-in time
165
- */
166
- getLastSignInTime(user: User): Date | null {
167
- if (!user.metadata.lastSignInTime) {
168
- return null;
169
- }
170
- return new Date(user.metadata.lastSignInTime);
171
- }
172
-
173
- /**
174
- * Check if account is new (created within specified days)
175
- */
176
- isAccountNew(user: User, maxAgeDays: number = 1): boolean {
177
- const creationTime = this.getCreationTime(user);
178
- if (!creationTime) return false;
179
-
180
- const ageMs = Date.now() - creationTime.getTime();
181
- const maxAgeMs = maxAgeDays * 24 * 60 * 60 * 1000;
182
-
183
- return ageMs <= maxAgeMs;
184
- }
185
-
186
- /**
187
- * Check if user recently signed in
188
- */
189
- isRecentSignIn(user: User, maxAgeMinutes: number = 5): boolean {
190
- const lastSignIn = this.getLastSignInTime(user);
191
- if (!lastSignIn) return false;
192
-
193
- const timeSinceSignIn = Date.now() - lastSignIn.getTime();
194
- const maxAgeMs = maxAgeMinutes * 60 * 1000;
195
-
196
- return timeSinceSignIn <= maxAgeMs;
197
- }
198
-
199
- /**
200
- * Mark user as deleted in database
201
- * Separate method for flexibility
202
- */
203
- async markUserDeleted(userId: string): Promise<Result<void>> {
204
- return this.execute(async () => {
205
- this.log('Marking user as deleted', { userId });
206
-
207
- const marked = await markUserDeleted(userId);
208
- if (!marked) {
209
- this.logError('Failed to mark user as deleted in database');
210
- }
211
-
212
- return successResult();
213
- }, 'account-deletion/mark-failed');
214
- }
215
-
216
- /**
217
- * Cleanup user data
218
- * Override in subclass for custom cleanup logic
219
- */
220
- protected async cleanupUserData(userId: string): Promise<Result<void>> {
221
- return this.execute(async () => {
222
- this.log('Cleaning up user data', { userId });
223
- // Override in subclass for custom cleanup
224
- return successResult();
225
- }, 'account-deletion/cleanup-failed');
226
- }
227
-
228
- /**
229
- * Complete deletion with cleanup
230
- * Deletes account and cleans up user data
231
- */
232
- async deleteWithCleanup(user: User): Promise<Result<void>> {
233
- return this.execute(async () => {
234
- this.log('Starting deletion with cleanup', { userId: user.uid });
235
-
236
- // Delete account (includes marking document as deleted)
237
- const deleteResult = await this.deleteAccount(user);
238
- if (!deleteResult.success) {
239
- return deleteResult;
240
- }
241
-
242
- // Cleanup additional user data
243
- const cleanupResult = await this.cleanupUserData(user.uid);
244
- if (!cleanupResult.success) {
245
- this.logError('Cleanup failed, but account was deleted', {
246
- userId: user.uid,
247
- error: cleanupResult.error,
248
- });
249
- }
250
-
251
- this.log('Deletion with cleanup completed', { userId: user.uid });
252
- }, 'account-deletion/complete-failed');
253
- }
254
- }
255
-
256
- /**
257
- * Factory function to create account deletion repository
258
- */
259
- export function createAccountDeletionRepository(): AccountDeletionRepository {
260
- return new AccountDeletionRepository();
261
- }
262
-
263
- /**
264
- * Default singleton instance
265
- */
266
- export const accountDeletionRepository = createAccountDeletionRepository();
@@ -1,150 +0,0 @@
1
- /**
2
- * Account Deletion Repository
3
- * Single Responsibility: Handle account deletion persistence
4
- *
5
- * Infrastructure repository that manages account deletion operations.
6
- * Uses ServiceBase for error handling and initialization.
7
- *
8
- * Max lines: 150 (enforced for maintainability)
9
- */
10
-
11
- import { deleteUser, type User } from 'firebase/auth';
12
- import { ServiceBase } from '../../../../shared/infrastructure/base/ServiceBase';
13
- import type { Result } from '../../../../shared/domain/utils';
14
- import { successResult } from '../../../../shared/domain/utils';
15
- import { markUserDeleted } from '../../../auth/infrastructure/services/user-document.service';
16
-
17
- /**
18
- * Account deletion repository
19
- * Manages account deletion operations and user document cleanup
20
- */
21
- export class AccountDeletionRepository extends ServiceBase {
22
- constructor() {
23
- super({
24
- serviceName: 'AccountDeletionRepository',
25
- autoInitialize: true,
26
- });
27
- }
28
-
29
- /**
30
- * Delete user account from Firebase Auth
31
- * Marks user document as deleted before account removal
32
- */
33
- async deleteAccount(user: User): Promise<Result<void>> {
34
- return this.execute(async () => {
35
- this.log('Deleting account', { userId: user.uid });
36
-
37
- // Mark user document as deleted
38
- const marked = await markUserDeleted(user.uid);
39
- if (!marked && __DEV__) {
40
- this.logError('Failed to mark user document as deleted');
41
- }
42
-
43
- // Delete user account
44
- await deleteUser(user);
45
-
46
- this.log('Account deleted successfully', { userId: user.uid });
47
- }, 'account-deletion/delete-failed');
48
- }
49
-
50
- /**
51
- * Validate user can be deleted
52
- * Checks user is not anonymous and has valid provider
53
- */
54
- async validateForDeletion(user: User | null): Promise<Result<{ userId: string; provider: string }>> {
55
- return this.executeSync(() => {
56
- if (!user) {
57
- return {
58
- success: false,
59
- error: {
60
- code: 'auth/not-ready',
61
- message: 'No authenticated user',
62
- },
63
- };
64
- }
65
-
66
- if (user.isAnonymous) {
67
- return {
68
- success: false,
69
- error: {
70
- code: 'auth/anonymous',
71
- message: 'Cannot delete anonymous account',
72
- },
73
- };
74
- }
75
-
76
- const provider = this.getUserAuthProvider(user);
77
- if (!provider) {
78
- return {
79
- success: false,
80
- error: {
81
- code: 'auth/unsupported',
82
- message: 'Unsupported auth provider',
83
- },
84
- };
85
- }
86
-
87
- return successResult({
88
- userId: user.uid,
89
- provider,
90
- });
91
- }, 'account-deletion/validation-failed');
92
- }
93
-
94
- /**
95
- * Get user's auth provider
96
- */
97
- private getUserAuthProvider(user: User): string | null {
98
- if (!user.providerData || user.providerData.length === 0) {
99
- return null;
100
- }
101
-
102
- for (const userInfo of user.providerData) {
103
- if (userInfo.providerId) {
104
- return userInfo.providerId;
105
- }
106
- }
107
-
108
- return null;
109
- }
110
-
111
- /**
112
- * Check if user is email/password user
113
- */
114
- isEmailPasswordUser(user: User): boolean {
115
- return this.getUserAuthProvider(user) === 'password';
116
- }
117
-
118
- /**
119
- * Check if user is Google user
120
- */
121
- isGoogleUser(user: User): boolean {
122
- return this.getUserAuthProvider(user) === 'google.com';
123
- }
124
-
125
- /**
126
- * Check if user is Apple user
127
- */
128
- isAppleUser(user: User): boolean {
129
- return this.getUserAuthProvider(user) === 'apple.com';
130
- }
131
-
132
- /**
133
- * Get user ID from user object
134
- */
135
- getUserId(user: User): string {
136
- return user.uid;
137
- }
138
-
139
- /**
140
- * Check if user email is verified
141
- */
142
- isEmailVerified(user: User): boolean {
143
- return user.emailVerified || false;
144
- }
145
-
146
- /**
147
- * Get user email
148
- */
149
- getEmail(user: User): string | null {
150
- return user.email || null;
@@ -1,116 +0,0 @@
1
- }
2
-
3
- /**
4
- * Get account creation time
5
- */
6
- getCreationTime(user: User): Date | null {
7
- if (!user.metadata.creationTime) {
8
- return null;
9
- }
10
- return new Date(user.metadata.creationTime);
11
- }
12
-
13
- /**
14
- * Get last sign-in time
15
- */
16
- getLastSignInTime(user: User): Date | null {
17
- if (!user.metadata.lastSignInTime) {
18
- return null;
19
- }
20
- return new Date(user.metadata.lastSignInTime);
21
- }
22
-
23
- /**
24
- * Check if account is new (created within specified days)
25
- */
26
- isAccountNew(user: User, maxAgeDays: number = 1): boolean {
27
- const creationTime = this.getCreationTime(user);
28
- if (!creationTime) return false;
29
-
30
- const ageMs = Date.now() - creationTime.getTime();
31
- const maxAgeMs = maxAgeDays * 24 * 60 * 60 * 1000;
32
-
33
- return ageMs <= maxAgeMs;
34
- }
35
-
36
- /**
37
- * Check if user recently signed in
38
- */
39
- isRecentSignIn(user: User, maxAgeMinutes: number = 5): boolean {
40
- const lastSignIn = this.getLastSignInTime(user);
41
- if (!lastSignIn) return false;
42
-
43
- const timeSinceSignIn = Date.now() - lastSignIn.getTime();
44
- const maxAgeMs = maxAgeMinutes * 60 * 1000;
45
-
46
- return timeSinceSignIn <= maxAgeMs;
47
- }
48
-
49
- /**
50
- * Mark user as deleted in database
51
- * Separate method for flexibility
52
- */
53
- async markUserDeleted(userId: string): Promise<Result<void>> {
54
- return this.execute(async () => {
55
- this.log('Marking user as deleted', { userId });
56
-
57
- const marked = await markUserDeleted(userId);
58
- if (!marked) {
59
- this.logError('Failed to mark user as deleted in database');
60
- }
61
-
62
- return successResult();
63
- }, 'account-deletion/mark-failed');
64
- }
65
-
66
- /**
67
- * Cleanup user data
68
- * Override in subclass for custom cleanup logic
69
- */
70
- protected async cleanupUserData(userId: string): Promise<Result<void>> {
71
- return this.execute(async () => {
72
- this.log('Cleaning up user data', { userId });
73
- // Override in subclass for custom cleanup
74
- return successResult();
75
- }, 'account-deletion/cleanup-failed');
76
- }
77
-
78
- /**
79
- * Complete deletion with cleanup
80
- * Deletes account and cleans up user data
81
- */
82
- async deleteWithCleanup(user: User): Promise<Result<void>> {
83
- return this.execute(async () => {
84
- this.log('Starting deletion with cleanup', { userId: user.uid });
85
-
86
- // Delete account (includes marking document as deleted)
87
- const deleteResult = await this.deleteAccount(user);
88
- if (!deleteResult.success) {
89
- return deleteResult;
90
- }
91
-
92
- // Cleanup additional user data
93
- const cleanupResult = await this.cleanupUserData(user.uid);
94
- if (!cleanupResult.success) {
95
- this.logError('Cleanup failed, but account was deleted', {
96
- userId: user.uid,
97
- error: cleanupResult.error,
98
- });
99
- }
100
-
101
- this.log('Deletion with cleanup completed', { userId: user.uid });
102
- }, 'account-deletion/complete-failed');
103
- }
104
- }
105
-
106
- /**
107
- * Factory function to create account deletion repository
108
- */
109
- export function createAccountDeletionRepository(): AccountDeletionRepository {
110
- return new AccountDeletionRepository();
111
- }
112
-
113
- /**
114
- * Default singleton instance
115
- */
116
- export const accountDeletionRepository = createAccountDeletionRepository();