@umituz/react-native-auth 1.11.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -0
- package/lib/__tests__/services/AuthCoreService.test.d.ts +4 -0
- package/lib/__tests__/services/AuthCoreService.test.js +198 -0
- package/lib/__tests__/services/AuthPackage.test.d.ts +4 -0
- package/lib/__tests__/services/AuthPackage.test.js +177 -0
- package/lib/__tests__/services/GuestModeService.test.d.ts +4 -0
- package/lib/__tests__/services/GuestModeService.test.js +141 -0
- package/lib/__tests__/utils/AuthValidation.test.d.ts +4 -0
- package/lib/__tests__/utils/AuthValidation.test.js +222 -0
- package/lib/application/ports/IAuthProvider.d.ts +42 -0
- package/lib/application/ports/IAuthProvider.js +5 -0
- package/lib/application/ports/IAuthService.d.ts +48 -0
- package/lib/application/ports/IAuthService.js +5 -0
- package/lib/domain/entities/AuthUser.d.ts +12 -0
- package/lib/domain/entities/AuthUser.js +5 -0
- package/lib/domain/errors/AuthError.d.ts +36 -0
- package/lib/domain/errors/AuthError.js +76 -0
- package/lib/domain/value-objects/AuthConfig.d.ts +16 -0
- package/lib/domain/value-objects/AuthConfig.js +14 -0
- package/lib/index.d.ts +45 -0
- package/lib/index.js +59 -0
- package/lib/infrastructure/adapters/StorageProviderAdapter.d.ts +16 -0
- package/lib/infrastructure/adapters/StorageProviderAdapter.js +72 -0
- package/lib/infrastructure/adapters/UIProviderAdapter.d.ts +18 -0
- package/lib/infrastructure/adapters/UIProviderAdapter.js +28 -0
- package/lib/infrastructure/providers/FirebaseAuthProvider.d.ts +19 -0
- package/lib/infrastructure/providers/FirebaseAuthProvider.js +94 -0
- package/lib/infrastructure/services/AuthCoreService.d.ts +22 -0
- package/lib/infrastructure/services/AuthCoreService.js +102 -0
- package/lib/infrastructure/services/AuthEventService.d.ts +28 -0
- package/lib/infrastructure/services/AuthEventService.js +88 -0
- package/lib/infrastructure/services/AuthPackage.d.ts +62 -0
- package/lib/infrastructure/services/AuthPackage.js +91 -0
- package/lib/infrastructure/services/AuthService.d.ts +42 -0
- package/lib/infrastructure/services/AuthService.js +123 -0
- package/lib/infrastructure/services/GuestModeService.d.ts +23 -0
- package/lib/infrastructure/services/GuestModeService.js +69 -0
- package/lib/infrastructure/storage/GuestModeStorage.d.ts +16 -0
- package/lib/infrastructure/storage/GuestModeStorage.js +73 -0
- package/lib/infrastructure/utils/AuthErrorMapper.d.ts +8 -0
- package/lib/infrastructure/utils/AuthErrorMapper.js +51 -0
- package/lib/infrastructure/utils/AuthEventEmitter.d.ts +12 -0
- package/lib/infrastructure/utils/AuthEventEmitter.js +25 -0
- package/lib/infrastructure/utils/AuthValidation.d.ts +49 -0
- package/lib/infrastructure/utils/AuthValidation.js +133 -0
- package/lib/infrastructure/utils/UserMapper.d.ts +15 -0
- package/lib/infrastructure/utils/UserMapper.js +16 -0
- package/lib/presentation/components/AuthContainer.d.ts +10 -0
- package/lib/presentation/components/AuthContainer.js +27 -0
- package/lib/presentation/components/AuthDivider.d.ts +6 -0
- package/lib/presentation/components/AuthDivider.js +36 -0
- package/lib/presentation/components/AuthErrorDisplay.d.ts +10 -0
- package/lib/presentation/components/AuthErrorDisplay.js +24 -0
- package/lib/presentation/components/AuthFormCard.d.ts +10 -0
- package/lib/presentation/components/AuthFormCard.js +19 -0
- package/lib/presentation/components/AuthGradientBackground.d.ts +6 -0
- package/lib/presentation/components/AuthGradientBackground.js +8 -0
- package/lib/presentation/components/AuthHeader.d.ts +11 -0
- package/lib/presentation/components/AuthHeader.js +38 -0
- package/lib/presentation/components/AuthLegalLinks.d.ts +28 -0
- package/lib/presentation/components/AuthLegalLinks.js +54 -0
- package/lib/presentation/components/AuthLink.d.ts +13 -0
- package/lib/presentation/components/AuthLink.js +27 -0
- package/lib/presentation/components/LoginForm.d.ts +10 -0
- package/lib/presentation/components/LoginForm.js +27 -0
- package/lib/presentation/components/PasswordMatchIndicator.d.ts +9 -0
- package/lib/presentation/components/PasswordMatchIndicator.js +30 -0
- package/lib/presentation/components/PasswordStrengthIndicator.d.ts +11 -0
- package/lib/presentation/components/PasswordStrengthIndicator.js +60 -0
- package/lib/presentation/components/RegisterForm.d.ts +14 -0
- package/lib/presentation/components/RegisterForm.js +30 -0
- package/lib/presentation/hooks/useAuth.d.ts +44 -0
- package/lib/presentation/hooks/useAuth.js +38 -0
- package/lib/presentation/hooks/useAuthActions.d.ts +15 -0
- package/lib/presentation/hooks/useAuthActions.js +162 -0
- package/lib/presentation/hooks/useAuthState.d.ts +19 -0
- package/lib/presentation/hooks/useAuthState.js +79 -0
- package/lib/presentation/hooks/useLoginForm.d.ts +21 -0
- package/lib/presentation/hooks/useLoginForm.js +131 -0
- package/lib/presentation/hooks/useRegisterForm.d.ts +31 -0
- package/lib/presentation/hooks/useRegisterForm.js +136 -0
- package/lib/presentation/navigation/AuthNavigator.d.ts +28 -0
- package/lib/presentation/navigation/AuthNavigator.js +37 -0
- package/lib/presentation/screens/LoginScreen.d.ts +6 -0
- package/lib/presentation/screens/LoginScreen.js +15 -0
- package/lib/presentation/screens/RegisterScreen.d.ts +12 -0
- package/lib/presentation/screens/RegisterScreen.js +15 -0
- package/lib/presentation/utils/getAuthErrorMessage.d.ts +8 -0
- package/lib/presentation/utils/getAuthErrorMessage.js +69 -0
- package/package.json +12 -4
- package/src/__tests__/services/AuthCoreService.test.ts +247 -0
- package/src/__tests__/services/AuthPackage.test.ts +226 -0
- package/src/__tests__/services/GuestModeService.test.ts +194 -0
- package/src/__tests__/utils/AuthValidation.test.ts +270 -0
- package/src/application/ports/IAuthProvider.ts +0 -0
- package/src/application/ports/IAuthService.ts +0 -0
- package/src/domain/entities/AuthUser.ts +0 -0
- package/src/domain/errors/AuthError.ts +0 -0
- package/src/domain/value-objects/AuthConfig.ts +0 -0
- package/src/index.ts +4 -0
- package/src/infrastructure/adapters/StorageProviderAdapter.ts +73 -0
- package/src/infrastructure/adapters/UIProviderAdapter.ts +39 -0
- package/src/infrastructure/providers/FirebaseAuthProvider.ts +10 -2
- package/src/infrastructure/services/AuthCoreService.ts +138 -0
- package/src/infrastructure/services/AuthEventService.ts +115 -0
- package/src/infrastructure/services/AuthPackage.ts +148 -0
- package/src/infrastructure/services/AuthService.ts +62 -128
- package/src/infrastructure/services/GuestModeService.ts +86 -0
- package/src/infrastructure/storage/GuestModeStorage.ts +40 -14
- package/src/infrastructure/utils/AuthErrorMapper.ts +7 -3
- package/src/infrastructure/utils/AuthEventEmitter.ts +0 -0
- package/src/infrastructure/utils/AuthValidation.ts +47 -17
- package/src/infrastructure/utils/UserMapper.ts +0 -0
- package/src/presentation/components/AuthContainer.tsx +0 -0
- package/src/presentation/components/AuthDivider.tsx +0 -0
- package/src/presentation/components/AuthErrorDisplay.tsx +0 -0
- package/src/presentation/components/AuthFormCard.tsx +0 -0
- package/src/presentation/components/AuthGradientBackground.tsx +0 -0
- package/src/presentation/components/AuthHeader.tsx +0 -0
- package/src/presentation/components/AuthLegalLinks.tsx +0 -0
- package/src/presentation/components/AuthLink.tsx +0 -0
- package/src/presentation/components/LoginForm.tsx +0 -0
- package/src/presentation/components/PasswordMatchIndicator.tsx +50 -0
- package/src/presentation/components/PasswordStrengthIndicator.tsx +118 -0
- package/src/presentation/components/RegisterForm.tsx +10 -0
- package/src/presentation/hooks/useAuth.ts +0 -0
- package/src/presentation/hooks/useAuthActions.ts +8 -11
- package/src/presentation/hooks/useAuthState.ts +10 -0
- package/src/presentation/hooks/useLoginForm.ts +0 -0
- package/src/presentation/hooks/useRegisterForm.ts +40 -18
- package/src/presentation/navigation/AuthNavigator.tsx +2 -2
- package/src/presentation/screens/LoginScreen.tsx +3 -6
- package/src/presentation/screens/RegisterScreen.tsx +3 -6
- package/src/presentation/utils/getAuthErrorMessage.ts +0 -0
- package/src/types/external.d.ts +68 -0
- package/LICENSE +0 -22
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage Provider Adapter
|
|
3
|
+
* Adapts external storage implementations to our IStorageProvider interface
|
|
4
|
+
*/
|
|
5
|
+
export class StorageProviderAdapter {
|
|
6
|
+
constructor(storage) {
|
|
7
|
+
this.storage = storage;
|
|
8
|
+
}
|
|
9
|
+
async get(key) {
|
|
10
|
+
try {
|
|
11
|
+
if (this.storage.getString) {
|
|
12
|
+
// @umituz/react-native-storage format
|
|
13
|
+
const result = await this.storage.getString(key, null);
|
|
14
|
+
return result?.value ?? null;
|
|
15
|
+
}
|
|
16
|
+
else if (this.storage.getItem) {
|
|
17
|
+
// AsyncStorage format
|
|
18
|
+
return await this.storage.getItem(key);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
throw new Error("Unsupported storage implementation");
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async set(key, value) {
|
|
29
|
+
try {
|
|
30
|
+
if (this.storage.setString) {
|
|
31
|
+
// @umituz/react-native-storage format
|
|
32
|
+
await this.storage.setString(key, value);
|
|
33
|
+
}
|
|
34
|
+
else if (this.storage.setItem) {
|
|
35
|
+
// AsyncStorage format
|
|
36
|
+
await this.storage.setItem(key, value);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
throw new Error("Unsupported storage implementation");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (__DEV__) {
|
|
44
|
+
console.warn("[StorageProviderAdapter] Failed to set value:", error);
|
|
45
|
+
}
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async remove(key) {
|
|
50
|
+
try {
|
|
51
|
+
if (this.storage.removeItem) {
|
|
52
|
+
// Both AsyncStorage and @umituz/react-native-storage support removeItem
|
|
53
|
+
await this.storage.removeItem(key);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
throw new Error("Unsupported storage implementation");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (__DEV__) {
|
|
61
|
+
console.warn("[StorageProviderAdapter] Failed to remove value:", error);
|
|
62
|
+
}
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Create storage provider from various storage implementations
|
|
69
|
+
*/
|
|
70
|
+
export function createStorageProvider(storage) {
|
|
71
|
+
return new StorageProviderAdapter(storage);
|
|
72
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI Provider Adapter
|
|
3
|
+
* Adapts external UI implementations to our IUIProvider interface
|
|
4
|
+
*/
|
|
5
|
+
import type { IUIProvider } from "../services/AuthPackage";
|
|
6
|
+
export declare class UIProviderAdapter implements IUIProvider {
|
|
7
|
+
private theme;
|
|
8
|
+
private localization;
|
|
9
|
+
constructor(theme?: any, localization?: any);
|
|
10
|
+
getTheme(): any;
|
|
11
|
+
getLocalization(): any;
|
|
12
|
+
updateTheme(theme: any): void;
|
|
13
|
+
updateLocalization(localization: any): void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Create UI provider from theme and localization implementations
|
|
17
|
+
*/
|
|
18
|
+
export declare function createUIProvider(theme?: any, localization?: any): IUIProvider;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI Provider Adapter
|
|
3
|
+
* Adapts external UI implementations to our IUIProvider interface
|
|
4
|
+
*/
|
|
5
|
+
export class UIProviderAdapter {
|
|
6
|
+
constructor(theme, localization) {
|
|
7
|
+
this.theme = theme;
|
|
8
|
+
this.localization = localization;
|
|
9
|
+
}
|
|
10
|
+
getTheme() {
|
|
11
|
+
return this.theme;
|
|
12
|
+
}
|
|
13
|
+
getLocalization() {
|
|
14
|
+
return this.localization;
|
|
15
|
+
}
|
|
16
|
+
updateTheme(theme) {
|
|
17
|
+
this.theme = theme;
|
|
18
|
+
}
|
|
19
|
+
updateLocalization(localization) {
|
|
20
|
+
this.localization = localization;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Create UI provider from theme and localization implementations
|
|
25
|
+
*/
|
|
26
|
+
export function createUIProvider(theme, localization) {
|
|
27
|
+
return new UIProviderAdapter(theme, localization);
|
|
28
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Firebase Auth Provider
|
|
3
|
+
* IAuthProvider implementation for Firebase Authentication
|
|
4
|
+
*/
|
|
5
|
+
import { type Auth } from "firebase/auth";
|
|
6
|
+
import type { IAuthProvider, AuthCredentials, SignUpCredentials } from "../../application/ports/IAuthProvider";
|
|
7
|
+
import type { AuthUser } from "../../domain/entities/AuthUser";
|
|
8
|
+
export declare class FirebaseAuthProvider implements IAuthProvider {
|
|
9
|
+
private auth;
|
|
10
|
+
constructor(auth?: Auth);
|
|
11
|
+
initialize(): Promise<void>;
|
|
12
|
+
setAuth(auth: Auth): void;
|
|
13
|
+
isInitialized(): boolean;
|
|
14
|
+
signIn(credentials: AuthCredentials): Promise<AuthUser>;
|
|
15
|
+
signUp(credentials: SignUpCredentials): Promise<AuthUser>;
|
|
16
|
+
signOut(): Promise<void>;
|
|
17
|
+
getCurrentUser(): AuthUser | null;
|
|
18
|
+
onAuthStateChange(callback: (user: AuthUser | null) => void): () => void;
|
|
19
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Firebase Auth Provider
|
|
3
|
+
* IAuthProvider implementation for Firebase Authentication
|
|
4
|
+
*/
|
|
5
|
+
import { createUserWithEmailAndPassword, signInWithEmailAndPassword, signOut as firebaseSignOut, onAuthStateChanged, updateProfile, } from "firebase/auth";
|
|
6
|
+
import { mapFirebaseAuthError } from "../utils/AuthErrorMapper";
|
|
7
|
+
import { mapToAuthUser } from "../utils/UserMapper";
|
|
8
|
+
export class FirebaseAuthProvider {
|
|
9
|
+
constructor(auth) {
|
|
10
|
+
this.auth = null;
|
|
11
|
+
if (auth) {
|
|
12
|
+
this.auth = auth;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
async initialize() {
|
|
16
|
+
if (!this.auth) {
|
|
17
|
+
throw new Error("Firebase Auth instance must be provided");
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
setAuth(auth) {
|
|
21
|
+
this.auth = auth;
|
|
22
|
+
}
|
|
23
|
+
isInitialized() {
|
|
24
|
+
return this.auth !== null;
|
|
25
|
+
}
|
|
26
|
+
async signIn(credentials) {
|
|
27
|
+
if (!this.auth) {
|
|
28
|
+
throw new Error("Firebase Auth is not initialized");
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const userCredential = await signInWithEmailAndPassword(this.auth, credentials.email.trim(), credentials.password);
|
|
32
|
+
const user = mapToAuthUser(userCredential.user);
|
|
33
|
+
if (!user) {
|
|
34
|
+
throw new Error("Failed to sign in");
|
|
35
|
+
}
|
|
36
|
+
return user;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
throw mapFirebaseAuthError(error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async signUp(credentials) {
|
|
43
|
+
if (!this.auth) {
|
|
44
|
+
throw new Error("Firebase Auth is not initialized");
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const userCredential = await createUserWithEmailAndPassword(this.auth, credentials.email.trim(), credentials.password);
|
|
48
|
+
if (credentials.displayName && userCredential.user) {
|
|
49
|
+
try {
|
|
50
|
+
await updateProfile(userCredential.user, {
|
|
51
|
+
displayName: credentials.displayName.trim(),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// Don't fail signup if display name update fails
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const user = mapToAuthUser(userCredential.user);
|
|
59
|
+
if (!user) {
|
|
60
|
+
throw new Error("Failed to create user account");
|
|
61
|
+
}
|
|
62
|
+
return user;
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
throw mapFirebaseAuthError(error);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async signOut() {
|
|
69
|
+
if (!this.auth) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
await firebaseSignOut(this.auth);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
throw mapFirebaseAuthError(error);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
getCurrentUser() {
|
|
80
|
+
if (!this.auth?.currentUser) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
return mapToAuthUser(this.auth.currentUser);
|
|
84
|
+
}
|
|
85
|
+
onAuthStateChange(callback) {
|
|
86
|
+
if (!this.auth) {
|
|
87
|
+
callback(null);
|
|
88
|
+
return () => { };
|
|
89
|
+
}
|
|
90
|
+
return onAuthStateChanged(this.auth, (user) => {
|
|
91
|
+
callback(mapToAuthUser(user));
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Core Service
|
|
3
|
+
* Handles core authentication operations
|
|
4
|
+
*/
|
|
5
|
+
import type { IAuthService, SignUpParams, SignInParams } from "../../application/ports/IAuthService";
|
|
6
|
+
import type { IAuthProvider } from "../../application/ports/IAuthProvider";
|
|
7
|
+
import type { AuthUser } from "../../domain/entities/AuthUser";
|
|
8
|
+
import type { AuthConfig } from "../../domain/value-objects/AuthConfig";
|
|
9
|
+
export declare class AuthCoreService implements Partial<IAuthService> {
|
|
10
|
+
private provider;
|
|
11
|
+
private config;
|
|
12
|
+
constructor(config: AuthConfig);
|
|
13
|
+
initialize(providerOrAuth: IAuthProvider | any): Promise<void>;
|
|
14
|
+
isInitialized(): boolean;
|
|
15
|
+
private getProvider;
|
|
16
|
+
signUp(params: SignUpParams): Promise<AuthUser>;
|
|
17
|
+
signIn(params: SignInParams): Promise<AuthUser>;
|
|
18
|
+
signOut(): Promise<void>;
|
|
19
|
+
getCurrentUser(): AuthUser | null;
|
|
20
|
+
onAuthStateChange(callback: (user: AuthUser | null) => void): () => void;
|
|
21
|
+
getConfig(): AuthConfig;
|
|
22
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Core Service
|
|
3
|
+
* Handles core authentication operations
|
|
4
|
+
*/
|
|
5
|
+
import { AuthInitializationError, AuthValidationError, AuthWeakPasswordError, AuthInvalidEmailError, } from "../../domain/errors/AuthError";
|
|
6
|
+
import { validateEmail, validatePasswordForLogin, validatePasswordForRegister, validateDisplayName, } from "../utils/AuthValidation";
|
|
7
|
+
export class AuthCoreService {
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.provider = null;
|
|
10
|
+
this.config = config;
|
|
11
|
+
}
|
|
12
|
+
async initialize(providerOrAuth) {
|
|
13
|
+
if (!providerOrAuth) {
|
|
14
|
+
throw new AuthInitializationError("Auth provider or Firebase Auth instance is required");
|
|
15
|
+
}
|
|
16
|
+
// Check if it's a Firebase Auth instance (has currentUser property)
|
|
17
|
+
if ("currentUser" in providerOrAuth) {
|
|
18
|
+
// Import FirebaseAuthProvider directly
|
|
19
|
+
const { FirebaseAuthProvider } = require("../providers/FirebaseAuthProvider");
|
|
20
|
+
const firebaseProvider = new FirebaseAuthProvider(providerOrAuth);
|
|
21
|
+
await firebaseProvider.initialize();
|
|
22
|
+
this.provider = firebaseProvider;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
this.provider = providerOrAuth;
|
|
26
|
+
await this.provider.initialize();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
isInitialized() {
|
|
30
|
+
return this.provider !== null && this.provider.isInitialized();
|
|
31
|
+
}
|
|
32
|
+
getProvider() {
|
|
33
|
+
if (!this.provider || !this.provider.isInitialized()) {
|
|
34
|
+
throw new AuthInitializationError("Auth service is not initialized");
|
|
35
|
+
}
|
|
36
|
+
return this.provider;
|
|
37
|
+
}
|
|
38
|
+
async signUp(params) {
|
|
39
|
+
const provider = this.getProvider();
|
|
40
|
+
// Validate email
|
|
41
|
+
const emailResult = validateEmail(params.email);
|
|
42
|
+
if (!emailResult.isValid) {
|
|
43
|
+
throw new AuthInvalidEmailError(emailResult.error);
|
|
44
|
+
}
|
|
45
|
+
// Validate display name if provided
|
|
46
|
+
if (params.displayName) {
|
|
47
|
+
const nameResult = validateDisplayName(params.displayName);
|
|
48
|
+
if (!nameResult.isValid) {
|
|
49
|
+
throw new AuthValidationError(nameResult.error || "Invalid name", "displayName");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Validate password strength for registration
|
|
53
|
+
const passwordResult = validatePasswordForRegister(params.password, this.config.password);
|
|
54
|
+
if (!passwordResult.isValid) {
|
|
55
|
+
throw new AuthWeakPasswordError(passwordResult.error);
|
|
56
|
+
}
|
|
57
|
+
return provider.signUp({
|
|
58
|
+
email: params.email,
|
|
59
|
+
password: params.password,
|
|
60
|
+
displayName: params.displayName,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
async signIn(params) {
|
|
64
|
+
const provider = this.getProvider();
|
|
65
|
+
// Validate email format
|
|
66
|
+
const emailResult = validateEmail(params.email);
|
|
67
|
+
if (!emailResult.isValid) {
|
|
68
|
+
throw new AuthInvalidEmailError(emailResult.error);
|
|
69
|
+
}
|
|
70
|
+
// For login, only check if password is provided (no strength requirements)
|
|
71
|
+
const passwordResult = validatePasswordForLogin(params.password);
|
|
72
|
+
if (!passwordResult.isValid) {
|
|
73
|
+
throw new AuthValidationError(passwordResult.error || "Password is required", "password");
|
|
74
|
+
}
|
|
75
|
+
return provider.signIn({
|
|
76
|
+
email: params.email,
|
|
77
|
+
password: params.password,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
async signOut() {
|
|
81
|
+
if (!this.provider) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
await this.provider.signOut();
|
|
85
|
+
}
|
|
86
|
+
getCurrentUser() {
|
|
87
|
+
if (!this.provider) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
return this.provider.getCurrentUser();
|
|
91
|
+
}
|
|
92
|
+
onAuthStateChange(callback) {
|
|
93
|
+
if (!this.provider) {
|
|
94
|
+
callback(null);
|
|
95
|
+
return () => { };
|
|
96
|
+
}
|
|
97
|
+
return this.provider.onAuthStateChange(callback);
|
|
98
|
+
}
|
|
99
|
+
getConfig() {
|
|
100
|
+
return this.config;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Event Service
|
|
3
|
+
* Handles authentication event emission and management
|
|
4
|
+
*/
|
|
5
|
+
export interface AuthEventPayload {
|
|
6
|
+
userId?: string;
|
|
7
|
+
error?: string;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
}
|
|
10
|
+
export interface AuthEventListener {
|
|
11
|
+
(payload: AuthEventPayload): void;
|
|
12
|
+
}
|
|
13
|
+
export declare class AuthEventService {
|
|
14
|
+
private static instance;
|
|
15
|
+
private listeners;
|
|
16
|
+
private constructor();
|
|
17
|
+
static getInstance(): AuthEventService;
|
|
18
|
+
emitUserAuthenticated(userId: string): void;
|
|
19
|
+
emitGuestModeEnabled(): void;
|
|
20
|
+
emitAuthError(error: string): void;
|
|
21
|
+
addEventListener(event: string, listener: AuthEventListener): () => void;
|
|
22
|
+
removeAllListeners(event?: string): void;
|
|
23
|
+
private notifyListeners;
|
|
24
|
+
}
|
|
25
|
+
export declare const authEventService: AuthEventService;
|
|
26
|
+
export declare function emitUserAuthenticated(userId: string): void;
|
|
27
|
+
export declare function emitGuestModeEnabled(): void;
|
|
28
|
+
export declare function emitAuthError(error: string): void;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Event Service
|
|
3
|
+
* Handles authentication event emission and management
|
|
4
|
+
*/
|
|
5
|
+
import { DeviceEventEmitter } from "react-native";
|
|
6
|
+
export class AuthEventService {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.listeners = new Map();
|
|
9
|
+
}
|
|
10
|
+
static getInstance() {
|
|
11
|
+
if (!AuthEventService.instance) {
|
|
12
|
+
AuthEventService.instance = new AuthEventService();
|
|
13
|
+
}
|
|
14
|
+
return AuthEventService.instance;
|
|
15
|
+
}
|
|
16
|
+
emitUserAuthenticated(userId) {
|
|
17
|
+
const payload = {
|
|
18
|
+
userId,
|
|
19
|
+
timestamp: Date.now(),
|
|
20
|
+
};
|
|
21
|
+
DeviceEventEmitter.emit("user-authenticated", payload);
|
|
22
|
+
this.notifyListeners("user-authenticated", payload);
|
|
23
|
+
}
|
|
24
|
+
emitGuestModeEnabled() {
|
|
25
|
+
const payload = {
|
|
26
|
+
timestamp: Date.now(),
|
|
27
|
+
};
|
|
28
|
+
DeviceEventEmitter.emit("guest-mode-enabled", payload);
|
|
29
|
+
this.notifyListeners("guest-mode-enabled", payload);
|
|
30
|
+
}
|
|
31
|
+
emitAuthError(error) {
|
|
32
|
+
const payload = {
|
|
33
|
+
error,
|
|
34
|
+
timestamp: Date.now(),
|
|
35
|
+
};
|
|
36
|
+
DeviceEventEmitter.emit("auth-error", payload);
|
|
37
|
+
this.notifyListeners("auth-error", payload);
|
|
38
|
+
}
|
|
39
|
+
addEventListener(event, listener) {
|
|
40
|
+
if (!this.listeners.has(event)) {
|
|
41
|
+
this.listeners.set(event, []);
|
|
42
|
+
}
|
|
43
|
+
const eventListeners = this.listeners.get(event);
|
|
44
|
+
eventListeners.push(listener);
|
|
45
|
+
// Return cleanup function
|
|
46
|
+
return () => {
|
|
47
|
+
const index = eventListeners.indexOf(listener);
|
|
48
|
+
if (index > -1) {
|
|
49
|
+
eventListeners.splice(index, 1);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
removeAllListeners(event) {
|
|
54
|
+
if (event) {
|
|
55
|
+
this.listeners.delete(event);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
this.listeners.clear();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
notifyListeners(event, payload) {
|
|
62
|
+
const eventListeners = this.listeners.get(event);
|
|
63
|
+
if (eventListeners) {
|
|
64
|
+
eventListeners.forEach(listener => {
|
|
65
|
+
try {
|
|
66
|
+
listener(payload);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (__DEV__) {
|
|
70
|
+
console.error(`Error in auth event listener for ${event}:`, error);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Export singleton instance for backward compatibility
|
|
78
|
+
export const authEventService = AuthEventService.getInstance();
|
|
79
|
+
// Legacy functions for backward compatibility
|
|
80
|
+
export function emitUserAuthenticated(userId) {
|
|
81
|
+
authEventService.emitUserAuthenticated(userId);
|
|
82
|
+
}
|
|
83
|
+
export function emitGuestModeEnabled() {
|
|
84
|
+
authEventService.emitGuestModeEnabled();
|
|
85
|
+
}
|
|
86
|
+
export function emitAuthError(error) {
|
|
87
|
+
authEventService.emitAuthError(error);
|
|
88
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Package Configuration
|
|
3
|
+
* Centralized configuration for the auth package
|
|
4
|
+
*/
|
|
5
|
+
import type { PasswordConfig } from "../../domain/value-objects/AuthConfig";
|
|
6
|
+
export interface AuthPackageConfig {
|
|
7
|
+
storageKeys: {
|
|
8
|
+
guestMode: string;
|
|
9
|
+
showRegister: string;
|
|
10
|
+
};
|
|
11
|
+
validation: {
|
|
12
|
+
emailRegex: RegExp;
|
|
13
|
+
passwordConfig: PasswordConfig;
|
|
14
|
+
};
|
|
15
|
+
ui: {
|
|
16
|
+
theme?: any;
|
|
17
|
+
localization?: any;
|
|
18
|
+
};
|
|
19
|
+
features: {
|
|
20
|
+
guestMode: boolean;
|
|
21
|
+
registration: boolean;
|
|
22
|
+
passwordStrength: boolean;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export declare const DEFAULT_AUTH_PACKAGE_CONFIG: AuthPackageConfig;
|
|
26
|
+
export interface IStorageProvider {
|
|
27
|
+
get(key: string): Promise<string | null>;
|
|
28
|
+
set(key: string, value: string): Promise<void>;
|
|
29
|
+
remove(key: string): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
export interface IUIProvider {
|
|
32
|
+
getTheme(): any;
|
|
33
|
+
getLocalization(): any;
|
|
34
|
+
}
|
|
35
|
+
export interface IValidationProvider {
|
|
36
|
+
validateEmail(email: string): {
|
|
37
|
+
isValid: boolean;
|
|
38
|
+
error?: string;
|
|
39
|
+
};
|
|
40
|
+
validatePassword(password: string, config: PasswordConfig): {
|
|
41
|
+
isValid: boolean;
|
|
42
|
+
error?: string;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export declare class AuthPackage {
|
|
46
|
+
private config;
|
|
47
|
+
private storageProvider?;
|
|
48
|
+
private uiProvider?;
|
|
49
|
+
private validationProvider?;
|
|
50
|
+
constructor(config?: Partial<AuthPackageConfig>);
|
|
51
|
+
setStorageProvider(provider: IStorageProvider): void;
|
|
52
|
+
setUIProvider(provider: IUIProvider): void;
|
|
53
|
+
setValidationProvider(provider: IValidationProvider): void;
|
|
54
|
+
getConfig(): AuthPackageConfig;
|
|
55
|
+
getStorageProvider(): IStorageProvider | undefined;
|
|
56
|
+
getUIProvider(): IUIProvider | undefined;
|
|
57
|
+
getValidationProvider(): IValidationProvider | undefined;
|
|
58
|
+
isFeatureEnabled(feature: keyof AuthPackageConfig['features']): boolean;
|
|
59
|
+
}
|
|
60
|
+
export declare function initializeAuthPackage(config?: Partial<AuthPackageConfig>): AuthPackage;
|
|
61
|
+
export declare function getAuthPackage(): AuthPackage | null;
|
|
62
|
+
export declare function resetAuthPackage(): void;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Package Configuration
|
|
3
|
+
* Centralized configuration for the auth package
|
|
4
|
+
*/
|
|
5
|
+
export const DEFAULT_AUTH_PACKAGE_CONFIG = {
|
|
6
|
+
storageKeys: {
|
|
7
|
+
guestMode: "@auth_guest_mode",
|
|
8
|
+
showRegister: "auth_show_register",
|
|
9
|
+
},
|
|
10
|
+
validation: {
|
|
11
|
+
emailRegex: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
|
|
12
|
+
passwordConfig: {
|
|
13
|
+
minLength: 8,
|
|
14
|
+
requireUppercase: true,
|
|
15
|
+
requireLowercase: true,
|
|
16
|
+
requireNumber: true,
|
|
17
|
+
requireSpecialChar: false,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
ui: {
|
|
21
|
+
theme: undefined,
|
|
22
|
+
localization: undefined,
|
|
23
|
+
},
|
|
24
|
+
features: {
|
|
25
|
+
guestMode: true,
|
|
26
|
+
registration: true,
|
|
27
|
+
passwordStrength: true,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
export class AuthPackage {
|
|
31
|
+
constructor(config = {}) {
|
|
32
|
+
this.config = {
|
|
33
|
+
...DEFAULT_AUTH_PACKAGE_CONFIG,
|
|
34
|
+
...config,
|
|
35
|
+
validation: {
|
|
36
|
+
...DEFAULT_AUTH_PACKAGE_CONFIG.validation,
|
|
37
|
+
...config.validation,
|
|
38
|
+
passwordConfig: {
|
|
39
|
+
...DEFAULT_AUTH_PACKAGE_CONFIG.validation.passwordConfig,
|
|
40
|
+
...config.validation?.passwordConfig,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
ui: {
|
|
44
|
+
...DEFAULT_AUTH_PACKAGE_CONFIG.ui,
|
|
45
|
+
...config.ui,
|
|
46
|
+
},
|
|
47
|
+
features: {
|
|
48
|
+
...DEFAULT_AUTH_PACKAGE_CONFIG.features,
|
|
49
|
+
...config.features,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
setStorageProvider(provider) {
|
|
54
|
+
this.storageProvider = provider;
|
|
55
|
+
}
|
|
56
|
+
setUIProvider(provider) {
|
|
57
|
+
this.uiProvider = provider;
|
|
58
|
+
}
|
|
59
|
+
setValidationProvider(provider) {
|
|
60
|
+
this.validationProvider = provider;
|
|
61
|
+
}
|
|
62
|
+
getConfig() {
|
|
63
|
+
return this.config;
|
|
64
|
+
}
|
|
65
|
+
getStorageProvider() {
|
|
66
|
+
return this.storageProvider;
|
|
67
|
+
}
|
|
68
|
+
getUIProvider() {
|
|
69
|
+
return this.uiProvider;
|
|
70
|
+
}
|
|
71
|
+
getValidationProvider() {
|
|
72
|
+
return this.validationProvider;
|
|
73
|
+
}
|
|
74
|
+
isFeatureEnabled(feature) {
|
|
75
|
+
return this.config.features[feature];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Global package instance
|
|
79
|
+
let packageInstance = null;
|
|
80
|
+
export function initializeAuthPackage(config = {}) {
|
|
81
|
+
if (!packageInstance) {
|
|
82
|
+
packageInstance = new AuthPackage(config);
|
|
83
|
+
}
|
|
84
|
+
return packageInstance;
|
|
85
|
+
}
|
|
86
|
+
export function getAuthPackage() {
|
|
87
|
+
return packageInstance;
|
|
88
|
+
}
|
|
89
|
+
export function resetAuthPackage() {
|
|
90
|
+
packageInstance = null;
|
|
91
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Service
|
|
3
|
+
* Orchestrates authentication operations using composition
|
|
4
|
+
*/
|
|
5
|
+
import type { Auth } from "firebase/auth";
|
|
6
|
+
import type { IAuthService, SignUpParams, SignInParams } from "../../application/ports/IAuthService";
|
|
7
|
+
import type { IAuthProvider } from "../../application/ports/IAuthProvider";
|
|
8
|
+
import type { AuthUser } from "../../domain/entities/AuthUser";
|
|
9
|
+
import type { AuthConfig } from "../../domain/value-objects/AuthConfig";
|
|
10
|
+
import { AuthCoreService } from "./AuthCoreService";
|
|
11
|
+
import { GuestModeService, type IStorageProvider } from "./GuestModeService";
|
|
12
|
+
export declare class AuthService implements IAuthService {
|
|
13
|
+
private coreService;
|
|
14
|
+
private guestModeService;
|
|
15
|
+
private storageProvider?;
|
|
16
|
+
private initialized;
|
|
17
|
+
constructor(config?: Partial<AuthConfig>, storageProvider?: IStorageProvider);
|
|
18
|
+
initialize(providerOrAuth: IAuthProvider | Auth): Promise<void>;
|
|
19
|
+
isInitialized(): boolean;
|
|
20
|
+
signUp(params: SignUpParams): Promise<AuthUser>;
|
|
21
|
+
signIn(params: SignInParams): Promise<AuthUser>;
|
|
22
|
+
signOut(): Promise<void>;
|
|
23
|
+
setGuestMode(): Promise<void>;
|
|
24
|
+
getCurrentUser(): AuthUser | null;
|
|
25
|
+
getIsGuestMode(): boolean;
|
|
26
|
+
onAuthStateChange(callback: (user: AuthUser | null) => void): () => void;
|
|
27
|
+
getConfig(): AuthConfig;
|
|
28
|
+
getCoreService(): AuthCoreService;
|
|
29
|
+
getGuestModeService(): GuestModeService;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Initialize auth service with provider or Firebase Auth instance
|
|
33
|
+
*/
|
|
34
|
+
export declare function initializeAuthService(providerOrAuth: IAuthProvider | Auth, config?: Partial<AuthConfig>, storageProvider?: IStorageProvider): Promise<AuthService>;
|
|
35
|
+
/**
|
|
36
|
+
* Get auth service instance
|
|
37
|
+
*/
|
|
38
|
+
export declare function getAuthService(): AuthService | null;
|
|
39
|
+
/**
|
|
40
|
+
* Reset auth service (useful for testing)
|
|
41
|
+
*/
|
|
42
|
+
export declare function resetAuthService(): void;
|