@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.
- package/package.json +1 -1
- package/src/application/auth/index.ts +2 -34
- package/src/application/auth/use-cases/index.ts +1 -21
- package/src/domains/account-deletion/domain/index.ts +1 -8
- package/src/domains/account-deletion/index.ts +0 -42
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor.ts +79 -0
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionTypes.ts +0 -1
- package/src/domains/account-deletion/infrastructure/services/account-deletion.service.ts +2 -14
- package/src/domains/auth/index.ts +3 -12
- package/src/domains/auth/infrastructure.ts +11 -0
- package/src/domains/firestore/domain/entities/Collection.ts +0 -2
- package/src/domains/firestore/domain/index.ts +8 -12
- package/src/domains/firestore/domain/value-objects/{QueryOptions.ts.bak → QueryOptions.ts} +20 -68
- package/src/domains/firestore/domain/value-objects/QueryOptionsFactory.ts +95 -0
- package/src/domains/firestore/domain/value-objects/QueryOptionsHelpers.ts +110 -0
- package/src/domains/firestore/domain/value-objects/WhereClause.ts +115 -0
- package/src/domains/firestore/domain/value-objects/WhereClauseFactory.ts +101 -0
- package/src/domains/firestore/domain/value-objects/WhereClauseHelpers.ts +123 -0
- package/src/domains/firestore/domain/value-objects/WhereClauseValidation.ts +83 -0
- package/src/domains/firestore/presentation/hooks/useFirestoreMutation.ts +1 -1
- package/src/domains/firestore/presentation/hooks/useFirestoreQuery.ts +1 -1
- package/src/shared/infrastructure/config/base/ServiceClientSingleton.ts +29 -0
- package/src/application/auth/ports/AuthPort.ts.bak +0 -164
- package/src/application/auth/ports/AuthPort_part_aa +0 -150
- package/src/application/auth/ports/AuthPort_part_ab +0 -14
- package/src/application/auth/use-cases/SignInUseCase.ts.bak +0 -253
- package/src/application/auth/use-cases/SignInUseCaseHelpers.ts +0 -0
- package/src/application/auth/use-cases/SignInUseCaseMain.ts +0 -0
- package/src/application/auth/use-cases/SignInUseCase_part_aa +0 -150
- package/src/application/auth/use-cases/SignInUseCase_part_ab +0 -103
- package/src/application/auth/use-cases/SignOutUseCase.ts.bak +0 -288
- package/src/application/auth/use-cases/SignOutUseCaseCleanup.ts +0 -0
- package/src/application/auth/use-cases/SignOutUseCaseMain.ts +0 -0
- package/src/application/auth/use-cases/SignOutUseCase_part_aa +0 -150
- package/src/application/auth/use-cases/SignOutUseCase_part_ab +0 -138
- package/src/domains/account-deletion/domain/services/UserValidationHelpers.ts.bak +0 -181
- package/src/domains/account-deletion/domain/services/UserValidationHelpers_part_aa +0 -150
- package/src/domains/account-deletion/domain/services/UserValidationHelpers_part_ab +0 -31
- package/src/domains/account-deletion/domain/services/UserValidationService.ts.bak +0 -286
- package/src/domains/account-deletion/domain/services/UserValidationService_part_aa +0 -150
- package/src/domains/account-deletion/domain/services/UserValidationService_part_ab +0 -136
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor.ts.bak +0 -230
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor_part_aa +0 -150
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionExecutor_part_ab +0 -80
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler.ts.bak +0 -174
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler_part_aa +0 -150
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionReauthHandler_part_ab +0 -24
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository.ts.bak +0 -266
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository_part_aa +0 -150
- package/src/domains/account-deletion/infrastructure/services/AccountDeletionRepository_part_ab +0 -116
- package/src/domains/account-deletion/infrastructure/services/reauthentication.service.ts.bak +0 -160
- package/src/domains/account-deletion/infrastructure/services/reauthentication.service_part_aa +0 -150
- package/src/domains/account-deletion/infrastructure/services/reauthentication.service_part_ab +0 -10
- package/src/domains/auth/infrastructure.ts.bak +0 -156
- package/src/domains/auth/infrastructure_part_aa +0 -150
- package/src/domains/auth/infrastructure_part_ab +0 -6
- package/src/domains/auth/presentation/hooks/GoogleOAuthHelpers.ts +0 -0
- package/src/domains/auth/presentation/hooks/GoogleOAuthHookService.ts.bak +0 -247
- package/src/domains/auth/presentation/hooks/GoogleOAuthHookService_part_aa +0 -150
- package/src/domains/auth/presentation/hooks/GoogleOAuthHookService_part_ab +0 -97
- package/src/domains/auth/presentation/hooks/GoogleOAuthService.ts +0 -0
- package/src/domains/firestore/domain/entities/Collection.ts.bak +0 -288
- package/src/domains/firestore/domain/entities/Collection_part_aa +0 -150
- package/src/domains/firestore/domain/entities/Collection_part_ab +0 -138
- package/src/domains/firestore/domain/entities/Document.ts.bak +0 -233
- package/src/domains/firestore/domain/entities/DocumentHelpers.ts +0 -0
- package/src/domains/firestore/domain/entities/DocumentMain.ts +0 -0
- package/src/domains/firestore/domain/entities/Document_part_aa +0 -150
- package/src/domains/firestore/domain/entities/Document_part_ab +0 -83
- package/src/domains/firestore/domain/services/QueryService.ts.bak +0 -182
- package/src/domains/firestore/domain/services/QueryServiceAnalysis.ts.bak +0 -169
- package/src/domains/firestore/domain/services/QueryServiceAnalysis_part_aa +0 -150
- package/src/domains/firestore/domain/services/QueryServiceAnalysis_part_ab +0 -19
- package/src/domains/firestore/domain/services/QueryServiceHelpers.ts.bak +0 -151
- package/src/domains/firestore/domain/services/QueryServiceHelpers_part_aa +0 -150
- package/src/domains/firestore/domain/services/QueryServiceHelpers_part_ab +0 -1
- package/src/domains/firestore/domain/services/QueryService_part_aa +0 -150
- package/src/domains/firestore/domain/services/QueryService_part_ab +0 -32
- package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization.ts.bak +0 -207
- package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization_part_aa +0 -150
- package/src/domains/firestore/domain/value-objects/QueryOptionsSerialization_part_ab +0 -57
- package/src/domains/firestore/domain/value-objects/QueryOptionsValidation.ts.bak +0 -182
- package/src/domains/firestore/domain/value-objects/QueryOptionsValidation_part_aa +0 -150
- package/src/domains/firestore/domain/value-objects/QueryOptionsValidation_part_ab +0 -32
- package/src/domains/firestore/domain/value-objects/QueryOptions_part_aa +0 -150
- package/src/domains/firestore/domain/value-objects/QueryOptions_part_ab +0 -41
- package/src/domains/firestore/domain/value-objects/WhereClause.ts.bak +0 -299
- package/src/domains/firestore/domain/value-objects/WhereClauseFactory.ts.bak +0 -207
- package/src/domains/firestore/domain/value-objects/WhereClauseFactory_part_aa +0 -150
- package/src/domains/firestore/domain/value-objects/WhereClauseFactory_part_ab +0 -57
- package/src/domains/firestore/domain/value-objects/WhereClause_part_aa +0 -150
- package/src/domains/firestore/domain/value-objects/WhereClause_part_ab +0 -149
- package/src/shared/infrastructure/base/ErrorHandler.ts.bak +0 -189
- package/src/shared/infrastructure/base/ErrorHandler_part_aa +0 -150
- package/src/shared/infrastructure/base/ErrorHandler_part_ab +0 -39
- package/src/shared/infrastructure/base/ServiceBase.ts.bak +0 -220
- package/src/shared/infrastructure/base/ServiceBase_part_aa +0 -150
- package/src/shared/infrastructure/base/ServiceBase_part_ab +0 -70
- package/src/shared/infrastructure/config/base/ServiceClientSingleton.ts.bak +0 -155
- package/src/shared/infrastructure/config/base/ServiceClientSingleton_part_aa +0 -150
- package/src/shared/infrastructure/config/base/ServiceClientSingleton_part_ab +0 -5
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sign In Use Case
|
|
3
|
-
* Single Responsibility: Handle user sign in operations
|
|
4
|
-
*
|
|
5
|
-
* Application use case for user authentication.
|
|
6
|
-
* Coordinates domain services and infrastructure.
|
|
7
|
-
*
|
|
8
|
-
* Max lines: 150 (enforced for maintainability)
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import type { User } from 'firebase/auth';
|
|
12
|
-
import type { Result } from '../../../shared/domain/utils';
|
|
13
|
-
import type { IAuthPort, EmailCredentials, SignInResult } from '../ports/AuthPort';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Sign in use case result
|
|
17
|
-
*/
|
|
18
|
-
export interface SignInUseCaseResult extends Result<SignInResult> {
|
|
19
|
-
readonly requiresVerification?: boolean;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Sign in use case options
|
|
24
|
-
*/
|
|
25
|
-
export interface SignInOptions {
|
|
26
|
-
/** Email credentials */
|
|
27
|
-
readonly email: string;
|
|
28
|
-
/** Password */
|
|
29
|
-
readonly password: string;
|
|
30
|
-
/** Remember user */
|
|
31
|
-
readonly rememberMe?: boolean;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Sign in use case
|
|
36
|
-
* Handles user sign in with validation and error handling
|
|
37
|
-
*/
|
|
38
|
-
export class SignInUseCase {
|
|
39
|
-
private readonly authPort: IAuthPort;
|
|
40
|
-
|
|
41
|
-
constructor(authPort: IAuthPort) {
|
|
42
|
-
this.authPort = authPort;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Execute sign in use case
|
|
47
|
-
* Validates credentials and signs in user
|
|
48
|
-
*/
|
|
49
|
-
async execute(options: SignInOptions): Promise<SignInUseCaseResult> {
|
|
50
|
-
// Validate credentials
|
|
51
|
-
const validation = this.validateCredentials(options);
|
|
52
|
-
if (!validation.valid) {
|
|
53
|
-
return {
|
|
54
|
-
success: false,
|
|
55
|
-
error: {
|
|
56
|
-
code: 'auth/invalid-credentials',
|
|
57
|
-
message: validation.error,
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Create credentials object
|
|
63
|
-
const credentials: EmailCredentials = {
|
|
64
|
-
email: options.email,
|
|
65
|
-
password: options.password,
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
// Sign in with credentials
|
|
69
|
-
const result = await this.authPort.signInWithEmail(credentials);
|
|
70
|
-
|
|
71
|
-
if (!result.success) {
|
|
72
|
-
return {
|
|
73
|
-
success: false,
|
|
74
|
-
error: result.error,
|
|
75
|
-
requiresVerification: this.requiresVerification(result.error?.code),
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return {
|
|
80
|
-
success: true,
|
|
81
|
-
data: result.data,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Validate email and password
|
|
87
|
-
*/
|
|
88
|
-
private validateCredentials(options: SignInOptions): { valid: boolean; error?: string } {
|
|
89
|
-
const { email, password } = options;
|
|
90
|
-
|
|
91
|
-
// Validate email
|
|
92
|
-
if (!email || typeof email !== 'string' || email.trim() === '') {
|
|
93
|
-
return { valid: false, error: 'Email is required' };
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
97
|
-
if (!emailRegex.test(email)) {
|
|
98
|
-
return { valid: false, error: 'Invalid email format' };
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Validate password
|
|
102
|
-
if (!password || typeof password !== 'string' || password.trim() === '') {
|
|
103
|
-
return { valid: false, error: 'Password is required' };
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (password.length < 6) {
|
|
107
|
-
return { valid: false, error: 'Password must be at least 6 characters' };
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return { valid: true };
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Check if error requires email verification
|
|
115
|
-
*/
|
|
116
|
-
private requiresVerification(errorCode?: string): boolean {
|
|
117
|
-
return errorCode === 'auth/unverified-email' || errorCode === 'auth/email-not-verified';
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Check if user is already signed in
|
|
122
|
-
*/
|
|
123
|
-
isSignedIn(): boolean {
|
|
124
|
-
return this.authPort.isAuthenticated();
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Get current user
|
|
129
|
-
*/
|
|
130
|
-
getCurrentUser(): User | null {
|
|
131
|
-
return this.authPort.getCurrentUser();
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Sign out current user
|
|
136
|
-
*/
|
|
137
|
-
async signOut(): Promise<Result<void>> {
|
|
138
|
-
return this.authPort.signOut();
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Check if credentials match current user
|
|
143
|
-
*/
|
|
144
|
-
async credentialsMatchCurrentUser(email: string): Promise<boolean> {
|
|
145
|
-
const currentUser = this.getCurrentUser();
|
|
146
|
-
if (!currentUser || !currentUser.email) {
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return currentUser.email.toLowerCase() === email.toLowerCase();
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
}
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Validate email format
|
|
5
|
-
*/
|
|
6
|
-
isValidEmail(email: string): boolean {
|
|
7
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
8
|
-
return emailRegex.test(email);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Validate password strength
|
|
13
|
-
*/
|
|
14
|
-
isStrongPassword(password: string): boolean {
|
|
15
|
-
// Basic password strength check
|
|
16
|
-
return password.length >= 8;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Get password strength indicator
|
|
21
|
-
*/
|
|
22
|
-
getPasswordStrength(password: string): 'weak' | 'medium' | 'strong' {
|
|
23
|
-
if (password.length < 6) {
|
|
24
|
-
return 'weak';
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (password.length < 8) {
|
|
28
|
-
return 'medium';
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Check for variety
|
|
32
|
-
const hasLower = /[a-z]/.test(password);
|
|
33
|
-
const hasUpper = /[A-Z]/.test(password);
|
|
34
|
-
const hasNumber = /[0-9]/.test(password);
|
|
35
|
-
const hasSpecial = /[^a-zA-Z0-9]/.test(password);
|
|
36
|
-
|
|
37
|
-
const varietyScore = [hasLower, hasUpper, hasNumber, hasSpecial].filter(Boolean).length;
|
|
38
|
-
|
|
39
|
-
if (varietyScore >= 3) {
|
|
40
|
-
return 'strong';
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return 'medium';
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Check if account is locked
|
|
48
|
-
*/
|
|
49
|
-
isAccountLocked(errorCode?: string): boolean {
|
|
50
|
-
return errorCode === 'auth/too-many-requests' || errorCode === 'auth/user-disabled';
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Get user-friendly error message
|
|
55
|
-
*/
|
|
56
|
-
getErrorMessage(errorCode: string): string {
|
|
57
|
-
const errorMessages: Record<string, string> = {
|
|
58
|
-
'auth/invalid-credentials': 'Invalid email or password',
|
|
59
|
-
'auth/user-not-found': 'No account found with this email',
|
|
60
|
-
'auth/wrong-password': 'Incorrect password',
|
|
61
|
-
'auth/unverified-email': 'Please verify your email first',
|
|
62
|
-
'auth/user-disabled': 'This account has been disabled',
|
|
63
|
-
'auth/too-many-requests': 'Too many attempts. Please try again later',
|
|
64
|
-
'auth/invalid-email': 'Invalid email address',
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
return errorMessages[errorCode] || 'Sign in failed. Please try again.';
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Create sign in options from email and password
|
|
72
|
-
*/
|
|
73
|
-
createOptions(email: string, password: string, rememberMe: boolean = false): SignInOptions {
|
|
74
|
-
return {
|
|
75
|
-
email,
|
|
76
|
-
password,
|
|
77
|
-
rememberMe,
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Quick sign in helper
|
|
83
|
-
*/
|
|
84
|
-
async quickSignIn(email: string, password: string): Promise<SignInUseCaseResult> {
|
|
85
|
-
return this.execute(this.createOptions(email, password));
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Factory function to create sign in use case
|
|
91
|
-
*/
|
|
92
|
-
export function createSignInUseCase(authPort: IAuthPort): SignInUseCase {
|
|
93
|
-
return new SignInUseCase(authPort);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Factory function to create sign in use case with default auth port
|
|
98
|
-
*/
|
|
99
|
-
export async function createDefaultSignInUseCase(): Promise<SignInUseCase> {
|
|
100
|
-
const { createAuthPort } = await import('../ports/AuthPort');
|
|
101
|
-
const authPort = createAuthPort();
|
|
102
|
-
return createSignInUseCase(authPort);
|
|
103
|
-
}
|
|
@@ -1,288 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sign Out Use Case
|
|
3
|
-
* Single Responsibility: Handle user sign out operations
|
|
4
|
-
*
|
|
5
|
-
* Application use case for user sign out.
|
|
6
|
-
* Ensures proper cleanup and state management.
|
|
7
|
-
*
|
|
8
|
-
* Max lines: 150 (enforced for maintainability)
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import type { User } from 'firebase/auth';
|
|
12
|
-
import type { Result } from '../../../shared/domain/utils';
|
|
13
|
-
import type { IAuthPort } from '../ports/AuthPort';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Sign out use case result
|
|
17
|
-
*/
|
|
18
|
-
export interface SignOutUseCaseResult extends Result<void> {
|
|
19
|
-
readonly wasSignedIn: boolean;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Sign out use case options
|
|
24
|
-
*/
|
|
25
|
-
export interface SignOutOptions {
|
|
26
|
-
/** Clear local data */
|
|
27
|
-
readonly clearLocalData?: boolean;
|
|
28
|
-
/** Navigate to sign in screen */
|
|
29
|
-
readonly navigateToSignIn?: boolean;
|
|
30
|
-
/** Show confirmation dialog */
|
|
31
|
-
readonly showConfirmation?: boolean;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Sign out use case
|
|
36
|
-
* Handles user sign out with proper cleanup
|
|
37
|
-
*/
|
|
38
|
-
export class SignOutUseCase {
|
|
39
|
-
private readonly authPort: IAuthPort;
|
|
40
|
-
|
|
41
|
-
constructor(authPort: IAuthPort) {
|
|
42
|
-
this.authPort = authPort;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Execute sign out use case
|
|
47
|
-
* Signs out user and performs cleanup
|
|
48
|
-
*/
|
|
49
|
-
async execute(options: SignOutOptions = {}): Promise<SignOutUseCaseResult> {
|
|
50
|
-
const wasSignedIn = this.authPort.isAuthenticated();
|
|
51
|
-
|
|
52
|
-
// Check if user is signed in
|
|
53
|
-
if (!wasSignedIn) {
|
|
54
|
-
return {
|
|
55
|
-
success: true,
|
|
56
|
-
wasSignedIn: false,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Sign out from auth
|
|
61
|
-
const result = await this.authPort.signOut();
|
|
62
|
-
|
|
63
|
-
if (!result.success) {
|
|
64
|
-
return {
|
|
65
|
-
success: false,
|
|
66
|
-
error: result.error,
|
|
67
|
-
wasSignedIn,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Perform cleanup
|
|
72
|
-
await this.performCleanup(options);
|
|
73
|
-
|
|
74
|
-
return {
|
|
75
|
-
success: true,
|
|
76
|
-
wasSignedIn,
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Perform cleanup after sign out
|
|
82
|
-
*/
|
|
83
|
-
private async performCleanup(options: SignOutOptions): Promise<void> {
|
|
84
|
-
// Clear local data if requested
|
|
85
|
-
if (options.clearLocalData) {
|
|
86
|
-
await this.clearLocalData();
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Additional cleanup can be added here
|
|
90
|
-
// For example: clear cache, reset state, etc.
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Clear local data
|
|
95
|
-
* Override in subclass for custom cleanup
|
|
96
|
-
*/
|
|
97
|
-
protected async clearLocalData(): Promise<void> {
|
|
98
|
-
// Default implementation does nothing
|
|
99
|
-
// Subclass can override for custom cleanup
|
|
100
|
-
if (__DEV__) {
|
|
101
|
-
console.log('[SignOutUseCase] Clearing local data');
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Check if user is signed in
|
|
107
|
-
*/
|
|
108
|
-
isSignedIn(): boolean {
|
|
109
|
-
return this.authPort.isAuthenticated();
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Get current user
|
|
114
|
-
*/
|
|
115
|
-
getCurrentUser(): User | null {
|
|
116
|
-
return this.authPort.getCurrentUser();
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Get current user ID
|
|
121
|
-
*/
|
|
122
|
-
getCurrentUserId(): string | null {
|
|
123
|
-
return this.authPort.getCurrentUserId();
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Check if user is anonymous
|
|
128
|
-
*/
|
|
129
|
-
isAnonymous(): boolean {
|
|
130
|
-
return this.authPort.isAnonymous();
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Confirm sign out
|
|
135
|
-
* Useful for showing confirmation dialog
|
|
136
|
-
*/
|
|
137
|
-
async confirmSignOut(): Promise<boolean> {
|
|
138
|
-
// Default implementation always returns true
|
|
139
|
-
// Override in subclass to show confirmation dialog
|
|
140
|
-
return true;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Validate can sign out
|
|
145
|
-
* Check if sign out is allowed
|
|
146
|
-
*/
|
|
147
|
-
async canSignOut(): Promise<Result<void>> {
|
|
148
|
-
if (!this.isSignedIn()) {
|
|
149
|
-
return {
|
|
150
|
-
success: false,
|
|
151
|
-
error: {
|
|
152
|
-
code: 'auth/not-signed-in',
|
|
153
|
-
message: 'No user is currently signed in',
|
|
154
|
-
},
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Additional checks can be added here
|
|
159
|
-
// For example: check for unsaved changes, active operations, etc.
|
|
160
|
-
|
|
161
|
-
return { success: true };
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Sign out with confirmation
|
|
166
|
-
* Shows confirmation dialog before signing out
|
|
167
|
-
*/
|
|
168
|
-
async signOutWithConfirmation(): Promise<SignOutUseCaseResult> {
|
|
169
|
-
const confirmed = await this.confirmSignOut();
|
|
170
|
-
|
|
171
|
-
if (!confirmed) {
|
|
172
|
-
return {
|
|
173
|
-
success: false,
|
|
174
|
-
error: {
|
|
175
|
-
code: 'auth/sign-out-cancelled',
|
|
176
|
-
message: 'Sign out was cancelled',
|
|
177
|
-
},
|
|
178
|
-
wasSignedIn: this.isSignedIn(),
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return this.execute();
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Sign out and navigate
|
|
187
|
-
* Signs out and navigates to sign in screen
|
|
188
|
-
*/
|
|
189
|
-
async signOutAndNavigate(): Promise<SignOutUseCaseResult> {
|
|
190
|
-
return this.execute({
|
|
191
|
-
clearLocalData: true,
|
|
192
|
-
navigateToSignIn: true,
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* Force sign out
|
|
198
|
-
* Signs out even if there are errors
|
|
199
|
-
*/
|
|
200
|
-
async forceSignOut(): Promise<void> {
|
|
201
|
-
try {
|
|
202
|
-
await this.execute({
|
|
203
|
-
clearLocalData: true,
|
|
204
|
-
});
|
|
205
|
-
} catch (error) {
|
|
206
|
-
// Ignore errors during force sign out
|
|
207
|
-
if (__DEV__) {
|
|
208
|
-
console.error('[SignOutUseCase] Force sign out error:', error);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// Ensure local data is cleared
|
|
213
|
-
await this.clearLocalData();
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Get sign out statistics
|
|
218
|
-
*/
|
|
219
|
-
getSignOutStats(): {
|
|
220
|
-
readonly isSignedIn: boolean;
|
|
221
|
-
readonly isAnonymous: boolean;
|
|
222
|
-
readonly hasUserId: boolean;
|
|
223
|
-
} {
|
|
224
|
-
return {
|
|
225
|
-
isSignedIn: this.isSignedIn(),
|
|
226
|
-
isAnonymous: this.isAnonymous(),
|
|
227
|
-
hasUserId: this.getCurrentUserId() !== null,
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Create sign out options
|
|
233
|
-
*/
|
|
234
|
-
createOptions(options: Partial<SignOutOptions> = {}): SignOutOptions {
|
|
235
|
-
return {
|
|
236
|
-
clearLocalData: false,
|
|
237
|
-
navigateToSignIn: false,
|
|
238
|
-
showConfirmation: false,
|
|
239
|
-
...options,
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Quick sign out helper
|
|
245
|
-
*/
|
|
246
|
-
async quickSignOut(): Promise<SignOutUseCaseResult> {
|
|
247
|
-
return this.execute();
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Check if confirmation should be shown
|
|
252
|
-
*/
|
|
253
|
-
shouldShowConfirmation(): boolean {
|
|
254
|
-
// Default: show confirmation for authenticated users
|
|
255
|
-
return this.isSignedIn() && !this.isAnonymous();
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Get user-friendly sign out message
|
|
260
|
-
*/
|
|
261
|
-
getSignOutMessage(): string {
|
|
262
|
-
if (!this.isSignedIn()) {
|
|
263
|
-
return 'You are not signed in';
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (this.isAnonymous()) {
|
|
267
|
-
return 'Sign out from guest session?';
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
return 'Are you sure you want to sign out?';
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Factory function to create sign out use case
|
|
276
|
-
*/
|
|
277
|
-
export function createSignOutUseCase(authPort: IAuthPort): SignOutUseCase {
|
|
278
|
-
return new SignOutUseCase(authPort);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Factory function to create sign out use case with default auth port
|
|
283
|
-
*/
|
|
284
|
-
export async function createDefaultSignOutUseCase(): Promise<SignOutUseCase> {
|
|
285
|
-
const { createAuthPort } = await import('../ports/AuthPort');
|
|
286
|
-
const authPort = createAuthPort();
|
|
287
|
-
return createSignOutUseCase(authPort);
|
|
288
|
-
}
|
|
File without changes
|
|
File without changes
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sign Out Use Case
|
|
3
|
-
* Single Responsibility: Handle user sign out operations
|
|
4
|
-
*
|
|
5
|
-
* Application use case for user sign out.
|
|
6
|
-
* Ensures proper cleanup and state management.
|
|
7
|
-
*
|
|
8
|
-
* Max lines: 150 (enforced for maintainability)
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import type { User } from 'firebase/auth';
|
|
12
|
-
import type { Result } from '../../../shared/domain/utils';
|
|
13
|
-
import type { IAuthPort } from '../ports/AuthPort';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Sign out use case result
|
|
17
|
-
*/
|
|
18
|
-
export interface SignOutUseCaseResult extends Result<void> {
|
|
19
|
-
readonly wasSignedIn: boolean;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Sign out use case options
|
|
24
|
-
*/
|
|
25
|
-
export interface SignOutOptions {
|
|
26
|
-
/** Clear local data */
|
|
27
|
-
readonly clearLocalData?: boolean;
|
|
28
|
-
/** Navigate to sign in screen */
|
|
29
|
-
readonly navigateToSignIn?: boolean;
|
|
30
|
-
/** Show confirmation dialog */
|
|
31
|
-
readonly showConfirmation?: boolean;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Sign out use case
|
|
36
|
-
* Handles user sign out with proper cleanup
|
|
37
|
-
*/
|
|
38
|
-
export class SignOutUseCase {
|
|
39
|
-
private readonly authPort: IAuthPort;
|
|
40
|
-
|
|
41
|
-
constructor(authPort: IAuthPort) {
|
|
42
|
-
this.authPort = authPort;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Execute sign out use case
|
|
47
|
-
* Signs out user and performs cleanup
|
|
48
|
-
*/
|
|
49
|
-
async execute(options: SignOutOptions = {}): Promise<SignOutUseCaseResult> {
|
|
50
|
-
const wasSignedIn = this.authPort.isAuthenticated();
|
|
51
|
-
|
|
52
|
-
// Check if user is signed in
|
|
53
|
-
if (!wasSignedIn) {
|
|
54
|
-
return {
|
|
55
|
-
success: true,
|
|
56
|
-
wasSignedIn: false,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Sign out from auth
|
|
61
|
-
const result = await this.authPort.signOut();
|
|
62
|
-
|
|
63
|
-
if (!result.success) {
|
|
64
|
-
return {
|
|
65
|
-
success: false,
|
|
66
|
-
error: result.error,
|
|
67
|
-
wasSignedIn,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Perform cleanup
|
|
72
|
-
await this.performCleanup(options);
|
|
73
|
-
|
|
74
|
-
return {
|
|
75
|
-
success: true,
|
|
76
|
-
wasSignedIn,
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Perform cleanup after sign out
|
|
82
|
-
*/
|
|
83
|
-
private async performCleanup(options: SignOutOptions): Promise<void> {
|
|
84
|
-
// Clear local data if requested
|
|
85
|
-
if (options.clearLocalData) {
|
|
86
|
-
await this.clearLocalData();
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Additional cleanup can be added here
|
|
90
|
-
// For example: clear cache, reset state, etc.
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Clear local data
|
|
95
|
-
* Override in subclass for custom cleanup
|
|
96
|
-
*/
|
|
97
|
-
protected async clearLocalData(): Promise<void> {
|
|
98
|
-
// Default implementation does nothing
|
|
99
|
-
// Subclass can override for custom cleanup
|
|
100
|
-
if (__DEV__) {
|
|
101
|
-
console.log('[SignOutUseCase] Clearing local data');
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Check if user is signed in
|
|
107
|
-
*/
|
|
108
|
-
isSignedIn(): boolean {
|
|
109
|
-
return this.authPort.isAuthenticated();
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Get current user
|
|
114
|
-
*/
|
|
115
|
-
getCurrentUser(): User | null {
|
|
116
|
-
return this.authPort.getCurrentUser();
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Get current user ID
|
|
121
|
-
*/
|
|
122
|
-
getCurrentUserId(): string | null {
|
|
123
|
-
return this.authPort.getCurrentUserId();
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Check if user is anonymous
|
|
128
|
-
*/
|
|
129
|
-
isAnonymous(): boolean {
|
|
130
|
-
return this.authPort.isAnonymous();
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Confirm sign out
|
|
135
|
-
* Useful for showing confirmation dialog
|
|
136
|
-
*/
|
|
137
|
-
async confirmSignOut(): Promise<boolean> {
|
|
138
|
-
// Default implementation always returns true
|
|
139
|
-
// Override in subclass to show confirmation dialog
|
|
140
|
-
return true;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Validate can sign out
|
|
145
|
-
* Check if sign out is allowed
|
|
146
|
-
*/
|
|
147
|
-
async canSignOut(): Promise<Result<void>> {
|
|
148
|
-
if (!this.isSignedIn()) {
|
|
149
|
-
return {
|
|
150
|
-
success: false,
|