@myassis/gateway 1.0.1 → 1.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/dist/api/index.js +69 -59
- package/dist/config/index.js +2 -2
- package/dist/index.js +85 -11
- package/dist/middleware/auth.js +9 -25
- package/dist/middleware/errorHandler.js +1 -1
- package/dist/routes/agent.js +30 -19
- package/dist/routes/auth.js +35 -26
- package/dist/routes/chat.js +1 -1
- package/dist/routes/models.js +11 -14
- package/dist/routes/service.js +3 -6
- package/dist/routes/settings.js +11 -9
- package/dist/routes/skillHub.js +10 -6
- package/dist/routes/skills.js +13 -10
- package/dist/routes/tasks.js +6 -3
- package/dist/routes/upload.js +5 -2
- package/dist/routes/version.js +4 -4
- package/dist/services/LocalTaskService.js +2 -2
- package/dist/services/NotificationService.js +4 -4
- package/dist/services/ServiceManager.js +12 -12
- package/dist/services/TaskSchedulerService.js +21 -12
- package/dist/services/TaskService.js +25 -22
- package/dist/services/WebSocketService.js +16 -6
- package/dist/services/agent/Agent.js +7 -7
- package/dist/services/agent/AgentManager.js +26 -18
- package/dist/services/agent/AgentStore.js +1 -1
- package/dist/services/dataService.js +63 -73
- package/dist/services/index.js +9 -9
- package/dist/services/llm/LLMClient.js +11 -9
- package/dist/services/memory/MemoryManager.js +180 -17
- package/dist/services/model/index.js +1 -1
- package/dist/services/session/MigrationManager.js +1 -1
- package/dist/services/session/Session.js +74 -50
- package/dist/services/session/SessionManager.js +14 -7
- package/dist/services/session/SessionStore.js +2 -28
- package/dist/services/session/index.js +2 -2
- package/dist/services/systemPrompt.js +9 -5
- package/dist/services/task/PushTokenStore.js +2 -20
- package/dist/services/task/TaskStore.js +2 -21
- package/dist/services/tools/edit.js +122 -148
- package/dist/services/tools/exec.js +1 -1
- package/dist/services/tools/fetch.js +1 -1
- package/dist/services/tools/file.js +4 -9
- package/dist/services/tools/index.js +18 -17
- package/dist/services/tools/model.js +9 -7
- package/dist/services/tools/sessionsSpawn.js +54 -0
- package/dist/services/tools/skill.js +14 -13
- package/dist/services/tools/task.js +3 -5
- package/dist/stores/authStore.js +52 -66
- package/dist/stores/index.js +3 -3
- package/dist/stores/persistStore.js +37 -3
- package/package.json +7 -3
- package/scripts/fix-dist-imports.js +95 -0
- package/scripts/fix-imports.js +90 -0
- package/scripts/postbuild.js +39 -0
package/dist/routes/auth.js
CHANGED
|
@@ -1,19 +1,12 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
2
|
import { authApi } from '../api/index.js';
|
|
3
3
|
import { authStore } from '../stores/index.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { requireAuth } from '../middleware/auth.js';
|
|
5
|
+
import { runWithToken } from '../api/index.js';
|
|
6
|
+
import { getLogger } from '@myassis/shared';
|
|
7
|
+
import { getPlatform } from '@myassis/shared/dist/utils/system.js';
|
|
7
8
|
const logger = getLogger('auth');
|
|
8
9
|
const router = Router();
|
|
9
|
-
// Check auth status - 解码请求中的 token 返回认证状态
|
|
10
|
-
router.get('/isAuth', optionalAuth, async (req, res) => {
|
|
11
|
-
const userId = req.userId;
|
|
12
|
-
res.json({
|
|
13
|
-
authenticated: !!userId,
|
|
14
|
-
user: userId ? { id: userId } : null,
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
10
|
// Get publish token - 获取发布技能库所需的 token
|
|
18
11
|
router.get('/publish-token', requireAuth, async (req, res) => {
|
|
19
12
|
res.json({
|
|
@@ -40,7 +33,7 @@ router.post('/register', async (req, res) => {
|
|
|
40
33
|
if (response.success && response.data) {
|
|
41
34
|
const expiresIn = response.data.expiresIn || 86400;
|
|
42
35
|
authStore.save({
|
|
43
|
-
|
|
36
|
+
accessToken: response.data.accessToken,
|
|
44
37
|
refreshToken: response.data.refreshToken,
|
|
45
38
|
expiresIn,
|
|
46
39
|
expiresAt: Date.now() + expiresIn * 1000,
|
|
@@ -79,17 +72,10 @@ router.post('/login', async (req, res) => {
|
|
|
79
72
|
platform: getPlatform(),
|
|
80
73
|
});
|
|
81
74
|
if (response.success && response.data) {
|
|
82
|
-
|
|
83
|
-
authStore.save({
|
|
84
|
-
token: response.data.accessToken,
|
|
85
|
-
refreshToken: response.data.refreshToken,
|
|
86
|
-
expiresIn,
|
|
87
|
-
expiresAt: Date.now() + expiresIn * 1000,
|
|
88
|
-
user: response.data.user,
|
|
89
|
-
});
|
|
75
|
+
authStore.save(response.data);
|
|
90
76
|
res.json({
|
|
91
77
|
success: true,
|
|
92
|
-
|
|
78
|
+
data: response.data,
|
|
93
79
|
});
|
|
94
80
|
}
|
|
95
81
|
else {
|
|
@@ -132,12 +118,13 @@ router.post('/refresh', async (req, res) => {
|
|
|
132
118
|
// Logout - 清除本地存储
|
|
133
119
|
router.post('/logout', requireAuth, async (req, res) => {
|
|
134
120
|
try {
|
|
135
|
-
// refreshToken 在请求 body 中
|
|
136
121
|
const { refreshToken } = req.body;
|
|
137
|
-
//
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
122
|
+
// 用 AsyncLocalStorage 将 token 注入 server 请求上下文
|
|
123
|
+
await runWithToken(req.token, async () => {
|
|
124
|
+
if (refreshToken) {
|
|
125
|
+
authApi.logout(req.token).catch(() => { });
|
|
126
|
+
}
|
|
127
|
+
});
|
|
141
128
|
authStore.clear();
|
|
142
129
|
res.json({ success: true });
|
|
143
130
|
}
|
|
@@ -146,6 +133,28 @@ router.post('/logout', requireAuth, async (req, res) => {
|
|
|
146
133
|
res.json({ success: true });
|
|
147
134
|
}
|
|
148
135
|
});
|
|
136
|
+
// Check authentication - 验证 token 有效性并获取用户信息
|
|
137
|
+
router.get('/isAuth', requireAuth, async (req, res) => {
|
|
138
|
+
try {
|
|
139
|
+
// 用 AsyncLocalStorage 将 token 注入 server 请求上下文
|
|
140
|
+
const userResponse = await runWithToken(req.token, async () => {
|
|
141
|
+
return await authApi.me(req.token);
|
|
142
|
+
});
|
|
143
|
+
res.json({
|
|
144
|
+
authenticated: true,
|
|
145
|
+
user: userResponse.data,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
logger.error('Auth check error:', error);
|
|
150
|
+
// token 无效时返回认证失败
|
|
151
|
+
res.status(401).json({
|
|
152
|
+
authenticated: false,
|
|
153
|
+
user: null,
|
|
154
|
+
error: error.message || 'Invalid token',
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
});
|
|
149
158
|
// Delete account - 删除账号
|
|
150
159
|
router.post('/account/delete', requireAuth, async (req, res) => {
|
|
151
160
|
try {
|
package/dist/routes/chat.js
CHANGED
package/dist/routes/models.js
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
|
-
import { getLogger, detectModelCapabilities } from '@
|
|
2
|
+
import { getLogger, detectModelCapabilities } from '@myassis/shared';
|
|
3
3
|
import { modelsService } from '../services/index.js';
|
|
4
4
|
import { persistStore } from '../stores/persistStore.js';
|
|
5
5
|
import { requireAuth } from '../middleware/auth.js';
|
|
6
|
+
import { runWithToken } from '../api/index.js';
|
|
6
7
|
const logger = getLogger('models');
|
|
7
8
|
const router = express.Router();
|
|
9
|
+
router.use(requireAuth, (req, _res, next) => {
|
|
10
|
+
void runWithToken(req.token, async () => { next(); });
|
|
11
|
+
});
|
|
8
12
|
/**
|
|
9
13
|
* 获取所有模型配置
|
|
10
14
|
* GET /api/v1/models
|
|
11
15
|
*/
|
|
12
16
|
router.get('/', async (req, res) => {
|
|
13
17
|
try {
|
|
14
|
-
const result = await modelsService.list();
|
|
18
|
+
const result = await modelsService.list(req.token);
|
|
15
19
|
res.json(result);
|
|
16
20
|
}
|
|
17
21
|
catch (error) {
|
|
@@ -25,7 +29,7 @@ router.get('/', async (req, res) => {
|
|
|
25
29
|
*/
|
|
26
30
|
router.get('/:id', async (req, res) => {
|
|
27
31
|
try {
|
|
28
|
-
const result = await modelsService.get(req.params.id);
|
|
32
|
+
const result = await modelsService.get(req.params.id, req.token);
|
|
29
33
|
res.json(result);
|
|
30
34
|
}
|
|
31
35
|
catch (error) {
|
|
@@ -42,18 +46,14 @@ router.post('/', requireAuth, async (req, res) => {
|
|
|
42
46
|
const userId = req.userId;
|
|
43
47
|
const modelData = req.body;
|
|
44
48
|
const apiKey = modelData.apiKey;
|
|
45
|
-
// 自动检测模型能力,设置 supportsToolCall
|
|
46
49
|
const modelCapabilities = detectModelCapabilities(modelData.modelId || '');
|
|
47
50
|
const dataToSave = {
|
|
48
51
|
...modelData,
|
|
49
|
-
// 数据库 is_primary, is_active, supports_tool_call 都是 INTEGER 类型,转换为 0/1
|
|
50
52
|
isPrimary: modelData.isPrimary ? 1 : 0,
|
|
51
53
|
isActive: modelData.isActive ? 1 : 0,
|
|
52
54
|
supportsToolCall: modelCapabilities.supportsToolCall ? 1 : 0,
|
|
53
55
|
};
|
|
54
|
-
|
|
55
|
-
const result = await modelsService.create(dataToSave);
|
|
56
|
-
// 如果提供了 API Key,持久化存储
|
|
56
|
+
const result = await runWithToken(req.token, () => modelsService.create(dataToSave, req.token));
|
|
57
57
|
if (apiKey && result.success && result.data?.id) {
|
|
58
58
|
persistStore.setModelApiKey(result.data.id, apiKey);
|
|
59
59
|
}
|
|
@@ -73,18 +73,15 @@ router.put('/:id', requireAuth, async (req, res) => {
|
|
|
73
73
|
const userId = req.userId;
|
|
74
74
|
const modelData = req.body;
|
|
75
75
|
const apiKey = modelData.apiKey;
|
|
76
|
-
// API Key 单独存储到本地,不传给服务端
|
|
77
76
|
if (apiKey) {
|
|
78
77
|
persistStore.setModelApiKey(req.params.id, apiKey);
|
|
79
78
|
}
|
|
80
|
-
// 自动检测模型能力,设置 supportsToolCall
|
|
81
79
|
const modelCapabilities = detectModelCapabilities(modelData.modelId || '');
|
|
82
80
|
const dataToSave = {
|
|
83
81
|
...modelData,
|
|
84
82
|
supportsToolCall: modelCapabilities.supportsToolCall ? 1 : 0,
|
|
85
83
|
};
|
|
86
|
-
|
|
87
|
-
const result = await modelsService.update(req.params.id, dataToSave);
|
|
84
|
+
const result = await runWithToken(req.token, () => modelsService.update(req.params.id, dataToSave, req.token));
|
|
88
85
|
res.json(result);
|
|
89
86
|
}
|
|
90
87
|
catch (error) {
|
|
@@ -98,7 +95,7 @@ router.put('/:id', requireAuth, async (req, res) => {
|
|
|
98
95
|
*/
|
|
99
96
|
router.delete('/:id', async (req, res) => {
|
|
100
97
|
try {
|
|
101
|
-
const result = await modelsService.delete(req.params.id);
|
|
98
|
+
const result = await modelsService.delete(req.params.id, req.token);
|
|
102
99
|
res.json(result);
|
|
103
100
|
}
|
|
104
101
|
catch (error) {
|
|
@@ -112,7 +109,7 @@ router.delete('/:id', async (req, res) => {
|
|
|
112
109
|
*/
|
|
113
110
|
router.post('/:id/primary', async (req, res) => {
|
|
114
111
|
try {
|
|
115
|
-
const result = await modelsService.setPrimary(req.params.id);
|
|
112
|
+
const result = await modelsService.setPrimary(req.params.id, req.token);
|
|
116
113
|
res.json(result);
|
|
117
114
|
}
|
|
118
115
|
catch (error) {
|
package/dist/routes/service.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
|
-
import { getLogger } from '@
|
|
2
|
+
import { getLogger } from '@myassis/shared';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { getServiceInfo, installService, uninstallService, startService, stopService, restartService, checkForUpdates, updateService, } from '../services/ServiceManager.js';
|
|
5
5
|
import { webSocketService } from '../services/WebSocketService.js';
|
|
6
|
-
import { requireAuth } from '../middleware/auth.js';
|
|
7
6
|
const router = Router();
|
|
8
|
-
// 所有 service 路由需要认证
|
|
9
|
-
router.use(requireAuth);
|
|
10
7
|
const logger = getLogger('service');
|
|
11
8
|
/**
|
|
12
9
|
* 获取服务状态
|
|
@@ -185,8 +182,8 @@ router.get('/latest-exe-url', async (_req, res) => {
|
|
|
185
182
|
return;
|
|
186
183
|
}
|
|
187
184
|
// TODO: 从 GitHub Releases 或自有 CDN 获取下载地址
|
|
188
|
-
// 示例: https://github.com/
|
|
189
|
-
const downloadUrl = `https://
|
|
185
|
+
// 示例: https://github.com/myassis/gateway/releases/download/v${check.latestVersion}/gateway.exe
|
|
186
|
+
const downloadUrl = `https://my-assis-1251246038.cos.ap-chengdu.myqcloud.com/my-assis-1251246038/installs/v${check.latestVersion}/gateway-installer_${check.latestVersion}.exe`;
|
|
190
187
|
res.json({
|
|
191
188
|
success: true,
|
|
192
189
|
hasUpdate: true,
|
package/dist/routes/settings.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
|
-
import { getLogger } from '@
|
|
2
|
+
import { getLogger } from '@myassis/shared';
|
|
3
3
|
import { settingsService } from '../services/index.js';
|
|
4
4
|
import { authStore, persistStore } from '../stores/index.js';
|
|
5
|
-
import { authApi } from '../api/index.js';
|
|
5
|
+
import { authApi, runWithToken } from '../api/index.js';
|
|
6
|
+
import { requireAuth } from '../middleware/auth.js';
|
|
6
7
|
const logger = getLogger('settings');
|
|
7
8
|
const router = express.Router();
|
|
9
|
+
router.use(requireAuth);
|
|
8
10
|
/**
|
|
9
11
|
* 获取用户设置
|
|
10
12
|
* GET /api/v1/settings
|
|
11
13
|
*/
|
|
12
14
|
router.get('/', async (req, res) => {
|
|
13
15
|
try {
|
|
14
|
-
const result = await settingsService.get();
|
|
16
|
+
const result = await settingsService.get(req.token);
|
|
15
17
|
res.json(result);
|
|
16
18
|
}
|
|
17
19
|
catch (error) {
|
|
@@ -23,9 +25,9 @@ router.get('/', async (req, res) => {
|
|
|
23
25
|
* 更新用户设置
|
|
24
26
|
* PUT /api/v1/settings
|
|
25
27
|
*/
|
|
26
|
-
router.put('/', async (req, res) => {
|
|
28
|
+
router.put('/', requireAuth, async (req, res) => {
|
|
27
29
|
try {
|
|
28
|
-
const result = await settingsService.update(req.body);
|
|
30
|
+
const result = await runWithToken(req.token, () => settingsService.update(req.body, req.token));
|
|
29
31
|
res.json(result);
|
|
30
32
|
}
|
|
31
33
|
catch (error) {
|
|
@@ -37,14 +39,14 @@ router.put('/', async (req, res) => {
|
|
|
37
39
|
* 修改密码
|
|
38
40
|
* PUT /api/v1/settings/password
|
|
39
41
|
*/
|
|
40
|
-
router.put('/password', async (req, res) => {
|
|
42
|
+
router.put('/password', requireAuth, async (req, res) => {
|
|
41
43
|
try {
|
|
42
44
|
const { oldPassword, newPassword } = req.body;
|
|
43
45
|
if (!oldPassword || !newPassword) {
|
|
44
46
|
res.status(400).json({ success: false, error: 'Missing required fields' });
|
|
45
47
|
return;
|
|
46
48
|
}
|
|
47
|
-
const result = await authApi.changePassword({ oldPassword, newPassword });
|
|
49
|
+
const result = await authApi.changePassword({ oldPassword, newPassword }, req.token);
|
|
48
50
|
res.json(result);
|
|
49
51
|
}
|
|
50
52
|
catch (error) {
|
|
@@ -85,9 +87,9 @@ router.put('/local', async (req, res) => {
|
|
|
85
87
|
* 删除账号
|
|
86
88
|
* DELETE /api/v1/settings/account
|
|
87
89
|
*/
|
|
88
|
-
router.delete('/account', async (req, res) => {
|
|
90
|
+
router.delete('/account', requireAuth, async (req, res) => {
|
|
89
91
|
try {
|
|
90
|
-
const result = await authApi.deleteAccount({ password: req.params.password });
|
|
92
|
+
const result = await authApi.deleteAccount({ password: req.params.password }, req.token);
|
|
91
93
|
if (result.success) {
|
|
92
94
|
authStore.clear();
|
|
93
95
|
}
|
package/dist/routes/skillHub.js
CHANGED
|
@@ -5,9 +5,13 @@
|
|
|
5
5
|
import express from 'express';
|
|
6
6
|
import { skillHubService } from '../services/index.js';
|
|
7
7
|
import { requireAuth } from '../middleware/auth.js';
|
|
8
|
-
import {
|
|
8
|
+
import { runWithToken } from '../api/index.js';
|
|
9
|
+
import { getLogger } from '@myassis/shared';
|
|
9
10
|
const logger = getLogger('skillHub');
|
|
10
11
|
const router = express.Router();
|
|
12
|
+
router.use(requireAuth, (req, _res, next) => {
|
|
13
|
+
void runWithToken(req.token, async () => { next(); });
|
|
14
|
+
});
|
|
11
15
|
/**
|
|
12
16
|
* 获取技能库列表
|
|
13
17
|
* GET /api/v1/skill-hub?page=1&pageSize=20&keyword=xxx&category=xxx
|
|
@@ -42,7 +46,7 @@ router.get('/:id', async (req, res) => {
|
|
|
42
46
|
if (!hubId) {
|
|
43
47
|
return res.status(400).json({ success: false, error: '无效的技能库ID' });
|
|
44
48
|
}
|
|
45
|
-
const result = await skillHubService.get(hubId);
|
|
49
|
+
const result = await skillHubService.get(hubId, req.token);
|
|
46
50
|
res.json(result);
|
|
47
51
|
}
|
|
48
52
|
catch (error) {
|
|
@@ -60,7 +64,7 @@ router.get('/:id/used', async (req, res) => {
|
|
|
60
64
|
if (!hubId) {
|
|
61
65
|
return res.status(400).json({ success: false, error: '无效的技能库ID' });
|
|
62
66
|
}
|
|
63
|
-
const result = await skillHubService.checkUsed(hubId);
|
|
67
|
+
const result = await skillHubService.checkUsed(hubId, req.token);
|
|
64
68
|
res.json(result);
|
|
65
69
|
}
|
|
66
70
|
catch (error) {
|
|
@@ -78,7 +82,7 @@ router.get('/:id/user-rating', async (req, res) => {
|
|
|
78
82
|
if (!hubId) {
|
|
79
83
|
return res.status(400).json({ success: false, error: '无效的技能库ID' });
|
|
80
84
|
}
|
|
81
|
-
const result = await skillHubService.userRating(hubId);
|
|
85
|
+
const result = await skillHubService.userRating(hubId, req.token);
|
|
82
86
|
res.json(result);
|
|
83
87
|
}
|
|
84
88
|
catch (error) {
|
|
@@ -92,7 +96,7 @@ router.get('/:id/user-rating', async (req, res) => {
|
|
|
92
96
|
*/
|
|
93
97
|
router.get('/categories/list', async (req, res) => {
|
|
94
98
|
try {
|
|
95
|
-
const result = await skillHubService.categories();
|
|
99
|
+
const result = await skillHubService.categories(req.token);
|
|
96
100
|
res.json(result);
|
|
97
101
|
}
|
|
98
102
|
catch (error) {
|
|
@@ -115,7 +119,7 @@ router.post('/:id/rate', requireAuth, async (req, res) => {
|
|
|
115
119
|
if (rating === undefined || rating < 1 || rating > 5) {
|
|
116
120
|
return res.status(400).json({ success: false, error: '评分必须是1-5的数字' });
|
|
117
121
|
}
|
|
118
|
-
const result = await skillHubService.rate(hubId, rating);
|
|
122
|
+
const result = await runWithToken(req.token, () => skillHubService.rate(hubId, rating, req.token));
|
|
119
123
|
res.json(result);
|
|
120
124
|
}
|
|
121
125
|
catch (error) {
|
package/dist/routes/skills.js
CHANGED
|
@@ -5,18 +5,21 @@
|
|
|
5
5
|
import express from 'express';
|
|
6
6
|
import { skillsService } from '../services/index.js';
|
|
7
7
|
import { persistStore } from '../stores/persistStore.js';
|
|
8
|
-
import { getLogger } from '@
|
|
8
|
+
import { getLogger } from '@myassis/shared';
|
|
9
9
|
import { requireAuth } from '../middleware/auth.js';
|
|
10
|
+
import { runWithToken } from '../api/index.js';
|
|
10
11
|
const logger = getLogger('skills');
|
|
11
12
|
const router = express.Router();
|
|
12
|
-
router.use(requireAuth)
|
|
13
|
+
router.use(requireAuth, (req, _res, next) => {
|
|
14
|
+
void runWithToken(req.token, async () => { next(); });
|
|
15
|
+
});
|
|
13
16
|
/**
|
|
14
17
|
* 获取用户已安装的技能列表
|
|
15
18
|
* GET /api/v1/skills
|
|
16
19
|
*/
|
|
17
20
|
router.get('/', async (req, res) => {
|
|
18
21
|
try {
|
|
19
|
-
const result = await skillsService.list();
|
|
22
|
+
const result = await skillsService.list(req.token);
|
|
20
23
|
res.json(result);
|
|
21
24
|
}
|
|
22
25
|
catch (error) {
|
|
@@ -34,7 +37,7 @@ router.post('/parse', async (req, res) => {
|
|
|
34
37
|
if (!content) {
|
|
35
38
|
return res.status(400).json({ success: false, error: '缺少 content 参数' });
|
|
36
39
|
}
|
|
37
|
-
const result = await skillsService.parse(content);
|
|
40
|
+
const result = await skillsService.parse(content, req.token);
|
|
38
41
|
res.json(result);
|
|
39
42
|
}
|
|
40
43
|
catch (error) {
|
|
@@ -49,7 +52,7 @@ router.post('/parse', async (req, res) => {
|
|
|
49
52
|
router.get('/:id', async (req, res) => {
|
|
50
53
|
try {
|
|
51
54
|
const skillId = req.params.id;
|
|
52
|
-
const result = await skillsService.get(skillId);
|
|
55
|
+
const result = await skillsService.get(skillId, req.token);
|
|
53
56
|
res.json(result);
|
|
54
57
|
}
|
|
55
58
|
catch (error) {
|
|
@@ -69,7 +72,7 @@ router.post('/', async (req, res) => {
|
|
|
69
72
|
if (skillHubId) {
|
|
70
73
|
// 从技能库安装
|
|
71
74
|
const hubId = String(skillHubId);
|
|
72
|
-
const result = await skillsService.install(hubId);
|
|
75
|
+
const result = await skillsService.install(hubId, req.token);
|
|
73
76
|
res.json(result);
|
|
74
77
|
}
|
|
75
78
|
else {
|
|
@@ -77,7 +80,7 @@ router.post('/', async (req, res) => {
|
|
|
77
80
|
if (!req.body.name) {
|
|
78
81
|
return res.status(400).json({ success: false, error: '自定义技能必须提供 name' });
|
|
79
82
|
}
|
|
80
|
-
const result = await skillsService.create(req.body);
|
|
83
|
+
const result = await skillsService.create(req.body, req.token);
|
|
81
84
|
res.json(result);
|
|
82
85
|
}
|
|
83
86
|
}
|
|
@@ -93,7 +96,7 @@ router.post('/', async (req, res) => {
|
|
|
93
96
|
router.put('/:id', async (req, res) => {
|
|
94
97
|
try {
|
|
95
98
|
const skillId = req.params.id;
|
|
96
|
-
const result = await skillsService.update(skillId, req.body);
|
|
99
|
+
const result = await skillsService.update(skillId, req.body, req.token);
|
|
97
100
|
res.json(result);
|
|
98
101
|
}
|
|
99
102
|
catch (error) {
|
|
@@ -108,7 +111,7 @@ router.put('/:id', async (req, res) => {
|
|
|
108
111
|
router.delete('/:id', async (req, res) => {
|
|
109
112
|
try {
|
|
110
113
|
const skillId = req.params.id;
|
|
111
|
-
const result = await skillsService.uninstall(skillId);
|
|
114
|
+
const result = await skillsService.uninstall(skillId, req.token);
|
|
112
115
|
res.json(result);
|
|
113
116
|
}
|
|
114
117
|
catch (error) {
|
|
@@ -148,7 +151,7 @@ router.post('/:id/rating', async (req, res) => {
|
|
|
148
151
|
if (!score || score < 1 || score > 5) {
|
|
149
152
|
return res.status(400).json({ success: false, error: '评分必须在 1-5 之间' });
|
|
150
153
|
}
|
|
151
|
-
const result = await skillsService.rate(skillId, score);
|
|
154
|
+
const result = await skillsService.rate(skillId, score, req.token);
|
|
152
155
|
res.json(result);
|
|
153
156
|
}
|
|
154
157
|
catch (error) {
|
package/dist/routes/tasks.js
CHANGED
|
@@ -4,11 +4,14 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import express from 'express';
|
|
6
6
|
import { tasksService } from '../services/index.js';
|
|
7
|
-
import { getLogger } from '@
|
|
7
|
+
import { getLogger } from '@myassis/shared';
|
|
8
8
|
import { requireAuth } from '../middleware/auth.js';
|
|
9
|
+
import { runWithToken } from '../api/index.js';
|
|
9
10
|
const logger = getLogger('tasks');
|
|
10
11
|
const router = express.Router();
|
|
11
|
-
router.use(requireAuth)
|
|
12
|
+
router.use(requireAuth, (req, _res, next) => {
|
|
13
|
+
void runWithToken(req.token, async () => { next(); });
|
|
14
|
+
});
|
|
12
15
|
/**
|
|
13
16
|
* 获取任务列表
|
|
14
17
|
* GET /api/v1/tasks
|
|
@@ -17,7 +20,7 @@ router.get('/', async (req, res) => {
|
|
|
17
20
|
try {
|
|
18
21
|
const { status, page, pageSize } = req.query;
|
|
19
22
|
const userId = req.userId;
|
|
20
|
-
const result = await tasksService.list({ status, page, pageSize }
|
|
23
|
+
const result = await tasksService.list(userId, { status, page, pageSize });
|
|
21
24
|
res.json(result);
|
|
22
25
|
}
|
|
23
26
|
catch (error) {
|
package/dist/routes/upload.js
CHANGED
|
@@ -2,10 +2,13 @@ import { Router } from 'express';
|
|
|
2
2
|
import multer from 'multer';
|
|
3
3
|
import { appConfig } from '@/config/index.js';
|
|
4
4
|
import { requireAuth } from '@/middleware/auth.js';
|
|
5
|
-
import {
|
|
5
|
+
import { runWithToken } from '@/api/index.js';
|
|
6
|
+
import { getLogger } from '@myassis/shared';
|
|
6
7
|
const logger = getLogger('UploadRoutes');
|
|
7
8
|
const router = Router();
|
|
8
|
-
router.use(requireAuth)
|
|
9
|
+
router.use(requireAuth, (req, _res, next) => {
|
|
10
|
+
void runWithToken(req.token, async () => { next(); });
|
|
11
|
+
});
|
|
9
12
|
// 配置 multer 用于解析 multipart/form-data
|
|
10
13
|
const upload = multer({
|
|
11
14
|
storage: multer.memoryStorage(),
|
package/dist/routes/version.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
2
|
import axios from 'axios';
|
|
3
3
|
import { appConfig } from '../config/index.js';
|
|
4
|
-
import {
|
|
4
|
+
import { requireAuth } from '../middleware/auth.js';
|
|
5
5
|
import { readFileSync } from 'fs';
|
|
6
6
|
import { resolve, dirname } from 'path';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
|
-
import { getLogger } from '@
|
|
8
|
+
import { getLogger } from '@myassis/shared';
|
|
9
9
|
const logger = getLogger('VersionRoutes');
|
|
10
10
|
const router = express.Router();
|
|
11
11
|
// ESM 兼容的 __dirname
|
|
@@ -42,9 +42,9 @@ router.get('/local', async (req, res) => {
|
|
|
42
42
|
/**
|
|
43
43
|
* 转发到服务端接口
|
|
44
44
|
*/
|
|
45
|
-
router.get('/latest',
|
|
45
|
+
router.get('/latest', requireAuth, async (req, res) => {
|
|
46
46
|
try {
|
|
47
|
-
const serverBaseUrl = appConfig.serverBaseUrl || '
|
|
47
|
+
const serverBaseUrl = appConfig.serverBaseUrl || 'http://localhost:9091';
|
|
48
48
|
const response = await axios.get(`${serverBaseUrl}/api/v1/version/latest`, {
|
|
49
49
|
timeout: 10000,
|
|
50
50
|
headers: {
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* 使用 SQLite 数据库存储任务
|
|
6
6
|
*/
|
|
7
7
|
import { v4 as uuidv4 } from 'uuid';
|
|
8
|
-
import { TaskStore } from './task/TaskStore';
|
|
9
|
-
import { getLogger, sharedTaskService, formatUTCForLog } from '@
|
|
8
|
+
import { TaskStore } from './task/TaskStore.js';
|
|
9
|
+
import { getLogger, sharedTaskService, formatUTCForLog } from '@myassis/shared';
|
|
10
10
|
const logger = getLogger('LocalTaskService');
|
|
11
11
|
class LocalTaskService {
|
|
12
12
|
store;
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* 负责发送任务通知
|
|
4
4
|
* 优先级:WebSocket > HMS Push (华为) / Expo Push (其他)
|
|
5
5
|
*/
|
|
6
|
-
import { PushTokenStore } from './task/PushTokenStore';
|
|
7
|
-
import { webSocketService } from './WebSocketService';
|
|
8
|
-
import { hmsPushService } from './HMSPushService';
|
|
9
|
-
import { getLogger } from '@
|
|
6
|
+
import { PushTokenStore } from './task/PushTokenStore.js';
|
|
7
|
+
import { webSocketService } from './WebSocketService.js';
|
|
8
|
+
import { hmsPushService } from './HMSPushService.js';
|
|
9
|
+
import { getLogger } from '@myassis/shared';
|
|
10
10
|
const logger = getLogger('NotificationService');
|
|
11
11
|
const log = logger;
|
|
12
12
|
// 全局 PushTokenStore 实例
|
|
@@ -5,8 +5,8 @@ import fs from 'fs';
|
|
|
5
5
|
import axios from 'axios';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
7
|
const execAsync = promisify(exec);
|
|
8
|
-
export const SERVICE_NAME = '
|
|
9
|
-
export const SERVICE_DISPLAY_NAME = '
|
|
8
|
+
export const SERVICE_NAME = 'myassis-gateway';
|
|
9
|
+
export const SERVICE_DISPLAY_NAME = '我的助手 Desktop Gateway Service';
|
|
10
10
|
// ─── 平台无关工具 ────────────────────────────────────────────
|
|
11
11
|
function getServiceScript() {
|
|
12
12
|
// pkg 环境
|
|
@@ -94,7 +94,7 @@ async function restartServiceWindows() {
|
|
|
94
94
|
success: false,
|
|
95
95
|
message: '检测到您尚未安装 nssm,无法自动重启服务。请手动执行以下步骤更新 Gateway:\n' +
|
|
96
96
|
'1. 在桌面上停止 Gateway 服务(系统托盘 → 右键 → 退出)\n' +
|
|
97
|
-
'2. 运行 `npm install -g @
|
|
97
|
+
'2. 运行 `npm install -g @myassis/gateway@latest`\n' +
|
|
98
98
|
'3. 重新启动 Gateway 服务\n\n' +
|
|
99
99
|
'如需自动重启功能,请从 https://nssm.cc/download 下载 nssm 并放置到 Gateway 同目录下',
|
|
100
100
|
};
|
|
@@ -160,11 +160,11 @@ Environment=NODE_ENV=production
|
|
|
160
160
|
[Install]
|
|
161
161
|
WantedBy=multi-user.target
|
|
162
162
|
`;
|
|
163
|
-
await fs.promises.writeFile('/tmp/
|
|
164
|
-
await execAsync('cp /tmp/
|
|
163
|
+
await fs.promises.writeFile('/tmp/myassis-gateway.service', unitContent, 'utf8');
|
|
164
|
+
await execAsync('cp /tmp/myassis-gateway.service /etc/systemd/system/myassis-gateway.service', { timeout: 10000 });
|
|
165
165
|
await execAsync('systemctl daemon-reload', { timeout: 10000 });
|
|
166
|
-
await execAsync('systemctl enable
|
|
167
|
-
await execAsync('systemctl start
|
|
166
|
+
await execAsync('systemctl enable myassis-gateway', { timeout: 10000 });
|
|
167
|
+
await execAsync('systemctl start myassis-gateway', { timeout: 10000 });
|
|
168
168
|
return { success: true, message: '服务安装并启动成功' };
|
|
169
169
|
}
|
|
170
170
|
catch (err) {
|
|
@@ -173,9 +173,9 @@ WantedBy=multi-user.target
|
|
|
173
173
|
}
|
|
174
174
|
async function uninstallLinux() {
|
|
175
175
|
try {
|
|
176
|
-
await execAsync('systemctl stop
|
|
177
|
-
await execAsync('systemctl disable
|
|
178
|
-
await execAsync('rm -f /etc/systemd/system/
|
|
176
|
+
await execAsync('systemctl stop myassis-gateway', { timeout: 10000 });
|
|
177
|
+
await execAsync('systemctl disable myassis-gateway', { timeout: 10000 });
|
|
178
|
+
await execAsync('rm -f /etc/systemd/system/myassis-gateway.service', { timeout: 10000 });
|
|
179
179
|
await execAsync('systemctl daemon-reload', { timeout: 10000 });
|
|
180
180
|
return { success: true, message: '服务卸载成功' };
|
|
181
181
|
}
|
|
@@ -304,7 +304,7 @@ function compareVersions(a, b) {
|
|
|
304
304
|
export async function checkForUpdates() {
|
|
305
305
|
try {
|
|
306
306
|
const currentVersion = getPackageVersion();
|
|
307
|
-
const response = await axios.get('https://registry.npmjs.org/@
|
|
307
|
+
const response = await axios.get('https://registry.npmjs.org/@myassis/gateway/latest', { timeout: 10000 });
|
|
308
308
|
const latestVersion = response.data.version;
|
|
309
309
|
if (!latestVersion) {
|
|
310
310
|
return { hasUpdate: false, currentVersion, latestVersion: currentVersion, error: '无法获取最新版本' };
|
|
@@ -326,7 +326,7 @@ export async function updateService() {
|
|
|
326
326
|
return { success: true, message: `已是最新版本 ${check.currentVersion}` };
|
|
327
327
|
}
|
|
328
328
|
console.log(`发现新版本 ${check.latestVersion},正在更新...`);
|
|
329
|
-
const { stdout, stderr } = await execAsync('npm install -g @
|
|
329
|
+
const { stdout, stderr } = await execAsync('npm install -g @myassis/gateway@latest', { timeout: 120000 });
|
|
330
330
|
if (stdout)
|
|
331
331
|
console.log(stdout);
|
|
332
332
|
if (stderr)
|