rn-swiftauth-sdk 1.0.0 → 1.0.2

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,9 @@
1
+ # 👥 Contributors
2
+
3
+ A huge thank you to the team who built the SwiftAuth SDK!
4
+
5
+ * 🛡️ **[@allcodez](https://github.com/allcodez)**
6
+ * 🎨 **[@Peliah](https://github.com/Peliah)**
7
+ * 🚀 **[@ukemeikot](https://github.com/ukemeikot)**
8
+
9
+ Interested in contributing? Pull requests are welcome!
@@ -40,13 +40,12 @@ const useAuth_1 = require("../hooks/useAuth");
40
40
  const PasswordInput_1 = require("./PasswordInput");
41
41
  const validation_1 = require("../utils/validation");
42
42
  const LoginForm = ({ styles: userStyles }) => {
43
- const { signInWithEmail, signInWithGoogle, signInWithApple, isLoading, // Using the simplified boolean we added to context
44
- error, config // ✅ We need this to check if social buttons are enabled
45
- } = (0, useAuth_1.useAuth)();
43
+ const { signInWithEmail, signInWithGoogle, signInWithApple, isLoading, error, config } = (0, useAuth_1.useAuth)();
46
44
  const [email, setEmail] = (0, react_1.useState)('');
47
45
  const [password, setPassword] = (0, react_1.useState)('');
48
- // ✅ Validation Error State
49
46
  const [validationErrors, setValidationErrors] = (0, react_1.useState)({});
47
+ //Check if form is filled to enable button
48
+ const isFormFilled = email.length > 0 && password.length > 0;
50
49
  const handleLogin = async () => {
51
50
  // 1. Reset previous errors
52
51
  setValidationErrors({});
@@ -58,14 +57,17 @@ const LoginForm = ({ styles: userStyles }) => {
58
57
  email: emailErr || undefined,
59
58
  password: passErr || undefined
60
59
  });
61
- return; // 🛑 Stop if invalid
60
+ return; //Stop if invalid
62
61
  }
63
62
  // 3. Attempt Login
64
63
  try {
65
- await signInWithEmail(email, password);
64
+ //UPDATED: Clean Object Syntax
65
+ await signInWithEmail({ email, password });
66
66
  }
67
67
  catch (e) {
68
68
  // Auth errors handled by global state
69
+ // DX: Log it for the developer (Optional but helpful for debugging)
70
+ console.log('Login failed:', e);
69
71
  }
70
72
  };
71
73
  const handleGoogleSignIn = async () => {
@@ -89,7 +91,7 @@ const LoginForm = ({ styles: userStyles }) => {
89
91
  react_1.default.createElement(react_native_1.TextInput, { style: [
90
92
  defaultStyles.input,
91
93
  userStyles?.input,
92
- validationErrors.email ? { borderColor: 'red' } : {} // Highlight on error
94
+ validationErrors.email ? { borderColor: 'red' } : {}
93
95
  ], placeholder: "Email", value: email, onChangeText: (text) => {
94
96
  setEmail(text);
95
97
  if (validationErrors.email)
@@ -104,9 +106,12 @@ const LoginForm = ({ styles: userStyles }) => {
104
106
  validationErrors.password && (react_1.default.createElement(react_native_1.Text, { style: defaultStyles.validationText }, validationErrors.password)),
105
107
  react_1.default.createElement(react_native_1.TouchableOpacity, { style: [
106
108
  defaultStyles.button,
107
- isLoading && defaultStyles.buttonDisabled,
109
+ // Disable style if loading OR form is incomplete
110
+ (isLoading || !isFormFilled) && defaultStyles.buttonDisabled,
108
111
  userStyles?.button
109
- ], onPress: handleLogin, disabled: isLoading }, isLoading ? (react_1.default.createElement(react_native_1.ActivityIndicator, { color: userStyles?.loadingIndicatorColor || "#fff" })) : (react_1.default.createElement(react_native_1.Text, { style: [defaultStyles.buttonText, userStyles?.buttonText] }, "Sign In"))),
112
+ ], onPress: handleLogin,
113
+ // Disable interaction if loading OR form is incomplete
114
+ disabled: isLoading || !isFormFilled }, isLoading ? (react_1.default.createElement(react_native_1.ActivityIndicator, { color: userStyles?.loadingIndicatorColor || "#fff" })) : (react_1.default.createElement(react_native_1.Text, { style: [defaultStyles.buttonText, userStyles?.buttonText] }, "Sign In"))),
110
115
  (config.enableGoogle || config.enableApple) && !isLoading && (react_1.default.createElement(react_1.default.Fragment, null,
111
116
  react_1.default.createElement(react_native_1.View, { style: defaultStyles.dividerContainer },
112
117
  react_1.default.createElement(react_native_1.View, { style: defaultStyles.divider }),
@@ -130,7 +135,7 @@ const defaultStyles = react_native_1.StyleSheet.create({
130
135
  backgroundColor: '#f5f5f5',
131
136
  padding: 15,
132
137
  borderRadius: 8,
133
- marginBottom: 8, // Reduced slightly to make room for validation text
138
+ marginBottom: 8,
134
139
  borderWidth: 1,
135
140
  borderColor: '#e0e0e0',
136
141
  fontSize: 16,
@@ -142,7 +147,10 @@ const defaultStyles = react_native_1.StyleSheet.create({
142
147
  alignItems: 'center',
143
148
  marginTop: 8,
144
149
  },
145
- buttonDisabled: { backgroundColor: '#a0cfff' },
150
+ buttonDisabled: {
151
+ backgroundColor: '#a0cfff',
152
+ opacity: 0.7
153
+ },
146
154
  buttonText: { color: '#fff', fontWeight: '600', fontSize: 16 },
147
155
  errorText: { color: 'red', marginBottom: 12, fontSize: 14, textAlign: 'center' },
148
156
  validationText: { color: 'red', fontSize: 12, marginBottom: 10, marginLeft: 4, marginTop: -4 },
@@ -40,22 +40,20 @@ const useAuth_1 = require("../hooks/useAuth");
40
40
  const PasswordInput_1 = require("./PasswordInput");
41
41
  const validation_1 = require("../utils/validation");
42
42
  const SignUpForm = ({ styles: userStyles, showHints = true }) => {
43
- const { signUpWithEmail, signInWithGoogle, signInWithApple, isLoading, // Use boolean loading state
44
- error, config // ✅ Use config for conditional rendering
45
- } = (0, useAuth_1.useAuth)();
43
+ const { signUpWithEmail, signInWithGoogle, signInWithApple, isLoading, error, config } = (0, useAuth_1.useAuth)();
46
44
  const [email, setEmail] = (0, react_1.useState)('');
47
45
  const [password, setPassword] = (0, react_1.useState)('');
48
46
  const [confirmPassword, setConfirmPassword] = (0, react_1.useState)('');
49
- // ✅ Proper Validation State
50
47
  const [validationErrors, setValidationErrors] = (0, react_1.useState)({});
51
- // Password Requirements Logic for Visual Hints
48
+ // 1. Smart Button Logic: Check if all fields have content
49
+ const isFormFilled = email.length > 0 && password.length > 0 && confirmPassword.length > 0;
50
+ // Password Requirements Logic
52
51
  const requirements = [
53
52
  { label: "At least 6 characters", met: password.length >= 6 },
54
53
  { label: "Contains a number", met: /\d/.test(password) },
55
54
  { label: "Passwords match", met: password.length > 0 && password === confirmPassword }
56
55
  ];
57
56
  const handleSignUp = async () => {
58
- // 1. Reset Errors
59
57
  setValidationErrors({});
60
58
  // 2. Validate Inputs
61
59
  const emailErr = (0, validation_1.validateEmail)(email);
@@ -64,7 +62,6 @@ const SignUpForm = ({ styles: userStyles, showHints = true }) => {
64
62
  if (password !== confirmPassword) {
65
63
  confirmErr = "Passwords do not match.";
66
64
  }
67
- // 3. Check if any errors exist
68
65
  if (emailErr || passErr || confirmErr) {
69
66
  setValidationErrors({
70
67
  email: emailErr || undefined,
@@ -73,12 +70,12 @@ const SignUpForm = ({ styles: userStyles, showHints = true }) => {
73
70
  });
74
71
  return;
75
72
  }
76
- // 4. Attempt Sign Up
77
73
  try {
78
- await signUpWithEmail(email, password);
74
+ // UPDATED: New Object Syntax
75
+ await signUpWithEmail({ email, password });
79
76
  }
80
77
  catch (e) {
81
- // Global error handled by useAuth
78
+ console.error('Sign Up Failed:', e);
82
79
  }
83
80
  };
84
81
  const handleGoogleSignIn = async () => {
@@ -130,9 +127,12 @@ const SignUpForm = ({ styles: userStyles, showHints = true }) => {
130
127
  ] }, req.label)))))),
131
128
  react_1.default.createElement(react_native_1.TouchableOpacity, { style: [
132
129
  defaultStyles.button,
133
- isLoading && defaultStyles.buttonDisabled,
130
+ // Disable style if loading OR form incomplete
131
+ (isLoading || !isFormFilled) && defaultStyles.buttonDisabled,
134
132
  userStyles?.button
135
- ], onPress: handleSignUp, disabled: isLoading }, isLoading ? (react_1.default.createElement(react_native_1.ActivityIndicator, { color: userStyles?.loadingIndicatorColor || "#fff" })) : (react_1.default.createElement(react_native_1.Text, { style: [defaultStyles.buttonText, userStyles?.buttonText] }, "Create Account"))),
133
+ ], onPress: handleSignUp,
134
+ // Disable interaction if loading OR form incomplete
135
+ disabled: isLoading || !isFormFilled }, isLoading ? (react_1.default.createElement(react_native_1.ActivityIndicator, { color: userStyles?.loadingIndicatorColor || "#fff" })) : (react_1.default.createElement(react_native_1.Text, { style: [defaultStyles.buttonText, userStyles?.buttonText] }, "Create Account"))),
136
136
  (config.enableGoogle || config.enableApple) && !isLoading && (react_1.default.createElement(react_1.default.Fragment, null,
137
137
  react_1.default.createElement(react_native_1.View, { style: defaultStyles.dividerContainer },
138
138
  react_1.default.createElement(react_native_1.View, { style: defaultStyles.divider }),
@@ -150,7 +150,7 @@ const defaultStyles = react_native_1.StyleSheet.create({
150
150
  backgroundColor: '#f5f5f5',
151
151
  padding: 15,
152
152
  borderRadius: 8,
153
- marginBottom: 8, // Reduced for validation text space
153
+ marginBottom: 8,
154
154
  borderWidth: 1,
155
155
  borderColor: '#e0e0e0',
156
156
  fontSize: 16,
@@ -162,11 +162,13 @@ const defaultStyles = react_native_1.StyleSheet.create({
162
162
  alignItems: 'center',
163
163
  marginTop: 8,
164
164
  },
165
- buttonDisabled: { backgroundColor: '#9ce4ae' },
165
+ buttonDisabled: {
166
+ backgroundColor: '#9ce4ae',
167
+ opacity: 0.7
168
+ },
166
169
  buttonText: { color: '#fff', fontWeight: '600', fontSize: 16 },
167
170
  globalError: { color: 'red', marginBottom: 12, fontSize: 14, textAlign: 'center' },
168
171
  validationText: { color: 'red', fontSize: 12, marginBottom: 10, marginLeft: 4, marginTop: -4 },
169
- // OAuth Styles
170
172
  dividerContainer: {
171
173
  flexDirection: 'row',
172
174
  alignItems: 'center',
@@ -190,7 +192,6 @@ const defaultStyles = react_native_1.StyleSheet.create({
190
192
  googleButtonText: { color: '#000', fontSize: 16, fontWeight: '500' },
191
193
  appleButton: { backgroundColor: '#000' },
192
194
  appleButtonText: { color: '#fff', fontSize: 16, fontWeight: '600' },
193
- // Password Hint Styles
194
195
  hintContainer: { marginBottom: 15, paddingLeft: 5 },
195
196
  hintRow: { flexDirection: 'row', alignItems: 'center', marginBottom: 4 },
196
197
  hintText: { color: '#666', fontSize: 12 },
@@ -40,33 +40,26 @@ exports.AuthProvider = void 0;
40
40
  const react_1 = __importStar(require("react"));
41
41
  const react_native_1 = require("react-native");
42
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;
43
+ const FirebaseAuth = __importStar(require("firebase/auth"));
49
44
  const async_storage_1 = __importDefault(require("@react-native-async-storage/async-storage"));
50
- // PROPER GOOGLE SIGN-IN
51
45
  const google_signin_1 = require("@react-native-google-signin/google-signin");
52
- // Apple Sign-In (Expo)
53
46
  const AppleAuthentication = __importStar(require("expo-apple-authentication"));
54
47
  const Crypto = __importStar(require("expo-crypto"));
55
48
  const errors_1 = require("../errors");
56
49
  const AuthContext_1 = require("./AuthContext");
57
50
  const types_1 = require("../types");
51
+ const getReactNativePersistence = FirebaseAuth.getReactNativePersistence;
58
52
  const AuthProvider = ({ config, children }) => {
59
53
  const [user, setUser] = (0, react_1.useState)(null);
60
54
  const [status, setStatus] = (0, react_1.useState)(types_1.AuthStatus.LOADING);
61
55
  const [error, setError] = (0, react_1.useState)(null);
62
56
  const [firebaseAuthInstance, setFirebaseAuthInstance] = (0, react_1.useState)(null);
63
- // ✅ NEW: Explicit loading state for initial app load vs action loading
64
57
  const [isDataLoading, setIsDataLoading] = (0, react_1.useState)(true);
58
+ // --- INITIALIZATION ---
65
59
  (0, react_1.useEffect)(() => {
66
60
  let app;
67
61
  let auth;
68
62
  if (!(0, app_1.getApps)().length) {
69
- // 1. Initialize App
70
63
  app = (0, app_1.initializeApp)({
71
64
  apiKey: config.apiKey,
72
65
  authDomain: config.authDomain,
@@ -75,39 +68,35 @@ const AuthProvider = ({ config, children }) => {
75
68
  messagingSenderId: config.messagingSenderId,
76
69
  appId: config.appId,
77
70
  });
78
- // 2. Select Persistence Strategy
79
71
  const selectedPersistence = config.persistence === 'memory'
80
- ? auth_1.inMemoryPersistence
72
+ ? FirebaseAuth.inMemoryPersistence
81
73
  : getReactNativePersistence(async_storage_1.default);
82
- // 3. Initialize Auth
83
- auth = (0, auth_1.initializeAuth)(app, {
74
+ auth = FirebaseAuth.initializeAuth(app, {
84
75
  persistence: selectedPersistence
85
76
  });
86
77
  }
87
78
  else {
88
79
  app = (0, app_1.getApp)();
89
- auth = (0, auth_1.getAuth)(app);
80
+ auth = FirebaseAuth.getAuth(app);
90
81
  }
91
82
  setFirebaseAuthInstance(auth);
92
- // 4. Configure Google Sign-In if enabled
93
83
  if (config.enableGoogle && config.googleWebClientId) {
94
84
  try {
95
85
  google_signin_1.GoogleSignin.configure({
96
86
  webClientId: config.googleWebClientId,
97
87
  offlineAccess: true,
98
- iosClientId: config.googleIOSClientId, // Optional
88
+ iosClientId: config.googleIOSClientId,
99
89
  });
100
- console.log('Google Sign-In configured successfully');
90
+ console.log('Google Sign-In configured successfully');
101
91
  }
102
92
  catch (err) {
103
- console.error('Google Sign-In configuration failed:', err);
93
+ console.error('Google Sign-In configuration failed:', err);
104
94
  }
105
95
  }
106
- const unsubscribe = (0, auth_1.onAuthStateChanged)(auth, async (fbUser) => {
96
+ const unsubscribe = FirebaseAuth.onAuthStateChanged(auth, async (fbUser) => {
107
97
  try {
108
98
  if (fbUser) {
109
99
  try {
110
- // Force token refresh to ensure validity on load
111
100
  const token = await fbUser.getIdToken(true);
112
101
  setUser({
113
102
  uid: fbUser.uid,
@@ -121,7 +110,8 @@ const AuthProvider = ({ config, children }) => {
121
110
  }
122
111
  catch (tokenError) {
123
112
  console.error('Token retrieval error:', tokenError);
124
- if (tokenError.code === 'auth/user-token-expired' || tokenError.code === 'auth/null-user') {
113
+ if (tokenError.code === types_1.ProviderErrorCodes.USER_TOKEN_EXPIRED ||
114
+ tokenError.code === types_1.ProviderErrorCodes.NULL_USER) {
125
115
  setStatus(types_1.AuthStatus.TOKEN_EXPIRED);
126
116
  }
127
117
  else {
@@ -140,60 +130,48 @@ const AuthProvider = ({ config, children }) => {
140
130
  setStatus(types_1.AuthStatus.UNAUTHENTICATED);
141
131
  }
142
132
  finally {
143
- // ✅ Stop initial loading spinner once Firebase has checked storage
144
133
  setIsDataLoading(false);
145
134
  }
146
- }, (err) => {
147
- console.error("Auth State Error:", err);
148
- setStatus(types_1.AuthStatus.UNAUTHENTICATED);
149
- setIsDataLoading(false);
150
135
  });
151
136
  return () => unsubscribe();
152
137
  }, [config]);
153
- // Email/Password Sign In
154
- const signInWithEmail = async (email, pass) => {
138
+ // --- ACTIONS ---
139
+ const signInWithEmail = async ({ email, password }) => {
155
140
  if (!firebaseAuthInstance)
156
141
  return;
157
142
  try {
158
143
  setError(null);
159
144
  setStatus(types_1.AuthStatus.LOADING);
160
- await (0, auth_1.signInWithEmailAndPassword)(firebaseAuthInstance, email, pass);
145
+ await FirebaseAuth.signInWithEmailAndPassword(firebaseAuthInstance, email, password);
161
146
  }
162
147
  catch (err) {
163
- const mappedError = (0, errors_1.mapFirebaseError)(err);
164
- setError(mappedError);
148
+ const mapped = (0, errors_1.mapFirebaseError)(err);
149
+ setError({ ...mapped, originalError: err });
165
150
  setStatus(types_1.AuthStatus.UNAUTHENTICATED);
166
- throw mappedError;
151
+ throw err;
167
152
  }
168
153
  };
169
- // Email/Password Sign Up
170
- const signUpWithEmail = async (email, pass) => {
154
+ const signUpWithEmail = async ({ email, password }) => {
171
155
  if (!firebaseAuthInstance)
172
156
  return;
173
157
  try {
174
158
  setError(null);
175
159
  setStatus(types_1.AuthStatus.LOADING);
176
- await (0, auth_1.createUserWithEmailAndPassword)(firebaseAuthInstance, email, pass);
160
+ await FirebaseAuth.createUserWithEmailAndPassword(firebaseAuthInstance, email, password);
177
161
  }
178
162
  catch (err) {
179
- const mappedError = (0, errors_1.mapFirebaseError)(err);
180
- setError(mappedError);
163
+ const mapped = (0, errors_1.mapFirebaseError)(err);
164
+ setError({ ...mapped, originalError: err });
181
165
  setStatus(types_1.AuthStatus.UNAUTHENTICATED);
182
- throw mappedError;
166
+ throw err;
183
167
  }
184
168
  };
185
- // PROPER GOOGLE SIGN-IN using @react-native-google-signin/google-signin
186
169
  const signInWithGoogle = async () => {
187
- if (!firebaseAuthInstance) {
170
+ if (!firebaseAuthInstance)
188
171
  throw new Error('Firebase not initialized');
189
- }
190
172
  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;
173
+ setError({ code: types_1.AuthErrorCode.CONFIG_ERROR, message: 'Google Auth not configured. Missing googleWebClientId.' });
174
+ return;
197
175
  }
198
176
  try {
199
177
  setError(null);
@@ -201,34 +179,32 @@ const AuthProvider = ({ config, children }) => {
201
179
  await google_signin_1.GoogleSignin.hasPlayServices({ showPlayServicesUpdateDialog: true });
202
180
  const userInfo = await google_signin_1.GoogleSignin.signIn();
203
181
  const idToken = userInfo.data?.idToken;
204
- if (!idToken) {
182
+ if (!idToken)
205
183
  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');
184
+ const credential = FirebaseAuth.GoogleAuthProvider.credential(idToken);
185
+ await FirebaseAuth.signInWithCredential(firebaseAuthInstance, credential);
186
+ console.log('Google Sign-In successful');
210
187
  }
211
188
  catch (err) {
212
- console.error('Google Sign-In Error:', err);
189
+ console.error('Google Sign-In Error:', err);
213
190
  let mappedError;
214
- if (err.code === 'SIGN_IN_CANCELLED') {
191
+ if (err.code === types_1.ProviderErrorCodes.GOOGLE_CANCELLED) {
215
192
  mappedError = {
216
193
  code: types_1.AuthErrorCode.GOOGLE_SIGN_IN_CANCELLED,
217
194
  message: 'Google Sign-In was cancelled',
218
195
  originalError: err
219
196
  };
220
- // Reset status if cancelled, don't leave it loading
221
197
  setStatus(types_1.AuthStatus.UNAUTHENTICATED);
222
198
  return;
223
199
  }
224
- else if (err.code === 'IN_PROGRESS') {
200
+ else if (err.code === types_1.ProviderErrorCodes.GOOGLE_IN_PROGRESS) {
225
201
  mappedError = {
226
202
  code: types_1.AuthErrorCode.GOOGLE_SIGN_IN_IN_PROGRESS,
227
203
  message: 'Google Sign-In is already in progress',
228
204
  originalError: err
229
205
  };
230
206
  }
231
- else if (err.code === 'PLAY_SERVICES_NOT_AVAILABLE') {
207
+ else if (err.code === types_1.ProviderErrorCodes.GOOGLE_PLAY_UNAVAILABLE) {
232
208
  mappedError = {
233
209
  code: types_1.AuthErrorCode.GOOGLE_PLAY_SERVICES_NOT_AVAILABLE,
234
210
  message: 'Google Play Services are not available. Please update Google Play Services.',
@@ -238,16 +214,14 @@ const AuthProvider = ({ config, children }) => {
238
214
  else {
239
215
  mappedError = (0, errors_1.mapFirebaseError)(err);
240
216
  }
241
- setError(mappedError);
217
+ setError({ ...mappedError, originalError: err });
242
218
  setStatus(types_1.AuthStatus.UNAUTHENTICATED);
243
219
  throw mappedError;
244
220
  }
245
221
  };
246
- // Apple Sign-In using expo-apple-authentication
247
222
  const signInWithApple = async () => {
248
- if (!firebaseAuthInstance) {
223
+ if (!firebaseAuthInstance)
249
224
  throw new Error('Firebase not initialized');
250
- }
251
225
  if (react_native_1.Platform.OS !== 'ios') {
252
226
  const platformError = {
253
227
  code: types_1.AuthErrorCode.APPLE_SIGN_IN_NOT_SUPPORTED,
@@ -278,20 +252,19 @@ const AuthProvider = ({ config, children }) => {
278
252
  nonce: hashedNonce,
279
253
  });
280
254
  const { identityToken } = appleCredential;
281
- if (!identityToken) {
255
+ if (!identityToken)
282
256
  throw new Error('No identity token received from Apple');
283
- }
284
- const provider = new auth_1.OAuthProvider('apple.com');
257
+ const provider = new FirebaseAuth.OAuthProvider('apple.com');
285
258
  const credential = provider.credential({
286
259
  idToken: identityToken,
287
260
  rawNonce: nonce,
288
261
  });
289
- await (0, auth_1.signInWithCredential)(firebaseAuthInstance, credential);
290
- console.log('Apple Sign-In successful');
262
+ await FirebaseAuth.signInWithCredential(firebaseAuthInstance, credential);
263
+ console.log('Apple Sign-In successful');
291
264
  }
292
265
  catch (err) {
293
- console.error('Apple Sign-In Error:', err);
294
- if (err.code === 'ERR_REQUEST_CANCELED') {
266
+ console.error('Apple Sign-In Error:', err);
267
+ if (err.code === types_1.ProviderErrorCodes.APPLE_CANCELLED) {
295
268
  const cancelError = {
296
269
  code: types_1.AuthErrorCode.APPLE_SIGN_IN_CANCELLED,
297
270
  message: 'Apple Sign-In was cancelled',
@@ -302,12 +275,11 @@ const AuthProvider = ({ config, children }) => {
302
275
  return;
303
276
  }
304
277
  const mappedError = (0, errors_1.mapFirebaseError)(err);
305
- setError(mappedError);
278
+ setError({ ...mappedError, originalError: err });
306
279
  setStatus(types_1.AuthStatus.UNAUTHENTICATED);
307
280
  throw mappedError;
308
281
  }
309
282
  };
310
- // Sign Out
311
283
  const signOut = async () => {
312
284
  try {
313
285
  if (firebaseAuthInstance) {
@@ -321,10 +293,10 @@ const AuthProvider = ({ config, children }) => {
321
293
  console.log('Google sign-out skipped or failed:', googleSignOutError);
322
294
  }
323
295
  }
324
- console.log('Sign out successful');
296
+ console.log('Sign out successful');
325
297
  }
326
298
  catch (err) {
327
- console.error('Sign out error:', err);
299
+ console.error('Sign out error:', err);
328
300
  setUser(null);
329
301
  setStatus(types_1.AuthStatus.UNAUTHENTICATED);
330
302
  }
@@ -333,10 +305,8 @@ const AuthProvider = ({ config, children }) => {
333
305
  const value = (0, react_1.useMemo)(() => ({
334
306
  user,
335
307
  status,
336
- // ✅ NEW: Combine internal loading with AuthStatus
337
308
  isLoading: isDataLoading || status === types_1.AuthStatus.LOADING,
338
309
  error,
339
- // ✅ NEW: Expose config for UI to read
340
310
  config,
341
311
  signInWithEmail,
342
312
  signUpWithEmail,
@@ -1,5 +1,5 @@
1
- import { AuthError } from './error.types';
2
1
  import { AuthConfig } from './config.types';
2
+ import { AuthError } from './error.types';
3
3
  export declare enum AuthStatus {
4
4
  AUTHENTICATED = "AUTHENTICATED",
5
5
  UNAUTHENTICATED = "UNAUTHENTICATED",
@@ -14,14 +14,22 @@ export interface User {
14
14
  emailVerified: boolean;
15
15
  token?: string;
16
16
  }
17
+ export interface EmailSignInOptions {
18
+ email: string;
19
+ password: string;
20
+ }
21
+ export interface EmailSignUpOptions {
22
+ email: string;
23
+ password: string;
24
+ }
17
25
  export interface AuthContextType {
18
26
  user: User | null;
19
27
  status: AuthStatus;
20
28
  isLoading: boolean;
21
29
  error: AuthError | null;
22
30
  config: AuthConfig;
23
- signInWithEmail: (email: string, pass: string) => Promise<void>;
24
- signUpWithEmail: (email: string, pass: string) => Promise<void>;
31
+ signInWithEmail: (options: EmailSignInOptions) => Promise<void>;
32
+ signUpWithEmail: (options: EmailSignUpOptions) => Promise<void>;
25
33
  signInWithGoogle: () => Promise<void>;
26
34
  signInWithApple: () => Promise<void>;
27
35
  signOut: () => Promise<void>;
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AuthStatus = void 0;
4
- // The specific states requested in the task
5
4
  var AuthStatus;
6
5
  (function (AuthStatus) {
7
6
  AuthStatus["AUTHENTICATED"] = "AUTHENTICATED";
@@ -1,3 +1,12 @@
1
+ export declare enum ProviderErrorCodes {
2
+ USER_TOKEN_EXPIRED = "auth/user-token-expired",
3
+ NULL_USER = "auth/null-user",
4
+ GOOGLE_CANCELLED = "SIGN_IN_CANCELLED",
5
+ GOOGLE_IN_PROGRESS = "IN_PROGRESS",
6
+ GOOGLE_PLAY_UNAVAILABLE = "PLAY_SERVICES_NOT_AVAILABLE",
7
+ APPLE_CANCELLED = "ERR_REQUEST_CANCELED",
8
+ APPLE_NOT_SUPPORTED = "APPLE_SIGN_IN_NOT_SUPPORTED"
9
+ }
1
10
  export declare enum AuthErrorCode {
2
11
  INVALID_CREDENTIALS = "auth/invalid-credentials",
3
12
  USER_NOT_FOUND = "auth/user-not-found",
@@ -17,7 +26,7 @@ export declare enum AuthErrorCode {
17
26
  APPLE_SIGN_IN_NOT_SUPPORTED = "APPLE_SIGN_IN_NOT_SUPPORTED"
18
27
  }
19
28
  export interface AuthError {
20
- code: AuthErrorCode;
29
+ code: string | ProviderErrorCodes | AuthErrorCode;
21
30
  message: string;
22
31
  originalError?: any;
23
32
  }
@@ -1,7 +1,22 @@
1
1
  "use strict";
2
2
  // src/types/error.types.ts
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.AuthErrorCode = void 0;
4
+ exports.AuthErrorCode = exports.ProviderErrorCodes = void 0;
5
+ // ✅ 1. Define Known Error Codes (Source of Truth)
6
+ var ProviderErrorCodes;
7
+ (function (ProviderErrorCodes) {
8
+ // Firebase specific
9
+ ProviderErrorCodes["USER_TOKEN_EXPIRED"] = "auth/user-token-expired";
10
+ ProviderErrorCodes["NULL_USER"] = "auth/null-user";
11
+ // Google specific
12
+ ProviderErrorCodes["GOOGLE_CANCELLED"] = "SIGN_IN_CANCELLED";
13
+ ProviderErrorCodes["GOOGLE_IN_PROGRESS"] = "IN_PROGRESS";
14
+ ProviderErrorCodes["GOOGLE_PLAY_UNAVAILABLE"] = "PLAY_SERVICES_NOT_AVAILABLE";
15
+ // Apple specific
16
+ ProviderErrorCodes["APPLE_CANCELLED"] = "ERR_REQUEST_CANCELED";
17
+ ProviderErrorCodes["APPLE_NOT_SUPPORTED"] = "APPLE_SIGN_IN_NOT_SUPPORTED";
18
+ })(ProviderErrorCodes || (exports.ProviderErrorCodes = ProviderErrorCodes = {}));
19
+ // Legacy error codes used in mapping (Keep this for backward compatibility if needed)
5
20
  var AuthErrorCode;
6
21
  (function (AuthErrorCode) {
7
22
  AuthErrorCode["INVALID_CREDENTIALS"] = "auth/invalid-credentials";
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "rn-swiftauth-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
7
7
  "dist",
8
- "src"
8
+ "src",
9
+ "CONTRIBUTORS.md"
9
10
  ],
10
11
  "scripts": {
11
12
  "build": "tsc",
@@ -59,4 +60,4 @@
59
60
  "react-native-safe-area-context": "^5.6.2",
60
61
  "typescript": "^5.0.0"
61
62
  }
62
- }
63
+ }