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
|
@@ -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;
|
package/dist/errors/index.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { AuthException, InvalidCredentialsException, UserNotFoundException, EmailAlreadyInUseException, WeakPasswordException, TokenExpiredException, NetworkException, GoogleSignInCancelledException, AppleSignInCancelledException, AppleSignInNotSupportedException, GooglePlayServicesUnavailableException, ConfigurationException, UnknownAuthException, } from './exceptions';
|
|
2
|
+
export { mapFirebaseError, isAuthException, getErrorMessage, } from './errorMapper';
|
package/dist/errors/index.js
CHANGED
|
@@ -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
|
-
|
|
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 {
|
|
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:
|
|
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-
|
|
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 = "
|
|
21
|
-
GOOGLE_SIGN_IN_IN_PROGRESS = "
|
|
22
|
-
GOOGLE_PLAY_SERVICES_NOT_AVAILABLE = "
|
|
23
|
-
GOOGLE_SIGN_IN_FAILED = "
|
|
24
|
-
APPLE_SIGN_IN_CANCELLED = "
|
|
25
|
-
APPLE_SIGN_IN_FAILED = "
|
|
26
|
-
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
|
-
//
|
|
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-
|
|
26
|
+
AuthErrorCode["NETWORK_ERROR"] = "auth/network-error";
|
|
28
27
|
AuthErrorCode["UNKNOWN"] = "auth/unknown";
|
|
29
|
-
//
|
|
28
|
+
// Configuration errors
|
|
30
29
|
AuthErrorCode["CONFIG_ERROR"] = "auth/configuration-error";
|
|
30
|
+
// User actions
|
|
31
31
|
AuthErrorCode["CANCELLED"] = "auth/cancelled";
|
|
32
|
-
// Google Sign-In
|
|
33
|
-
AuthErrorCode["GOOGLE_SIGN_IN_CANCELLED"] = "
|
|
34
|
-
AuthErrorCode["GOOGLE_SIGN_IN_IN_PROGRESS"] = "
|
|
35
|
-
AuthErrorCode["GOOGLE_PLAY_SERVICES_NOT_AVAILABLE"] = "
|
|
36
|
-
AuthErrorCode["GOOGLE_SIGN_IN_FAILED"] = "
|
|
37
|
-
// Apple Sign-In
|
|
38
|
-
AuthErrorCode["APPLE_SIGN_IN_CANCELLED"] = "
|
|
39
|
-
AuthErrorCode["APPLE_SIGN_IN_FAILED"] = "
|
|
40
|
-
AuthErrorCode["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
|
@@ -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 {
|
|
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
|
-
|
|
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<
|
|
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
|
|
126
|
-
setError(
|
|
134
|
+
const mappedException = mapFirebaseError(err);
|
|
135
|
+
setError(mappedException);
|
|
127
136
|
setStatus(AuthStatus.UNAUTHENTICATED);
|
|
128
|
-
throw
|
|
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
|
|
140
|
-
setError(
|
|
148
|
+
const mappedException = mapFirebaseError(err);
|
|
149
|
+
setError(mappedException);
|
|
141
150
|
setStatus(AuthStatus.UNAUTHENTICATED);
|
|
142
|
-
throw
|
|
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
|
-
|
|
150
|
-
|
|
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
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
189
|
+
const mappedException = mapFirebaseError(err);
|
|
190
|
+
setError(mappedException);
|
|
196
191
|
setStatus(AuthStatus.UNAUTHENTICATED);
|
|
197
|
-
throw
|
|
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
|
|
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
|
|
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
|
|
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
|
|
266
|
-
setError(
|
|
250
|
+
const mappedException = mapFirebaseError(err);
|
|
251
|
+
setError(mappedException);
|
|
267
252
|
setStatus(AuthStatus.UNAUTHENTICATED);
|
|
268
|
-
throw
|
|
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
|
}
|