@umituz/react-native-auth 4.3.14 → 4.3.15
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/services/ValidationService.ts +0 -28
- package/src/domain/value-objects/AuthConfig.ts +2 -2
- package/src/infrastructure/adapters/StorageProviderAdapter.ts +1 -1
- package/src/infrastructure/services/AuthEventService.ts +3 -10
- package/src/infrastructure/utils/AuthValidation.ts +2 -2
- package/src/infrastructure/utils/UserMapper.ts +1 -1
- package/src/infrastructure/utils/authConversionDetector.ts +1 -1
- package/src/infrastructure/utils/authStateHandler.ts +1 -1
- package/src/infrastructure/utils/listener/anonymousSignInHandler.ts +3 -3
- package/src/infrastructure/utils/listener/cleanupHandlers.ts +1 -1
- package/src/infrastructure/utils/listener/listenerLifecycle.util.ts +0 -7
- package/src/infrastructure/utils/listener/listenerState.util.ts +1 -22
- package/src/init/index.ts +1 -6
- package/src/presentation/components/AccountActions.tsx +1 -1
- package/src/presentation/components/AuthHeader.tsx +1 -1
- package/src/presentation/components/AuthLegalLinks.tsx +1 -1
- package/src/presentation/components/EditProfileActions.tsx +1 -1
- package/src/presentation/components/EditProfileAvatar.tsx +1 -1
- package/src/presentation/components/EditProfileForm.tsx +1 -1
- package/src/presentation/components/LoginForm.tsx +1 -1
- package/src/presentation/components/PasswordMatchIndicator.tsx +1 -1
- package/src/presentation/components/PasswordStrengthIndicator.tsx +1 -1
- package/src/presentation/components/ProfileBenefitsList.tsx +3 -3
- package/src/presentation/components/RegisterForm.tsx +1 -1
- package/src/presentation/components/SocialLoginButtons.tsx +1 -1
- package/src/presentation/components/form/FormEmailInput.tsx +1 -1
- package/src/presentation/components/form/FormPasswordInput.tsx +1 -1
- package/src/presentation/components/form/FormTextInput.tsx +1 -1
- package/src/presentation/components/form/index.ts +0 -3
- package/src/presentation/hooks/useAuthRequired.ts +1 -1
- package/src/presentation/hooks/useGoogleAuth.ts +0 -2
- package/src/presentation/hooks/useLoginForm.ts +1 -1
- package/src/presentation/hooks/useSocialLogin.ts +0 -1
- package/src/presentation/navigation/AuthNavigator.tsx +27 -25
- package/src/presentation/providers/AuthProvider.tsx +1 -1
- package/src/presentation/screens/EditProfileScreen.tsx +2 -2
- package/src/presentation/screens/PasswordPromptScreen.tsx +0 -1
- package/src/presentation/stores/authModalStore.ts +1 -1
- package/src/presentation/stores/authStore.ts +1 -47
- package/src/presentation/utils/authTransition.util.ts +2 -14
- package/src/presentation/utils/commonStyles.ts +0 -45
- package/src/presentation/utils/form/formErrorUtils.ts +0 -55
- package/src/presentation/utils/form/formValidation.util.ts +0 -12
- package/src/presentation/utils/form/useFormField.hook.ts +1 -51
- package/src/presentation/utils/form/usePasswordValidation.hook.ts +2 -16
- package/src/presentation/utils/passwordPromptCallback.ts +0 -2
- package/src/presentation/utils/socialAuthHandler.util.ts +1 -55
- package/src/infrastructure/utils/AuthErrorMapper.ts +0 -93
- package/src/infrastructure/utils/error/errorCodeMapping.constants.ts +0 -23
- package/src/infrastructure/utils/error/errorExtraction.ts +0 -80
- package/src/infrastructure/utils/error/mappings/actionCodeErrorMappings.ts +0 -26
- package/src/infrastructure/utils/error/mappings/authErrorMappings.ts +0 -69
- package/src/infrastructure/utils/error/mappings/configErrorMappings.ts +0 -31
- package/src/infrastructure/utils/error/mappings/errorMapping.types.ts +0 -12
- package/src/infrastructure/utils/error/mappings/networkErrorMappings.ts +0 -22
- package/src/presentation/utils/authOperation.util.ts +0 -67
- package/src/presentation/utils/form/formFieldState.util.ts +0 -82
- package/src/presentation/utils/form/validation/formValidation.hook.ts +0 -30
|
@@ -11,15 +11,8 @@
|
|
|
11
11
|
|
|
12
12
|
import { createStore, storageService } from "@umituz/react-native-design-system";
|
|
13
13
|
import { mapToAuthUser } from "../../infrastructure/utils/UserMapper";
|
|
14
|
-
import type { AuthState, AuthActions
|
|
14
|
+
import type { AuthState, AuthActions } from "../../types/auth-store.types";
|
|
15
15
|
import { initialAuthState } from "../../types/auth-store.types";
|
|
16
|
-
import {
|
|
17
|
-
selectUserId,
|
|
18
|
-
selectIsAuthenticated,
|
|
19
|
-
selectIsAnonymous,
|
|
20
|
-
selectUserType,
|
|
21
|
-
selectIsRegisteredUser,
|
|
22
|
-
} from "./auth.selectors";
|
|
23
16
|
|
|
24
17
|
// =============================================================================
|
|
25
18
|
// STORE
|
|
@@ -96,42 +89,3 @@ export const useAuthStore = createStore<AuthState, AuthActions>({
|
|
|
96
89
|
}),
|
|
97
90
|
});
|
|
98
91
|
|
|
99
|
-
// =============================================================================
|
|
100
|
-
// NON-HOOK GETTERS
|
|
101
|
-
// =============================================================================
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Get user ID without hook
|
|
105
|
-
*/
|
|
106
|
-
export function getUserId(): string | null {
|
|
107
|
-
return selectUserId(useAuthStore.getState());
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Get user type without hook
|
|
112
|
-
*/
|
|
113
|
-
export function getUserType(): UserType {
|
|
114
|
-
return selectUserType(useAuthStore.getState());
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Check if authenticated without hook
|
|
119
|
-
*/
|
|
120
|
-
export function getIsAuthenticated(): boolean {
|
|
121
|
-
return selectIsAuthenticated(useAuthStore.getState());
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Check if anonymous without hook
|
|
126
|
-
*/
|
|
127
|
-
export function getIsAnonymous(): boolean {
|
|
128
|
-
return selectIsAnonymous(useAuthStore.getState());
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Check if registered user without hook
|
|
133
|
-
* Returns true only if user is authenticated AND not anonymous
|
|
134
|
-
*/
|
|
135
|
-
export function getIsRegisteredUser(): boolean {
|
|
136
|
-
return selectIsRegisteredUser(useAuthStore.getState());
|
|
137
|
-
}
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
|
|
6
6
|
import { useRef, useEffect } from "react";
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
interface AuthTransitionState {
|
|
9
9
|
isAuthenticated: boolean;
|
|
10
10
|
isAnonymous: boolean;
|
|
11
11
|
isVisible: boolean;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
interface AuthTransitionResult {
|
|
15
15
|
justAuthenticated: boolean;
|
|
16
16
|
justConvertedFromAnonymous: boolean;
|
|
17
17
|
shouldClose: boolean;
|
|
@@ -60,18 +60,6 @@ export function useAuthTransitions(
|
|
|
60
60
|
}, [state.isAuthenticated, state.isVisible, state.isAnonymous, onTransition]);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
/**
|
|
64
|
-
* Check if should close modal after auth transition
|
|
65
|
-
*/
|
|
66
|
-
export function shouldCloseAfterAuth(
|
|
67
|
-
justAuthenticated: boolean,
|
|
68
|
-
justConvertedFromAnonymous: boolean,
|
|
69
|
-
isVisible: boolean,
|
|
70
|
-
isAnonymous: boolean
|
|
71
|
-
): boolean {
|
|
72
|
-
return (justAuthenticated || justConvertedFromAnonymous) && isVisible && !isAnonymous;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
63
|
/**
|
|
76
64
|
* Execute callback with delay after auth
|
|
77
65
|
*/
|
|
@@ -5,9 +5,6 @@
|
|
|
5
5
|
|
|
6
6
|
import { StyleSheet } from "react-native";
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* Action button style - used in account actions and profile sections
|
|
10
|
-
*/
|
|
11
8
|
export const actionButtonStyle = StyleSheet.create({
|
|
12
9
|
container: {
|
|
13
10
|
flexDirection: "row" as const,
|
|
@@ -24,45 +21,3 @@ export const actionButtonStyle = StyleSheet.create({
|
|
|
24
21
|
fontWeight: "500",
|
|
25
22
|
},
|
|
26
23
|
});
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Input field styles - used in forms
|
|
30
|
-
*/
|
|
31
|
-
export const inputFieldStyle = StyleSheet.create({
|
|
32
|
-
container: {
|
|
33
|
-
marginBottom: 20,
|
|
34
|
-
},
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Card content styles
|
|
39
|
-
*/
|
|
40
|
-
export const cardContentStyle = StyleSheet.create({
|
|
41
|
-
container: {
|
|
42
|
-
padding: 16,
|
|
43
|
-
},
|
|
44
|
-
divider: {
|
|
45
|
-
height: 24,
|
|
46
|
-
},
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Avatar container styles
|
|
51
|
-
*/
|
|
52
|
-
export const avatarContainerStyle = StyleSheet.create({
|
|
53
|
-
container: {
|
|
54
|
-
marginRight: 12,
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Info text styles
|
|
60
|
-
*/
|
|
61
|
-
export const infoTextStyle = StyleSheet.create({
|
|
62
|
-
container: {
|
|
63
|
-
flex: 1,
|
|
64
|
-
},
|
|
65
|
-
displayName: {
|
|
66
|
-
marginBottom: 2,
|
|
67
|
-
},
|
|
68
|
-
});
|
|
@@ -3,63 +3,8 @@
|
|
|
3
3
|
* Shared utilities for form error state management
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { useCallback } from "react";
|
|
7
|
-
|
|
8
6
|
export type FieldErrors<T extends string> = Partial<Record<T, string>>;
|
|
9
7
|
|
|
10
|
-
/**
|
|
11
|
-
* Create a field error updater that clears the specified field error
|
|
12
|
-
* @param fieldErrors - Current field errors state
|
|
13
|
-
* @param setFieldErrors - Function to update field errors
|
|
14
|
-
* @param field - Field to clear
|
|
15
|
-
* @returns Function to clear the specified field error
|
|
16
|
-
*/
|
|
17
|
-
export function createFieldErrorUpdater<T extends string>(
|
|
18
|
-
fieldErrors: FieldErrors<T>,
|
|
19
|
-
setFieldErrors: (errors: FieldErrors<T> | ((prev: FieldErrors<T>) => FieldErrors<T>)) => void,
|
|
20
|
-
localError: string | null,
|
|
21
|
-
setLocalError: (error: string | null) => void
|
|
22
|
-
) {
|
|
23
|
-
return useCallback((field: T) => {
|
|
24
|
-
if (fieldErrors[field]) {
|
|
25
|
-
setFieldErrors((prev) => {
|
|
26
|
-
const next = { ...prev };
|
|
27
|
-
delete next[field];
|
|
28
|
-
return next;
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
if (localError) {
|
|
32
|
-
setLocalError(null);
|
|
33
|
-
}
|
|
34
|
-
}, [fieldErrors, setFieldErrors, localError, setLocalError]);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Create a single field error updater
|
|
39
|
-
* @param setFieldErrors - Function to update field errors
|
|
40
|
-
* @param setLocalError - Function to update local error
|
|
41
|
-
* @param fields - Fields to clear when this updater is called
|
|
42
|
-
* @returns Function to clear specified field errors
|
|
43
|
-
*/
|
|
44
|
-
export function useFieldErrorClearer<T extends string>(
|
|
45
|
-
setFieldErrors: (errors: FieldErrors<T> | ((prev: FieldErrors<T>) => FieldErrors<T>)) => void,
|
|
46
|
-
setLocalError: (error: string | null) => void,
|
|
47
|
-
fields: T[]
|
|
48
|
-
) {
|
|
49
|
-
return useCallback(() => {
|
|
50
|
-
setFieldErrors((prev) => {
|
|
51
|
-
const next = { ...prev };
|
|
52
|
-
fields.forEach((field) => {
|
|
53
|
-
if (next[field]) {
|
|
54
|
-
delete next[field];
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
return next;
|
|
58
|
-
});
|
|
59
|
-
setLocalError(null);
|
|
60
|
-
}, [setFieldErrors, setLocalError, fields]);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
8
|
/**
|
|
64
9
|
* Clear a specific field error
|
|
65
10
|
* @param setFieldErrors - Function to update field errors
|
|
@@ -3,15 +3,6 @@
|
|
|
3
3
|
* Exports all form validation utilities
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
// Types
|
|
7
|
-
export type {
|
|
8
|
-
FormValidationError,
|
|
9
|
-
FormValidationResult,
|
|
10
|
-
LoginFormValues,
|
|
11
|
-
RegisterFormValues,
|
|
12
|
-
ProfileFormValues,
|
|
13
|
-
} from "./validation/formValidation.types";
|
|
14
|
-
|
|
15
6
|
// Validators
|
|
16
7
|
export {
|
|
17
8
|
validateLoginForm,
|
|
@@ -21,6 +12,3 @@ export {
|
|
|
21
12
|
|
|
22
13
|
// Utilities
|
|
23
14
|
export { errorsToFieldErrors } from "./validation/formValidation.utils";
|
|
24
|
-
|
|
25
|
-
// Hook
|
|
26
|
-
export { useFormValidation } from "./validation/formValidation.hook";
|
|
@@ -5,61 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
import { useCallback, useState } from "react";
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
interface UseFormFieldOptions {
|
|
9
9
|
clearLocalError?: () => void;
|
|
10
10
|
fieldsToClear?: string[];
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export interface UseFormFieldResult {
|
|
14
|
-
value: string;
|
|
15
|
-
error: string | null;
|
|
16
|
-
setValue: (value: string) => void;
|
|
17
|
-
setError: (error: string | null) => void;
|
|
18
|
-
clearError: () => void;
|
|
19
|
-
handleChange: (text: string) => void;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Hook for managing a single form field with automatic error clearing
|
|
24
|
-
* @param initialValue - Initial field value
|
|
25
|
-
* @param setError - Function to set field error in parent state
|
|
26
|
-
* @param options - Additional options
|
|
27
|
-
* @returns Field state and handlers
|
|
28
|
-
*/
|
|
29
|
-
export function useFormField(
|
|
30
|
-
initialValue: string,
|
|
31
|
-
setError: (error: string | null) => void,
|
|
32
|
-
options?: UseFormFieldOptions
|
|
33
|
-
): UseFormFieldResult {
|
|
34
|
-
const [value, setValue] = useState(initialValue);
|
|
35
|
-
const [error, setLocalError] = useState<string | null>(null);
|
|
36
|
-
|
|
37
|
-
const clearError = useCallback(() => {
|
|
38
|
-
setLocalError(null);
|
|
39
|
-
setError(null);
|
|
40
|
-
options?.clearLocalError?.();
|
|
41
|
-
}, [setError, options]);
|
|
42
|
-
|
|
43
|
-
const handleChange = useCallback(
|
|
44
|
-
(text: string) => {
|
|
45
|
-
setValue(text);
|
|
46
|
-
if (error) {
|
|
47
|
-
clearError();
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
[error, clearError]
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
return {
|
|
54
|
-
value,
|
|
55
|
-
error,
|
|
56
|
-
setValue,
|
|
57
|
-
setError: setLocalError,
|
|
58
|
-
clearError,
|
|
59
|
-
handleChange,
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
13
|
/**
|
|
64
14
|
* Hook for managing multiple form fields
|
|
65
15
|
* @param initialFields - Initial field values
|
|
@@ -8,18 +8,17 @@ import {
|
|
|
8
8
|
validatePasswordForRegister,
|
|
9
9
|
validatePasswordConfirmation,
|
|
10
10
|
type PasswordRequirements,
|
|
11
|
-
type ValidationResult,
|
|
12
11
|
} from "../../../application/services/ValidationService";
|
|
13
12
|
import type { PasswordConfig } from "../../../domain/value-objects/AuthConfig";
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
interface UsePasswordValidationResult {
|
|
16
15
|
passwordRequirements: PasswordRequirements;
|
|
17
16
|
passwordsMatch: boolean;
|
|
18
17
|
isValid: boolean;
|
|
19
18
|
confirmationError: string | null;
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
interface UsePasswordValidationOptions {
|
|
23
22
|
passwordConfig?: PasswordConfig;
|
|
24
23
|
}
|
|
25
24
|
|
|
@@ -72,16 +71,3 @@ export function usePasswordValidation(
|
|
|
72
71
|
};
|
|
73
72
|
}
|
|
74
73
|
|
|
75
|
-
/**
|
|
76
|
-
* Hook for login password validation (simpler, no requirements)
|
|
77
|
-
* @param password - Password value
|
|
78
|
-
* @returns Validation result
|
|
79
|
-
*/
|
|
80
|
-
export function useLoginPasswordValidation(password: string): ValidationResult {
|
|
81
|
-
return useMemo(() => {
|
|
82
|
-
if (!password || password.length === 0) {
|
|
83
|
-
return { isValid: false, error: "auth.validation.passwordRequired" };
|
|
84
|
-
}
|
|
85
|
-
return { isValid: true };
|
|
86
|
-
}, [password]);
|
|
87
|
-
}
|
|
@@ -4,8 +4,6 @@ export const setPasswordPromptCallback = (cb: ((value: string | null) => void) |
|
|
|
4
4
|
callback = cb;
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
-
export const getPasswordPromptCallback = (): ((value: string | null) => void) | null => callback;
|
|
8
|
-
|
|
9
7
|
export const resolvePasswordPrompt = (value: string | null): void => {
|
|
10
8
|
if (callback) {
|
|
11
9
|
callback(value);
|
|
@@ -3,56 +3,14 @@
|
|
|
3
3
|
* Manages social authentication state and handlers
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { useState, useCallback } from "react";
|
|
7
6
|
import type { SocialAuthProvider } from "../../domain/value-objects/AuthConfig";
|
|
8
7
|
import { Platform } from "react-native";
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
googleLoading: boolean;
|
|
12
|
-
appleLoading: boolean;
|
|
13
|
-
handleGoogleSignIn: () => Promise<void>;
|
|
14
|
-
handleAppleSignIn: () => Promise<void>;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface SocialAuthConfig {
|
|
9
|
+
interface SocialAuthConfig {
|
|
18
10
|
google?: { iosClientId?: string; webClientId?: string; androidClientId?: string };
|
|
19
11
|
apple?: { enabled: boolean };
|
|
20
12
|
}
|
|
21
13
|
|
|
22
|
-
/**
|
|
23
|
-
* Hook for managing a single social auth provider's loading state
|
|
24
|
-
* @returns Loading state and handler creator
|
|
25
|
-
*/
|
|
26
|
-
export function useSocialAuthLoading() {
|
|
27
|
-
const [googleLoading, setGoogleLoading] = useState(false);
|
|
28
|
-
const [appleLoading, setAppleLoading] = useState(false);
|
|
29
|
-
|
|
30
|
-
const createHandler = useCallback(
|
|
31
|
-
(setter: (loading: boolean) => void, signInHandler?: () => Promise<void>) => {
|
|
32
|
-
return async () => {
|
|
33
|
-
if (!signInHandler) {
|
|
34
|
-
throw new Error("Sign-in handler not available");
|
|
35
|
-
}
|
|
36
|
-
setter(true);
|
|
37
|
-
try {
|
|
38
|
-
await signInHandler();
|
|
39
|
-
} finally {
|
|
40
|
-
setter(false);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
},
|
|
44
|
-
[]
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
return {
|
|
48
|
-
googleLoading,
|
|
49
|
-
appleLoading,
|
|
50
|
-
setGoogleLoading,
|
|
51
|
-
setAppleLoading,
|
|
52
|
-
createHandler,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
14
|
/**
|
|
57
15
|
* Determine enabled social auth providers
|
|
58
16
|
*/
|
|
@@ -74,16 +32,4 @@ export function determineEnabledProviders(
|
|
|
74
32
|
return providers;
|
|
75
33
|
}
|
|
76
34
|
|
|
77
|
-
/**
|
|
78
|
-
* Select the appropriate sign-in handler from external and internal options
|
|
79
|
-
* @param externalHandler - External handler provided by parent
|
|
80
|
-
* @param internalHandler - Internal handler from auth hook
|
|
81
|
-
* @returns The selected handler or undefined
|
|
82
|
-
*/
|
|
83
|
-
export function selectSignInHandler(
|
|
84
|
-
externalHandler?: () => Promise<void>,
|
|
85
|
-
internalHandler?: () => Promise<void>
|
|
86
|
-
): (() => Promise<void>) | undefined {
|
|
87
|
-
return externalHandler ?? internalHandler;
|
|
88
|
-
}
|
|
89
35
|
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auth Error Mapper
|
|
3
|
-
* Single Responsibility: Map Firebase Auth errors to domain errors
|
|
4
|
-
*
|
|
5
|
-
* @module AuthErrorMapper
|
|
6
|
-
* @description Provides type-safe error mapping from Firebase Auth errors to
|
|
7
|
-
* domain-specific error types. Includes runtime validation and type guards.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
AuthError,
|
|
12
|
-
AuthConfigurationError,
|
|
13
|
-
AuthNetworkError,
|
|
14
|
-
} from "../../domain/errors/AuthError";
|
|
15
|
-
import {
|
|
16
|
-
extractErrorCode,
|
|
17
|
-
extractErrorMessage,
|
|
18
|
-
} from "./error/errorExtraction";
|
|
19
|
-
import { ERROR_CODE_MAP, type ErrorConstructor, type ErrorFactory } from "./error/errorCodeMapping.constants";
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Create error from error mapping
|
|
23
|
-
* @param mapping - Error mapping configuration
|
|
24
|
-
* @returns Created error instance
|
|
25
|
-
*/
|
|
26
|
-
function createErrorFromMapping(mapping: { type: "class" | "factory"; create: ErrorConstructor | ErrorFactory }): Error {
|
|
27
|
-
return mapping.type === "class"
|
|
28
|
-
? new (mapping.create as ErrorConstructor)()
|
|
29
|
-
: (mapping.create as ErrorFactory)();
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Map Firebase Auth errors to domain errors
|
|
34
|
-
*
|
|
35
|
-
* @param error - Unknown error from Firebase Auth or other sources
|
|
36
|
-
* @returns Mapped domain error with appropriate error type and message
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* ```ts
|
|
40
|
-
* try {
|
|
41
|
-
* await signInWithEmailAndPassword(auth, email, password);
|
|
42
|
-
* } catch (error) {
|
|
43
|
-
* throw mapFirebaseAuthError(error);
|
|
44
|
-
* }
|
|
45
|
-
* ```
|
|
46
|
-
*
|
|
47
|
-
* @remarks
|
|
48
|
-
* This function handles:
|
|
49
|
-
* - Firebase Auth errors with proper code mapping
|
|
50
|
-
* - Standard JavaScript Error objects
|
|
51
|
-
* - Unknown error types with safe fallbacks
|
|
52
|
-
* - Type-safe error extraction using type guards
|
|
53
|
-
*/
|
|
54
|
-
export function mapFirebaseAuthError(error: unknown): Error {
|
|
55
|
-
// Handle null/undefined
|
|
56
|
-
if (!error || typeof error !== 'object') {
|
|
57
|
-
return new AuthError("Authentication failed", "AUTH_UNKNOWN_ERROR");
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const code = extractErrorCode(error);
|
|
61
|
-
const message = extractErrorMessage(error);
|
|
62
|
-
|
|
63
|
-
// Map known Firebase Auth error codes to domain errors
|
|
64
|
-
const mapping = ERROR_CODE_MAP[code];
|
|
65
|
-
if (mapping) {
|
|
66
|
-
return createErrorFromMapping(mapping);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Default fallback for unknown error codes
|
|
70
|
-
return new AuthError(message, code || "AUTH_UNKNOWN_ERROR");
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Check if error is a network-related error
|
|
75
|
-
* @param error - Error to check
|
|
76
|
-
* @returns True if error is network-related
|
|
77
|
-
*/
|
|
78
|
-
export function isNetworkError(error: unknown): boolean {
|
|
79
|
-
return (
|
|
80
|
-
error instanceof AuthNetworkError ||
|
|
81
|
-
(error instanceof AuthError && error.code === "auth/network-request-failed")
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Check if error is a configuration-related error
|
|
87
|
-
* @param error - Error to check
|
|
88
|
-
* @returns True if error is configuration-related
|
|
89
|
-
*/
|
|
90
|
-
export function isConfigurationError(error: unknown): boolean {
|
|
91
|
-
return error instanceof AuthConfigurationError;
|
|
92
|
-
}
|
|
93
|
-
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Firebase Error Code Mapping Constants
|
|
3
|
-
* Centralized configuration for mapping Firebase error codes to domain errors
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { ErrorMapping } from "./mappings/errorMapping.types";
|
|
7
|
-
import { AUTH_ERROR_MAPPINGS } from "./mappings/authErrorMappings";
|
|
8
|
-
import { CONFIG_ERROR_MAPPINGS } from "./mappings/configErrorMappings";
|
|
9
|
-
import { NETWORK_ERROR_MAPPINGS } from "./mappings/networkErrorMappings";
|
|
10
|
-
import { ACTION_CODE_ERROR_MAPPINGS } from "./mappings/actionCodeErrorMappings";
|
|
11
|
-
|
|
12
|
-
// Export types needed by AuthErrorMapper
|
|
13
|
-
export type { ErrorConstructor, ErrorFactory } from "./mappings/errorMapping.types";
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Combined Firebase error code to domain error mapping
|
|
17
|
-
*/
|
|
18
|
-
export const ERROR_CODE_MAP: Record<string, ErrorMapping> = {
|
|
19
|
-
...AUTH_ERROR_MAPPINGS,
|
|
20
|
-
...CONFIG_ERROR_MAPPINGS,
|
|
21
|
-
...NETWORK_ERROR_MAPPINGS,
|
|
22
|
-
...ACTION_CODE_ERROR_MAPPINGS,
|
|
23
|
-
};
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Error Extraction Utilities
|
|
3
|
-
* Utilities for extracting error information from various error types
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Firebase Auth error structure
|
|
8
|
-
* Based on Firebase Auth SDK error format
|
|
9
|
-
*/
|
|
10
|
-
interface FirebaseAuthError {
|
|
11
|
-
code: string;
|
|
12
|
-
message: string;
|
|
13
|
-
name?: string;
|
|
14
|
-
stack?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Type guard to check if error is a valid Firebase Auth error
|
|
19
|
-
* @param error - Unknown error to check
|
|
20
|
-
* @returns True if error matches Firebase Auth error structure
|
|
21
|
-
*/
|
|
22
|
-
export function isFirebaseAuthError(error: unknown): error is FirebaseAuthError {
|
|
23
|
-
if (!error || typeof error !== 'object') {
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const err = error as Partial<FirebaseAuthError>;
|
|
28
|
-
return (
|
|
29
|
-
typeof err.code === 'string' &&
|
|
30
|
-
typeof err.message === 'string' &&
|
|
31
|
-
err.code.startsWith('auth/')
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Extract error code from error object
|
|
37
|
-
* @param error - Unknown error
|
|
38
|
-
* @returns Error code or empty string
|
|
39
|
-
*/
|
|
40
|
-
export function extractErrorCode(error: unknown): string {
|
|
41
|
-
if (isFirebaseAuthError(error)) {
|
|
42
|
-
return error.code;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Fallback for non-Firebase errors
|
|
46
|
-
if (error && typeof error === 'object' && 'code' in error) {
|
|
47
|
-
const code = (error as { code?: unknown }).code;
|
|
48
|
-
if (typeof code === 'string') {
|
|
49
|
-
return code;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return '';
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Extract error message from error object
|
|
58
|
-
* @param error - Unknown error
|
|
59
|
-
* @returns Error message or default message
|
|
60
|
-
*/
|
|
61
|
-
export function extractErrorMessage(error: unknown): string {
|
|
62
|
-
if (isFirebaseAuthError(error)) {
|
|
63
|
-
return error.message;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Fallback for Error objects
|
|
67
|
-
if (error instanceof Error) {
|
|
68
|
-
return error.message;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Fallback for objects with message property
|
|
72
|
-
if (error && typeof error === 'object' && 'message' in error) {
|
|
73
|
-
const message = (error as { message?: unknown }).message;
|
|
74
|
-
if (typeof message === 'string') {
|
|
75
|
-
return message;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return "Authentication failed";
|
|
80
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Action Code Error Mappings
|
|
3
|
-
* Email verification, password reset link errors
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { AuthError } from "../../../../domain/errors/AuthError";
|
|
7
|
-
import type { ErrorMapping } from "./errorMapping.types";
|
|
8
|
-
|
|
9
|
-
export const ACTION_CODE_ERROR_MAPPINGS: Record<string, ErrorMapping> = {
|
|
10
|
-
"auth/expired-action-code": {
|
|
11
|
-
type: "factory",
|
|
12
|
-
create: () =>
|
|
13
|
-
new AuthError(
|
|
14
|
-
"This link has expired. Please request a new one.",
|
|
15
|
-
"AUTH_EXPIRED_ACTION_CODE"
|
|
16
|
-
),
|
|
17
|
-
},
|
|
18
|
-
"auth/invalid-action-code": {
|
|
19
|
-
type: "factory",
|
|
20
|
-
create: () =>
|
|
21
|
-
new AuthError(
|
|
22
|
-
"This link is invalid. Please request a new one.",
|
|
23
|
-
"AUTH_INVALID_ACTION_CODE"
|
|
24
|
-
),
|
|
25
|
-
},
|
|
26
|
-
};
|