rn-swiftauth-sdk 1.0.2 → 1.0.3
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 +121 -35
- package/dist/core/AuthProvider.js +25 -49
- package/dist/errors/errorMapper.d.ts +10 -2
- package/dist/errors/errorMapper.js +61 -99
- package/dist/errors/exceptions.d.ts +82 -0
- package/dist/errors/exceptions.js +134 -0
- package/dist/errors/index.d.ts +2 -1
- package/dist/errors/index.js +19 -15
- package/dist/types/auth.types.d.ts +2 -2
- package/dist/types/error.types.d.ts +9 -8
- package/dist/types/error.types.js +22 -15
- package/package.json +1 -1
- package/src/core/AuthProvider.tsx +52 -65
- package/src/errors/errorMapper.ts +97 -105
- package/src/errors/exceptions.ts +174 -0
- package/src/errors/index.ts +22 -1
- package/src/types/auth.types.ts +3 -3
- package/src/types/error.types.ts +29 -21
package/README.md
CHANGED
|
@@ -237,63 +237,149 @@ const {
|
|
|
237
237
|
|
|
238
238
|
## Error Handling
|
|
239
239
|
|
|
240
|
-
SwiftAuth
|
|
240
|
+
SwiftAuth provides a comprehensive error handling system with custom exceptions that map Firebase errors to user-friendly messages.
|
|
241
|
+
|
|
242
|
+
### Custom Exception Classes
|
|
243
|
+
|
|
244
|
+
All errors extend the base `AuthException` class and include:
|
|
245
|
+
- `code`: Machine-readable error code
|
|
246
|
+
- `message`: User-friendly error message
|
|
247
|
+
- `timestamp`: When the error occurred
|
|
248
|
+
- `originalError`: The underlying Firebase error (optional)
|
|
249
|
+
- `toJSON()`: Serialize for logging/debugging
|
|
250
|
+
|
|
251
|
+
### Supported Exceptions
|
|
252
|
+
|
|
253
|
+
| Exception Class | Error Code | User Message |
|
|
254
|
+
|-----------------|------------|--------------|
|
|
255
|
+
| `InvalidCredentialsException` | `auth/invalid-credentials` | "Invalid email or password. Please check your credentials and try again." |
|
|
256
|
+
| `UserNotFoundException` | `auth/user-not-found` | "No account found with this email. Please sign up first." |
|
|
257
|
+
| `EmailAlreadyInUseException` | `auth/email-already-in-use` | "This email is already registered. Please sign in or use a different email." |
|
|
258
|
+
| `WeakPasswordException` | `auth/weak-password` | "Password is too weak. Please use at least 6 characters with a mix of letters and numbers." |
|
|
259
|
+
| `TokenExpiredException` | `auth/token-expired` | "Your session has expired. Please sign in again." |
|
|
260
|
+
| `NetworkException` | `auth/network-error` | "Network error. Please check your internet connection and try again." |
|
|
261
|
+
| `GoogleSignInCancelledException` | `auth/google-sign-in-cancelled` | "Google Sign-In was cancelled." |
|
|
262
|
+
| `AppleSignInCancelledException` | `auth/apple-sign-in-cancelled` | "Apple Sign-In was cancelled." |
|
|
263
|
+
| `AppleSignInNotSupportedException` | `auth/apple-sign-in-not-supported` | "Apple Sign-In is only available on iOS 13+ devices." |
|
|
264
|
+
| `GooglePlayServicesUnavailableException` | `auth/google-play-services-unavailable` | "Google Play Services are not available. Please update Google Play Services." |
|
|
265
|
+
| `ConfigurationException` | `auth/configuration-error` | Custom message based on configuration issue |
|
|
266
|
+
| `UnknownAuthException` | `auth/unknown` | "An unexpected error occurred." |
|
|
267
|
+
|
|
268
|
+
### Basic Error Display
|
|
269
|
+
```typescript
|
|
270
|
+
import { useAuth } from 'rn-swiftauth-sdk';
|
|
241
271
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
| `auth/invalid-credentials` | "Invalid email or password." |
|
|
245
|
-
| `auth/user-not-found` | "Invalid email or password." |
|
|
246
|
-
| `auth/email-already-in-use` | "This email is already registered." |
|
|
247
|
-
| `auth/weak-password` | "Password is too weak." |
|
|
248
|
-
| `auth/network-request-failed` | "Network error. Please check your connection." |
|
|
272
|
+
const LoginScreen = () => {
|
|
273
|
+
const { error, clearError } = useAuth();
|
|
249
274
|
|
|
250
|
-
|
|
275
|
+
return (
|
|
276
|
+
<View>
|
|
277
|
+
{error && (
|
|
278
|
+
<View style={styles.errorContainer}>
|
|
279
|
+
<Text style={styles.errorText}>{error.message}</Text>
|
|
280
|
+
<Button title="Dismiss" onPress={clearError} />
|
|
281
|
+
</View>
|
|
282
|
+
)}
|
|
283
|
+
</View>
|
|
284
|
+
);
|
|
285
|
+
};
|
|
286
|
+
```
|
|
251
287
|
|
|
288
|
+
### Handling Specific Exception Types
|
|
252
289
|
```typescript
|
|
253
|
-
|
|
290
|
+
import {
|
|
291
|
+
useAuth,
|
|
292
|
+
InvalidCredentialsException,
|
|
293
|
+
EmailAlreadyInUseException,
|
|
294
|
+
NetworkException
|
|
295
|
+
} from 'rn-swiftauth-sdk';
|
|
254
296
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
```
|
|
297
|
+
const SignUpScreen = () => {
|
|
298
|
+
const { signUpWithEmail } = useAuth();
|
|
259
299
|
|
|
260
|
-
|
|
300
|
+
const handleSignUp = async () => {
|
|
301
|
+
try {
|
|
302
|
+
await signUpWithEmail({ email, password });
|
|
303
|
+
} catch (error) {
|
|
304
|
+
if (error instanceof EmailAlreadyInUseException) {
|
|
305
|
+
Alert.alert(
|
|
306
|
+
"Account Exists",
|
|
307
|
+
"Would you like to sign in instead?",
|
|
308
|
+
[
|
|
309
|
+
{ text: "Cancel", style: "cancel" },
|
|
310
|
+
{ text: "Sign In", onPress: () => navigation.navigate('SignIn') }
|
|
311
|
+
]
|
|
312
|
+
);
|
|
313
|
+
} else if (error instanceof NetworkException) {
|
|
314
|
+
Alert.alert("Connection Issue", "Please check your internet and try again.");
|
|
315
|
+
} else if (error instanceof InvalidCredentialsException) {
|
|
316
|
+
Alert.alert("Invalid Input", "Please check your email and password.");
|
|
317
|
+
} else {
|
|
318
|
+
Alert.alert("Error", error.message);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
return <Button title="Sign Up" onPress={handleSignUp} />;
|
|
324
|
+
};
|
|
325
|
+
```
|
|
261
326
|
|
|
262
|
-
|
|
327
|
+
### Accessing Original Firebase Errors
|
|
263
328
|
|
|
264
|
-
|
|
329
|
+
For advanced use cases, access the raw Firebase error:
|
|
265
330
|
```typescript
|
|
266
|
-
const {
|
|
331
|
+
const { error } = useAuth();
|
|
267
332
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
333
|
+
useEffect(() => {
|
|
334
|
+
if (error?.originalError) {
|
|
335
|
+
console.log('Firebase Error Code:', error.originalError.code);
|
|
336
|
+
console.log('Firebase Error Message:', error.originalError.message);
|
|
337
|
+
|
|
338
|
+
// Custom handling for specific Firebase codes
|
|
339
|
+
if (error.originalError.code === 'auth/requires-recent-login') {
|
|
340
|
+
showReauthenticationPrompt();
|
|
276
341
|
}
|
|
277
342
|
}
|
|
278
|
-
};
|
|
343
|
+
}, [error]);
|
|
279
344
|
```
|
|
280
345
|
|
|
281
|
-
|
|
346
|
+
### Error Logging for Debugging
|
|
282
347
|
```typescript
|
|
283
348
|
const { error } = useAuth();
|
|
284
349
|
|
|
285
350
|
useEffect(() => {
|
|
286
|
-
if (error
|
|
287
|
-
|
|
288
|
-
console.log(
|
|
351
|
+
if (error) {
|
|
352
|
+
// Log full error details (includes timestamp, code, original error)
|
|
353
|
+
console.log('Auth Error:', JSON.stringify(error.toJSON(), null, 2));
|
|
289
354
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
}
|
|
355
|
+
// Send to error tracking service (e.g., Sentry)
|
|
356
|
+
logErrorToService(error.toJSON());
|
|
293
357
|
}
|
|
294
358
|
}, [error]);
|
|
295
359
|
```
|
|
296
360
|
|
|
361
|
+
### Global Error Boundary
|
|
362
|
+
```typescript
|
|
363
|
+
import { useAuth } from 'rn-swiftauth-sdk';
|
|
364
|
+
|
|
365
|
+
const ErrorBoundary = ({ children }) => {
|
|
366
|
+
const { error, clearError } = useAuth();
|
|
367
|
+
|
|
368
|
+
if (error) {
|
|
369
|
+
return (
|
|
370
|
+
<View style={styles.errorScreen}>
|
|
371
|
+
<Text style={styles.errorTitle}>Oops!</Text>
|
|
372
|
+
<Text style={styles.errorMessage}>{error.message}</Text>
|
|
373
|
+
<Text style={styles.errorCode}>Error Code: {error.code}</Text>
|
|
374
|
+
<Button title="Try Again" onPress={clearError} />
|
|
375
|
+
</View>
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
return <>{children}</>;
|
|
380
|
+
};
|
|
381
|
+
```
|
|
382
|
+
|
|
297
383
|
---
|
|
298
384
|
|
|
299
385
|
## Session Management
|
|
@@ -421,4 +507,4 @@ MIT License - see [LICENSE](LICENSE) file for details.
|
|
|
421
507
|
|
|
422
508
|
- **Issues:** [GitHub Issues](https://github.com/allcodez/Auth-SDK_Stage8/issues)
|
|
423
509
|
- **NPM Package:** [rn-swiftauth-sdk](https://www.npmjs.com/package/rn-swiftauth-sdk)
|
|
424
|
-
- **Documentation:** [Full Docs](https://github.com/allcodez/Auth-SDK_Stage8)
|
|
510
|
+
- **Documentation:** [Full Docs](https://github.com/allcodez/Auth-SDK_Stage8)
|
|
@@ -113,9 +113,11 @@ const AuthProvider = ({ config, children }) => {
|
|
|
113
113
|
if (tokenError.code === types_1.ProviderErrorCodes.USER_TOKEN_EXPIRED ||
|
|
114
114
|
tokenError.code === types_1.ProviderErrorCodes.NULL_USER) {
|
|
115
115
|
setStatus(types_1.AuthStatus.TOKEN_EXPIRED);
|
|
116
|
+
setError((0, errors_1.mapFirebaseError)(tokenError));
|
|
116
117
|
}
|
|
117
118
|
else {
|
|
118
119
|
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
120
|
+
setError((0, errors_1.mapFirebaseError)(tokenError));
|
|
119
121
|
}
|
|
120
122
|
setUser(null);
|
|
121
123
|
}
|
|
@@ -128,6 +130,7 @@ const AuthProvider = ({ config, children }) => {
|
|
|
128
130
|
catch (err) {
|
|
129
131
|
console.error("Auth State Error:", err);
|
|
130
132
|
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
133
|
+
setError((0, errors_1.mapFirebaseError)(err));
|
|
131
134
|
}
|
|
132
135
|
finally {
|
|
133
136
|
setIsDataLoading(false);
|
|
@@ -145,10 +148,10 @@ const AuthProvider = ({ config, children }) => {
|
|
|
145
148
|
await FirebaseAuth.signInWithEmailAndPassword(firebaseAuthInstance, email, password);
|
|
146
149
|
}
|
|
147
150
|
catch (err) {
|
|
148
|
-
const
|
|
149
|
-
setError(
|
|
151
|
+
const mappedException = (0, errors_1.mapFirebaseError)(err);
|
|
152
|
+
setError(mappedException);
|
|
150
153
|
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
151
|
-
throw
|
|
154
|
+
throw mappedException;
|
|
152
155
|
}
|
|
153
156
|
};
|
|
154
157
|
const signUpWithEmail = async ({ email, password }) => {
|
|
@@ -160,18 +163,19 @@ const AuthProvider = ({ config, children }) => {
|
|
|
160
163
|
await FirebaseAuth.createUserWithEmailAndPassword(firebaseAuthInstance, email, password);
|
|
161
164
|
}
|
|
162
165
|
catch (err) {
|
|
163
|
-
const
|
|
164
|
-
setError(
|
|
166
|
+
const mappedException = (0, errors_1.mapFirebaseError)(err);
|
|
167
|
+
setError(mappedException);
|
|
165
168
|
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
166
|
-
throw
|
|
169
|
+
throw mappedException;
|
|
167
170
|
}
|
|
168
171
|
};
|
|
169
172
|
const signInWithGoogle = async () => {
|
|
170
173
|
if (!firebaseAuthInstance)
|
|
171
174
|
throw new Error('Firebase not initialized');
|
|
172
175
|
if (!config.enableGoogle || !config.googleWebClientId) {
|
|
173
|
-
|
|
174
|
-
|
|
176
|
+
const configError = new errors_1.ConfigurationException('Google Auth not configured. Missing googleWebClientId.');
|
|
177
|
+
setError(configError);
|
|
178
|
+
throw configError;
|
|
175
179
|
}
|
|
176
180
|
try {
|
|
177
181
|
setError(null);
|
|
@@ -187,55 +191,29 @@ const AuthProvider = ({ config, children }) => {
|
|
|
187
191
|
}
|
|
188
192
|
catch (err) {
|
|
189
193
|
console.error('Google Sign-In Error:', err);
|
|
190
|
-
let mappedError;
|
|
191
194
|
if (err.code === types_1.ProviderErrorCodes.GOOGLE_CANCELLED) {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
message: 'Google Sign-In was cancelled',
|
|
195
|
-
originalError: err
|
|
196
|
-
};
|
|
195
|
+
const cancelError = new errors_1.GoogleSignInCancelledException(err);
|
|
196
|
+
setError(cancelError);
|
|
197
197
|
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
198
198
|
return;
|
|
199
199
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
code: types_1.AuthErrorCode.GOOGLE_SIGN_IN_IN_PROGRESS,
|
|
203
|
-
message: 'Google Sign-In is already in progress',
|
|
204
|
-
originalError: err
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
else if (err.code === types_1.ProviderErrorCodes.GOOGLE_PLAY_UNAVAILABLE) {
|
|
208
|
-
mappedError = {
|
|
209
|
-
code: types_1.AuthErrorCode.GOOGLE_PLAY_SERVICES_NOT_AVAILABLE,
|
|
210
|
-
message: 'Google Play Services are not available. Please update Google Play Services.',
|
|
211
|
-
originalError: err
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
mappedError = (0, errors_1.mapFirebaseError)(err);
|
|
216
|
-
}
|
|
217
|
-
setError({ ...mappedError, originalError: err });
|
|
200
|
+
const mappedException = (0, errors_1.mapFirebaseError)(err);
|
|
201
|
+
setError(mappedException);
|
|
218
202
|
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
219
|
-
throw
|
|
203
|
+
throw mappedException;
|
|
220
204
|
}
|
|
221
205
|
};
|
|
222
206
|
const signInWithApple = async () => {
|
|
223
207
|
if (!firebaseAuthInstance)
|
|
224
208
|
throw new Error('Firebase not initialized');
|
|
225
209
|
if (react_native_1.Platform.OS !== 'ios') {
|
|
226
|
-
const platformError =
|
|
227
|
-
code: types_1.AuthErrorCode.APPLE_SIGN_IN_NOT_SUPPORTED,
|
|
228
|
-
message: 'Apple Sign-In is only available on iOS devices',
|
|
229
|
-
};
|
|
210
|
+
const platformError = new errors_1.AppleSignInNotSupportedException();
|
|
230
211
|
setError(platformError);
|
|
231
212
|
throw platformError;
|
|
232
213
|
}
|
|
233
214
|
const isAvailable = await AppleAuthentication.isAvailableAsync();
|
|
234
215
|
if (!isAvailable) {
|
|
235
|
-
const availabilityError =
|
|
236
|
-
code: types_1.AuthErrorCode.APPLE_SIGN_IN_NOT_SUPPORTED,
|
|
237
|
-
message: 'Apple Sign-In is not available on this device (requires iOS 13+)',
|
|
238
|
-
};
|
|
216
|
+
const availabilityError = new errors_1.AppleSignInNotSupportedException();
|
|
239
217
|
setError(availabilityError);
|
|
240
218
|
throw availabilityError;
|
|
241
219
|
}
|
|
@@ -265,19 +243,15 @@ const AuthProvider = ({ config, children }) => {
|
|
|
265
243
|
catch (err) {
|
|
266
244
|
console.error('Apple Sign-In Error:', err);
|
|
267
245
|
if (err.code === types_1.ProviderErrorCodes.APPLE_CANCELLED) {
|
|
268
|
-
const cancelError =
|
|
269
|
-
code: types_1.AuthErrorCode.APPLE_SIGN_IN_CANCELLED,
|
|
270
|
-
message: 'Apple Sign-In was cancelled',
|
|
271
|
-
originalError: err
|
|
272
|
-
};
|
|
246
|
+
const cancelError = new errors_1.AppleSignInCancelledException(err);
|
|
273
247
|
setError(cancelError);
|
|
274
248
|
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
275
249
|
return;
|
|
276
250
|
}
|
|
277
|
-
const
|
|
278
|
-
setError(
|
|
251
|
+
const mappedException = (0, errors_1.mapFirebaseError)(err);
|
|
252
|
+
setError(mappedException);
|
|
279
253
|
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
280
|
-
throw
|
|
254
|
+
throw mappedException;
|
|
281
255
|
}
|
|
282
256
|
};
|
|
283
257
|
const signOut = async () => {
|
|
@@ -297,6 +271,8 @@ const AuthProvider = ({ config, children }) => {
|
|
|
297
271
|
}
|
|
298
272
|
catch (err) {
|
|
299
273
|
console.error('Sign out error:', err);
|
|
274
|
+
const signOutError = (0, errors_1.mapFirebaseError)(err);
|
|
275
|
+
setError(signOutError);
|
|
300
276
|
setUser(null);
|
|
301
277
|
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
302
278
|
}
|
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const mapFirebaseError: (error: any) =>
|
|
1
|
+
import { AuthException } from './exceptions';
|
|
2
|
+
export declare const mapFirebaseError: (error: any) => AuthException;
|
|
3
|
+
/**
|
|
4
|
+
* Helper function to check if an error is a specific exception type
|
|
5
|
+
*/
|
|
6
|
+
export declare const isAuthException: (error: any, exceptionType: new (...args: any[]) => AuthException) => boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Helper to extract user-friendly message from any error
|
|
9
|
+
*/
|
|
10
|
+
export declare const getErrorMessage: (error: any) => string;
|
|
@@ -1,124 +1,86 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
// swiftauth-sdk/src/errors/errorMapper.ts
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.mapFirebaseError = void 0;
|
|
4
|
+
exports.getErrorMessage = exports.isAuthException = exports.mapFirebaseError = void 0;
|
|
5
|
+
const exceptions_1 = require("./exceptions");
|
|
4
6
|
const types_1 = require("../types");
|
|
5
7
|
const mapFirebaseError = (error) => {
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
// If it's not a Firebase error, return generic
|
|
8
|
+
// If it's already our custom exception, return it
|
|
9
|
+
if (error instanceof exceptions_1.AuthException) {
|
|
10
|
+
return error;
|
|
11
|
+
}
|
|
12
|
+
// If it's not a Firebase error or doesn't have a code, return generic
|
|
13
13
|
if (!error || typeof error.code !== 'string') {
|
|
14
|
-
return
|
|
15
|
-
...fallbackError,
|
|
16
|
-
message: error?.message || fallbackError.message
|
|
17
|
-
};
|
|
14
|
+
return new exceptions_1.UnknownAuthException(error?.message || 'An unexpected error occurred', error);
|
|
18
15
|
}
|
|
19
16
|
const fbError = error;
|
|
17
|
+
// Map Firebase error codes to custom exceptions
|
|
20
18
|
switch (fbError.code) {
|
|
21
|
-
//
|
|
19
|
+
// Invalid Credentials
|
|
22
20
|
case 'auth/invalid-email':
|
|
23
|
-
case 'auth/user-not-found':
|
|
24
21
|
case 'auth/wrong-password':
|
|
25
22
|
case 'auth/invalid-credential':
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
case 'auth/user-disabled':
|
|
24
|
+
return new exceptions_1.InvalidCredentialsException(error);
|
|
25
|
+
// User Not Found
|
|
26
|
+
case 'auth/user-not-found':
|
|
27
|
+
return new exceptions_1.UserNotFoundException(error);
|
|
28
|
+
// Email Already In Use
|
|
31
29
|
case 'auth/email-already-in-use':
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
originalError: error
|
|
36
|
-
};
|
|
30
|
+
case 'auth/account-exists-with-different-credential':
|
|
31
|
+
return new exceptions_1.EmailAlreadyInUseException(error);
|
|
32
|
+
// Weak Password
|
|
37
33
|
case 'auth/weak-password':
|
|
38
|
-
return
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
return new exceptions_1.WeakPasswordException(error);
|
|
35
|
+
// Token Expired
|
|
36
|
+
case 'auth/id-token-expired':
|
|
37
|
+
case 'auth/user-token-expired':
|
|
38
|
+
case types_1.ProviderErrorCodes.USER_TOKEN_EXPIRED:
|
|
39
|
+
return new exceptions_1.TokenExpiredException(error);
|
|
40
|
+
// Network Error
|
|
43
41
|
case 'auth/network-request-failed':
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
message: 'Network error. Please check your connection.',
|
|
47
|
-
originalError: error
|
|
48
|
-
};
|
|
42
|
+
case 'auth/timeout':
|
|
43
|
+
return new exceptions_1.NetworkException(error);
|
|
49
44
|
// Google Sign-In Errors
|
|
45
|
+
case types_1.ProviderErrorCodes.GOOGLE_CANCELLED:
|
|
50
46
|
case 'auth/popup-closed-by-user':
|
|
51
47
|
case 'auth/cancelled-popup-request':
|
|
52
|
-
return
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
originalError: error
|
|
56
|
-
};
|
|
57
|
-
case 'auth/account-exists-with-different-credential':
|
|
58
|
-
return {
|
|
59
|
-
code: types_1.AuthErrorCode.EMAIL_ALREADY_IN_USE,
|
|
60
|
-
message: 'An account already exists with this email using a different sign-in method.',
|
|
61
|
-
originalError: error
|
|
62
|
-
};
|
|
63
|
-
case 'auth/invalid-credential':
|
|
64
|
-
return {
|
|
65
|
-
code: types_1.AuthErrorCode.INVALID_CREDENTIALS,
|
|
66
|
-
message: 'The credential received is invalid. Please try again.',
|
|
67
|
-
originalError: error
|
|
68
|
-
};
|
|
69
|
-
case 'auth/operation-not-allowed':
|
|
70
|
-
return {
|
|
71
|
-
code: types_1.AuthErrorCode.UNKNOWN,
|
|
72
|
-
message: 'This sign-in method is not enabled. Please contact support.',
|
|
73
|
-
originalError: error
|
|
74
|
-
};
|
|
75
|
-
case 'auth/user-disabled':
|
|
76
|
-
return {
|
|
77
|
-
code: types_1.AuthErrorCode.INVALID_CREDENTIALS,
|
|
78
|
-
message: 'This account has been disabled.',
|
|
79
|
-
originalError: error
|
|
80
|
-
};
|
|
48
|
+
return new exceptions_1.GoogleSignInCancelledException(error);
|
|
49
|
+
case types_1.ProviderErrorCodes.GOOGLE_PLAY_UNAVAILABLE:
|
|
50
|
+
return new exceptions_1.GooglePlayServicesUnavailableException(error);
|
|
81
51
|
// Apple Sign-In Errors
|
|
82
|
-
case
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
// Token Expiration
|
|
90
|
-
case 'auth/id-token-expired':
|
|
91
|
-
case 'auth/user-token-expired':
|
|
92
|
-
return {
|
|
93
|
-
code: types_1.AuthErrorCode.TOKEN_EXPIRED,
|
|
94
|
-
message: 'Your session has expired. Please sign in again.',
|
|
95
|
-
originalError: error
|
|
96
|
-
};
|
|
97
|
-
// OAuth-Specific Errors
|
|
52
|
+
case types_1.ProviderErrorCodes.APPLE_CANCELLED:
|
|
53
|
+
return new exceptions_1.AppleSignInCancelledException(error);
|
|
54
|
+
case types_1.ProviderErrorCodes.APPLE_NOT_SUPPORTED:
|
|
55
|
+
return new exceptions_1.AppleSignInNotSupportedException(error);
|
|
56
|
+
// Configuration Errors
|
|
57
|
+
case 'auth/operation-not-allowed':
|
|
58
|
+
return new exceptions_1.ConfigurationException('This sign-in method is not enabled. Please check your Firebase configuration.', error);
|
|
98
59
|
case 'auth/unauthorized-domain':
|
|
99
|
-
return
|
|
100
|
-
code: types_1.AuthErrorCode.UNKNOWN,
|
|
101
|
-
message: 'This domain is not authorized for OAuth operations.',
|
|
102
|
-
originalError: error
|
|
103
|
-
};
|
|
60
|
+
return new exceptions_1.ConfigurationException('This domain is not authorized for OAuth operations.', error);
|
|
104
61
|
case 'auth/invalid-oauth-provider':
|
|
105
|
-
return {
|
|
106
|
-
code: types_1.AuthErrorCode.UNKNOWN,
|
|
107
|
-
message: 'The OAuth provider configuration is invalid.',
|
|
108
|
-
originalError: error
|
|
109
|
-
};
|
|
110
62
|
case 'auth/invalid-oauth-client-id':
|
|
111
|
-
return
|
|
112
|
-
|
|
113
|
-
message: 'The OAuth client ID is invalid.',
|
|
114
|
-
originalError: error
|
|
115
|
-
};
|
|
63
|
+
return new exceptions_1.ConfigurationException('The OAuth configuration is invalid.', error);
|
|
64
|
+
// Default
|
|
116
65
|
default:
|
|
117
|
-
return
|
|
118
|
-
code: types_1.AuthErrorCode.UNKNOWN,
|
|
119
|
-
message: fbError.message || 'An unknown error occurred.',
|
|
120
|
-
originalError: error
|
|
121
|
-
};
|
|
66
|
+
return new exceptions_1.UnknownAuthException(fbError.message || 'An unknown error occurred.', error);
|
|
122
67
|
}
|
|
123
68
|
};
|
|
124
69
|
exports.mapFirebaseError = mapFirebaseError;
|
|
70
|
+
/**
|
|
71
|
+
* Helper function to check if an error is a specific exception type
|
|
72
|
+
*/
|
|
73
|
+
const isAuthException = (error, exceptionType) => {
|
|
74
|
+
return error instanceof exceptionType;
|
|
75
|
+
};
|
|
76
|
+
exports.isAuthException = isAuthException;
|
|
77
|
+
/**
|
|
78
|
+
* Helper to extract user-friendly message from any error
|
|
79
|
+
*/
|
|
80
|
+
const getErrorMessage = (error) => {
|
|
81
|
+
if (error instanceof exceptions_1.AuthException) {
|
|
82
|
+
return error.message;
|
|
83
|
+
}
|
|
84
|
+
return error?.message || 'An unexpected error occurred';
|
|
85
|
+
};
|
|
86
|
+
exports.getErrorMessage = getErrorMessage;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export declare class AuthException extends Error {
|
|
2
|
+
readonly code: string;
|
|
3
|
+
readonly originalError?: any;
|
|
4
|
+
readonly timestamp: Date;
|
|
5
|
+
constructor(message: string, code: string, originalError?: any);
|
|
6
|
+
toJSON(): {
|
|
7
|
+
name: string;
|
|
8
|
+
code: string;
|
|
9
|
+
message: string;
|
|
10
|
+
timestamp: string;
|
|
11
|
+
originalError: any;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export declare class InvalidCredentialsException extends AuthException {
|
|
15
|
+
constructor(originalError?: any);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Thrown when user account does not exist
|
|
19
|
+
*/
|
|
20
|
+
export declare class UserNotFoundException extends AuthException {
|
|
21
|
+
constructor(originalError?: any);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Thrown when attempting to sign up with an email that's already registered
|
|
25
|
+
*/
|
|
26
|
+
export declare class EmailAlreadyInUseException extends AuthException {
|
|
27
|
+
constructor(originalError?: any);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Thrown when password doesn't meet minimum security requirements
|
|
31
|
+
*/
|
|
32
|
+
export declare class WeakPasswordException extends AuthException {
|
|
33
|
+
constructor(originalError?: any);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Thrown when user's authentication token has expired
|
|
37
|
+
*/
|
|
38
|
+
export declare class TokenExpiredException extends AuthException {
|
|
39
|
+
constructor(originalError?: any);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Thrown when network connectivity issues occur
|
|
43
|
+
*/
|
|
44
|
+
export declare class NetworkException extends AuthException {
|
|
45
|
+
constructor(originalError?: any);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Thrown when Google Sign-In is cancelled by user
|
|
49
|
+
*/
|
|
50
|
+
export declare class GoogleSignInCancelledException extends AuthException {
|
|
51
|
+
constructor(originalError?: any);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Thrown when Apple Sign-In is cancelled by user
|
|
55
|
+
*/
|
|
56
|
+
export declare class AppleSignInCancelledException extends AuthException {
|
|
57
|
+
constructor(originalError?: any);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Thrown when Apple Sign-In is not supported on the device
|
|
61
|
+
*/
|
|
62
|
+
export declare class AppleSignInNotSupportedException extends AuthException {
|
|
63
|
+
constructor(originalError?: any);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Thrown when Google Play Services are not available
|
|
67
|
+
*/
|
|
68
|
+
export declare class GooglePlayServicesUnavailableException extends AuthException {
|
|
69
|
+
constructor(originalError?: any);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Thrown for configuration errors
|
|
73
|
+
*/
|
|
74
|
+
export declare class ConfigurationException extends AuthException {
|
|
75
|
+
constructor(message: string, originalError?: any);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Generic unknown error
|
|
79
|
+
*/
|
|
80
|
+
export declare class UnknownAuthException extends AuthException {
|
|
81
|
+
constructor(message?: string, originalError?: any);
|
|
82
|
+
}
|