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
package/README.md
ADDED
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
# SwiftAuth SDK
|
|
2
|
+
|
|
3
|
+
A production-ready React Native authentication SDK powered by Firebase. Built with TypeScript, offering both pre-built UI components and headless hooks for complete flexibility.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/swiftauth-sdk)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## ✨ Features
|
|
9
|
+
|
|
10
|
+
- 🔐 **Email/Password Authentication** - Built-in validation and error handling
|
|
11
|
+
- 🎨 **Pre-built UI Components** - Beautiful, customizable auth screens out of the box
|
|
12
|
+
- 🎣 **Headless Hooks** - Full control with `useAuth()` for custom implementations
|
|
13
|
+
- 🍎 **Social Login Support** - Google and Apple Sign-In (iOS only for Apple)
|
|
14
|
+
- 💾 **Persistent Sessions** - Configurable session management (local/memory)
|
|
15
|
+
- 🎯 **TypeScript First** - Full type safety and IntelliSense support
|
|
16
|
+
- ⚡ **Zero Configuration** - Works with minimal setup
|
|
17
|
+
- 📱 **Expo & Bare React Native** - Compatible with both workflows
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 📦 Installation
|
|
22
|
+
|
|
23
|
+
### Prerequisites
|
|
24
|
+
|
|
25
|
+
Ensure your environment meets these requirements:
|
|
26
|
+
- **Node.js**: v18 or higher
|
|
27
|
+
- **React Native**: v0.70+
|
|
28
|
+
- **Expo**: SDK 49+ (Recommended)
|
|
29
|
+
|
|
30
|
+
### Step 1: Install the SDK
|
|
31
|
+
|
|
32
|
+
Since SwiftAuth SDK is currently distributed as a source package, clone and link it locally:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Clone the repository
|
|
36
|
+
git clone https://github.com/allcodez/Auth-SDK_Stage8
|
|
37
|
+
|
|
38
|
+
# Navigate to SDK folder
|
|
39
|
+
cd Auth-SDK_Stage8/swiftauth-sdk
|
|
40
|
+
|
|
41
|
+
# Install dependencies and build
|
|
42
|
+
npm install
|
|
43
|
+
npm run build
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Step 2: Link to Your Project
|
|
47
|
+
|
|
48
|
+
Navigate to your React Native/Expo project and install the SDK:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
cd your-project-folder
|
|
52
|
+
npm install ../path/to/Auth-SDK_Stage8/swiftauth-sdk
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Step 3: Install Required Dependencies
|
|
56
|
+
|
|
57
|
+
SwiftAuth requires these peer dependencies:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm install firebase @react-native-async-storage/async-storage react-native-safe-area-context
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**For Expo projects:**
|
|
64
|
+
```bash
|
|
65
|
+
npx expo install firebase @react-native-async-storage/async-storage react-native-safe-area-context
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**For Google Sign-In (Optional):**
|
|
69
|
+
```bash
|
|
70
|
+
npm install @react-native-google-signin/google-signin
|
|
71
|
+
# or for Expo
|
|
72
|
+
npx expo install @react-native-google-signin/google-signin
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**For Apple Sign-In (Optional, iOS only):**
|
|
76
|
+
```bash
|
|
77
|
+
npm install @invertase/react-native-apple-authentication
|
|
78
|
+
# or for Expo
|
|
79
|
+
npx expo install @invertase/react-native-apple-authentication
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Step 4: Metro Configuration (Important)
|
|
83
|
+
|
|
84
|
+
Update your `metro.config.js` to resolve the SDK properly:
|
|
85
|
+
|
|
86
|
+
```javascript
|
|
87
|
+
const { getDefaultConfig } = require('expo/metro-config');
|
|
88
|
+
const path = require('path');
|
|
89
|
+
|
|
90
|
+
const projectRoot = __dirname;
|
|
91
|
+
const workspaceRoot = path.resolve(projectRoot, '../');
|
|
92
|
+
|
|
93
|
+
const config = getDefaultConfig(projectRoot);
|
|
94
|
+
|
|
95
|
+
config.watchFolders = [workspaceRoot];
|
|
96
|
+
config.resolver.nodeModulesPaths = [
|
|
97
|
+
path.resolve(projectRoot, 'node_modules'),
|
|
98
|
+
path.resolve(workspaceRoot, 'node_modules'),
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
module.exports = config;
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### ⚠️ Troubleshooting "Duplicate React"
|
|
105
|
+
|
|
106
|
+
If you encounter an "Invalid Hook Call" error:
|
|
107
|
+
|
|
108
|
+
1. Build the SDK: `npm run build`
|
|
109
|
+
2. Delete SDK's `node_modules`: `rm -rf node_modules` inside `swiftauth-sdk`
|
|
110
|
+
3. Clear cache and restart: `npx expo start -c`
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 🔧 Firebase Setup
|
|
115
|
+
|
|
116
|
+
### 1. Create Firebase Project
|
|
117
|
+
|
|
118
|
+
1. Go to [Firebase Console](https://console.firebase.google.com/)
|
|
119
|
+
2. Create a new project or select existing one
|
|
120
|
+
3. Register a **Web App** (click the `</>` icon)
|
|
121
|
+
4. Copy the `firebaseConfig` object
|
|
122
|
+
|
|
123
|
+
### 2. Enable Authentication Methods
|
|
124
|
+
|
|
125
|
+
1. Go to **Authentication** > **Sign-in method**
|
|
126
|
+
2. Enable **Email/Password**
|
|
127
|
+
3. (Optional) Enable **Google** and/or **Apple** for social login
|
|
128
|
+
|
|
129
|
+
### 3. Platform-Specific Configuration
|
|
130
|
+
|
|
131
|
+
#### Android Setup
|
|
132
|
+
|
|
133
|
+
1. In Firebase Console, register an **Android app**
|
|
134
|
+
2. Download `google-services.json`
|
|
135
|
+
3. Place it in your project: `android/app/google-services.json`
|
|
136
|
+
|
|
137
|
+
**Update `android/build.gradle`:**
|
|
138
|
+
```gradle
|
|
139
|
+
buildscript {
|
|
140
|
+
dependencies {
|
|
141
|
+
// Add this line
|
|
142
|
+
classpath 'com.google.gms:google-services:4.3.15'
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Update `android/app/build.gradle`:**
|
|
148
|
+
```gradle
|
|
149
|
+
apply plugin: 'com.android.application'
|
|
150
|
+
// Add this line at the bottom
|
|
151
|
+
apply plugin: 'com.google.gms.google-services'
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Update `app.json` for Expo:**
|
|
155
|
+
```json
|
|
156
|
+
{
|
|
157
|
+
"expo": {
|
|
158
|
+
"android": {
|
|
159
|
+
"googleServicesFile": "./google-services.json",
|
|
160
|
+
"package": "com.yourcompany.yourapp"
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
#### iOS Setup
|
|
167
|
+
|
|
168
|
+
1. In Firebase Console, register an **iOS app**
|
|
169
|
+
2. Download `GoogleService-Info.plist`
|
|
170
|
+
3. Place it in your project: `ios/YourAppName/GoogleService-Info.plist`
|
|
171
|
+
|
|
172
|
+
**For Bare React Native:**
|
|
173
|
+
- Drag `GoogleService-Info.plist` into your Xcode project
|
|
174
|
+
|
|
175
|
+
**Update `app.json` for Expo:**
|
|
176
|
+
```json
|
|
177
|
+
{
|
|
178
|
+
"expo": {
|
|
179
|
+
"ios": {
|
|
180
|
+
"googleServicesFile": "./GoogleService-Info.plist",
|
|
181
|
+
"bundleIdentifier": "com.yourcompany.yourapp"
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Install CocoaPods (iOS only):**
|
|
188
|
+
```bash
|
|
189
|
+
cd ios
|
|
190
|
+
pod install
|
|
191
|
+
cd ..
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### 4. Google Sign-In Configuration (Optional)
|
|
195
|
+
|
|
196
|
+
#### Get Google Client IDs
|
|
197
|
+
|
|
198
|
+
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
|
|
199
|
+
2. Select your Firebase project
|
|
200
|
+
3. Go to **APIs & Services** > **Credentials**
|
|
201
|
+
4. You'll need:
|
|
202
|
+
- **Web Client ID** (for all platforms)
|
|
203
|
+
- **iOS Client ID** (optional, iOS-specific)
|
|
204
|
+
|
|
205
|
+
**Update `app.json` for Google Sign-In:**
|
|
206
|
+
```json
|
|
207
|
+
{
|
|
208
|
+
"expo": {
|
|
209
|
+
"ios": {
|
|
210
|
+
"bundleIdentifier": "com.yourcompany.yourapp",
|
|
211
|
+
"googleServicesFile": "./GoogleService-Info.plist"
|
|
212
|
+
},
|
|
213
|
+
"android": {
|
|
214
|
+
"package": "com.yourcompany.yourapp",
|
|
215
|
+
"googleServicesFile": "./google-services.json"
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### 5. Apple Sign-In Configuration (Optional, iOS only)
|
|
222
|
+
|
|
223
|
+
1. Go to your [Apple Developer Account](https://developer.apple.com/)
|
|
224
|
+
2. Enable **Sign in with Apple** capability
|
|
225
|
+
3. Add the capability in Xcode: **Signing & Capabilities** > **+ Capability** > **Sign in with Apple**
|
|
226
|
+
|
|
227
|
+
**Update `app.json`:**
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"expo": {
|
|
231
|
+
"ios": {
|
|
232
|
+
"usesAppleSignIn": true
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## 🚀 Quick Start
|
|
241
|
+
|
|
242
|
+
### Basic Setup (Email Authentication)
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
// App.tsx
|
|
246
|
+
import React from 'react';
|
|
247
|
+
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
248
|
+
import { AuthProvider, AuthScreen, useAuth } from 'swiftauth-sdk';
|
|
249
|
+
|
|
250
|
+
// Your Firebase configuration
|
|
251
|
+
const firebaseConfig = {
|
|
252
|
+
apiKey: "AIzaSyD-Your-Actual-Key",
|
|
253
|
+
authDomain: "your-project.firebaseapp.com",
|
|
254
|
+
projectId: "your-project-id",
|
|
255
|
+
storageBucket: "your-project.appspot.com",
|
|
256
|
+
messagingSenderId: "123456789",
|
|
257
|
+
appId: "1:123456789:web:abcdef"
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
const MainNavigation = () => {
|
|
261
|
+
const { user } = useAuth();
|
|
262
|
+
|
|
263
|
+
if (!user) {
|
|
264
|
+
return <AuthScreen />;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return <HomeScreen user={user} />;
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
export default function App() {
|
|
271
|
+
return (
|
|
272
|
+
<SafeAreaProvider>
|
|
273
|
+
<AuthProvider config={firebaseConfig}>
|
|
274
|
+
<MainNavigation />
|
|
275
|
+
</AuthProvider>
|
|
276
|
+
</SafeAreaProvider>
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### With Social Login
|
|
282
|
+
|
|
283
|
+
```tsx
|
|
284
|
+
const firebaseConfig = {
|
|
285
|
+
apiKey: "AIzaSyD-Your-Actual-Key",
|
|
286
|
+
authDomain: "your-project.firebaseapp.com",
|
|
287
|
+
projectId: "your-project-id",
|
|
288
|
+
|
|
289
|
+
// Enable social login
|
|
290
|
+
enableGoogle: true,
|
|
291
|
+
enableApple: true, // iOS only
|
|
292
|
+
|
|
293
|
+
// Required for Google Sign-In
|
|
294
|
+
googleWebClientId: "YOUR-CLIENT-ID.apps.googleusercontent.com",
|
|
295
|
+
};
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## 📚 API Reference
|
|
301
|
+
|
|
302
|
+
### `<AuthProvider>`
|
|
303
|
+
|
|
304
|
+
Wraps your app and provides authentication context.
|
|
305
|
+
|
|
306
|
+
**Props:**
|
|
307
|
+
|
|
308
|
+
| Prop | Type | Required | Description |
|
|
309
|
+
|------|------|----------|-------------|
|
|
310
|
+
| `config` | `AuthConfig` | Yes | Firebase configuration object |
|
|
311
|
+
| `children` | `ReactNode` | Yes | Your app components |
|
|
312
|
+
|
|
313
|
+
**AuthConfig Interface:**
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
interface AuthConfig {
|
|
317
|
+
// Firebase credentials (Required)
|
|
318
|
+
apiKey: string;
|
|
319
|
+
authDomain: string;
|
|
320
|
+
projectId: string;
|
|
321
|
+
storageBucket?: string;
|
|
322
|
+
messagingSenderId?: string;
|
|
323
|
+
appId?: string;
|
|
324
|
+
|
|
325
|
+
// Session persistence
|
|
326
|
+
persistence?: 'local' | 'memory'; // Default: 'local'
|
|
327
|
+
|
|
328
|
+
// Feature flags
|
|
329
|
+
enableEmail?: boolean; // Default: true
|
|
330
|
+
enableGoogle?: boolean; // Default: false
|
|
331
|
+
enableApple?: boolean; // Default: false (iOS only)
|
|
332
|
+
|
|
333
|
+
// Google Sign-In
|
|
334
|
+
googleWebClientId?: string;
|
|
335
|
+
googleIosClientId?: string;
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### `useAuth()` Hook
|
|
340
|
+
|
|
341
|
+
Access authentication state and methods.
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
const {
|
|
345
|
+
user, // Current user object or null
|
|
346
|
+
status, // 'AUTHENTICATED' | 'UNAUTHENTICATED' | 'LOADING'
|
|
347
|
+
error, // Last error object or null
|
|
348
|
+
signInWithEmail,
|
|
349
|
+
signUpWithEmail,
|
|
350
|
+
signOut,
|
|
351
|
+
clearError
|
|
352
|
+
} = useAuth();
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**Methods:**
|
|
356
|
+
|
|
357
|
+
| Method | Signature | Description |
|
|
358
|
+
|--------|-----------|-------------|
|
|
359
|
+
| `signInWithEmail` | `(email: string, password: string) => Promise<void>` | Sign in existing user |
|
|
360
|
+
| `signUpWithEmail` | `(email: string, password: string) => Promise<void>` | Create new account |
|
|
361
|
+
| `signOut` | `() => Promise<void>` | Log out current user |
|
|
362
|
+
| `clearError` | `() => void` | Clear error state |
|
|
363
|
+
|
|
364
|
+
### `<AuthScreen>` Component
|
|
365
|
+
|
|
366
|
+
Pre-built authentication UI with login and signup.
|
|
367
|
+
|
|
368
|
+
**Props:**
|
|
369
|
+
|
|
370
|
+
| Prop | Type | Default | Description |
|
|
371
|
+
|------|------|---------|-------------|
|
|
372
|
+
| `styles` | `AuthScreenStyles` | `undefined` | Custom styles object |
|
|
373
|
+
| `titles` | `object` | `undefined` | Custom text labels |
|
|
374
|
+
| `showPasswordHints` | `boolean` | `true` | Show password requirements |
|
|
375
|
+
|
|
376
|
+
**Example:**
|
|
377
|
+
|
|
378
|
+
```tsx
|
|
379
|
+
<AuthScreen
|
|
380
|
+
titles={{
|
|
381
|
+
loginTitle: "Welcome Back",
|
|
382
|
+
loginSubtitle: "Sign in to continue",
|
|
383
|
+
signupTitle: "Create Account",
|
|
384
|
+
signupSubtitle: "Join us today"
|
|
385
|
+
}}
|
|
386
|
+
styles={{
|
|
387
|
+
container: { backgroundColor: '#f5f5f5' },
|
|
388
|
+
button: { backgroundColor: '#007AFF' },
|
|
389
|
+
buttonText: { color: '#ffffff' }
|
|
390
|
+
}}
|
|
391
|
+
showPasswordHints={true}
|
|
392
|
+
/>
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
## 🎨 Customization Examples
|
|
398
|
+
|
|
399
|
+
### Dark Mode Theme
|
|
400
|
+
|
|
401
|
+
```tsx
|
|
402
|
+
<AuthScreen
|
|
403
|
+
styles={{
|
|
404
|
+
container: { backgroundColor: '#1a1a1a' },
|
|
405
|
+
title: { color: '#ffffff', fontSize: 30, fontWeight: '800' },
|
|
406
|
+
subtitle: { color: '#cccccc' },
|
|
407
|
+
input: {
|
|
408
|
+
backgroundColor: '#333333',
|
|
409
|
+
color: '#ffffff',
|
|
410
|
+
borderColor: '#555555'
|
|
411
|
+
},
|
|
412
|
+
button: { backgroundColor: '#FFD700' },
|
|
413
|
+
buttonText: { color: '#000000', fontWeight: 'bold' }
|
|
414
|
+
}}
|
|
415
|
+
/>
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Custom UI (Headless)
|
|
419
|
+
|
|
420
|
+
Build your own interface using the `useAuth()` hook:
|
|
421
|
+
|
|
422
|
+
```tsx
|
|
423
|
+
import { useState } from 'react';
|
|
424
|
+
import { View, TextInput, Button, Text } from 'react-native';
|
|
425
|
+
import { useAuth } from 'swiftauth-sdk';
|
|
426
|
+
|
|
427
|
+
export const CustomLoginScreen = () => {
|
|
428
|
+
const { signInWithEmail, error } = useAuth();
|
|
429
|
+
const [email, setEmail] = useState('');
|
|
430
|
+
const [password, setPassword] = useState('');
|
|
431
|
+
|
|
432
|
+
const handleLogin = async () => {
|
|
433
|
+
try {
|
|
434
|
+
await signInWithEmail(email, password);
|
|
435
|
+
} catch (err) {
|
|
436
|
+
console.error('Login failed:', err);
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
return (
|
|
441
|
+
<View style={{ padding: 20 }}>
|
|
442
|
+
<Text style={{ fontSize: 24, marginBottom: 20 }}>Login</Text>
|
|
443
|
+
|
|
444
|
+
{error && <Text style={{ color: 'red' }}>{error.message}</Text>}
|
|
445
|
+
|
|
446
|
+
<TextInput
|
|
447
|
+
placeholder="Email"
|
|
448
|
+
value={email}
|
|
449
|
+
onChangeText={setEmail}
|
|
450
|
+
style={{ borderWidth: 1, padding: 10, marginBottom: 10 }}
|
|
451
|
+
/>
|
|
452
|
+
|
|
453
|
+
<TextInput
|
|
454
|
+
placeholder="Password"
|
|
455
|
+
value={password}
|
|
456
|
+
onChangeText={setPassword}
|
|
457
|
+
secureTextEntry
|
|
458
|
+
style={{ borderWidth: 1, padding: 10, marginBottom: 20 }}
|
|
459
|
+
/>
|
|
460
|
+
|
|
461
|
+
<Button title="Sign In" onPress={handleLogin} />
|
|
462
|
+
</View>
|
|
463
|
+
);
|
|
464
|
+
};
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
## ⚠️ Error Handling
|
|
470
|
+
|
|
471
|
+
SwiftAuth maps Firebase errors to user-friendly codes:
|
|
472
|
+
|
|
473
|
+
| Error Code | Meaning | User Message |
|
|
474
|
+
|------------|---------|--------------|
|
|
475
|
+
| `auth/invalid-credentials` | Wrong email/password | "Invalid email or password." |
|
|
476
|
+
| `auth/user-not-found` | Account doesn't exist | "Invalid email or password." |
|
|
477
|
+
| `auth/email-already-in-use` | Email already registered | "This email is already registered." |
|
|
478
|
+
| `auth/weak-password` | Password too weak | "Password is too weak." |
|
|
479
|
+
| `auth/network-request-failed` | No internet connection | "Network error. Please check your connection." |
|
|
480
|
+
| `auth/invalid-email` | Invalid email format | "Invalid email address." |
|
|
481
|
+
| `auth/configuration-error` | Missing API keys | "Authentication is not configured correctly." |
|
|
482
|
+
|
|
483
|
+
**Usage:**
|
|
484
|
+
|
|
485
|
+
```tsx
|
|
486
|
+
const { error } = useAuth();
|
|
487
|
+
|
|
488
|
+
if (error) {
|
|
489
|
+
if (error.code === 'auth/network-request-failed') {
|
|
490
|
+
return <OfflineBanner />;
|
|
491
|
+
}
|
|
492
|
+
return <Text style={{ color: 'red' }}>{error.message}</Text>;
|
|
493
|
+
}
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
498
|
+
## 🔐 Session Management
|
|
499
|
+
|
|
500
|
+
### Keep User Logged In (Default)
|
|
501
|
+
|
|
502
|
+
```tsx
|
|
503
|
+
const config = {
|
|
504
|
+
...firebaseConfig,
|
|
505
|
+
persistence: 'local' // User stays logged in
|
|
506
|
+
};
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
### Banking App Mode
|
|
510
|
+
|
|
511
|
+
```tsx
|
|
512
|
+
const config = {
|
|
513
|
+
...firebaseConfig,
|
|
514
|
+
persistence: 'memory' // User logged out when app closes
|
|
515
|
+
};
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
## 🧪 Testing
|
|
521
|
+
|
|
522
|
+
Run the example app to test the SDK:
|
|
523
|
+
|
|
524
|
+
```bash
|
|
525
|
+
cd swiftauth-example
|
|
526
|
+
npm install
|
|
527
|
+
npx expo start
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
## 📖 Full Documentation
|
|
533
|
+
|
|
534
|
+
- [Installation Guide](./docs/installation.md)
|
|
535
|
+
- [Getting Started](./docs/getting-started.md)
|
|
536
|
+
- [API Reference](./docs/api-reference.md)
|
|
537
|
+
- [Usage Examples](./docs/usage-examples.md)
|
|
538
|
+
- [Error Codes](./docs/error-codes.md)
|
|
539
|
+
|
|
540
|
+
---
|
|
541
|
+
|
|
542
|
+
## 🤝 Contributing
|
|
543
|
+
|
|
544
|
+
We welcome contributions! See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
|
|
545
|
+
|
|
546
|
+
---
|
|
547
|
+
|
|
548
|
+
## 📄 License
|
|
549
|
+
|
|
550
|
+
MIT License - see [LICENSE](./LICENSE) file for details.
|
|
551
|
+
|
|
552
|
+
---
|
|
553
|
+
|
|
554
|
+
## 🆘 Support
|
|
555
|
+
|
|
556
|
+
- 📧 Email: support@swiftauth.dev
|
|
557
|
+
- 🐛 Issues: [GitHub Issues](https://github.com/allcodez/Auth-SDK_Stage8/issues)
|
|
558
|
+
- 💬 Discussions: [GitHub Discussions](https://github.com/allcodez/Auth-SDK_Stage8/discussions)
|
|
559
|
+
|
|
560
|
+
---
|
|
561
|
+
|
|
562
|
+
## 🎯 Roadmap
|
|
563
|
+
|
|
564
|
+
- [ ] Password reset functionality
|
|
565
|
+
- [ ] Email verification
|
|
566
|
+
- [ ] Phone authentication
|
|
567
|
+
- [ ] Multi-factor authentication (MFA)
|
|
568
|
+
- [ ] Biometric authentication
|
|
569
|
+
- [ ] Session refresh tokens
|
|
570
|
+
- [ ] NPM package distribution
|
|
571
|
+
|
|
572
|
+
---
|
|
573
|
+
|
|
574
|
+
Made with ❤️ by the SwiftAuth Team
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AuthScreenStyles } from '../types';
|
|
3
|
+
interface AuthScreenProps {
|
|
4
|
+
styles?: AuthScreenStyles;
|
|
5
|
+
titles?: {
|
|
6
|
+
loginTitle?: string;
|
|
7
|
+
loginSubtitle?: string;
|
|
8
|
+
signupTitle?: string;
|
|
9
|
+
signupSubtitle?: string;
|
|
10
|
+
};
|
|
11
|
+
showPasswordHints?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare const AuthScreen: ({ styles: userStyles, titles, showPasswordHints }: AuthScreenProps) => React.JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.AuthScreen = void 0;
|
|
37
|
+
const react_1 = __importStar(require("react"));
|
|
38
|
+
const react_native_1 = require("react-native");
|
|
39
|
+
const react_native_safe_area_context_1 = require("react-native-safe-area-context");
|
|
40
|
+
const LoginForm_1 = require("./LoginForm");
|
|
41
|
+
const SignUpForm_1 = require("./SignUpForm");
|
|
42
|
+
const AuthScreen = ({ styles: userStyles, titles, showPasswordHints = true }) => {
|
|
43
|
+
const [view, setView] = (0, react_1.useState)('login');
|
|
44
|
+
const isLogin = view === 'login';
|
|
45
|
+
return (react_1.default.createElement(react_native_safe_area_context_1.SafeAreaView, { style: [defaultStyles.safeArea, userStyles?.container] },
|
|
46
|
+
react_1.default.createElement(react_native_1.KeyboardAvoidingView, { behavior: react_native_1.Platform.OS === "ios" ? "padding" : "height", style: { flex: 1 } },
|
|
47
|
+
react_1.default.createElement(react_native_1.ScrollView, { contentContainerStyle: defaultStyles.scrollContainer, keyboardShouldPersistTaps: "handled" },
|
|
48
|
+
react_1.default.createElement(react_native_1.View, { style: defaultStyles.innerContainer },
|
|
49
|
+
react_1.default.createElement(react_native_1.View, { style: [defaultStyles.header, userStyles?.header] },
|
|
50
|
+
react_1.default.createElement(react_native_1.Text, { style: [defaultStyles.title, userStyles?.title] }, isLogin
|
|
51
|
+
? (titles?.loginTitle || 'Welcome Back')
|
|
52
|
+
: (titles?.signupTitle || 'Create Account')),
|
|
53
|
+
react_1.default.createElement(react_native_1.Text, { style: [defaultStyles.subtitle, userStyles?.subtitle] }, isLogin
|
|
54
|
+
? (titles?.loginSubtitle || 'Sign in to continue')
|
|
55
|
+
: (titles?.signupSubtitle || 'Sign up to get started'))),
|
|
56
|
+
isLogin
|
|
57
|
+
? react_1.default.createElement(LoginForm_1.LoginForm, { styles: userStyles })
|
|
58
|
+
: react_1.default.createElement(SignUpForm_1.SignUpForm, { styles: userStyles, showHints: showPasswordHints }),
|
|
59
|
+
react_1.default.createElement(react_native_1.View, { style: [defaultStyles.footer, userStyles?.footer] },
|
|
60
|
+
react_1.default.createElement(react_native_1.Text, { style: [defaultStyles.footerText, userStyles?.footerText] }, isLogin ? "Don't have an account?" : "Already have an account?"),
|
|
61
|
+
react_1.default.createElement(react_native_1.TouchableOpacity, { onPress: () => setView(isLogin ? 'signup' : 'login') },
|
|
62
|
+
react_1.default.createElement(react_native_1.Text, { style: [defaultStyles.linkText, userStyles?.linkText] }, isLogin ? ' Sign Up' : ' Sign In'))))))));
|
|
63
|
+
};
|
|
64
|
+
exports.AuthScreen = AuthScreen;
|
|
65
|
+
const defaultStyles = react_native_1.StyleSheet.create({
|
|
66
|
+
safeArea: { flex: 1, backgroundColor: '#fff' },
|
|
67
|
+
scrollContainer: { flexGrow: 1, justifyContent: 'center' },
|
|
68
|
+
innerContainer: { padding: 24, width: '100%', maxWidth: 500, alignSelf: 'center' },
|
|
69
|
+
header: { marginBottom: 32, alignItems: 'center' },
|
|
70
|
+
title: { fontSize: 28, fontWeight: 'bold', color: '#1a1a1a', marginBottom: 8 },
|
|
71
|
+
subtitle: { fontSize: 16, color: '#666', textAlign: 'center' },
|
|
72
|
+
footer: { flexDirection: 'row', justifyContent: 'center', marginTop: 24, marginBottom: 20 },
|
|
73
|
+
footerText: { color: '#666', fontSize: 14 },
|
|
74
|
+
linkText: { color: '#007AFF', fontWeight: '600', fontSize: 14, marginLeft: 5 },
|
|
75
|
+
});
|