@amaster.ai/auth-client 1.1.2 → 1.1.4
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 +105 -86
- package/dist/auth.d.cts +43 -30
- package/dist/auth.d.ts +43 -30
- 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-YfiSfMTJ.d.cts → types-CsCZTBIx.d.cts} +60 -24
- package/dist/{types-YfiSfMTJ.d.ts → types-CsCZTBIx.d.ts} +60 -24
- package/dist/user.d.cts +1 -1
- package/dist/user.d.ts +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -96,7 +96,6 @@ interface AuthClientOptions {
|
|
|
96
96
|
|
|
97
97
|
```typescript
|
|
98
98
|
const authClient = createAuthClient({
|
|
99
|
-
baseURL: "https://api.example.com",
|
|
100
99
|
onTokenExpired: () => (window.location.href = "/login"),
|
|
101
100
|
onUnauthorized: () => alert("Session expired"),
|
|
102
101
|
});
|
|
@@ -217,40 +216,56 @@ if (window.opener) {
|
|
|
217
216
|
}
|
|
218
217
|
```
|
|
219
218
|
|
|
220
|
-
###
|
|
219
|
+
### Mini Program Login
|
|
221
220
|
|
|
222
|
-
The SDK
|
|
221
|
+
The SDK exposes a unified Mini Program API for both WeChat and Douyin.
|
|
222
|
+
|
|
223
|
+
- WeChat runtime: auto-detects `wx` and uses WeChat endpoints
|
|
224
|
+
- Douyin Mini Program: auto-detects the `tt` runtime and uses Douyin endpoints
|
|
225
|
+
- Non-runtime or mixed environments: you can explicitly pass `platform`
|
|
226
|
+
|
|
227
|
+
The SDK automatically detects the Mini Program storage runtime and uses WeChat `wx.storage` or Douyin `tt.storage`.
|
|
228
|
+
For most app code, prefer the high-level methods:
|
|
229
|
+
|
|
230
|
+
- `miniLogin()` - automatically calls `Taro.login` / Douyin `tt.login` / WeChat `wx.login`, then completes backend login
|
|
231
|
+
- `miniGetPhone(...)` - accepts a raw code or event object, extracts the phone code, then binds the phone number
|
|
223
232
|
|
|
224
233
|
```typescript
|
|
225
234
|
import { createAuthClient } from "@amaster.ai/auth-client";
|
|
235
|
+
import Taro from "@tarojs/taro";
|
|
226
236
|
|
|
227
|
-
// Zero configuration - auto-detects
|
|
228
|
-
const authClient = createAuthClient(
|
|
229
|
-
baseURL: "https://api.yourdomain.com",
|
|
230
|
-
});
|
|
237
|
+
// Zero configuration - auto-detects mini-program environment
|
|
238
|
+
const authClient = createAuthClient();
|
|
231
239
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
console.error("wx.login failed:", err);
|
|
252
|
-
},
|
|
240
|
+
const result = await authClient.miniLogin();
|
|
241
|
+
|
|
242
|
+
if (result.data) {
|
|
243
|
+
console.log("Logged in:", result.data.user);
|
|
244
|
+
// Token automatically saved to mini-program storage
|
|
245
|
+
Taro.switchTab({ url: "/pages/index/index" });
|
|
246
|
+
} else if (result.error) {
|
|
247
|
+
Taro.showToast({
|
|
248
|
+
title: result.error.message || "Login failed",
|
|
249
|
+
icon: "none",
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**Login with Douyin Mini Program:**
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
const result = await authClient.miniLogin({
|
|
258
|
+
platform: "douyin",
|
|
253
259
|
});
|
|
260
|
+
|
|
261
|
+
if (result.data) {
|
|
262
|
+
console.log("Logged in:", result.data.user);
|
|
263
|
+
} else if (result.error) {
|
|
264
|
+
Taro.showToast({
|
|
265
|
+
title: result.error.message || "Login failed",
|
|
266
|
+
icon: "none",
|
|
267
|
+
});
|
|
268
|
+
}
|
|
254
269
|
```
|
|
255
270
|
|
|
256
271
|
**Get user phone number (optional):**
|
|
@@ -268,25 +283,21 @@ wx.login({
|
|
|
268
283
|
```typescript
|
|
269
284
|
// JS
|
|
270
285
|
async onGetPhoneNumber(e) {
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
if (code) {
|
|
274
|
-
const result = await authClient.getMiniProgramPhoneNumber(code);
|
|
286
|
+
const result = await authClient.miniGetPhone(e);
|
|
275
287
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
288
|
+
if (result.data) {
|
|
289
|
+
console.log("Phone number:", result.data.phone);
|
|
290
|
+
console.log("Verified:", result.data.phoneVerified);
|
|
279
291
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
292
|
+
// Update UI with phone number
|
|
293
|
+
this.setData({
|
|
294
|
+
phone: result.data.phone
|
|
295
|
+
});
|
|
296
|
+
} else if (result.error) {
|
|
297
|
+
Taro.showToast({
|
|
298
|
+
title: result.error.message || 'Failed to get phone number',
|
|
299
|
+
icon: 'none'
|
|
300
|
+
});
|
|
290
301
|
} else {
|
|
291
302
|
// User denied authorization
|
|
292
303
|
console.log("User cancelled phone number authorization");
|
|
@@ -294,15 +305,29 @@ async onGetPhoneNumber(e) {
|
|
|
294
305
|
}
|
|
295
306
|
```
|
|
296
307
|
|
|
308
|
+
**Get Douyin Mini Program phone number:**
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
async function onGetPhoneNumber(e) {
|
|
312
|
+
const result = await authClient.miniGetPhone({
|
|
313
|
+
...e,
|
|
314
|
+
platform: "douyin",
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
if (result.data) {
|
|
318
|
+
console.log("Phone number:", result.data.phone);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
297
323
|
**Complete Mini Program example:**
|
|
298
324
|
|
|
299
325
|
```typescript
|
|
300
326
|
// pages/login/login.js
|
|
301
327
|
import { createAuthClient } from "@amaster.ai/auth-client";
|
|
328
|
+
import Taro from "@tarojs/taro";
|
|
302
329
|
|
|
303
|
-
const authClient = createAuthClient(
|
|
304
|
-
baseURL: "https://api.yourdomain.com",
|
|
305
|
-
});
|
|
330
|
+
const authClient = createAuthClient();
|
|
306
331
|
|
|
307
332
|
Page({
|
|
308
333
|
data: {
|
|
@@ -317,38 +342,25 @@ Page({
|
|
|
317
342
|
|
|
318
343
|
// WeChat Mini Program login
|
|
319
344
|
async handleLogin() {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
icon: "none",
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
},
|
|
344
|
-
fail: () => {
|
|
345
|
-
wx.hideLoading();
|
|
346
|
-
wx.showToast({
|
|
347
|
-
title: "Login failed",
|
|
348
|
-
icon: "none",
|
|
349
|
-
});
|
|
350
|
-
},
|
|
351
|
-
});
|
|
345
|
+
Taro.showLoading({ title: "Logging in..." });
|
|
346
|
+
|
|
347
|
+
const result = await authClient.miniLogin();
|
|
348
|
+
|
|
349
|
+
Taro.hideLoading();
|
|
350
|
+
|
|
351
|
+
if (result.data) {
|
|
352
|
+
this.setData({
|
|
353
|
+
userInfo: result.data.user,
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
// Navigate to home
|
|
357
|
+
Taro.switchTab({ url: "/pages/index/index" });
|
|
358
|
+
} else {
|
|
359
|
+
Taro.showToast({
|
|
360
|
+
title: "Login failed",
|
|
361
|
+
icon: "none",
|
|
362
|
+
});
|
|
363
|
+
}
|
|
352
364
|
},
|
|
353
365
|
|
|
354
366
|
// Get phone number with user authorization
|
|
@@ -356,30 +368,30 @@ Page({
|
|
|
356
368
|
const { code } = e.detail;
|
|
357
369
|
|
|
358
370
|
if (!code) {
|
|
359
|
-
|
|
371
|
+
Taro.showToast({
|
|
360
372
|
title: "Authorization cancelled",
|
|
361
373
|
icon: "none",
|
|
362
374
|
});
|
|
363
375
|
return;
|
|
364
376
|
}
|
|
365
377
|
|
|
366
|
-
|
|
378
|
+
Taro.showLoading({ title: "Getting phone..." });
|
|
367
379
|
|
|
368
|
-
const result = await authClient.
|
|
380
|
+
const result = await authClient.miniGetPhone(e);
|
|
369
381
|
|
|
370
|
-
|
|
382
|
+
Taro.hideLoading();
|
|
371
383
|
|
|
372
384
|
if (result.data) {
|
|
373
385
|
this.setData({
|
|
374
386
|
hasPhone: true,
|
|
375
387
|
});
|
|
376
388
|
|
|
377
|
-
|
|
389
|
+
Taro.showToast({
|
|
378
390
|
title: "Phone number obtained",
|
|
379
391
|
icon: "success",
|
|
380
392
|
});
|
|
381
393
|
} else {
|
|
382
|
-
|
|
394
|
+
Taro.showToast({
|
|
383
395
|
title: result.error?.message || "Failed to get phone",
|
|
384
396
|
icon: "none",
|
|
385
397
|
});
|
|
@@ -388,6 +400,13 @@ Page({
|
|
|
388
400
|
});
|
|
389
401
|
```
|
|
390
402
|
|
|
403
|
+
**Low-level compatibility APIs (deprecated, advanced use only):**
|
|
404
|
+
|
|
405
|
+
If your app already has a login `code` or phone `code`, you can still call:
|
|
406
|
+
|
|
407
|
+
- `loginWithMiniProgram(code | { code, platform })`
|
|
408
|
+
- `getMiniProgramPhoneNumber(code | { code, platform })`
|
|
409
|
+
|
|
391
410
|
### Logout
|
|
392
411
|
|
|
393
412
|
```typescript
|
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 {
|
|
17
|
+
import { w as User, o as RegisterParams, e as LoginResponse, L as LoginParams, c as CodeLoginParams, S as SendCodeParams, v as SuccessResponse, b as CaptchaResponse, m as OAuthProvider, i as MiniProgramLoginParams, h as MiniLoginParams, k as MiniProgramPhoneParams, l as MiniProgramPhoneResponse, g as MiniGetPhoneParams, R as RefreshTokenResponse } from './types-CsCZTBIx.cjs';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Authentication Module
|
|
@@ -135,50 +135,63 @@ declare function createAuthModule(deps: AuthModuleDeps): {
|
|
|
135
135
|
*/
|
|
136
136
|
handleOAuthCallback(): Promise<ClientResult<LoginResponse>>;
|
|
137
137
|
/**
|
|
138
|
-
* Login with
|
|
138
|
+
* Login with Mini Program code
|
|
139
|
+
*
|
|
140
|
+
* Lower-level API for submitting an already acquired mini-program login code.
|
|
141
|
+
* For most app code, prefer `miniLogin()`.
|
|
142
|
+
*
|
|
143
|
+
* @deprecated Prefer `miniLogin()` unless you already have a resolved mini-program login code.
|
|
144
|
+
*
|
|
145
|
+
* @category Authentication
|
|
146
|
+
*/
|
|
147
|
+
loginWithMiniProgram(input: string | MiniProgramLoginParams): Promise<ClientResult<LoginResponse>>;
|
|
148
|
+
/**
|
|
149
|
+
* Unified Mini Program login entry.
|
|
150
|
+
*
|
|
151
|
+
* Automatically calls Taro / WeChat `wx` / Douyin `tt` login APIs to fetch the temporary login code,
|
|
152
|
+
* then submits it to the backend using the correct platform endpoint.
|
|
139
153
|
*
|
|
140
154
|
* @category Authentication
|
|
141
155
|
* @example
|
|
142
156
|
* ```typescript
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
* const result = await auth.loginWithMiniProgram(res.code);
|
|
148
|
-
* if (result.data) {
|
|
149
|
-
* console.log("Logged in:", result.data.user);
|
|
150
|
-
* }
|
|
151
|
-
* }
|
|
152
|
-
* }
|
|
157
|
+
* const result = await auth.miniLogin();
|
|
158
|
+
*
|
|
159
|
+
* const douyinResult = await auth.miniLogin({
|
|
160
|
+
* platform: "douyin",
|
|
153
161
|
* });
|
|
154
162
|
* ```
|
|
155
163
|
*/
|
|
156
|
-
|
|
164
|
+
miniLogin(params?: MiniLoginParams): Promise<ClientResult<LoginResponse>>;
|
|
157
165
|
/**
|
|
158
|
-
* Get
|
|
166
|
+
* Get Mini Program user phone number
|
|
159
167
|
* Requires user authorization via getPhoneNumber button
|
|
160
168
|
*
|
|
169
|
+
* Lower-level API for submitting an already acquired phone code.
|
|
170
|
+
* For most app code, prefer `miniGetPhone(...)`.
|
|
171
|
+
*
|
|
172
|
+
* @deprecated Prefer `miniGetPhone(...)` unless you already have a resolved phone authorization code.
|
|
173
|
+
*
|
|
174
|
+
* @category Authentication
|
|
175
|
+
*/
|
|
176
|
+
getMiniProgramPhoneNumber(input: string | MiniProgramPhoneParams): Promise<ClientResult<MiniProgramPhoneResponse>>;
|
|
177
|
+
/**
|
|
178
|
+
* Unified Mini Program phone binding entry.
|
|
179
|
+
*
|
|
180
|
+
* Accepts a raw code, a `{ code, platform }` object, or a Mini Program event object
|
|
181
|
+
* such as the payload received from WeChat `wx`, Douyin `tt`, or Taro `getPhoneNumber`.
|
|
182
|
+
*
|
|
161
183
|
* @category Authentication
|
|
162
184
|
* @example
|
|
163
185
|
* ```typescript
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
* async onGetPhoneNumber(e) {
|
|
171
|
-
* const { code } = e.detail;
|
|
172
|
-
* if (code) {
|
|
173
|
-
* const result = await auth.getMiniProgramPhoneNumber(code);
|
|
174
|
-
* if (result.data) {
|
|
175
|
-
* console.log("Phone:", result.data.phone);
|
|
176
|
-
* }
|
|
177
|
-
* }
|
|
178
|
-
* }
|
|
186
|
+
* const result = await auth.miniGetPhone(e);
|
|
187
|
+
*
|
|
188
|
+
* const douyinResult = await auth.miniGetPhone({
|
|
189
|
+
* code,
|
|
190
|
+
* platform: "douyin",
|
|
191
|
+
* });
|
|
179
192
|
* ```
|
|
180
193
|
*/
|
|
181
|
-
|
|
194
|
+
miniGetPhone(input: MiniGetPhoneParams): Promise<ClientResult<MiniProgramPhoneResponse>>;
|
|
182
195
|
/**
|
|
183
196
|
* Logout current user
|
|
184
197
|
*
|
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 {
|
|
17
|
+
import { w as User, o as RegisterParams, e as LoginResponse, L as LoginParams, c as CodeLoginParams, S as SendCodeParams, v as SuccessResponse, b as CaptchaResponse, m as OAuthProvider, i as MiniProgramLoginParams, h as MiniLoginParams, k as MiniProgramPhoneParams, l as MiniProgramPhoneResponse, g as MiniGetPhoneParams, R as RefreshTokenResponse } from './types-CsCZTBIx.js';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Authentication Module
|
|
@@ -135,50 +135,63 @@ declare function createAuthModule(deps: AuthModuleDeps): {
|
|
|
135
135
|
*/
|
|
136
136
|
handleOAuthCallback(): Promise<ClientResult<LoginResponse>>;
|
|
137
137
|
/**
|
|
138
|
-
* Login with
|
|
138
|
+
* Login with Mini Program code
|
|
139
|
+
*
|
|
140
|
+
* Lower-level API for submitting an already acquired mini-program login code.
|
|
141
|
+
* For most app code, prefer `miniLogin()`.
|
|
142
|
+
*
|
|
143
|
+
* @deprecated Prefer `miniLogin()` unless you already have a resolved mini-program login code.
|
|
144
|
+
*
|
|
145
|
+
* @category Authentication
|
|
146
|
+
*/
|
|
147
|
+
loginWithMiniProgram(input: string | MiniProgramLoginParams): Promise<ClientResult<LoginResponse>>;
|
|
148
|
+
/**
|
|
149
|
+
* Unified Mini Program login entry.
|
|
150
|
+
*
|
|
151
|
+
* Automatically calls Taro / WeChat `wx` / Douyin `tt` login APIs to fetch the temporary login code,
|
|
152
|
+
* then submits it to the backend using the correct platform endpoint.
|
|
139
153
|
*
|
|
140
154
|
* @category Authentication
|
|
141
155
|
* @example
|
|
142
156
|
* ```typescript
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
* const result = await auth.loginWithMiniProgram(res.code);
|
|
148
|
-
* if (result.data) {
|
|
149
|
-
* console.log("Logged in:", result.data.user);
|
|
150
|
-
* }
|
|
151
|
-
* }
|
|
152
|
-
* }
|
|
157
|
+
* const result = await auth.miniLogin();
|
|
158
|
+
*
|
|
159
|
+
* const douyinResult = await auth.miniLogin({
|
|
160
|
+
* platform: "douyin",
|
|
153
161
|
* });
|
|
154
162
|
* ```
|
|
155
163
|
*/
|
|
156
|
-
|
|
164
|
+
miniLogin(params?: MiniLoginParams): Promise<ClientResult<LoginResponse>>;
|
|
157
165
|
/**
|
|
158
|
-
* Get
|
|
166
|
+
* Get Mini Program user phone number
|
|
159
167
|
* Requires user authorization via getPhoneNumber button
|
|
160
168
|
*
|
|
169
|
+
* Lower-level API for submitting an already acquired phone code.
|
|
170
|
+
* For most app code, prefer `miniGetPhone(...)`.
|
|
171
|
+
*
|
|
172
|
+
* @deprecated Prefer `miniGetPhone(...)` unless you already have a resolved phone authorization code.
|
|
173
|
+
*
|
|
174
|
+
* @category Authentication
|
|
175
|
+
*/
|
|
176
|
+
getMiniProgramPhoneNumber(input: string | MiniProgramPhoneParams): Promise<ClientResult<MiniProgramPhoneResponse>>;
|
|
177
|
+
/**
|
|
178
|
+
* Unified Mini Program phone binding entry.
|
|
179
|
+
*
|
|
180
|
+
* Accepts a raw code, a `{ code, platform }` object, or a Mini Program event object
|
|
181
|
+
* such as the payload received from WeChat `wx`, Douyin `tt`, or Taro `getPhoneNumber`.
|
|
182
|
+
*
|
|
161
183
|
* @category Authentication
|
|
162
184
|
* @example
|
|
163
185
|
* ```typescript
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
* async onGetPhoneNumber(e) {
|
|
171
|
-
* const { code } = e.detail;
|
|
172
|
-
* if (code) {
|
|
173
|
-
* const result = await auth.getMiniProgramPhoneNumber(code);
|
|
174
|
-
* if (result.data) {
|
|
175
|
-
* console.log("Phone:", result.data.phone);
|
|
176
|
-
* }
|
|
177
|
-
* }
|
|
178
|
-
* }
|
|
186
|
+
* const result = await auth.miniGetPhone(e);
|
|
187
|
+
*
|
|
188
|
+
* const douyinResult = await auth.miniGetPhone({
|
|
189
|
+
* code,
|
|
190
|
+
* platform: "douyin",
|
|
191
|
+
* });
|
|
179
192
|
* ```
|
|
180
193
|
*/
|
|
181
|
-
|
|
194
|
+
miniGetPhone(input: MiniGetPhoneParams): Promise<ClientResult<MiniProgramPhoneResponse>>;
|
|
182
195
|
/**
|
|
183
196
|
* Logout current user
|
|
184
197
|
*
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var httpClient=require('@amaster.ai/http-client');var S=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(o){console.error(`[AuthClient] Error in event handler for "${e}":`,o);}});}removeAllListeners(){this.events={};}};var d={ACCESS_TOKEN:"amaster_access_token",REFRESH_TOKEN:"amaster_refresh_token",USER:"amaster_user"};function z(){return typeof wx<"u"&&wx.getStorageSync?"wechat-miniprogram":typeof tt<"u"&&tt.getStorageSync?"douyin-miniprogram":typeof window<"u"&&typeof window.localStorage<"u"?"browser":"node"}function P(){switch(z()){case "wechat-miniprogram":return T(wx,"WeChat");case "douyin-miniprogram":return T(tt,"Douyin");case "browser":return K();case "node":return j()}}function K(){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 T(t,e){return {getItem(n){try{return t.getStorageSync(n)||null}catch(r){return console.error(`[AuthClient] Failed to get item from ${e} storage:`,r),null}},setItem(n,r){try{t.setStorageSync(n,r);}catch(o){console.error(`[AuthClient] Failed to set item in ${e} storage:`,o);}},removeItem(n){try{t.removeStorageSync(n);}catch(r){console.error(`[AuthClient] Failed to remove item from ${e} storage:`,r);}},clear(){try{t.removeStorageSync(d.ACCESS_TOKEN),t.removeStorageSync(d.REFRESH_TOKEN),t.removeStorageSync(d.USER);}catch(n){console.error(`[AuthClient] Failed to clear ${e} storage:`,n);}}}}function j(){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 D(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 o=decodeURIComponent(atob(r).split("").map(l=>"%"+("00"+l.charCodeAt(0).toString(16)).slice(-2)).join(""));return JSON.parse(o)}if(typeof Buffer<"u"){let o=Buffer.from(r,"base64").toString("utf-8");return JSON.parse(o)}return null}catch(e){return console.error("[AuthClient] Failed to parse JWT token:",e),null}}var v=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=D(e);if(!r||!r.exp){console.warn("[AuthClient] Cannot schedule refresh: invalid token or missing exp claim");return}let o=r.exp*1e3,l=Date.now(),a=o-l-n*1e3;a<=0?(console.warn("[AuthClient] Token already expired or expiring soon, refreshing immediately"),this.refresh()):this.scheduleRefresh(a);}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 E(t){return t&&typeof t=="object"&&("statusCode"in t||"status"in t)&&"data"in t?t.data:t}var k={transformResponse:E,logErrors:true};function J(t){if(t.email)return "email";if(t.username)return "username";if(t.phone)return "phone"}function W(t){if(t.email)return "email";if(t.phone)return "phone"}function G(t){let e=new URLSearchParams(t);return e.get("access_token")||e.get("accessToken")}function Y(t){return new URLSearchParams(t).get("user")}function Q(){if(typeof window>"u")return null;try{let t=new URLSearchParams(window.location.search).get("redirect");if(!t)return null;let e=new URL(t,window.location.origin);return e.origin!==window.location.origin?(console.warn("[AuthClient] Ignored cross-origin redirect target:",t),null):`${e.pathname}${e.search}${e.hash}`}catch(t){return console.warn("[AuthClient] Failed to resolve redirect target:",t),null}}var V={replace(t){window.location.replace(t);}};function R(t,e){return e.handled?{...t,redirectHandled:true,redirectTarget:e.target}:t}function A(t){if(!t||typeof window>"u"||window.opener)return {handled:false};let e=Q();return e?(V.replace(e),{handled:true,target:e}):{handled:false}}function M(t){let{http:e,onLoginSuccess:n,onLogout:r,autoRedirectAfterLogin:o,storage:l,clearAuth:m}=t;return {async register(a){let s=await e.request({url:"/api/auth/register",method:"post",headers:{"Content-Type":"application/json"},data:a});if(s.data?.user&&s.data?.accessToken){n(s.data.user,s.data.accessToken);let h=A(o);s.data=R(s.data,h);}return s},async login(a){let s=a.loginType||J(a);if(!s)return {data:null,error:{message:"Unable to determine login type. Please provide email, username, or phone.",status:400},status:400};let h={...a,loginType:s},u=await e.request({url:"/api/auth/login",method:"post",headers:{"Content-Type":"application/json"},data:h});if(u.data?.user&&u.data?.accessToken){n(u.data.user,u.data.accessToken);let c=A(o);u.data=R(u.data,c);}return u},async loginWithCode(a){let s=a.loginType||W(a);if(!s)return {data:null,error:{message:"Unable to determine login type. Please provide email or phone.",status:400},status:400};let h={...a,loginType:s},u=await e.request({url:"/api/auth/login-with-code",method:"post",headers:{"Content-Type":"application/json"},data:h});if(u.data?.user&&u.data?.accessToken){n(u.data.user,u.data.accessToken);let c=A(o);u.data=R(u.data,c);}return u},async sendCode(a){return e.request({url:"/api/auth/send-code",method:"post",headers:{"Content-Type":"application/json"},data:a})},async getCaptcha(){return e.request({url:"/api/auth/captcha",method:"get"})},loginWithOAuth(a,s){if(typeof window>"u"){console.error("[AuthClient] OAuth login is only available in browser environment");return}let h=s?`/api/auth/oauth/${a}?redirect_url=${encodeURIComponent(s)}`:`/api/auth/oauth/${a}`;window.location.href=h;},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 a=window.location.hash.substring(1),s=G(a),h=Y(a);if(!s)return {data:null,error:{message:"OAuth callback failed: missing access token",status:400},status:400};let u;if(h)u=JSON.parse(decodeURIComponent(h));else {l.setItem(d.ACCESS_TOKEN,s);let p=await e.request({url:"/api/auth/me",method:"get",headers:{Authorization:`Bearer ${s}`}});if(!p.data)return {data:null,error:{message:"OAuth callback failed: unable to fetch user info",status:p.status||500},status:p.status||500};u=p.data;}if(n(u,s),window.history&&window.history.replaceState){let p=window.location.pathname+window.location.search;window.history.replaceState(null,"",p);}else window.location.hash="";let c=A(o);return {data:R({user:u,accessToken:s},c),error:null,status:200}}catch(a){return {data:null,error:{message:`OAuth callback failed: ${a instanceof Error?a.message:String(a)}`,status:400},status:400}}},async loginWithMiniProgram(a){let s=await e.request({url:"/api/auth/miniprogram/login",method:"post",headers:{"Content-Type":"application/json"},data:{code:a}});if(s.data?.user&&s.data?.accessToken){n(s.data.user,s.data.accessToken);let h=A(o);s.data=R(s.data,h);}return s},async getMiniProgramPhoneNumber(a){let s=l.getItem("amaster_access_token");return s?e.request({url:"/api/auth/miniprogram/phone",method:"post",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`},data:{code:a}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async logout(){let a=l.getItem("amaster_access_token"),s=await e.request({url:"/api/auth/logout",method:"post",headers:a?{Authorization:`Bearer ${a}`}:void 0});return m(),r(),s},async refreshToken(){let a=await e.request({url:"/api/auth/refresh",method:"post"});return a.data?.accessToken&&l.setItem("amaster_access_token",a.data.accessToken),a}}}function O(t){let{getCurrentUser:e}=t;return {hasRole(n){let r=e();return !r||!r.roles?false:r.roles.includes(n)},hasPermission(n,r){let o=e();if(!o||!o.permissions)return false;let l=`${n}.${r}`;return o.permissions.includes(l)},hasAnyPermission(n){return n.some(({resource:r,action:o})=>this.hasPermission(r,o))},hasAllPermissions(n){return n.every(({resource:r,action:o})=>this.hasPermission(r,o))}}}function b(t){let{http:e,storage:n,onUserUpdate:r}=t;return {async getMe(){let o=n.getItem("amaster_access_token");if(!o)return {data:null,error:{message:"Not authenticated",status:401},status:401};let l=await e.request({url:"/api/auth/me",method:"get",headers:{Authorization:`Bearer ${o}`}});return l.data&&r(l.data),l},async updateMe(o){let l=n.getItem("amaster_access_token");if(!l)return {data:null,error:{message:"Not authenticated",status:401},status:401};let m=await e.request({url:"/api/auth/me",method:"put",headers:{Authorization:`Bearer ${l}`,"Content-Type":"application/json"},data:o});return m.data&&r(m.data),m},async changePassword(o){let l=n.getItem("amaster_access_token");return l?e.request({url:"/api/auth/change-password",method:"post",headers:{Authorization:`Bearer ${l}`,"Content-Type":"application/json"},data:o}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function U(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 o=n.getItem("amaster_access_token");return o?e.request({url:`/api/auth/oauth/${r}/unbind`,method:"delete",headers:{Authorization:`Bearer ${o}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function I(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 o=n.getItem("amaster_access_token");return o?r?e.request({url:`/api/auth/sessions/${r}`,method:"delete",headers:{Authorization:`Bearer ${o}`}}):{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 Z(t={},e){let {baseURL:n,headers:r,onTokenExpired:o,onUnauthorized:l,autoHandleOAuthCallback:m=true,autoRedirectAfterLogin:a=true}=t,s=e||httpClient.createHttpClient({...k,baseURL:n,headers:r}),u=300,c=P(),p=new S,C=new v,y=null;try{let i=c.getItem(d.USER);i&&(y=JSON.parse(i));}catch(i){console.error("[AuthClient] Failed to load user from storage:",i);}let f;C.setRefreshCallback(async()=>{let i=await f.refreshToken();i.data?(await f.getMe(),p.emit("tokenRefreshed",i.data.accessToken)):(p.emit("tokenExpired"),o?.());});function L(i,g){c.setItem(d.ACCESS_TOKEN,g),c.setItem(d.USER,JSON.stringify(i)),y=i,C.scheduleRefreshFromToken(g,u),p.emit("login",i);}function _(i){y=i,c.setItem(d.USER,JSON.stringify(i));}function x(){p.emit("logout");}function w(){c.clear(),y=null,C.clearSchedule();}function H(){return y}let N=M({http:s,onLoginSuccess:L,onLogout:x,autoRedirectAfterLogin:a,storage:c,clearAuth:w}),$=O({getCurrentUser:H}),q=b({http:s,storage:c,onUserUpdate:_}),B=U({http:s,storage:c}),F=I({http:s,storage:c});if(f={...N,...$,...q,...B,...F,on(i,g){p.on(i,g);},off(i,g){p.off(i,g);},isAuthenticated(){return !!c.getItem(d.ACCESS_TOKEN)},getAccessToken(){return c.getItem(d.ACCESS_TOKEN)},setAccessToken(i){c.setItem(d.ACCESS_TOKEN,i),C.scheduleRefreshFromToken(i,u);},clearAuth:w},f.on("unauthorized",()=>{l?.();}),f.isAuthenticated()&&f.getMe().catch(i=>{console.warn("[AuthClient] Failed to sync user info on init:",i);}),m&&typeof window<"u"){let i=window.location.hash;i&&(i.includes("access_token")||i.includes("accessToken"))&&f.handleOAuthCallback().then(g=>{g.error&&console.error("[AuthClient] Auto OAuth callback failed:",g.error);}).catch(g=>{console.error("[AuthClient] Auto OAuth callback error:",g);});}return f}exports.createAuthClient=Z;exports.defaultHttpClientOptions=k;exports.transformAmasterResponse=E;//# sourceMappingURL=index.cjs.map
|
|
1
|
+
'use strict';var httpClient=require('@amaster.ai/http-client');var C=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(n=>n!==r));}emit(e,...r){this.events[e]&&this.events[e].forEach(n=>{try{n(...r);}catch(i){console.error(`[AuthClient] Error in event handler for "${e}":`,i);}});}removeAllListeners(){this.events={};}};var h={ACCESS_TOKEN:"amaster_access_token",REFRESH_TOKEN:"amaster_refresh_token",USER:"amaster_user"};function J(){return typeof wx<"u"&&wx.getStorageSync?"wechat-miniprogram":typeof tt<"u"&&tt.getStorageSync?"douyin-miniprogram":typeof window<"u"&&typeof window.localStorage<"u"?"browser":"node"}function E(){switch(J()){case "wechat-miniprogram":return M(wx,"WeChat");case "douyin-miniprogram":return M(tt,"Douyin");case "browser":return G();case "node":return W()}}function G(){let t=window.localStorage;return {getItem(e){try{return t.getItem(e)}catch(r){return console.error("[AuthClient] Failed to get item from localStorage:",r),null}},setItem(e,r){try{t.setItem(e,r);}catch(n){console.error("[AuthClient] Failed to set item in localStorage:",n);}},removeItem(e){try{t.removeItem(e);}catch(r){console.error("[AuthClient] Failed to remove item from localStorage:",r);}},clear(){try{t.removeItem(h.ACCESS_TOKEN),t.removeItem(h.REFRESH_TOKEN),t.removeItem(h.USER);}catch(e){console.error("[AuthClient] Failed to clear localStorage:",e);}}}}function M(t,e){return {getItem(r){try{return t.getStorageSync(r)||null}catch(n){return console.error(`[AuthClient] Failed to get item from ${e} storage:`,n),null}},setItem(r,n){try{t.setStorageSync(r,n);}catch(i){console.error(`[AuthClient] Failed to set item in ${e} storage:`,i);}},removeItem(r){try{t.removeStorageSync(r);}catch(n){console.error(`[AuthClient] Failed to remove item from ${e} storage:`,n);}},clear(){try{t.removeStorageSync(h.ACCESS_TOKEN),t.removeStorageSync(h.REFRESH_TOKEN),t.removeStorageSync(h.USER);}catch(r){console.error(`[AuthClient] Failed to clear ${e} storage:`,r);}}}}function W(){let t=new Map;return {getItem(e){return t.get(e)??null},setItem(e,r){t.set(e,r);},removeItem(e){t.delete(e);},clear(){t.clear();}}}function Y(t){try{let e=t.split(".");if(e.length!==3)return null;let n=(e[1]||"").replace(/-/g,"+").replace(/_/g,"/");if(typeof atob<"u"){let i=decodeURIComponent(atob(n).split("").map(u=>"%"+("00"+u.charCodeAt(0).toString(16)).slice(-2)).join(""));return JSON.parse(i)}if(typeof Buffer<"u"){let i=Buffer.from(n,"base64").toString("utf-8");return JSON.parse(i)}return null}catch(e){return console.error("[AuthClient] Failed to parse JWT token:",e),null}}var v=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 n=Y(e);if(!n||!n.exp){console.warn("[AuthClient] Cannot schedule refresh: invalid token or missing exp claim");return}let i=n.exp*1e3,u=Date.now(),o=i-u-r*1e3;o<=0?(console.warn("[AuthClient] Token already expired or expiring soon, refreshing immediately"),this.refresh()):this.scheduleRefresh(o);}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 b(t){return t&&typeof t=="object"&&("statusCode"in t||"status"in t)&&"data"in t?t.data:t}var w={transformResponse:b,logErrors:true};function V(t){if(t.email)return "email";if(t.username)return "username";if(t.phone)return "phone"}function Q(t){if(t.email)return "email";if(t.phone)return "phone"}function O(t){return typeof globalThis<"u"&&typeof globalThis[t]<"u"}function S(t){if(t)return t;let e=typeof globalThis<"u"?globalThis.Taro:void 0,r=e?.getEnv?.(),n=e?.ENV_TYPE;return n&&r===n.TT?"douyin":n&&r===n.WEAPP?"wechat":O("tt")?"douyin":("wechat")}function k(t){return typeof t=="string"?{code:t,platform:S()}:{code:t.code,platform:S(t.platform)}}function U(t,e){return e==="douyin"?`/api/auth/miniprogram/douyin/${t}`:`/api/auth/miniprogram/${t}`}async function X(t){let e=S(t),r=typeof globalThis<"u"?globalThis.Taro:void 0;if(typeof r?.login=="function"){let u=await r.login();if(typeof u?.code=="string"&&u.code)return {code:u.code,platform:e};throw new Error("Mini Program login failed: missing code")}let i=typeof globalThis<"u"?globalThis[e==="douyin"?"tt":"wx"]:void 0;if(typeof i?.login!="function")throw new Error(`Mini Program login API is not available for platform '${e}'`);return new Promise((u,m)=>{i.login?.({success:o=>{if(typeof o?.code=="string"&&o.code){u({code:o.code,platform:e});return}m(new Error("Mini Program login failed: missing code"));},fail:o=>{m(new Error(`Mini Program login failed: ${o instanceof Error?o.message:String(o)}`));}});})}function Z(t){if(typeof t=="string")return k(t);let e="detail"in t&&t.detail&&typeof t.detail=="object"?t.detail:null,r=typeof e?.code=="string"&&e.code?e.code:typeof t.code=="string"&&t.code?t.code:void 0;return r?{code:r,platform:S(t.platform)}:null}function ee(t){let e=new URLSearchParams(t);return e.get("access_token")||e.get("accessToken")}function te(t){return new URLSearchParams(t).get("user")}function re(){if(typeof window>"u")return null;try{let t=new URLSearchParams(window.location.search).get("redirect");if(!t)return null;let e=new URL(t,window.location.origin);return e.origin!==window.location.origin?(console.warn("[AuthClient] Ignored cross-origin redirect target:",t),null):`${e.pathname}${e.search}${e.hash}`}catch(t){return console.warn("[AuthClient] Failed to resolve redirect target:",t),null}}var ne={replace(t){window.location.replace(t);}};function P(t,e){return e.handled?{...t,redirectHandled:true,redirectTarget:e.target}:t}function R(t){if(!t||typeof window>"u"||window.opener)return {handled:false};let e=re();return e?(ne.replace(e),{handled:true,target:e}):{handled:false}}function L(t){let{http:e,onLoginSuccess:r,onLogout:n,autoRedirectAfterLogin:i,storage:u,clearAuth:m}=t;return {async register(o){let s=await e.request({url:"/api/auth/register",method:"post",headers:{"Content-Type":"application/json"},data:o});if(s.data?.user&&s.data?.accessToken){r(s.data.user,s.data.accessToken);let d=R(i);s.data=P(s.data,d);}return s},async login(o){let s=o.loginType||V(o);if(!s)return {data:null,error:{message:"Unable to determine login type. Please provide email, username, or phone.",status:400},status:400};let d={...o,loginType:s},a=await e.request({url:"/api/auth/login",method:"post",headers:{"Content-Type":"application/json"},data:d});if(a.data?.user&&a.data?.accessToken){r(a.data.user,a.data.accessToken);let c=R(i);a.data=P(a.data,c);}return a},async loginWithCode(o){let s=o.loginType||Q(o);if(!s)return {data:null,error:{message:"Unable to determine login type. Please provide email or phone.",status:400},status:400};let d={...o,loginType:s},a=await e.request({url:"/api/auth/login-with-code",method:"post",headers:{"Content-Type":"application/json"},data:d});if(a.data?.user&&a.data?.accessToken){r(a.data.user,a.data.accessToken);let c=R(i);a.data=P(a.data,c);}return a},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,s){if(typeof window>"u"){console.error("[AuthClient] OAuth login is only available in browser environment");return}let d=s?`/api/auth/oauth/${o}?redirect_url=${encodeURIComponent(s)}`:`/api/auth/oauth/${o}`;window.location.href=d;},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),s=ee(o),d=te(o);if(!s)return {data:null,error:{message:"OAuth callback failed: missing access token",status:400},status:400};let a;if(d)a=JSON.parse(decodeURIComponent(d));else {u.setItem(h.ACCESS_TOKEN,s);let g=await e.request({url:"/api/auth/me",method:"get",headers:{Authorization:`Bearer ${s}`}});if(!g.data)return {data:null,error:{message:"OAuth callback failed: unable to fetch user info",status:g.status||500},status:g.status||500};a=g.data;}if(r(a,s),window.history&&window.history.replaceState){let g=window.location.pathname+window.location.search;window.history.replaceState(null,"",g);}else window.location.hash="";let c=R(i);return {data:P({user:a,accessToken:s},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{code:s,platform:d}=k(o),a=await e.request({url:U("login",d),method:"post",headers:{"Content-Type":"application/json"},data:{code:s}});if(a.data?.user&&a.data?.accessToken){r(a.data.user,a.data.accessToken);let c=R(i);a.data=P(a.data,c);}return a},async miniLogin(o={}){try{let s=await X(o.platform);return await this.loginWithMiniProgram(s)}catch(s){return {data:null,error:{message:s instanceof Error?s.message:String(s),status:400},status:400}}},async getMiniProgramPhoneNumber(o){let{code:s,platform:d}=k(o),a=u.getItem(h.ACCESS_TOKEN);return a?e.request({url:U("phone",d),method:"post",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`},data:{code:s}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async miniGetPhone(o){let s=Z(o);return s?this.getMiniProgramPhoneNumber(s):{data:null,error:{message:"Unable to resolve mini-program phone code from input",status:400},status:400}},async logout(){let o=u.getItem("amaster_access_token"),s=await e.request({url:"/api/auth/logout",method:"post",headers:o?{Authorization:`Bearer ${o}`}:void 0});return m(),n(),s},async refreshToken(){let o=await e.request({url:"/api/auth/refresh",method:"post"});return o.data?.accessToken&&u.setItem("amaster_access_token",o.data.accessToken),o}}}function I(t){let{getCurrentUser:e}=t;return {hasRole(r){let n=e();return !n||!n.roles?false:n.roles.includes(r)},hasPermission(r,n){let i=e();if(!i||!i.permissions)return false;let u=`${r}.${n}`;return i.permissions.includes(u)},hasAnyPermission(r){return r.some(({resource:n,action:i})=>this.hasPermission(n,i))},hasAllPermissions(r){return r.every(({resource:n,action:i})=>this.hasPermission(n,i))}}}function _(t){let{http:e,storage:r,onUserUpdate:n}=t;return {async getMe(){let i=r.getItem("amaster_access_token");if(!i)return {data:null,error:{message:"Not authenticated",status:401},status:401};let u=await e.request({url:"/api/auth/me",method:"get",headers:{Authorization:`Bearer ${i}`}});return u.data&&n(u.data),u},async updateMe(i){let u=r.getItem("amaster_access_token");if(!u)return {data:null,error:{message:"Not authenticated",status:401},status:401};let m=await e.request({url:"/api/auth/me",method:"put",headers:{Authorization:`Bearer ${u}`,"Content-Type":"application/json"},data:i});return m.data&&n(m.data),m},async changePassword(i){let u=r.getItem("amaster_access_token");return u?e.request({url:"/api/auth/change-password",method:"post",headers:{Authorization:`Bearer ${u}`,"Content-Type":"application/json"},data:i}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function x(t){let{http:e,storage:r}=t;return {async getOAuthBindings(){let n=r.getItem("amaster_access_token");return n?e.request({url:"/api/auth/oauth-bindings",method:"get",headers:{Authorization:`Bearer ${n}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},bindOAuth(n){if(typeof window>"u"){console.error("[AuthClient] OAuth binding is only available in browser environment");return}window.location.href=`/api/auth/oauth/${n}/bind`;},async unbindOAuth(n){let i=r.getItem("amaster_access_token");return i?e.request({url:`/api/auth/oauth/${n}/unbind`,method:"delete",headers:{Authorization:`Bearer ${i}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function H(t){let{http:e,storage:r}=t;return {async getSession(){let n=r.getItem("amaster_access_token");return n?e.request({url:"/api/auth/sessions/current",method:"get",headers:{Authorization:`Bearer ${n}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async getSessions(){let n=r.getItem("amaster_access_token");return n?e.request({url:"/api/auth/sessions",method:"get",headers:{Authorization:`Bearer ${n}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async revokeSession(n){let i=r.getItem("amaster_access_token");return i?n?e.request({url:`/api/auth/sessions/${n}`,method:"delete",headers:{Authorization:`Bearer ${i}`}}):{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 n=r.getItem("amaster_access_token");return n?e.request({url:"/api/auth/sessions",method:"delete",headers:{Authorization:`Bearer ${n}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function se(t={},e){let {baseURL:r,headers:n,onTokenExpired:i,onUnauthorized:u,autoHandleOAuthCallback:m=true,autoRedirectAfterLogin:o=true}=t,s=e||httpClient.createHttpClient({...w,baseURL:r,headers:n}),a=300,c=E(),g=new C,A=new v,y=null;try{let l=c.getItem(h.USER);l&&(y=JSON.parse(l));}catch(l){console.error("[AuthClient] Failed to load user from storage:",l);}let f;A.setRefreshCallback(async()=>{let l=await f.refreshToken();l.data?(await f.getMe(),g.emit("tokenRefreshed",l.data.accessToken)):(g.emit("tokenExpired"),i?.());});function N(l,p){c.setItem(h.ACCESS_TOKEN,p),c.setItem(h.USER,JSON.stringify(l)),y=l,A.scheduleRefreshFromToken(p,a),g.emit("login",l);}function $(l){y=l,c.setItem(h.USER,JSON.stringify(l));}function q(){g.emit("logout");}function T(){c.clear(),y=null,A.clearSchedule();}function B(){return y}let F=L({http:s,onLoginSuccess:N,onLogout:q,autoRedirectAfterLogin:o,storage:c,clearAuth:T}),z=I({getCurrentUser:B}),K=_({http:s,storage:c,onUserUpdate:$}),D=x({http:s,storage:c}),j=H({http:s,storage:c});if(f={...F,...z,...K,...D,...j,on(l,p){g.on(l,p);},off(l,p){g.off(l,p);},isAuthenticated(){return !!c.getItem(h.ACCESS_TOKEN)},getAccessToken(){return c.getItem(h.ACCESS_TOKEN)},setAccessToken(l){c.setItem(h.ACCESS_TOKEN,l),A.scheduleRefreshFromToken(l,a);},clearAuth:T},f.on("unauthorized",()=>{u?.();}),f.isAuthenticated()&&f.getMe().catch(l=>{console.warn("[AuthClient] Failed to sync user info on init:",l);}),m&&typeof window<"u"){let l=window.location.hash;l&&(l.includes("access_token")||l.includes("accessToken"))&&f.handleOAuthCallback().then(p=>{p.error&&console.error("[AuthClient] Auto OAuth callback failed:",p.error);}).catch(p=>{console.error("[AuthClient] Auto OAuth callback error:",p);});}return f}exports.createAuthClient=se;exports.defaultHttpClientOptions=w;exports.transformAmasterResponse=b;//# sourceMappingURL=index.cjs.map
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|