@amaster.ai/auth-client 1.1.0-beta.72 → 1.1.0-beta.74
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 +110 -86
- package/dist/auth.d.cts +44 -30
- package/dist/auth.d.ts +44 -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-DGF9cpAg.d.cts → types-DqwQ2EzH.d.cts} +103 -9
- package/dist/{types-DGF9cpAg.d.ts → types-DqwQ2EzH.d.ts} +103 -9
- 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
|
});
|
|
@@ -192,6 +191,11 @@ verification-code login, registration auto-login, and mini-program login. Set
|
|
|
192
191
|
`autoRedirectAfterLogin: false` to disable this behavior and fully control
|
|
193
192
|
navigation in the application layer.
|
|
194
193
|
|
|
194
|
+
When the SDK actually consumes a redirect target, successful login results will
|
|
195
|
+
include `result.data.redirectHandled === true` and `result.data.redirectTarget`.
|
|
196
|
+
Applications that still run their own post-login navigation should short-circuit
|
|
197
|
+
on that flag to avoid double redirects.
|
|
198
|
+
|
|
195
199
|
**Popup window:**
|
|
196
200
|
|
|
197
201
|
```typescript
|
|
@@ -212,40 +216,56 @@ if (window.opener) {
|
|
|
212
216
|
}
|
|
213
217
|
```
|
|
214
218
|
|
|
215
|
-
###
|
|
219
|
+
### Mini Program Login
|
|
220
|
+
|
|
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:
|
|
216
229
|
|
|
217
|
-
|
|
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
|
|
218
232
|
|
|
219
233
|
```typescript
|
|
220
234
|
import { createAuthClient } from "@amaster.ai/auth-client";
|
|
235
|
+
import Taro from "@tarojs/taro";
|
|
221
236
|
|
|
222
|
-
// Zero configuration - auto-detects
|
|
223
|
-
const authClient = createAuthClient(
|
|
224
|
-
baseURL: "https://api.yourdomain.com",
|
|
225
|
-
});
|
|
237
|
+
// Zero configuration - auto-detects mini-program environment
|
|
238
|
+
const authClient = createAuthClient();
|
|
226
239
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
console.error("wx.login failed:", err);
|
|
247
|
-
},
|
|
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",
|
|
248
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
|
+
}
|
|
249
269
|
```
|
|
250
270
|
|
|
251
271
|
**Get user phone number (optional):**
|
|
@@ -263,25 +283,21 @@ wx.login({
|
|
|
263
283
|
```typescript
|
|
264
284
|
// JS
|
|
265
285
|
async onGetPhoneNumber(e) {
|
|
266
|
-
const
|
|
286
|
+
const result = await authClient.miniGetPhone(e);
|
|
267
287
|
|
|
268
|
-
if (
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (result.data) {
|
|
272
|
-
console.log("Phone number:", result.data.phone);
|
|
273
|
-
console.log("Verified:", result.data.phoneVerified);
|
|
288
|
+
if (result.data) {
|
|
289
|
+
console.log("Phone number:", result.data.phone);
|
|
290
|
+
console.log("Verified:", result.data.phoneVerified);
|
|
274
291
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
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
|
+
});
|
|
285
301
|
} else {
|
|
286
302
|
// User denied authorization
|
|
287
303
|
console.log("User cancelled phone number authorization");
|
|
@@ -289,15 +305,29 @@ async onGetPhoneNumber(e) {
|
|
|
289
305
|
}
|
|
290
306
|
```
|
|
291
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
|
+
|
|
292
323
|
**Complete Mini Program example:**
|
|
293
324
|
|
|
294
325
|
```typescript
|
|
295
326
|
// pages/login/login.js
|
|
296
327
|
import { createAuthClient } from "@amaster.ai/auth-client";
|
|
328
|
+
import Taro from "@tarojs/taro";
|
|
297
329
|
|
|
298
|
-
const authClient = createAuthClient(
|
|
299
|
-
baseURL: "https://api.yourdomain.com",
|
|
300
|
-
});
|
|
330
|
+
const authClient = createAuthClient();
|
|
301
331
|
|
|
302
332
|
Page({
|
|
303
333
|
data: {
|
|
@@ -312,38 +342,25 @@ Page({
|
|
|
312
342
|
|
|
313
343
|
// WeChat Mini Program login
|
|
314
344
|
async handleLogin() {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
icon: "none",
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
},
|
|
339
|
-
fail: () => {
|
|
340
|
-
wx.hideLoading();
|
|
341
|
-
wx.showToast({
|
|
342
|
-
title: "Login failed",
|
|
343
|
-
icon: "none",
|
|
344
|
-
});
|
|
345
|
-
},
|
|
346
|
-
});
|
|
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
|
+
}
|
|
347
364
|
},
|
|
348
365
|
|
|
349
366
|
// Get phone number with user authorization
|
|
@@ -351,30 +368,30 @@ Page({
|
|
|
351
368
|
const { code } = e.detail;
|
|
352
369
|
|
|
353
370
|
if (!code) {
|
|
354
|
-
|
|
371
|
+
Taro.showToast({
|
|
355
372
|
title: "Authorization cancelled",
|
|
356
373
|
icon: "none",
|
|
357
374
|
});
|
|
358
375
|
return;
|
|
359
376
|
}
|
|
360
377
|
|
|
361
|
-
|
|
378
|
+
Taro.showLoading({ title: "Getting phone..." });
|
|
362
379
|
|
|
363
|
-
const result = await authClient.
|
|
380
|
+
const result = await authClient.miniGetPhone(e);
|
|
364
381
|
|
|
365
|
-
|
|
382
|
+
Taro.hideLoading();
|
|
366
383
|
|
|
367
384
|
if (result.data) {
|
|
368
385
|
this.setData({
|
|
369
386
|
hasPhone: true,
|
|
370
387
|
});
|
|
371
388
|
|
|
372
|
-
|
|
389
|
+
Taro.showToast({
|
|
373
390
|
title: "Phone number obtained",
|
|
374
391
|
icon: "success",
|
|
375
392
|
});
|
|
376
393
|
} else {
|
|
377
|
-
|
|
394
|
+
Taro.showToast({
|
|
378
395
|
title: result.error?.message || "Failed to get phone",
|
|
379
396
|
icon: "none",
|
|
380
397
|
});
|
|
@@ -383,6 +400,13 @@ Page({
|
|
|
383
400
|
});
|
|
384
401
|
```
|
|
385
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
|
+
|
|
386
410
|
### Logout
|
|
387
411
|
|
|
388
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-DqwQ2EzH.cjs';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Authentication Module
|
|
@@ -36,6 +36,7 @@ declare const browserNavigation: {
|
|
|
36
36
|
interface AuthModuleDeps {
|
|
37
37
|
http: HttpClient;
|
|
38
38
|
onLoginSuccess: (user: User, accessToken: string) => void;
|
|
39
|
+
onLogout: () => void;
|
|
39
40
|
autoRedirectAfterLogin: boolean;
|
|
40
41
|
storage: {
|
|
41
42
|
getItem: (key: string) => string | null;
|
|
@@ -134,50 +135,63 @@ declare function createAuthModule(deps: AuthModuleDeps): {
|
|
|
134
135
|
*/
|
|
135
136
|
handleOAuthCallback(): Promise<ClientResult<LoginResponse>>;
|
|
136
137
|
/**
|
|
137
|
-
* 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.
|
|
138
153
|
*
|
|
139
154
|
* @category Authentication
|
|
140
155
|
* @example
|
|
141
156
|
* ```typescript
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
* const result = await auth.loginWithMiniProgram(res.code);
|
|
147
|
-
* if (result.data) {
|
|
148
|
-
* console.log("Logged in:", result.data.user);
|
|
149
|
-
* }
|
|
150
|
-
* }
|
|
151
|
-
* }
|
|
157
|
+
* const result = await auth.miniLogin();
|
|
158
|
+
*
|
|
159
|
+
* const douyinResult = await auth.miniLogin({
|
|
160
|
+
* platform: "douyin",
|
|
152
161
|
* });
|
|
153
162
|
* ```
|
|
154
163
|
*/
|
|
155
|
-
|
|
164
|
+
miniLogin(params?: MiniLoginParams): Promise<ClientResult<LoginResponse>>;
|
|
156
165
|
/**
|
|
157
|
-
* Get
|
|
166
|
+
* Get Mini Program user phone number
|
|
158
167
|
* Requires user authorization via getPhoneNumber button
|
|
159
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
|
+
*
|
|
160
183
|
* @category Authentication
|
|
161
184
|
* @example
|
|
162
185
|
* ```typescript
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
* async onGetPhoneNumber(e) {
|
|
170
|
-
* const { code } = e.detail;
|
|
171
|
-
* if (code) {
|
|
172
|
-
* const result = await auth.getMiniProgramPhoneNumber(code);
|
|
173
|
-
* if (result.data) {
|
|
174
|
-
* console.log("Phone:", result.data.phone);
|
|
175
|
-
* }
|
|
176
|
-
* }
|
|
177
|
-
* }
|
|
186
|
+
* const result = await auth.miniGetPhone(e);
|
|
187
|
+
*
|
|
188
|
+
* const douyinResult = await auth.miniGetPhone({
|
|
189
|
+
* code,
|
|
190
|
+
* platform: "douyin",
|
|
191
|
+
* });
|
|
178
192
|
* ```
|
|
179
193
|
*/
|
|
180
|
-
|
|
194
|
+
miniGetPhone(input: MiniGetPhoneParams): Promise<ClientResult<MiniProgramPhoneResponse>>;
|
|
181
195
|
/**
|
|
182
196
|
* Logout current user
|
|
183
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-DqwQ2EzH.js';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Authentication Module
|
|
@@ -36,6 +36,7 @@ declare const browserNavigation: {
|
|
|
36
36
|
interface AuthModuleDeps {
|
|
37
37
|
http: HttpClient;
|
|
38
38
|
onLoginSuccess: (user: User, accessToken: string) => void;
|
|
39
|
+
onLogout: () => void;
|
|
39
40
|
autoRedirectAfterLogin: boolean;
|
|
40
41
|
storage: {
|
|
41
42
|
getItem: (key: string) => string | null;
|
|
@@ -134,50 +135,63 @@ declare function createAuthModule(deps: AuthModuleDeps): {
|
|
|
134
135
|
*/
|
|
135
136
|
handleOAuthCallback(): Promise<ClientResult<LoginResponse>>;
|
|
136
137
|
/**
|
|
137
|
-
* 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.
|
|
138
153
|
*
|
|
139
154
|
* @category Authentication
|
|
140
155
|
* @example
|
|
141
156
|
* ```typescript
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
* const result = await auth.loginWithMiniProgram(res.code);
|
|
147
|
-
* if (result.data) {
|
|
148
|
-
* console.log("Logged in:", result.data.user);
|
|
149
|
-
* }
|
|
150
|
-
* }
|
|
151
|
-
* }
|
|
157
|
+
* const result = await auth.miniLogin();
|
|
158
|
+
*
|
|
159
|
+
* const douyinResult = await auth.miniLogin({
|
|
160
|
+
* platform: "douyin",
|
|
152
161
|
* });
|
|
153
162
|
* ```
|
|
154
163
|
*/
|
|
155
|
-
|
|
164
|
+
miniLogin(params?: MiniLoginParams): Promise<ClientResult<LoginResponse>>;
|
|
156
165
|
/**
|
|
157
|
-
* Get
|
|
166
|
+
* Get Mini Program user phone number
|
|
158
167
|
* Requires user authorization via getPhoneNumber button
|
|
159
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
|
+
*
|
|
160
183
|
* @category Authentication
|
|
161
184
|
* @example
|
|
162
185
|
* ```typescript
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
* async onGetPhoneNumber(e) {
|
|
170
|
-
* const { code } = e.detail;
|
|
171
|
-
* if (code) {
|
|
172
|
-
* const result = await auth.getMiniProgramPhoneNumber(code);
|
|
173
|
-
* if (result.data) {
|
|
174
|
-
* console.log("Phone:", result.data.phone);
|
|
175
|
-
* }
|
|
176
|
-
* }
|
|
177
|
-
* }
|
|
186
|
+
* const result = await auth.miniGetPhone(e);
|
|
187
|
+
*
|
|
188
|
+
* const douyinResult = await auth.miniGetPhone({
|
|
189
|
+
* code,
|
|
190
|
+
* platform: "douyin",
|
|
191
|
+
* });
|
|
178
192
|
* ```
|
|
179
193
|
*/
|
|
180
|
-
|
|
194
|
+
miniGetPhone(input: MiniGetPhoneParams): Promise<ClientResult<MiniProgramPhoneResponse>>;
|
|
181
195
|
/**
|
|
182
196
|
* Logout current user
|
|
183
197
|
*
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var httpClient=require('@amaster.ai/http-client');var R=class{constructor(){this.events={};}on(e,s){this.events[e]||(this.events[e]=[]),this.events[e].push(s);}off(e,s){this.events[e]&&(this.events[e]=this.events[e].filter(r=>r!==s));}emit(e,...s){this.events[e]&&this.events[e].forEach(r=>{try{r(...s);}catch(a){console.error(`[AuthClient] Error in event handler for "${e}":`,a);}});}removeAllListeners(){this.events={};}};var c={ACCESS_TOKEN:"amaster_access_token",REFRESH_TOKEN:"amaster_refresh_token",USER:"amaster_user"};function q(){return typeof wx<"u"&&wx.getStorageSync?"wechat-miniprogram":typeof window<"u"&&typeof window.localStorage<"u"?"browser":"node"}function k(){switch(q()){case "wechat-miniprogram":return F();case "browser":return B();case "node":return z()}}function B(){let t=window.localStorage;return {getItem(e){try{return t.getItem(e)}catch(s){return console.error("[AuthClient] Failed to get item from localStorage:",s),null}},setItem(e,s){try{t.setItem(e,s);}catch(r){console.error("[AuthClient] Failed to set item in localStorage:",r);}},removeItem(e){try{t.removeItem(e);}catch(s){console.error("[AuthClient] Failed to remove item from localStorage:",s);}},clear(){try{t.removeItem(c.ACCESS_TOKEN),t.removeItem(c.REFRESH_TOKEN),t.removeItem(c.USER);}catch(e){console.error("[AuthClient] Failed to clear localStorage:",e);}}}}function F(){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(s){console.error("[AuthClient] Failed to set item in WeChat storage:",s);}},removeItem(t){try{wx.removeStorageSync(t);}catch(e){console.error("[AuthClient] Failed to remove item from WeChat storage:",e);}},clear(){try{wx.removeStorageSync(c.ACCESS_TOKEN),wx.removeStorageSync(c.REFRESH_TOKEN),wx.removeStorageSync(c.USER);}catch(t){console.error("[AuthClient] Failed to clear WeChat storage:",t);}}}}function z(){let t=new Map;return {getItem(e){return t.get(e)??null},setItem(e,s){t.set(e,s);},removeItem(e){t.delete(e);},clear(){t.clear();}}}function K(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(u=>"%"+("00"+u.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 S=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,s=300){let r=K(e);if(!r||!r.exp){console.warn("[AuthClient] Cannot schedule refresh: invalid token or missing exp claim");return}let a=r.exp*1e3,u=Date.now(),o=a-u-s*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 T(t){return t&&typeof t=="object"&&("statusCode"in t||"status"in t)&&"data"in t?t.data:t}var v={transformResponse:T,logErrors:true};function j(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 D(t){let e=new URLSearchParams(t);return e.get("access_token")||e.get("accessToken")}function W(t){return new URLSearchParams(t).get("user")}function G(){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 Y={replace(t){window.location.replace(t);}};function C(t){if(!t||typeof window>"u"||window.opener)return;let e=G();e&&Y.replace(e);}function P(t){let{http:e,onLoginSuccess:s,autoRedirectAfterLogin:r,storage:a,clearAuth:u}=t;return {async register(n){let o=await e.request({url:"/api/auth/register",method:"post",headers:{"Content-Type":"application/json"},data:n});return o.data?.user&&o.data?.accessToken&&(s(o.data.user,o.data.accessToken),C(r)),o},async login(n){let o=n.loginType||j(n);if(!o)return {data:null,error:{message:"Unable to determine login type. Please provide email, username, or phone.",status:400},status:400};let d={...n,loginType:o},l=await e.request({url:"/api/auth/login",method:"post",headers:{"Content-Type":"application/json"},data:d});return l.data?.user&&l.data?.accessToken&&(s(l.data.user,l.data.accessToken),C(r)),l},async loginWithCode(n){let o=n.loginType||J(n);if(!o)return {data:null,error:{message:"Unable to determine login type. Please provide email or phone.",status:400},status:400};let d={...n,loginType:o},l=await e.request({url:"/api/auth/login-with-code",method:"post",headers:{"Content-Type":"application/json"},data:d});return l.data?.user&&l.data?.accessToken&&(s(l.data.user,l.data.accessToken),C(r)),l},async sendCode(n){return e.request({url:"/api/auth/send-code",method:"post",headers:{"Content-Type":"application/json"},data:n})},async getCaptcha(){return e.request({url:"/api/auth/captcha",method:"get"})},loginWithOAuth(n,o){if(typeof window>"u"){console.error("[AuthClient] OAuth login is only available in browser environment");return}let d=o?`/api/auth/oauth/${n}?redirect_url=${encodeURIComponent(o)}`:`/api/auth/oauth/${n}`;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 n=window.location.hash.substring(1),o=D(n),d=W(n);if(!o)return {data:null,error:{message:"OAuth callback failed: missing access token",status:400},status:400};let l;if(d)l=JSON.parse(decodeURIComponent(d));else {a.setItem(c.ACCESS_TOKEN,o);let m=await e.request({url:"/api/auth/me",method:"get",headers:{Authorization:`Bearer ${o}`}});if(!m.data)return {data:null,error:{message:"OAuth callback failed: unable to fetch user info",status:m.status||500},status:m.status||500};l=m.data;}if(s(l,o),window.history&&window.history.replaceState){let m=window.location.pathname+window.location.search;window.history.replaceState(null,"",m);}else window.location.hash="";return C(r),{data:{user:l,accessToken:o},error:null,status:200}}catch(n){return {data:null,error:{message:`OAuth callback failed: ${n instanceof Error?n.message:String(n)}`,status:400},status:400}}},async loginWithMiniProgram(n){let o=await e.request({url:"/api/auth/miniprogram/login",method:"post",headers:{"Content-Type":"application/json"},data:{code:n}});return o.data?.user&&o.data?.accessToken&&(s(o.data.user,o.data.accessToken),C(r)),o},async getMiniProgramPhoneNumber(n){let o=a.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:n}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async logout(){let n=a.getItem("amaster_access_token"),o=await e.request({url:"/api/auth/logout",method:"post",headers:n?{Authorization:`Bearer ${n}`}:void 0});return u(),o},async refreshToken(){let n=await e.request({url:"/api/auth/refresh",method:"post"});return n.data?.accessToken&&a.setItem("amaster_access_token",n.data.accessToken),n}}}function E(t){let{getCurrentUser:e}=t;return {hasRole(s){let r=e();return !r||!r.roles?false:r.roles.includes(s)},hasPermission(s,r){let a=e();if(!a||!a.permissions)return false;let u=`${s}.${r}`;return a.permissions.includes(u)},hasAnyPermission(s){return s.some(({resource:r,action:a})=>this.hasPermission(r,a))},hasAllPermissions(s){return s.every(({resource:r,action:a})=>this.hasPermission(r,a))}}}function O(t){let{http:e,storage:s,onUserUpdate:r}=t;return {async getMe(){let a=s.getItem("amaster_access_token");if(!a)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 ${a}`}});return u.data&&r(u.data),u},async updateMe(a){let u=s.getItem("amaster_access_token");if(!u)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 ${u}`,"Content-Type":"application/json"},data:a});return n.data&&r(n.data),n},async changePassword(a){let u=s.getItem("amaster_access_token");return u?e.request({url:"/api/auth/change-password",method:"post",headers:{Authorization:`Bearer ${u}`,"Content-Type":"application/json"},data:a}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function b(t){let{http:e,storage:s}=t;return {async getOAuthBindings(){let r=s.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=s.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:s}=t;return {async getSession(){let r=s.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=s.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=s.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=s.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 V(t={},e){let {baseURL:s,headers:r,onTokenExpired:a,onUnauthorized:u,autoHandleOAuthCallback:n=true,autoRedirectAfterLogin:o=true}=t,d=e||httpClient.createHttpClient({...v,baseURL:s,headers:r}),m=300,h=k(),f=new R,A=new S,y=null;try{let i=h.getItem(c.USER);i&&(y=JSON.parse(i));}catch(i){console.error("[AuthClient] Failed to load user from storage:",i);}let g;A.setRefreshCallback(async()=>{let i=await g.refreshToken();i.data?(await g.getMe(),f.emit("tokenRefreshed",i.data.accessToken)):(f.emit("tokenExpired"),a?.());});function U(i,p){h.setItem(c.ACCESS_TOKEN,p),h.setItem(c.USER,JSON.stringify(i)),y=i,A.scheduleRefreshFromToken(p,m),f.emit("login",i);}function I(i){y=i,h.setItem(c.USER,JSON.stringify(i));}function w(){h.clear(),y=null,A.clearSchedule();}function x(){return y}let _=P({http:d,onLoginSuccess:U,autoRedirectAfterLogin:o,storage:h,clearAuth:w}),L=E({getCurrentUser:x}),H=O({http:d,storage:h,onUserUpdate:I}),N=b({http:d,storage:h}),$=M({http:d,storage:h});if(g={..._,...L,...H,...N,...$,on(i,p){f.on(i,p);},off(i,p){f.off(i,p);},isAuthenticated(){return !!h.getItem(c.ACCESS_TOKEN)},getAccessToken(){return h.getItem(c.ACCESS_TOKEN)},setAccessToken(i){h.setItem(c.ACCESS_TOKEN,i),A.scheduleRefreshFromToken(i,m);},clearAuth:w},g.on("unauthorized",()=>{u?.();}),g.isAuthenticated()&&g.getMe().catch(i=>{console.warn("[AuthClient] Failed to sync user info on init:",i);}),n&&typeof window<"u"){let i=window.location.hash;i&&(i.includes("access_token")||i.includes("accessToken"))&&g.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 g}exports.createAuthClient=V;exports.defaultHttpClientOptions=v;exports.transformAmasterResponse=T;//# sourceMappingURL=index.cjs.map
|
|
1
|
+
'use strict';var httpClient=require('@amaster.ai/http-client');var A=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(a){console.error(`[AuthClient] Error in event handler for "${e}":`,a);}});}removeAllListeners(){this.events={};}};var g={ACCESS_TOKEN:"amaster_access_token",REFRESH_TOKEN:"amaster_refresh_token",USER:"amaster_user"};function v(t){return globalThis[t]}function J(){let t=v("wx"),e=v("tt");return t?.getStorageSync&&t?.setStorageSync&&t?.removeStorageSync?"wechat-miniprogram":e?.getStorageSync&&e?.setStorageSync&&e?.removeStorageSync?"douyin-miniprogram":typeof window<"u"&&typeof window.localStorage<"u"?"browser":"node"}function O(){switch(J()){case "wechat-miniprogram":return b(v("wx"),"WeChat");case "douyin-miniprogram":return b(v("tt"),"Douyin");case "browser":return W();case "node":return Y()}}function W(){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(g.ACCESS_TOKEN),t.removeItem(g.REFRESH_TOKEN),t.removeItem(g.USER);}catch(e){console.error("[AuthClient] Failed to clear localStorage:",e);}}}}function b(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(a){console.error(`[AuthClient] Failed to set item in ${e} storage:`,a);}},removeItem(r){try{t.removeStorageSync(r);}catch(n){console.error(`[AuthClient] Failed to remove item from ${e} storage:`,n);}},clear(){try{t.removeStorageSync(g.ACCESS_TOKEN),t.removeStorageSync(g.REFRESH_TOKEN),t.removeStorageSync(g.USER);}catch(r){console.error(`[AuthClient] Failed to clear ${e} storage:`,r);}}}}function Y(){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 Q(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 a=decodeURIComponent(atob(n).split("").map(l=>"%"+("00"+l.charCodeAt(0).toString(16)).slice(-2)).join(""));return JSON.parse(a)}if(typeof Buffer<"u"){let a=Buffer.from(n,"base64").toString("utf-8");return JSON.parse(a)}return null}catch(e){return console.error("[AuthClient] Failed to parse JWT token:",e),null}}var w=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=Q(e);if(!n||!n.exp){console.warn("[AuthClient] Cannot schedule refresh: invalid token or missing exp claim");return}let a=n.exp*1e3,l=Date.now(),s=a-l-r*1e3;s<=0?(console.warn("[AuthClient] Token already expired or expiring soon, refreshing immediately"),this.refresh()):this.scheduleRefresh(s);}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 U(t){return t&&typeof t=="object"&&("statusCode"in t||"status"in t)&&"data"in t?t.data:t}var M={transformResponse:U,logErrors:true};function Z(t){if(t.email)return "email";if(t.username)return "username";if(t.phone)return "phone"}function ee(t){if(t.email)return "email";if(t.phone)return "phone"}function k(t){return t||(httpClient.detectMiniProgramPlatform()??"wechat")}function T(t){return typeof t=="string"?{code:t,platform:k()}:{code:t.code,platform:k(t.platform)}}function L(t,e){return e==="douyin"?`/api/auth/miniprogram/douyin/${t}`:`/api/auth/miniprogram/${t}`}async function te(t){let e=k(t),r=httpClient.getMiniProgramLogin(e),n=async a=>await new Promise((l,m)=>{let s=false,i=o=>{if(!s){if(s=true,typeof o?.code=="string"&&o.code){l(o.code);return}m(new Error("Mini Program login failed: missing code"));}},c=o=>{s||(s=true,m(new Error(`Mini Program login failed: ${o instanceof Error?o.message:String(o)}`)));};try{let o=a({success:i,fail:c});if(o&&typeof o.then=="function"){o.then(i,c);return}o&&typeof o=="object"&&"code"in o&&i(o);}catch(o){c(o);}});if(typeof r!="function")throw new Error(`Mini Program login API is not available for platform '${e}'`);return {code:await n(r),platform:e}}function re(t){if(typeof t=="string")return T(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:k(t.platform)}:null}function ne(t){let e=new URLSearchParams(t);return e.get("access_token")||e.get("accessToken")}function oe(t){return new URLSearchParams(t).get("user")}function se(){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 ie={replace(t){window.location.replace(t);}};function S(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=se();return e?(ie.replace(e),{handled:true,target:e}):{handled:false}}function I(t){let{http:e,onLoginSuccess:r,onLogout:n,autoRedirectAfterLogin:a,storage:l,clearAuth:m}=t;return {async register(s){let i=await e.request({url:"/api/auth/register",method:"post",headers:{"Content-Type":"application/json"},data:s});if(i.data?.user&&i.data?.accessToken){r(i.data.user,i.data.accessToken);let c=R(a);i.data=S(i.data,c);}return i},async login(s){let i=s.loginType||Z(s);if(!i)return {data:null,error:{message:"Unable to determine login type. Please provide email, username, or phone.",status:400},status:400};let c={...s,loginType:i},o=await e.request({url:"/api/auth/login",method:"post",headers:{"Content-Type":"application/json"},data:c});if(o.data?.user&&o.data?.accessToken){r(o.data.user,o.data.accessToken);let p=R(a);o.data=S(o.data,p);}return o},async loginWithCode(s){let i=s.loginType||ee(s);if(!i)return {data:null,error:{message:"Unable to determine login type. Please provide email or phone.",status:400},status:400};let c={...s,loginType:i},o=await e.request({url:"/api/auth/login-with-code",method:"post",headers:{"Content-Type":"application/json"},data:c});if(o.data?.user&&o.data?.accessToken){r(o.data.user,o.data.accessToken);let p=R(a);o.data=S(o.data,p);}return o},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,i){if(typeof window>"u"){console.error("[AuthClient] OAuth login is only available in browser environment");return}let c=i?`/api/auth/oauth/${s}?redirect_url=${encodeURIComponent(i)}`:`/api/auth/oauth/${s}`;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 s=window.location.hash.substring(1),i=ne(s),c=oe(s);if(!i)return {data:null,error:{message:"OAuth callback failed: missing access token",status:400},status:400};let o;if(c)o=JSON.parse(decodeURIComponent(c));else {l.setItem(g.ACCESS_TOKEN,i);let d=await e.request({url:"/api/auth/me",method:"get",headers:{Authorization:`Bearer ${i}`}});if(!d.data)return {data:null,error:{message:"OAuth callback failed: unable to fetch user info",status:d.status||500},status:d.status||500};o=d.data;}if(r(o,i),window.history&&window.history.replaceState){let d=window.location.pathname+window.location.search;window.history.replaceState(null,"",d);}else window.location.hash="";let p=R(a);return {data:S({user:o,accessToken:i},p),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{code:i,platform:c}=T(s),o=await e.request({url:L("login",c),method:"post",headers:{"Content-Type":"application/json"},data:{code:i}});if(o.data?.user&&o.data?.accessToken){r(o.data.user,o.data.accessToken);let p=R(a);o.data=S(o.data,p);}return o},async miniLogin(s={}){try{let i=await te(s.platform);return await this.loginWithMiniProgram(i)}catch(i){return {data:null,error:{message:i instanceof Error?i.message:String(i),status:400},status:400}}},async getMiniProgramPhoneNumber(s){let{code:i,platform:c}=T(s),o=l.getItem(g.ACCESS_TOKEN);return o?e.request({url:L("phone",c),method:"post",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`},data:{code:i}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async miniGetPhone(s){let i=re(s);return i?this.getMiniProgramPhoneNumber(i):{data:null,error:{message:"Unable to resolve mini-program phone code from input",status:400},status:400}},async logout(){let s=l.getItem("amaster_access_token"),i=await e.request({url:"/api/auth/logout",method:"post",headers:s?{Authorization:`Bearer ${s}`}:void 0});return m(),n(),i},async refreshToken(){let s=await e.request({url:"/api/auth/refresh",method:"post"});return s.data?.accessToken&&l.setItem("amaster_access_token",s.data.accessToken),s}}}function _(t){let{getCurrentUser:e}=t;return {hasRole(r){let n=e();return !n||!n.roles?false:n.roles.includes(r)},hasPermission(r,n){let a=e();if(!a||!a.permissions)return false;let l=`${r}.${n}`;return a.permissions.includes(l)},hasAnyPermission(r){return r.some(({resource:n,action:a})=>this.hasPermission(n,a))},hasAllPermissions(r){return r.every(({resource:n,action:a})=>this.hasPermission(n,a))}}}function x(t){let{http:e,storage:r,onUserUpdate:n}=t;return {async getMe(){let a=r.getItem("amaster_access_token");if(!a)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 ${a}`}});return l.data&&n(l.data),l},async updateMe(a){let l=r.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:a});return m.data&&n(m.data),m},async changePassword(a){let l=r.getItem("amaster_access_token");return l?e.request({url:"/api/auth/change-password",method:"post",headers:{Authorization:`Bearer ${l}`,"Content-Type":"application/json"},data:a}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function H(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 a=r.getItem("amaster_access_token");return a?e.request({url:`/api/auth/oauth/${n}/unbind`,method:"delete",headers:{Authorization:`Bearer ${a}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function $(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 a=r.getItem("amaster_access_token");return a?n?e.request({url:`/api/auth/sessions/${n}`,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 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 le(t={},e){let{baseURL:r,headers:n,onTokenExpired:a,onUnauthorized:l,autoHandleOAuthCallback:m=true,autoRedirectAfterLogin:s=true,runtime:i}=t;i&&httpClient.setMiniProgramRuntime(i);let c=e||httpClient.createHttpClient({...M,baseURL:r,headers:n,runtime:i}),p=300,d=O(),y=new A,C=new w,P=null;try{let u=d.getItem(g.USER);u&&(P=JSON.parse(u));}catch(u){console.error("[AuthClient] Failed to load user from storage:",u);}let f;C.setRefreshCallback(async()=>{let u=await f.refreshToken();u.data?(await f.getMe(),y.emit("tokenRefreshed",u.data.accessToken)):(y.emit("tokenExpired"),a?.());});function N(u,h){d.setItem(g.ACCESS_TOKEN,h),d.setItem(g.USER,JSON.stringify(u)),P=u,C.scheduleRefreshFromToken(h,p),y.emit("login",u);}function q(u){P=u,d.setItem(g.USER,JSON.stringify(u));}function B(){y.emit("logout");}function E(){d.clear(),P=null,C.clearSchedule();}function F(){return P}let G=I({http:c,onLoginSuccess:N,onLogout:B,autoRedirectAfterLogin:s,storage:d,clearAuth:E}),z=_({getCurrentUser:F}),K=x({http:c,storage:d,onUserUpdate:q}),j=H({http:c,storage:d}),D=$({http:c,storage:d});if(f={...G,...z,...K,...j,...D,on(u,h){y.on(u,h);},off(u,h){y.off(u,h);},isAuthenticated(){return !!d.getItem(g.ACCESS_TOKEN)},getAccessToken(){return d.getItem(g.ACCESS_TOKEN)},setAccessToken(u){d.setItem(g.ACCESS_TOKEN,u),C.scheduleRefreshFromToken(u,p);},clearAuth:E},f.on("unauthorized",()=>{l?.();}),f.isAuthenticated()&&f.getMe().catch(u=>{console.warn("[AuthClient] Failed to sync user info on init:",u);}),m&&typeof window<"u"){let u=window.location.hash;u&&(u.includes("access_token")||u.includes("accessToken"))&&f.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 f}exports.createAuthClient=le;exports.defaultHttpClientOptions=M;exports.transformAmasterResponse=U;//# sourceMappingURL=index.cjs.map
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|