rn-swiftauth-sdk 1.0.2 → 1.0.4

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.
@@ -1,139 +1,131 @@
1
- import { FirebaseError } from 'firebase/app';
2
- import { AuthError, AuthErrorCode } from '../types';
1
+ // swiftauth-sdk/src/errors/errorMapper.ts
3
2
 
4
- export const mapFirebaseError = (error: any): AuthError => {
5
- // Default fallback
6
- const fallbackError: AuthError = {
7
- code: AuthErrorCode.UNKNOWN,
8
- message: 'An unexpected error occurred',
9
- originalError: error,
10
- };
3
+ import { FirebaseError } from 'firebase/app';
4
+ import {
5
+ AuthException,
6
+ InvalidCredentialsException,
7
+ UserNotFoundException,
8
+ EmailAlreadyInUseException,
9
+ WeakPasswordException,
10
+ TokenExpiredException,
11
+ NetworkException,
12
+ GoogleSignInCancelledException,
13
+ AppleSignInCancelledException,
14
+ AppleSignInNotSupportedException,
15
+ GooglePlayServicesUnavailableException,
16
+ ConfigurationException,
17
+ UnknownAuthException,
18
+ } from './exceptions';
19
+ import { ProviderErrorCodes } from '../types';
20
+
21
+
22
+ export const mapFirebaseError = (error: any): AuthException => {
23
+ // If it's already our custom exception, return it
24
+ if (error instanceof AuthException) {
25
+ return error;
26
+ }
11
27
 
12
- // If it's not a Firebase error, return generic
28
+ // If it's not a Firebase error or doesn't have a code, return generic
13
29
  if (!error || typeof error.code !== 'string') {
14
- return {
15
- ...fallbackError,
16
- message: error?.message || fallbackError.message
17
- };
30
+ return new UnknownAuthException(
31
+ error?.message || 'An unexpected error occurred',
32
+ error
33
+ );
18
34
  }
19
35
 
20
36
  const fbError = error as FirebaseError;
21
37
 
38
+ // Map Firebase error codes to custom exceptions
22
39
  switch (fbError.code) {
23
- // Email/Password Errors
40
+ // Invalid Credentials
24
41
  case 'auth/invalid-email':
25
- case 'auth/user-not-found':
26
42
  case 'auth/wrong-password':
27
43
  case 'auth/invalid-credential':
28
- return {
29
- code: AuthErrorCode.INVALID_CREDENTIALS,
30
- message: 'Invalid email or password.',
31
- originalError: error
32
- };
44
+ case 'auth/user-disabled':
45
+ return new InvalidCredentialsException(error);
46
+
47
+ // User Not Found
48
+ case 'auth/user-not-found':
49
+ return new UserNotFoundException(error);
33
50
 
51
+ // Email Already In Use
34
52
  case 'auth/email-already-in-use':
35
- return {
36
- code: AuthErrorCode.EMAIL_ALREADY_IN_USE,
37
- message: 'This email is already registered.',
38
- originalError: error
39
- };
53
+ case 'auth/account-exists-with-different-credential':
54
+ return new EmailAlreadyInUseException(error);
40
55
 
56
+ // Weak Password
41
57
  case 'auth/weak-password':
42
- return {
43
- code: AuthErrorCode.WEAK_PASSWORD,
44
- message: 'Password is too weak. Please use a stronger password.',
45
- originalError: error
46
- };
58
+ return new WeakPasswordException(error);
59
+
60
+ // Token Expired
61
+ case 'auth/id-token-expired':
62
+ case 'auth/user-token-expired':
63
+ case ProviderErrorCodes.USER_TOKEN_EXPIRED:
64
+ return new TokenExpiredException(error);
47
65
 
66
+ // Network Error
48
67
  case 'auth/network-request-failed':
49
- return {
50
- code: AuthErrorCode.NETWORK_ERROR,
51
- message: 'Network error. Please check your connection.',
52
- originalError: error
53
- };
68
+ case 'auth/timeout':
69
+ return new NetworkException(error);
54
70
 
55
71
  // Google Sign-In Errors
72
+ case ProviderErrorCodes.GOOGLE_CANCELLED:
56
73
  case 'auth/popup-closed-by-user':
57
74
  case 'auth/cancelled-popup-request':
58
- return {
59
- code: AuthErrorCode.UNKNOWN,
60
- message: 'Sign-in was cancelled.',
61
- originalError: error
62
- };
75
+ return new GoogleSignInCancelledException(error);
63
76
 
64
- case 'auth/account-exists-with-different-credential':
65
- return {
66
- code: AuthErrorCode.EMAIL_ALREADY_IN_USE,
67
- message: 'An account already exists with this email using a different sign-in method.',
68
- originalError: error
69
- };
77
+ case ProviderErrorCodes.GOOGLE_PLAY_UNAVAILABLE:
78
+ return new GooglePlayServicesUnavailableException(error);
70
79
 
71
- case 'auth/invalid-credential':
72
- return {
73
- code: AuthErrorCode.INVALID_CREDENTIALS,
74
- message: 'The credential received is invalid. Please try again.',
75
- originalError: error
76
- };
77
-
78
- case 'auth/operation-not-allowed':
79
- return {
80
- code: AuthErrorCode.UNKNOWN,
81
- message: 'This sign-in method is not enabled. Please contact support.',
82
- originalError: error
83
- };
80
+ // Apple Sign-In Errors
81
+ case ProviderErrorCodes.APPLE_CANCELLED:
82
+ return new AppleSignInCancelledException(error);
84
83
 
85
- case 'auth/user-disabled':
86
- return {
87
- code: AuthErrorCode.INVALID_CREDENTIALS,
88
- message: 'This account has been disabled.',
89
- originalError: error
90
- };
84
+ case ProviderErrorCodes.APPLE_NOT_SUPPORTED:
85
+ return new AppleSignInNotSupportedException(error);
91
86
 
92
- // Apple Sign-In Errors
93
- case 'auth/invalid-verification-code':
94
- case 'auth/invalid-verification-id':
95
- return {
96
- code: AuthErrorCode.INVALID_CREDENTIALS,
97
- message: 'The verification code is invalid. Please try again.',
98
- originalError: error
99
- };
100
-
101
- // Token Expiration
102
- case 'auth/id-token-expired':
103
- case 'auth/user-token-expired':
104
- return {
105
- code: AuthErrorCode.TOKEN_EXPIRED,
106
- message: 'Your session has expired. Please sign in again.',
107
- originalError: error
108
- };
87
+ // Configuration Errors
88
+ case 'auth/operation-not-allowed':
89
+ return new ConfigurationException(
90
+ 'This sign-in method is not enabled. Please check your Firebase configuration.',
91
+ error
92
+ );
109
93
 
110
- // OAuth-Specific Errors
111
94
  case 'auth/unauthorized-domain':
112
- return {
113
- code: AuthErrorCode.UNKNOWN,
114
- message: 'This domain is not authorized for OAuth operations.',
115
- originalError: error
116
- };
95
+ return new ConfigurationException(
96
+ 'This domain is not authorized for OAuth operations.',
97
+ error
98
+ );
117
99
 
118
100
  case 'auth/invalid-oauth-provider':
119
- return {
120
- code: AuthErrorCode.UNKNOWN,
121
- message: 'The OAuth provider configuration is invalid.',
122
- originalError: error
123
- };
124
-
125
101
  case 'auth/invalid-oauth-client-id':
126
- return {
127
- code: AuthErrorCode.UNKNOWN,
128
- message: 'The OAuth client ID is invalid.',
129
- originalError: error
130
- };
102
+ return new ConfigurationException(
103
+ 'The OAuth configuration is invalid.',
104
+ error
105
+ );
131
106
 
107
+ // Default
132
108
  default:
133
- return {
134
- code: AuthErrorCode.UNKNOWN,
135
- message: fbError.message || 'An unknown error occurred.',
136
- originalError: error
137
- };
109
+ return new UnknownAuthException(
110
+ fbError.message || 'An unknown error occurred.',
111
+ error
112
+ );
113
+ }
114
+ };
115
+
116
+ /**
117
+ * Helper function to check if an error is a specific exception type
118
+ */
119
+ export const isAuthException = (error: any, exceptionType: new (...args: any[]) => AuthException): boolean => {
120
+ return error instanceof exceptionType;
121
+ };
122
+
123
+ /**
124
+ * Helper to extract user-friendly message from any error
125
+ */
126
+ export const getErrorMessage = (error: any): string => {
127
+ if (error instanceof AuthException) {
128
+ return error.message;
138
129
  }
130
+ return error?.message || 'An unexpected error occurred';
139
131
  };
@@ -0,0 +1,174 @@
1
+ export class AuthException extends Error {
2
+ public readonly code: string;
3
+ public readonly originalError?: any;
4
+ public readonly timestamp: Date;
5
+
6
+ constructor(message: string, code: string, originalError?: any) {
7
+ super(message);
8
+ this.name = this.constructor.name;
9
+ this.code = code;
10
+ this.originalError = originalError;
11
+ this.timestamp = new Date();
12
+
13
+ if (Error.captureStackTrace) {
14
+ Error.captureStackTrace(this, this.constructor);
15
+ }
16
+
17
+ Object.setPrototypeOf(this, new.target.prototype);
18
+ }
19
+
20
+ toJSON() {
21
+ return {
22
+ name: this.name,
23
+ code: this.code,
24
+ message: this.message,
25
+ timestamp: this.timestamp.toISOString(),
26
+ originalError: this.originalError?.code || this.originalError?.message,
27
+ };
28
+ }
29
+ }
30
+
31
+ export class InvalidCredentialsException extends AuthException {
32
+ constructor(originalError?: any) {
33
+ super(
34
+ 'Invalid email or password. Please check your credentials and try again.',
35
+ 'auth/invalid-credentials',
36
+ originalError
37
+ );
38
+ }
39
+ }
40
+
41
+ /**
42
+ * Thrown when user account does not exist
43
+ */
44
+ export class UserNotFoundException extends AuthException {
45
+ constructor(originalError?: any) {
46
+ super(
47
+ 'No account found with this email. Please sign up first.',
48
+ 'auth/user-not-found',
49
+ originalError
50
+ );
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Thrown when attempting to sign up with an email that's already registered
56
+ */
57
+ export class EmailAlreadyInUseException extends AuthException {
58
+ constructor(originalError?: any) {
59
+ super(
60
+ 'This email is already registered. Please sign in or use a different email.',
61
+ 'auth/email-already-in-use',
62
+ originalError
63
+ );
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Thrown when password doesn't meet minimum security requirements
69
+ */
70
+ export class WeakPasswordException extends AuthException {
71
+ constructor(originalError?: any) {
72
+ super(
73
+ 'Password is too weak. Please use at least 6 characters with a mix of letters and numbers.',
74
+ 'auth/weak-password',
75
+ originalError
76
+ );
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Thrown when user's authentication token has expired
82
+ */
83
+ export class TokenExpiredException extends AuthException {
84
+ constructor(originalError?: any) {
85
+ super(
86
+ 'Your session has expired. Please sign in again.',
87
+ 'auth/token-expired',
88
+ originalError
89
+ );
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Thrown when network connectivity issues occur
95
+ */
96
+ export class NetworkException extends AuthException {
97
+ constructor(originalError?: any) {
98
+ super(
99
+ 'Network error. Please check your internet connection and try again.',
100
+ 'auth/network-error',
101
+ originalError
102
+ );
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Thrown when Google Sign-In is cancelled by user
108
+ */
109
+ export class GoogleSignInCancelledException extends AuthException {
110
+ constructor(originalError?: any) {
111
+ super(
112
+ 'Google Sign-In was cancelled.',
113
+ 'auth/google-sign-in-cancelled',
114
+ originalError
115
+ );
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Thrown when Apple Sign-In is cancelled by user
121
+ */
122
+ export class AppleSignInCancelledException extends AuthException {
123
+ constructor(originalError?: any) {
124
+ super(
125
+ 'Apple Sign-In was cancelled.',
126
+ 'auth/apple-sign-in-cancelled',
127
+ originalError
128
+ );
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Thrown when Apple Sign-In is not supported on the device
134
+ */
135
+ export class AppleSignInNotSupportedException extends AuthException {
136
+ constructor(originalError?: any) {
137
+ super(
138
+ 'Apple Sign-In is only available on iOS 13+ devices.',
139
+ 'auth/apple-sign-in-not-supported',
140
+ originalError
141
+ );
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Thrown when Google Play Services are not available
147
+ */
148
+ export class GooglePlayServicesUnavailableException extends AuthException {
149
+ constructor(originalError?: any) {
150
+ super(
151
+ 'Google Play Services are not available. Please update Google Play Services.',
152
+ 'auth/google-play-services-unavailable',
153
+ originalError
154
+ );
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Thrown for configuration errors
160
+ */
161
+ export class ConfigurationException extends AuthException {
162
+ constructor(message: string, originalError?: any) {
163
+ super(message, 'auth/configuration-error', originalError);
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Generic unknown error
169
+ */
170
+ export class UnknownAuthException extends AuthException {
171
+ constructor(message: string = 'An unexpected error occurred.', originalError?: any) {
172
+ super(message, 'auth/unknown', originalError);
173
+ }
174
+ }
@@ -1 +1,22 @@
1
- export * from './errorMapper';
1
+
2
+ export {
3
+ AuthException,
4
+ InvalidCredentialsException,
5
+ UserNotFoundException,
6
+ EmailAlreadyInUseException,
7
+ WeakPasswordException,
8
+ TokenExpiredException,
9
+ NetworkException,
10
+ GoogleSignInCancelledException,
11
+ AppleSignInCancelledException,
12
+ AppleSignInNotSupportedException,
13
+ GooglePlayServicesUnavailableException,
14
+ ConfigurationException,
15
+ UnknownAuthException,
16
+ } from './exceptions';
17
+
18
+ export {
19
+ mapFirebaseError,
20
+ isAuthException,
21
+ getErrorMessage,
22
+ } from './errorMapper';
@@ -1,5 +1,5 @@
1
1
  import { AuthConfig } from './config.types';
2
- import { AuthError } from './error.types';
2
+ import { AuthException } from '../errors';
3
3
 
4
4
  export enum AuthStatus {
5
5
  AUTHENTICATED = 'AUTHENTICATED',
@@ -32,13 +32,13 @@ export interface AuthContextType {
32
32
  user: User | null;
33
33
  status: AuthStatus;
34
34
  isLoading: boolean;
35
- error: AuthError | null; // ✅ Uses the type imported from error.types.ts
35
+ error: AuthException | null;
36
36
  config: AuthConfig;
37
37
 
38
38
  // Function Signatures
39
39
  signInWithEmail: (options: EmailSignInOptions) => Promise<void>;
40
40
  signUpWithEmail: (options: EmailSignUpOptions) => Promise<void>;
41
-
41
+ sendPasswordReset: (email: string) => Promise<void>;
42
42
  signInWithGoogle: () => Promise<void>;
43
43
  signInWithApple: () => Promise<void>;
44
44
  signOut: () => Promise<void>;
@@ -1,50 +1,58 @@
1
- // src/types/error.types.ts
2
-
3
- // ✅ 1. Define Known Error Codes (Source of Truth)
4
1
  export enum ProviderErrorCodes {
5
2
  // Firebase specific
6
3
  USER_TOKEN_EXPIRED = 'auth/user-token-expired',
7
4
  NULL_USER = 'auth/null-user',
8
-
5
+
9
6
  // Google specific
10
7
  GOOGLE_CANCELLED = 'SIGN_IN_CANCELLED',
11
8
  GOOGLE_IN_PROGRESS = 'IN_PROGRESS',
12
9
  GOOGLE_PLAY_UNAVAILABLE = 'PLAY_SERVICES_NOT_AVAILABLE',
13
-
10
+
14
11
  // Apple specific
15
12
  APPLE_CANCELLED = 'ERR_REQUEST_CANCELED',
16
13
  APPLE_NOT_SUPPORTED = 'APPLE_SIGN_IN_NOT_SUPPORTED'
17
14
  }
18
15
 
19
- // Legacy error codes used in mapping (Keep this for backward compatibility if needed)
16
+ // Standardized error codes (used by custom exceptions)
20
17
  export enum AuthErrorCode {
18
+ // Core authentication errors
21
19
  INVALID_CREDENTIALS = 'auth/invalid-credentials',
22
20
  USER_NOT_FOUND = 'auth/user-not-found',
23
21
  EMAIL_ALREADY_IN_USE = 'auth/email-already-in-use',
24
22
  WEAK_PASSWORD = 'auth/weak-password',
25
23
  TOKEN_EXPIRED = 'auth/token-expired',
26
- NETWORK_ERROR = 'auth/network-request-failed',
24
+ NETWORK_ERROR = 'auth/network-error',
27
25
  UNKNOWN = 'auth/unknown',
28
- // Specific to SDK flow
26
+
27
+ // Configuration errors
29
28
  CONFIG_ERROR = 'auth/configuration-error',
29
+
30
+ // User actions
30
31
  CANCELLED = 'auth/cancelled',
31
32
 
32
- // Google Sign-In Errors
33
- GOOGLE_SIGN_IN_CANCELLED = 'GOOGLE_SIGN_IN_CANCELLED',
34
- GOOGLE_SIGN_IN_IN_PROGRESS = 'GOOGLE_SIGN_IN_IN_PROGRESS',
35
- GOOGLE_PLAY_SERVICES_NOT_AVAILABLE = 'GOOGLE_PLAY_SERVICES_NOT_AVAILABLE',
36
- GOOGLE_SIGN_IN_FAILED = 'GOOGLE_SIGN_IN_FAILED',
33
+ // Google Sign-In errors
34
+ GOOGLE_SIGN_IN_CANCELLED = 'auth/google-sign-in-cancelled',
35
+ GOOGLE_SIGN_IN_IN_PROGRESS = 'auth/google-sign-in-in-progress',
36
+ GOOGLE_PLAY_SERVICES_NOT_AVAILABLE = 'auth/google-play-services-unavailable',
37
+ GOOGLE_SIGN_IN_FAILED = 'auth/google-sign-in-failed',
37
38
 
38
- // Apple Sign-In Errors
39
- APPLE_SIGN_IN_CANCELLED = 'APPLE_SIGN_IN_CANCELLED',
40
- APPLE_SIGN_IN_FAILED = 'APPLE_SIGN_IN_FAILED',
41
- APPLE_SIGN_IN_NOT_SUPPORTED = 'APPLE_SIGN_IN_NOT_SUPPORTED',
39
+ // Apple Sign-In errors
40
+ APPLE_SIGN_IN_CANCELLED = 'auth/apple-sign-in-cancelled',
41
+ APPLE_SIGN_IN_FAILED = 'auth/apple-sign-in-failed',
42
+ APPLE_SIGN_IN_NOT_SUPPORTED = 'auth/apple-sign-in-not-supported',
42
43
  }
43
44
 
44
- // ✅ 2. Strong Typing for Error Objects
45
- // We allow 'code' to be either our new Enum or the legacy Enum
46
45
  export interface AuthError {
47
46
  code: string | ProviderErrorCodes | AuthErrorCode;
48
47
  message: string;
49
- originalError?: any; // To store the raw Firebase error for debugging
50
- }
48
+ originalError?: any;
49
+ }
50
+
51
+ export const isAuthError = (error: any): error is AuthError => {
52
+ return (
53
+ error &&
54
+ typeof error === 'object' &&
55
+ 'code' in error &&
56
+ 'message' in error
57
+ );
58
+ };