sumor 3.1.5 → 3.1.6

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 CHANGED
@@ -266,14 +266,6 @@ await window.sumor.refresh()
266
266
  await window.sumor.refresh(true)
267
267
  ```
268
268
 
269
- #### refreshConfig()
270
-
271
- Manually refresh configuration (same as `refresh(true)`).
272
-
273
- ```typescript
274
- await window.sumor.refreshConfig()
275
- ```
276
-
277
269
  #### login()
278
270
 
279
271
  Redirect to OAuth authorization page.
@@ -0,0 +1,12 @@
1
+ /**
2
+ * 检查用户是否有特定权限
3
+ * @param module 模块名称(如:posts、comments)
4
+ * @param operation 操作名称(如:view、edit、delete),为 * 或不传时表示检查模块的任何权限
5
+ * @returns 是否拥有权限
6
+ *
7
+ * 例如:
8
+ * - hasPermission('posts', 'edit') 检查是否有 'posts:edit' 权限
9
+ * - hasPermission('posts', '*') 或 hasPermission('posts') 检查是否有任何 posts 权限
10
+ */
11
+ export default function hasPermission(module: string, operation?: string): boolean;
12
+ //# sourceMappingURL=hasPermission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hasPermission.d.ts","sourceRoot":"","sources":["../../../web/api/hasPermission.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,MAAY,GAAG,OAAO,CAgBtF"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * 检查用户是否有特定权限
3
+ * @param module 模块名称(如:posts、comments)
4
+ * @param operation 操作名称(如:view、edit、delete),为 * 或不传时表示检查模块的任何权限
5
+ * @returns 是否拥有权限
6
+ *
7
+ * 例如:
8
+ * - hasPermission('posts', 'edit') 检查是否有 'posts:edit' 权限
9
+ * - hasPermission('posts', '*') 或 hasPermission('posts') 检查是否有任何 posts 权限
10
+ */
11
+ import { oauthStore } from '../OAuthStore';
12
+ export default function hasPermission(module, operation = '*') {
13
+ const user = oauthStore.getUser();
14
+ if (!user || !user.permissions) {
15
+ return false;
16
+ }
17
+ const userPermissions = user.permissions.split(',').map(p => p.trim());
18
+ // 如果 operation 为 *,检查是否有该模块的任何权限
19
+ if (operation === '*') {
20
+ return userPermissions.some(permission => permission.startsWith(`${module}:`));
21
+ }
22
+ // 否则检查特定的 module:operation 权限
23
+ const requiredPermission = `${module}:${operation}`;
24
+ return userPermissions.includes(requiredPermission);
25
+ }
26
+ //# sourceMappingURL=hasPermission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hasPermission.js","sourceRoot":"","sources":["../../../web/api/hasPermission.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE1C,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,MAAc,EAAE,YAAoB,GAAG;IAC3E,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,EAAE,CAAA;IACjC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;IAEtE,iCAAiC;IACjC,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;QACtB,OAAO,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAA;IAChF,CAAC;IAED,8BAA8B;IAC9B,MAAM,kBAAkB,GAAG,GAAG,MAAM,IAAI,SAAS,EAAE,CAAA;IACnD,OAAO,eAAe,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAA;AACrD,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 检查用户是否拥有指定角色
3
+ * @param role 角色名称
4
+ * @returns 是否拥有该角色
5
+ */
6
+ export default function hasRole(role: string): boolean;
7
+ //# sourceMappingURL=hasRole.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hasRole.d.ts","sourceRoot":"","sources":["../../../web/api/hasRole.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQrD"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * 检查用户是否拥有指定角色
3
+ * @param role 角色名称
4
+ * @returns 是否拥有该角色
5
+ */
6
+ import { oauthStore } from '../OAuthStore';
7
+ export default function hasRole(role) {
8
+ const user = oauthStore.getUser();
9
+ if (!user || !user.roles) {
10
+ return false;
11
+ }
12
+ const userRoles = user.roles.split(',');
13
+ return userRoles.some(r => r.trim() === role);
14
+ }
15
+ //# sourceMappingURL=hasRole.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hasRole.js","sourceRoot":"","sources":["../../../web/api/hasRole.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE1C,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,IAAY;IAC1C,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,EAAE,CAAA;IACjC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACzB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACvC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,CAAA;AAC/C,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 登录:跳转到授权页面
3
+ */
4
+ export default function login(): void;
5
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../web/api/login.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,CAAC,OAAO,UAAU,KAAK,SAO5B"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * 登录:跳转到授权页面
3
+ */
4
+ import { oauthStore } from '../OAuthStore';
5
+ export default function login() {
6
+ const authorizeUrl = oauthStore.getAuthorizeUrl();
7
+ if (authorizeUrl) {
8
+ window.location.href = authorizeUrl;
9
+ }
10
+ else {
11
+ throw new Error('无法获取授权 URL');
12
+ }
13
+ }
14
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../web/api/login.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE1C,MAAM,CAAC,OAAO,UAAU,KAAK;IAC3B,MAAM,YAAY,GAAG,UAAU,CAAC,eAAe,EAAE,CAAA;IACjD,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,YAAY,CAAA;IACrC,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAA;IAC/B,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 登出:调用后端登出接口,撤销会话
3
+ */
4
+ export default function logout(): Promise<void>;
5
+ //# sourceMappingURL=logout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../../web/api/logout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,wBAA8B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAUpD"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 登出:调用后端登出接口,撤销会话
3
+ */
4
+ import { oauthStore } from '../OAuthStore';
5
+ import { axiosInstance } from '../axiosInstance';
6
+ export default async function logout() {
7
+ try {
8
+ await axiosInstance.post('/api/oauth/logout', {}, { withCredentials: true });
9
+ }
10
+ catch (error) {
11
+ console.error('Logout error:', error);
12
+ throw error;
13
+ }
14
+ finally {
15
+ // 清空本地用户信息
16
+ oauthStore.clear();
17
+ }
18
+ }
19
+ //# sourceMappingURL=logout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../../web/api/logout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEhD,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,MAAM;IAClC,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAA;IAC9E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAA;QACrC,MAAM,KAAK,CAAA;IACb,CAAC;YAAS,CAAC;QACT,WAAW;QACX,UAAU,CAAC,KAAK,EAAE,CAAA;IACpB,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 刷新 OAuth 信息和用户状态
3
+ * 通过刷新 access token 接口获取 endpoint、authorizeUrl 和用户信息
4
+ * @param force 是否强制刷新,忽略缓存
5
+ */
6
+ export default function refreshToken(force?: boolean): Promise<void>;
7
+ //# sourceMappingURL=refreshToken.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refreshToken.d.ts","sourceRoot":"","sources":["../../../web/api/refreshToken.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,wBAA8B,YAAY,CAAC,KAAK,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BhF"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * 刷新 OAuth 信息和用户状态
3
+ * 通过刷新 access token 接口获取 endpoint、authorizeUrl 和用户信息
4
+ * @param force 是否强制刷新,忽略缓存
5
+ */
6
+ import { oauthStore } from '../OAuthStore';
7
+ import { axiosInstance } from '../axiosInstance';
8
+ const CACHE_TTL = 3600000; // 1小时,单位毫秒
9
+ export default async function refreshToken(force = false) {
10
+ // 如果缓存仍然有效且不是强制刷新,直接返回
11
+ if (!force && oauthStore.isCacheValid(CACHE_TTL)) {
12
+ return;
13
+ }
14
+ try {
15
+ // 直接调用 PUT /api/oauth/token 刷新接口
16
+ // 浏览器会自动在请求中包含 HttpOnly Cookie 中的 refresh_token
17
+ console.log('[Sumor] Calling PUT /api/oauth/token...');
18
+ const response = await axiosInstance.put('/api/oauth/token', {});
19
+ console.log('[Sumor] Response received:', response);
20
+ // 响应已被拦截器处理,返回的是 { endpoint, authorizeUrl, user }
21
+ if (response) {
22
+ const data = response;
23
+ oauthStore.setData(data);
24
+ console.log('[Sumor] User info updated:', oauthStore.getUser());
25
+ }
26
+ oauthStore.markAsLoaded();
27
+ }
28
+ catch (error) {
29
+ console.error('[Sumor] Failed to refresh OAuth info:', error);
30
+ // 刷新失败时,清除用户信息(401 表示未认证)
31
+ if (error.response?.status === 401 || error.code === 'TOKEN_REFRESH_FAILED') {
32
+ console.log('[Sumor] Token refresh failed or unauthorized, clearing user');
33
+ oauthStore.clear();
34
+ }
35
+ }
36
+ }
37
+ //# sourceMappingURL=refreshToken.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refreshToken.js","sourceRoot":"","sources":["../../../web/api/refreshToken.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAsB,MAAM,eAAe,CAAA;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEhD,MAAM,SAAS,GAAG,OAAO,CAAA,CAAC,WAAW;AAErC,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,YAAY,CAAC,QAAiB,KAAK;IAC/D,uBAAuB;IACvB,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;QACjD,OAAM;IACR,CAAC;IAED,IAAI,CAAC;QACH,iCAAiC;QACjC,gDAAgD;QAChD,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAA;QACtD,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,GAAG,CAAqB,kBAAkB,EAAE,EAAE,CAAC,CAAA;QACpF,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,QAAQ,CAAC,CAAA;QAEnD,kDAAkD;QAClD,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,QAAyC,CAAA;YACtD,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;YACxB,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,CAAA;QACjE,CAAC;QAED,UAAU,CAAC,YAAY,EAAE,CAAA;IAC3B,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAA;QAE7D,0BAA0B;QAC1B,IAAI,KAAK,CAAC,QAAQ,EAAE,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,KAAK,sBAAsB,EAAE,CAAC;YAC5E,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAA;YAC1E,UAAU,CAAC,KAAK,EAAE,CAAA;QACpB,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -1,8 +1,11 @@
1
1
  /**
2
- * Sumor Framework - 轻呈云客户端初始化
2
+ * Sumor Framework - 轻呈云客户端 API
3
3
  */
4
- export declare function setupSumor(): Promise<void>;
5
- export { Sumor } from './Sumor';
4
+ export { default as refreshToken } from './api/refreshToken';
5
+ export { default as login } from './api/login';
6
+ export { default as logout } from './api/logout';
7
+ export { default as hasPermission } from './api/hasPermission';
8
+ export { default as hasRole } from './api/hasRole';
6
9
  export { oauthUrl } from './UrlHelper';
7
10
  export { oauthStore } from './OAuthStore';
8
11
  export { axiosInstance as axios } from './axiosInstance';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../web/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAsB,UAAU,kBAa/B;AAED,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,aAAa,IAAI,KAAK,EAAE,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../web/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC5D,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,eAAe,CAAA;AAGlD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,aAAa,IAAI,KAAK,EAAE,MAAM,iBAAiB,CAAA"}
package/dist/web/index.js CHANGED
@@ -1,19 +1,13 @@
1
1
  /**
2
- * Sumor Framework - 轻呈云客户端初始化
2
+ * Sumor Framework - 轻呈云客户端 API
3
3
  */
4
- import { Sumor } from './Sumor';
5
- export async function setupSumor() {
6
- console.log('[setupSumor] Creating Sumor instance...');
7
- const sumor = new Sumor();
8
- // 初始化 Sumor
9
- console.log('[setupSumor] Calling refreshToken...');
10
- await sumor.refreshToken();
11
- // 挂载到全局 window 对象
12
- window.sumor = sumor;
13
- console.log('[setupSumor] Sumor initialized');
14
- console.log('✓ 完成轻呈云客户端初始化');
15
- }
16
- export { Sumor } from './Sumor';
4
+ // 导出所有 API 函数
5
+ export { default as refreshToken } from './api/refreshToken';
6
+ export { default as login } from './api/login';
7
+ export { default as logout } from './api/logout';
8
+ export { default as hasPermission } from './api/hasPermission';
9
+ export { default as hasRole } from './api/hasRole';
10
+ // 导出其他工具
17
11
  export { oauthUrl } from './UrlHelper';
18
12
  export { oauthStore } from './OAuthStore';
19
13
  export { axiosInstance as axios } from './axiosInstance';
@@ -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,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAA;IACtD,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAA;IAEzB,YAAY;IACZ,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAA;IACnD,MAAM,KAAK,CAAC,YAAY,EAAE,CAAA;IAE1B,kBAAkB;IAClB,MAAM,CAAC,KAAK,GAAG,KAAK,CAAA;IAEpB,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAA;IAC7C,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;AAC9B,CAAC;AAED,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,aAAa,IAAI,KAAK,EAAE,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../web/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc;AACd,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC5D,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,eAAe,CAAA;AAElD,SAAS;AACT,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,aAAa,IAAI,KAAK,EAAE,MAAM,iBAAiB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sumor",
3
- "version": "3.1.5",
3
+ "version": "3.1.6",
4
4
  "description": "Sumor OAuth framework",
5
5
  "main": "dist/server/index.js",
6
6
  "types": "dist/server/index.d.ts",
@@ -1,50 +0,0 @@
1
- /**
2
- * Sumor Class - 轻呈云客户端主类
3
- */
4
- import { UserInfo } from './OAuthStore';
5
- export declare class Sumor {
6
- private readonly axios;
7
- private readonly CACHE_TTL;
8
- constructor();
9
- /**
10
- * 订阅用户变化事件
11
- * @param callback 用户变化时的回调函数
12
- */
13
- onUserChange(callback: (user: UserInfo | null) => void): void;
14
- /**
15
- * 刷新 OAuth 信息和用户状态
16
- * 通过刷新 access token 接口获取 endpoint、authorizeUrl 和用户信息
17
- * @param force 是否强制刷新,忽略缓存
18
- */
19
- refreshToken(force?: boolean): Promise<void>;
20
- /**
21
- * 登录:跳转到授权页面
22
- */
23
- login(): void;
24
- /**
25
- * 登出:调用后端登出接口,撤销会话
26
- */
27
- logout(): Promise<void>;
28
- /**
29
- * 手动刷新配置(用于处理长期运行的应用需要更新配置的情况)
30
- */
31
- refreshConfig(): Promise<void>;
32
- /**
33
- * 检查用户是否有特定权限
34
- * @param module 模块名称(如:posts、comments)
35
- * @param operation 操作名称(如:view、edit、delete),为 * 或不传时表示检查模块的任何权限
36
- * @returns 是否拥有权限
37
- *
38
- * 例如:
39
- * - hasPermission('posts', 'edit') 检查是否有 'posts:edit' 权限
40
- * - hasPermission('posts', '*') 或 hasPermission('posts') 检查是否有任何 posts 权限
41
- */
42
- hasPermission(module: string, operation?: string): boolean;
43
- /**
44
- * 检查用户是否拥有指定角色
45
- * @param role 角色名称
46
- * @returns 是否拥有该角色
47
- */
48
- hasRole(role: string): boolean;
49
- }
50
- //# sourceMappingURL=Sumor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Sumor.d.ts","sourceRoot":"","sources":["../../web/Sumor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAc,QAAQ,EAAsB,MAAM,cAAc,CAAA;AAGvE,qBAAa,KAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAU;;IAOpC;;;OAGG;IACH,YAAY,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI;IAI7D;;;;OAIG;IACG,YAAY,CAAC,KAAK,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCzD;;OAEG;IACH,KAAK;IASL;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAY7B;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC;;;;;;;;;OASG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,MAAY,GAAG,OAAO;IAkB/D;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAS/B"}
package/dist/web/Sumor.js DELETED
@@ -1,124 +0,0 @@
1
- /**
2
- * Sumor Class - 轻呈云客户端主类
3
- */
4
- import { oauthStore } from './OAuthStore';
5
- import { axiosInstance } from './axiosInstance';
6
- export class Sumor {
7
- constructor() {
8
- this.CACHE_TTL = 3600000; // 1小时,单位毫秒
9
- console.log('初始化轻呈云客户端...');
10
- this.axios = axiosInstance;
11
- }
12
- /**
13
- * 订阅用户变化事件
14
- * @param callback 用户变化时的回调函数
15
- */
16
- onUserChange(callback) {
17
- oauthStore.onUserChange(callback);
18
- }
19
- /**
20
- * 刷新 OAuth 信息和用户状态
21
- * 通过刷新 access token 接口获取 endpoint、authorizeUrl 和用户信息
22
- * @param force 是否强制刷新,忽略缓存
23
- */
24
- async refreshToken(force = false) {
25
- // 如果缓存仍然有效且不是强制刷新,直接返回
26
- if (!force && oauthStore.isCacheValid(this.CACHE_TTL)) {
27
- return;
28
- }
29
- try {
30
- // 直接调用 PUT /api/oauth/token 刷新接口
31
- // 浏览器会自动在请求中包含 HttpOnly Cookie 中的 refresh_token
32
- console.log('[Sumor] Calling PUT /api/oauth/token...');
33
- const response = await this.axios.put('/api/oauth/token', {});
34
- console.log('[Sumor] Response received:', response);
35
- // 响应已被拦截器处理,返回的是 { endpoint, authorizeUrl, user }
36
- if (response) {
37
- const data = response;
38
- oauthStore.setData(data);
39
- console.log('[Sumor] User info updated:', oauthStore.getUser());
40
- }
41
- oauthStore.markAsLoaded();
42
- }
43
- catch (error) {
44
- console.error('[Sumor] Failed to refresh OAuth info:', error);
45
- // 刷新失败时,清除用户信息(401 表示未认证)
46
- if (error.response?.status === 401 || error.code === 'TOKEN_REFRESH_FAILED') {
47
- console.log('[Sumor] Token refresh failed or unauthorized, clearing user');
48
- oauthStore.clear();
49
- }
50
- }
51
- }
52
- /**
53
- * 登录:跳转到授权页面
54
- */
55
- login() {
56
- const authorizeUrl = oauthStore.getAuthorizeUrl();
57
- if (authorizeUrl) {
58
- window.location.href = authorizeUrl;
59
- }
60
- else {
61
- throw new Error('无法获取授权 URL');
62
- }
63
- }
64
- /**
65
- * 登出:调用后端登出接口,撤销会话
66
- */
67
- async logout() {
68
- try {
69
- await this.axios.post('/api/oauth/logout', {}, { withCredentials: true });
70
- }
71
- catch (error) {
72
- console.error('Logout error:', error);
73
- throw error;
74
- }
75
- finally {
76
- // 清空本地用户信息
77
- oauthStore.clear();
78
- }
79
- }
80
- /**
81
- * 手动刷新配置(用于处理长期运行的应用需要更新配置的情况)
82
- */
83
- async refreshConfig() {
84
- await this.refreshToken(true);
85
- }
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, operation = '*') {
97
- const user = oauthStore.getUser();
98
- if (!user || !user.permissions) {
99
- return false;
100
- }
101
- const userPermissions = user.permissions.split(',').map(p => p.trim());
102
- // 如果 operation 为 *,检查是否有该模块的任何权限
103
- if (operation === '*') {
104
- return userPermissions.some(permission => permission.startsWith(`${module}:`));
105
- }
106
- // 否则检查特定的 module:operation 权限
107
- const requiredPermission = `${module}:${operation}`;
108
- return userPermissions.includes(requiredPermission);
109
- }
110
- /**
111
- * 检查用户是否拥有指定角色
112
- * @param role 角色名称
113
- * @returns 是否拥有该角色
114
- */
115
- hasRole(role) {
116
- const user = oauthStore.getUser();
117
- if (!user || !user.roles) {
118
- return false;
119
- }
120
- const userRoles = user.roles.split(',');
121
- return userRoles.some(r => r.trim() === role);
122
- }
123
- }
124
- //# sourceMappingURL=Sumor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Sumor.js","sourceRoot":"","sources":["../../web/Sumor.ts"],"names":[],"mappings":"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"}