rn-swiftauth-sdk 1.0.0
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 +574 -0
- package/dist/components/AuthScreen.d.ts +14 -0
- package/dist/components/AuthScreen.js +75 -0
- package/dist/components/LoginForm.d.ts +7 -0
- package/dist/components/LoginForm.js +180 -0
- package/dist/components/PasswordInput.d.ts +8 -0
- package/dist/components/PasswordInput.js +70 -0
- package/dist/components/SignUpForm.d.ts +8 -0
- package/dist/components/SignUpForm.js +198 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.js +19 -0
- package/dist/core/AuthContext.d.ts +3 -0
- package/dist/core/AuthContext.js +10 -0
- package/dist/core/AuthProvider.d.ts +8 -0
- package/dist/core/AuthProvider.js +350 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +18 -0
- package/dist/errors/errorMapper.d.ts +2 -0
- package/dist/errors/errorMapper.js +124 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.js +17 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +17 -0
- package/dist/hooks/useAuth.d.ts +2 -0
- package/dist/hooks/useAuth.js +13 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +27 -0
- package/dist/types/auth.types.d.ts +29 -0
- package/dist/types/auth.types.js +11 -0
- package/dist/types/config.types.d.ts +21 -0
- package/dist/types/config.types.js +12 -0
- package/dist/types/error.types.d.ts +23 -0
- package/dist/types/error.types.js +26 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.js +21 -0
- package/dist/types/ui.types.d.ts +20 -0
- package/dist/types/ui.types.js +2 -0
- package/dist/utils/validation.d.ts +3 -0
- package/dist/utils/validation.js +29 -0
- package/package.json +62 -0
- package/src/components/AuthScreen.tsx +87 -0
- package/src/components/LoginForm.tsx +246 -0
- package/src/components/PasswordInput.tsx +56 -0
- package/src/components/SignUpForm.tsx +293 -0
- package/src/components/index.ts +3 -0
- package/src/core/AuthContext.tsx +6 -0
- package/src/core/AuthProvider.tsx +362 -0
- package/src/core/index.ts +2 -0
- package/src/errors/errorMapper.ts +139 -0
- package/src/errors/index.ts +1 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useAuth.ts +13 -0
- package/src/index.ts +12 -0
- package/src/types/auth.types.ts +43 -0
- package/src/types/config.types.ts +46 -0
- package/src/types/error.types.ts +31 -0
- package/src/types/index.ts +5 -0
- package/src/types/ui.types.ts +26 -0
- package/src/utils/validation.ts +20 -0
|
@@ -0,0 +1,350 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.AuthProvider = void 0;
|
|
40
|
+
const react_1 = __importStar(require("react"));
|
|
41
|
+
const react_native_1 = require("react-native");
|
|
42
|
+
const app_1 = require("firebase/app");
|
|
43
|
+
// Firebase Auth
|
|
44
|
+
const auth_1 = require("firebase/auth");
|
|
45
|
+
// The Hack: Import for getReactNativePersistence
|
|
46
|
+
const firebaseAuth = __importStar(require("firebase/auth"));
|
|
47
|
+
// @ts-ignore
|
|
48
|
+
const getReactNativePersistence = firebaseAuth.getReactNativePersistence;
|
|
49
|
+
const async_storage_1 = __importDefault(require("@react-native-async-storage/async-storage"));
|
|
50
|
+
// PROPER GOOGLE SIGN-IN
|
|
51
|
+
const google_signin_1 = require("@react-native-google-signin/google-signin");
|
|
52
|
+
// Apple Sign-In (Expo)
|
|
53
|
+
const AppleAuthentication = __importStar(require("expo-apple-authentication"));
|
|
54
|
+
const Crypto = __importStar(require("expo-crypto"));
|
|
55
|
+
const errors_1 = require("../errors");
|
|
56
|
+
const AuthContext_1 = require("./AuthContext");
|
|
57
|
+
const types_1 = require("../types");
|
|
58
|
+
const AuthProvider = ({ config, children }) => {
|
|
59
|
+
const [user, setUser] = (0, react_1.useState)(null);
|
|
60
|
+
const [status, setStatus] = (0, react_1.useState)(types_1.AuthStatus.LOADING);
|
|
61
|
+
const [error, setError] = (0, react_1.useState)(null);
|
|
62
|
+
const [firebaseAuthInstance, setFirebaseAuthInstance] = (0, react_1.useState)(null);
|
|
63
|
+
// ✅ NEW: Explicit loading state for initial app load vs action loading
|
|
64
|
+
const [isDataLoading, setIsDataLoading] = (0, react_1.useState)(true);
|
|
65
|
+
(0, react_1.useEffect)(() => {
|
|
66
|
+
let app;
|
|
67
|
+
let auth;
|
|
68
|
+
if (!(0, app_1.getApps)().length) {
|
|
69
|
+
// 1. Initialize App
|
|
70
|
+
app = (0, app_1.initializeApp)({
|
|
71
|
+
apiKey: config.apiKey,
|
|
72
|
+
authDomain: config.authDomain,
|
|
73
|
+
projectId: config.projectId,
|
|
74
|
+
storageBucket: config.storageBucket,
|
|
75
|
+
messagingSenderId: config.messagingSenderId,
|
|
76
|
+
appId: config.appId,
|
|
77
|
+
});
|
|
78
|
+
// 2. Select Persistence Strategy
|
|
79
|
+
const selectedPersistence = config.persistence === 'memory'
|
|
80
|
+
? auth_1.inMemoryPersistence
|
|
81
|
+
: getReactNativePersistence(async_storage_1.default);
|
|
82
|
+
// 3. Initialize Auth
|
|
83
|
+
auth = (0, auth_1.initializeAuth)(app, {
|
|
84
|
+
persistence: selectedPersistence
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
app = (0, app_1.getApp)();
|
|
89
|
+
auth = (0, auth_1.getAuth)(app);
|
|
90
|
+
}
|
|
91
|
+
setFirebaseAuthInstance(auth);
|
|
92
|
+
// 4. Configure Google Sign-In if enabled
|
|
93
|
+
if (config.enableGoogle && config.googleWebClientId) {
|
|
94
|
+
try {
|
|
95
|
+
google_signin_1.GoogleSignin.configure({
|
|
96
|
+
webClientId: config.googleWebClientId,
|
|
97
|
+
offlineAccess: true,
|
|
98
|
+
iosClientId: config.googleIOSClientId, // Optional
|
|
99
|
+
});
|
|
100
|
+
console.log('✅ Google Sign-In configured successfully');
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
console.error('❌ Google Sign-In configuration failed:', err);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const unsubscribe = (0, auth_1.onAuthStateChanged)(auth, async (fbUser) => {
|
|
107
|
+
try {
|
|
108
|
+
if (fbUser) {
|
|
109
|
+
try {
|
|
110
|
+
// Force token refresh to ensure validity on load
|
|
111
|
+
const token = await fbUser.getIdToken(true);
|
|
112
|
+
setUser({
|
|
113
|
+
uid: fbUser.uid,
|
|
114
|
+
email: fbUser.email,
|
|
115
|
+
displayName: fbUser.displayName,
|
|
116
|
+
photoURL: fbUser.photoURL,
|
|
117
|
+
emailVerified: fbUser.emailVerified,
|
|
118
|
+
token: token
|
|
119
|
+
});
|
|
120
|
+
setStatus(types_1.AuthStatus.AUTHENTICATED);
|
|
121
|
+
}
|
|
122
|
+
catch (tokenError) {
|
|
123
|
+
console.error('Token retrieval error:', tokenError);
|
|
124
|
+
if (tokenError.code === 'auth/user-token-expired' || tokenError.code === 'auth/null-user') {
|
|
125
|
+
setStatus(types_1.AuthStatus.TOKEN_EXPIRED);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
129
|
+
}
|
|
130
|
+
setUser(null);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
setUser(null);
|
|
135
|
+
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
console.error("Auth State Error:", err);
|
|
140
|
+
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
// ✅ Stop initial loading spinner once Firebase has checked storage
|
|
144
|
+
setIsDataLoading(false);
|
|
145
|
+
}
|
|
146
|
+
}, (err) => {
|
|
147
|
+
console.error("Auth State Error:", err);
|
|
148
|
+
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
149
|
+
setIsDataLoading(false);
|
|
150
|
+
});
|
|
151
|
+
return () => unsubscribe();
|
|
152
|
+
}, [config]);
|
|
153
|
+
// Email/Password Sign In
|
|
154
|
+
const signInWithEmail = async (email, pass) => {
|
|
155
|
+
if (!firebaseAuthInstance)
|
|
156
|
+
return;
|
|
157
|
+
try {
|
|
158
|
+
setError(null);
|
|
159
|
+
setStatus(types_1.AuthStatus.LOADING);
|
|
160
|
+
await (0, auth_1.signInWithEmailAndPassword)(firebaseAuthInstance, email, pass);
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
const mappedError = (0, errors_1.mapFirebaseError)(err);
|
|
164
|
+
setError(mappedError);
|
|
165
|
+
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
166
|
+
throw mappedError;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
// Email/Password Sign Up
|
|
170
|
+
const signUpWithEmail = async (email, pass) => {
|
|
171
|
+
if (!firebaseAuthInstance)
|
|
172
|
+
return;
|
|
173
|
+
try {
|
|
174
|
+
setError(null);
|
|
175
|
+
setStatus(types_1.AuthStatus.LOADING);
|
|
176
|
+
await (0, auth_1.createUserWithEmailAndPassword)(firebaseAuthInstance, email, pass);
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
const mappedError = (0, errors_1.mapFirebaseError)(err);
|
|
180
|
+
setError(mappedError);
|
|
181
|
+
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
182
|
+
throw mappedError;
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
// PROPER GOOGLE SIGN-IN using @react-native-google-signin/google-signin
|
|
186
|
+
const signInWithGoogle = async () => {
|
|
187
|
+
if (!firebaseAuthInstance) {
|
|
188
|
+
throw new Error('Firebase not initialized');
|
|
189
|
+
}
|
|
190
|
+
if (!config.enableGoogle || !config.googleWebClientId) {
|
|
191
|
+
const configError = {
|
|
192
|
+
code: types_1.AuthErrorCode.CONFIG_ERROR,
|
|
193
|
+
message: 'Google Sign-In is not enabled or configured. Please add googleWebClientId to your AuthConfig.',
|
|
194
|
+
};
|
|
195
|
+
setError(configError);
|
|
196
|
+
throw configError;
|
|
197
|
+
}
|
|
198
|
+
try {
|
|
199
|
+
setError(null);
|
|
200
|
+
setStatus(types_1.AuthStatus.LOADING);
|
|
201
|
+
await google_signin_1.GoogleSignin.hasPlayServices({ showPlayServicesUpdateDialog: true });
|
|
202
|
+
const userInfo = await google_signin_1.GoogleSignin.signIn();
|
|
203
|
+
const idToken = userInfo.data?.idToken;
|
|
204
|
+
if (!idToken) {
|
|
205
|
+
throw new Error('No ID token received from Google Sign-In');
|
|
206
|
+
}
|
|
207
|
+
const credential = auth_1.GoogleAuthProvider.credential(idToken);
|
|
208
|
+
await (0, auth_1.signInWithCredential)(firebaseAuthInstance, credential);
|
|
209
|
+
console.log('✅ Google Sign-In successful');
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
console.error('❌ Google Sign-In Error:', err);
|
|
213
|
+
let mappedError;
|
|
214
|
+
if (err.code === 'SIGN_IN_CANCELLED') {
|
|
215
|
+
mappedError = {
|
|
216
|
+
code: types_1.AuthErrorCode.GOOGLE_SIGN_IN_CANCELLED,
|
|
217
|
+
message: 'Google Sign-In was cancelled',
|
|
218
|
+
originalError: err
|
|
219
|
+
};
|
|
220
|
+
// Reset status if cancelled, don't leave it loading
|
|
221
|
+
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
else if (err.code === 'IN_PROGRESS') {
|
|
225
|
+
mappedError = {
|
|
226
|
+
code: types_1.AuthErrorCode.GOOGLE_SIGN_IN_IN_PROGRESS,
|
|
227
|
+
message: 'Google Sign-In is already in progress',
|
|
228
|
+
originalError: err
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
else if (err.code === 'PLAY_SERVICES_NOT_AVAILABLE') {
|
|
232
|
+
mappedError = {
|
|
233
|
+
code: types_1.AuthErrorCode.GOOGLE_PLAY_SERVICES_NOT_AVAILABLE,
|
|
234
|
+
message: 'Google Play Services are not available. Please update Google Play Services.',
|
|
235
|
+
originalError: err
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
mappedError = (0, errors_1.mapFirebaseError)(err);
|
|
240
|
+
}
|
|
241
|
+
setError(mappedError);
|
|
242
|
+
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
243
|
+
throw mappedError;
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
// Apple Sign-In using expo-apple-authentication
|
|
247
|
+
const signInWithApple = async () => {
|
|
248
|
+
if (!firebaseAuthInstance) {
|
|
249
|
+
throw new Error('Firebase not initialized');
|
|
250
|
+
}
|
|
251
|
+
if (react_native_1.Platform.OS !== 'ios') {
|
|
252
|
+
const platformError = {
|
|
253
|
+
code: types_1.AuthErrorCode.APPLE_SIGN_IN_NOT_SUPPORTED,
|
|
254
|
+
message: 'Apple Sign-In is only available on iOS devices',
|
|
255
|
+
};
|
|
256
|
+
setError(platformError);
|
|
257
|
+
throw platformError;
|
|
258
|
+
}
|
|
259
|
+
const isAvailable = await AppleAuthentication.isAvailableAsync();
|
|
260
|
+
if (!isAvailable) {
|
|
261
|
+
const availabilityError = {
|
|
262
|
+
code: types_1.AuthErrorCode.APPLE_SIGN_IN_NOT_SUPPORTED,
|
|
263
|
+
message: 'Apple Sign-In is not available on this device (requires iOS 13+)',
|
|
264
|
+
};
|
|
265
|
+
setError(availabilityError);
|
|
266
|
+
throw availabilityError;
|
|
267
|
+
}
|
|
268
|
+
try {
|
|
269
|
+
setError(null);
|
|
270
|
+
setStatus(types_1.AuthStatus.LOADING);
|
|
271
|
+
const nonce = Math.random().toString(36).substring(2, 10);
|
|
272
|
+
const hashedNonce = await Crypto.digestStringAsync(Crypto.CryptoDigestAlgorithm.SHA256, nonce);
|
|
273
|
+
const appleCredential = await AppleAuthentication.signInAsync({
|
|
274
|
+
requestedScopes: [
|
|
275
|
+
AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
|
|
276
|
+
AppleAuthentication.AppleAuthenticationScope.EMAIL,
|
|
277
|
+
],
|
|
278
|
+
nonce: hashedNonce,
|
|
279
|
+
});
|
|
280
|
+
const { identityToken } = appleCredential;
|
|
281
|
+
if (!identityToken) {
|
|
282
|
+
throw new Error('No identity token received from Apple');
|
|
283
|
+
}
|
|
284
|
+
const provider = new auth_1.OAuthProvider('apple.com');
|
|
285
|
+
const credential = provider.credential({
|
|
286
|
+
idToken: identityToken,
|
|
287
|
+
rawNonce: nonce,
|
|
288
|
+
});
|
|
289
|
+
await (0, auth_1.signInWithCredential)(firebaseAuthInstance, credential);
|
|
290
|
+
console.log('✅ Apple Sign-In successful');
|
|
291
|
+
}
|
|
292
|
+
catch (err) {
|
|
293
|
+
console.error('❌ Apple Sign-In Error:', err);
|
|
294
|
+
if (err.code === 'ERR_REQUEST_CANCELED') {
|
|
295
|
+
const cancelError = {
|
|
296
|
+
code: types_1.AuthErrorCode.APPLE_SIGN_IN_CANCELLED,
|
|
297
|
+
message: 'Apple Sign-In was cancelled',
|
|
298
|
+
originalError: err
|
|
299
|
+
};
|
|
300
|
+
setError(cancelError);
|
|
301
|
+
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
const mappedError = (0, errors_1.mapFirebaseError)(err);
|
|
305
|
+
setError(mappedError);
|
|
306
|
+
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
307
|
+
throw mappedError;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
// Sign Out
|
|
311
|
+
const signOut = async () => {
|
|
312
|
+
try {
|
|
313
|
+
if (firebaseAuthInstance) {
|
|
314
|
+
await firebaseAuthInstance.signOut();
|
|
315
|
+
}
|
|
316
|
+
if (config.enableGoogle) {
|
|
317
|
+
try {
|
|
318
|
+
await google_signin_1.GoogleSignin.signOut();
|
|
319
|
+
}
|
|
320
|
+
catch (googleSignOutError) {
|
|
321
|
+
console.log('Google sign-out skipped or failed:', googleSignOutError);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
console.log('✅ Sign out successful');
|
|
325
|
+
}
|
|
326
|
+
catch (err) {
|
|
327
|
+
console.error('❌ Sign out error:', err);
|
|
328
|
+
setUser(null);
|
|
329
|
+
setStatus(types_1.AuthStatus.UNAUTHENTICATED);
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
const clearError = () => setError(null);
|
|
333
|
+
const value = (0, react_1.useMemo)(() => ({
|
|
334
|
+
user,
|
|
335
|
+
status,
|
|
336
|
+
// ✅ NEW: Combine internal loading with AuthStatus
|
|
337
|
+
isLoading: isDataLoading || status === types_1.AuthStatus.LOADING,
|
|
338
|
+
error,
|
|
339
|
+
// ✅ NEW: Expose config for UI to read
|
|
340
|
+
config,
|
|
341
|
+
signInWithEmail,
|
|
342
|
+
signUpWithEmail,
|
|
343
|
+
signInWithGoogle,
|
|
344
|
+
signInWithApple,
|
|
345
|
+
signOut,
|
|
346
|
+
clearError
|
|
347
|
+
}), [user, status, isDataLoading, error, config, firebaseAuthInstance]);
|
|
348
|
+
return (react_1.default.createElement(AuthContext_1.AuthContext.Provider, { value: value }, children));
|
|
349
|
+
};
|
|
350
|
+
exports.AuthProvider = AuthProvider;
|
|
@@ -0,0 +1,18 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./AuthContext"), exports);
|
|
18
|
+
__exportStar(require("./AuthProvider"), exports);
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mapFirebaseError = void 0;
|
|
4
|
+
const types_1 = require("../types");
|
|
5
|
+
const mapFirebaseError = (error) => {
|
|
6
|
+
// Default fallback
|
|
7
|
+
const fallbackError = {
|
|
8
|
+
code: types_1.AuthErrorCode.UNKNOWN,
|
|
9
|
+
message: 'An unexpected error occurred',
|
|
10
|
+
originalError: error,
|
|
11
|
+
};
|
|
12
|
+
// If it's not a Firebase error, return generic
|
|
13
|
+
if (!error || typeof error.code !== 'string') {
|
|
14
|
+
return {
|
|
15
|
+
...fallbackError,
|
|
16
|
+
message: error?.message || fallbackError.message
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const fbError = error;
|
|
20
|
+
switch (fbError.code) {
|
|
21
|
+
// Email/Password Errors
|
|
22
|
+
case 'auth/invalid-email':
|
|
23
|
+
case 'auth/user-not-found':
|
|
24
|
+
case 'auth/wrong-password':
|
|
25
|
+
case 'auth/invalid-credential':
|
|
26
|
+
return {
|
|
27
|
+
code: types_1.AuthErrorCode.INVALID_CREDENTIALS,
|
|
28
|
+
message: 'Invalid email or password.',
|
|
29
|
+
originalError: error
|
|
30
|
+
};
|
|
31
|
+
case 'auth/email-already-in-use':
|
|
32
|
+
return {
|
|
33
|
+
code: types_1.AuthErrorCode.EMAIL_ALREADY_IN_USE,
|
|
34
|
+
message: 'This email is already registered.',
|
|
35
|
+
originalError: error
|
|
36
|
+
};
|
|
37
|
+
case 'auth/weak-password':
|
|
38
|
+
return {
|
|
39
|
+
code: types_1.AuthErrorCode.WEAK_PASSWORD,
|
|
40
|
+
message: 'Password is too weak. Please use a stronger password.',
|
|
41
|
+
originalError: error
|
|
42
|
+
};
|
|
43
|
+
case 'auth/network-request-failed':
|
|
44
|
+
return {
|
|
45
|
+
code: types_1.AuthErrorCode.NETWORK_ERROR,
|
|
46
|
+
message: 'Network error. Please check your connection.',
|
|
47
|
+
originalError: error
|
|
48
|
+
};
|
|
49
|
+
// Google Sign-In Errors
|
|
50
|
+
case 'auth/popup-closed-by-user':
|
|
51
|
+
case 'auth/cancelled-popup-request':
|
|
52
|
+
return {
|
|
53
|
+
code: types_1.AuthErrorCode.UNKNOWN,
|
|
54
|
+
message: 'Sign-in was cancelled.',
|
|
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
|
+
};
|
|
81
|
+
// Apple Sign-In Errors
|
|
82
|
+
case 'auth/invalid-verification-code':
|
|
83
|
+
case 'auth/invalid-verification-id':
|
|
84
|
+
return {
|
|
85
|
+
code: types_1.AuthErrorCode.INVALID_CREDENTIALS,
|
|
86
|
+
message: 'The verification code is invalid. Please try again.',
|
|
87
|
+
originalError: error
|
|
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
|
|
98
|
+
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
|
+
};
|
|
104
|
+
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
|
+
case 'auth/invalid-oauth-client-id':
|
|
111
|
+
return {
|
|
112
|
+
code: types_1.AuthErrorCode.UNKNOWN,
|
|
113
|
+
message: 'The OAuth client ID is invalid.',
|
|
114
|
+
originalError: error
|
|
115
|
+
};
|
|
116
|
+
default:
|
|
117
|
+
return {
|
|
118
|
+
code: types_1.AuthErrorCode.UNKNOWN,
|
|
119
|
+
message: fbError.message || 'An unknown error occurred.',
|
|
120
|
+
originalError: error
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
exports.mapFirebaseError = mapFirebaseError;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './errorMapper';
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./errorMapper"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useAuth';
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./useAuth"), exports);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useAuth = void 0;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const AuthContext_1 = require("../core/AuthContext");
|
|
6
|
+
const useAuth = () => {
|
|
7
|
+
const context = (0, react_1.useContext)(AuthContext_1.AuthContext);
|
|
8
|
+
if (context === undefined) {
|
|
9
|
+
throw new Error('useAuth must be used within an AuthProvider');
|
|
10
|
+
}
|
|
11
|
+
return context;
|
|
12
|
+
};
|
|
13
|
+
exports.useAuth = useAuth;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// src/index.ts
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
15
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.SDK_VERSION = void 0;
|
|
19
|
+
// We will uncomment these as we build them
|
|
20
|
+
__exportStar(require("./core"), exports);
|
|
21
|
+
// export * from './providers';
|
|
22
|
+
__exportStar(require("./components"), exports);
|
|
23
|
+
__exportStar(require("./hooks"), exports);
|
|
24
|
+
__exportStar(require("./errors"), exports);
|
|
25
|
+
__exportStar(require("./types"), exports);
|
|
26
|
+
// Placeholder so the build doesn't fail right now
|
|
27
|
+
exports.SDK_VERSION = "1.0.0";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AuthError } from './error.types';
|
|
2
|
+
import { AuthConfig } from './config.types';
|
|
3
|
+
export declare enum AuthStatus {
|
|
4
|
+
AUTHENTICATED = "AUTHENTICATED",
|
|
5
|
+
UNAUTHENTICATED = "UNAUTHENTICATED",
|
|
6
|
+
TOKEN_EXPIRED = "TOKEN_EXPIRED",
|
|
7
|
+
LOADING = "LOADING"
|
|
8
|
+
}
|
|
9
|
+
export interface User {
|
|
10
|
+
uid: string;
|
|
11
|
+
email: string | null;
|
|
12
|
+
displayName: string | null;
|
|
13
|
+
photoURL: string | null;
|
|
14
|
+
emailVerified: boolean;
|
|
15
|
+
token?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface AuthContextType {
|
|
18
|
+
user: User | null;
|
|
19
|
+
status: AuthStatus;
|
|
20
|
+
isLoading: boolean;
|
|
21
|
+
error: AuthError | null;
|
|
22
|
+
config: AuthConfig;
|
|
23
|
+
signInWithEmail: (email: string, pass: string) => Promise<void>;
|
|
24
|
+
signUpWithEmail: (email: string, pass: string) => Promise<void>;
|
|
25
|
+
signInWithGoogle: () => Promise<void>;
|
|
26
|
+
signInWithApple: () => Promise<void>;
|
|
27
|
+
signOut: () => Promise<void>;
|
|
28
|
+
clearError: () => void;
|
|
29
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AuthStatus = void 0;
|
|
4
|
+
// The specific states requested in the task
|
|
5
|
+
var AuthStatus;
|
|
6
|
+
(function (AuthStatus) {
|
|
7
|
+
AuthStatus["AUTHENTICATED"] = "AUTHENTICATED";
|
|
8
|
+
AuthStatus["UNAUTHENTICATED"] = "UNAUTHENTICATED";
|
|
9
|
+
AuthStatus["TOKEN_EXPIRED"] = "TOKEN_EXPIRED";
|
|
10
|
+
AuthStatus["LOADING"] = "LOADING";
|
|
11
|
+
})(AuthStatus || (exports.AuthStatus = AuthStatus = {}));
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface AuthConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
authDomain: string;
|
|
4
|
+
projectId: string;
|
|
5
|
+
storageBucket?: string;
|
|
6
|
+
messagingSenderId?: string;
|
|
7
|
+
appId?: string;
|
|
8
|
+
persistence?: 'local' | 'memory';
|
|
9
|
+
enableGoogle?: boolean;
|
|
10
|
+
enableApple?: boolean;
|
|
11
|
+
enableEmail?: boolean;
|
|
12
|
+
googleWebClientId?: string;
|
|
13
|
+
googleIOSClientId?: string;
|
|
14
|
+
ui?: {
|
|
15
|
+
enableGoogleAuth?: boolean;
|
|
16
|
+
enableAppleAuth?: boolean;
|
|
17
|
+
enableEmailAuth?: boolean;
|
|
18
|
+
};
|
|
19
|
+
enablePasswordHints?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare const DEFAULT_AUTH_CONFIG: Partial<AuthConfig>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_AUTH_CONFIG = void 0;
|
|
4
|
+
exports.DEFAULT_AUTH_CONFIG = {
|
|
5
|
+
persistence: 'local',
|
|
6
|
+
ui: {
|
|
7
|
+
enableGoogleAuth: true,
|
|
8
|
+
enableAppleAuth: true,
|
|
9
|
+
enableEmailAuth: true,
|
|
10
|
+
},
|
|
11
|
+
enablePasswordHints: true,
|
|
12
|
+
};
|