@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.
Files changed (136) hide show
  1. package/README.md +0 -0
  2. package/lib/__tests__/services/AuthCoreService.test.d.ts +4 -0
  3. package/lib/__tests__/services/AuthCoreService.test.js +198 -0
  4. package/lib/__tests__/services/AuthPackage.test.d.ts +4 -0
  5. package/lib/__tests__/services/AuthPackage.test.js +177 -0
  6. package/lib/__tests__/services/GuestModeService.test.d.ts +4 -0
  7. package/lib/__tests__/services/GuestModeService.test.js +141 -0
  8. package/lib/__tests__/utils/AuthValidation.test.d.ts +4 -0
  9. package/lib/__tests__/utils/AuthValidation.test.js +222 -0
  10. package/lib/application/ports/IAuthProvider.d.ts +42 -0
  11. package/lib/application/ports/IAuthProvider.js +5 -0
  12. package/lib/application/ports/IAuthService.d.ts +48 -0
  13. package/lib/application/ports/IAuthService.js +5 -0
  14. package/lib/domain/entities/AuthUser.d.ts +12 -0
  15. package/lib/domain/entities/AuthUser.js +5 -0
  16. package/lib/domain/errors/AuthError.d.ts +36 -0
  17. package/lib/domain/errors/AuthError.js +76 -0
  18. package/lib/domain/value-objects/AuthConfig.d.ts +16 -0
  19. package/lib/domain/value-objects/AuthConfig.js +14 -0
  20. package/lib/index.d.ts +45 -0
  21. package/lib/index.js +59 -0
  22. package/lib/infrastructure/adapters/StorageProviderAdapter.d.ts +16 -0
  23. package/lib/infrastructure/adapters/StorageProviderAdapter.js +72 -0
  24. package/lib/infrastructure/adapters/UIProviderAdapter.d.ts +18 -0
  25. package/lib/infrastructure/adapters/UIProviderAdapter.js +28 -0
  26. package/lib/infrastructure/providers/FirebaseAuthProvider.d.ts +19 -0
  27. package/lib/infrastructure/providers/FirebaseAuthProvider.js +94 -0
  28. package/lib/infrastructure/services/AuthCoreService.d.ts +22 -0
  29. package/lib/infrastructure/services/AuthCoreService.js +102 -0
  30. package/lib/infrastructure/services/AuthEventService.d.ts +28 -0
  31. package/lib/infrastructure/services/AuthEventService.js +88 -0
  32. package/lib/infrastructure/services/AuthPackage.d.ts +62 -0
  33. package/lib/infrastructure/services/AuthPackage.js +91 -0
  34. package/lib/infrastructure/services/AuthService.d.ts +42 -0
  35. package/lib/infrastructure/services/AuthService.js +123 -0
  36. package/lib/infrastructure/services/GuestModeService.d.ts +23 -0
  37. package/lib/infrastructure/services/GuestModeService.js +69 -0
  38. package/lib/infrastructure/storage/GuestModeStorage.d.ts +16 -0
  39. package/lib/infrastructure/storage/GuestModeStorage.js +73 -0
  40. package/lib/infrastructure/utils/AuthErrorMapper.d.ts +8 -0
  41. package/lib/infrastructure/utils/AuthErrorMapper.js +51 -0
  42. package/lib/infrastructure/utils/AuthEventEmitter.d.ts +12 -0
  43. package/lib/infrastructure/utils/AuthEventEmitter.js +25 -0
  44. package/lib/infrastructure/utils/AuthValidation.d.ts +49 -0
  45. package/lib/infrastructure/utils/AuthValidation.js +133 -0
  46. package/lib/infrastructure/utils/UserMapper.d.ts +15 -0
  47. package/lib/infrastructure/utils/UserMapper.js +16 -0
  48. package/lib/presentation/components/AuthContainer.d.ts +10 -0
  49. package/lib/presentation/components/AuthContainer.js +27 -0
  50. package/lib/presentation/components/AuthDivider.d.ts +6 -0
  51. package/lib/presentation/components/AuthDivider.js +36 -0
  52. package/lib/presentation/components/AuthErrorDisplay.d.ts +10 -0
  53. package/lib/presentation/components/AuthErrorDisplay.js +24 -0
  54. package/lib/presentation/components/AuthFormCard.d.ts +10 -0
  55. package/lib/presentation/components/AuthFormCard.js +19 -0
  56. package/lib/presentation/components/AuthGradientBackground.d.ts +6 -0
  57. package/lib/presentation/components/AuthGradientBackground.js +8 -0
  58. package/lib/presentation/components/AuthHeader.d.ts +11 -0
  59. package/lib/presentation/components/AuthHeader.js +38 -0
  60. package/lib/presentation/components/AuthLegalLinks.d.ts +28 -0
  61. package/lib/presentation/components/AuthLegalLinks.js +54 -0
  62. package/lib/presentation/components/AuthLink.d.ts +13 -0
  63. package/lib/presentation/components/AuthLink.js +27 -0
  64. package/lib/presentation/components/LoginForm.d.ts +10 -0
  65. package/lib/presentation/components/LoginForm.js +27 -0
  66. package/lib/presentation/components/PasswordMatchIndicator.d.ts +9 -0
  67. package/lib/presentation/components/PasswordMatchIndicator.js +30 -0
  68. package/lib/presentation/components/PasswordStrengthIndicator.d.ts +11 -0
  69. package/lib/presentation/components/PasswordStrengthIndicator.js +60 -0
  70. package/lib/presentation/components/RegisterForm.d.ts +14 -0
  71. package/lib/presentation/components/RegisterForm.js +30 -0
  72. package/lib/presentation/hooks/useAuth.d.ts +44 -0
  73. package/lib/presentation/hooks/useAuth.js +38 -0
  74. package/lib/presentation/hooks/useAuthActions.d.ts +15 -0
  75. package/lib/presentation/hooks/useAuthActions.js +162 -0
  76. package/lib/presentation/hooks/useAuthState.d.ts +19 -0
  77. package/lib/presentation/hooks/useAuthState.js +79 -0
  78. package/lib/presentation/hooks/useLoginForm.d.ts +21 -0
  79. package/lib/presentation/hooks/useLoginForm.js +131 -0
  80. package/lib/presentation/hooks/useRegisterForm.d.ts +31 -0
  81. package/lib/presentation/hooks/useRegisterForm.js +136 -0
  82. package/lib/presentation/navigation/AuthNavigator.d.ts +28 -0
  83. package/lib/presentation/navigation/AuthNavigator.js +37 -0
  84. package/lib/presentation/screens/LoginScreen.d.ts +6 -0
  85. package/lib/presentation/screens/LoginScreen.js +15 -0
  86. package/lib/presentation/screens/RegisterScreen.d.ts +12 -0
  87. package/lib/presentation/screens/RegisterScreen.js +15 -0
  88. package/lib/presentation/utils/getAuthErrorMessage.d.ts +8 -0
  89. package/lib/presentation/utils/getAuthErrorMessage.js +69 -0
  90. package/package.json +12 -4
  91. package/src/__tests__/services/AuthCoreService.test.ts +247 -0
  92. package/src/__tests__/services/AuthPackage.test.ts +226 -0
  93. package/src/__tests__/services/GuestModeService.test.ts +194 -0
  94. package/src/__tests__/utils/AuthValidation.test.ts +270 -0
  95. package/src/application/ports/IAuthProvider.ts +0 -0
  96. package/src/application/ports/IAuthService.ts +0 -0
  97. package/src/domain/entities/AuthUser.ts +0 -0
  98. package/src/domain/errors/AuthError.ts +0 -0
  99. package/src/domain/value-objects/AuthConfig.ts +0 -0
  100. package/src/index.ts +4 -0
  101. package/src/infrastructure/adapters/StorageProviderAdapter.ts +73 -0
  102. package/src/infrastructure/adapters/UIProviderAdapter.ts +39 -0
  103. package/src/infrastructure/providers/FirebaseAuthProvider.ts +10 -2
  104. package/src/infrastructure/services/AuthCoreService.ts +138 -0
  105. package/src/infrastructure/services/AuthEventService.ts +115 -0
  106. package/src/infrastructure/services/AuthPackage.ts +148 -0
  107. package/src/infrastructure/services/AuthService.ts +62 -128
  108. package/src/infrastructure/services/GuestModeService.ts +86 -0
  109. package/src/infrastructure/storage/GuestModeStorage.ts +40 -14
  110. package/src/infrastructure/utils/AuthErrorMapper.ts +7 -3
  111. package/src/infrastructure/utils/AuthEventEmitter.ts +0 -0
  112. package/src/infrastructure/utils/AuthValidation.ts +47 -17
  113. package/src/infrastructure/utils/UserMapper.ts +0 -0
  114. package/src/presentation/components/AuthContainer.tsx +0 -0
  115. package/src/presentation/components/AuthDivider.tsx +0 -0
  116. package/src/presentation/components/AuthErrorDisplay.tsx +0 -0
  117. package/src/presentation/components/AuthFormCard.tsx +0 -0
  118. package/src/presentation/components/AuthGradientBackground.tsx +0 -0
  119. package/src/presentation/components/AuthHeader.tsx +0 -0
  120. package/src/presentation/components/AuthLegalLinks.tsx +0 -0
  121. package/src/presentation/components/AuthLink.tsx +0 -0
  122. package/src/presentation/components/LoginForm.tsx +0 -0
  123. package/src/presentation/components/PasswordMatchIndicator.tsx +50 -0
  124. package/src/presentation/components/PasswordStrengthIndicator.tsx +118 -0
  125. package/src/presentation/components/RegisterForm.tsx +10 -0
  126. package/src/presentation/hooks/useAuth.ts +0 -0
  127. package/src/presentation/hooks/useAuthActions.ts +8 -11
  128. package/src/presentation/hooks/useAuthState.ts +10 -0
  129. package/src/presentation/hooks/useLoginForm.ts +0 -0
  130. package/src/presentation/hooks/useRegisterForm.ts +40 -18
  131. package/src/presentation/navigation/AuthNavigator.tsx +2 -2
  132. package/src/presentation/screens/LoginScreen.tsx +3 -6
  133. package/src/presentation/screens/RegisterScreen.tsx +3 -6
  134. package/src/presentation/utils/getAuthErrorMessage.ts +0 -0
  135. package/src/types/external.d.ts +68 -0
  136. package/LICENSE +0 -22
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Auth Core Service
3
+ * Handles core authentication operations
4
+ */
5
+
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 {
11
+ AuthInitializationError,
12
+ AuthValidationError,
13
+ AuthWeakPasswordError,
14
+ AuthInvalidEmailError,
15
+ } from "../../domain/errors/AuthError";
16
+ import {
17
+ validateEmail,
18
+ validatePasswordForLogin,
19
+ validatePasswordForRegister,
20
+ validateDisplayName,
21
+ } from "../utils/AuthValidation";
22
+
23
+ export class AuthCoreService implements Partial<IAuthService> {
24
+ private provider: IAuthProvider | null = null;
25
+ private config: AuthConfig;
26
+
27
+ constructor(config: AuthConfig) {
28
+ this.config = config;
29
+ }
30
+
31
+ async initialize(providerOrAuth: IAuthProvider | any): Promise<void> {
32
+ if (!providerOrAuth) {
33
+ throw new AuthInitializationError("Auth provider or Firebase Auth instance is required");
34
+ }
35
+
36
+ // Check if it's a Firebase Auth instance (has currentUser property)
37
+ if ("currentUser" in providerOrAuth) {
38
+ // Import FirebaseAuthProvider directly
39
+ const { FirebaseAuthProvider } = require("../providers/FirebaseAuthProvider");
40
+ const firebaseProvider = new FirebaseAuthProvider(providerOrAuth);
41
+ await firebaseProvider.initialize();
42
+ this.provider = firebaseProvider;
43
+ } else {
44
+ this.provider = providerOrAuth as IAuthProvider;
45
+ await this.provider.initialize();
46
+ }
47
+ }
48
+
49
+ isInitialized(): boolean {
50
+ return this.provider !== null && this.provider.isInitialized();
51
+ }
52
+
53
+ private getProvider(): IAuthProvider {
54
+ if (!this.provider || !this.provider.isInitialized()) {
55
+ throw new AuthInitializationError("Auth service is not initialized");
56
+ }
57
+ return this.provider;
58
+ }
59
+
60
+ async signUp(params: SignUpParams): Promise<AuthUser> {
61
+ const provider = this.getProvider();
62
+
63
+ // Validate email
64
+ const emailResult = validateEmail(params.email);
65
+ if (!emailResult.isValid) {
66
+ throw new AuthInvalidEmailError(emailResult.error);
67
+ }
68
+
69
+ // Validate display name if provided
70
+ if (params.displayName) {
71
+ const nameResult = validateDisplayName(params.displayName);
72
+ if (!nameResult.isValid) {
73
+ throw new AuthValidationError(nameResult.error || "Invalid name", "displayName");
74
+ }
75
+ }
76
+
77
+ // Validate password strength for registration
78
+ const passwordResult = validatePasswordForRegister(params.password, this.config.password);
79
+ if (!passwordResult.isValid) {
80
+ throw new AuthWeakPasswordError(passwordResult.error);
81
+ }
82
+
83
+ return provider.signUp({
84
+ email: params.email,
85
+ password: params.password,
86
+ displayName: params.displayName,
87
+ });
88
+ }
89
+
90
+ async signIn(params: SignInParams): Promise<AuthUser> {
91
+ const provider = this.getProvider();
92
+
93
+ // Validate email format
94
+ const emailResult = validateEmail(params.email);
95
+ if (!emailResult.isValid) {
96
+ throw new AuthInvalidEmailError(emailResult.error);
97
+ }
98
+
99
+ // For login, only check if password is provided (no strength requirements)
100
+ const passwordResult = validatePasswordForLogin(params.password);
101
+ if (!passwordResult.isValid) {
102
+ throw new AuthValidationError(passwordResult.error || "Password is required", "password");
103
+ }
104
+
105
+ return provider.signIn({
106
+ email: params.email,
107
+ password: params.password,
108
+ });
109
+ }
110
+
111
+ async signOut(): Promise<void> {
112
+ if (!this.provider) {
113
+ return;
114
+ }
115
+
116
+ await this.provider.signOut();
117
+ }
118
+
119
+ getCurrentUser(): AuthUser | null {
120
+ if (!this.provider) {
121
+ return null;
122
+ }
123
+ return this.provider.getCurrentUser();
124
+ }
125
+
126
+ onAuthStateChange(callback: (user: AuthUser | null) => void): () => void {
127
+ if (!this.provider) {
128
+ callback(null);
129
+ return () => {};
130
+ }
131
+
132
+ return this.provider.onAuthStateChange(callback);
133
+ }
134
+
135
+ getConfig(): AuthConfig {
136
+ return this.config;
137
+ }
138
+ }
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Auth Event Service
3
+ * Handles authentication event emission and management
4
+ */
5
+
6
+ import { DeviceEventEmitter } from "react-native";
7
+
8
+ export interface AuthEventPayload {
9
+ userId?: string;
10
+ error?: string;
11
+ timestamp: number;
12
+ }
13
+
14
+ export interface AuthEventListener {
15
+ (payload: AuthEventPayload): void;
16
+ }
17
+
18
+ export class AuthEventService {
19
+ private static instance: AuthEventService;
20
+ private listeners: Map<string, AuthEventListener[]> = new Map();
21
+
22
+ private constructor() {}
23
+
24
+ static getInstance(): AuthEventService {
25
+ if (!AuthEventService.instance) {
26
+ AuthEventService.instance = new AuthEventService();
27
+ }
28
+ return AuthEventService.instance;
29
+ }
30
+
31
+ emitUserAuthenticated(userId: string): void {
32
+ const payload: AuthEventPayload = {
33
+ userId,
34
+ timestamp: Date.now(),
35
+ };
36
+
37
+ DeviceEventEmitter.emit("user-authenticated", payload);
38
+ this.notifyListeners("user-authenticated", payload);
39
+ }
40
+
41
+ emitGuestModeEnabled(): void {
42
+ const payload: AuthEventPayload = {
43
+ timestamp: Date.now(),
44
+ };
45
+
46
+ DeviceEventEmitter.emit("guest-mode-enabled", payload);
47
+ this.notifyListeners("guest-mode-enabled", payload);
48
+ }
49
+
50
+ emitAuthError(error: string): void {
51
+ const payload: AuthEventPayload = {
52
+ error,
53
+ timestamp: Date.now(),
54
+ };
55
+
56
+ DeviceEventEmitter.emit("auth-error", payload);
57
+ this.notifyListeners("auth-error", payload);
58
+ }
59
+
60
+ addEventListener(event: string, listener: AuthEventListener): () => void {
61
+ if (!this.listeners.has(event)) {
62
+ this.listeners.set(event, []);
63
+ }
64
+
65
+ const eventListeners = this.listeners.get(event)!;
66
+ eventListeners.push(listener);
67
+
68
+ // Return cleanup function
69
+ return () => {
70
+ const index = eventListeners.indexOf(listener);
71
+ if (index > -1) {
72
+ eventListeners.splice(index, 1);
73
+ }
74
+ };
75
+ }
76
+
77
+ removeAllListeners(event?: string): void {
78
+ if (event) {
79
+ this.listeners.delete(event);
80
+ } else {
81
+ this.listeners.clear();
82
+ }
83
+ }
84
+
85
+ private notifyListeners(event: string, payload: AuthEventPayload): void {
86
+ const eventListeners = this.listeners.get(event);
87
+ if (eventListeners) {
88
+ eventListeners.forEach(listener => {
89
+ try {
90
+ listener(payload);
91
+ } catch (error) {
92
+ if (__DEV__) {
93
+ console.error(`Error in auth event listener for ${event}:`, error);
94
+ }
95
+ }
96
+ });
97
+ }
98
+ }
99
+ }
100
+
101
+ // Export singleton instance for backward compatibility
102
+ export const authEventService = AuthEventService.getInstance();
103
+
104
+ // Legacy functions for backward compatibility
105
+ export function emitUserAuthenticated(userId: string): void {
106
+ authEventService.emitUserAuthenticated(userId);
107
+ }
108
+
109
+ export function emitGuestModeEnabled(): void {
110
+ authEventService.emitGuestModeEnabled();
111
+ }
112
+
113
+ export function emitAuthError(error: string): void {
114
+ authEventService.emitAuthError(error);
115
+ }
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Auth Package Configuration
3
+ * Centralized configuration for the auth package
4
+ */
5
+
6
+ import type { AuthConfig, PasswordConfig } from "../../domain/value-objects/AuthConfig";
7
+
8
+ export interface AuthPackageConfig {
9
+ storageKeys: {
10
+ guestMode: string;
11
+ showRegister: string;
12
+ };
13
+ validation: {
14
+ emailRegex: RegExp;
15
+ passwordConfig: PasswordConfig;
16
+ };
17
+ ui: {
18
+ theme?: any;
19
+ localization?: any;
20
+ };
21
+ features: {
22
+ guestMode: boolean;
23
+ registration: boolean;
24
+ passwordStrength: boolean;
25
+ };
26
+ }
27
+
28
+ export const DEFAULT_AUTH_PACKAGE_CONFIG: AuthPackageConfig = {
29
+ storageKeys: {
30
+ guestMode: "@auth_guest_mode",
31
+ showRegister: "auth_show_register",
32
+ },
33
+ validation: {
34
+ emailRegex: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
35
+ passwordConfig: {
36
+ minLength: 8,
37
+ requireUppercase: true,
38
+ requireLowercase: true,
39
+ requireNumber: true,
40
+ requireSpecialChar: false,
41
+ },
42
+ },
43
+ ui: {
44
+ theme: undefined,
45
+ localization: undefined,
46
+ },
47
+ features: {
48
+ guestMode: true,
49
+ registration: true,
50
+ passwordStrength: true,
51
+ },
52
+ };
53
+
54
+ export interface IStorageProvider {
55
+ get(key: string): Promise<string | null>;
56
+ set(key: string, value: string): Promise<void>;
57
+ remove(key: string): Promise<void>;
58
+ }
59
+
60
+ export interface IUIProvider {
61
+ getTheme(): any;
62
+ getLocalization(): any;
63
+ }
64
+
65
+ export interface IValidationProvider {
66
+ validateEmail(email: string): { isValid: boolean; error?: string };
67
+ validatePassword(password: string, config: PasswordConfig): { isValid: boolean; error?: string };
68
+ }
69
+
70
+ export class AuthPackage {
71
+ private config: AuthPackageConfig;
72
+ private storageProvider?: IStorageProvider;
73
+ private uiProvider?: IUIProvider;
74
+ private validationProvider?: IValidationProvider;
75
+
76
+ constructor(config: Partial<AuthPackageConfig> = {}) {
77
+ this.config = {
78
+ ...DEFAULT_AUTH_PACKAGE_CONFIG,
79
+ ...config,
80
+ validation: {
81
+ ...DEFAULT_AUTH_PACKAGE_CONFIG.validation,
82
+ ...config.validation,
83
+ passwordConfig: {
84
+ ...DEFAULT_AUTH_PACKAGE_CONFIG.validation.passwordConfig,
85
+ ...config.validation?.passwordConfig,
86
+ },
87
+ },
88
+ ui: {
89
+ ...DEFAULT_AUTH_PACKAGE_CONFIG.ui,
90
+ ...config.ui,
91
+ },
92
+ features: {
93
+ ...DEFAULT_AUTH_PACKAGE_CONFIG.features,
94
+ ...config.features,
95
+ },
96
+ };
97
+ }
98
+
99
+ setStorageProvider(provider: IStorageProvider): void {
100
+ this.storageProvider = provider;
101
+ }
102
+
103
+ setUIProvider(provider: IUIProvider): void {
104
+ this.uiProvider = provider;
105
+ }
106
+
107
+ setValidationProvider(provider: IValidationProvider): void {
108
+ this.validationProvider = provider;
109
+ }
110
+
111
+ getConfig(): AuthPackageConfig {
112
+ return this.config;
113
+ }
114
+
115
+ getStorageProvider(): IStorageProvider | undefined {
116
+ return this.storageProvider;
117
+ }
118
+
119
+ getUIProvider(): IUIProvider | undefined {
120
+ return this.uiProvider;
121
+ }
122
+
123
+ getValidationProvider(): IValidationProvider | undefined {
124
+ return this.validationProvider;
125
+ }
126
+
127
+ isFeatureEnabled(feature: keyof AuthPackageConfig['features']): boolean {
128
+ return this.config.features[feature];
129
+ }
130
+ }
131
+
132
+ // Global package instance
133
+ let packageInstance: AuthPackage | null = null;
134
+
135
+ export function initializeAuthPackage(config: Partial<AuthPackageConfig> = {}): AuthPackage {
136
+ if (!packageInstance) {
137
+ packageInstance = new AuthPackage(config);
138
+ }
139
+ return packageInstance;
140
+ }
141
+
142
+ export function getAuthPackage(): AuthPackage | null {
143
+ return packageInstance;
144
+ }
145
+
146
+ export function resetAuthPackage(): void {
147
+ packageInstance = null;
148
+ }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auth Service
3
- * Provider-agnostic authentication orchestrator
3
+ * Orchestrates authentication operations using composition
4
4
  */
5
5
 
6
6
  import type { Auth } from "firebase/auth";
@@ -9,29 +9,19 @@ import type { IAuthProvider } from "../../application/ports/IAuthProvider";
9
9
  import type { AuthUser } from "../../domain/entities/AuthUser";
10
10
  import type { AuthConfig } from "../../domain/value-objects/AuthConfig";
11
11
  import { DEFAULT_AUTH_CONFIG } from "../../domain/value-objects/AuthConfig";
12
- import {
13
- AuthInitializationError,
14
- AuthValidationError,
15
- AuthWeakPasswordError,
16
- AuthInvalidEmailError,
17
- } from "../../domain/errors/AuthError";
18
- import {
19
- validateEmail,
20
- validatePasswordForLogin,
21
- validatePasswordForRegister,
22
- validateDisplayName,
23
- } from "../utils/AuthValidation";
24
- import { FirebaseAuthProvider } from "../providers/FirebaseAuthProvider";
25
- import { emitUserAuthenticated, emitGuestModeEnabled } from "../utils/AuthEventEmitter";
26
- import { loadGuestMode, saveGuestMode, clearGuestMode } from "../storage/GuestModeStorage";
12
+ import { AuthCoreService } from "./AuthCoreService";
13
+ import { GuestModeService, type IStorageProvider } from "./GuestModeService";
14
+ import { authEventService } from "./AuthEventService";
15
+ import { initializeAuthPackage, getAuthPackage } from "./AuthPackage";
27
16
 
28
17
  export class AuthService implements IAuthService {
29
- private provider: IAuthProvider | null = null;
30
- private config: AuthConfig;
31
- private isGuestMode: boolean = false;
18
+ private coreService: AuthCoreService;
19
+ private guestModeService: GuestModeService;
20
+ private storageProvider?: IStorageProvider;
21
+ private initialized: boolean = false;
32
22
 
33
- constructor(config: Partial<AuthConfig> = {}) {
34
- this.config = {
23
+ constructor(config: Partial<AuthConfig> = {}, storageProvider?: IStorageProvider) {
24
+ const authConfig = {
35
25
  ...DEFAULT_AUTH_CONFIG,
36
26
  ...config,
37
27
  password: {
@@ -39,160 +29,101 @@ export class AuthService implements IAuthService {
39
29
  ...config.password,
40
30
  },
41
31
  };
32
+
33
+ this.coreService = new AuthCoreService(authConfig);
34
+ this.guestModeService = new GuestModeService();
35
+ this.storageProvider = storageProvider;
42
36
  }
43
37
 
44
38
  async initialize(providerOrAuth: IAuthProvider | Auth): Promise<void> {
45
- if (!providerOrAuth) {
46
- throw new AuthInitializationError("Auth provider or Firebase Auth instance is required");
39
+ if (this.initialized) {
40
+ return;
47
41
  }
48
42
 
49
- // Check if it's a Firebase Auth instance (has currentUser property)
50
- if ("currentUser" in providerOrAuth) {
51
- const firebaseProvider = new FirebaseAuthProvider(providerOrAuth as Auth);
52
- await firebaseProvider.initialize();
53
- this.provider = firebaseProvider;
54
- } else {
55
- this.provider = providerOrAuth as IAuthProvider;
56
- await this.provider.initialize();
43
+ // Initialize core service
44
+ await this.coreService.initialize(providerOrAuth);
45
+
46
+ // Initialize guest mode if storage provider is available
47
+ if (this.storageProvider) {
48
+ await this.guestModeService.load(this.storageProvider);
57
49
  }
58
50
 
59
- this.isGuestMode = await loadGuestMode();
51
+ this.initialized = true;
60
52
  }
61
53
 
62
54
  isInitialized(): boolean {
63
- return this.provider !== null && this.provider.isInitialized();
64
- }
65
-
66
- private getProvider(): IAuthProvider {
67
- if (!this.provider || !this.provider.isInitialized()) {
68
- throw new AuthInitializationError("Auth service is not initialized");
69
- }
70
- return this.provider;
55
+ return this.initialized && this.coreService.isInitialized();
71
56
  }
72
57
 
73
58
  async signUp(params: SignUpParams): Promise<AuthUser> {
74
- const provider = this.getProvider();
75
-
76
- // Validate email
77
- const emailResult = validateEmail(params.email);
78
- if (!emailResult.isValid) {
79
- throw new AuthInvalidEmailError(emailResult.error);
80
- }
81
-
82
- // Validate display name if provided
83
- if (params.displayName) {
84
- const nameResult = validateDisplayName(params.displayName);
85
- if (!nameResult.isValid) {
86
- throw new AuthValidationError(nameResult.error || "Invalid name", "displayName");
87
- }
88
- }
89
-
90
- // Validate password strength for registration
91
- const passwordResult = validatePasswordForRegister(params.password, this.config.password);
92
- if (!passwordResult.isValid) {
93
- throw new AuthWeakPasswordError(passwordResult.error);
94
- }
95
-
96
- const user = await provider.signUp({
97
- email: params.email,
98
- password: params.password,
99
- displayName: params.displayName,
100
- });
59
+ const user = await this.coreService.signUp(params);
101
60
 
102
61
  // Clear guest mode when user signs up
103
- if (this.isGuestMode) {
104
- this.isGuestMode = false;
105
- await clearGuestMode();
62
+ if (this.guestModeService.getIsGuestMode() && this.storageProvider) {
63
+ await this.guestModeService.clear(this.storageProvider);
106
64
  }
107
65
 
108
- emitUserAuthenticated(user.uid);
66
+ authEventService.emitUserAuthenticated(user.uid);
109
67
  return user;
110
68
  }
111
69
 
112
70
  async signIn(params: SignInParams): Promise<AuthUser> {
113
- const provider = this.getProvider();
114
-
115
- // Validate email format
116
- const emailResult = validateEmail(params.email);
117
- if (!emailResult.isValid) {
118
- throw new AuthInvalidEmailError(emailResult.error);
119
- }
120
-
121
- // For login, only check if password is provided (no strength requirements)
122
- const passwordResult = validatePasswordForLogin(params.password);
123
- if (!passwordResult.isValid) {
124
- throw new AuthValidationError(passwordResult.error || "Password is required", "password");
125
- }
126
-
127
- const user = await provider.signIn({
128
- email: params.email,
129
- password: params.password,
130
- });
71
+ const user = await this.coreService.signIn(params);
131
72
 
132
73
  // Clear guest mode when user signs in
133
- if (this.isGuestMode) {
134
- this.isGuestMode = false;
135
- await clearGuestMode();
74
+ if (this.guestModeService.getIsGuestMode() && this.storageProvider) {
75
+ await this.guestModeService.clear(this.storageProvider);
136
76
  }
137
77
 
138
- emitUserAuthenticated(user.uid);
78
+ authEventService.emitUserAuthenticated(user.uid);
139
79
  return user;
140
80
  }
141
81
 
142
82
  async signOut(): Promise<void> {
143
- if (!this.provider) {
144
- this.isGuestMode = false;
145
- await clearGuestMode();
146
- return;
147
- }
83
+ await this.coreService.signOut();
148
84
 
149
- await this.provider.signOut();
85
+ // Clear guest mode if signing out explicitly
86
+ if (this.guestModeService.getIsGuestMode() && this.storageProvider) {
87
+ await this.guestModeService.clear(this.storageProvider);
88
+ }
150
89
  }
151
90
 
152
91
  async setGuestMode(): Promise<void> {
153
- // Sign out from provider if logged in
154
- if (this.provider?.getCurrentUser()) {
155
- try {
156
- await this.provider.signOut();
157
- } catch {
158
- // Ignore sign out errors when switching to guest mode
159
- }
92
+ if (!this.storageProvider) {
93
+ throw new Error("Storage provider is required for guest mode");
160
94
  }
161
95
 
162
- this.isGuestMode = true;
163
- await saveGuestMode(true);
164
- emitGuestModeEnabled();
96
+ // No provider needed for guest mode enablement
97
+
98
+ await this.guestModeService.enable(this.storageProvider);
165
99
  }
166
100
 
167
101
  getCurrentUser(): AuthUser | null {
168
- if (!this.provider) {
102
+ if (this.guestModeService.getIsGuestMode()) {
169
103
  return null;
170
104
  }
171
- return this.provider.getCurrentUser();
105
+ return this.coreService.getCurrentUser();
172
106
  }
173
107
 
174
108
  getIsGuestMode(): boolean {
175
- return this.isGuestMode;
109
+ return this.guestModeService.getIsGuestMode();
176
110
  }
177
111
 
178
112
  onAuthStateChange(callback: (user: AuthUser | null) => void): () => void {
179
- if (!this.provider) {
180
- callback(null);
181
- return () => {};
182
- }
183
-
184
- return this.provider.onAuthStateChange((user) => {
185
- // Don't update if in guest mode
186
- if (!this.isGuestMode) {
187
- callback(user);
188
- } else {
189
- callback(null);
190
- }
191
- });
113
+ const wrappedCallback = this.guestModeService.wrapAuthStateCallback(callback);
114
+ return this.coreService.onAuthStateChange(wrappedCallback);
192
115
  }
193
116
 
194
117
  getConfig(): AuthConfig {
195
- return this.config;
118
+ return this.coreService.getConfig();
119
+ }
120
+
121
+ getCoreService(): AuthCoreService {
122
+ return this.coreService;
123
+ }
124
+
125
+ getGuestModeService(): GuestModeService {
126
+ return this.guestModeService;
196
127
  }
197
128
  }
198
129
 
@@ -204,10 +135,13 @@ let authServiceInstance: AuthService | null = null;
204
135
  */
205
136
  export async function initializeAuthService(
206
137
  providerOrAuth: IAuthProvider | Auth,
207
- config?: Partial<AuthConfig>
138
+ config?: Partial<AuthConfig>,
139
+ storageProvider?: IStorageProvider
208
140
  ): Promise<AuthService> {
209
141
  if (!authServiceInstance) {
210
- authServiceInstance = new AuthService(config);
142
+ // Initialize package if not already done
143
+ const packageConfig = getAuthPackage()?.getConfig();
144
+ authServiceInstance = new AuthService(config, storageProvider);
211
145
  }
212
146
  await authServiceInstance.initialize(providerOrAuth);
213
147
  return authServiceInstance;