@umituz/react-native-firebase 2.6.3 → 2.6.5

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 (108) 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/config/FirebaseAuthClient.ts +48 -60
  11. package/src/domains/auth/infrastructure/config/index.ts +2 -0
  12. package/src/domains/auth/infrastructure/config/initializers/index.ts +1 -0
  13. package/src/domains/auth/infrastructure/services/index.ts +16 -0
  14. package/src/domains/auth/infrastructure/services/utils/index.ts +1 -0
  15. package/src/domains/auth/infrastructure/stores/index.ts +1 -0
  16. package/src/domains/auth/infrastructure/utils/index.ts +1 -0
  17. package/src/domains/auth/infrastructure.ts +11 -0
  18. package/src/domains/auth/presentation/hooks/useGoogleOAuth.ts +18 -59
  19. package/src/domains/firestore/domain/entities/Collection.ts +0 -2
  20. package/src/domains/firestore/domain/index.ts +6 -2
  21. package/src/domains/firestore/domain/value-objects/WhereClause.ts +0 -14
  22. package/src/domains/firestore/index.ts +0 -1
  23. package/src/domains/firestore/infrastructure/config/FirestoreClient.ts +42 -60
  24. package/src/domains/firestore/presentation/hooks/useFirestoreMutation.ts +1 -1
  25. package/src/domains/firestore/presentation/hooks/useFirestoreQuery.ts +1 -1
  26. package/src/shared/infrastructure/base/ErrorHandler.ts +81 -0
  27. package/src/shared/infrastructure/base/ServiceBase.ts +62 -0
  28. package/src/shared/infrastructure/config/base/ServiceClientSingleton.ts +39 -0
  29. package/src/application/auth/ports/AuthPort.ts.bak +0 -164
  30. package/src/application/auth/ports/AuthPort_part_aa +0 -150
  31. package/src/application/auth/ports/AuthPort_part_ab +0 -14
  32. package/src/application/auth/use-cases/SignInUseCase.ts.bak +0 -253
  33. package/src/application/auth/use-cases/SignInUseCaseHelpers.ts +0 -0
  34. package/src/application/auth/use-cases/SignInUseCaseMain.ts +0 -0
  35. package/src/application/auth/use-cases/SignInUseCase_part_aa +0 -150
  36. package/src/application/auth/use-cases/SignInUseCase_part_ab +0 -103
  37. package/src/application/auth/use-cases/SignOutUseCase.ts.bak +0 -288
  38. package/src/application/auth/use-cases/SignOutUseCaseCleanup.ts +0 -0
  39. package/src/application/auth/use-cases/SignOutUseCaseMain.ts +0 -0
  40. package/src/application/auth/use-cases/SignOutUseCase_part_aa +0 -150
  41. package/src/application/auth/use-cases/SignOutUseCase_part_ab +0 -138
  42. package/src/domains/account-deletion/domain/services/UserValidationHelpers.ts.bak +0 -181
  43. package/src/domains/account-deletion/domain/services/UserValidationHelpers_part_aa +0 -150
  44. package/src/domains/account-deletion/domain/services/UserValidationHelpers_part_ab +0 -31
  45. package/src/domains/account-deletion/domain/services/UserValidationService.ts.bak +0 -286
  46. package/src/domains/account-deletion/domain/services/UserValidationService_part_aa +0 -150
  47. package/src/domains/account-deletion/domain/services/UserValidationService_part_ab +0 -136
  48. package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor.ts.bak +0 -230
  49. package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor_part_aa +0 -150
  50. package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor_part_ab +0 -80
  51. package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler.ts.bak +0 -174
  52. package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler_part_aa +0 -150
  53. package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler_part_ab +0 -24
  54. package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository.ts.bak +0 -266
  55. package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository_part_aa +0 -150
  56. package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository_part_ab +0 -116
  57. package/src/domains/account-deletion/infrastructure/services/reauthentication.service.ts.bak +0 -160
  58. package/src/domains/account-deletion/infrastructure/services/reauthentication.service_part_aa +0 -150
  59. package/src/domains/account-deletion/infrastructure/services/reauthentication.service_part_ab +0 -10
  60. package/src/domains/auth/infrastructure.ts.bak +0 -156
  61. package/src/domains/auth/infrastructure_part_aa +0 -150
  62. package/src/domains/auth/infrastructure_part_ab +0 -6
  63. package/src/domains/auth/presentation/hooks/GoogleOAuthHelpers.ts +0 -0
  64. package/src/domains/auth/presentation/hooks/GoogleOAuthHookService.ts.bak +0 -247
  65. package/src/domains/auth/presentation/hooks/GoogleOAuthHookService_part_aa +0 -150
  66. package/src/domains/auth/presentation/hooks/GoogleOAuthHookService_part_ab +0 -97
  67. package/src/domains/auth/presentation/hooks/GoogleOAuthService.ts +0 -0
  68. package/src/domains/firestore/domain/entities/Collection.ts.bak +0 -288
  69. package/src/domains/firestore/domain/entities/Collection_part_aa +0 -150
  70. package/src/domains/firestore/domain/entities/Collection_part_ab +0 -138
  71. package/src/domains/firestore/domain/entities/Document.ts.bak +0 -233
  72. package/src/domains/firestore/domain/entities/DocumentHelpers.ts +0 -0
  73. package/src/domains/firestore/domain/entities/DocumentMain.ts +0 -0
  74. package/src/domains/firestore/domain/entities/Document_part_aa +0 -150
  75. package/src/domains/firestore/domain/entities/Document_part_ab +0 -83
  76. package/src/domains/firestore/domain/services/QueryService.ts.bak +0 -182
  77. package/src/domains/firestore/domain/services/QueryServiceAnalysis.ts.bak +0 -169
  78. package/src/domains/firestore/domain/services/QueryServiceAnalysis_part_aa +0 -150
  79. package/src/domains/firestore/domain/services/QueryServiceAnalysis_part_ab +0 -19
  80. package/src/domains/firestore/domain/services/QueryServiceHelpers.ts.bak +0 -151
  81. package/src/domains/firestore/domain/services/QueryServiceHelpers_part_aa +0 -150
  82. package/src/domains/firestore/domain/services/QueryServiceHelpers_part_ab +0 -1
  83. package/src/domains/firestore/domain/services/QueryService_part_aa +0 -150
  84. package/src/domains/firestore/domain/services/QueryService_part_ab +0 -32
  85. package/src/domains/firestore/domain/value-objects/QueryOptions.ts.bak +0 -191
  86. package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization.ts.bak +0 -207
  87. package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization_part_aa +0 -150
  88. package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization_part_ab +0 -57
  89. package/src/domains/firestore/domain/value-objects/QueryOptionsValidation.ts.bak +0 -182
  90. package/src/domains/firestore/domain/value-objects/QueryOptionsValidation_part_aa +0 -150
  91. package/src/domains/firestore/domain/value-objects/QueryOptionsValidation_part_ab +0 -32
  92. package/src/domains/firestore/domain/value-objects/QueryOptions_part_aa +0 -150
  93. package/src/domains/firestore/domain/value-objects/QueryOptions_part_ab +0 -41
  94. package/src/domains/firestore/domain/value-objects/WhereClause.ts.bak +0 -299
  95. package/src/domains/firestore/domain/value-objects/WhereClauseFactory.ts.bak +0 -207
  96. package/src/domains/firestore/domain/value-objects/WhereClauseFactory_part_aa +0 -150
  97. package/src/domains/firestore/domain/value-objects/WhereClauseFactory_part_ab +0 -57
  98. package/src/domains/firestore/domain/value-objects/WhereClause_part_aa +0 -150
  99. package/src/domains/firestore/domain/value-objects/WhereClause_part_ab +0 -149
  100. package/src/shared/infrastructure/base/ErrorHandler.ts.bak +0 -189
  101. package/src/shared/infrastructure/base/ErrorHandler_part_aa +0 -150
  102. package/src/shared/infrastructure/base/ErrorHandler_part_ab +0 -39
  103. package/src/shared/infrastructure/base/ServiceBase.ts.bak +0 -220
  104. package/src/shared/infrastructure/base/ServiceBase_part_aa +0 -150
  105. package/src/shared/infrastructure/base/ServiceBase_part_ab +0 -70
  106. package/src/shared/infrastructure/config/base/ServiceClientSingleton.ts.bak +0 -155
  107. package/src/shared/infrastructure/config/base/ServiceClientSingleton_part_aa +0 -150
  108. package/src/shared/infrastructure/config/base/ServiceClientSingleton_part_ab +0 -5
@@ -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();
@@ -1,160 +0,0 @@
1
- /**
2
- * Reauthentication Service
3
- * Handles Firebase Auth reauthentication for sensitive operations
4
- */
5
-
6
- import {
7
- reauthenticateWithCredential,
8
- GoogleAuthProvider,
9
- OAuthProvider,
10
- EmailAuthProvider,
11
- type User,
12
- } from "firebase/auth";
13
- import { Platform } from "react-native";
14
-
15
- /**
16
- * Lazy-loads expo-apple-authentication (optional peer dependency).
17
- * Returns null if the package is not installed.
18
- */
19
- function getAppleAuthModule(): typeof import("expo-apple-authentication") | null {
20
- try {
21
- // Dynamic require needed for optional peer dependency
22
- // eslint-disable-next-line @typescript-eslint/no-require-imports
23
- return require("expo-apple-authentication");
24
- } catch {
25
- return null;
26
- }
27
- }
28
- import { generateNonce, hashNonce } from "../../../auth/infrastructure/services/crypto.util";
29
- import { executeOperation, failureResultFrom, toErrorInfo, ERROR_MESSAGES } from "../../../../shared/domain/utils";
30
- import { isCancelledError } from "../../../../shared/domain/utils/error-handlers/error-checkers";
31
- import type {
32
- ReauthenticationResult,
33
- AuthProviderType,
34
- ReauthCredentialResult
35
- } from "../../application/ports/reauthentication.types";
36
-
37
- /**
38
- * Validates email format
39
- */
40
- function isValidEmail(email: string): boolean {
41
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
42
- return emailRegex.test(email);
43
- }
44
-
45
- /**
46
- * Validates password (Firebase minimum is 6 characters)
47
- */
48
- function isValidPassword(password: string): boolean {
49
- return password.length >= 6;
50
- }
51
-
52
- export function getUserAuthProvider(user: User): AuthProviderType {
53
- if (user.isAnonymous) return "anonymous";
54
- const data = user.providerData;
55
- if (!data?.length) return "unknown";
56
- if (data.find(p => p.providerId === "google.com")) return "google.com";
57
- if (data.find(p => p.providerId === "apple.com")) return "apple.com";
58
- if (data.find(p => p.providerId === "password")) return "password";
59
- return "unknown";
60
- }
61
-
62
- export async function reauthenticateWithGoogle(user: User, idToken: string): Promise<ReauthenticationResult> {
63
- return executeOperation(async () => {
64
- await reauthenticateWithCredential(user, GoogleAuthProvider.credential(idToken));
65
- });
66
- }
67
-
68
- export async function reauthenticateWithPassword(user: User, pass: string): Promise<ReauthenticationResult> {
69
- const email = user.email;
70
- if (!email) {
71
- return failureResultFrom("auth/no-email", ERROR_MESSAGES.AUTH.NO_USER);
72
- }
73
-
74
- // FIX: Add email validation
75
- if (!isValidEmail(email)) {
76
- return failureResultFrom("auth/invalid-email", ERROR_MESSAGES.AUTH.INVALID_EMAIL);
77
- }
78
-
79
- // FIX: Add password validation
80
- if (!isValidPassword(pass)) {
81
- return failureResultFrom("auth/invalid-password", ERROR_MESSAGES.AUTH.INVALID_PASSWORD);
82
- }
83
-
84
- return executeOperation(async () => {
85
- await reauthenticateWithCredential(user, EmailAuthProvider.credential(email, pass));
86
- });
87
- }
88
-
89
- export async function getAppleReauthCredential(): Promise<ReauthCredentialResult> {
90
- if (Platform.OS !== "ios") {
91
- return {
92
- success: false,
93
- error: { code: "auth/ios-only", message: "iOS only" }
94
- };
95
- }
96
-
97
- const AppleAuthentication = getAppleAuthModule();
98
- if (!AppleAuthentication) {
99
- return {
100
- success: false,
101
- error: { code: "auth/unavailable", message: "expo-apple-authentication is not installed" }
102
- };
103
- }
104
-
105
- try {
106
- const isAvailable = await AppleAuthentication.isAvailableAsync();
107
- if (!isAvailable) {
108
- return {
109
- success: false,
110
- error: { code: "auth/unavailable", message: "Unavailable" }
111
- };
112
- }
113
-
114
- const nonce = await generateNonce();
115
- const hashed = await hashNonce(nonce);
116
- const apple = await AppleAuthentication.signInAsync({
117
- requestedScopes: [
118
- AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
119
- AppleAuthentication.AppleAuthenticationScope.EMAIL
120
- ],
121
- nonce: hashed,
122
- });
123
-
124
- if (!apple.identityToken) {
125
- return {
126
- success: false,
127
- error: { code: "auth/no-token", message: "No token" }
128
- };
129
- }
130
-
131
- const credential = new OAuthProvider("apple.com").credential({
132
- idToken: apple.identityToken,
133
- rawNonce: nonce
134
- });
135
-
136
- return {
137
- success: true,
138
- credential
139
- };
140
- } catch (error: unknown) {
141
- const errorInfo = toErrorInfo(error, 'auth/failed');
142
- const code = isCancelledError(errorInfo) ? "auth/cancelled" : errorInfo.code;
143
- return {
144
- success: false,
145
- error: { code, message: errorInfo.message }
146
- };
147
- }
148
- }
149
-
150
- export async function reauthenticateWithApple(user: User): Promise<ReauthenticationResult> {
151
- const res = await getAppleReauthCredential();
152
- if (!res.success || !res.credential) {
153
- return { success: false, error: res.error ?? { code: "auth/failed", message: "Failed to get credential" } };
154
- }
155
-
156
- const credential = res.credential;
157
- return executeOperation(async () => {
158
- await reauthenticateWithCredential(user, credential);
159
- });
160
- }
@@ -1,150 +0,0 @@
1
- /**
2
- * Reauthentication Service
3
- * Handles Firebase Auth reauthentication for sensitive operations
4
- */
5
-
6
- import {
7
- reauthenticateWithCredential,
8
- GoogleAuthProvider,
9
- OAuthProvider,
10
- EmailAuthProvider,
11
- type User,
12
- } from "firebase/auth";
13
- import { Platform } from "react-native";
14
-
15
- /**
16
- * Lazy-loads expo-apple-authentication (optional peer dependency).
17
- * Returns null if the package is not installed.
18
- */
19
- function getAppleAuthModule(): typeof import("expo-apple-authentication") | null {
20
- try {
21
- // Dynamic require needed for optional peer dependency
22
- // eslint-disable-next-line @typescript-eslint/no-require-imports
23
- return require("expo-apple-authentication");
24
- } catch {
25
- return null;
26
- }
27
- }
28
- import { generateNonce, hashNonce } from "../../../auth/infrastructure/services/crypto.util";
29
- import { executeOperation, failureResultFrom, toErrorInfo, ERROR_MESSAGES } from "../../../../shared/domain/utils";
30
- import { isCancelledError } from "../../../../shared/domain/utils/error-handlers/error-checkers";
31
- import type {
32
- ReauthenticationResult,
33
- AuthProviderType,
34
- ReauthCredentialResult
35
- } from "../../application/ports/reauthentication.types";
36
-
37
- /**
38
- * Validates email format
39
- */
40
- function isValidEmail(email: string): boolean {
41
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
42
- return emailRegex.test(email);
43
- }
44
-
45
- /**
46
- * Validates password (Firebase minimum is 6 characters)
47
- */
48
- function isValidPassword(password: string): boolean {
49
- return password.length >= 6;
50
- }
51
-
52
- export function getUserAuthProvider(user: User): AuthProviderType {
53
- if (user.isAnonymous) return "anonymous";
54
- const data = user.providerData;
55
- if (!data?.length) return "unknown";
56
- if (data.find(p => p.providerId === "google.com")) return "google.com";
57
- if (data.find(p => p.providerId === "apple.com")) return "apple.com";
58
- if (data.find(p => p.providerId === "password")) return "password";
59
- return "unknown";
60
- }
61
-
62
- export async function reauthenticateWithGoogle(user: User, idToken: string): Promise<ReauthenticationResult> {
63
- return executeOperation(async () => {
64
- await reauthenticateWithCredential(user, GoogleAuthProvider.credential(idToken));
65
- });
66
- }
67
-
68
- export async function reauthenticateWithPassword(user: User, pass: string): Promise<ReauthenticationResult> {
69
- const email = user.email;
70
- if (!email) {
71
- return failureResultFrom("auth/no-email", ERROR_MESSAGES.AUTH.NO_USER);
72
- }
73
-
74
- // FIX: Add email validation
75
- if (!isValidEmail(email)) {
76
- return failureResultFrom("auth/invalid-email", ERROR_MESSAGES.AUTH.INVALID_EMAIL);
77
- }
78
-
79
- // FIX: Add password validation
80
- if (!isValidPassword(pass)) {
81
- return failureResultFrom("auth/invalid-password", ERROR_MESSAGES.AUTH.INVALID_PASSWORD);
82
- }
83
-
84
- return executeOperation(async () => {
85
- await reauthenticateWithCredential(user, EmailAuthProvider.credential(email, pass));
86
- });
87
- }
88
-
89
- export async function getAppleReauthCredential(): Promise<ReauthCredentialResult> {
90
- if (Platform.OS !== "ios") {
91
- return {
92
- success: false,
93
- error: { code: "auth/ios-only", message: "iOS only" }
94
- };
95
- }
96
-
97
- const AppleAuthentication = getAppleAuthModule();
98
- if (!AppleAuthentication) {
99
- return {
100
- success: false,
101
- error: { code: "auth/unavailable", message: "expo-apple-authentication is not installed" }
102
- };
103
- }
104
-
105
- try {
106
- const isAvailable = await AppleAuthentication.isAvailableAsync();
107
- if (!isAvailable) {
108
- return {
109
- success: false,
110
- error: { code: "auth/unavailable", message: "Unavailable" }
111
- };
112
- }
113
-
114
- const nonce = await generateNonce();
115
- const hashed = await hashNonce(nonce);
116
- const apple = await AppleAuthentication.signInAsync({
117
- requestedScopes: [
118
- AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
119
- AppleAuthentication.AppleAuthenticationScope.EMAIL
120
- ],
121
- nonce: hashed,
122
- });
123
-
124
- if (!apple.identityToken) {
125
- return {
126
- success: false,
127
- error: { code: "auth/no-token", message: "No token" }
128
- };
129
- }
130
-
131
- const credential = new OAuthProvider("apple.com").credential({
132
- idToken: apple.identityToken,
133
- rawNonce: nonce
134
- });
135
-
136
- return {
137
- success: true,
138
- credential
139
- };
140
- } catch (error: unknown) {
141
- const errorInfo = toErrorInfo(error, 'auth/failed');
142
- const code = isCancelledError(errorInfo) ? "auth/cancelled" : errorInfo.code;
143
- return {
144
- success: false,
145
- error: { code, message: errorInfo.message }
146
- };
147
- }
148
- }
149
-
150
- export async function reauthenticateWithApple(user: User): Promise<ReauthenticationResult> {
@@ -1,10 +0,0 @@
1
- const res = await getAppleReauthCredential();
2
- if (!res.success || !res.credential) {
3
- return { success: false, error: res.error ?? { code: "auth/failed", message: "Failed to get credential" } };
4
- }
5
-
6
- const credential = res.credential;
7
- return executeOperation(async () => {
8
- await reauthenticateWithCredential(user, credential);
9
- });
10
- }