dsh-workspace-migrate 0.5.0 → 0.5.2
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 +5 -2
- package/index.js +33 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# dsh-workspace-migrate
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/dsh-workspace-migrate)
|
|
4
|
+
[](https://www.dshplugin.store/plugin/lij0000-arch/dsh-workspace-migrate)
|
|
3
5
|
[](https://github.com/lij0000-arch/dsh-workspace-migrate/releases)
|
|
4
6
|
[](https://github.com/lij0000-arch/dsh-workspace-migrate)
|
|
5
7
|
[](LICENSE)
|
|
@@ -16,7 +18,7 @@
|
|
|
16
18
|
|
|
17
19
|
```bash
|
|
18
20
|
# 桌面端(大多数情况)
|
|
19
|
-
dsh plugin --profile desktop add
|
|
21
|
+
dsh plugin --profile desktop add dsh-workspace-migrate
|
|
20
22
|
```
|
|
21
23
|
|
|
22
24
|
不想用命令行:设置 → 插件 里安装,或在一个对话里让 agent 用 `plugin_manager` 装这个仓库。装完刷新页面,**设置 → 迁移** 出现即可用。
|
|
@@ -39,7 +41,8 @@ dsh plugin --profile desktop add https://github.com/lij0000-arch/dsh-workspace-m
|
|
|
39
41
|
- **读**:`~/.dsh/sessions`(会话事件流)、`~/.dsh/storages/workspace.json`(项目登记、置顶/归档集合)、`~/.dsh/attachments`、以及所选项目目录
|
|
40
42
|
- **写**:经公开服务新建会话与项目登记(`sessionPersistence` / `workspaceRegistry`)、按路径映射复制项目文件与附件
|
|
41
43
|
- **删**:只有「撤销这次导入」会删,而且只删**本次进程内由本插件创建**的项目登记与会话目录,其它 id 一律拒绝
|
|
42
|
-
- **网络**:不向外发起请求;仅在本机 `127.0.0.1` 注册 `/api/dsh-migrate`
|
|
44
|
+
- **网络**:不向外发起请求;仅在本机 `127.0.0.1` 注册 `/api/dsh-migrate` 供当前页面调用
|
|
45
|
+
- **鉴权**:每个请求都经宿主 `ctx.connection.admit()` 校验浏览器签名凭据(401/403 拒绝);老宿主没有该服务时,退回同源检查并要求 Origin 必须存在
|
|
43
46
|
- **凭据**:不读取、不导出 `~/.dsh/.credentials.yaml`
|
|
44
47
|
- **隐私**:迁移包含完整对话与项目文件,导出目录不要放在公开位置
|
|
45
48
|
|
package/index.js
CHANGED
|
@@ -1157,16 +1157,6 @@ export function apply(ctx, config = {}) {
|
|
|
1157
1157
|
res.end(body)
|
|
1158
1158
|
}
|
|
1159
1159
|
|
|
1160
|
-
function sameOrigin(req) {
|
|
1161
|
-
const origin = req.headers.origin
|
|
1162
|
-
if (!origin) return true
|
|
1163
|
-
try {
|
|
1164
|
-
return new URL(origin).host === req.headers.host
|
|
1165
|
-
} catch {
|
|
1166
|
-
return false
|
|
1167
|
-
}
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
1160
|
async function readJson(req) {
|
|
1171
1161
|
const chunks = []
|
|
1172
1162
|
let size = 0
|
|
@@ -1179,9 +1169,40 @@ export function apply(ctx, config = {}) {
|
|
|
1179
1169
|
return JSON.parse(Buffer.concat(chunks).toString('utf8'))
|
|
1180
1170
|
}
|
|
1181
1171
|
|
|
1172
|
+
/**
|
|
1173
|
+
* 身份认证。宿主提供 `connection` 服务时必须用它:
|
|
1174
|
+
* ctx.connection.admit({ headers }) 会校验浏览器签名凭据(或 API token),
|
|
1175
|
+
* 返回 `{}` 或 `{ rejection: 401 | 403 }`。
|
|
1176
|
+
* 没有该服务(老宿主)时退回 Origin 检查,并额外要求 Origin 存在——
|
|
1177
|
+
* 缺 Origin 的请求只可能来自非浏览器客户端。
|
|
1178
|
+
*/
|
|
1179
|
+
function authenticate(req) {
|
|
1180
|
+
const connection = ctx.get('connection')
|
|
1181
|
+
if (connection) {
|
|
1182
|
+
try {
|
|
1183
|
+
const admission = connection.admit({ headers: req.headers })
|
|
1184
|
+
if (admission && admission.rejection) return { status: admission.rejection }
|
|
1185
|
+
return {}
|
|
1186
|
+
} catch {
|
|
1187
|
+
return { status: 401 }
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
const origin = req.headers.origin
|
|
1191
|
+
if (!origin) return { status: 401 }
|
|
1192
|
+
try {
|
|
1193
|
+
if (new URL(origin).host !== req.headers.host) return { status: 403 }
|
|
1194
|
+
} catch {
|
|
1195
|
+
return { status: 403 }
|
|
1196
|
+
}
|
|
1197
|
+
return {}
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1182
1200
|
async function handler(req, res) {
|
|
1183
|
-
|
|
1184
|
-
|
|
1201
|
+
const auth = authenticate(req)
|
|
1202
|
+
if (auth.status) {
|
|
1203
|
+
sendJson(res, auth.status, {
|
|
1204
|
+
error: auth.status === 401 ? '需要先在 Harness 中登录(缺少或无效的浏览器凭据)' : '拒绝跨站请求',
|
|
1205
|
+
})
|
|
1185
1206
|
return
|
|
1186
1207
|
}
|
|
1187
1208
|
const url = new URL(req.url ?? '/', 'http://localhost')
|