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.
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UnknownAuthException = exports.ConfigurationException = exports.GooglePlayServicesUnavailableException = exports.AppleSignInNotSupportedException = exports.AppleSignInCancelledException = exports.GoogleSignInCancelledException = exports.NetworkException = exports.TokenExpiredException = exports.WeakPasswordException = exports.EmailAlreadyInUseException = exports.UserNotFoundException = exports.InvalidCredentialsException = exports.AuthException = void 0;
4
+ class AuthException extends Error {
5
+ code;
6
+ originalError;
7
+ timestamp;
8
+ constructor(message, code, originalError) {
9
+ super(message);
10
+ this.name = this.constructor.name;
11
+ this.code = code;
12
+ this.originalError = originalError;
13
+ this.timestamp = new Date();
14
+ if (Error.captureStackTrace) {
15
+ Error.captureStackTrace(this, this.constructor);
16
+ }
17
+ Object.setPrototypeOf(this, new.target.prototype);
18
+ }
19
+ toJSON() {
20
+ return {
21
+ name: this.name,
22
+ code: this.code,
23
+ message: this.message,
24
+ timestamp: this.timestamp.toISOString(),
25
+ originalError: this.originalError?.code || this.originalError?.message,
26
+ };
27
+ }
28
+ }
29
+ exports.AuthException = AuthException;
30
+ class InvalidCredentialsException extends AuthException {
31
+ constructor(originalError) {
32
+ super('Invalid email or password. Please check your credentials and try again.', 'auth/invalid-credentials', originalError);
33
+ }
34
+ }
35
+ exports.InvalidCredentialsException = InvalidCredentialsException;
36
+ /**
37
+ * Thrown when user account does not exist
38
+ */
39
+ class UserNotFoundException extends AuthException {
40
+ constructor(originalError) {
41
+ super('No account found with this email. Please sign up first.', 'auth/user-not-found', originalError);
42
+ }
43
+ }
44
+ exports.UserNotFoundException = UserNotFoundException;
45
+ /**
46
+ * Thrown when attempting to sign up with an email that's already registered
47
+ */
48
+ class EmailAlreadyInUseException extends AuthException {
49
+ constructor(originalError) {
50
+ super('This email is already registered. Please sign in or use a different email.', 'auth/email-already-in-use', originalError);
51
+ }
52
+ }
53
+ exports.EmailAlreadyInUseException = EmailAlreadyInUseException;
54
+ /**
55
+ * Thrown when password doesn't meet minimum security requirements
56
+ */
57
+ class WeakPasswordException extends AuthException {
58
+ constructor(originalError) {
59
+ super('Password is too weak. Please use at least 6 characters with a mix of letters and numbers.', 'auth/weak-password', originalError);
60
+ }
61
+ }
62
+ exports.WeakPasswordException = WeakPasswordException;
63
+ /**
64
+ * Thrown when user's authentication token has expired
65
+ */
66
+ class TokenExpiredException extends AuthException {
67
+ constructor(originalError) {
68
+ super('Your session has expired. Please sign in again.', 'auth/token-expired', originalError);
69
+ }
70
+ }
71
+ exports.TokenExpiredException = TokenExpiredException;
72
+ /**
73
+ * Thrown when network connectivity issues occur
74
+ */
75
+ class NetworkException extends AuthException {
76
+ constructor(originalError) {
77
+ super('Network error. Please check your internet connection and try again.', 'auth/network-error', originalError);
78
+ }
79
+ }
80
+ exports.NetworkException = NetworkException;
81
+ /**
82
+ * Thrown when Google Sign-In is cancelled by user
83
+ */
84
+ class GoogleSignInCancelledException extends AuthException {
85
+ constructor(originalError) {
86
+ super('Google Sign-In was cancelled.', 'auth/google-sign-in-cancelled', originalError);
87
+ }
88
+ }
89
+ exports.GoogleSignInCancelledException = GoogleSignInCancelledException;
90
+ /**
91
+ * Thrown when Apple Sign-In is cancelled by user
92
+ */
93
+ class AppleSignInCancelledException extends AuthException {
94
+ constructor(originalError) {
95
+ super('Apple Sign-In was cancelled.', 'auth/apple-sign-in-cancelled', originalError);
96
+ }
97
+ }
98
+ exports.AppleSignInCancelledException = AppleSignInCancelledException;
99
+ /**
100
+ * Thrown when Apple Sign-In is not supported on the device
101
+ */
102
+ class AppleSignInNotSupportedException extends AuthException {
103
+ constructor(originalError) {
104
+ super('Apple Sign-In is only available on iOS 13+ devices.', 'auth/apple-sign-in-not-supported', originalError);
105
+ }
106
+ }
107
+ exports.AppleSignInNotSupportedException = AppleSignInNotSupportedException;
108
+ /**
109
+ * Thrown when Google Play Services are not available
110
+ */
111
+ class GooglePlayServicesUnavailableException extends AuthException {
112
+ constructor(originalError) {
113
+ super('Google Play Services are not available. Please update Google Play Services.', 'auth/google-play-services-unavailable', originalError);
114
+ }
115
+ }
116
+ exports.GooglePlayServicesUnavailableException = GooglePlayServicesUnavailableException;
117
+ /**
118
+ * Thrown for configuration errors
119
+ */
120
+ class ConfigurationException extends AuthException {
121
+ constructor(message, originalError) {
122
+ super(message, 'auth/configuration-error', originalError);
123
+ }
124
+ }
125
+ exports.ConfigurationException = ConfigurationException;
126
+ /**
127
+ * Generic unknown error
128
+ */
129
+ class UnknownAuthException extends AuthException {
130
+ constructor(message = 'An unexpected error occurred.', originalError) {
131
+ super(message, 'auth/unknown', originalError);
132
+ }
133
+ }
134
+ exports.UnknownAuthException = UnknownAuthException;
@@ -1 +1,2 @@
1
- export * from './errorMapper';
1
+ export { AuthException, InvalidCredentialsException, UserNotFoundException, EmailAlreadyInUseException, WeakPasswordException, TokenExpiredException, NetworkException, GoogleSignInCancelledException, AppleSignInCancelledException, AppleSignInNotSupportedException, GooglePlayServicesUnavailableException, ConfigurationException, UnknownAuthException, } from './exceptions';
2
+ export { mapFirebaseError, isAuthException, getErrorMessage, } from './errorMapper';
@@ -1,17 +1,21 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
2
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./errorMapper"), exports);
3
+ exports.getErrorMessage = exports.isAuthException = exports.mapFirebaseError = exports.UnknownAuthException = exports.ConfigurationException = exports.GooglePlayServicesUnavailableException = exports.AppleSignInNotSupportedException = exports.AppleSignInCancelledException = exports.GoogleSignInCancelledException = exports.NetworkException = exports.TokenExpiredException = exports.WeakPasswordException = exports.EmailAlreadyInUseException = exports.UserNotFoundException = exports.InvalidCredentialsException = exports.AuthException = void 0;
4
+ var exceptions_1 = require("./exceptions");
5
+ Object.defineProperty(exports, "AuthException", { enumerable: true, get: function () { return exceptions_1.AuthException; } });
6
+ Object.defineProperty(exports, "InvalidCredentialsException", { enumerable: true, get: function () { return exceptions_1.InvalidCredentialsException; } });
7
+ Object.defineProperty(exports, "UserNotFoundException", { enumerable: true, get: function () { return exceptions_1.UserNotFoundException; } });
8
+ Object.defineProperty(exports, "EmailAlreadyInUseException", { enumerable: true, get: function () { return exceptions_1.EmailAlreadyInUseException; } });
9
+ Object.defineProperty(exports, "WeakPasswordException", { enumerable: true, get: function () { return exceptions_1.WeakPasswordException; } });
10
+ Object.defineProperty(exports, "TokenExpiredException", { enumerable: true, get: function () { return exceptions_1.TokenExpiredException; } });
11
+ Object.defineProperty(exports, "NetworkException", { enumerable: true, get: function () { return exceptions_1.NetworkException; } });
12
+ Object.defineProperty(exports, "GoogleSignInCancelledException", { enumerable: true, get: function () { return exceptions_1.GoogleSignInCancelledException; } });
13
+ Object.defineProperty(exports, "AppleSignInCancelledException", { enumerable: true, get: function () { return exceptions_1.AppleSignInCancelledException; } });
14
+ Object.defineProperty(exports, "AppleSignInNotSupportedException", { enumerable: true, get: function () { return exceptions_1.AppleSignInNotSupportedException; } });
15
+ Object.defineProperty(exports, "GooglePlayServicesUnavailableException", { enumerable: true, get: function () { return exceptions_1.GooglePlayServicesUnavailableException; } });
16
+ Object.defineProperty(exports, "ConfigurationException", { enumerable: true, get: function () { return exceptions_1.ConfigurationException; } });
17
+ Object.defineProperty(exports, "UnknownAuthException", { enumerable: true, get: function () { return exceptions_1.UnknownAuthException; } });
18
+ var errorMapper_1 = require("./errorMapper");
19
+ Object.defineProperty(exports, "mapFirebaseError", { enumerable: true, get: function () { return errorMapper_1.mapFirebaseError; } });
20
+ Object.defineProperty(exports, "isAuthException", { enumerable: true, get: function () { return errorMapper_1.isAuthException; } });
21
+ Object.defineProperty(exports, "getErrorMessage", { enumerable: true, get: function () { return errorMapper_1.getErrorMessage; } });
@@ -1,5 +1,5 @@
1
1
  import { AuthConfig } from './config.types';
2
- import { AuthError } from './error.types';
2
+ import { AuthException } from '../errors';
3
3
  export declare enum AuthStatus {
4
4
  AUTHENTICATED = "AUTHENTICATED",
5
5
  UNAUTHENTICATED = "UNAUTHENTICATED",
@@ -26,7 +26,7 @@ export interface AuthContextType {
26
26
  user: User | null;
27
27
  status: AuthStatus;
28
28
  isLoading: boolean;
29
- error: AuthError | null;
29
+ error: AuthException | null;
30
30
  config: AuthConfig;
31
31
  signInWithEmail: (options: EmailSignInOptions) => Promise<void>;
32
32
  signUpWithEmail: (options: EmailSignUpOptions) => Promise<void>;
@@ -13,20 +13,21 @@ export declare enum AuthErrorCode {
13
13
  EMAIL_ALREADY_IN_USE = "auth/email-already-in-use",
14
14
  WEAK_PASSWORD = "auth/weak-password",
15
15
  TOKEN_EXPIRED = "auth/token-expired",
16
- NETWORK_ERROR = "auth/network-request-failed",
16
+ NETWORK_ERROR = "auth/network-error",
17
17
  UNKNOWN = "auth/unknown",
18
18
  CONFIG_ERROR = "auth/configuration-error",
19
19
  CANCELLED = "auth/cancelled",
20
- GOOGLE_SIGN_IN_CANCELLED = "GOOGLE_SIGN_IN_CANCELLED",
21
- GOOGLE_SIGN_IN_IN_PROGRESS = "GOOGLE_SIGN_IN_IN_PROGRESS",
22
- GOOGLE_PLAY_SERVICES_NOT_AVAILABLE = "GOOGLE_PLAY_SERVICES_NOT_AVAILABLE",
23
- GOOGLE_SIGN_IN_FAILED = "GOOGLE_SIGN_IN_FAILED",
24
- APPLE_SIGN_IN_CANCELLED = "APPLE_SIGN_IN_CANCELLED",
25
- APPLE_SIGN_IN_FAILED = "APPLE_SIGN_IN_FAILED",
26
- APPLE_SIGN_IN_NOT_SUPPORTED = "APPLE_SIGN_IN_NOT_SUPPORTED"
20
+ GOOGLE_SIGN_IN_CANCELLED = "auth/google-sign-in-cancelled",
21
+ GOOGLE_SIGN_IN_IN_PROGRESS = "auth/google-sign-in-in-progress",
22
+ GOOGLE_PLAY_SERVICES_NOT_AVAILABLE = "auth/google-play-services-unavailable",
23
+ GOOGLE_SIGN_IN_FAILED = "auth/google-sign-in-failed",
24
+ APPLE_SIGN_IN_CANCELLED = "auth/apple-sign-in-cancelled",
25
+ APPLE_SIGN_IN_FAILED = "auth/apple-sign-in-failed",
26
+ APPLE_SIGN_IN_NOT_SUPPORTED = "auth/apple-sign-in-not-supported"
27
27
  }
28
28
  export interface AuthError {
29
29
  code: string | ProviderErrorCodes | AuthErrorCode;
30
30
  message: string;
31
31
  originalError?: any;
32
32
  }
33
+ export declare const isAuthError: (error: any) => error is AuthError;
@@ -1,8 +1,6 @@
1
1
  "use strict";
2
- // src/types/error.types.ts
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.AuthErrorCode = exports.ProviderErrorCodes = void 0;
5
- // ✅ 1. Define Known Error Codes (Source of Truth)
3
+ exports.isAuthError = exports.AuthErrorCode = exports.ProviderErrorCodes = void 0;
6
4
  var ProviderErrorCodes;
7
5
  (function (ProviderErrorCodes) {
8
6
  // Firebase specific
@@ -16,26 +14,35 @@ var ProviderErrorCodes;
16
14
  ProviderErrorCodes["APPLE_CANCELLED"] = "ERR_REQUEST_CANCELED";
17
15
  ProviderErrorCodes["APPLE_NOT_SUPPORTED"] = "APPLE_SIGN_IN_NOT_SUPPORTED";
18
16
  })(ProviderErrorCodes || (exports.ProviderErrorCodes = ProviderErrorCodes = {}));
19
- // Legacy error codes used in mapping (Keep this for backward compatibility if needed)
17
+ // Standardized error codes (used by custom exceptions)
20
18
  var AuthErrorCode;
21
19
  (function (AuthErrorCode) {
20
+ // Core authentication errors
22
21
  AuthErrorCode["INVALID_CREDENTIALS"] = "auth/invalid-credentials";
23
22
  AuthErrorCode["USER_NOT_FOUND"] = "auth/user-not-found";
24
23
  AuthErrorCode["EMAIL_ALREADY_IN_USE"] = "auth/email-already-in-use";
25
24
  AuthErrorCode["WEAK_PASSWORD"] = "auth/weak-password";
26
25
  AuthErrorCode["TOKEN_EXPIRED"] = "auth/token-expired";
27
- AuthErrorCode["NETWORK_ERROR"] = "auth/network-request-failed";
26
+ AuthErrorCode["NETWORK_ERROR"] = "auth/network-error";
28
27
  AuthErrorCode["UNKNOWN"] = "auth/unknown";
29
- // Specific to SDK flow
28
+ // Configuration errors
30
29
  AuthErrorCode["CONFIG_ERROR"] = "auth/configuration-error";
30
+ // User actions
31
31
  AuthErrorCode["CANCELLED"] = "auth/cancelled";
32
- // Google Sign-In Errors
33
- AuthErrorCode["GOOGLE_SIGN_IN_CANCELLED"] = "GOOGLE_SIGN_IN_CANCELLED";
34
- AuthErrorCode["GOOGLE_SIGN_IN_IN_PROGRESS"] = "GOOGLE_SIGN_IN_IN_PROGRESS";
35
- AuthErrorCode["GOOGLE_PLAY_SERVICES_NOT_AVAILABLE"] = "GOOGLE_PLAY_SERVICES_NOT_AVAILABLE";
36
- AuthErrorCode["GOOGLE_SIGN_IN_FAILED"] = "GOOGLE_SIGN_IN_FAILED";
37
- // Apple Sign-In Errors
38
- AuthErrorCode["APPLE_SIGN_IN_CANCELLED"] = "APPLE_SIGN_IN_CANCELLED";
39
- AuthErrorCode["APPLE_SIGN_IN_FAILED"] = "APPLE_SIGN_IN_FAILED";
40
- AuthErrorCode["APPLE_SIGN_IN_NOT_SUPPORTED"] = "APPLE_SIGN_IN_NOT_SUPPORTED";
32
+ // Google Sign-In errors
33
+ AuthErrorCode["GOOGLE_SIGN_IN_CANCELLED"] = "auth/google-sign-in-cancelled";
34
+ AuthErrorCode["GOOGLE_SIGN_IN_IN_PROGRESS"] = "auth/google-sign-in-in-progress";
35
+ AuthErrorCode["GOOGLE_PLAY_SERVICES_NOT_AVAILABLE"] = "auth/google-play-services-unavailable";
36
+ AuthErrorCode["GOOGLE_SIGN_IN_FAILED"] = "auth/google-sign-in-failed";
37
+ // Apple Sign-In errors
38
+ AuthErrorCode["APPLE_SIGN_IN_CANCELLED"] = "auth/apple-sign-in-cancelled";
39
+ AuthErrorCode["APPLE_SIGN_IN_FAILED"] = "auth/apple-sign-in-failed";
40
+ AuthErrorCode["APPLE_SIGN_IN_NOT_SUPPORTED"] = "auth/apple-sign-in-not-supported";
41
41
  })(AuthErrorCode || (exports.AuthErrorCode = AuthErrorCode = {}));
42
+ const isAuthError = (error) => {
43
+ return (error &&
44
+ typeof error === 'object' &&
45
+ 'code' in error &&
46
+ 'message' in error);
47
+ };
48
+ exports.isAuthError = isAuthError;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rn-swiftauth-sdk",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
@@ -6,18 +6,24 @@ import ReactNativeAsyncStorage from '@react-native-async-storage/async-storage';
6
6
  import { GoogleSignin } from '@react-native-google-signin/google-signin';
7
7
  import * as AppleAuthentication from 'expo-apple-authentication';
8
8
  import * as Crypto from 'expo-crypto';
9
- import { mapFirebaseError } from '../errors';
9
+ import {
10
+ AuthException,
11
+ mapFirebaseError,
12
+ ConfigurationException,
13
+ AppleSignInNotSupportedException,
14
+ AppleSignInCancelledException,
15
+ GoogleSignInCancelledException,
16
+ } from '../errors';
10
17
  import { AuthContext } from './AuthContext';
11
- import {
12
- AuthConfig,
13
- AuthStatus,
14
- User,
15
- AuthError,
16
- AuthErrorCode,
17
- ProviderErrorCodes,
18
+ import {
19
+ AuthConfig,
20
+ AuthStatus,
21
+ User,
22
+ ProviderErrorCodes,
18
23
  EmailSignInOptions,
19
- EmailSignUpOptions
24
+ EmailSignUpOptions
20
25
  } from '../types';
26
+
21
27
  const getReactNativePersistence = (FirebaseAuth as any).getReactNativePersistence;
22
28
 
23
29
  interface AuthProviderProps {
@@ -28,7 +34,7 @@ interface AuthProviderProps {
28
34
  export const AuthProvider: React.FC<AuthProviderProps> = ({ config, children }) => {
29
35
  const [user, setUser] = useState<User | null>(null);
30
36
  const [status, setStatus] = useState<AuthStatus>(AuthStatus.LOADING);
31
- const [error, setError] = useState<AuthError | null>(null);
37
+ const [error, setError] = useState<AuthException | null>(null);
32
38
  const [firebaseAuthInstance, setFirebaseAuthInstance] = useState<FirebaseAuth.Auth | null>(null);
33
39
  const [isDataLoading, setIsDataLoading] = useState(true);
34
40
 
@@ -47,8 +53,8 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ config, children })
47
53
  appId: config.appId,
48
54
  });
49
55
 
50
- const selectedPersistence = config.persistence === 'memory'
51
- ? FirebaseAuth.inMemoryPersistence
56
+ const selectedPersistence = config.persistence === 'memory'
57
+ ? FirebaseAuth.inMemoryPersistence
52
58
  : getReactNativePersistence(ReactNativeAsyncStorage);
53
59
 
54
60
  auth = FirebaseAuth.initializeAuth(app, {
@@ -66,7 +72,7 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ config, children })
66
72
  GoogleSignin.configure({
67
73
  webClientId: config.googleWebClientId,
68
74
  offlineAccess: true,
69
- iosClientId: config.googleIOSClientId,
75
+ iosClientId: config.googleIOSClientId,
70
76
  });
71
77
  console.log('Google Sign-In configured successfully');
72
78
  } catch (err) {
@@ -90,11 +96,13 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ config, children })
90
96
  setStatus(AuthStatus.AUTHENTICATED);
91
97
  } catch (tokenError: any) {
92
98
  console.error('Token retrieval error:', tokenError);
93
- if (tokenError.code === ProviderErrorCodes.USER_TOKEN_EXPIRED ||
99
+ if (tokenError.code === ProviderErrorCodes.USER_TOKEN_EXPIRED ||
94
100
  tokenError.code === ProviderErrorCodes.NULL_USER) {
95
101
  setStatus(AuthStatus.TOKEN_EXPIRED);
102
+ setError(mapFirebaseError(tokenError));
96
103
  } else {
97
104
  setStatus(AuthStatus.UNAUTHENTICATED);
105
+ setError(mapFirebaseError(tokenError));
98
106
  }
99
107
  setUser(null);
100
108
  }
@@ -105,6 +113,7 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ config, children })
105
113
  } catch (err) {
106
114
  console.error("Auth State Error:", err);
107
115
  setStatus(AuthStatus.UNAUTHENTICATED);
116
+ setError(mapFirebaseError(err));
108
117
  } finally {
109
118
  setIsDataLoading(false);
110
119
  }
@@ -122,10 +131,10 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ config, children })
122
131
  setStatus(AuthStatus.LOADING);
123
132
  await FirebaseAuth.signInWithEmailAndPassword(firebaseAuthInstance, email, password);
124
133
  } catch (err: any) {
125
- const mapped = mapFirebaseError(err);
126
- setError({ ...mapped, originalError: err });
134
+ const mappedException = mapFirebaseError(err);
135
+ setError(mappedException);
127
136
  setStatus(AuthStatus.UNAUTHENTICATED);
128
- throw err;
137
+ throw mappedException;
129
138
  }
130
139
  };
131
140
 
@@ -136,18 +145,21 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ config, children })
136
145
  setStatus(AuthStatus.LOADING);
137
146
  await FirebaseAuth.createUserWithEmailAndPassword(firebaseAuthInstance, email, password);
138
147
  } catch (err: any) {
139
- const mapped = mapFirebaseError(err);
140
- setError({ ...mapped, originalError: err });
148
+ const mappedException = mapFirebaseError(err);
149
+ setError(mappedException);
141
150
  setStatus(AuthStatus.UNAUTHENTICATED);
142
- throw err;
151
+ throw mappedException;
143
152
  }
144
153
  };
145
154
 
146
155
  const signInWithGoogle = async () => {
147
156
  if (!firebaseAuthInstance) throw new Error('Firebase not initialized');
148
157
  if (!config.enableGoogle || !config.googleWebClientId) {
149
- setError({ code: AuthErrorCode.CONFIG_ERROR, message: 'Google Auth not configured. Missing googleWebClientId.' });
150
- return;
158
+ const configError = new ConfigurationException(
159
+ 'Google Auth not configured. Missing googleWebClientId.'
160
+ );
161
+ setError(configError);
162
+ throw configError;
151
163
  }
152
164
 
153
165
  try {
@@ -166,56 +178,33 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ config, children })
166
178
 
167
179
  } catch (err: any) {
168
180
  console.error('Google Sign-In Error:', err);
169
- let mappedError: AuthError;
170
181
 
171
182
  if (err.code === ProviderErrorCodes.GOOGLE_CANCELLED) {
172
- mappedError = {
173
- code: AuthErrorCode.GOOGLE_SIGN_IN_CANCELLED,
174
- message: 'Google Sign-In was cancelled',
175
- originalError: err
176
- };
177
- setStatus(AuthStatus.UNAUTHENTICATED);
178
- return;
179
- } else if (err.code === ProviderErrorCodes.GOOGLE_IN_PROGRESS) {
180
- mappedError = {
181
- code: AuthErrorCode.GOOGLE_SIGN_IN_IN_PROGRESS,
182
- message: 'Google Sign-In is already in progress',
183
- originalError: err
184
- };
185
- } else if (err.code === ProviderErrorCodes.GOOGLE_PLAY_UNAVAILABLE) {
186
- mappedError = {
187
- code: AuthErrorCode.GOOGLE_PLAY_SERVICES_NOT_AVAILABLE,
188
- message: 'Google Play Services are not available. Please update Google Play Services.',
189
- originalError: err
190
- };
191
- } else {
192
- mappedError = mapFirebaseError(err);
183
+ const cancelError = new GoogleSignInCancelledException(err);
184
+ setError(cancelError);
185
+ setStatus(AuthStatus.UNAUTHENTICATED);
186
+ return;
193
187
  }
194
188
 
195
- setError({ ...mappedError, originalError: err });
189
+ const mappedException = mapFirebaseError(err);
190
+ setError(mappedException);
196
191
  setStatus(AuthStatus.UNAUTHENTICATED);
197
- throw mappedError;
192
+ throw mappedException;
198
193
  }
199
194
  };
200
195
 
201
196
  const signInWithApple = async () => {
202
197
  if (!firebaseAuthInstance) throw new Error('Firebase not initialized');
203
-
198
+
204
199
  if (Platform.OS !== 'ios') {
205
- const platformError: AuthError = {
206
- code: AuthErrorCode.APPLE_SIGN_IN_NOT_SUPPORTED,
207
- message: 'Apple Sign-In is only available on iOS devices',
208
- };
200
+ const platformError = new AppleSignInNotSupportedException();
209
201
  setError(platformError);
210
202
  throw platformError;
211
203
  }
212
204
 
213
205
  const isAvailable = await AppleAuthentication.isAvailableAsync();
214
206
  if (!isAvailable) {
215
- const availabilityError: AuthError = {
216
- code: AuthErrorCode.APPLE_SIGN_IN_NOT_SUPPORTED,
217
- message: 'Apple Sign-In is not available on this device (requires iOS 13+)',
218
- };
207
+ const availabilityError = new AppleSignInNotSupportedException();
219
208
  setError(availabilityError);
220
209
  throw availabilityError;
221
210
  }
@@ -223,10 +212,10 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ config, children })
223
212
  try {
224
213
  setError(null);
225
214
  setStatus(AuthStatus.LOADING);
226
-
215
+
227
216
  const nonce = Math.random().toString(36).substring(2, 10);
228
217
  const hashedNonce = await Crypto.digestStringAsync(Crypto.CryptoDigestAlgorithm.SHA256, nonce);
229
-
218
+
230
219
  const appleCredential = await AppleAuthentication.signInAsync({
231
220
  requestedScopes: [
232
221
  AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
@@ -252,20 +241,16 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ config, children })
252
241
  console.error('Apple Sign-In Error:', err);
253
242
 
254
243
  if (err.code === ProviderErrorCodes.APPLE_CANCELLED) {
255
- const cancelError: AuthError = {
256
- code: AuthErrorCode.APPLE_SIGN_IN_CANCELLED,
257
- message: 'Apple Sign-In was cancelled',
258
- originalError: err
259
- };
244
+ const cancelError = new AppleSignInCancelledException(err);
260
245
  setError(cancelError);
261
246
  setStatus(AuthStatus.UNAUTHENTICATED);
262
247
  return;
263
248
  }
264
249
 
265
- const mappedError = mapFirebaseError(err);
266
- setError({ ...mappedError, originalError: err });
250
+ const mappedException = mapFirebaseError(err);
251
+ setError(mappedException);
267
252
  setStatus(AuthStatus.UNAUTHENTICATED);
268
- throw mappedError;
253
+ throw mappedException;
269
254
  }
270
255
  };
271
256
 
@@ -284,6 +269,8 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ config, children })
284
269
  console.log('Sign out successful');
285
270
  } catch (err) {
286
271
  console.error('Sign out error:', err);
272
+ const signOutError = mapFirebaseError(err);
273
+ setError(signOutError);
287
274
  setUser(null);
288
275
  setStatus(AuthStatus.UNAUTHENTICATED);
289
276
  }