@amaster.ai/auth-client 1.1.0-beta.4 → 1.1.0-beta.41
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 +84 -120
- package/dist/auth.d.cts +16 -3
- package/dist/auth.d.ts +16 -3
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/oauth.d.cts +1 -1
- package/dist/oauth.d.ts +1 -1
- package/dist/permissions.d.cts +1 -1
- package/dist/permissions.d.ts +1 -1
- package/dist/sessions.d.cts +1 -1
- package/dist/sessions.d.ts +1 -1
- package/dist/{types-Be3I8qJG.d.cts → types-BhHE_geU.d.cts} +19 -2
- package/dist/{types-Be3I8qJG.d.ts → types-BhHE_geU.d.ts} +19 -2
- package/dist/user.d.cts +1 -1
- package/dist/user.d.ts +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@ Authentication SDK for Amaster Platform - Complete client-side authentication so
|
|
|
8
8
|
- 🔄 **Automatic Token Refresh**: JWT token auto-refresh before expiration
|
|
9
9
|
- 📦 **Token Storage**: localStorage or sessionStorage with SSR support
|
|
10
10
|
- 🎯 **Permission System**: Role-based and permission-based access control
|
|
11
|
+
- 👤 **Anonymous Access**: Automatic support for anonymous users with configurable permissions
|
|
11
12
|
- 🔗 **OAuth Integration**: Google, GitHub, WeChat OAuth, WeChat Mini Program, and custom OAuth providers
|
|
12
13
|
- 📡 **Event System**: Listen to login, logout, and token events
|
|
13
14
|
- 💾 **Session Management**: View and revoke active sessions
|
|
@@ -82,10 +83,10 @@ const authClient = createAuthClient();
|
|
|
82
83
|
|
|
83
84
|
```typescript
|
|
84
85
|
interface AuthClientOptions {
|
|
85
|
-
baseURL?: string;
|
|
86
|
+
baseURL?: string; // API base URL, defaults to window.location.origin
|
|
86
87
|
headers?: Record<string, string>; // Custom headers for all requests
|
|
87
|
-
onTokenExpired?: () => void;
|
|
88
|
-
onUnauthorized?: () => void;
|
|
88
|
+
onTokenExpired?: () => void; // Token expiration callback
|
|
89
|
+
onUnauthorized?: () => void; // Unauthorized (401) callback
|
|
89
90
|
}
|
|
90
91
|
```
|
|
91
92
|
|
|
@@ -94,19 +95,18 @@ interface AuthClientOptions {
|
|
|
94
95
|
```typescript
|
|
95
96
|
const authClient = createAuthClient({
|
|
96
97
|
baseURL: "https://api.example.com",
|
|
97
|
-
onTokenExpired: () => window.location.href = "/login",
|
|
98
|
+
onTokenExpired: () => (window.location.href = "/login"),
|
|
98
99
|
onUnauthorized: () => alert("Session expired"),
|
|
99
100
|
});
|
|
100
101
|
```
|
|
101
102
|
|
|
102
103
|
**Built-in Features (Zero Config):**
|
|
103
104
|
|
|
104
|
-
- ✅
|
|
105
|
-
- ✅
|
|
106
|
-
- ✅
|
|
107
|
-
- ✅
|
|
108
|
-
- ✅
|
|
109
|
-
- ✅ **On-Demand DataScope**: Loads only when needed
|
|
105
|
+
- ✅ Auto environment detection (browser, WeChat Mini Program, SSR)
|
|
106
|
+
- ✅ Auto token refresh (5 minutes before expiry)
|
|
107
|
+
- ✅ Auto permission sync
|
|
108
|
+
- ✅ Auto anonymous support
|
|
109
|
+
- ✅ Smart storage (localStorage, wx.storage, no-op for SSR)
|
|
110
110
|
|
|
111
111
|
## Authentication
|
|
112
112
|
|
|
@@ -184,11 +184,7 @@ window.location.href = redirectUrl;
|
|
|
184
184
|
|
|
185
185
|
```typescript
|
|
186
186
|
// Main page
|
|
187
|
-
const popup = window.open(
|
|
188
|
-
"/api/auth/oauth/google",
|
|
189
|
-
"oauth-login",
|
|
190
|
-
"width=600,height=700"
|
|
191
|
-
);
|
|
187
|
+
const popup = window.open("/api/auth/oauth/google", "oauth-login", "width=600,height=700");
|
|
192
188
|
|
|
193
189
|
window.addEventListener("message", (event) => {
|
|
194
190
|
if (event.data.type === "oauth-success") {
|
|
@@ -213,7 +209,7 @@ import { createAuthClient } from "@amaster.ai/auth-client";
|
|
|
213
209
|
|
|
214
210
|
// Zero configuration - auto-detects WeChat environment
|
|
215
211
|
const authClient = createAuthClient({
|
|
216
|
-
baseURL: "https://api.yourdomain.com"
|
|
212
|
+
baseURL: "https://api.yourdomain.com",
|
|
217
213
|
});
|
|
218
214
|
|
|
219
215
|
// Login with WeChat code
|
|
@@ -221,22 +217,22 @@ wx.login({
|
|
|
221
217
|
success: async (res) => {
|
|
222
218
|
if (res.code) {
|
|
223
219
|
const result = await authClient.loginWithMiniProgram(res.code);
|
|
224
|
-
|
|
220
|
+
|
|
225
221
|
if (result.data) {
|
|
226
222
|
console.log("Logged in:", result.data.user);
|
|
227
223
|
// Token automatically saved to wx.storage
|
|
228
|
-
wx.switchTab({ url:
|
|
224
|
+
wx.switchTab({ url: "/pages/index/index" });
|
|
229
225
|
} else if (result.error) {
|
|
230
226
|
wx.showToast({
|
|
231
|
-
title: result.error.message ||
|
|
232
|
-
icon:
|
|
227
|
+
title: result.error.message || "Login failed",
|
|
228
|
+
icon: "none",
|
|
233
229
|
});
|
|
234
230
|
}
|
|
235
231
|
}
|
|
236
232
|
},
|
|
237
233
|
fail: (err) => {
|
|
238
234
|
console.error("wx.login failed:", err);
|
|
239
|
-
}
|
|
235
|
+
},
|
|
240
236
|
});
|
|
241
237
|
```
|
|
242
238
|
|
|
@@ -244,8 +240,8 @@ wx.login({
|
|
|
244
240
|
|
|
245
241
|
```xml
|
|
246
242
|
<!-- WXML -->
|
|
247
|
-
<button
|
|
248
|
-
open-type="getPhoneNumber"
|
|
243
|
+
<button
|
|
244
|
+
open-type="getPhoneNumber"
|
|
249
245
|
bindgetphonenumber="onGetPhoneNumber"
|
|
250
246
|
>
|
|
251
247
|
Get Phone Number
|
|
@@ -256,14 +252,14 @@ wx.login({
|
|
|
256
252
|
// JS
|
|
257
253
|
async onGetPhoneNumber(e) {
|
|
258
254
|
const { code } = e.detail;
|
|
259
|
-
|
|
255
|
+
|
|
260
256
|
if (code) {
|
|
261
257
|
const result = await authClient.getMiniProgramPhoneNumber(code);
|
|
262
|
-
|
|
258
|
+
|
|
263
259
|
if (result.data) {
|
|
264
260
|
console.log("Phone number:", result.data.phone);
|
|
265
261
|
console.log("Verified:", result.data.phoneVerified);
|
|
266
|
-
|
|
262
|
+
|
|
267
263
|
// Update UI with phone number
|
|
268
264
|
this.setData({
|
|
269
265
|
phone: result.data.phone
|
|
@@ -288,13 +284,13 @@ async onGetPhoneNumber(e) {
|
|
|
288
284
|
import { createAuthClient } from "@amaster.ai/auth-client";
|
|
289
285
|
|
|
290
286
|
const authClient = createAuthClient({
|
|
291
|
-
baseURL: "https://api.yourdomain.com"
|
|
287
|
+
baseURL: "https://api.yourdomain.com",
|
|
292
288
|
});
|
|
293
289
|
|
|
294
290
|
Page({
|
|
295
291
|
data: {
|
|
296
292
|
userInfo: null,
|
|
297
|
-
hasPhone: false
|
|
293
|
+
hasPhone: false,
|
|
298
294
|
},
|
|
299
295
|
|
|
300
296
|
// Auto-login on page load
|
|
@@ -304,26 +300,26 @@ Page({
|
|
|
304
300
|
|
|
305
301
|
// WeChat Mini Program login
|
|
306
302
|
async handleLogin() {
|
|
307
|
-
wx.showLoading({ title:
|
|
308
|
-
|
|
303
|
+
wx.showLoading({ title: "Logging in..." });
|
|
304
|
+
|
|
309
305
|
wx.login({
|
|
310
306
|
success: async (res) => {
|
|
311
307
|
if (res.code) {
|
|
312
308
|
const result = await authClient.loginWithMiniProgram(res.code);
|
|
313
|
-
|
|
309
|
+
|
|
314
310
|
wx.hideLoading();
|
|
315
|
-
|
|
311
|
+
|
|
316
312
|
if (result.data) {
|
|
317
313
|
this.setData({
|
|
318
|
-
userInfo: result.data.user
|
|
314
|
+
userInfo: result.data.user,
|
|
319
315
|
});
|
|
320
|
-
|
|
316
|
+
|
|
321
317
|
// Navigate to home
|
|
322
|
-
wx.switchTab({ url:
|
|
318
|
+
wx.switchTab({ url: "/pages/index/index" });
|
|
323
319
|
} else {
|
|
324
320
|
wx.showToast({
|
|
325
|
-
title:
|
|
326
|
-
icon:
|
|
321
|
+
title: "Login failed",
|
|
322
|
+
icon: "none",
|
|
327
323
|
});
|
|
328
324
|
}
|
|
329
325
|
}
|
|
@@ -331,47 +327,47 @@ Page({
|
|
|
331
327
|
fail: () => {
|
|
332
328
|
wx.hideLoading();
|
|
333
329
|
wx.showToast({
|
|
334
|
-
title:
|
|
335
|
-
icon:
|
|
330
|
+
title: "Login failed",
|
|
331
|
+
icon: "none",
|
|
336
332
|
});
|
|
337
|
-
}
|
|
333
|
+
},
|
|
338
334
|
});
|
|
339
335
|
},
|
|
340
336
|
|
|
341
337
|
// Get phone number with user authorization
|
|
342
338
|
async onGetPhoneNumber(e) {
|
|
343
339
|
const { code } = e.detail;
|
|
344
|
-
|
|
340
|
+
|
|
345
341
|
if (!code) {
|
|
346
342
|
wx.showToast({
|
|
347
|
-
title:
|
|
348
|
-
icon:
|
|
343
|
+
title: "Authorization cancelled",
|
|
344
|
+
icon: "none",
|
|
349
345
|
});
|
|
350
346
|
return;
|
|
351
347
|
}
|
|
352
348
|
|
|
353
|
-
wx.showLoading({ title:
|
|
354
|
-
|
|
349
|
+
wx.showLoading({ title: "Getting phone..." });
|
|
350
|
+
|
|
355
351
|
const result = await authClient.getMiniProgramPhoneNumber(code);
|
|
356
|
-
|
|
352
|
+
|
|
357
353
|
wx.hideLoading();
|
|
358
|
-
|
|
354
|
+
|
|
359
355
|
if (result.data) {
|
|
360
356
|
this.setData({
|
|
361
|
-
hasPhone: true
|
|
357
|
+
hasPhone: true,
|
|
362
358
|
});
|
|
363
|
-
|
|
359
|
+
|
|
364
360
|
wx.showToast({
|
|
365
|
-
title:
|
|
366
|
-
icon:
|
|
361
|
+
title: "Phone number obtained",
|
|
362
|
+
icon: "success",
|
|
367
363
|
});
|
|
368
364
|
} else {
|
|
369
365
|
wx.showToast({
|
|
370
|
-
title: result.error?.message ||
|
|
371
|
-
icon:
|
|
366
|
+
title: result.error?.message || "Failed to get phone",
|
|
367
|
+
icon: "none",
|
|
372
368
|
});
|
|
373
369
|
}
|
|
374
|
-
}
|
|
370
|
+
},
|
|
375
371
|
});
|
|
376
372
|
```
|
|
377
373
|
|
|
@@ -412,67 +408,50 @@ await authClient.changePassword({
|
|
|
412
408
|
|
|
413
409
|
## Permission Checks
|
|
414
410
|
|
|
415
|
-
###
|
|
411
|
+
### Anonymous Access Support
|
|
416
412
|
|
|
417
|
-
|
|
413
|
+
The SDK automatically supports anonymous users with **zero configuration**:
|
|
418
414
|
|
|
419
415
|
```typescript
|
|
420
|
-
//
|
|
421
|
-
|
|
422
|
-
// Admin only
|
|
423
|
-
}
|
|
416
|
+
// Create client
|
|
417
|
+
const authClient = createAuthClient();
|
|
424
418
|
|
|
425
|
-
//
|
|
426
|
-
if (authClient.hasPermission("
|
|
427
|
-
|
|
419
|
+
// Permission checks work for both authenticated and anonymous users
|
|
420
|
+
if (authClient.hasPermission("article", "read")) {
|
|
421
|
+
showArticleList();
|
|
428
422
|
}
|
|
429
423
|
|
|
430
|
-
// Check
|
|
431
|
-
if (authClient.
|
|
432
|
-
|
|
424
|
+
// Check if user is anonymous
|
|
425
|
+
if (authClient.isAnonymous()) {
|
|
426
|
+
showLoginPrompt();
|
|
433
427
|
}
|
|
434
428
|
|
|
435
|
-
//
|
|
436
|
-
|
|
437
|
-
// Has all permissions
|
|
438
|
-
}
|
|
429
|
+
// After login, permissions automatically update
|
|
430
|
+
await authClient.login({ ... });
|
|
439
431
|
```
|
|
440
432
|
|
|
441
|
-
###
|
|
433
|
+
### Local Permission Checks (Fast)
|
|
442
434
|
|
|
443
|
-
|
|
435
|
+
Permissions are cached locally for fast UI checks:
|
|
444
436
|
|
|
445
437
|
```typescript
|
|
446
|
-
//
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
const { dataScope } = result.data;
|
|
450
|
-
|
|
451
|
-
if (dataScope.scopeType === "department") {
|
|
452
|
-
// Filter users by department
|
|
453
|
-
const users = await api.getUsers({
|
|
454
|
-
departmentId: dataScope.scopeFilter.departmentId
|
|
455
|
-
});
|
|
456
|
-
} else if (dataScope.scopeType === "all") {
|
|
457
|
-
// Show all users
|
|
458
|
-
const users = await api.getUsers();
|
|
459
|
-
}
|
|
438
|
+
// Check role
|
|
439
|
+
if (authClient.hasRole("admin")) {
|
|
440
|
+
showAdminPanel();
|
|
460
441
|
}
|
|
461
|
-
```
|
|
462
442
|
|
|
463
|
-
|
|
443
|
+
if (authClient.isAnonymous()) {
|
|
444
|
+
showLoginPrompt();
|
|
445
|
+
}
|
|
464
446
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
uid: "xxx",
|
|
469
|
-
email: "user@example.com",
|
|
470
|
-
roles: ["admin", "user"], // Only role codes
|
|
471
|
-
permissions: ["user.read", "user.write", "order.read"], // Only permission names
|
|
472
|
-
// NO dataScopes - loaded on demand
|
|
447
|
+
// Check permission
|
|
448
|
+
if (authClient.hasPermission("user", "read")) {
|
|
449
|
+
showUserList();
|
|
473
450
|
}
|
|
474
451
|
```
|
|
475
452
|
|
|
453
|
+
````
|
|
454
|
+
|
|
476
455
|
## OAuth Bindings
|
|
477
456
|
|
|
478
457
|
### Get Bindings
|
|
@@ -613,48 +592,32 @@ if (result.error) {
|
|
|
613
592
|
|
|
614
593
|
### Token Management
|
|
615
594
|
|
|
616
|
-
-
|
|
617
|
-
- Access Token
|
|
618
|
-
-
|
|
619
|
-
- Token is automatically refreshed 5 minutes before expiration (configurable)
|
|
620
|
-
|
|
621
|
-
### Permission Sync
|
|
622
|
-
|
|
623
|
-
- **On Page Load**: User info and permissions automatically sync from backend
|
|
624
|
-
- **On Token Refresh**: Permissions re-sync every 5 minutes when token refreshes
|
|
625
|
-
- **Manual Sync**: Call `await authClient.getMe()` to force sync anytime
|
|
626
|
-
|
|
627
|
-
**Behavior:**
|
|
628
|
-
- Permissions always stay fresh without any configuration
|
|
629
|
-
- Page refresh loads latest permissions from backend
|
|
630
|
-
- Background sync happens automatically every 5 minutes
|
|
595
|
+
- Tokens are automatically managed by the SDK
|
|
596
|
+
- Access Token refreshes 5 minutes before expiration
|
|
597
|
+
- No manual token handling required
|
|
631
598
|
|
|
632
599
|
### Permission Checks
|
|
633
600
|
|
|
634
|
-
-
|
|
635
|
-
-
|
|
636
|
-
-
|
|
601
|
+
- Use permission checks for UI control (show/hide buttons, menus)
|
|
602
|
+
- Frontend checks are NOT security measures
|
|
603
|
+
- Backend must always verify permissions
|
|
637
604
|
|
|
638
605
|
### SSR Support
|
|
639
606
|
|
|
640
|
-
The SDK
|
|
607
|
+
The SDK works in both browser and SSR environments:
|
|
641
608
|
|
|
642
609
|
```typescript
|
|
643
|
-
// Safe in both browser and SSR
|
|
644
610
|
const authClient = createAuthClient();
|
|
645
611
|
```
|
|
646
612
|
|
|
647
613
|
## TypeScript
|
|
648
614
|
|
|
649
|
-
Full TypeScript support
|
|
615
|
+
Full TypeScript support:
|
|
650
616
|
|
|
651
617
|
```typescript
|
|
652
618
|
import type {
|
|
653
619
|
User,
|
|
654
620
|
LoginResponse,
|
|
655
|
-
Permission,
|
|
656
|
-
Role,
|
|
657
|
-
DataScope,
|
|
658
621
|
Session,
|
|
659
622
|
OAuthBinding,
|
|
660
623
|
} from "@amaster.ai/auth-client";
|
|
@@ -667,3 +630,4 @@ MIT
|
|
|
667
630
|
## Contributing
|
|
668
631
|
|
|
669
632
|
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
|
|
633
|
+
````
|
package/dist/auth.d.cts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* ============================================================================
|
|
15
15
|
*/
|
|
16
16
|
import { HttpClient, ClientResult } from '@amaster.ai/http-client';
|
|
17
|
-
import { q as User, i as RegisterParams, e as LoginResponse, L as LoginParams, c as CodeLoginParams, S as SendCodeParams, p as SuccessResponse, b as CaptchaResponse, g as OAuthProvider, M as MiniProgramPhoneResponse, R as RefreshTokenResponse } from './types-
|
|
17
|
+
import { q as User, i as RegisterParams, e as LoginResponse, L as LoginParams, c as CodeLoginParams, S as SendCodeParams, p as SuccessResponse, b as CaptchaResponse, g as OAuthProvider, M as MiniProgramPhoneResponse, R as RefreshTokenResponse } from './types-BhHE_geU.cjs';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Authentication Module
|
|
@@ -35,6 +35,7 @@ interface AuthModuleDeps {
|
|
|
35
35
|
onLoginSuccess: (user: User, accessToken: string) => void;
|
|
36
36
|
storage: {
|
|
37
37
|
getItem: (key: string) => string | null;
|
|
38
|
+
setItem: (key: string, value: string) => void;
|
|
38
39
|
};
|
|
39
40
|
clearAuth: () => void;
|
|
40
41
|
}
|
|
@@ -59,8 +60,14 @@ declare function createAuthModule(deps: AuthModuleDeps): {
|
|
|
59
60
|
* @category Authentication
|
|
60
61
|
* @example
|
|
61
62
|
* ```typescript
|
|
63
|
+
* // Auto-detect loginType from username
|
|
64
|
+
* await auth.login({
|
|
65
|
+
* username: "john_doe",
|
|
66
|
+
* password: "Password@123",
|
|
67
|
+
* });
|
|
68
|
+
*
|
|
69
|
+
* // Auto-detect loginType from email
|
|
62
70
|
* await auth.login({
|
|
63
|
-
* loginType: "email",
|
|
64
71
|
* email: "user@example.com",
|
|
65
72
|
* password: "Password@123",
|
|
66
73
|
* });
|
|
@@ -73,11 +80,17 @@ declare function createAuthModule(deps: AuthModuleDeps): {
|
|
|
73
80
|
* @category Authentication
|
|
74
81
|
* @example
|
|
75
82
|
* ```typescript
|
|
83
|
+
* // Auto-detect loginType from email
|
|
76
84
|
* await auth.loginWithCode({
|
|
77
|
-
* loginType: "email",
|
|
78
85
|
* email: "user@example.com",
|
|
79
86
|
* code: "123456",
|
|
80
87
|
* });
|
|
88
|
+
*
|
|
89
|
+
* // Auto-detect loginType from phone
|
|
90
|
+
* await auth.loginWithCode({
|
|
91
|
+
* phone: "13800138000",
|
|
92
|
+
* code: "123456",
|
|
93
|
+
* });
|
|
81
94
|
* ```
|
|
82
95
|
*/
|
|
83
96
|
loginWithCode(params: CodeLoginParams): Promise<ClientResult<LoginResponse>>;
|
package/dist/auth.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* ============================================================================
|
|
15
15
|
*/
|
|
16
16
|
import { HttpClient, ClientResult } from '@amaster.ai/http-client';
|
|
17
|
-
import { q as User, i as RegisterParams, e as LoginResponse, L as LoginParams, c as CodeLoginParams, S as SendCodeParams, p as SuccessResponse, b as CaptchaResponse, g as OAuthProvider, M as MiniProgramPhoneResponse, R as RefreshTokenResponse } from './types-
|
|
17
|
+
import { q as User, i as RegisterParams, e as LoginResponse, L as LoginParams, c as CodeLoginParams, S as SendCodeParams, p as SuccessResponse, b as CaptchaResponse, g as OAuthProvider, M as MiniProgramPhoneResponse, R as RefreshTokenResponse } from './types-BhHE_geU.js';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Authentication Module
|
|
@@ -35,6 +35,7 @@ interface AuthModuleDeps {
|
|
|
35
35
|
onLoginSuccess: (user: User, accessToken: string) => void;
|
|
36
36
|
storage: {
|
|
37
37
|
getItem: (key: string) => string | null;
|
|
38
|
+
setItem: (key: string, value: string) => void;
|
|
38
39
|
};
|
|
39
40
|
clearAuth: () => void;
|
|
40
41
|
}
|
|
@@ -59,8 +60,14 @@ declare function createAuthModule(deps: AuthModuleDeps): {
|
|
|
59
60
|
* @category Authentication
|
|
60
61
|
* @example
|
|
61
62
|
* ```typescript
|
|
63
|
+
* // Auto-detect loginType from username
|
|
64
|
+
* await auth.login({
|
|
65
|
+
* username: "john_doe",
|
|
66
|
+
* password: "Password@123",
|
|
67
|
+
* });
|
|
68
|
+
*
|
|
69
|
+
* // Auto-detect loginType from email
|
|
62
70
|
* await auth.login({
|
|
63
|
-
* loginType: "email",
|
|
64
71
|
* email: "user@example.com",
|
|
65
72
|
* password: "Password@123",
|
|
66
73
|
* });
|
|
@@ -73,11 +80,17 @@ declare function createAuthModule(deps: AuthModuleDeps): {
|
|
|
73
80
|
* @category Authentication
|
|
74
81
|
* @example
|
|
75
82
|
* ```typescript
|
|
83
|
+
* // Auto-detect loginType from email
|
|
76
84
|
* await auth.loginWithCode({
|
|
77
|
-
* loginType: "email",
|
|
78
85
|
* email: "user@example.com",
|
|
79
86
|
* code: "123456",
|
|
80
87
|
* });
|
|
88
|
+
*
|
|
89
|
+
* // Auto-detect loginType from phone
|
|
90
|
+
* await auth.loginWithCode({
|
|
91
|
+
* phone: "13800138000",
|
|
92
|
+
* code: "123456",
|
|
93
|
+
* });
|
|
81
94
|
* ```
|
|
82
95
|
*/
|
|
83
96
|
loginWithCode(params: CodeLoginParams): Promise<ClientResult<LoginResponse>>;
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var httpClient=require('@amaster.ai/http-client');var y=class{constructor(){this.events={};}on(e,r){this.events[e]||(this.events[e]=[]),this.events[e].push(r);}off(e,r){this.events[e]&&(this.events[e]=this.events[e].filter(t=>t!==r));}emit(e,...r){this.events[e]&&this.events[e].forEach(t=>{try{t(...r);}catch(a){console.error(`[AuthClient] Error in event handler for "${e}":`,a);}});}removeAllListeners(){this.events={};}};var l={ACCESS_TOKEN:"amaster_access_token",REFRESH_TOKEN:"amaster_refresh_token",USER:"amaster_user"};function N(){return typeof wx<"u"&&wx.getStorageSync?"wechat-miniprogram":typeof window<"u"&&typeof window.localStorage<"u"?"browser":"node"}function S(){switch(N()){case "wechat-miniprogram":return $();case "browser":return L();case "node":return q()}}function L(){let s=window.localStorage;return {getItem(e){try{return s.getItem(e)}catch(r){return console.error("[AuthClient] Failed to get item from localStorage:",r),null}},setItem(e,r){try{s.setItem(e,r);}catch(t){console.error("[AuthClient] Failed to set item in localStorage:",t);}},removeItem(e){try{s.removeItem(e);}catch(r){console.error("[AuthClient] Failed to remove item from localStorage:",r);}},clear(){try{s.removeItem(l.ACCESS_TOKEN),s.removeItem(l.REFRESH_TOKEN),s.removeItem(l.USER);}catch(e){console.error("[AuthClient] Failed to clear localStorage:",e);}}}}function $(){return {getItem(s){try{return wx.getStorageSync(s)||null}catch(e){return console.error("[AuthClient] Failed to get item from WeChat storage:",e),null}},setItem(s,e){try{wx.setStorageSync(s,e);}catch(r){console.error("[AuthClient] Failed to set item in WeChat storage:",r);}},removeItem(s){try{wx.removeStorageSync(s);}catch(e){console.error("[AuthClient] Failed to remove item from WeChat storage:",e);}},clear(){try{wx.removeStorageSync(l.ACCESS_TOKEN),wx.removeStorageSync(l.REFRESH_TOKEN),wx.removeStorageSync(l.USER);}catch(s){console.error("[AuthClient] Failed to clear WeChat storage:",s);}}}}function q(){let s=new Map;return {getItem(e){return s.get(e)??null},setItem(e,r){s.set(e,r);},removeItem(e){s.delete(e);},clear(){s.clear();}}}function B(s){try{let e=s.split(".");if(e.length!==3)return null;let t=(e[1]||"").replace(/-/g,"+").replace(/_/g,"/");if(typeof atob<"u"){let a=decodeURIComponent(atob(t).split("").map(o=>"%"+("00"+o.charCodeAt(0).toString(16)).slice(-2)).join(""));return JSON.parse(a)}if(typeof Buffer<"u"){let a=Buffer.from(t,"base64").toString("utf-8");return JSON.parse(a)}return null}catch(e){return console.error("[AuthClient] Failed to parse JWT token:",e),null}}var C=class{constructor(){this.refreshTimer=null;this.isRefreshing=false;this.refreshCallback=null;}setRefreshCallback(e){this.refreshCallback=e;}scheduleRefresh(e){this.clearSchedule(),!(e<=0)&&(this.refreshTimer=setTimeout(()=>{this.refresh();},e));}scheduleRefreshFromToken(e,r=300){let t=B(e);if(!t||!t.exp){console.warn("[AuthClient] Cannot schedule refresh: invalid token or missing exp claim");return}let a=t.exp*1e3,o=Date.now(),c=a-o-r*1e3;c<=0?(console.warn("[AuthClient] Token already expired or expiring soon, refreshing immediately"),this.refresh()):this.scheduleRefresh(c);}async refresh(){if(!this.isRefreshing){if(!this.refreshCallback){console.error("[AuthClient] No refresh callback set");return}this.isRefreshing=true;try{await this.refreshCallback();}catch(e){console.error("[AuthClient] Token refresh failed:",e);}finally{this.isRefreshing=false;}}}clearSchedule(){this.refreshTimer&&(clearTimeout(this.refreshTimer),this.refreshTimer=null);}isCurrentlyRefreshing(){return this.isRefreshing}destroy(){this.clearSchedule(),this.refreshCallback=null,this.isRefreshing=false;}};function v(s){return s&&typeof s=="object"&&("statusCode"in s||"status"in s)&&"data"in s?s.data:s}var R={transformResponse:v,logErrors:true};function k(s){let{http:e,onLoginSuccess:r,storage:t,clearAuth:a}=s;return {async register(o){let n=await e.request({url:"/api/auth/register",method:"post",headers:{"Content-Type":"application/json"},data:o});return n.data?.user&&n.data?.accessToken&&r(n.data.user,n.data.accessToken),n},async login(o){let n=await e.request({url:"/api/auth/login",method:"post",headers:{"Content-Type":"application/json"},data:o});return n.data?.user&&n.data?.accessToken&&r(n.data.user,n.data.accessToken),n},async loginWithCode(o){let n=await e.request({url:"/api/auth/login-with-code",method:"post",headers:{"Content-Type":"application/json"},data:o});return n.data?.user&&n.data?.accessToken&&r(n.data.user,n.data.accessToken),n},async sendCode(o){return e.request({url:"/api/auth/send-code",method:"post",headers:{"Content-Type":"application/json"},data:o})},async getCaptcha(){return e.request({url:"/api/auth/captcha",method:"get"})},loginWithOAuth(o,n){if(typeof window>"u"){console.error("[AuthClient] OAuth login is only available in browser environment");return}let c=n?`/api/auth/oauth/${o}?redirect_url=${encodeURIComponent(n)}`:`/api/auth/oauth/${o}`;window.location.href=c;},async handleOAuthCallback(){if(typeof window>"u")return {data:null,error:{message:"OAuth callback is only available in browser environment",status:400},status:400};try{let o=window.location.hash.substring(1),n=new URLSearchParams(o),c=n.get("access_token"),h=n.get("user");if(!c||!h)return {data:null,error:{message:"OAuth callback failed: missing token or user data",status:400},status:400};let u=JSON.parse(decodeURIComponent(h));return r(u,c),{data:{user:u,accessToken:c},error:null,status:200}}catch(o){return {data:null,error:{message:`OAuth callback failed: ${o instanceof Error?o.message:String(o)}`,status:400},status:400}}},async loginWithMiniProgram(o){let n=await e.request({url:"/api/auth/miniprogram/login",method:"post",headers:{"Content-Type":"application/json"},data:{code:o}});return n.data?.user&&n.data?.accessToken&&r(n.data.user,n.data.accessToken),n},async getMiniProgramPhoneNumber(o){let n=t.getItem("amaster_access_token");return n?e.request({url:"/api/auth/miniprogram/phone",method:"post",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`},data:{code:o}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async logout(){let o=t.getItem("amaster_access_token"),n=await e.request({url:"/api/auth/logout",method:"post",headers:o?{Authorization:`Bearer ${o}`}:void 0});return a(),n},async refreshToken(){return e.request({url:"/api/auth/refresh",method:"post"})}}}function P(s){let{getCurrentUser:e}=s;return {hasRole(r){let t=e();return !t||!t.roles?false:t.roles.includes(r)},hasPermission(r,t){let a=e();if(!a||!a.permissions)return false;let o=`${r}:${t}`;return a.permissions.includes(o)},hasAnyPermission(r){return r.some(({resource:t,action:a})=>this.hasPermission(t,a))},hasAllPermissions(r){return r.every(({resource:t,action:a})=>this.hasPermission(t,a))}}}function T(s){let{http:e,storage:r,onUserUpdate:t}=s;return {async getMe(){let a=r.getItem("amaster_access_token");if(!a)return {data:null,error:{message:"Not authenticated",status:401},status:401};let o=await e.request({url:"/api/auth/me",method:"get",headers:{Authorization:`Bearer ${a}`}});return o.data&&t(o.data),o},async updateMe(a){let o=r.getItem("amaster_access_token");if(!o)return {data:null,error:{message:"Not authenticated",status:401},status:401};let n=await e.request({url:"/api/auth/me",method:"put",headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"},data:a});return n.data&&t(n.data),n},async changePassword(a){let o=r.getItem("amaster_access_token");return o?e.request({url:"/api/auth/change-password",method:"post",headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"},data:a}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function w(s){let{http:e,storage:r}=s;return {async getOAuthBindings(){let t=r.getItem("amaster_access_token");return t?e.request({url:"/api/auth/oauth-bindings",method:"get",headers:{Authorization:`Bearer ${t}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},bindOAuth(t){if(typeof window>"u"){console.error("[AuthClient] OAuth binding is only available in browser environment");return}window.location.href=`/api/auth/oauth/${t}/bind`;},async unbindOAuth(t){let a=r.getItem("amaster_access_token");return a?e.request({url:`/api/auth/oauth/${t}/unbind`,method:"delete",headers:{Authorization:`Bearer ${a}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function E(s){let{http:e,storage:r}=s;return {async getSession(){let t=r.getItem("amaster_access_token");return t?e.request({url:"/api/auth/sessions/current",method:"get",headers:{Authorization:`Bearer ${t}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async getSessions(){let t=r.getItem("amaster_access_token");return t?e.request({url:"/api/auth/sessions",method:"get",headers:{Authorization:`Bearer ${t}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async revokeSession(t){let a=r.getItem("amaster_access_token");return a?t?e.request({url:`/api/auth/sessions/${t}`,method:"delete",headers:{Authorization:`Bearer ${a}`}}):{data:null,error:{message:"Session ID is required",status:400},status:400}:{data:null,error:{message:"Not authenticated",status:401},status:401}},async revokeAllSessions(){let t=r.getItem("amaster_access_token");return t?e.request({url:"/api/auth/sessions",method:"delete",headers:{Authorization:`Bearer ${t}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function z(s={},e){let {baseURL:r,headers:t,onTokenExpired:a,onUnauthorized:o}=s,n=e||httpClient.createHttpClient({...R,baseURL:r,headers:t}),h=300,u=S(),m=new y,f=new C,g=null;try{let i=u.getItem(l.USER);i&&(g=JSON.parse(i));}catch(i){console.error("[AuthClient] Failed to load user from storage:",i);}let d;f.setRefreshCallback(async()=>{let i=await d.refreshToken();i.data?(await d.getMe(),m.emit("tokenRefreshed",i.data.accessToken)):(m.emit("tokenExpired"),a?.());});function M(i,p){u.setItem(l.ACCESS_TOKEN,p),u.setItem(l.USER,JSON.stringify(i)),g=i,f.scheduleRefreshFromToken(p,h),m.emit("login",i);}function O(i){g=i,u.setItem(l.USER,JSON.stringify(i));}function A(){u.clear(),g=null,f.clearSchedule();}function U(){return g}let b=k({http:n,onLoginSuccess:M,storage:u,clearAuth:A}),x=P({getCurrentUser:U}),I=T({http:n,storage:u,onUserUpdate:O}),_=w({http:n,storage:u}),H=E({http:n,storage:u});return d={...b,...x,...I,..._,...H,on(i,p){m.on(i,p);},off(i,p){m.off(i,p);},isAuthenticated(){return !!u.getItem(l.ACCESS_TOKEN)},getAccessToken(){return u.getItem(l.ACCESS_TOKEN)},setAccessToken(i){u.setItem(l.ACCESS_TOKEN,i),f.scheduleRefreshFromToken(i,h);},clearAuth:A},d.on("unauthorized",()=>{o?.();}),d.isAuthenticated()&&d.getMe().catch(i=>{console.warn("[AuthClient] Failed to sync user info on init:",i);}),d}exports.createAuthClient=z;exports.defaultHttpClientOptions=R;exports.transformAmasterResponse=v;//# sourceMappingURL=index.cjs.map
|
|
1
|
+
'use strict';var httpClient=require('@amaster.ai/http-client');var C=class{constructor(){this.events={};}on(e,n){this.events[e]||(this.events[e]=[]),this.events[e].push(n);}off(e,n){this.events[e]&&(this.events[e]=this.events[e].filter(r=>r!==n));}emit(e,...n){this.events[e]&&this.events[e].forEach(r=>{try{r(...n);}catch(a){console.error(`[AuthClient] Error in event handler for "${e}":`,a);}});}removeAllListeners(){this.events={};}};var d={ACCESS_TOKEN:"amaster_access_token",REFRESH_TOKEN:"amaster_refresh_token",USER:"amaster_user"};function N(){return typeof wx<"u"&&wx.getStorageSync?"wechat-miniprogram":typeof window<"u"&&typeof window.localStorage<"u"?"browser":"node"}function v(){switch(N()){case "wechat-miniprogram":return $();case "browser":return q();case "node":return B()}}function q(){let t=window.localStorage;return {getItem(e){try{return t.getItem(e)}catch(n){return console.error("[AuthClient] Failed to get item from localStorage:",n),null}},setItem(e,n){try{t.setItem(e,n);}catch(r){console.error("[AuthClient] Failed to set item in localStorage:",r);}},removeItem(e){try{t.removeItem(e);}catch(n){console.error("[AuthClient] Failed to remove item from localStorage:",n);}},clear(){try{t.removeItem(d.ACCESS_TOKEN),t.removeItem(d.REFRESH_TOKEN),t.removeItem(d.USER);}catch(e){console.error("[AuthClient] Failed to clear localStorage:",e);}}}}function $(){return {getItem(t){try{return wx.getStorageSync(t)||null}catch(e){return console.error("[AuthClient] Failed to get item from WeChat storage:",e),null}},setItem(t,e){try{wx.setStorageSync(t,e);}catch(n){console.error("[AuthClient] Failed to set item in WeChat storage:",n);}},removeItem(t){try{wx.removeStorageSync(t);}catch(e){console.error("[AuthClient] Failed to remove item from WeChat storage:",e);}},clear(){try{wx.removeStorageSync(d.ACCESS_TOKEN),wx.removeStorageSync(d.REFRESH_TOKEN),wx.removeStorageSync(d.USER);}catch(t){console.error("[AuthClient] Failed to clear WeChat storage:",t);}}}}function B(){let t=new Map;return {getItem(e){return t.get(e)??null},setItem(e,n){t.set(e,n);},removeItem(e){t.delete(e);},clear(){t.clear();}}}function F(t){try{let e=t.split(".");if(e.length!==3)return null;let r=(e[1]||"").replace(/-/g,"+").replace(/_/g,"/");if(typeof atob<"u"){let a=decodeURIComponent(atob(r).split("").map(s=>"%"+("00"+s.charCodeAt(0).toString(16)).slice(-2)).join(""));return JSON.parse(a)}if(typeof Buffer<"u"){let a=Buffer.from(r,"base64").toString("utf-8");return JSON.parse(a)}return null}catch(e){return console.error("[AuthClient] Failed to parse JWT token:",e),null}}var A=class{constructor(){this.refreshTimer=null;this.isRefreshing=false;this.refreshCallback=null;}setRefreshCallback(e){this.refreshCallback=e;}scheduleRefresh(e){this.clearSchedule(),!(e<=0)&&(this.refreshTimer=setTimeout(()=>{this.refresh();},e));}scheduleRefreshFromToken(e,n=300){let r=F(e);if(!r||!r.exp){console.warn("[AuthClient] Cannot schedule refresh: invalid token or missing exp claim");return}let a=r.exp*1e3,s=Date.now(),u=a-s-n*1e3;u<=0?(console.warn("[AuthClient] Token already expired or expiring soon, refreshing immediately"),this.refresh()):this.scheduleRefresh(u);}async refresh(){if(!this.isRefreshing){if(!this.refreshCallback){console.error("[AuthClient] No refresh callback set");return}this.isRefreshing=true;try{await this.refreshCallback();}catch(e){console.error("[AuthClient] Token refresh failed:",e);}finally{this.isRefreshing=false;}}}clearSchedule(){this.refreshTimer&&(clearTimeout(this.refreshTimer),this.refreshTimer=null);}isCurrentlyRefreshing(){return this.isRefreshing}destroy(){this.clearSchedule(),this.refreshCallback=null,this.isRefreshing=false;}};function k(t){return t&&typeof t=="object"&&("statusCode"in t||"status"in t)&&"data"in t?t.data:t}var R={transformResponse:k,logErrors:true};function z(t){if(t.email)return "email";if(t.username)return "username";if(t.phone)return "phone"}function j(t){if(t.email)return "email";if(t.phone)return "phone"}function T(t){let{http:e,onLoginSuccess:n,storage:r,clearAuth:a}=t;return {async register(s){let o=await e.request({url:"/api/auth/register",method:"post",headers:{"Content-Type":"application/json"},data:s});return o.data?.user&&o.data?.accessToken&&n(o.data.user,o.data.accessToken),o},async login(s){let o=s.loginType||z(s);if(!o)return {data:null,error:{message:"Unable to determine login type. Please provide email, username, or phone.",status:400},status:400};let u={...s,loginType:o},l=await e.request({url:"/api/auth/login",method:"post",headers:{"Content-Type":"application/json"},data:u});return l.data?.user&&l.data?.accessToken&&n(l.data.user,l.data.accessToken),l},async loginWithCode(s){let o=s.loginType||j(s);if(!o)return {data:null,error:{message:"Unable to determine login type. Please provide email or phone.",status:400},status:400};let u={...s,loginType:o},l=await e.request({url:"/api/auth/login-with-code",method:"post",headers:{"Content-Type":"application/json"},data:u});return l.data?.user&&l.data?.accessToken&&n(l.data.user,l.data.accessToken),l},async sendCode(s){return e.request({url:"/api/auth/send-code",method:"post",headers:{"Content-Type":"application/json"},data:s})},async getCaptcha(){return e.request({url:"/api/auth/captcha",method:"get"})},loginWithOAuth(s,o){if(typeof window>"u"){console.error("[AuthClient] OAuth login is only available in browser environment");return}let u=o?`/api/auth/oauth/${s}?redirect_url=${encodeURIComponent(o)}`:`/api/auth/oauth/${s}`;window.location.href=u;},async handleOAuthCallback(){if(typeof window>"u")return {data:null,error:{message:"OAuth callback is only available in browser environment",status:400},status:400};try{let s=window.location.hash.substring(1),o=new URLSearchParams(s),u=o.get("access_token"),l=o.get("user");if(!u||!l)return {data:null,error:{message:"OAuth callback failed: missing token or user data",status:400},status:400};let m=JSON.parse(decodeURIComponent(l));if(n(m,u),window.history&&window.history.replaceState){let c=window.location.pathname+window.location.search;window.history.replaceState(null,"",c);}else window.location.hash="";return {data:{user:m,accessToken:u},error:null,status:200}}catch(s){return {data:null,error:{message:`OAuth callback failed: ${s instanceof Error?s.message:String(s)}`,status:400},status:400}}},async loginWithMiniProgram(s){let o=await e.request({url:"/api/auth/miniprogram/login",method:"post",headers:{"Content-Type":"application/json"},data:{code:s}});return o.data?.user&&o.data?.accessToken&&n(o.data.user,o.data.accessToken),o},async getMiniProgramPhoneNumber(s){let o=r.getItem("amaster_access_token");return o?e.request({url:"/api/auth/miniprogram/phone",method:"post",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`},data:{code:s}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async logout(){let s=r.getItem("amaster_access_token"),o=await e.request({url:"/api/auth/logout",method:"post",headers:s?{Authorization:`Bearer ${s}`}:void 0});return a(),o},async refreshToken(){let s=await e.request({url:"/api/auth/refresh",method:"post"});return s.data?.accessToken&&r.setItem("amaster_access_token",s.data.accessToken),s}}}function w(t){let{getCurrentUser:e}=t;return {hasRole(n){let r=e();return !r||!r.roles?false:r.roles.includes(n)},hasPermission(n,r){let a=e();if(!a||!a.permissions)return false;let s=`${n}:${r}`;return a.permissions.includes(s)},hasAnyPermission(n){return n.some(({resource:r,action:a})=>this.hasPermission(r,a))},hasAllPermissions(n){return n.every(({resource:r,action:a})=>this.hasPermission(r,a))}}}function P(t){let{http:e,storage:n,onUserUpdate:r}=t;return {async getMe(){let a=n.getItem("amaster_access_token");if(!a)return {data:null,error:{message:"Not authenticated",status:401},status:401};let s=await e.request({url:"/api/auth/me",method:"get",headers:{Authorization:`Bearer ${a}`}});return s.data&&r(s.data),s},async updateMe(a){let s=n.getItem("amaster_access_token");if(!s)return {data:null,error:{message:"Not authenticated",status:401},status:401};let o=await e.request({url:"/api/auth/me",method:"put",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},data:a});return o.data&&r(o.data),o},async changePassword(a){let s=n.getItem("amaster_access_token");return s?e.request({url:"/api/auth/change-password",method:"post",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},data:a}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function E(t){let{http:e,storage:n}=t;return {async getOAuthBindings(){let r=n.getItem("amaster_access_token");return r?e.request({url:"/api/auth/oauth-bindings",method:"get",headers:{Authorization:`Bearer ${r}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},bindOAuth(r){if(typeof window>"u"){console.error("[AuthClient] OAuth binding is only available in browser environment");return}window.location.href=`/api/auth/oauth/${r}/bind`;},async unbindOAuth(r){let a=n.getItem("amaster_access_token");return a?e.request({url:`/api/auth/oauth/${r}/unbind`,method:"delete",headers:{Authorization:`Bearer ${a}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function M(t){let{http:e,storage:n}=t;return {async getSession(){let r=n.getItem("amaster_access_token");return r?e.request({url:"/api/auth/sessions/current",method:"get",headers:{Authorization:`Bearer ${r}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async getSessions(){let r=n.getItem("amaster_access_token");return r?e.request({url:"/api/auth/sessions",method:"get",headers:{Authorization:`Bearer ${r}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async revokeSession(r){let a=n.getItem("amaster_access_token");return a?r?e.request({url:`/api/auth/sessions/${r}`,method:"delete",headers:{Authorization:`Bearer ${a}`}}):{data:null,error:{message:"Session ID is required",status:400},status:400}:{data:null,error:{message:"Not authenticated",status:401},status:401}},async revokeAllSessions(){let r=n.getItem("amaster_access_token");return r?e.request({url:"/api/auth/sessions",method:"delete",headers:{Authorization:`Bearer ${r}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function K(t={},e){let {baseURL:n,headers:r,onTokenExpired:a,onUnauthorized:s,autoHandleOAuthCallback:o=true}=t,u=e||httpClient.createHttpClient({...R,baseURL:n,headers:r}),m=300,c=v(),g=new C,y=new A,f=null;try{let i=c.getItem(d.USER);i&&(f=JSON.parse(i));}catch(i){console.error("[AuthClient] Failed to load user from storage:",i);}let p;y.setRefreshCallback(async()=>{let i=await p.refreshToken();i.data?(await p.getMe(),g.emit("tokenRefreshed",i.data.accessToken)):(g.emit("tokenExpired"),a?.());});function O(i,h){c.setItem(d.ACCESS_TOKEN,h),c.setItem(d.USER,JSON.stringify(i)),f=i,y.scheduleRefreshFromToken(h,m),g.emit("login",i);}function U(i){f=i,c.setItem(d.USER,JSON.stringify(i));}function S(){c.clear(),f=null,y.clearSchedule();}function b(){return f}let I=T({http:u,onLoginSuccess:O,storage:c,clearAuth:S}),x=w({getCurrentUser:b}),_=P({http:u,storage:c,onUserUpdate:U}),L=E({http:u,storage:c}),H=M({http:u,storage:c});if(p={...I,...x,..._,...L,...H,on(i,h){g.on(i,h);},off(i,h){g.off(i,h);},isAuthenticated(){return !!c.getItem(d.ACCESS_TOKEN)},getAccessToken(){return c.getItem(d.ACCESS_TOKEN)},setAccessToken(i){c.setItem(d.ACCESS_TOKEN,i),y.scheduleRefreshFromToken(i,m);},clearAuth:S},p.on("unauthorized",()=>{s?.();}),p.isAuthenticated()&&p.getMe().catch(i=>{console.warn("[AuthClient] Failed to sync user info on init:",i);}),o&&typeof window<"u"){let i=window.location.hash;i&&i.includes("access_token")&&p.handleOAuthCallback().then(h=>{h.error&&console.error("[AuthClient] Auto OAuth callback failed:",h.error);}).catch(h=>{console.error("[AuthClient] Auto OAuth callback error:",h);});}return p}exports.createAuthClient=K;exports.defaultHttpClientOptions=R;exports.transformAmasterResponse=k;//# sourceMappingURL=index.cjs.map
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|