binoauth 0.0.1
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/CHANGELOG.md +7 -0
- package/README.md +265 -0
- package/dist/esm/index.d.ts +51 -0
- package/dist/esm/index.js +343 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.js +347 -0
- package/package.json +47 -0
- package/src/index.ts +387 -0
- package/tsconfig.esm.json +8 -0
- package/tsconfig.json +23 -0
package/CHANGELOG.md
ADDED
package/README.md
ADDED
@@ -0,0 +1,265 @@
|
|
1
|
+
# binoauth
|
2
|
+
|
3
|
+
A simplified Node.js SDK for BinoAuth authentication that provides OAuth2-compatible tokens without the complexity of traditional OAuth2 flows.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
```bash
|
8
|
+
npm install binoauth
|
9
|
+
# or
|
10
|
+
yarn add binoauth
|
11
|
+
# or
|
12
|
+
bun add binoauth
|
13
|
+
```
|
14
|
+
|
15
|
+
## Quick Start
|
16
|
+
|
17
|
+
```typescript
|
18
|
+
import BinoAuth from 'binoauth';
|
19
|
+
|
20
|
+
const auth = new BinoAuth({
|
21
|
+
apiKey: 'ak_live_your_api_key',
|
22
|
+
tenant: 'your-tenant-id'
|
23
|
+
});
|
24
|
+
|
25
|
+
// Email OTP
|
26
|
+
const resp = await auth.sendEmailOTP('user@example.com');
|
27
|
+
if (resp.ok) {
|
28
|
+
console.log('OTP sent successfully');
|
29
|
+
}
|
30
|
+
|
31
|
+
// Login with password
|
32
|
+
const loginResp = await auth.login('password', {
|
33
|
+
email: 'user@example.com',
|
34
|
+
password: 'password123'
|
35
|
+
});
|
36
|
+
|
37
|
+
if (loginResp.ok) {
|
38
|
+
console.log('Login successful:', loginResp.data);
|
39
|
+
}
|
40
|
+
```
|
41
|
+
|
42
|
+
## Features
|
43
|
+
|
44
|
+
### Authentication Methods
|
45
|
+
- **Email OTP**: Send and verify email-based one-time passwords
|
46
|
+
- **Phone OTP**: Send and verify SMS-based one-time passwords
|
47
|
+
- **Password Login**: Traditional email/password authentication
|
48
|
+
- **Magic Links**: Passwordless email-based authentication
|
49
|
+
- **Device Code Flow**: For CLI applications and IoT devices
|
50
|
+
|
51
|
+
### Token Management
|
52
|
+
- **OAuth2 Compatible**: All tokens work with existing OAuth2 resource servers
|
53
|
+
- **Refresh Tokens**: Automatic token refresh capabilities
|
54
|
+
- **Session Management**: Secure logout and session invalidation
|
55
|
+
|
56
|
+
### User Management
|
57
|
+
- **Profile Access**: Get and update user profiles
|
58
|
+
- **User Administration**: Create, read, update, delete users (admin API)
|
59
|
+
|
60
|
+
## API Reference
|
61
|
+
|
62
|
+
### Constructor
|
63
|
+
|
64
|
+
```typescript
|
65
|
+
const auth = new BinoAuth({
|
66
|
+
apiKey: string; // Your BinoAuth API key
|
67
|
+
tenant: string; // Your tenant ID
|
68
|
+
baseUrl?: string; // Optional: Custom API base URL
|
69
|
+
});
|
70
|
+
```
|
71
|
+
|
72
|
+
### Authentication Methods
|
73
|
+
|
74
|
+
#### `sendEmailOTP(email: string)`
|
75
|
+
Send an OTP code to the user's email address.
|
76
|
+
|
77
|
+
```typescript
|
78
|
+
const result = await auth.sendEmailOTP('user@example.com');
|
79
|
+
```
|
80
|
+
|
81
|
+
#### `sendPhoneOTP(phone: string)`
|
82
|
+
Send an OTP code to the user's phone number.
|
83
|
+
|
84
|
+
```typescript
|
85
|
+
const result = await auth.sendPhoneOTP('+1234567890');
|
86
|
+
```
|
87
|
+
|
88
|
+
#### `sendMagicLink(email: string)`
|
89
|
+
Send a magic link to the user's email address.
|
90
|
+
|
91
|
+
```typescript
|
92
|
+
const result = await auth.sendMagicLink('user@example.com');
|
93
|
+
```
|
94
|
+
|
95
|
+
#### `login(type: 'password' | 'otp', credentials: LoginCredentials)`
|
96
|
+
Authenticate a user with different methods.
|
97
|
+
|
98
|
+
```typescript
|
99
|
+
// Password login
|
100
|
+
const result = await auth.login('password', {
|
101
|
+
email: 'user@example.com',
|
102
|
+
password: 'password123'
|
103
|
+
});
|
104
|
+
|
105
|
+
// OTP login
|
106
|
+
const result = await auth.login('otp', {
|
107
|
+
otp: '123456',
|
108
|
+
phone: '+1234567890' // Optional: specify if phone OTP
|
109
|
+
});
|
110
|
+
```
|
111
|
+
|
112
|
+
### Password Reset
|
113
|
+
|
114
|
+
#### `sendResetPasswordEmailOTP(email: string)`
|
115
|
+
Send a password reset OTP to email.
|
116
|
+
|
117
|
+
```typescript
|
118
|
+
const result = await auth.sendResetPasswordEmailOTP('user@example.com');
|
119
|
+
```
|
120
|
+
|
121
|
+
#### `sendResetPasswordPhoneOTP(phone: string)`
|
122
|
+
Send a password reset OTP to phone.
|
123
|
+
|
124
|
+
```typescript
|
125
|
+
const result = await auth.sendResetPasswordPhoneOTP('+1234567890');
|
126
|
+
```
|
127
|
+
|
128
|
+
#### `resetPassword(params: ResetPasswordParams)`
|
129
|
+
Reset user password with OTP verification.
|
130
|
+
|
131
|
+
```typescript
|
132
|
+
const result = await auth.resetPassword({
|
133
|
+
otp: '123456',
|
134
|
+
newPassword: 'newpassword123',
|
135
|
+
repeatNewPassword: 'newpassword123'
|
136
|
+
});
|
137
|
+
```
|
138
|
+
|
139
|
+
### Token Management
|
140
|
+
|
141
|
+
#### `refreshToken(refreshToken: string)`
|
142
|
+
Refresh an access token using a refresh token.
|
143
|
+
|
144
|
+
```typescript
|
145
|
+
const result = await auth.refreshToken('refresh_token_here');
|
146
|
+
```
|
147
|
+
|
148
|
+
#### `logout(accessToken?: string)`
|
149
|
+
Logout and invalidate session.
|
150
|
+
|
151
|
+
```typescript
|
152
|
+
const result = await auth.logout('access_token_here');
|
153
|
+
```
|
154
|
+
|
155
|
+
### User Profile
|
156
|
+
|
157
|
+
#### `getProfile()`
|
158
|
+
Get the current user's profile information.
|
159
|
+
|
160
|
+
```typescript
|
161
|
+
const result = await auth.getProfile();
|
162
|
+
```
|
163
|
+
|
164
|
+
### Device Code Flow
|
165
|
+
|
166
|
+
#### `requestDeviceCode()`
|
167
|
+
Request a device code for CLI/IoT authentication.
|
168
|
+
|
169
|
+
```typescript
|
170
|
+
const result = await auth.requestDeviceCode();
|
171
|
+
console.log(`Visit: ${result.data.verification_uri}`);
|
172
|
+
console.log(`Code: ${result.data.user_code}`);
|
173
|
+
```
|
174
|
+
|
175
|
+
#### `pollDeviceToken(deviceCode: string)`
|
176
|
+
Poll for device authorization completion.
|
177
|
+
|
178
|
+
```typescript
|
179
|
+
const result = await auth.pollDeviceToken('device_code_here');
|
180
|
+
```
|
181
|
+
|
182
|
+
### User Management (Admin API)
|
183
|
+
|
184
|
+
#### `getUser(userId: string)`
|
185
|
+
Get user information by ID.
|
186
|
+
|
187
|
+
```typescript
|
188
|
+
const result = await auth.getUser('user_id_here');
|
189
|
+
```
|
190
|
+
|
191
|
+
#### `getUsers(params?: { page?: number; limit?: number })`
|
192
|
+
Get paginated list of users.
|
193
|
+
|
194
|
+
```typescript
|
195
|
+
const result = await auth.getUsers({ page: 1, limit: 10 });
|
196
|
+
```
|
197
|
+
|
198
|
+
#### `createUser(userData: any)`
|
199
|
+
Create a new user (not implemented in current admin SDK).
|
200
|
+
|
201
|
+
#### `updateUser(userId: string, userData: any)`
|
202
|
+
Update user information (not implemented in current admin SDK).
|
203
|
+
|
204
|
+
#### `deleteUser(userId: string)`
|
205
|
+
Delete a user (not implemented in current admin SDK).
|
206
|
+
|
207
|
+
## Response Format
|
208
|
+
|
209
|
+
All methods return a `BinoAuthResponse` object:
|
210
|
+
|
211
|
+
```typescript
|
212
|
+
interface BinoAuthResponse<T = any> {
|
213
|
+
ok: boolean; // Success indicator
|
214
|
+
data?: T; // Response data (if successful)
|
215
|
+
error?: string; // Error message (if failed)
|
216
|
+
error_description?: string; // Detailed error description (if failed)
|
217
|
+
}
|
218
|
+
```
|
219
|
+
|
220
|
+
## Error Handling
|
221
|
+
|
222
|
+
```typescript
|
223
|
+
const result = await auth.login('password', {
|
224
|
+
email: 'user@example.com',
|
225
|
+
password: 'wrong_password'
|
226
|
+
});
|
227
|
+
|
228
|
+
if (!result.ok) {
|
229
|
+
console.error('Login failed:', result.error);
|
230
|
+
console.error('Details:', result.error_description);
|
231
|
+
} else {
|
232
|
+
console.log('Login successful:', result.data);
|
233
|
+
}
|
234
|
+
```
|
235
|
+
|
236
|
+
## OAuth2 Compatibility
|
237
|
+
|
238
|
+
All tokens generated by this SDK are OAuth2-compatible JWT tokens that can be used with:
|
239
|
+
- Resource servers expecting OAuth2 Bearer tokens
|
240
|
+
- Existing OAuth2 middleware and libraries
|
241
|
+
- Standard Authorization headers: `Authorization: Bearer <token>`
|
242
|
+
|
243
|
+
## Development
|
244
|
+
|
245
|
+
```bash
|
246
|
+
# Install dependencies
|
247
|
+
bun install
|
248
|
+
|
249
|
+
# Build the package
|
250
|
+
bun run build
|
251
|
+
|
252
|
+
# Watch mode for development
|
253
|
+
bun run dev
|
254
|
+
```
|
255
|
+
|
256
|
+
## License
|
257
|
+
|
258
|
+
MIT
|
259
|
+
|
260
|
+
## Support
|
261
|
+
|
262
|
+
For issues and questions:
|
263
|
+
- GitHub Issues: [binoauth/binoauth](https://github.com/binoauth/binoauth/issues)
|
264
|
+
- Email: support@binoauth.com
|
265
|
+
- Documentation: [docs.binoauth.com](https://docs.binoauth.com)
|
@@ -0,0 +1,51 @@
|
|
1
|
+
export interface BinoAuthConfig {
|
2
|
+
apiKey: string;
|
3
|
+
tenant: string;
|
4
|
+
baseUrl?: string;
|
5
|
+
}
|
6
|
+
export interface LoginCredentials {
|
7
|
+
email?: string;
|
8
|
+
password?: string;
|
9
|
+
otp?: string;
|
10
|
+
phone?: string;
|
11
|
+
}
|
12
|
+
export interface BinoAuthResponse<T = any> {
|
13
|
+
ok: boolean;
|
14
|
+
data?: T;
|
15
|
+
error?: string;
|
16
|
+
error_description?: string;
|
17
|
+
}
|
18
|
+
export declare class BinoAuth {
|
19
|
+
private tenantConfig;
|
20
|
+
private adminConfig;
|
21
|
+
private authApi;
|
22
|
+
private oauthApi;
|
23
|
+
private userProfileApi;
|
24
|
+
private adminApi;
|
25
|
+
constructor(config: BinoAuthConfig);
|
26
|
+
sendEmailOTP(email: string): Promise<BinoAuthResponse>;
|
27
|
+
sendPhoneOTP(phone: string): Promise<BinoAuthResponse>;
|
28
|
+
sendMagicLink(email: string): Promise<BinoAuthResponse>;
|
29
|
+
login(type: 'password' | 'otp', credentials: LoginCredentials): Promise<BinoAuthResponse>;
|
30
|
+
sendResetPasswordEmailOTP(email: string): Promise<BinoAuthResponse>;
|
31
|
+
sendResetPasswordPhoneOTP(phone: string): Promise<BinoAuthResponse>;
|
32
|
+
resetPassword(params: {
|
33
|
+
otp: string;
|
34
|
+
newPassword: string;
|
35
|
+
repeatNewPassword: string;
|
36
|
+
}): Promise<BinoAuthResponse>;
|
37
|
+
refreshToken(refreshToken: string): Promise<BinoAuthResponse>;
|
38
|
+
logout(accessToken?: string): Promise<BinoAuthResponse>;
|
39
|
+
getProfile(): Promise<BinoAuthResponse>;
|
40
|
+
requestDeviceCode(): Promise<BinoAuthResponse>;
|
41
|
+
pollDeviceToken(deviceCode: string): Promise<BinoAuthResponse>;
|
42
|
+
createUser(userData: any): Promise<BinoAuthResponse>;
|
43
|
+
getUser(userId: string): Promise<BinoAuthResponse>;
|
44
|
+
getUsers(params?: {
|
45
|
+
page?: number;
|
46
|
+
limit?: number;
|
47
|
+
}): Promise<BinoAuthResponse>;
|
48
|
+
updateUser(userId: string, userData: any): Promise<BinoAuthResponse>;
|
49
|
+
deleteUser(userId: string): Promise<BinoAuthResponse>;
|
50
|
+
}
|
51
|
+
export default BinoAuth;
|
@@ -0,0 +1,343 @@
|
|
1
|
+
import { AuthenticationApi, OAuth2Api, UserProfileApi, Configuration as TenantConfiguration } from '@binoauth/tenant-sdk';
|
2
|
+
import { AdminApi, Configuration as AdminConfiguration } from '@binoauth/admin-sdk';
|
3
|
+
export class BinoAuth {
|
4
|
+
constructor(config) {
|
5
|
+
const baseUrl = config.baseUrl || 'https://api.binoauth.com';
|
6
|
+
// Configure tenant SDK
|
7
|
+
this.tenantConfig = new TenantConfiguration({
|
8
|
+
basePath: baseUrl,
|
9
|
+
headers: {
|
10
|
+
'X-API-Key': config.apiKey,
|
11
|
+
'X-Tenant-ID': config.tenant
|
12
|
+
}
|
13
|
+
});
|
14
|
+
// Configure admin SDK
|
15
|
+
this.adminConfig = new AdminConfiguration({
|
16
|
+
basePath: baseUrl,
|
17
|
+
headers: {
|
18
|
+
'X-API-Key': config.apiKey,
|
19
|
+
'X-Tenant-ID': config.tenant
|
20
|
+
}
|
21
|
+
});
|
22
|
+
// Initialize APIs
|
23
|
+
this.authApi = new AuthenticationApi(this.tenantConfig);
|
24
|
+
this.oauthApi = new OAuth2Api(this.tenantConfig);
|
25
|
+
this.userProfileApi = new UserProfileApi(this.tenantConfig);
|
26
|
+
this.adminApi = new AdminApi(this.adminConfig);
|
27
|
+
}
|
28
|
+
// Authentication Methods
|
29
|
+
async sendEmailOTP(email) {
|
30
|
+
try {
|
31
|
+
const response = await this.authApi.requestMagicLinkApiV1AuthMlPost({
|
32
|
+
magicLinkRequest: { email }
|
33
|
+
});
|
34
|
+
return { ok: true, data: response };
|
35
|
+
}
|
36
|
+
catch (error) {
|
37
|
+
return {
|
38
|
+
ok: false,
|
39
|
+
error: error.message || 'Failed to send email OTP',
|
40
|
+
error_description: error.response?.data?.detail || error.message
|
41
|
+
};
|
42
|
+
}
|
43
|
+
}
|
44
|
+
async sendPhoneOTP(phone) {
|
45
|
+
try {
|
46
|
+
const response = await this.authApi.requestOtpViaPhoneApiV1AuthPhonePost({
|
47
|
+
phoneOTPRequest: { phone }
|
48
|
+
});
|
49
|
+
return { ok: true, data: response };
|
50
|
+
}
|
51
|
+
catch (error) {
|
52
|
+
return {
|
53
|
+
ok: false,
|
54
|
+
error: error.message || 'Failed to send phone OTP',
|
55
|
+
error_description: error.response?.data?.detail || error.message
|
56
|
+
};
|
57
|
+
}
|
58
|
+
}
|
59
|
+
async sendMagicLink(email) {
|
60
|
+
try {
|
61
|
+
const response = await this.authApi.requestMagicLinkApiV1AuthMlPost({
|
62
|
+
magicLinkRequest: { email }
|
63
|
+
});
|
64
|
+
return { ok: true, data: response };
|
65
|
+
}
|
66
|
+
catch (error) {
|
67
|
+
return {
|
68
|
+
ok: false,
|
69
|
+
error: error.message || 'Failed to send magic link',
|
70
|
+
error_description: error.response?.data?.detail || error.message
|
71
|
+
};
|
72
|
+
}
|
73
|
+
}
|
74
|
+
async login(type, credentials) {
|
75
|
+
try {
|
76
|
+
let response;
|
77
|
+
if (type === 'password') {
|
78
|
+
if (!credentials.email || !credentials.password) {
|
79
|
+
return {
|
80
|
+
ok: false,
|
81
|
+
error: 'Missing credentials',
|
82
|
+
error_description: 'Email and password are required for password login'
|
83
|
+
};
|
84
|
+
}
|
85
|
+
response = await this.authApi.loginApiV1AuthLoginPost({
|
86
|
+
loginRequest: {
|
87
|
+
email: credentials.email,
|
88
|
+
password: credentials.password
|
89
|
+
}
|
90
|
+
});
|
91
|
+
}
|
92
|
+
else if (type === 'otp') {
|
93
|
+
if (!credentials.otp) {
|
94
|
+
return {
|
95
|
+
ok: false,
|
96
|
+
error: 'Missing OTP',
|
97
|
+
error_description: 'OTP code is required for OTP login'
|
98
|
+
};
|
99
|
+
}
|
100
|
+
// For OTP login, we need to verify the OTP
|
101
|
+
if (credentials.phone) {
|
102
|
+
response = await this.authApi.verifyPhoneOtpApiV1AuthPhoneVerifyPost({
|
103
|
+
phoneOTPVerificationRequest: {
|
104
|
+
otp: credentials.otp.toString()
|
105
|
+
}
|
106
|
+
});
|
107
|
+
}
|
108
|
+
else {
|
109
|
+
response = await this.authApi.verifyMagicLinkCodeApiV1AuthMlCodeVerifyPost({
|
110
|
+
verifyMagicLinkCodeRequest: {
|
111
|
+
code: credentials.otp.toString()
|
112
|
+
}
|
113
|
+
});
|
114
|
+
}
|
115
|
+
}
|
116
|
+
return { ok: true, data: response };
|
117
|
+
}
|
118
|
+
catch (error) {
|
119
|
+
return {
|
120
|
+
ok: false,
|
121
|
+
error: error.message || 'Login failed',
|
122
|
+
error_description: error.response?.data?.detail || error.message
|
123
|
+
};
|
124
|
+
}
|
125
|
+
}
|
126
|
+
// Password Reset
|
127
|
+
async sendResetPasswordEmailOTP(email) {
|
128
|
+
try {
|
129
|
+
const response = await this.authApi.requestMagicLinkApiV1AuthMlPost({
|
130
|
+
magicLinkRequest: { email }
|
131
|
+
});
|
132
|
+
return { ok: true, data: response };
|
133
|
+
}
|
134
|
+
catch (error) {
|
135
|
+
return {
|
136
|
+
ok: false,
|
137
|
+
error: error.message || 'Failed to send reset password email',
|
138
|
+
error_description: error.response?.data?.detail || error.message
|
139
|
+
};
|
140
|
+
}
|
141
|
+
}
|
142
|
+
async sendResetPasswordPhoneOTP(phone) {
|
143
|
+
try {
|
144
|
+
const response = await this.authApi.requestOtpViaPhoneApiV1AuthPhonePost({
|
145
|
+
phoneOTPRequest: { phone }
|
146
|
+
});
|
147
|
+
return { ok: true, data: response };
|
148
|
+
}
|
149
|
+
catch (error) {
|
150
|
+
return {
|
151
|
+
ok: false,
|
152
|
+
error: error.message || 'Failed to send reset password phone OTP',
|
153
|
+
error_description: error.response?.data?.detail || error.message
|
154
|
+
};
|
155
|
+
}
|
156
|
+
}
|
157
|
+
async resetPassword(params) {
|
158
|
+
try {
|
159
|
+
if (params.newPassword !== params.repeatNewPassword) {
|
160
|
+
return {
|
161
|
+
ok: false,
|
162
|
+
error: 'Password mismatch',
|
163
|
+
error_description: 'New password and repeat password do not match'
|
164
|
+
};
|
165
|
+
}
|
166
|
+
// This would typically be handled by verifying the OTP first, then updating password
|
167
|
+
// For now, we'll verify the magic link code
|
168
|
+
const response = await this.authApi.verifyMagicLinkCodeApiV1AuthMlCodeVerifyPost({
|
169
|
+
verifyMagicLinkCodeRequest: {
|
170
|
+
code: params.otp
|
171
|
+
}
|
172
|
+
});
|
173
|
+
return { ok: true, data: response };
|
174
|
+
}
|
175
|
+
catch (error) {
|
176
|
+
return {
|
177
|
+
ok: false,
|
178
|
+
error: error.message || 'Failed to reset password',
|
179
|
+
error_description: error.response?.data?.detail || error.message
|
180
|
+
};
|
181
|
+
}
|
182
|
+
}
|
183
|
+
// Token Management
|
184
|
+
async refreshToken(refreshToken) {
|
185
|
+
try {
|
186
|
+
const response = await this.oauthApi.getTokensApiV1OauthTokenPost({
|
187
|
+
tokenRequest: {
|
188
|
+
grantType: 'refresh_token',
|
189
|
+
clientId: 'binoauth-sdk',
|
190
|
+
refreshToken: refreshToken
|
191
|
+
}
|
192
|
+
});
|
193
|
+
return { ok: true, data: response };
|
194
|
+
}
|
195
|
+
catch (error) {
|
196
|
+
return {
|
197
|
+
ok: false,
|
198
|
+
error: error.message || 'Failed to refresh token',
|
199
|
+
error_description: error.response?.data?.detail || error.message
|
200
|
+
};
|
201
|
+
}
|
202
|
+
}
|
203
|
+
async logout(accessToken) {
|
204
|
+
try {
|
205
|
+
const response = await this.authApi.logoutApiV1AuthLogoutPost({
|
206
|
+
sessionBinoauth: accessToken || ''
|
207
|
+
});
|
208
|
+
return { ok: true, data: response };
|
209
|
+
}
|
210
|
+
catch (error) {
|
211
|
+
return {
|
212
|
+
ok: false,
|
213
|
+
error: error.message || 'Failed to logout',
|
214
|
+
error_description: error.response?.data?.detail || error.message
|
215
|
+
};
|
216
|
+
}
|
217
|
+
}
|
218
|
+
// User Profile
|
219
|
+
async getProfile() {
|
220
|
+
try {
|
221
|
+
const response = await this.userProfileApi.getCurrentUserApiV1AuthUserinfoGet();
|
222
|
+
return { ok: true, data: response };
|
223
|
+
}
|
224
|
+
catch (error) {
|
225
|
+
return {
|
226
|
+
ok: false,
|
227
|
+
error: error.message || 'Failed to get profile',
|
228
|
+
error_description: error.response?.data?.detail || error.message
|
229
|
+
};
|
230
|
+
}
|
231
|
+
}
|
232
|
+
// Device Code Flow
|
233
|
+
async requestDeviceCode() {
|
234
|
+
try {
|
235
|
+
const response = await this.oauthApi.deviceAuthorizationApiV1OauthDeviceCodePost({
|
236
|
+
deviceAuthorizationRequest: {
|
237
|
+
clientId: 'binoauth-sdk'
|
238
|
+
}
|
239
|
+
});
|
240
|
+
return { ok: true, data: response };
|
241
|
+
}
|
242
|
+
catch (error) {
|
243
|
+
return {
|
244
|
+
ok: false,
|
245
|
+
error: error.message || 'Failed to request device code',
|
246
|
+
error_description: error.response?.data?.detail || error.message
|
247
|
+
};
|
248
|
+
}
|
249
|
+
}
|
250
|
+
async pollDeviceToken(deviceCode) {
|
251
|
+
try {
|
252
|
+
const response = await this.oauthApi.getTokensApiV1OauthTokenPost({
|
253
|
+
tokenRequest: {
|
254
|
+
grantType: 'urn:ietf:params:oauth:grant-type:device_code',
|
255
|
+
clientId: 'binoauth-sdk',
|
256
|
+
deviceCode: deviceCode
|
257
|
+
}
|
258
|
+
});
|
259
|
+
return { ok: true, data: response };
|
260
|
+
}
|
261
|
+
catch (error) {
|
262
|
+
return {
|
263
|
+
ok: false,
|
264
|
+
error: error.message || 'Failed to poll device token',
|
265
|
+
error_description: error.response?.data?.detail || error.message
|
266
|
+
};
|
267
|
+
}
|
268
|
+
}
|
269
|
+
// User Management (Admin API)
|
270
|
+
async createUser(userData) {
|
271
|
+
try {
|
272
|
+
// Admin API user creation method may not be available - this is a placeholder
|
273
|
+
throw new Error('User creation not implemented in admin SDK');
|
274
|
+
}
|
275
|
+
catch (error) {
|
276
|
+
return {
|
277
|
+
ok: false,
|
278
|
+
error: error.message || 'Failed to create user',
|
279
|
+
error_description: error.response?.data?.detail || error.message
|
280
|
+
};
|
281
|
+
}
|
282
|
+
}
|
283
|
+
async getUser(userId) {
|
284
|
+
try {
|
285
|
+
const response = await this.adminApi.getUserApiV1UsersUserIdGet({
|
286
|
+
userId,
|
287
|
+
xTenantId: ''
|
288
|
+
});
|
289
|
+
return { ok: true, data: response };
|
290
|
+
}
|
291
|
+
catch (error) {
|
292
|
+
return {
|
293
|
+
ok: false,
|
294
|
+
error: error.message || 'Failed to get user',
|
295
|
+
error_description: error.response?.data?.detail || error.message
|
296
|
+
};
|
297
|
+
}
|
298
|
+
}
|
299
|
+
async getUsers(params = {}) {
|
300
|
+
try {
|
301
|
+
const response = await this.adminApi.getUsersApiV1UsersGet({
|
302
|
+
page: params.page || 1,
|
303
|
+
limit: params.limit || 10,
|
304
|
+
xTenantId: ''
|
305
|
+
});
|
306
|
+
return { ok: true, data: response };
|
307
|
+
}
|
308
|
+
catch (error) {
|
309
|
+
return {
|
310
|
+
ok: false,
|
311
|
+
error: error.message || 'Failed to get users',
|
312
|
+
error_description: error.response?.data?.detail || error.message
|
313
|
+
};
|
314
|
+
}
|
315
|
+
}
|
316
|
+
async updateUser(userId, userData) {
|
317
|
+
try {
|
318
|
+
// Admin API user update method may not be available - this is a placeholder
|
319
|
+
throw new Error('User update not implemented in admin SDK');
|
320
|
+
}
|
321
|
+
catch (error) {
|
322
|
+
return {
|
323
|
+
ok: false,
|
324
|
+
error: error.message || 'Failed to update user',
|
325
|
+
error_description: error.response?.data?.detail || error.message
|
326
|
+
};
|
327
|
+
}
|
328
|
+
}
|
329
|
+
async deleteUser(userId) {
|
330
|
+
try {
|
331
|
+
// Admin API user delete method may not be available - this is a placeholder
|
332
|
+
throw new Error('User delete not implemented in admin SDK');
|
333
|
+
}
|
334
|
+
catch (error) {
|
335
|
+
return {
|
336
|
+
ok: false,
|
337
|
+
error: error.message || 'Failed to delete user',
|
338
|
+
error_description: error.response?.data?.detail || error.message
|
339
|
+
};
|
340
|
+
}
|
341
|
+
}
|
342
|
+
}
|
343
|
+
export default BinoAuth;
|