sumor 3.0.2 → 3.0.3
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 +163 -5
- package/dist/server/controllers/tokenRefreshController.d.ts +1 -1
- package/dist/server/controllers/tokenRefreshController.d.ts.map +1 -1
- package/dist/server/controllers/tokenRefreshController.js +32 -5
- package/dist/server/controllers/tokenRefreshController.js.map +1 -1
- package/dist/server/middlewares/loadJwtUserMiddleware.d.ts +2 -0
- package/dist/server/middlewares/loadJwtUserMiddleware.d.ts.map +1 -1
- package/dist/server/middlewares/loadJwtUserMiddleware.js +2 -0
- package/dist/server/middlewares/loadJwtUserMiddleware.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +0 -10
- package/dist/server/routes.js.map +1 -1
- package/dist/server/utils/authorizationUrlGenerator.d.ts +10 -0
- package/dist/server/utils/authorizationUrlGenerator.d.ts.map +1 -0
- package/dist/server/{controllers/infoController.js → utils/authorizationUrlGenerator.js} +5 -27
- package/dist/server/utils/authorizationUrlGenerator.js.map +1 -0
- package/dist/web/Sumor.d.ts +44 -1
- package/dist/web/Sumor.d.ts.map +1 -1
- package/dist/web/Sumor.js +103 -11
- package/dist/web/Sumor.js.map +1 -1
- package/dist/web/index.js +1 -1
- package/dist/web/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/server/controllers/infoController.d.ts +0 -12
- package/dist/server/controllers/infoController.d.ts.map +0 -1
- package/dist/server/controllers/infoController.js.map +0 -1
package/README.md
CHANGED
|
@@ -220,12 +220,157 @@ await req.sumor.revokeSession(sessionId)
|
|
|
220
220
|
|
|
221
221
|
Sumor automatically registers these routes:
|
|
222
222
|
|
|
223
|
-
- `GET /api/oauth/info` - Get OAuth provider info and authorization URL (no auth required)
|
|
224
223
|
- `GET /api/oauth/callback` - Handle OAuth provider callback with authorization code (no auth required)
|
|
225
|
-
- `PUT /api/oauth/token` - Refresh access token (can use refreshToken from body or cookie)
|
|
224
|
+
- `PUT /api/oauth/token` - Refresh access token and get user info + authorization URL (can use refreshToken from body or cookie)
|
|
225
|
+
- Response includes `endpoint` and `authorizeUrl` for OAuth configuration, and `user` object with current user info
|
|
226
226
|
- `POST /api/oauth/logout` - Logout and revoke session (requires valid token)
|
|
227
227
|
|
|
228
|
-
##
|
|
228
|
+
## 🎯 Web Client (Sumor Class)
|
|
229
|
+
|
|
230
|
+
The Sumor framework includes a client-side class for browser applications to manage OAuth and user state.
|
|
231
|
+
|
|
232
|
+
### Basic Setup
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
import { setupSumor } from 'sumor'
|
|
236
|
+
|
|
237
|
+
// Call this on app initialization
|
|
238
|
+
await setupSumor()
|
|
239
|
+
|
|
240
|
+
// Now use window.sumor to access the Sumor client
|
|
241
|
+
console.log(window.sumor.user) // Current user info or null
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Sumor Client Properties
|
|
245
|
+
|
|
246
|
+
- `endpoint` - OAuth provider endpoint
|
|
247
|
+
- `authorizeUrl` - Authorization URL for login redirect
|
|
248
|
+
- `user` - Current user object or null
|
|
249
|
+
- `id` - User ID
|
|
250
|
+
- `isVerified` - Verification status
|
|
251
|
+
- `roles` - Comma-separated role list
|
|
252
|
+
- `permissions` - Comma-separated permission list
|
|
253
|
+
|
|
254
|
+
### Sumor Client Methods
|
|
255
|
+
|
|
256
|
+
#### refresh(force = false)
|
|
257
|
+
|
|
258
|
+
Refresh OAuth configuration and user info from `PUT /api/oauth/token` using the stored refresh token.
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
// Use cache if available
|
|
262
|
+
await window.sumor.refresh()
|
|
263
|
+
|
|
264
|
+
// Force refresh, ignore cache
|
|
265
|
+
await window.sumor.refresh(true)
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
#### refreshConfig()
|
|
269
|
+
|
|
270
|
+
Manually refresh configuration (same as `refresh(true)`).
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
await window.sumor.refreshConfig()
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
#### login()
|
|
277
|
+
|
|
278
|
+
Redirect to OAuth authorization page.
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
window.sumor.login()
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
#### logout()
|
|
285
|
+
|
|
286
|
+
Logout and clear local user state.
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
await window.sumor.logout()
|
|
290
|
+
// window.sumor.user becomes null
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
#### hasPermission(module, operation = '\*')
|
|
294
|
+
|
|
295
|
+
Check if user has a specific permission.
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
// Check specific permission
|
|
299
|
+
if (window.sumor.hasPermission('posts', 'edit')) {
|
|
300
|
+
// User can edit posts
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Check module (any operation)
|
|
304
|
+
if (window.sumor.hasPermission('posts')) {
|
|
305
|
+
// User has any posts permission
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (window.sumor.hasPermission('posts', '*')) {
|
|
309
|
+
// Same as above
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
#### hasRole(role)
|
|
314
|
+
|
|
315
|
+
Check if user has a specific role.
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
if (window.sumor.hasRole('admin')) {
|
|
319
|
+
// User is admin
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
#### onUserChange(callback)
|
|
324
|
+
|
|
325
|
+
Subscribe to user state changes (login, logout, token refresh).
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
window.sumor.onUserChange(user => {
|
|
329
|
+
if (user) {
|
|
330
|
+
console.log('User logged in:', user.id)
|
|
331
|
+
} else {
|
|
332
|
+
console.log('User logged out')
|
|
333
|
+
}
|
|
334
|
+
})
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Web Client Example
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
import { setupSumor } from 'sumor'
|
|
341
|
+
import { ref, watch } from 'vue'
|
|
342
|
+
|
|
343
|
+
export default {
|
|
344
|
+
setup() {
|
|
345
|
+
const userInfo = ref(null)
|
|
346
|
+
const isLoggedIn = ref(false)
|
|
347
|
+
|
|
348
|
+
onMounted(async () => {
|
|
349
|
+
await setupSumor()
|
|
350
|
+
|
|
351
|
+
// Get initial user state
|
|
352
|
+
userInfo.value = window.sumor.user
|
|
353
|
+
isLoggedIn.value = !!window.sumor.user
|
|
354
|
+
|
|
355
|
+
// Subscribe to user changes
|
|
356
|
+
window.sumor.onUserChange(user => {
|
|
357
|
+
userInfo.value = user
|
|
358
|
+
isLoggedIn.value = !!user
|
|
359
|
+
})
|
|
360
|
+
})
|
|
361
|
+
|
|
362
|
+
return {
|
|
363
|
+
userInfo,
|
|
364
|
+
isLoggedIn,
|
|
365
|
+
login: () => window.sumor.login(),
|
|
366
|
+
logout: () => window.sumor.logout(),
|
|
367
|
+
canEdit: () => window.sumor.hasPermission('posts', 'edit')
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## 📚 API Reference
|
|
229
374
|
|
|
230
375
|
Sumor uses environment variables for configuration. The key is configuring the OAuth provider endpoint:
|
|
231
376
|
|
|
@@ -266,6 +411,7 @@ OAUTH_REDIRECT_URI=https://app.mycompany.com/api/oauth/callback
|
|
|
266
411
|
### Example 1: Protect Routes with Permission Checks
|
|
267
412
|
|
|
268
413
|
```typescript
|
|
414
|
+
// Server-side: Express route with permission check
|
|
269
415
|
app.post('/api/posts', (req: any, res) => {
|
|
270
416
|
// Check if user has permission
|
|
271
417
|
const permissions = req.jwtUser.permissions?.split(',') || []
|
|
@@ -277,6 +423,18 @@ app.post('/api/posts', (req: any, res) => {
|
|
|
277
423
|
// Create post logic here
|
|
278
424
|
res.json({ postId: 123 })
|
|
279
425
|
})
|
|
426
|
+
|
|
427
|
+
// Client-side: Vue component with permission check
|
|
428
|
+
export default {
|
|
429
|
+
setup() {
|
|
430
|
+
return {
|
|
431
|
+
canCreatePost: () => window.sumor.hasPermission('posts', 'create')
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Template
|
|
437
|
+
<button v-if="canCreatePost()" @click="createPost">Create Post</button>
|
|
280
438
|
```
|
|
281
439
|
|
|
282
440
|
### Example 2: Multi-Tenant Support
|
|
@@ -418,7 +576,7 @@ const permissions = req.jwtUser.permissions?.split(',').map(p => p.trim()) || []
|
|
|
418
576
|
┌──────────────────────────────────────┐
|
|
419
577
|
│ Your Express App (Port 3000) │
|
|
420
578
|
│ ┌────────────────────────────────┐ │
|
|
421
|
-
│ │
|
|
579
|
+
│ │ PUT /api/oauth/token │ │ (2) Get OAuth URL & User Info
|
|
422
580
|
│ │ GET /api/oauth/callback │ │
|
|
423
581
|
│ │ POST /api/oauth/logout │ │
|
|
424
582
|
│ └────────────────────────────────┘ │
|
|
@@ -441,7 +599,7 @@ const permissions = req.jwtUser.permissions?.split(',').map(p => p.trim()) || []
|
|
|
441
599
|
**Flow Steps:**
|
|
442
600
|
|
|
443
601
|
1. User clicks "Login" on your app
|
|
444
|
-
2. App calls `
|
|
602
|
+
2. App calls `PUT /api/oauth/token` with refresh token to get OAuth provider URL and user info
|
|
445
603
|
3. User redirected to OAuth provider
|
|
446
604
|
4. OAuth provider authenticates and redirects back to `/api/oauth/callback` with authorization code
|
|
447
605
|
5. Server exchanges code for JWT token via ITS OAuth API
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Token 刷新控制器
|
|
3
3
|
* PUT /api/oauth/token
|
|
4
4
|
*
|
|
5
|
-
* 刷新过期的 access_token
|
|
5
|
+
* 刷新过期的 access_token,并返回用户信息
|
|
6
6
|
*/
|
|
7
7
|
import { Request, Response } from 'express';
|
|
8
8
|
export default function tokenRefreshController(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenRefreshController.d.ts","sourceRoot":"","sources":["../../../server/controllers/tokenRefreshController.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"tokenRefreshController.d.ts","sourceRoot":"","sources":["../../../server/controllers/tokenRefreshController.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAO3C,wBAA8B,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,+CAyE/E"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Token 刷新控制器
|
|
4
4
|
* PUT /api/oauth/token
|
|
5
5
|
*
|
|
6
|
-
* 刷新过期的 access_token
|
|
6
|
+
* 刷新过期的 access_token,并返回用户信息
|
|
7
7
|
*/
|
|
8
8
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
9
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -12,6 +12,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.default = tokenRefreshController;
|
|
13
13
|
const oauthService_1 = __importDefault(require("../services/oauthService"));
|
|
14
14
|
const oauthTokenUtils_1 = require("../utils/oauthTokenUtils");
|
|
15
|
+
const tokenModel_1 = require("../models/tokenModel");
|
|
16
|
+
const config_1 = require("../utils/config");
|
|
17
|
+
const authorizationUrlGenerator_1 = require("../utils/authorizationUrlGenerator");
|
|
15
18
|
async function tokenRefreshController(req, res) {
|
|
16
19
|
try {
|
|
17
20
|
// 仅支持驼峰格式(refreshToken)
|
|
@@ -38,12 +41,36 @@ async function tokenRefreshController(req, res) {
|
|
|
38
41
|
if (tokenData.refreshToken && tokenData.refreshToken !== refreshToken) {
|
|
39
42
|
(0, oauthTokenUtils_1.setOAuthTokenCookie)(res, tokenData.refreshToken, 2592000, 'refresh'); // 30 days
|
|
40
43
|
}
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
// 验证新的 accessToken 获取用户信息
|
|
45
|
+
let user = null;
|
|
46
|
+
try {
|
|
47
|
+
const tokenModel = (0, tokenModel_1.getTokenModel)();
|
|
48
|
+
const claims = await tokenModel.verify(tokenData.accessToken);
|
|
49
|
+
if (claims.sub) {
|
|
50
|
+
user = {
|
|
51
|
+
id: claims.sub,
|
|
52
|
+
isVerified: claims.isVerified || 0,
|
|
53
|
+
roles: claims.roles || '',
|
|
54
|
+
permissions: claims.permissions || ''
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
// Token 验证失败,返回 null user
|
|
60
|
+
console.error('Failed to verify new token:', error);
|
|
61
|
+
}
|
|
62
|
+
// ✅ 返回用户信息供客户端使用
|
|
63
|
+
// Token 已通过 HttpOnly Cookie 设置,响应中包含 user 信息用于更新客户端状态
|
|
64
|
+
const config = (0, config_1.getOAuthConfig)();
|
|
65
|
+
const oauthAuthorizeUrl = (0, authorizationUrlGenerator_1.generateAuthorizationUrl)();
|
|
44
66
|
res.status(200).json({
|
|
45
67
|
code: 'OK',
|
|
46
|
-
message: 'Token 刷新成功'
|
|
68
|
+
message: 'Token 刷新成功',
|
|
69
|
+
data: {
|
|
70
|
+
endpoint: config.endpoint,
|
|
71
|
+
authorizeUrl: oauthAuthorizeUrl,
|
|
72
|
+
user
|
|
73
|
+
}
|
|
47
74
|
});
|
|
48
75
|
}
|
|
49
76
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenRefreshController.js","sourceRoot":"","sources":["../../../server/controllers/tokenRefreshController.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;
|
|
1
|
+
{"version":3,"file":"tokenRefreshController.js","sourceRoot":"","sources":["../../../server/controllers/tokenRefreshController.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,8 @@ import { Response, NextFunction } from 'express';
|
|
|
14
14
|
* - jti: JWT 唯一标识
|
|
15
15
|
* - roleLevel: 用户角色级别
|
|
16
16
|
* - isVerified: 用户认证状态标记(0=未认证, 1=已认证)
|
|
17
|
+
* - roles: 用户角色列表(逗号分隔的字符串)
|
|
18
|
+
* - permissions: 用户权限列表(逗号分隔的2段式权限字符串)
|
|
17
19
|
* - iss: 签发者
|
|
18
20
|
* - sub: 用户 ID(标准 JWT 字段)
|
|
19
21
|
* - aud: 受众
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadJwtUserMiddleware.d.ts","sourceRoot":"","sources":["../../../server/middlewares/loadJwtUserMiddleware.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAIhD
|
|
1
|
+
{"version":3,"file":"loadJwtUserMiddleware.d.ts","sourceRoot":"","sources":["../../../server/middlewares/loadJwtUserMiddleware.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAIhD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAqCf;AAED,eAAe,qBAAqB,CAAA"}
|
|
@@ -18,6 +18,8 @@ const authUtils_1 = require("../utils/authUtils");
|
|
|
18
18
|
* - jti: JWT 唯一标识
|
|
19
19
|
* - roleLevel: 用户角色级别
|
|
20
20
|
* - isVerified: 用户认证状态标记(0=未认证, 1=已认证)
|
|
21
|
+
* - roles: 用户角色列表(逗号分隔的字符串)
|
|
22
|
+
* - permissions: 用户权限列表(逗号分隔的2段式权限字符串)
|
|
21
23
|
* - iss: 签发者
|
|
22
24
|
* - sub: 用户 ID(标准 JWT 字段)
|
|
23
25
|
* - aud: 受众
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadJwtUserMiddleware.js","sourceRoot":"","sources":["../../../server/middlewares/loadJwtUserMiddleware.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;
|
|
1
|
+
{"version":3,"file":"loadJwtUserMiddleware.js","sourceRoot":"","sources":["../../../server/middlewares/loadJwtUserMiddleware.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAyBH,sDAyCC;AA/DD,qDAAkD;AAClD,kDAAmD;AAEnD;;;;;;;;;;;;;;;;;;GAkBG;AACI,KAAK,UAAU,qBAAqB,CACzC,GAAQ,EACR,GAAa,EACb,IAAkB;IAElB,IAAI,CAAC;QACH,qBAAqB;QACrB,MAAM,KAAK,GAAG,IAAA,0BAAc,EAAC,GAAG,CAAC,CAAA;QAEjC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;YAClB,OAAO,IAAI,EAAE,CAAA;QACf,CAAC;QAED,cAAc;QACd,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAA,wBAAW,EAAC,KAAK,CAAC,CAAA;YAEvC,mBAAmB;YACnB,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;gBAChB,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;gBAClB,OAAO,IAAI,EAAE,CAAA;YACf,CAAC;YAED,oBAAoB;YACpB,GAAG,CAAC,OAAO,GAAG;gBACZ,GAAG,MAAM;gBACT,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,sBAAsB;gBAC1C,GAAG,EAAE,MAAM,CAAC,GAAG;aAChB,CAAA;YAED,IAAI,EAAE,CAAA;QACR,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,wBAAwB;YACxB,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;YAClB,IAAI,EAAE,CAAA;QACR,CAAC;IACH,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;QAClB,IAAI,CAAC,KAAK,CAAC,CAAA;IACb,CAAC;AACH,CAAC;AAED,kBAAe,qBAAqB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../server/routes.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../server/routes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,QAAA,MAAM,SAAS,4CAAmB,CAAA;AA+BlC,eAAe,SAAS,CAAA"}
|
package/dist/server/routes.js
CHANGED
|
@@ -10,7 +10,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
const express_1 = __importDefault(require("express"));
|
|
11
11
|
const tokenRefreshController_1 = __importDefault(require("./controllers/tokenRefreshController"));
|
|
12
12
|
const oauthCallbackController_1 = __importDefault(require("./controllers/oauthCallbackController"));
|
|
13
|
-
const infoController_1 = require("./controllers/infoController");
|
|
14
13
|
const logoutController_1 = require("./controllers/logoutController");
|
|
15
14
|
const itsRoutes = express_1.default.Router();
|
|
16
15
|
/**
|
|
@@ -33,15 +32,6 @@ itsRoutes.put('/token', tokenRefreshController_1.default);
|
|
|
33
32
|
* 无需认证 - ITS 直接调用此端点
|
|
34
33
|
*/
|
|
35
34
|
itsRoutes.get('/callback', oauthCallbackController_1.default);
|
|
36
|
-
/**
|
|
37
|
-
* 获取 ITS 配置信息 - 无需认证
|
|
38
|
-
* GET /api/oauth/info
|
|
39
|
-
*
|
|
40
|
-
* 返回:
|
|
41
|
-
* - endpoint: ITS 服务器地址
|
|
42
|
-
* - oauthAuthorizeUrl: OAuth 授权 URL
|
|
43
|
-
*/
|
|
44
|
-
itsRoutes.get('/info', infoController_1.getItsInfo);
|
|
45
35
|
/**
|
|
46
36
|
* 用户登出 - 需要有效的 Token
|
|
47
37
|
* POST /api/oauth/logout
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../server/routes.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;AAEH,sDAA6B;AAC7B,kGAAyE;AACzE,oGAA2E;AAC3E,
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../server/routes.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;AAEH,sDAA6B;AAC7B,kGAAyE;AACzE,oGAA2E;AAC3E,qEAAuD;AAEvD,MAAM,SAAS,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAA;AAElC;;GAEG;AAEH;;;;;;;GAOG;AACH,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,gCAAsB,CAAC,CAAA;AAE/C;;;;;;GAMG;AACH,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,iCAAuB,CAAC,CAAA;AAEnD;;;GAGG;AACH,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,yBAAM,CAAC,CAAA;AAEjC,kBAAe,SAAS,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 生成授权 URL 工具函数
|
|
3
|
+
* RFC 6749 §4.1.1,支持 PKCE(RFC 7636)用于增强安全性
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* 生成授权 URL
|
|
7
|
+
* RFC 6749 §4.1.1,支持 PKCE(RFC 7636)用于增强安全性
|
|
8
|
+
*/
|
|
9
|
+
export declare function generateAuthorizationUrl(): string;
|
|
10
|
+
//# sourceMappingURL=authorizationUrlGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorizationUrlGenerator.d.ts","sourceRoot":"","sources":["../../../server/utils/authorizationUrlGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAkCH;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CA0BjD"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* 生成授权 URL 工具函数
|
|
4
|
+
* RFC 6749 §4.1.1,支持 PKCE(RFC 7636)用于增强安全性
|
|
5
5
|
*/
|
|
6
6
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
7
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
8
|
};
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.
|
|
10
|
+
exports.generateAuthorizationUrl = generateAuthorizationUrl;
|
|
11
11
|
const crypto_1 = __importDefault(require("crypto"));
|
|
12
|
-
const config_1 = require("
|
|
12
|
+
const config_1 = require("./config");
|
|
13
13
|
/**
|
|
14
14
|
* 生成 PKCE code_challenge 和 code_verifier
|
|
15
15
|
*/
|
|
@@ -58,26 +58,4 @@ function generateAuthorizationUrl() {
|
|
|
58
58
|
const authUrl = `${oauthConfig.baseUrl}/authorize?${params.toString()}`;
|
|
59
59
|
return authUrl;
|
|
60
60
|
}
|
|
61
|
-
|
|
62
|
-
* 获取 ITS 配置信息
|
|
63
|
-
* GET /api/oauth/info
|
|
64
|
-
*
|
|
65
|
-
* 无需认证 - 在 JWT 中间件之前调用
|
|
66
|
-
*/
|
|
67
|
-
const getItsInfo = async (req, res, next) => {
|
|
68
|
-
try {
|
|
69
|
-
const oauthAuthorizeUrl = generateAuthorizationUrl();
|
|
70
|
-
res.json({
|
|
71
|
-
code: 'OK',
|
|
72
|
-
data: {
|
|
73
|
-
endpoint: req.config.its?.endpoint,
|
|
74
|
-
authorizeUrl: oauthAuthorizeUrl
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
catch (error) {
|
|
79
|
-
next(error);
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
exports.getItsInfo = getItsInfo;
|
|
83
|
-
//# sourceMappingURL=infoController.js.map
|
|
61
|
+
//# sourceMappingURL=authorizationUrlGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorizationUrlGenerator.js","sourceRoot":"","sources":["../../../server/utils/authorizationUrlGenerator.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;AAsCH,4DA0BC;AA9DD,oDAA2B;AAC3B,qCAAyC;AAEzC;;GAEG;AACH,SAAS,qBAAqB;IAI5B,MAAM,YAAY,GAAG,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC3D,MAAM,SAAS,GAAG,gBAAM;SACrB,UAAU,CAAC,QAAQ,CAAC;SACpB,MAAM,CAAC,YAAY,CAAC;SACpB,MAAM,CAAC,QAAQ,CAAC;SAChB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IAEpB,OAAO;QACL,aAAa,EAAE,SAAS;QACxB,YAAY,EAAE,YAAY;KAC3B,CAAA;AACH,CAAC;AAED;;GAEG;AACH,SAAS,aAAa;IACpB,OAAO,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AAC/C,CAAC;AAED;;;GAGG;AACH,SAAgB,wBAAwB;IACtC,MAAM,WAAW,GAAG,IAAA,uBAAc,GAAE,CAAA;IACpC,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,qBAAqB,EAAE,CAAA;IAE/D,MAAM,GAAG,GAAG,WAAW,CAAC,WAAW,CAAA;IAEnC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAA;IAClD,CAAC;IAED,MAAM,WAAW,GAAG,aAAa,EAAE,CAAA;IACnC,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,GAAG,GAAG,WAAW,CAAA;IAEvF,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,SAAS,EAAE,WAAW,CAAC,SAAS;QAChC,WAAW,EAAE,GAAG;QAChB,YAAY,EAAE,MAAM;QACpB,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,cAAc;QACrB,aAAa,EAAE,aAAa;QAC5B,mBAAmB,EAAE,MAAM;KAC5B,CAAC,CAAA;IAEF,MAAM,OAAO,GAAG,GAAG,WAAW,CAAC,OAAO,cAAc,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAA;IAEvE,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
package/dist/web/Sumor.d.ts
CHANGED
|
@@ -10,18 +10,39 @@ export declare class ApiError extends Error {
|
|
|
10
10
|
status?: number;
|
|
11
11
|
constructor(message: string, code: string | number, status?: number);
|
|
12
12
|
}
|
|
13
|
+
export interface UserInfo {
|
|
14
|
+
id: string;
|
|
15
|
+
isVerified: number;
|
|
16
|
+
roles: string;
|
|
17
|
+
permissions: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 用户变化回调类型
|
|
21
|
+
*/
|
|
22
|
+
export type UserChangeCallback = (user: UserInfo | null) => void;
|
|
13
23
|
export declare class Sumor {
|
|
14
24
|
endpoint: string;
|
|
15
25
|
authorizeUrl: string;
|
|
26
|
+
user: UserInfo | null;
|
|
16
27
|
axios: AxiosInstance;
|
|
17
28
|
private loaded;
|
|
18
29
|
private loadTime;
|
|
19
30
|
private readonly CACHE_TTL;
|
|
20
31
|
private isRefreshing;
|
|
21
32
|
private refreshSubscribers;
|
|
33
|
+
private userChangeSubscribers;
|
|
22
34
|
constructor();
|
|
23
35
|
private subscribeTokenRefresh;
|
|
24
36
|
private onTokenRefreshed;
|
|
37
|
+
/**
|
|
38
|
+
* 订阅用户变化事件
|
|
39
|
+
* @param callback 用户变化时的回调函数
|
|
40
|
+
*/
|
|
41
|
+
onUserChange(callback: UserChangeCallback): void;
|
|
42
|
+
/**
|
|
43
|
+
* 触发用户变化事件
|
|
44
|
+
*/
|
|
45
|
+
private emitUserChange;
|
|
25
46
|
/**
|
|
26
47
|
* 创建 Axios 实例并配置拦截器
|
|
27
48
|
*/
|
|
@@ -39,7 +60,12 @@ export declare class Sumor {
|
|
|
39
60
|
*/
|
|
40
61
|
post<T = any>(url: string, data: Record<string, any>, config?: AxiosRequestConfig): Promise<T>;
|
|
41
62
|
private isCacheValid;
|
|
42
|
-
|
|
63
|
+
/**
|
|
64
|
+
* 刷新 OAuth 信息和用户状态
|
|
65
|
+
* 通过刷新 access token 接口获取 endpoint、authorizeUrl 和用户信息
|
|
66
|
+
* @param force 是否强制刷新,忽略缓存
|
|
67
|
+
*/
|
|
68
|
+
refreshToken(force?: boolean): Promise<void>;
|
|
43
69
|
getAvatarUrl(id: string): string;
|
|
44
70
|
getHomeUrl(): string;
|
|
45
71
|
getSiteUrl(): string;
|
|
@@ -57,5 +83,22 @@ export declare class Sumor {
|
|
|
57
83
|
* 手动刷新配置(用于处理长期运行的应用需要更新配置的情况)
|
|
58
84
|
*/
|
|
59
85
|
refreshConfig(): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* 检查用户是否有特定权限
|
|
88
|
+
* @param module 模块名称(如:posts、comments)
|
|
89
|
+
* @param operation 操作名称(如:view、edit、delete),为 * 或不传时表示检查模块的任何权限
|
|
90
|
+
* @returns 是否拥有权限
|
|
91
|
+
*
|
|
92
|
+
* 例如:
|
|
93
|
+
* - hasPermission('posts', 'edit') 检查是否有 'posts:edit' 权限
|
|
94
|
+
* - hasPermission('posts', '*') 或 hasPermission('posts') 检查是否有任何 posts 权限
|
|
95
|
+
*/
|
|
96
|
+
hasPermission(module: string, operation?: string): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* 检查用户是否拥有指定角色
|
|
99
|
+
* @param role 角色名称
|
|
100
|
+
* @returns 是否拥有该角色
|
|
101
|
+
*/
|
|
102
|
+
hasRole(role: string): boolean;
|
|
60
103
|
}
|
|
61
104
|
//# sourceMappingURL=Sumor.d.ts.map
|
package/dist/web/Sumor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sumor.d.ts","sourceRoot":"","sources":["../../web/Sumor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAc,EAAE,aAAa,EAAE,kBAAkB,EAAc,MAAM,OAAO,CAAA;AAW5E;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;gBAEH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;CAMpE;AAED,qBAAa,KAAK;IACT,QAAQ,EAAE,MAAM,CAAK;IACrB,YAAY,EAAE,MAAM,CAAK;IACzB,KAAK,EAAE,aAAa,CAAA;IAC3B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAY;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAU;IACpC,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,kBAAkB,CAAwB;;
|
|
1
|
+
{"version":3,"file":"Sumor.d.ts","sourceRoot":"","sources":["../../web/Sumor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAc,EAAE,aAAa,EAAE,kBAAkB,EAAc,MAAM,OAAO,CAAA;AAW5E;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;gBAEH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;CAMpE;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAA;AAEhE,qBAAa,KAAK;IACT,QAAQ,EAAE,MAAM,CAAK;IACrB,YAAY,EAAE,MAAM,CAAK;IACzB,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAO;IAC5B,KAAK,EAAE,aAAa,CAAA;IAC3B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAY;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAU;IACpC,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,kBAAkB,CAAwB;IAClD,OAAO,CAAC,qBAAqB,CAAgC;;IAO7D,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,gBAAgB;IAKxB;;;OAGG;IACH,YAAY,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI;IAIhD;;OAEG;IACH,OAAO,CAAC,cAAc;IAUtB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAgH3B;;OAEG;IACG,OAAO,CAAC,CAAC,GAAG,GAAG,EACnB,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EAChC,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,CAAC,CAAC;IAQb;;OAEG;IACG,GAAG,CAAC,CAAC,GAAG,GAAG,EACf,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC5B,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,CAAC,CAAC;IAIb;;OAEG;IACG,IAAI,CAAC,CAAC,GAAG,GAAG,EAChB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,CAAC,CAAC;IAIb,OAAO,CAAC,YAAY;IAQpB;;;;OAIG;IACG,YAAY,CAAC,KAAK,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCzD,YAAY,CAAC,EAAE,EAAE,MAAM;IAIvB,UAAU;IAIV,UAAU;IAIV,UAAU;IAIV,cAAc;IAId;;OAEG;IACH,KAAK;IAQL;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAc7B;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC;;;;;;;;;OASG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,MAAY,GAAG,OAAO;IAiB/D;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAQ/B"}
|
package/dist/web/Sumor.js
CHANGED
|
@@ -17,11 +17,13 @@ export class Sumor {
|
|
|
17
17
|
constructor() {
|
|
18
18
|
this.endpoint = '';
|
|
19
19
|
this.authorizeUrl = '';
|
|
20
|
+
this.user = null;
|
|
20
21
|
this.loaded = false;
|
|
21
22
|
this.loadTime = 0;
|
|
22
23
|
this.CACHE_TTL = 3600000; // 1小时,单位毫秒
|
|
23
24
|
this.isRefreshing = false;
|
|
24
25
|
this.refreshSubscribers = [];
|
|
26
|
+
this.userChangeSubscribers = [];
|
|
25
27
|
console.log('初始化轻呈云客户端...');
|
|
26
28
|
this.axios = this.createAxiosInstance();
|
|
27
29
|
}
|
|
@@ -32,6 +34,26 @@ export class Sumor {
|
|
|
32
34
|
this.refreshSubscribers.forEach(callback => callback());
|
|
33
35
|
this.refreshSubscribers = [];
|
|
34
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* 订阅用户变化事件
|
|
39
|
+
* @param callback 用户变化时的回调函数
|
|
40
|
+
*/
|
|
41
|
+
onUserChange(callback) {
|
|
42
|
+
this.userChangeSubscribers.push(callback);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 触发用户变化事件
|
|
46
|
+
*/
|
|
47
|
+
emitUserChange() {
|
|
48
|
+
this.userChangeSubscribers.forEach(callback => {
|
|
49
|
+
try {
|
|
50
|
+
callback(this.user);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error('User change callback error:', error);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
35
57
|
/**
|
|
36
58
|
* 创建 Axios 实例并配置拦截器
|
|
37
59
|
*/
|
|
@@ -75,6 +97,15 @@ export class Sumor {
|
|
|
75
97
|
});
|
|
76
98
|
const response = await refreshInstance.put('/api/oauth/token', {});
|
|
77
99
|
if (response.status === 200) {
|
|
100
|
+
// 如果响应中包含新的用户信息,更新本地状态
|
|
101
|
+
if (response.data && response.data.data && response.data.data.user) {
|
|
102
|
+
const previousUser = this.user;
|
|
103
|
+
this.user = response.data.data.user;
|
|
104
|
+
// 如果用户信息发生变化,触发回调
|
|
105
|
+
if (this.user !== previousUser) {
|
|
106
|
+
this.emitUserChange();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
78
109
|
this.isRefreshing = false;
|
|
79
110
|
this.onTokenRefreshed();
|
|
80
111
|
return instance(originalRequest);
|
|
@@ -86,6 +117,9 @@ export class Sumor {
|
|
|
86
117
|
catch (refreshError) {
|
|
87
118
|
this.isRefreshing = false;
|
|
88
119
|
this.refreshSubscribers = [];
|
|
120
|
+
// 清空用户信息,表示已退出登录
|
|
121
|
+
this.user = null;
|
|
122
|
+
this.emitUserChange();
|
|
89
123
|
const apiError = new ApiError('令牌已过期,请重新登录', 'TOKEN_REFRESH_FAILED', 401);
|
|
90
124
|
return Promise.reject(apiError);
|
|
91
125
|
}
|
|
@@ -138,22 +172,42 @@ export class Sumor {
|
|
|
138
172
|
const now = Date.now();
|
|
139
173
|
return now - this.loadTime < this.CACHE_TTL;
|
|
140
174
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
175
|
+
/**
|
|
176
|
+
* 刷新 OAuth 信息和用户状态
|
|
177
|
+
* 通过刷新 access token 接口获取 endpoint、authorizeUrl 和用户信息
|
|
178
|
+
* @param force 是否强制刷新,忽略缓存
|
|
179
|
+
*/
|
|
180
|
+
async refreshToken(force = false) {
|
|
181
|
+
// 如果缓存仍然有效且不是强制刷新,直接返回
|
|
182
|
+
if (!force && this.isCacheValid()) {
|
|
144
183
|
return;
|
|
145
184
|
}
|
|
185
|
+
const previousUser = this.user;
|
|
146
186
|
try {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
187
|
+
// 直接调用 PUT /api/oauth/token 刷新接口
|
|
188
|
+
// 浏览器会自动在请求中包含 HttpOnly Cookie 中的 refresh_token
|
|
189
|
+
const response = await this.axios.put('/api/oauth/token', {});
|
|
190
|
+
if (response && response.data) {
|
|
191
|
+
this.endpoint = response.data.endpoint || '';
|
|
192
|
+
this.authorizeUrl = response.data.authorizeUrl || '';
|
|
193
|
+
this.user = response.data.user || null;
|
|
151
194
|
}
|
|
152
195
|
this.loaded = true;
|
|
153
196
|
this.loadTime = Date.now();
|
|
197
|
+
// 如果用户信息发生变化,触发回调
|
|
198
|
+
if (this.user !== previousUser) {
|
|
199
|
+
this.emitUserChange();
|
|
200
|
+
}
|
|
154
201
|
}
|
|
155
202
|
catch (error) {
|
|
156
|
-
console.error('Failed to
|
|
203
|
+
console.error('Failed to refresh OAuth info:', error);
|
|
204
|
+
// 刷新失败时,清除用户信息(401 表示未认证)
|
|
205
|
+
if (error.response?.status === 401 || error.code === 'TOKEN_REFRESH_FAILED') {
|
|
206
|
+
if (this.user !== null) {
|
|
207
|
+
this.user = null;
|
|
208
|
+
this.emitUserChange();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
157
211
|
}
|
|
158
212
|
}
|
|
159
213
|
getAvatarUrl(id) {
|
|
@@ -194,14 +248,52 @@ export class Sumor {
|
|
|
194
248
|
// 即使请求失败,仍然返回(由调用方处理清除本地状态)
|
|
195
249
|
throw error;
|
|
196
250
|
}
|
|
251
|
+
finally {
|
|
252
|
+
// 清空本地用户信息
|
|
253
|
+
this.user = null;
|
|
254
|
+
this.emitUserChange();
|
|
255
|
+
}
|
|
197
256
|
}
|
|
198
257
|
/**
|
|
199
258
|
* 手动刷新配置(用于处理长期运行的应用需要更新配置的情况)
|
|
200
259
|
*/
|
|
201
260
|
async refreshConfig() {
|
|
202
|
-
this.
|
|
203
|
-
|
|
204
|
-
|
|
261
|
+
await this.refreshToken(true);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* 检查用户是否有特定权限
|
|
265
|
+
* @param module 模块名称(如:posts、comments)
|
|
266
|
+
* @param operation 操作名称(如:view、edit、delete),为 * 或不传时表示检查模块的任何权限
|
|
267
|
+
* @returns 是否拥有权限
|
|
268
|
+
*
|
|
269
|
+
* 例如:
|
|
270
|
+
* - hasPermission('posts', 'edit') 检查是否有 'posts:edit' 权限
|
|
271
|
+
* - hasPermission('posts', '*') 或 hasPermission('posts') 检查是否有任何 posts 权限
|
|
272
|
+
*/
|
|
273
|
+
hasPermission(module, operation = '*') {
|
|
274
|
+
if (!this.user || !this.user.permissions) {
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
const userPermissions = this.user.permissions.split(',').map(p => p.trim());
|
|
278
|
+
// 如果 operation 为 *,检查是否有该模块的任何权限
|
|
279
|
+
if (operation === '*') {
|
|
280
|
+
return userPermissions.some(permission => permission.startsWith(`${module}:`));
|
|
281
|
+
}
|
|
282
|
+
// 否则检查特定的 module:operation 权限
|
|
283
|
+
const requiredPermission = `${module}:${operation}`;
|
|
284
|
+
return userPermissions.includes(requiredPermission);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* 检查用户是否拥有指定角色
|
|
288
|
+
* @param role 角色名称
|
|
289
|
+
* @returns 是否拥有该角色
|
|
290
|
+
*/
|
|
291
|
+
hasRole(role) {
|
|
292
|
+
if (!this.user || !this.user.roles) {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
const userRoles = this.user.roles.split(',');
|
|
296
|
+
return userRoles.some(r => r.trim() === role);
|
|
205
297
|
}
|
|
206
298
|
}
|
|
207
299
|
//# sourceMappingURL=Sumor.js.map
|
package/dist/web/Sumor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sumor.js","sourceRoot":"","sources":["../../web/Sumor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAwD,MAAM,OAAO,CAAA;AAW5E;;GAEG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IAIjC,YAAY,OAAe,EAAE,IAAqB,EAAE,MAAe;QACjE,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,IAAI,GAAG,UAAU,CAAA;IACxB,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"Sumor.js","sourceRoot":"","sources":["../../web/Sumor.ts"],"names":[],"mappings":"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"}
|
package/dist/web/index.js
CHANGED
package/dist/web/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../web/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAE/B,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAA;IAEzB,YAAY;IACZ,MAAM,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../web/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAE/B,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAA;IAEzB,YAAY;IACZ,MAAM,KAAK,CAAC,YAAY,EAAE,CAAA;IAE1B,kBAAkB;IAClB,MAAM,CAAC,KAAK,GAAG,KAAK,CAAA;IAEpB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;AAC9B,CAAC;AAED,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA"}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"infoController.d.ts","sourceRoot":"","sources":["../../../server/controllers/infoController.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAkEH;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GAAU,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,GAAG,kBAc7D,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"infoController.js","sourceRoot":"","sources":["../../../server/controllers/infoController.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;AAEH,oDAA2B;AAC3B,4CAAgD;AAEhD;;GAEG;AACH,SAAS,qBAAqB;IAI5B,MAAM,YAAY,GAAG,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC3D,MAAM,SAAS,GAAG,gBAAM;SACrB,UAAU,CAAC,QAAQ,CAAC;SACpB,MAAM,CAAC,YAAY,CAAC;SACpB,MAAM,CAAC,QAAQ,CAAC;SAChB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IAEpB,OAAO;QACL,aAAa,EAAE,SAAS;QACxB,YAAY,EAAE,YAAY;KAC3B,CAAA;AACH,CAAC;AAED;;GAEG;AACH,SAAS,aAAa;IACpB,OAAO,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AAC/C,CAAC;AAED;;;GAGG;AACH,SAAS,wBAAwB;IAC/B,MAAM,WAAW,GAAG,IAAA,uBAAc,GAAE,CAAA;IACpC,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,qBAAqB,EAAE,CAAA;IAE/D,MAAM,GAAG,GAAG,WAAW,CAAC,WAAW,CAAA;IAEnC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAA;IAClD,CAAC;IAED,MAAM,WAAW,GAAG,aAAa,EAAE,CAAA;IACnC,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,GAAG,GAAG,WAAW,CAAA;IAEvF,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,SAAS,EAAE,WAAW,CAAC,SAAS;QAChC,WAAW,EAAE,GAAG;QAChB,YAAY,EAAE,MAAM;QACpB,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,cAAc;QACrB,aAAa,EAAE,aAAa;QAC5B,mBAAmB,EAAE,MAAM;KAC5B,CAAC,CAAA;IAEF,MAAM,OAAO,GAAG,GAAG,WAAW,CAAC,OAAO,cAAc,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAA;IAEvE,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;GAKG;AACI,MAAM,UAAU,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAQ,EAAE,IAAS,EAAE,EAAE;IAChE,IAAI,CAAC;QACH,MAAM,iBAAiB,GAAG,wBAAwB,EAAE,CAAA;QAEpD,GAAG,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,IAAI;YACV,IAAI,EAAE;gBACJ,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ;gBAClC,YAAY,EAAE,iBAAiB;aAChC;SACF,CAAC,CAAA;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,KAAK,CAAC,CAAA;IACb,CAAC;AACH,CAAC,CAAA;AAdY,QAAA,UAAU,cActB"}
|