binoauth 0.0.11 → 0.0.13
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 +359 -165
- package/dist/core/src/admin/client.d.ts +203 -0
- package/dist/core/src/admin/client.d.ts.map +1 -0
- package/dist/core/src/admin/client.js +391 -0
- package/dist/core/src/admin/client.js.map +1 -0
- package/dist/core/src/admin/index.d.ts +6 -0
- package/dist/core/src/admin/index.d.ts.map +1 -0
- package/dist/core/src/admin/index.js +5 -0
- package/dist/core/src/admin/index.js.map +1 -0
- package/dist/core/src/admin/types.d.ts +412 -0
- package/dist/core/src/admin/types.d.ts.map +1 -0
- package/dist/core/src/admin/types.js +5 -0
- package/dist/core/src/admin/types.js.map +1 -0
- package/dist/core/src/auth/client.d.ts +330 -0
- package/dist/core/src/auth/client.d.ts.map +1 -0
- package/dist/core/src/auth/client.js +408 -0
- package/dist/core/src/auth/client.js.map +1 -0
- package/dist/core/src/auth/error.d.ts +113 -0
- package/dist/core/src/auth/error.d.ts.map +1 -0
- package/dist/core/src/auth/error.js +257 -0
- package/dist/core/src/auth/error.js.map +1 -0
- package/dist/core/src/auth/flows/base-flow.d.ts +98 -0
- package/dist/core/src/auth/flows/base-flow.d.ts.map +1 -0
- package/dist/core/src/auth/flows/base-flow.js +182 -0
- package/dist/core/src/auth/flows/base-flow.js.map +1 -0
- package/dist/core/src/auth/flows/magic-link.d.ts +175 -0
- package/dist/core/src/auth/flows/magic-link.d.ts.map +1 -0
- package/dist/core/src/auth/flows/magic-link.js +228 -0
- package/dist/core/src/auth/flows/magic-link.js.map +1 -0
- package/dist/core/src/auth/flows/mfa.d.ts +81 -0
- package/dist/core/src/auth/flows/mfa.d.ts.map +1 -0
- package/dist/core/src/auth/flows/mfa.js +103 -0
- package/dist/core/src/auth/flows/mfa.js.map +1 -0
- package/dist/core/src/auth/flows/otp.d.ts +172 -0
- package/dist/core/src/auth/flows/otp.d.ts.map +1 -0
- package/dist/core/src/auth/flows/otp.js +222 -0
- package/dist/core/src/auth/flows/otp.js.map +1 -0
- package/dist/core/src/auth/flows/password.d.ts +242 -0
- package/dist/core/src/auth/flows/password.d.ts.map +1 -0
- package/dist/core/src/auth/flows/password.js +344 -0
- package/dist/core/src/auth/flows/password.js.map +1 -0
- package/dist/core/src/auth/flows/social.d.ts +209 -0
- package/dist/core/src/auth/flows/social.d.ts.map +1 -0
- package/dist/core/src/auth/flows/social.js +284 -0
- package/dist/core/src/auth/flows/social.js.map +1 -0
- package/dist/core/src/auth/index.d.ts +19 -0
- package/dist/core/src/auth/index.d.ts.map +1 -0
- package/dist/core/src/auth/index.js +32 -0
- package/dist/core/src/auth/index.js.map +1 -0
- package/dist/core/src/auth/types.d.ts +151 -0
- package/dist/core/src/auth/types.d.ts.map +1 -0
- package/dist/core/src/auth/types.js +7 -0
- package/dist/core/src/auth/types.js.map +1 -0
- package/dist/core/src/index.d.ts +53 -49
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/index.js +61 -343
- package/dist/core/src/index.js.map +1 -1
- package/dist/core/src/oauth/client.d.ts +322 -0
- package/dist/core/src/oauth/client.d.ts.map +1 -0
- package/dist/core/src/oauth/client.js +491 -0
- package/dist/core/src/oauth/client.js.map +1 -0
- package/dist/core/src/oauth/error.d.ts +18 -0
- package/dist/core/src/oauth/error.d.ts.map +1 -0
- package/dist/core/src/oauth/error.js +24 -0
- package/dist/core/src/oauth/error.js.map +1 -0
- package/dist/core/src/oauth/flows/authorization-code.d.ts +122 -0
- package/dist/core/src/oauth/flows/authorization-code.d.ts.map +1 -0
- package/dist/core/src/oauth/flows/authorization-code.js +278 -0
- package/dist/core/src/oauth/flows/authorization-code.js.map +1 -0
- package/dist/core/src/oauth/flows/base-flow.d.ts +17 -0
- package/dist/core/src/oauth/flows/base-flow.d.ts.map +1 -0
- package/dist/core/src/oauth/flows/base-flow.js +107 -0
- package/dist/core/src/oauth/flows/base-flow.js.map +1 -0
- package/dist/core/src/oauth/flows/client-credentials.d.ts +72 -0
- package/dist/core/src/oauth/flows/client-credentials.d.ts.map +1 -0
- package/dist/core/src/oauth/flows/client-credentials.js +100 -0
- package/dist/core/src/oauth/flows/client-credentials.js.map +1 -0
- package/dist/core/src/oauth/flows/device-code.d.ts +108 -0
- package/dist/core/src/oauth/flows/device-code.d.ts.map +1 -0
- package/dist/core/src/oauth/flows/device-code.js +193 -0
- package/dist/core/src/oauth/flows/device-code.js.map +1 -0
- package/dist/core/src/oauth/flows/refresh-token.d.ts +59 -0
- package/dist/core/src/oauth/flows/refresh-token.d.ts.map +1 -0
- package/dist/core/src/oauth/flows/refresh-token.js +105 -0
- package/dist/core/src/oauth/flows/refresh-token.js.map +1 -0
- package/dist/core/src/oauth/index.d.ts +12 -0
- package/dist/core/src/oauth/index.d.ts.map +1 -0
- package/dist/core/src/oauth/index.js +11 -0
- package/dist/core/src/oauth/index.js.map +1 -0
- package/dist/core/src/oauth/storage/encryption.d.ts +12 -0
- package/dist/core/src/oauth/storage/encryption.d.ts.map +1 -0
- package/dist/core/src/oauth/storage/encryption.js +76 -0
- package/dist/core/src/oauth/storage/encryption.js.map +1 -0
- package/dist/core/src/oauth/storage/index.d.ts +201 -0
- package/dist/core/src/oauth/storage/index.d.ts.map +1 -0
- package/dist/core/src/oauth/storage/index.js +322 -0
- package/dist/core/src/oauth/storage/index.js.map +1 -0
- package/dist/core/src/oauth/storage/strategies.d.ts +34 -0
- package/dist/core/src/oauth/storage/strategies.d.ts.map +1 -0
- package/dist/core/src/oauth/storage/strategies.js +100 -0
- package/dist/core/src/oauth/storage/strategies.js.map +1 -0
- package/dist/core/src/oauth/types.d.ts +261 -0
- package/dist/core/src/oauth/types.d.ts.map +1 -0
- package/dist/core/src/oauth/types.js +39 -0
- package/dist/core/src/oauth/types.js.map +1 -0
- package/dist/core/src/oauth/utils.d.ts +56 -0
- package/dist/core/src/oauth/utils.d.ts.map +1 -0
- package/dist/core/src/oauth/utils.js +140 -0
- package/dist/core/src/oauth/utils.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
@@ -1,6 +1,16 @@
|
|
1
|
-
#
|
1
|
+
# BinoAuth Core SDK
|
2
2
|
|
3
|
-
A
|
3
|
+
A comprehensive TypeScript SDK for BinoAuth authentication platform with support for multiple authentication flows, user management, and admin operations.
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
- **Multiple Authentication Methods**: Password, Magic Link, OTP, OAuth 2.0, Social Login
|
8
|
+
- **Multi-Factor Authentication**: TOTP, SMS, Email verification
|
9
|
+
- **Admin Operations**: User management, tenant management, API key management
|
10
|
+
- **Secure Token Storage**: Encrypted token storage with multiple strategies
|
11
|
+
- **Cross-Platform**: Works in browsers, Node.js, React Native
|
12
|
+
- **Type Safe**: Full TypeScript support with comprehensive types
|
13
|
+
- **OAuth 2.0 Complete**: Authorization Code, Device Code, Client Credentials, and Refresh Token flows
|
4
14
|
|
5
15
|
## Installation
|
6
16
|
|
@@ -14,274 +24,458 @@ bun add binoauth
|
|
14
24
|
|
15
25
|
## Quick Start
|
16
26
|
|
27
|
+
### Basic Authentication
|
28
|
+
|
17
29
|
```typescript
|
18
|
-
import
|
30
|
+
import { BinoAuthClient } from 'binoauth';
|
19
31
|
|
20
|
-
const auth = new
|
21
|
-
|
22
|
-
|
32
|
+
const auth = new BinoAuthClient({
|
33
|
+
issuer: 'https://auth.binoauth.com',
|
34
|
+
clientId: 'your_client_id',
|
35
|
+
redirectUri: 'https://yourapp.com/callback'
|
23
36
|
});
|
24
37
|
|
25
|
-
//
|
26
|
-
const
|
27
|
-
if (
|
28
|
-
console.log(
|
38
|
+
// Password authentication
|
39
|
+
const result = await auth.loginWithPassword('user@example.com', 'password123');
|
40
|
+
if (result.success) {
|
41
|
+
console.log('Welcome,', result.user.name);
|
29
42
|
}
|
30
43
|
|
31
|
-
//
|
32
|
-
|
33
|
-
email:
|
34
|
-
|
44
|
+
// Magic link authentication
|
45
|
+
await auth.magicLink.sendMagicLink({
|
46
|
+
email: 'user@example.com',
|
47
|
+
returnTo: 'https://yourapp.com/dashboard'
|
35
48
|
});
|
36
49
|
|
37
|
-
|
38
|
-
|
39
|
-
}
|
50
|
+
// Check authentication status
|
51
|
+
const isLoggedIn = await auth.isAuthenticated();
|
40
52
|
```
|
41
53
|
|
42
|
-
|
43
|
-
|
44
|
-
### Authentication Methods
|
54
|
+
### OAuth 2.0 Flow
|
45
55
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
56
|
+
```typescript
|
57
|
+
// Authorization Code Flow
|
58
|
+
const authUrl = await auth.oauth.getAuthorizationUrl();
|
59
|
+
window.location.href = authUrl;
|
60
|
+
|
61
|
+
// Handle callback
|
62
|
+
const urlParams = new URLSearchParams(window.location.search);
|
63
|
+
await auth.oauth.handleCallback(
|
64
|
+
urlParams.get('code')!,
|
65
|
+
urlParams.get('state')!
|
66
|
+
);
|
67
|
+
|
68
|
+
// Device Code Flow (for devices without browsers)
|
69
|
+
const deviceAuth = await auth.oauth.requestDeviceCode();
|
70
|
+
console.log(`Visit: ${deviceAuth.verification_uri}`);
|
71
|
+
console.log(`Enter code: ${deviceAuth.user_code}`);
|
72
|
+
|
73
|
+
// Poll for authorization
|
74
|
+
await auth.oauth.pollForToken(deviceAuth.device_code);
|
75
|
+
```
|
51
76
|
|
52
|
-
|
77
|
+
## Authentication Flows
|
53
78
|
|
54
|
-
|
55
|
-
- **Refresh Tokens**: Automatic token refresh capabilities
|
56
|
-
- **Session Management**: Secure logout and session invalidation
|
79
|
+
### 1. Password Authentication
|
57
80
|
|
58
|
-
|
81
|
+
```typescript
|
82
|
+
import { PasswordFlow } from 'binoauth';
|
59
83
|
|
60
|
-
|
61
|
-
- **User Administration**: Create, read, update, delete users (admin API)
|
84
|
+
const passwordFlow = new PasswordFlow(config);
|
62
85
|
|
63
|
-
|
86
|
+
// Login
|
87
|
+
const result = await passwordFlow.login('user@example.com', 'password123');
|
64
88
|
|
65
|
-
|
89
|
+
// Register new user
|
90
|
+
await passwordFlow.register({
|
91
|
+
email: 'newuser@example.com',
|
92
|
+
password: 'securepassword',
|
93
|
+
name: 'John Doe',
|
94
|
+
acceptTerms: true
|
95
|
+
});
|
66
96
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
97
|
+
// Login with credentials object
|
98
|
+
await passwordFlow.loginWithCredentials({
|
99
|
+
email: 'user@example.com',
|
100
|
+
password: 'password123',
|
101
|
+
rememberMe: true
|
72
102
|
});
|
73
103
|
```
|
74
104
|
|
75
|
-
### Authentication
|
76
|
-
|
77
|
-
#### `sendEmailOTP(email: string)`
|
78
|
-
|
79
|
-
Send an OTP code to the user's email address.
|
105
|
+
### 2. Magic Link Authentication
|
80
106
|
|
81
107
|
```typescript
|
82
|
-
|
83
|
-
```
|
108
|
+
import { MagicLinkFlow } from 'binoauth';
|
84
109
|
|
85
|
-
|
110
|
+
const magicLinkFlow = new MagicLinkFlow(config);
|
86
111
|
|
87
|
-
Send
|
112
|
+
// Send magic link
|
113
|
+
await magicLinkFlow.sendMagicLink({
|
114
|
+
email: 'user@example.com',
|
115
|
+
returnTo: 'https://yourapp.com/dashboard'
|
116
|
+
});
|
88
117
|
|
89
|
-
|
90
|
-
const result = await
|
91
|
-
```
|
118
|
+
// Verify magic link token
|
119
|
+
const result = await magicLinkFlow.verifyMagicLink(token);
|
92
120
|
|
93
|
-
|
121
|
+
// Verify magic link code
|
122
|
+
const result = await magicLinkFlow.verifyMagicLinkCode(code);
|
123
|
+
```
|
94
124
|
|
95
|
-
|
125
|
+
### 3. OTP Authentication
|
96
126
|
|
97
127
|
```typescript
|
98
|
-
|
99
|
-
```
|
100
|
-
|
101
|
-
#### `login(type: 'password' | 'otp', credentials: LoginCredentials)`
|
128
|
+
import { OTPFlow } from 'binoauth';
|
102
129
|
|
103
|
-
|
130
|
+
const otpFlow = new OTPFlow(config);
|
104
131
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
email: "user@example.com",
|
109
|
-
password: "password123",
|
132
|
+
// Send phone OTP
|
133
|
+
await otpFlow.sendPhoneOTP({
|
134
|
+
phoneNumber: '+1234567890'
|
110
135
|
});
|
111
136
|
|
112
|
-
// OTP
|
113
|
-
const result = await
|
114
|
-
|
115
|
-
|
137
|
+
// Verify phone OTP
|
138
|
+
const result = await otpFlow.verifyPhoneOTP({
|
139
|
+
phoneNumber: '+1234567890',
|
140
|
+
code: '123456'
|
116
141
|
});
|
117
142
|
```
|
118
143
|
|
119
|
-
###
|
120
|
-
|
121
|
-
#### `sendResetPasswordEmailOTP(email: string)`
|
122
|
-
|
123
|
-
Send a password reset OTP to email.
|
144
|
+
### 4. Multi-Factor Authentication
|
124
145
|
|
125
146
|
```typescript
|
126
|
-
|
127
|
-
```
|
147
|
+
import { MFAFlow } from 'binoauth';
|
128
148
|
|
129
|
-
|
149
|
+
const mfaFlow = new MFAFlow(config);
|
130
150
|
|
131
|
-
Send
|
151
|
+
// Send MFA challenge
|
152
|
+
await mfaFlow.sendMFAChallenge({
|
153
|
+
challengeId: 'challenge_123',
|
154
|
+
method: 'sms'
|
155
|
+
});
|
132
156
|
|
133
|
-
|
134
|
-
const result = await
|
157
|
+
// Verify MFA challenge
|
158
|
+
const result = await mfaFlow.verifyMFAChallenge({
|
159
|
+
challengeId: 'challenge_123',
|
160
|
+
code: '123456',
|
161
|
+
method: 'sms'
|
162
|
+
});
|
135
163
|
```
|
136
164
|
|
137
|
-
|
138
|
-
|
139
|
-
Reset user password with OTP verification.
|
165
|
+
### 5. Social Authentication
|
140
166
|
|
141
167
|
```typescript
|
142
|
-
|
143
|
-
otp: "123456",
|
144
|
-
newPassword: "newpassword123",
|
145
|
-
repeatNewPassword: "newpassword123",
|
146
|
-
});
|
147
|
-
```
|
168
|
+
import { SocialFlow } from 'binoauth';
|
148
169
|
|
149
|
-
|
170
|
+
const socialFlow = new SocialFlow(config);
|
150
171
|
|
151
|
-
|
172
|
+
// Get authentication URL for provider
|
173
|
+
const googleUrl = await socialFlow.getAuthUrl('google');
|
174
|
+
window.location.href = googleUrl;
|
152
175
|
|
153
|
-
|
176
|
+
// Handle callback
|
177
|
+
const result = await socialFlow.handleCallback('google', code, state);
|
154
178
|
|
155
|
-
|
156
|
-
const
|
179
|
+
// Get available providers
|
180
|
+
const providers = await socialFlow.getAvailableProviders();
|
157
181
|
```
|
158
182
|
|
159
|
-
|
183
|
+
## OAuth 2.0 Flows
|
160
184
|
|
161
|
-
|
185
|
+
### Authorization Code Flow
|
162
186
|
|
163
187
|
```typescript
|
164
|
-
|
165
|
-
```
|
188
|
+
import { BinoAuthOAuth } from 'binoauth';
|
166
189
|
|
167
|
-
|
190
|
+
const oauth = new BinoAuthOAuth(config, storageConfig);
|
168
191
|
|
169
|
-
|
192
|
+
// Get authorization URL
|
193
|
+
const authUrl = await oauth.getAuthorizationUrl();
|
170
194
|
|
171
|
-
|
172
|
-
|
173
|
-
```typescript
|
174
|
-
const result = await auth.getProfile();
|
195
|
+
// Handle callback
|
196
|
+
const result = await oauth.handleCallback(code, state);
|
175
197
|
```
|
176
198
|
|
177
199
|
### Device Code Flow
|
178
200
|
|
179
|
-
|
201
|
+
```typescript
|
202
|
+
// Request device code
|
203
|
+
const deviceAuth = await oauth.requestDeviceCode();
|
204
|
+
|
205
|
+
// Poll for token
|
206
|
+
await oauth.pollForToken(deviceAuth.device_code);
|
207
|
+
```
|
180
208
|
|
181
|
-
|
209
|
+
### Client Credentials Flow
|
182
210
|
|
183
211
|
```typescript
|
184
|
-
|
185
|
-
|
186
|
-
console.log(`Code: ${result.data.user_code}`);
|
212
|
+
// Get client credentials token
|
213
|
+
const tokenSet = await oauth.getClientCredentialsToken();
|
187
214
|
```
|
188
215
|
|
189
|
-
|
190
|
-
|
191
|
-
Poll for device authorization completion.
|
216
|
+
### Refresh Token Flow
|
192
217
|
|
193
218
|
```typescript
|
194
|
-
|
219
|
+
// Refresh access token
|
220
|
+
const newTokenSet = await oauth.refreshAccessToken();
|
195
221
|
```
|
196
222
|
|
197
|
-
|
223
|
+
## Admin Operations
|
198
224
|
|
199
|
-
|
225
|
+
```typescript
|
226
|
+
import { AdminClient } from 'binoauth';
|
200
227
|
|
201
|
-
|
228
|
+
const adminClient = new AdminClient({
|
229
|
+
baseUrl: 'https://auth.binoauth.com',
|
230
|
+
apiKey: 'admin_api_key',
|
231
|
+
tenantId: 'your_tenant_id'
|
232
|
+
});
|
202
233
|
|
203
|
-
|
204
|
-
const
|
234
|
+
// User management
|
235
|
+
const users = await adminClient.getUsers();
|
236
|
+
const user = await adminClient.getUser('user_id');
|
237
|
+
|
238
|
+
// Tenant management
|
239
|
+
const tenants = await adminClient.listTenants();
|
240
|
+
const tenant = await adminClient.getTenant('tenant_id');
|
241
|
+
await adminClient.createTenant(tenantData);
|
242
|
+
await adminClient.updateTenant('tenant_id', updateData);
|
243
|
+
|
244
|
+
// API key management
|
245
|
+
const apiKeys = await adminClient.listApiKeys();
|
246
|
+
const apiKey = await adminClient.createApiKey(apiKeyData);
|
247
|
+
await adminClient.revokeApiKey('key_id');
|
248
|
+
|
249
|
+
// OAuth client management
|
250
|
+
const clients = await adminClient.listClients();
|
251
|
+
const client = await adminClient.createClient(clientData);
|
252
|
+
const clientInfo = await adminClient.getClient('client_id');
|
253
|
+
|
254
|
+
// Provider management
|
255
|
+
const providers = await adminClient.listProviders();
|
256
|
+
const provider = await adminClient.createProvider(providerData);
|
257
|
+
|
258
|
+
// Statistics and health
|
259
|
+
const stats = await adminClient.getStats();
|
260
|
+
const health = await adminClient.healthCheck();
|
261
|
+
|
262
|
+
// Admin authentication
|
263
|
+
const adminAuth = await adminClient.adminLogin('admin@example.com', 'password');
|
264
|
+
const currentAdmin = await adminClient.getCurrentAdmin();
|
265
|
+
await adminClient.adminLogout();
|
205
266
|
```
|
206
267
|
|
207
|
-
|
268
|
+
## Configuration
|
208
269
|
|
209
|
-
|
270
|
+
### Basic Configuration
|
210
271
|
|
211
272
|
```typescript
|
212
|
-
const
|
273
|
+
const config = {
|
274
|
+
issuer: 'https://auth.binoauth.com',
|
275
|
+
clientId: 'your_client_id',
|
276
|
+
redirectUri: 'https://yourapp.com/callback'
|
277
|
+
};
|
213
278
|
```
|
214
279
|
|
215
|
-
|
216
|
-
|
217
|
-
Create a new user (not implemented in current admin SDK).
|
280
|
+
### Advanced Configuration
|
218
281
|
|
219
|
-
|
220
|
-
|
221
|
-
|
282
|
+
```typescript
|
283
|
+
const config = {
|
284
|
+
issuer: 'https://auth.binoauth.com',
|
285
|
+
clientId: 'your_client_id',
|
286
|
+
clientSecret: 'your_client_secret', // For server-side apps
|
287
|
+
redirectUri: 'https://yourapp.com/callback',
|
288
|
+
scope: 'openid profile email',
|
289
|
+
|
290
|
+
// OAuth endpoints (auto-discovered by default)
|
291
|
+
authorizeEndpoint: 'https://auth.binoauth.com/oauth/authorize',
|
292
|
+
tokenEndpoint: 'https://auth.binoauth.com/oauth/token',
|
293
|
+
userinfoEndpoint: 'https://auth.binoauth.com/oauth/userinfo',
|
294
|
+
|
295
|
+
// Additional config
|
296
|
+
tenant: 'your_tenant_id',
|
297
|
+
apiKey: 'your_api_key'
|
298
|
+
};
|
299
|
+
```
|
222
300
|
|
223
|
-
|
301
|
+
### Token Storage Configuration
|
224
302
|
|
225
|
-
|
303
|
+
```typescript
|
304
|
+
import { LocalStorageTokenStorage, SessionStorageTokenStorage, InMemoryTokenStorage } from 'binoauth';
|
226
305
|
|
227
|
-
|
306
|
+
// Use localStorage (default for browsers)
|
307
|
+
const storage = new LocalStorageTokenStorage({
|
308
|
+
clientId: 'your_client_id',
|
309
|
+
encryptionKey: 'your-encryption-key'
|
310
|
+
});
|
228
311
|
|
229
|
-
|
312
|
+
// Use sessionStorage (cleared when browser closes)
|
313
|
+
const sessionStorage = new SessionStorageTokenStorage({
|
314
|
+
clientId: 'your_client_id',
|
315
|
+
encryptionKey: 'your-encryption-key'
|
316
|
+
});
|
230
317
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
error_description?: string; // Detailed error description (if failed)
|
237
|
-
}
|
318
|
+
// Use in-memory storage (for server-side or testing)
|
319
|
+
const memoryStorage = new InMemoryTokenStorage({
|
320
|
+
clientId: 'your_client_id',
|
321
|
+
encryptionKey: 'your-encryption-key'
|
322
|
+
});
|
238
323
|
```
|
239
324
|
|
240
325
|
## Error Handling
|
241
326
|
|
242
327
|
```typescript
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
if (
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
328
|
+
import { AuthError, AuthErrorCode } from 'binoauth';
|
329
|
+
|
330
|
+
try {
|
331
|
+
await auth.loginWithPassword('user@example.com', 'wrong_password');
|
332
|
+
} catch (error) {
|
333
|
+
if (error instanceof AuthError) {
|
334
|
+
switch (error.code) {
|
335
|
+
case AuthErrorCode.INVALID_CREDENTIALS:
|
336
|
+
console.log('Invalid email or password');
|
337
|
+
break;
|
338
|
+
case AuthErrorCode.MFA_REQUIRED:
|
339
|
+
console.log('MFA required:', error.details);
|
340
|
+
break;
|
341
|
+
case AuthErrorCode.ACCOUNT_LOCKED:
|
342
|
+
console.log('Account is locked');
|
343
|
+
break;
|
344
|
+
case AuthErrorCode.ACCOUNT_NOT_FOUND:
|
345
|
+
console.log('Account not found');
|
346
|
+
break;
|
347
|
+
case AuthErrorCode.NETWORK_ERROR:
|
348
|
+
console.log('Network connection error');
|
349
|
+
break;
|
350
|
+
default:
|
351
|
+
console.log('Auth error:', error.message);
|
352
|
+
}
|
353
|
+
}
|
253
354
|
}
|
254
355
|
```
|
255
356
|
|
256
|
-
##
|
357
|
+
## TypeScript Support
|
257
358
|
|
258
|
-
|
359
|
+
The SDK is built with TypeScript and provides comprehensive type definitions:
|
259
360
|
|
260
|
-
|
261
|
-
|
262
|
-
|
361
|
+
```typescript
|
362
|
+
import type {
|
363
|
+
AuthConfig,
|
364
|
+
AuthResult,
|
365
|
+
User,
|
366
|
+
LoginRequest,
|
367
|
+
SignupRequest,
|
368
|
+
TokenSet,
|
369
|
+
MFAChallenge,
|
370
|
+
AdminConfig
|
371
|
+
} from 'binoauth';
|
372
|
+
|
373
|
+
// All methods are fully typed
|
374
|
+
const result: AuthResult = await auth.loginWithPassword(email, password);
|
375
|
+
const user: User = result.user;
|
376
|
+
```
|
263
377
|
|
264
|
-
##
|
378
|
+
## Available Error Codes
|
379
|
+
|
380
|
+
- `INVALID_CREDENTIALS` - Invalid email or password
|
381
|
+
- `INVALID_EMAIL` - Invalid email format
|
382
|
+
- `INVALID_PASSWORD` - Invalid password
|
383
|
+
- `INVALID_OTP` - Invalid OTP code
|
384
|
+
- `EXPIRED_OTP` - OTP code has expired
|
385
|
+
- `INVALID_TOKEN` - Invalid or expired token
|
386
|
+
- `ACCOUNT_NOT_FOUND` - User account not found
|
387
|
+
- `ACCOUNT_LOCKED` - Account is locked
|
388
|
+
- `ACCOUNT_DISABLED` - Account is disabled
|
389
|
+
- `EMAIL_NOT_VERIFIED` - Email verification required
|
390
|
+
- `MFA_REQUIRED` - Multi-factor authentication required
|
391
|
+
- `TOO_MANY_ATTEMPTS` - Too many failed attempts
|
392
|
+
- `RATE_LIMITED` - Rate limit exceeded
|
393
|
+
- `EMAIL_ALREADY_EXISTS` - Email already registered
|
394
|
+
- `WEAK_PASSWORD` - Password is too weak
|
395
|
+
- `NETWORK_ERROR` - Network connection error
|
396
|
+
- `SERVER_ERROR` - Server error
|
397
|
+
- `INVALID_CONFIG` - Invalid configuration
|
398
|
+
- `OAUTH_ERROR` - OAuth-specific error
|
399
|
+
|
400
|
+
## Examples
|
401
|
+
|
402
|
+
### React Integration
|
265
403
|
|
266
|
-
```
|
267
|
-
|
268
|
-
|
404
|
+
```typescript
|
405
|
+
import { BinoAuthClient } from 'binoauth';
|
406
|
+
import { useEffect, useState } from 'react';
|
407
|
+
|
408
|
+
function App() {
|
409
|
+
const [auth] = useState(() => new BinoAuthClient(config));
|
410
|
+
const [user, setUser] = useState(null);
|
411
|
+
|
412
|
+
useEffect(() => {
|
413
|
+
auth.isAuthenticated().then(isAuth => {
|
414
|
+
if (isAuth) {
|
415
|
+
auth.getUser().then(setUser);
|
416
|
+
}
|
417
|
+
});
|
418
|
+
}, []);
|
419
|
+
|
420
|
+
const handleLogin = async (email, password) => {
|
421
|
+
try {
|
422
|
+
const result = await auth.loginWithPassword(email, password);
|
423
|
+
if (result.success) {
|
424
|
+
setUser(result.user);
|
425
|
+
}
|
426
|
+
} catch (error) {
|
427
|
+
console.error('Login failed:', error.message);
|
428
|
+
}
|
429
|
+
};
|
430
|
+
|
431
|
+
return (
|
432
|
+
<div>
|
433
|
+
{user ? (
|
434
|
+
<div>Welcome, {user.name}!</div>
|
435
|
+
) : (
|
436
|
+
<LoginForm onLogin={handleLogin} />
|
437
|
+
)}
|
438
|
+
</div>
|
439
|
+
);
|
440
|
+
}
|
441
|
+
```
|
442
|
+
|
443
|
+
### Node.js Server
|
269
444
|
|
270
|
-
|
271
|
-
|
445
|
+
```typescript
|
446
|
+
import { BinoAuthClient } from 'binoauth';
|
447
|
+
import express from 'express';
|
448
|
+
|
449
|
+
const app = express();
|
450
|
+
const auth = new BinoAuthClient({
|
451
|
+
issuer: 'https://auth.binoauth.com',
|
452
|
+
clientId: process.env.BINOAUTH_CLIENT_ID,
|
453
|
+
clientSecret: process.env.BINOAUTH_CLIENT_SECRET,
|
454
|
+
redirectUri: 'https://yourapp.com/callback'
|
455
|
+
});
|
272
456
|
|
273
|
-
|
274
|
-
|
457
|
+
app.get('/auth/callback', async (req, res) => {
|
458
|
+
try {
|
459
|
+
const result = await auth.oauth.handleCallback(
|
460
|
+
req.query.code,
|
461
|
+
req.query.state
|
462
|
+
);
|
463
|
+
|
464
|
+
// Store tokens and redirect
|
465
|
+
req.session.tokens = result.tokens;
|
466
|
+
res.redirect('/dashboard');
|
467
|
+
} catch (error) {
|
468
|
+
res.status(401).send('Authentication failed');
|
469
|
+
}
|
470
|
+
});
|
275
471
|
```
|
276
472
|
|
277
473
|
## License
|
278
474
|
|
279
|
-
MIT
|
475
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
280
476
|
|
281
477
|
## Support
|
282
478
|
|
283
|
-
|
284
|
-
|
285
|
-
-
|
286
|
-
- Email: support@binoauth.com
|
287
|
-
- Documentation: [docs.binoauth.com](https://docs.binoauth.com)
|
479
|
+
- **Documentation**: [https://docs.binoauth.com](https://docs.binoauth.com)
|
480
|
+
- **Issues**: [GitHub Issues](https://github.com/binoauth/binoauth/issues)
|
481
|
+
- **Email**: support@binoauth.com
|