@umituz/react-native-auth 1.12.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 +0 -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 +2 -2
- package/src/presentation/components/PasswordStrengthIndicator.tsx +0 -0
- package/src/presentation/components/RegisterForm.tsx +0 -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 +16 -17
- 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,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AuthValidation Tests
|
|
3
|
+
*/
|
|
4
|
+
import { validateEmail, validatePasswordForLogin, validatePasswordForRegister, validatePasswordConfirmation, validateDisplayName, } from '../../../src/infrastructure/utils/AuthValidation';
|
|
5
|
+
import { DEFAULT_PASSWORD_CONFIG } from '../../../src/domain/value-objects/AuthConfig';
|
|
6
|
+
import { initializeAuthPackage } from '../../../src/infrastructure/services/AuthPackage';
|
|
7
|
+
describe('AuthValidation', () => {
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
// Reset package config before each test
|
|
10
|
+
initializeAuthPackage();
|
|
11
|
+
});
|
|
12
|
+
describe('validateEmail', () => {
|
|
13
|
+
it('should reject empty email', () => {
|
|
14
|
+
const result = validateEmail('');
|
|
15
|
+
expect(result.isValid).toBe(false);
|
|
16
|
+
expect(result.error).toBe('Email is required');
|
|
17
|
+
});
|
|
18
|
+
it('should reject whitespace-only email', () => {
|
|
19
|
+
const result = validateEmail(' ');
|
|
20
|
+
expect(result.isValid).toBe(false);
|
|
21
|
+
expect(result.error).toBe('Email is required');
|
|
22
|
+
});
|
|
23
|
+
it('should reject invalid email format', () => {
|
|
24
|
+
const result = validateEmail('invalid-email');
|
|
25
|
+
expect(result.isValid).toBe(false);
|
|
26
|
+
expect(result.error).toBe('Please enter a valid email address');
|
|
27
|
+
});
|
|
28
|
+
it('should accept valid email format', () => {
|
|
29
|
+
const result = validateEmail('test@example.com');
|
|
30
|
+
expect(result.isValid).toBe(true);
|
|
31
|
+
expect(result.error).toBeUndefined();
|
|
32
|
+
});
|
|
33
|
+
it('should accept valid email with subdomain', () => {
|
|
34
|
+
const result = validateEmail('test@mail.example.com');
|
|
35
|
+
expect(result.isValid).toBe(true);
|
|
36
|
+
expect(result.error).toBeUndefined();
|
|
37
|
+
});
|
|
38
|
+
it('should trim whitespace', () => {
|
|
39
|
+
const result = validateEmail(' test@example.com ');
|
|
40
|
+
expect(result.isValid).toBe(true);
|
|
41
|
+
expect(result.error).toBeUndefined();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe('validatePasswordForLogin', () => {
|
|
45
|
+
it('should reject empty password', () => {
|
|
46
|
+
const result = validatePasswordForLogin('');
|
|
47
|
+
expect(result.isValid).toBe(false);
|
|
48
|
+
expect(result.error).toBe('Password is required');
|
|
49
|
+
});
|
|
50
|
+
it('should accept any non-empty password', () => {
|
|
51
|
+
const result = validatePasswordForLogin('any');
|
|
52
|
+
expect(result.isValid).toBe(true);
|
|
53
|
+
expect(result.error).toBeUndefined();
|
|
54
|
+
});
|
|
55
|
+
it('should accept password with spaces', () => {
|
|
56
|
+
const result = validatePasswordForLogin(' password ');
|
|
57
|
+
expect(result.isValid).toBe(true);
|
|
58
|
+
expect(result.error).toBeUndefined();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe('validatePasswordForRegister', () => {
|
|
62
|
+
const config = DEFAULT_PASSWORD_CONFIG;
|
|
63
|
+
it('should reject empty password', () => {
|
|
64
|
+
const result = validatePasswordForRegister('', config);
|
|
65
|
+
expect(result.isValid).toBe(false);
|
|
66
|
+
expect(result.error).toBe('Password is required');
|
|
67
|
+
expect(result.requirements.hasMinLength).toBe(false);
|
|
68
|
+
});
|
|
69
|
+
it('should reject password that is too short', () => {
|
|
70
|
+
const result = validatePasswordForRegister('123', config);
|
|
71
|
+
expect(result.isValid).toBe(false);
|
|
72
|
+
expect(result.error).toBe(`Password must be at least ${config.minLength} characters`);
|
|
73
|
+
expect(result.requirements.hasMinLength).toBe(false);
|
|
74
|
+
});
|
|
75
|
+
it('should accept password that meets minimum length', () => {
|
|
76
|
+
const result = validatePasswordForRegister('12345678', config);
|
|
77
|
+
expect(result.requirements.hasMinLength).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
it('should validate uppercase requirement', () => {
|
|
80
|
+
const configWithUppercase = {
|
|
81
|
+
...config,
|
|
82
|
+
requireUppercase: true,
|
|
83
|
+
};
|
|
84
|
+
const result = validatePasswordForRegister('password', configWithUppercase);
|
|
85
|
+
expect(result.isValid).toBe(false);
|
|
86
|
+
expect(result.error).toBe('Password must contain at least one uppercase letter');
|
|
87
|
+
expect(result.requirements.hasUppercase).toBe(false);
|
|
88
|
+
const validResult = validatePasswordForRegister('Password', configWithUppercase);
|
|
89
|
+
expect(validResult.requirements.hasUppercase).toBe(true);
|
|
90
|
+
});
|
|
91
|
+
it('should validate lowercase requirement', () => {
|
|
92
|
+
const configWithLowercase = {
|
|
93
|
+
...config,
|
|
94
|
+
requireLowercase: true,
|
|
95
|
+
};
|
|
96
|
+
const result = validatePasswordForRegister('PASSWORD', configWithLowercase);
|
|
97
|
+
expect(result.isValid).toBe(false);
|
|
98
|
+
expect(result.error).toBe('Password must contain at least one lowercase letter');
|
|
99
|
+
expect(result.requirements.hasLowercase).toBe(false);
|
|
100
|
+
const validResult = validatePasswordForRegister('Password', configWithLowercase);
|
|
101
|
+
expect(validResult.requirements.hasLowercase).toBe(true);
|
|
102
|
+
});
|
|
103
|
+
it('should validate number requirement', () => {
|
|
104
|
+
const configWithNumber = {
|
|
105
|
+
...config,
|
|
106
|
+
requireNumber: true,
|
|
107
|
+
};
|
|
108
|
+
const result = validatePasswordForRegister('Password', configWithNumber);
|
|
109
|
+
expect(result.isValid).toBe(false);
|
|
110
|
+
expect(result.error).toBe('Password must contain at least one number');
|
|
111
|
+
expect(result.requirements.hasNumber).toBe(false);
|
|
112
|
+
const validResult = validatePasswordForRegister('Password1', configWithNumber);
|
|
113
|
+
expect(validResult.requirements.hasNumber).toBe(true);
|
|
114
|
+
});
|
|
115
|
+
it('should validate special character requirement', () => {
|
|
116
|
+
const configWithSpecial = {
|
|
117
|
+
...config,
|
|
118
|
+
requireSpecialChar: true,
|
|
119
|
+
};
|
|
120
|
+
const result = validatePasswordForRegister('Password1', configWithSpecial);
|
|
121
|
+
expect(result.isValid).toBe(false);
|
|
122
|
+
expect(result.error).toBe('Password must contain at least one special character');
|
|
123
|
+
expect(result.requirements.hasSpecialChar).toBe(false);
|
|
124
|
+
const validResult = validatePasswordForRegister('Password1!', configWithSpecial);
|
|
125
|
+
expect(validResult.requirements.hasSpecialChar).toBe(true);
|
|
126
|
+
});
|
|
127
|
+
it('should accept password that meets all requirements', () => {
|
|
128
|
+
const strictConfig = {
|
|
129
|
+
...config,
|
|
130
|
+
requireUppercase: true,
|
|
131
|
+
requireLowercase: true,
|
|
132
|
+
requireNumber: true,
|
|
133
|
+
requireSpecialChar: true,
|
|
134
|
+
};
|
|
135
|
+
const result = validatePasswordForRegister('Password1!', strictConfig);
|
|
136
|
+
expect(result.isValid).toBe(true);
|
|
137
|
+
expect(result.requirements).toEqual({
|
|
138
|
+
hasMinLength: true,
|
|
139
|
+
hasUppercase: true,
|
|
140
|
+
hasLowercase: true,
|
|
141
|
+
hasNumber: true,
|
|
142
|
+
hasSpecialChar: true,
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
it('should skip requirements when disabled', () => {
|
|
146
|
+
const lenientConfig = {
|
|
147
|
+
...config,
|
|
148
|
+
requireUppercase: false,
|
|
149
|
+
requireLowercase: false,
|
|
150
|
+
requireNumber: false,
|
|
151
|
+
requireSpecialChar: false,
|
|
152
|
+
};
|
|
153
|
+
const result = validatePasswordForRegister('password', lenientConfig);
|
|
154
|
+
expect(result.requirements).toEqual({
|
|
155
|
+
hasMinLength: true,
|
|
156
|
+
hasUppercase: true, // Should be true when requirement is disabled
|
|
157
|
+
hasLowercase: true, // Should be true when requirement is disabled
|
|
158
|
+
hasNumber: true, // Should be true when requirement is disabled
|
|
159
|
+
hasSpecialChar: true, // Should be true when requirement is disabled
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
describe('validatePasswordConfirmation', () => {
|
|
164
|
+
it('should reject empty confirmation', () => {
|
|
165
|
+
const result = validatePasswordConfirmation('password', '');
|
|
166
|
+
expect(result.isValid).toBe(false);
|
|
167
|
+
expect(result.error).toBe('Please confirm your password');
|
|
168
|
+
});
|
|
169
|
+
it('should reject mismatched passwords', () => {
|
|
170
|
+
const result = validatePasswordConfirmation('password', 'different');
|
|
171
|
+
expect(result.isValid).toBe(false);
|
|
172
|
+
expect(result.error).toBe('Passwords do not match');
|
|
173
|
+
});
|
|
174
|
+
it('should accept matching passwords', () => {
|
|
175
|
+
const result = validatePasswordConfirmation('password', 'password');
|
|
176
|
+
expect(result.isValid).toBe(true);
|
|
177
|
+
expect(result.error).toBeUndefined();
|
|
178
|
+
});
|
|
179
|
+
it('should handle empty passwords that match', () => {
|
|
180
|
+
const result = validatePasswordConfirmation('', '');
|
|
181
|
+
expect(result.isValid).toBe(true);
|
|
182
|
+
expect(result.error).toBeUndefined();
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
describe('validateDisplayName', () => {
|
|
186
|
+
it('should reject empty name', () => {
|
|
187
|
+
const result = validateDisplayName('');
|
|
188
|
+
expect(result.isValid).toBe(false);
|
|
189
|
+
expect(result.error).toBe('Name is required');
|
|
190
|
+
});
|
|
191
|
+
it('should reject whitespace-only name', () => {
|
|
192
|
+
const result = validateDisplayName(' ');
|
|
193
|
+
expect(result.isValid).toBe(false);
|
|
194
|
+
expect(result.error).toBe('Name is required');
|
|
195
|
+
});
|
|
196
|
+
it('should reject name that is too short', () => {
|
|
197
|
+
const result = validateDisplayName('A');
|
|
198
|
+
expect(result.isValid).toBe(false);
|
|
199
|
+
expect(result.error).toBe('Name must be at least 2 characters');
|
|
200
|
+
});
|
|
201
|
+
it('should accept name that meets minimum length', () => {
|
|
202
|
+
const result = validateDisplayName('Al');
|
|
203
|
+
expect(result.isValid).toBe(true);
|
|
204
|
+
expect(result.error).toBeUndefined();
|
|
205
|
+
});
|
|
206
|
+
it('should use custom minimum length', () => {
|
|
207
|
+
const result = validateDisplayName('Al', 3);
|
|
208
|
+
expect(result.isValid).toBe(false);
|
|
209
|
+
expect(result.error).toBe('Name must be at least 3 characters');
|
|
210
|
+
});
|
|
211
|
+
it('should trim whitespace', () => {
|
|
212
|
+
const result = validateDisplayName(' John Doe ');
|
|
213
|
+
expect(result.isValid).toBe(true);
|
|
214
|
+
expect(result.error).toBeUndefined();
|
|
215
|
+
});
|
|
216
|
+
it('should accept name with special characters', () => {
|
|
217
|
+
const result = validateDisplayName('John-O\'Connor');
|
|
218
|
+
expect(result.isValid).toBe(true);
|
|
219
|
+
expect(result.error).toBeUndefined();
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Provider Interface
|
|
3
|
+
* Port for provider-agnostic authentication (Firebase, Supabase, etc.)
|
|
4
|
+
*/
|
|
5
|
+
import type { AuthUser } from "../../domain/entities/AuthUser";
|
|
6
|
+
export interface AuthCredentials {
|
|
7
|
+
email: string;
|
|
8
|
+
password: string;
|
|
9
|
+
}
|
|
10
|
+
export interface SignUpCredentials extends AuthCredentials {
|
|
11
|
+
displayName?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface IAuthProvider {
|
|
14
|
+
/**
|
|
15
|
+
* Initialize the auth provider
|
|
16
|
+
*/
|
|
17
|
+
initialize(): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Check if provider is initialized
|
|
20
|
+
*/
|
|
21
|
+
isInitialized(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Sign in with email and password
|
|
24
|
+
*/
|
|
25
|
+
signIn(credentials: AuthCredentials): Promise<AuthUser>;
|
|
26
|
+
/**
|
|
27
|
+
* Sign up with email, password, and optional display name
|
|
28
|
+
*/
|
|
29
|
+
signUp(credentials: SignUpCredentials): Promise<AuthUser>;
|
|
30
|
+
/**
|
|
31
|
+
* Sign out current user
|
|
32
|
+
*/
|
|
33
|
+
signOut(): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Get current authenticated user
|
|
36
|
+
*/
|
|
37
|
+
getCurrentUser(): AuthUser | null;
|
|
38
|
+
/**
|
|
39
|
+
* Subscribe to auth state changes
|
|
40
|
+
*/
|
|
41
|
+
onAuthStateChange(callback: (user: AuthUser | null) => void): () => void;
|
|
42
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Service Interface
|
|
3
|
+
* Port for authentication operations (provider-agnostic)
|
|
4
|
+
*/
|
|
5
|
+
import type { AuthUser } from "../../domain/entities/AuthUser";
|
|
6
|
+
export interface SignUpParams {
|
|
7
|
+
email: string;
|
|
8
|
+
password: string;
|
|
9
|
+
displayName?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface SignInParams {
|
|
12
|
+
email: string;
|
|
13
|
+
password: string;
|
|
14
|
+
}
|
|
15
|
+
export interface IAuthService {
|
|
16
|
+
/**
|
|
17
|
+
* Sign up a new user
|
|
18
|
+
*/
|
|
19
|
+
signUp(params: SignUpParams): Promise<AuthUser>;
|
|
20
|
+
/**
|
|
21
|
+
* Sign in an existing user
|
|
22
|
+
*/
|
|
23
|
+
signIn(params: SignInParams): Promise<AuthUser>;
|
|
24
|
+
/**
|
|
25
|
+
* Sign out current user
|
|
26
|
+
*/
|
|
27
|
+
signOut(): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Set guest mode (no authentication)
|
|
30
|
+
*/
|
|
31
|
+
setGuestMode(): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Check if currently in guest mode
|
|
34
|
+
*/
|
|
35
|
+
getIsGuestMode(): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Get current authenticated user
|
|
38
|
+
*/
|
|
39
|
+
getCurrentUser(): AuthUser | null;
|
|
40
|
+
/**
|
|
41
|
+
* Subscribe to auth state changes
|
|
42
|
+
*/
|
|
43
|
+
onAuthStateChange(callback: (user: AuthUser | null) => void): () => void;
|
|
44
|
+
/**
|
|
45
|
+
* Check if auth is initialized
|
|
46
|
+
*/
|
|
47
|
+
isInitialized(): boolean;
|
|
48
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Error Types
|
|
3
|
+
* Domain-specific error classes for authentication operations
|
|
4
|
+
*/
|
|
5
|
+
export declare class AuthError extends Error {
|
|
6
|
+
code?: string | undefined;
|
|
7
|
+
constructor(message: string, code?: string | undefined);
|
|
8
|
+
}
|
|
9
|
+
export declare class AuthInitializationError extends AuthError {
|
|
10
|
+
constructor(message?: string);
|
|
11
|
+
}
|
|
12
|
+
export declare class AuthConfigurationError extends AuthError {
|
|
13
|
+
constructor(message?: string);
|
|
14
|
+
}
|
|
15
|
+
export declare class AuthValidationError extends AuthError {
|
|
16
|
+
field?: string | undefined;
|
|
17
|
+
constructor(message: string, field?: string | undefined);
|
|
18
|
+
}
|
|
19
|
+
export declare class AuthNetworkError extends AuthError {
|
|
20
|
+
constructor(message?: string);
|
|
21
|
+
}
|
|
22
|
+
export declare class AuthUserNotFoundError extends AuthError {
|
|
23
|
+
constructor(message?: string);
|
|
24
|
+
}
|
|
25
|
+
export declare class AuthWrongPasswordError extends AuthError {
|
|
26
|
+
constructor(message?: string);
|
|
27
|
+
}
|
|
28
|
+
export declare class AuthEmailAlreadyInUseError extends AuthError {
|
|
29
|
+
constructor(message?: string);
|
|
30
|
+
}
|
|
31
|
+
export declare class AuthWeakPasswordError extends AuthError {
|
|
32
|
+
constructor(message?: string);
|
|
33
|
+
}
|
|
34
|
+
export declare class AuthInvalidEmailError extends AuthError {
|
|
35
|
+
constructor(message?: string);
|
|
36
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Error Types
|
|
3
|
+
* Domain-specific error classes for authentication operations
|
|
4
|
+
*/
|
|
5
|
+
export class AuthError extends Error {
|
|
6
|
+
constructor(message, code) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.name = "AuthError";
|
|
10
|
+
Object.setPrototypeOf(this, AuthError.prototype);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export class AuthInitializationError extends AuthError {
|
|
14
|
+
constructor(message = "Firebase Auth is not initialized") {
|
|
15
|
+
super(message, "AUTH_NOT_INITIALIZED");
|
|
16
|
+
this.name = "AuthInitializationError";
|
|
17
|
+
Object.setPrototypeOf(this, AuthInitializationError.prototype);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class AuthConfigurationError extends AuthError {
|
|
21
|
+
constructor(message = "Invalid auth configuration") {
|
|
22
|
+
super(message, "AUTH_CONFIG_ERROR");
|
|
23
|
+
this.name = "AuthConfigurationError";
|
|
24
|
+
Object.setPrototypeOf(this, AuthConfigurationError.prototype);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export class AuthValidationError extends AuthError {
|
|
28
|
+
constructor(message, field) {
|
|
29
|
+
super(message, "AUTH_VALIDATION_ERROR");
|
|
30
|
+
this.field = field;
|
|
31
|
+
this.name = "AuthValidationError";
|
|
32
|
+
Object.setPrototypeOf(this, AuthValidationError.prototype);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export class AuthNetworkError extends AuthError {
|
|
36
|
+
constructor(message = "Network error during authentication") {
|
|
37
|
+
super(message, "AUTH_NETWORK_ERROR");
|
|
38
|
+
this.name = "AuthNetworkError";
|
|
39
|
+
Object.setPrototypeOf(this, AuthNetworkError.prototype);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export class AuthUserNotFoundError extends AuthError {
|
|
43
|
+
constructor(message = "User not found") {
|
|
44
|
+
super(message, "AUTH_USER_NOT_FOUND");
|
|
45
|
+
this.name = "AuthUserNotFoundError";
|
|
46
|
+
Object.setPrototypeOf(this, AuthUserNotFoundError.prototype);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export class AuthWrongPasswordError extends AuthError {
|
|
50
|
+
constructor(message = "Wrong password") {
|
|
51
|
+
super(message, "AUTH_WRONG_PASSWORD");
|
|
52
|
+
this.name = "AuthWrongPasswordError";
|
|
53
|
+
Object.setPrototypeOf(this, AuthWrongPasswordError.prototype);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export class AuthEmailAlreadyInUseError extends AuthError {
|
|
57
|
+
constructor(message = "Email already in use") {
|
|
58
|
+
super(message, "AUTH_EMAIL_ALREADY_IN_USE");
|
|
59
|
+
this.name = "AuthEmailAlreadyInUseError";
|
|
60
|
+
Object.setPrototypeOf(this, AuthEmailAlreadyInUseError.prototype);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export class AuthWeakPasswordError extends AuthError {
|
|
64
|
+
constructor(message = "Password is too weak") {
|
|
65
|
+
super(message, "AUTH_WEAK_PASSWORD");
|
|
66
|
+
this.name = "AuthWeakPasswordError";
|
|
67
|
+
Object.setPrototypeOf(this, AuthWeakPasswordError.prototype);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export class AuthInvalidEmailError extends AuthError {
|
|
71
|
+
constructor(message = "Invalid email address") {
|
|
72
|
+
super(message, "AUTH_INVALID_EMAIL");
|
|
73
|
+
this.name = "AuthInvalidEmailError";
|
|
74
|
+
Object.setPrototypeOf(this, AuthInvalidEmailError.prototype);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Configuration Value Object
|
|
3
|
+
* Validates and stores authentication configuration
|
|
4
|
+
*/
|
|
5
|
+
export interface PasswordConfig {
|
|
6
|
+
minLength: number;
|
|
7
|
+
requireUppercase: boolean;
|
|
8
|
+
requireLowercase: boolean;
|
|
9
|
+
requireNumber: boolean;
|
|
10
|
+
requireSpecialChar: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface AuthConfig {
|
|
13
|
+
password: PasswordConfig;
|
|
14
|
+
}
|
|
15
|
+
export declare const DEFAULT_PASSWORD_CONFIG: PasswordConfig;
|
|
16
|
+
export declare const DEFAULT_AUTH_CONFIG: AuthConfig;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Configuration Value Object
|
|
3
|
+
* Validates and stores authentication configuration
|
|
4
|
+
*/
|
|
5
|
+
export const DEFAULT_PASSWORD_CONFIG = {
|
|
6
|
+
minLength: 6,
|
|
7
|
+
requireUppercase: false,
|
|
8
|
+
requireLowercase: false,
|
|
9
|
+
requireNumber: false,
|
|
10
|
+
requireSpecialChar: false,
|
|
11
|
+
};
|
|
12
|
+
export const DEFAULT_AUTH_CONFIG = {
|
|
13
|
+
password: DEFAULT_PASSWORD_CONFIG,
|
|
14
|
+
};
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native Auth - Public API
|
|
3
|
+
*
|
|
4
|
+
* Domain-Driven Design (DDD) Architecture
|
|
5
|
+
*
|
|
6
|
+
* This is the SINGLE SOURCE OF TRUTH for all Auth operations.
|
|
7
|
+
* ALL imports from the Auth package MUST go through this file.
|
|
8
|
+
*
|
|
9
|
+
* Architecture:
|
|
10
|
+
* - domain: Entities, value objects, errors (business logic)
|
|
11
|
+
* - application: Ports (interfaces)
|
|
12
|
+
* - infrastructure: Auth providers and service implementation
|
|
13
|
+
* - presentation: Hooks (React integration)
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* import { initializeAuthService, useAuth } from '@umituz/react-native-auth';
|
|
17
|
+
*/
|
|
18
|
+
export type { AuthUser } from './domain/entities/AuthUser';
|
|
19
|
+
export { AuthError, AuthInitializationError, AuthConfigurationError, AuthValidationError, AuthNetworkError, AuthUserNotFoundError, AuthWrongPasswordError, AuthEmailAlreadyInUseError, AuthWeakPasswordError, AuthInvalidEmailError, } from './domain/errors/AuthError';
|
|
20
|
+
export type { AuthConfig, PasswordConfig } from './domain/value-objects/AuthConfig';
|
|
21
|
+
export { DEFAULT_AUTH_CONFIG, DEFAULT_PASSWORD_CONFIG } from './domain/value-objects/AuthConfig';
|
|
22
|
+
export type { IAuthService, SignUpParams, SignInParams } from './application/ports/IAuthService';
|
|
23
|
+
export type { IAuthProvider, AuthCredentials, SignUpCredentials, } from './application/ports/IAuthProvider';
|
|
24
|
+
export { FirebaseAuthProvider } from './infrastructure/providers/FirebaseAuthProvider';
|
|
25
|
+
export { AuthService, initializeAuthService, getAuthService, resetAuthService, } from './infrastructure/services/AuthService';
|
|
26
|
+
export { validateEmail, validatePasswordForLogin, validatePasswordForRegister, validatePasswordConfirmation, validateDisplayName, } from './infrastructure/utils/AuthValidation';
|
|
27
|
+
export type { ValidationResult, PasswordStrengthResult, PasswordRequirements, } from './infrastructure/utils/AuthValidation';
|
|
28
|
+
export { useAuth } from './presentation/hooks/useAuth';
|
|
29
|
+
export type { UseAuthResult } from './presentation/hooks/useAuth';
|
|
30
|
+
export { LoginScreen } from './presentation/screens/LoginScreen';
|
|
31
|
+
export { RegisterScreen } from './presentation/screens/RegisterScreen';
|
|
32
|
+
export { AuthNavigator } from './presentation/navigation/AuthNavigator';
|
|
33
|
+
export type { AuthStackParamList, AuthNavigatorProps, } from './presentation/navigation/AuthNavigator';
|
|
34
|
+
export { AuthContainer } from './presentation/components/AuthContainer';
|
|
35
|
+
export { AuthHeader } from './presentation/components/AuthHeader';
|
|
36
|
+
export { AuthFormCard } from './presentation/components/AuthFormCard';
|
|
37
|
+
export { LoginForm } from './presentation/components/LoginForm';
|
|
38
|
+
export { RegisterForm } from './presentation/components/RegisterForm';
|
|
39
|
+
export { AuthLegalLinks } from './presentation/components/AuthLegalLinks';
|
|
40
|
+
export type { AuthLegalLinksProps } from './presentation/components/AuthLegalLinks';
|
|
41
|
+
export { PasswordStrengthIndicator } from './presentation/components/PasswordStrengthIndicator';
|
|
42
|
+
export type { PasswordStrengthIndicatorProps } from './presentation/components/PasswordStrengthIndicator';
|
|
43
|
+
export { PasswordMatchIndicator } from './presentation/components/PasswordMatchIndicator';
|
|
44
|
+
export type { PasswordMatchIndicatorProps } from './presentation/components/PasswordMatchIndicator';
|
|
45
|
+
export { getAuthErrorLocalizationKey } from './presentation/utils/getAuthErrorMessage';
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native Auth - Public API
|
|
3
|
+
*
|
|
4
|
+
* Domain-Driven Design (DDD) Architecture
|
|
5
|
+
*
|
|
6
|
+
* This is the SINGLE SOURCE OF TRUTH for all Auth operations.
|
|
7
|
+
* ALL imports from the Auth package MUST go through this file.
|
|
8
|
+
*
|
|
9
|
+
* Architecture:
|
|
10
|
+
* - domain: Entities, value objects, errors (business logic)
|
|
11
|
+
* - application: Ports (interfaces)
|
|
12
|
+
* - infrastructure: Auth providers and service implementation
|
|
13
|
+
* - presentation: Hooks (React integration)
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* import { initializeAuthService, useAuth } from '@umituz/react-native-auth';
|
|
17
|
+
*/
|
|
18
|
+
// =============================================================================
|
|
19
|
+
// DOMAIN LAYER - Errors
|
|
20
|
+
// =============================================================================
|
|
21
|
+
export { AuthError, AuthInitializationError, AuthConfigurationError, AuthValidationError, AuthNetworkError, AuthUserNotFoundError, AuthWrongPasswordError, AuthEmailAlreadyInUseError, AuthWeakPasswordError, AuthInvalidEmailError, } from './domain/errors/AuthError';
|
|
22
|
+
export { DEFAULT_AUTH_CONFIG, DEFAULT_PASSWORD_CONFIG } from './domain/value-objects/AuthConfig';
|
|
23
|
+
// =============================================================================
|
|
24
|
+
// INFRASTRUCTURE LAYER - Providers
|
|
25
|
+
// =============================================================================
|
|
26
|
+
export { FirebaseAuthProvider } from './infrastructure/providers/FirebaseAuthProvider';
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// INFRASTRUCTURE LAYER - Services
|
|
29
|
+
// =============================================================================
|
|
30
|
+
export { AuthService, initializeAuthService, getAuthService, resetAuthService, } from './infrastructure/services/AuthService';
|
|
31
|
+
// =============================================================================
|
|
32
|
+
// INFRASTRUCTURE LAYER - Validation
|
|
33
|
+
// =============================================================================
|
|
34
|
+
export { validateEmail, validatePasswordForLogin, validatePasswordForRegister, validatePasswordConfirmation, validateDisplayName, } from './infrastructure/utils/AuthValidation';
|
|
35
|
+
// =============================================================================
|
|
36
|
+
// PRESENTATION LAYER - Hooks
|
|
37
|
+
// =============================================================================
|
|
38
|
+
export { useAuth } from './presentation/hooks/useAuth';
|
|
39
|
+
// =============================================================================
|
|
40
|
+
// PRESENTATION LAYER - Screens & Navigation
|
|
41
|
+
// =============================================================================
|
|
42
|
+
export { LoginScreen } from './presentation/screens/LoginScreen';
|
|
43
|
+
export { RegisterScreen } from './presentation/screens/RegisterScreen';
|
|
44
|
+
export { AuthNavigator } from './presentation/navigation/AuthNavigator';
|
|
45
|
+
// =============================================================================
|
|
46
|
+
// PRESENTATION LAYER - Components
|
|
47
|
+
// =============================================================================
|
|
48
|
+
export { AuthContainer } from './presentation/components/AuthContainer';
|
|
49
|
+
export { AuthHeader } from './presentation/components/AuthHeader';
|
|
50
|
+
export { AuthFormCard } from './presentation/components/AuthFormCard';
|
|
51
|
+
export { LoginForm } from './presentation/components/LoginForm';
|
|
52
|
+
export { RegisterForm } from './presentation/components/RegisterForm';
|
|
53
|
+
export { AuthLegalLinks } from './presentation/components/AuthLegalLinks';
|
|
54
|
+
export { PasswordStrengthIndicator } from './presentation/components/PasswordStrengthIndicator';
|
|
55
|
+
export { PasswordMatchIndicator } from './presentation/components/PasswordMatchIndicator';
|
|
56
|
+
// =============================================================================
|
|
57
|
+
// PRESENTATION LAYER - Utilities
|
|
58
|
+
// =============================================================================
|
|
59
|
+
export { getAuthErrorLocalizationKey } from './presentation/utils/getAuthErrorMessage';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage Provider Adapter
|
|
3
|
+
* Adapts external storage implementations to our IStorageProvider interface
|
|
4
|
+
*/
|
|
5
|
+
import type { IStorageProvider } from "../services/GuestModeService";
|
|
6
|
+
export declare class StorageProviderAdapter implements IStorageProvider {
|
|
7
|
+
private storage;
|
|
8
|
+
constructor(storage: any);
|
|
9
|
+
get(key: string): Promise<string | null>;
|
|
10
|
+
set(key: string, value: string): Promise<void>;
|
|
11
|
+
remove(key: string): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Create storage provider from various storage implementations
|
|
15
|
+
*/
|
|
16
|
+
export declare function createStorageProvider(storage: any): IStorageProvider;
|