sumor 3.2.3 → 3.3.0
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 +372 -413
- package/README.zh-CN.md +576 -0
- package/dist/server/index.d.ts +2 -6
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -5
- package/dist/server/index.js.map +1 -1
- package/dist/server/middlewares/loadJwtUserMiddleware.d.ts +0 -1
- package/dist/server/middlewares/loadJwtUserMiddleware.d.ts.map +1 -1
- package/dist/server/middlewares/loadJwtUserMiddleware.js +4 -2
- package/dist/server/middlewares/loadJwtUserMiddleware.js.map +1 -1
- package/dist/server/mock/mockApiRoutes.d.ts +14 -0
- package/dist/server/mock/mockApiRoutes.d.ts.map +1 -0
- package/dist/server/mock/mockApiRoutes.js +151 -0
- package/dist/server/mock/mockApiRoutes.js.map +1 -0
- package/dist/server/mock/mockConfig.d.ts +38 -0
- package/dist/server/mock/mockConfig.d.ts.map +1 -0
- package/dist/server/mock/mockConfig.js +51 -0
- package/dist/server/mock/mockConfig.js.map +1 -0
- package/dist/server/mock/mockRoutes.d.ts +9 -0
- package/dist/server/mock/mockRoutes.d.ts.map +1 -0
- package/dist/server/mock/mockRoutes.js +103 -0
- package/dist/server/mock/mockRoutes.js.map +1 -0
- package/dist/server/mock/mockTokenUtils.d.ts +30 -0
- package/dist/server/mock/mockTokenUtils.d.ts.map +1 -0
- package/dist/server/mock/mockTokenUtils.js +81 -0
- package/dist/server/mock/mockTokenUtils.js.map +1 -0
- package/dist/server/routes.d.ts +1 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +29 -25
- package/dist/server/routes.js.map +1 -1
- package/dist/server/services/oauthService.d.ts +0 -8
- package/dist/server/services/oauthService.d.ts.map +1 -1
- package/dist/server/services/oauthService.js +0 -24
- package/dist/server/services/oauthService.js.map +1 -1
- package/dist/server/types/oauth.d.ts +0 -1
- package/dist/server/types/oauth.d.ts.map +1 -1
- package/dist/server/utils/config.d.ts.map +1 -1
- package/dist/server/utils/config.js +13 -0
- package/dist/server/utils/config.js.map +1 -1
- package/dist/web/OAuthStore.d.ts +11 -5
- package/dist/web/OAuthStore.d.ts.map +1 -1
- package/dist/web/OAuthStore.js +43 -64
- package/dist/web/OAuthStore.js.map +1 -1
- package/dist/web/UrlHelper.d.ts +1 -0
- package/dist/web/UrlHelper.d.ts.map +1 -1
- package/dist/web/UrlHelper.js +11 -0
- package/dist/web/UrlHelper.js.map +1 -1
- package/dist/web/api/login.d.ts +2 -2
- package/dist/web/api/login.d.ts.map +1 -1
- package/dist/web/api/login.js +12 -2
- package/dist/web/api/login.js.map +1 -1
- package/dist/web/api/logout.d.ts +1 -1
- package/dist/web/api/logout.d.ts.map +1 -1
- package/dist/web/api/logout.js +3 -2
- package/dist/web/api/logout.js.map +1 -1
- package/package.json +2 -1
- package/dist/server/middlewares/isLoggedMiddleware.d.ts +0 -15
- package/dist/server/middlewares/isLoggedMiddleware.d.ts.map +0 -1
- package/dist/server/middlewares/isLoggedMiddleware.js +0 -35
- package/dist/server/middlewares/isLoggedMiddleware.js.map +0 -1
- package/dist/server/middlewares/isVerifiedMiddleware.d.ts +0 -16
- package/dist/server/middlewares/isVerifiedMiddleware.d.ts.map +0 -1
- package/dist/server/middlewares/isVerifiedMiddleware.js +0 -44
- package/dist/server/middlewares/isVerifiedMiddleware.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockApiRoutes.d.ts","sourceRoot":"","sources":["../../../server/mock/mockApiRoutes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAYH,QAAA,MAAM,aAAa,4CAAmB,CAAA;AA4ItC,eAAe,aAAa,CAAA"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Mock API 路由(挂载到 /api/oauth/mock)
|
|
4
|
+
*
|
|
5
|
+
* 提供给 web SDK 在 mock 模式下直接调用的接口,无需页面跳转。
|
|
6
|
+
*
|
|
7
|
+
* 路由列表:
|
|
8
|
+
* POST /api/oauth/mock/login - 签发 mock token,返回用户信息
|
|
9
|
+
* POST /api/oauth/mock/logout - 清除 mock token cookie
|
|
10
|
+
* GET /api/oauth/mock/avatar/:id - 返回 404(mock 模式无头像服务)
|
|
11
|
+
* GET /api/oauth/mock/nav/:target - 导航占位页(home/site/user/feedback)
|
|
12
|
+
*/
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
const express_1 = __importDefault(require("express"));
|
|
18
|
+
const mockConfig_1 = require("./mockConfig");
|
|
19
|
+
const mockTokenUtils_1 = require("./mockTokenUtils");
|
|
20
|
+
const oauthTokenUtils_1 = require("../utils/oauthTokenUtils");
|
|
21
|
+
const mockApiRoutes = express_1.default.Router();
|
|
22
|
+
/**
|
|
23
|
+
* POST /api/oauth/mock/login
|
|
24
|
+
* 直接签发 mock token,写入 HttpOnly Cookie,并返回用户信息
|
|
25
|
+
* web SDK 拿到用户信息后直接更新 store,无需页面跳转
|
|
26
|
+
*/
|
|
27
|
+
mockApiRoutes.post('/login', (_req, res) => {
|
|
28
|
+
const { user, endpoint } = (0, mockConfig_1.getMockConfig)();
|
|
29
|
+
const accessToken = (0, mockTokenUtils_1.generateMockAccessToken)(user);
|
|
30
|
+
const refreshToken = (0, mockTokenUtils_1.generateMockRefreshToken)(user);
|
|
31
|
+
(0, oauthTokenUtils_1.setOAuthTokenCookie)(res, accessToken, mockTokenUtils_1.MOCK_ACCESS_TOKEN_EXPIRES_IN, 'access');
|
|
32
|
+
(0, oauthTokenUtils_1.setOAuthTokenCookie)(res, refreshToken, mockTokenUtils_1.MOCK_REFRESH_TOKEN_EXPIRES_IN, 'refresh');
|
|
33
|
+
return res.json({
|
|
34
|
+
code: 'OK',
|
|
35
|
+
message: '登录成功',
|
|
36
|
+
data: {
|
|
37
|
+
isMock: true,
|
|
38
|
+
endpoint,
|
|
39
|
+
authorizeUrl: '',
|
|
40
|
+
user: {
|
|
41
|
+
id: user.userId,
|
|
42
|
+
isVerified: user.isVerified,
|
|
43
|
+
roles: user.roles,
|
|
44
|
+
permissions: user.permissions
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
/**
|
|
50
|
+
* POST /api/oauth/mock/logout
|
|
51
|
+
* 清除 mock token cookie
|
|
52
|
+
*/
|
|
53
|
+
mockApiRoutes.post('/logout', (_req, res) => {
|
|
54
|
+
res.clearCookie('access_token');
|
|
55
|
+
res.clearCookie('refresh_token');
|
|
56
|
+
return res.json({ code: 'OK', message: '登出成功' });
|
|
57
|
+
});
|
|
58
|
+
/**
|
|
59
|
+
* GET /api/oauth/mock/avatar/:id
|
|
60
|
+
* mock 模式无头像服务,直接返回 404
|
|
61
|
+
*/
|
|
62
|
+
mockApiRoutes.get('/avatar/:id', (_req, res) => {
|
|
63
|
+
res.status(404).end();
|
|
64
|
+
});
|
|
65
|
+
const NAV_LABELS = {
|
|
66
|
+
home: '首页',
|
|
67
|
+
site: '站点管理',
|
|
68
|
+
user: '用户中心',
|
|
69
|
+
feedback: '意见反馈'
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* GET /api/oauth/mock/nav/:target
|
|
73
|
+
* mock 模式导航占位页,展示目标页面名称并提供回退按钮
|
|
74
|
+
*/
|
|
75
|
+
mockApiRoutes.get('/nav/:target', (req, res) => {
|
|
76
|
+
const target = req.params['target'];
|
|
77
|
+
const label = NAV_LABELS[target] || target;
|
|
78
|
+
res.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
79
|
+
res.send(`<!DOCTYPE html>
|
|
80
|
+
<html lang="zh-CN">
|
|
81
|
+
<head>
|
|
82
|
+
<meta charset="UTF-8" />
|
|
83
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
84
|
+
<title>[Mock] ${label}</title>
|
|
85
|
+
<style>
|
|
86
|
+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
87
|
+
body {
|
|
88
|
+
min-height: 100vh;
|
|
89
|
+
display: flex;
|
|
90
|
+
align-items: center;
|
|
91
|
+
justify-content: center;
|
|
92
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
93
|
+
background: #f5f5f5;
|
|
94
|
+
color: #333;
|
|
95
|
+
}
|
|
96
|
+
.card {
|
|
97
|
+
background: #fff;
|
|
98
|
+
border-radius: 12px;
|
|
99
|
+
box-shadow: 0 4px 24px rgba(0,0,0,.08);
|
|
100
|
+
padding: 48px 56px;
|
|
101
|
+
text-align: center;
|
|
102
|
+
max-width: 420px;
|
|
103
|
+
width: 90%;
|
|
104
|
+
}
|
|
105
|
+
.badge {
|
|
106
|
+
display: inline-block;
|
|
107
|
+
background: #fff3cd;
|
|
108
|
+
color: #856404;
|
|
109
|
+
font-size: 12px;
|
|
110
|
+
font-weight: 600;
|
|
111
|
+
letter-spacing: .5px;
|
|
112
|
+
padding: 3px 10px;
|
|
113
|
+
border-radius: 99px;
|
|
114
|
+
margin-bottom: 20px;
|
|
115
|
+
}
|
|
116
|
+
h1 {
|
|
117
|
+
font-size: 24px;
|
|
118
|
+
font-weight: 700;
|
|
119
|
+
margin-bottom: 8px;
|
|
120
|
+
}
|
|
121
|
+
p {
|
|
122
|
+
font-size: 14px;
|
|
123
|
+
color: #888;
|
|
124
|
+
margin-bottom: 32px;
|
|
125
|
+
line-height: 1.6;
|
|
126
|
+
}
|
|
127
|
+
button {
|
|
128
|
+
background: #333;
|
|
129
|
+
color: #fff;
|
|
130
|
+
border: none;
|
|
131
|
+
border-radius: 8px;
|
|
132
|
+
padding: 10px 28px;
|
|
133
|
+
font-size: 14px;
|
|
134
|
+
cursor: pointer;
|
|
135
|
+
transition: background .15s;
|
|
136
|
+
}
|
|
137
|
+
button:hover { background: #555; }
|
|
138
|
+
</style>
|
|
139
|
+
</head>
|
|
140
|
+
<body>
|
|
141
|
+
<div class="card">
|
|
142
|
+
<span class="badge">MOCK</span>
|
|
143
|
+
<h1>${label}</h1>
|
|
144
|
+
<p>当前处于 Mock 模式,此页面为占位页。<br/>真实环境中将跳转到 OAuth 服务的「${label}」页面。</p>
|
|
145
|
+
<button onclick="history.back()">返回上一页</button>
|
|
146
|
+
</div>
|
|
147
|
+
</body>
|
|
148
|
+
</html>`);
|
|
149
|
+
});
|
|
150
|
+
exports.default = mockApiRoutes;
|
|
151
|
+
//# sourceMappingURL=mockApiRoutes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockApiRoutes.js","sourceRoot":"","sources":["../../../server/mock/mockApiRoutes.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;;;AAEH,sDAAoD;AACpD,6CAA4C;AAC5C,qDAKyB;AACzB,8DAA8D;AAE9D,MAAM,aAAa,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAA;AAEtC;;;;GAIG;AACH,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE;IAC5D,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAA,0BAAa,GAAE,CAAA;IAE1C,MAAM,WAAW,GAAG,IAAA,wCAAuB,EAAC,IAAI,CAAC,CAAA;IACjD,MAAM,YAAY,GAAG,IAAA,yCAAwB,EAAC,IAAI,CAAC,CAAA;IAEnD,IAAA,qCAAmB,EAAC,GAAG,EAAE,WAAW,EAAE,6CAA4B,EAAE,QAAQ,CAAC,CAAA;IAC7E,IAAA,qCAAmB,EAAC,GAAG,EAAE,YAAY,EAAE,8CAA6B,EAAE,SAAS,CAAC,CAAA;IAEhF,OAAO,GAAG,CAAC,IAAI,CAAC;QACd,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,MAAM;QACf,IAAI,EAAE;YACJ,MAAM,EAAE,IAAI;YACZ,QAAQ;YACR,YAAY,EAAE,EAAE;YAChB,IAAI,EAAE;gBACJ,EAAE,EAAE,IAAI,CAAC,MAAM;gBACf,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,WAAW,EAAE,IAAI,CAAC,WAAW;aAC9B;SACF;KACF,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF;;;GAGG;AACH,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE;IAC7D,GAAG,CAAC,WAAW,CAAC,cAAc,CAAC,CAAA;IAC/B,GAAG,CAAC,WAAW,CAAC,eAAe,CAAC,CAAA;IAEhC,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAA;AAClD,CAAC,CAAC,CAAA;AAEF;;;GAGG;AACH,aAAa,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE;IAChE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAA;AACvB,CAAC,CAAC,CAAA;AAEF,MAAM,UAAU,GAA2B;IACzC,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,MAAM;CACjB,CAAA;AAED;;;GAGG;AACH,aAAa,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;IAChE,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAW,CAAA;IAC7C,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,MAAM,CAAA;IAE1C,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAA;IACzD,GAAG,CAAC,IAAI,CAAC;;;;;kBAKO,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA2Db,KAAK;uDACwC,KAAK;;;;QAIpD,CAAC,CAAA;AACT,CAAC,CAAC,CAAA;AAEF,kBAAe,aAAa,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock 模式配置
|
|
3
|
+
*
|
|
4
|
+
* 通过 OAUTH_MOCK=true 启用 Mock 模式。
|
|
5
|
+
* Mock 用户数据通过以下环境变量配置:
|
|
6
|
+
*
|
|
7
|
+
* OAUTH_MOCK_USER_ID - 用户 ID(默认:mock-user-001)
|
|
8
|
+
* OAUTH_MOCK_USER_ROLES - 用户角色,逗号分隔(默认:admin)
|
|
9
|
+
* OAUTH_MOCK_USER_PERMISSIONS - 用户权限,逗号分隔(默认:空)
|
|
10
|
+
* OAUTH_MOCK_USER_IS_VERIFIED - 是否已认证 0/1(默认:1)
|
|
11
|
+
* OAUTH_MOCK_ENDPOINT - Mock 时返回的 endpoint(默认:http://localhost)
|
|
12
|
+
* OAUTH_MOCK_REDIRECT_URI - Mock 回调后跳转的 origin(默认:http://localhost)
|
|
13
|
+
*/
|
|
14
|
+
export interface MockUserConfig {
|
|
15
|
+
userId: string;
|
|
16
|
+
roles: string;
|
|
17
|
+
permissions: string;
|
|
18
|
+
isVerified: number;
|
|
19
|
+
}
|
|
20
|
+
export interface MockConfig {
|
|
21
|
+
enabled: boolean;
|
|
22
|
+
user: MockUserConfig;
|
|
23
|
+
endpoint: string;
|
|
24
|
+
redirectUri: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 判断是否启用了 Mock 模式
|
|
28
|
+
*/
|
|
29
|
+
export declare function isMockMode(): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* 获取 Mock 配置
|
|
32
|
+
*/
|
|
33
|
+
export declare function getMockConfig(): MockConfig;
|
|
34
|
+
/**
|
|
35
|
+
* 重置缓存(测试用)
|
|
36
|
+
*/
|
|
37
|
+
export declare function resetMockConfigCache(): void;
|
|
38
|
+
//# sourceMappingURL=mockConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockConfig.d.ts","sourceRoot":"","sources":["../../../server/mock/mockConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,cAAc,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;CACpB;AAID;;GAEG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,UAAU,CAe1C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Mock 模式配置
|
|
4
|
+
*
|
|
5
|
+
* 通过 OAUTH_MOCK=true 启用 Mock 模式。
|
|
6
|
+
* Mock 用户数据通过以下环境变量配置:
|
|
7
|
+
*
|
|
8
|
+
* OAUTH_MOCK_USER_ID - 用户 ID(默认:mock-user-001)
|
|
9
|
+
* OAUTH_MOCK_USER_ROLES - 用户角色,逗号分隔(默认:admin)
|
|
10
|
+
* OAUTH_MOCK_USER_PERMISSIONS - 用户权限,逗号分隔(默认:空)
|
|
11
|
+
* OAUTH_MOCK_USER_IS_VERIFIED - 是否已认证 0/1(默认:1)
|
|
12
|
+
* OAUTH_MOCK_ENDPOINT - Mock 时返回的 endpoint(默认:http://localhost)
|
|
13
|
+
* OAUTH_MOCK_REDIRECT_URI - Mock 回调后跳转的 origin(默认:http://localhost)
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.isMockMode = isMockMode;
|
|
17
|
+
exports.getMockConfig = getMockConfig;
|
|
18
|
+
exports.resetMockConfigCache = resetMockConfigCache;
|
|
19
|
+
let cachedMockConfig = null;
|
|
20
|
+
/**
|
|
21
|
+
* 判断是否启用了 Mock 模式
|
|
22
|
+
*/
|
|
23
|
+
function isMockMode() {
|
|
24
|
+
return process.env.OAUTH_MOCK === 'true';
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 获取 Mock 配置
|
|
28
|
+
*/
|
|
29
|
+
function getMockConfig() {
|
|
30
|
+
if (!cachedMockConfig) {
|
|
31
|
+
cachedMockConfig = {
|
|
32
|
+
enabled: isMockMode(),
|
|
33
|
+
user: {
|
|
34
|
+
userId: process.env.OAUTH_MOCK_USER_ID || 'mock-user-001',
|
|
35
|
+
roles: process.env.OAUTH_MOCK_USER_ROLES || 'admin',
|
|
36
|
+
permissions: process.env.OAUTH_MOCK_USER_PERMISSIONS || '',
|
|
37
|
+
isVerified: parseInt(process.env.OAUTH_MOCK_USER_IS_VERIFIED || '1', 10)
|
|
38
|
+
},
|
|
39
|
+
endpoint: process.env.OAUTH_MOCK_ENDPOINT || 'http://localhost',
|
|
40
|
+
redirectUri: process.env.OAUTH_MOCK_REDIRECT_URI || 'http://localhost'
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return cachedMockConfig;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 重置缓存(测试用)
|
|
47
|
+
*/
|
|
48
|
+
function resetMockConfigCache() {
|
|
49
|
+
cachedMockConfig = null;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=mockConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockConfig.js","sourceRoot":"","sources":["../../../server/mock/mockConfig.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;AAqBH,gCAEC;AAKD,sCAeC;AAKD,oDAEC;AAlCD,IAAI,gBAAgB,GAAsB,IAAI,CAAA;AAE9C;;GAEG;AACH,SAAgB,UAAU;IACxB,OAAO,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,MAAM,CAAA;AAC1C,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa;IAC3B,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,gBAAgB,GAAG;YACjB,OAAO,EAAE,UAAU,EAAE;YACrB,IAAI,EAAE;gBACJ,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,eAAe;gBACzD,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO;gBACnD,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,EAAE;gBAC1D,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,GAAG,EAAE,EAAE,CAAC;aACzE;YACD,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,kBAAkB;YAC/D,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,kBAAkB;SACvE,CAAA;IACH,CAAC;IACD,OAAO,gBAAgB,CAAA;AACzB,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB;IAClC,gBAAgB,GAAG,IAAI,CAAA;AACzB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock OAuth 路由(替换 /api/oauth/* 下的真实路由)
|
|
3
|
+
*
|
|
4
|
+
* 在 OAUTH_MOCK=true 模式下挂载,替代真实 OAuth 流程。
|
|
5
|
+
* PUT /token 会在响应中携带 isMock: true,web SDK 据此走纯前端 mock 路径。
|
|
6
|
+
*/
|
|
7
|
+
declare const mockRoutes: import("express-serve-static-core").Router;
|
|
8
|
+
export default mockRoutes;
|
|
9
|
+
//# sourceMappingURL=mockRoutes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockRoutes.d.ts","sourceRoot":"","sources":["../../../server/mock/mockRoutes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,QAAA,MAAM,UAAU,4CAAmB,CAAA;AA4FnC,eAAe,UAAU,CAAA"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Mock OAuth 路由(替换 /api/oauth/* 下的真实路由)
|
|
4
|
+
*
|
|
5
|
+
* 在 OAUTH_MOCK=true 模式下挂载,替代真实 OAuth 流程。
|
|
6
|
+
* PUT /token 会在响应中携带 isMock: true,web SDK 据此走纯前端 mock 路径。
|
|
7
|
+
*/
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const express_1 = __importDefault(require("express"));
|
|
13
|
+
const mockConfig_1 = require("./mockConfig");
|
|
14
|
+
const mockTokenUtils_1 = require("./mockTokenUtils");
|
|
15
|
+
const oauthTokenUtils_1 = require("../utils/oauthTokenUtils");
|
|
16
|
+
const mockRoutes = express_1.default.Router();
|
|
17
|
+
/**
|
|
18
|
+
* PUT /token
|
|
19
|
+
* 验证 mock token 并返回用户信息,响应中包含 isMock: true
|
|
20
|
+
*/
|
|
21
|
+
mockRoutes.put('/token', (req, res) => {
|
|
22
|
+
const { user, endpoint } = (0, mockConfig_1.getMockConfig)();
|
|
23
|
+
const cookies = parseCookies(req.headers.cookie);
|
|
24
|
+
const accessTokenRaw = cookies.access_token || '';
|
|
25
|
+
const refreshTokenRaw = cookies.refresh_token || '';
|
|
26
|
+
// 先验证 access_token
|
|
27
|
+
if (accessTokenRaw && (0, mockTokenUtils_1.isMockToken)(accessTokenRaw)) {
|
|
28
|
+
try {
|
|
29
|
+
const claims = (0, mockTokenUtils_1.verifyMockToken)(accessTokenRaw);
|
|
30
|
+
if (claims.sub) {
|
|
31
|
+
return res.json({
|
|
32
|
+
code: 'OK',
|
|
33
|
+
message: 'Token 仍然有效',
|
|
34
|
+
data: {
|
|
35
|
+
isMock: true,
|
|
36
|
+
endpoint,
|
|
37
|
+
authorizeUrl: '',
|
|
38
|
+
user: {
|
|
39
|
+
id: claims.sub,
|
|
40
|
+
isVerified: claims.isVerified ?? user.isVerified,
|
|
41
|
+
roles: claims.roles ?? user.roles,
|
|
42
|
+
permissions: claims.permissions ?? user.permissions
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// access_token 过期,继续尝试 refresh_token
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// 使用 refresh_token 重签 access_token
|
|
53
|
+
if (refreshTokenRaw && (0, mockTokenUtils_1.isMockToken)(refreshTokenRaw)) {
|
|
54
|
+
try {
|
|
55
|
+
(0, mockTokenUtils_1.verifyMockToken)(refreshTokenRaw);
|
|
56
|
+
const newAccessToken = (0, mockTokenUtils_1.generateMockAccessToken)(user);
|
|
57
|
+
(0, oauthTokenUtils_1.setOAuthTokenCookie)(res, newAccessToken, mockTokenUtils_1.MOCK_ACCESS_TOKEN_EXPIRES_IN, 'access');
|
|
58
|
+
return res.json({
|
|
59
|
+
code: 'OK',
|
|
60
|
+
message: 'Token 刷新成功',
|
|
61
|
+
data: {
|
|
62
|
+
isMock: true,
|
|
63
|
+
endpoint,
|
|
64
|
+
authorizeUrl: '',
|
|
65
|
+
user: {
|
|
66
|
+
id: user.userId,
|
|
67
|
+
isVerified: user.isVerified,
|
|
68
|
+
roles: user.roles,
|
|
69
|
+
permissions: user.permissions
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// refresh_token 也过期了
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// 未登录
|
|
79
|
+
return res.json({
|
|
80
|
+
code: 'OK',
|
|
81
|
+
message: '未登录',
|
|
82
|
+
data: {
|
|
83
|
+
isMock: true,
|
|
84
|
+
endpoint,
|
|
85
|
+
authorizeUrl: '',
|
|
86
|
+
user: null
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
function parseCookies(cookieString) {
|
|
91
|
+
const cookies = {};
|
|
92
|
+
if (!cookieString)
|
|
93
|
+
return cookies;
|
|
94
|
+
cookieString.split(';').forEach(cookie => {
|
|
95
|
+
const [name, value] = cookie.split('=');
|
|
96
|
+
if (name && value) {
|
|
97
|
+
cookies[name.trim()] = value.trim();
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
return cookies;
|
|
101
|
+
}
|
|
102
|
+
exports.default = mockRoutes;
|
|
103
|
+
//# sourceMappingURL=mockRoutes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockRoutes.js","sourceRoot":"","sources":["../../../server/mock/mockRoutes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock Token 工具
|
|
3
|
+
*
|
|
4
|
+
* 在 Mock 模式下生成伪造的 JWT token(使用 HS256 对称密钥签名)。
|
|
5
|
+
* 仅用于开发/测试环境,不得用于生产。
|
|
6
|
+
*/
|
|
7
|
+
import type { TokenPayload } from '../types/oauth';
|
|
8
|
+
import type { MockUserConfig } from './mockConfig';
|
|
9
|
+
/** Mock access token 有效期(秒) */
|
|
10
|
+
export declare const MOCK_ACCESS_TOKEN_EXPIRES_IN = 3600;
|
|
11
|
+
/** Mock refresh token 有效期(秒) */
|
|
12
|
+
export declare const MOCK_REFRESH_TOKEN_EXPIRES_IN = 2592000;
|
|
13
|
+
/**
|
|
14
|
+
* 生成 Mock Access Token(HS256)
|
|
15
|
+
*/
|
|
16
|
+
export declare function generateMockAccessToken(user: MockUserConfig): string;
|
|
17
|
+
/**
|
|
18
|
+
* 生成 Mock Refresh Token(HS256)
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateMockRefreshToken(user: MockUserConfig): string;
|
|
21
|
+
/**
|
|
22
|
+
* 验证 Mock Token(HS256),返回 TokenPayload
|
|
23
|
+
* 仅用于 Mock 模式内部校验
|
|
24
|
+
*/
|
|
25
|
+
export declare function verifyMockToken(token: string): TokenPayload;
|
|
26
|
+
/**
|
|
27
|
+
* 判断一个 token 是否是 Mock Token(不验证签名,仅检查 issuer)
|
|
28
|
+
*/
|
|
29
|
+
export declare function isMockToken(token: string): boolean;
|
|
30
|
+
//# sourceMappingURL=mockTokenUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockTokenUtils.d.ts","sourceRoot":"","sources":["../../../server/mock/mockTokenUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAKlD,+BAA+B;AAC/B,eAAO,MAAM,4BAA4B,OAAO,CAAA;AAEhD,gCAAgC;AAChC,eAAO,MAAM,6BAA6B,UAAU,CAAA;AAKpD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAepE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAerE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAG3D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAUlD"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Mock Token 工具
|
|
4
|
+
*
|
|
5
|
+
* 在 Mock 模式下生成伪造的 JWT token(使用 HS256 对称密钥签名)。
|
|
6
|
+
* 仅用于开发/测试环境,不得用于生产。
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.MOCK_REFRESH_TOKEN_EXPIRES_IN = exports.MOCK_ACCESS_TOKEN_EXPIRES_IN = void 0;
|
|
10
|
+
exports.generateMockAccessToken = generateMockAccessToken;
|
|
11
|
+
exports.generateMockRefreshToken = generateMockRefreshToken;
|
|
12
|
+
exports.verifyMockToken = verifyMockToken;
|
|
13
|
+
exports.isMockToken = isMockToken;
|
|
14
|
+
const jsonwebtoken_1 = require("jsonwebtoken");
|
|
15
|
+
/** Mock 模式固定使用的 HS256 密钥 */
|
|
16
|
+
const MOCK_JWT_SECRET = 'sumor-mock-secret-do-not-use-in-production';
|
|
17
|
+
/** Mock access token 有效期(秒) */
|
|
18
|
+
exports.MOCK_ACCESS_TOKEN_EXPIRES_IN = 3600;
|
|
19
|
+
/** Mock refresh token 有效期(秒) */
|
|
20
|
+
exports.MOCK_REFRESH_TOKEN_EXPIRES_IN = 2592000; // 30 days
|
|
21
|
+
/** Mock session ID */
|
|
22
|
+
const MOCK_SESSION_ID = 'mock-session-001';
|
|
23
|
+
/**
|
|
24
|
+
* 生成 Mock Access Token(HS256)
|
|
25
|
+
*/
|
|
26
|
+
function generateMockAccessToken(user) {
|
|
27
|
+
const now = Math.floor(Date.now() / 1000);
|
|
28
|
+
const payload = {
|
|
29
|
+
sub: user.userId,
|
|
30
|
+
iss: 'mock-oauth',
|
|
31
|
+
aud: 'mock-client',
|
|
32
|
+
iat: now,
|
|
33
|
+
exp: now + exports.MOCK_ACCESS_TOKEN_EXPIRES_IN,
|
|
34
|
+
jti: `mock-jti-${Date.now()}`,
|
|
35
|
+
sessionId: MOCK_SESSION_ID,
|
|
36
|
+
isVerified: user.isVerified,
|
|
37
|
+
roles: user.roles,
|
|
38
|
+
permissions: user.permissions
|
|
39
|
+
};
|
|
40
|
+
return (0, jsonwebtoken_1.sign)(payload, MOCK_JWT_SECRET, { algorithm: 'HS256' });
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 生成 Mock Refresh Token(HS256)
|
|
44
|
+
*/
|
|
45
|
+
function generateMockRefreshToken(user) {
|
|
46
|
+
const now = Math.floor(Date.now() / 1000);
|
|
47
|
+
return (0, jsonwebtoken_1.sign)({
|
|
48
|
+
sub: user.userId,
|
|
49
|
+
iss: 'mock-oauth',
|
|
50
|
+
aud: 'mock-client',
|
|
51
|
+
iat: now,
|
|
52
|
+
exp: now + exports.MOCK_REFRESH_TOKEN_EXPIRES_IN,
|
|
53
|
+
jti: `mock-refresh-jti-${Date.now()}`,
|
|
54
|
+
type: 'refresh'
|
|
55
|
+
}, MOCK_JWT_SECRET, { algorithm: 'HS256' });
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 验证 Mock Token(HS256),返回 TokenPayload
|
|
59
|
+
* 仅用于 Mock 模式内部校验
|
|
60
|
+
*/
|
|
61
|
+
function verifyMockToken(token) {
|
|
62
|
+
const payload = (0, jsonwebtoken_1.verify)(token, MOCK_JWT_SECRET, { algorithms: ['HS256'] });
|
|
63
|
+
return payload;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 判断一个 token 是否是 Mock Token(不验证签名,仅检查 issuer)
|
|
67
|
+
*/
|
|
68
|
+
function isMockToken(token) {
|
|
69
|
+
try {
|
|
70
|
+
// decode without verify
|
|
71
|
+
const parts = token.split('.');
|
|
72
|
+
if (parts.length !== 3)
|
|
73
|
+
return false;
|
|
74
|
+
const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf-8'));
|
|
75
|
+
return payload.iss === 'mock-oauth';
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=mockTokenUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockTokenUtils.js","sourceRoot":"","sources":["../../../server/mock/mockTokenUtils.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAqBH,0DAeC;AAKD,4DAeC;AAMD,0CAGC;AAKD,kCAUC;AA9ED,+CAA2C;AAI3C,4BAA4B;AAC5B,MAAM,eAAe,GAAG,4CAA4C,CAAA;AAEpE,+BAA+B;AAClB,QAAA,4BAA4B,GAAG,IAAI,CAAA;AAEhD,gCAAgC;AACnB,QAAA,6BAA6B,GAAG,OAAO,CAAA,CAAC,UAAU;AAE/D,sBAAsB;AACtB,MAAM,eAAe,GAAG,kBAAkB,CAAA;AAE1C;;GAEG;AACH,SAAgB,uBAAuB,CAAC,IAAoB;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;IACzC,MAAM,OAAO,GAAwB;QACnC,GAAG,EAAE,IAAI,CAAC,MAAM;QAChB,GAAG,EAAE,YAAY;QACjB,GAAG,EAAE,aAAa;QAClB,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG,GAAG,oCAA4B;QACvC,GAAG,EAAE,YAAY,IAAI,CAAC,GAAG,EAAE,EAAE;QAC7B,SAAS,EAAE,eAAe;QAC1B,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAW;KAC9B,CAAA;IACD,OAAO,IAAA,mBAAI,EAAC,OAAO,EAAE,eAAe,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAA;AAC/D,CAAC;AAED;;GAEG;AACH,SAAgB,wBAAwB,CAAC,IAAoB;IAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;IACzC,OAAO,IAAA,mBAAI,EACT;QACE,GAAG,EAAE,IAAI,CAAC,MAAM;QAChB,GAAG,EAAE,YAAY;QACjB,GAAG,EAAE,aAAa;QAClB,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG,GAAG,qCAA6B;QACxC,GAAG,EAAE,oBAAoB,IAAI,CAAC,GAAG,EAAE,EAAE;QACrC,IAAI,EAAE,SAAS;KAChB,EACD,eAAe,EACf,EAAE,SAAS,EAAE,OAAO,EAAE,CACvB,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe,CAAC,KAAa;IAC3C,MAAM,OAAO,GAAG,IAAA,qBAAM,EAAC,KAAK,EAAE,eAAe,EAAE,EAAE,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,CAAQ,CAAA;IAChF,OAAO,OAAuB,CAAA;AAChC,CAAC;AAED;;GAEG;AACH,SAAgB,WAAW,CAAC,KAAa;IACvC,IAAI,CAAC;QACH,wBAAwB;QACxB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAA;QACpC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;QAChF,OAAO,OAAO,CAAC,GAAG,KAAK,YAAY,CAAA;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC"}
|
package/dist/server/routes.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../server/routes.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../server/routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,QAAA,MAAM,WAAW,4CAAmB,CAAA;AA6BpC,eAAe,WAAW,CAAA"}
|
package/dist/server/routes.js
CHANGED
|
@@ -2,40 +2,44 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Sumor OAuth 路由
|
|
4
4
|
* 处理与 Sumor OAuth 服务器的交互以及相关操作
|
|
5
|
+
* 当 OAUTH_MOCK=true 时,挂载 mock 路由替代真实 OAuth 流程
|
|
5
6
|
*/
|
|
6
7
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
8
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
9
|
};
|
|
9
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
11
|
const express_1 = __importDefault(require("express"));
|
|
12
|
+
const mockConfig_1 = require("./mock/mockConfig");
|
|
13
|
+
const mockRoutes_1 = __importDefault(require("./mock/mockRoutes"));
|
|
14
|
+
const mockApiRoutes_1 = __importDefault(require("./mock/mockApiRoutes"));
|
|
11
15
|
const tokenRefreshController_1 = __importDefault(require("./controllers/tokenRefreshController"));
|
|
12
16
|
const oauthCallbackController_1 = __importDefault(require("./controllers/oauthCallbackController"));
|
|
13
17
|
const logoutController_1 = require("./controllers/logoutController");
|
|
14
18
|
const oauthRoutes = express_1.default.Router();
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
19
|
+
if ((0, mockConfig_1.isMockMode)()) {
|
|
20
|
+
/**
|
|
21
|
+
* Mock 模式:token 刷新由 mockRoutes 处理
|
|
22
|
+
* mock login/logout 挂载到 /mock 下(即 /api/oauth/mock/*)
|
|
23
|
+
*/
|
|
24
|
+
oauthRoutes.use('/', mockRoutes_1.default);
|
|
25
|
+
oauthRoutes.use('/mock', mockApiRoutes_1.default);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
/**
|
|
29
|
+
* Token 刷新端点
|
|
30
|
+
* PUT /api/oauth/token
|
|
31
|
+
*/
|
|
32
|
+
oauthRoutes.put('/token', tokenRefreshController_1.default);
|
|
33
|
+
/**
|
|
34
|
+
* OAuth 授权回调处理
|
|
35
|
+
* GET /api/oauth/callback
|
|
36
|
+
*/
|
|
37
|
+
oauthRoutes.get('/callback', oauthCallbackController_1.default);
|
|
38
|
+
/**
|
|
39
|
+
* 用户登出 - 需要有效的 Token
|
|
40
|
+
* POST /api/oauth/logout
|
|
41
|
+
*/
|
|
42
|
+
oauthRoutes.post('/logout', logoutController_1.logout);
|
|
43
|
+
}
|
|
40
44
|
exports.default = oauthRoutes;
|
|
41
45
|
//# sourceMappingURL=routes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../server/routes.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../server/routes.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;AAEH,sDAA6B;AAC7B,kDAA8C;AAC9C,mEAA0C;AAC1C,yEAAgD;AAChD,kGAAyE;AACzE,oGAA2E;AAC3E,qEAAuD;AAEvD,MAAM,WAAW,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAA;AAEpC,IAAI,IAAA,uBAAU,GAAE,EAAE,CAAC;IACjB;;;OAGG;IACH,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,oBAAU,CAAC,CAAA;IAChC,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,uBAAa,CAAC,CAAA;AACzC,CAAC;KAAM,CAAC;IACN;;;OAGG;IACH,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,gCAAsB,CAAC,CAAA;IAEjD;;;OAGG;IACH,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,iCAAuB,CAAC,CAAA;IAErD;;;OAGG;IACH,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,yBAAM,CAAC,CAAA;AACrC,CAAC;AAED,kBAAe,WAAW,CAAA"}
|
|
@@ -65,14 +65,6 @@ export declare class OAuthService {
|
|
|
65
65
|
* @throws OAuthServiceError 当刷新失败时抛出异常
|
|
66
66
|
*/
|
|
67
67
|
refreshAccessToken(refreshToken: string): Promise<ITokenResponse>;
|
|
68
|
-
/**
|
|
69
|
-
* 获取超级用户列表
|
|
70
|
-
* 用于在服务启动时获取所有超级用户(roleLevel >= 100),以便发送通知
|
|
71
|
-
*
|
|
72
|
-
* @returns 超级用户列表
|
|
73
|
-
* @throws OAuthServiceError 当获取失败时抛出异常
|
|
74
|
-
*/
|
|
75
|
-
getSuperUsersList(): Promise<any[]>;
|
|
76
68
|
/**
|
|
77
69
|
* 发送微信模板消息
|
|
78
70
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauthService.d.ts","sourceRoot":"","sources":["../../../server/services/oauthService.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,uBAAuB,EACvB,0BAA0B,EAC1B,+BAA+B,EAChC,MAAM,gBAAgB,CAAA;AAEvB;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAEjC,IAAI,EAAE,MAAM;IAEZ,OAAO,CAAC,EAAE,GAAG;gBAFb,IAAI,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,GAAG;CAKvB;AAED;;;GAGG;AACH,qBAAa,YAAY;;IAGvB;;;;;;;;;;OAUG;IACG,YAAY,CAChB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,cAAc,CAAC;IAoB1B;;;;;;OAMG;IACG,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC;IAevC;;;;;;;OAOG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAmBzE;;;;;;OAMG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAarD;;;;;;;OAOG;IACG,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAmBvE
|
|
1
|
+
{"version":3,"file":"oauthService.d.ts","sourceRoot":"","sources":["../../../server/services/oauthService.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,uBAAuB,EACvB,0BAA0B,EAC1B,+BAA+B,EAChC,MAAM,gBAAgB,CAAA;AAEvB;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAEjC,IAAI,EAAE,MAAM;IAEZ,OAAO,CAAC,EAAE,GAAG;gBAFb,IAAI,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,GAAG;CAKvB;AAED;;;GAGG;AACH,qBAAa,YAAY;;IAGvB;;;;;;;;;;OAUG;IACG,YAAY,CAChB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,cAAc,CAAC;IAoB1B;;;;;;OAMG;IACG,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC;IAevC;;;;;;;OAOG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAmBzE;;;;;;OAMG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAarD;;;;;;;OAOG;IACG,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAmBvE;;;;;;;;;OASG;IACG,iBAAiB,CACrB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,0BAA0B,CAAC;IAuBtC;;;;;;;;;OASG;IACG,sBAAsB,CAC1B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,EACvC,OAAO,EAAE,MAAM,EAAE,EACjB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,+BAA+B,CAAC;IAuB3C;;;;;;;OAOG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAgB/C;;;;;;;OAOG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC;IA+B9D;;;;;;;;OAQG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAuBzE;;;;;;OAMG;IACG,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC;IAepC;;;;;;;;;OASG;IACG,iBAAiB,CAAC,iBAAiB,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;CAc9D;AAKD;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAAO,YAOnC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,QAAO,YAAY,GAAG,IAEjD,CAAA;AAED,eAAe,YAAY,CAAA"}
|
|
@@ -145,30 +145,6 @@ class OAuthService {
|
|
|
145
145
|
throw new OAuthServiceError('REFRESH_TOKEN_FAILED', errorMsg, error.response?.data);
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
|
-
/**
|
|
149
|
-
* 获取超级用户列表
|
|
150
|
-
* 用于在服务启动时获取所有超级用户(roleLevel >= 100),以便发送通知
|
|
151
|
-
*
|
|
152
|
-
* @returns 超级用户列表
|
|
153
|
-
* @throws OAuthServiceError 当获取失败时抛出异常
|
|
154
|
-
*/
|
|
155
|
-
async getSuperUsersList() {
|
|
156
|
-
try {
|
|
157
|
-
const httpClient = (0, http_1.default)();
|
|
158
|
-
const response = await httpClient.get('/users', {
|
|
159
|
-
params: {
|
|
160
|
-
roleLevel: '>=100',
|
|
161
|
-
limit: 1000
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
const users = response.data?.data || [];
|
|
165
|
-
return users;
|
|
166
|
-
}
|
|
167
|
-
catch (error) {
|
|
168
|
-
const errorMsg = error.message || '超级用户列表获取失败';
|
|
169
|
-
throw new OAuthServiceError('GET_SUPER_USERS_FAILED', errorMsg, error.response?.data);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
148
|
/**
|
|
173
149
|
* 发送微信模板消息
|
|
174
150
|
*
|