@shgroup/dsh-serenity-hooks 1.24.6 → 1.24.8
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/dsh.plugin.json +1 -1
- package/lib/client.js +8 -18
- package/lib/index.js +7 -6
- package/package.json +1 -1
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-serenity-hooks",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.8",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"description": "宁静号 ACC harness(Native Cordis 插件):真实 DSH 工具 cc_fs/session/acc_msm/eap/neat/cce/handyman/session_rebuild + 拦截缝机械约束(safe-mode/路径守卫)+ 高级设定面板(双端口网关/账号管理)。适配 DSH 公开版(0.1.0-rc,deepseek-ai/deepseek-harness)。",
|
|
6
6
|
"engines": {
|
package/lib/client.js
CHANGED
|
@@ -3212,11 +3212,10 @@ window.__ModuleLoader__.load({
|
|
|
3212
3212
|
...d.totpState === "pending" && d.totpSecret !== void 0 && d.totpSecret !== "" ? { totpSecret: d.totpSecret } : d.totpState === "clear" ? { totpReset: true } : {}
|
|
3213
3213
|
};
|
|
3214
3214
|
}
|
|
3215
|
-
/** 校验本地编辑行:user
|
|
3215
|
+
/** 校验本地编辑行:user 非空;新账号必须设密码(v1.24.7:TOTP 生成即绑定,无确认码要求) */
|
|
3216
3216
|
function validateDraft(d) {
|
|
3217
3217
|
if (d.user.trim() === "") return "用户名不能为空";
|
|
3218
3218
|
if (d.isNew && d.pass === "") return "新账号必须设置密码";
|
|
3219
|
-
if (d.totpState === "pending" && !/^\d{6}$/.test(d.totpConfirm ?? "")) return `绑定 ${d.user} 的验证器需输入 6 位确认码`;
|
|
3220
3219
|
return null;
|
|
3221
3220
|
}
|
|
3222
3221
|
const CONFIG_PATH = "/serenity/config";
|
|
@@ -3277,7 +3276,7 @@ window.__ModuleLoader__.load({
|
|
|
3277
3276
|
}
|
|
3278
3277
|
//#endregion
|
|
3279
3278
|
//#region \0sp-css:/home/yh/home/home-serenity/AI_LAB/dsh-serenity-plugin/hooks/dsh-serenity-hooks/src/client/AccountsEditor
|
|
3280
|
-
const css$2 = "/* AccountsEditor — DSH 设置面板「外部访问」区块(v1.22)\n * 与 SettingsSection ss-* 同设计语言:--dsw-alias-* 语义 token,明暗自适应。 */\n\n.ae-root {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 12px 14px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n font-size: 13px;\n}\n\n.ae-warn {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-warning-fg, #f59e0b);\n word-break: break-word;\n}\n\n.ae-block {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.ae-title {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n color: var(--dsw-alias-label-secondary);\n}\n\n.ae-desc {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n word-break: break-word;\n overflow-wrap: anywhere;\n}\n\n.ae-note {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n}\n\n/* ── 监听设置 / 白名单输入行 ── */\n\n.ae-row {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.ae-label {\n flex: none;\n font-size: 12px;\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n white-space: nowrap;\n}\n\n.ae-input {\n flex: 1;\n min-width: 0;\n padding: 6px 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 8px;\n background: var(--dsw-alias-bg-module);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n outline: none;\n}\n\n.ae-input:focus {\n border-color: var(--dsw-alias-button-primary-bg, var(--dsw-alias-accent, #3b82f6));\n}\n\n.ae-input::placeholder {\n color: var(--dsw-alias-label-dimmed);\n}\n\n.ae-input.ae-port {\n flex: none;\n width: 76px;\n}\n\n/* ── 账号列表 ── */\n\n.ae-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.ae-head {\n display: flex;\n gap: 8px;\n font-size: 11px;\n font-weight: 500;\n color: var(--dsw-alias-label-dimmed);\n padding: 0 2px;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n}\n\n.ae-item {\n display: flex;\n gap: 8px;\n align-items: center;\n padding: 6px 2px;\n}\n\n.ae-colUser { flex: 1.2; }\n.ae-colPass { flex: 1.6; }\n.ae-colTotp { flex: 2.2; min-width: 0; }\n.ae-colOp { flex: none; width: 48px; }\n\n/* ── v1.22.4 TOTP 第二因素 ── */\n\n.ae-totpBtn {\n flex: none;\n padding: 4px 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.ae-totpBtn:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.ae-totpPending {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n align-items: center;\n min-width: 0;\n}\n\n/* v1.24.6:TOTP 绑定二维码(扫码即录入;scalable SVG,白底保证扫码识别) */\n.ae-totpQr {\n flex-basis: 100%;\n display: inline-flex;\n justify-content: center;\n padding: 8px;\n background: #fff;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 8px;\n}\n\n.ae-totpQr svg {\n width: 132px;\n height: 132px;\n display: block;\n}\n\n.ae-totpSecret {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 11px;\n background: var(--dsw-alias-surface-raised, rgba(0, 0, 0, 0.25));\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 4px;\n padding: 2px 6px;\n color: var(--dsw-alias-label-secondary);\n word-break: break-all;\n}\n\n.ae-totpUri {\n font-size: 11px;\n color: var(--dsw-alias-accent, #3b82f6);\n text-decoration: none;\n}\n\n.ae-totpUri:hover {\n text-decoration: underline;\n}\n\n.ae-
|
|
3279
|
+
const css$2 = "/* AccountsEditor — DSH 设置面板「外部访问」区块(v1.22)\n * 与 SettingsSection ss-* 同设计语言:--dsw-alias-* 语义 token,明暗自适应。 */\n\n.ae-root {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 12px 14px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n font-size: 13px;\n}\n\n.ae-warn {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-warning-fg, #f59e0b);\n word-break: break-word;\n}\n\n.ae-block {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.ae-title {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n color: var(--dsw-alias-label-secondary);\n}\n\n.ae-desc {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n word-break: break-word;\n overflow-wrap: anywhere;\n}\n\n.ae-note {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n}\n\n/* ── 监听设置 / 白名单输入行 ── */\n\n.ae-row {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.ae-label {\n flex: none;\n font-size: 12px;\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n white-space: nowrap;\n}\n\n.ae-input {\n flex: 1;\n min-width: 0;\n padding: 6px 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 8px;\n background: var(--dsw-alias-bg-module);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n outline: none;\n}\n\n.ae-input:focus {\n border-color: var(--dsw-alias-button-primary-bg, var(--dsw-alias-accent, #3b82f6));\n}\n\n.ae-input::placeholder {\n color: var(--dsw-alias-label-dimmed);\n}\n\n.ae-input.ae-port {\n flex: none;\n width: 76px;\n}\n\n/* ── 账号列表 ── */\n\n.ae-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.ae-head {\n display: flex;\n gap: 8px;\n font-size: 11px;\n font-weight: 500;\n color: var(--dsw-alias-label-dimmed);\n padding: 0 2px;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n}\n\n.ae-item {\n display: flex;\n gap: 8px;\n align-items: center;\n padding: 6px 2px;\n}\n\n.ae-colUser { flex: 1.2; }\n.ae-colPass { flex: 1.6; }\n.ae-colTotp { flex: 2.2; min-width: 0; }\n.ae-colOp { flex: none; width: 48px; }\n\n/* ── v1.22.4 TOTP 第二因素 ── */\n\n.ae-totpBtn {\n flex: none;\n padding: 4px 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.ae-totpBtn:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.ae-totpPending {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n align-items: center;\n min-width: 0;\n}\n\n/* v1.24.6:TOTP 绑定二维码(扫码即录入;scalable SVG,白底保证扫码识别) */\n.ae-totpQr {\n flex-basis: 100%;\n display: inline-flex;\n justify-content: center;\n padding: 8px;\n background: #fff;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 8px;\n}\n\n.ae-totpQr svg {\n width: 132px;\n height: 132px;\n display: block;\n}\n\n.ae-totpSecret {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 11px;\n background: var(--dsw-alias-surface-raised, rgba(0, 0, 0, 0.25));\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 4px;\n padding: 2px 6px;\n color: var(--dsw-alias-label-secondary);\n word-break: break-all;\n}\n\n.ae-totpUri {\n font-size: 11px;\n color: var(--dsw-alias-accent, #3b82f6);\n text-decoration: none;\n}\n\n.ae-totpUri:hover {\n text-decoration: underline;\n}\n\n/* v1.24.7:绑定提示(去确认码后——扫码或手动录入,保存即绑定) */\n.ae-totpHint {\n flex-basis: 100%;\n font-size: 11px;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.ae-totpBadge {\n font-size: 12px;\n color: var(--dsw-alias-state-warning-fg, #f59e0b);\n}\n\n.ae-totpClear {\n display: flex;\n gap: 6px;\n align-items: center;\n}\n\n.ae-check {\n display: flex;\n gap: 8px;\n align-items: center;\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n margin-top: 10px;\n cursor: pointer;\n}\n\n.ae-check input {\n accent-color: var(--dsw-alias-accent, #3b82f6);\n}\n\n.ae-del {\n flex: none;\n padding: 4px 10px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-state-danger-fg, #f87171);\n font-size: 12px;\n cursor: pointer;\n}\n\n.ae-del:hover {\n background: var(--dsw-alias-state-danger-bg, rgba(248, 113, 113, 0.12));\n}\n\n.ae-add {\n align-self: flex-start;\n padding: 5px 12px;\n border: 1px dashed var(--dsw-alias-border-l2);\n border-radius: 8px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n cursor: pointer;\n}\n\n.ae-add:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.ae-wsSelect {\n margin-top: 8px;\n max-width: 100%;\n cursor: pointer;\n}\n\n/* ── 工作区白名单 chips ── */\n\n.ae-wsList {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.ae-wsChip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 8px;\n background: var(--dsw-alias-interactive-bg-active, rgba(128, 128, 128, 0.14));\n}\n\n.ae-wsPath {\n font-size: 12px;\n color: var(--dsw-alias-label-primary);\n font-family: var(--ds-font-family-code, monospace);\n word-break: break-all;\n}\n\n.ae-wsDel {\n flex: none;\n width: 18px;\n height: 18px;\n border: none;\n border-radius: 50%;\n background: transparent;\n color: var(--dsw-alias-label-dimmed);\n font-size: 13px;\n line-height: 1;\n cursor: pointer;\n}\n\n.ae-wsDel:hover {\n background: var(--dsw-alias-state-danger-bg, rgba(248, 113, 113, 0.18));\n color: var(--dsw-alias-state-danger-fg, #f87171);\n}\n\n/* ── 错误 / 操作区 ── */\n\n.ae-error {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-danger-fg, #f87171);\n word-break: break-word;\n}\n\n.ae-actions {\n display: flex;\n justify-content: flex-end;\n padding-top: 4px;\n border-top: 1px solid var(--dsw-alias-border-l1);\n}\n\n.ae-save {\n padding: 7px 24px;\n border: 0;\n border-radius: 8px;\n background: var(--dsw-alias-button-primary-bg, var(--dsw-alias-accent, #3b82f6));\n color: var(--dsw-alias-button-primary-fg, #fff);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.ae-save:hover:not(:disabled) {\n filter: brightness(1.08);\n}\n\n.ae-save:disabled {\n opacity: 0.6;\n cursor: default;\n}\n";
|
|
3281
3280
|
if (typeof document !== "undefined" && document.querySelector("style[data-sp-css=\"AccountsEditor\"]") === null) {
|
|
3282
3281
|
const tag = document.createElement("style");
|
|
3283
3282
|
tag.setAttribute("data-sp-css", "AccountsEditor");
|
|
@@ -3360,22 +3359,19 @@ window.__ModuleLoader__.load({
|
|
|
3360
3359
|
const secret = newTotpSecret();
|
|
3361
3360
|
updateDraft(d.id, {
|
|
3362
3361
|
totpState: "pending",
|
|
3363
|
-
totpSecret: secret
|
|
3364
|
-
totpConfirm: ""
|
|
3362
|
+
totpSecret: secret
|
|
3365
3363
|
});
|
|
3366
3364
|
};
|
|
3367
3365
|
const cancelTotpBind = (d) => {
|
|
3368
3366
|
updateDraft(d.id, {
|
|
3369
3367
|
totpState: d.hasTotp ? "none" : "none",
|
|
3370
|
-
totpSecret: void 0
|
|
3371
|
-
totpConfirm: ""
|
|
3368
|
+
totpSecret: void 0
|
|
3372
3369
|
});
|
|
3373
3370
|
};
|
|
3374
3371
|
const markTotpClear = (d) => {
|
|
3375
3372
|
updateDraft(d.id, {
|
|
3376
3373
|
totpState: "clear",
|
|
3377
|
-
totpSecret: void 0
|
|
3378
|
-
totpConfirm: ""
|
|
3374
|
+
totpSecret: void 0
|
|
3379
3375
|
});
|
|
3380
3376
|
};
|
|
3381
3377
|
const toggleWorkspace = (path) => {
|
|
@@ -3562,15 +3558,9 @@ window.__ModuleLoader__.load({
|
|
|
3562
3558
|
rel: "noreferrer",
|
|
3563
3559
|
children: "otpauth://"
|
|
3564
3560
|
}),
|
|
3565
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
3566
|
-
className: "ae-
|
|
3567
|
-
|
|
3568
|
-
inputMode: "numeric",
|
|
3569
|
-
pattern: "[0-9]{6}",
|
|
3570
|
-
maxLength: 6,
|
|
3571
|
-
value: d.totpConfirm ?? "",
|
|
3572
|
-
placeholder: "输入验证码确认",
|
|
3573
|
-
onChange: (e) => updateDraft(d.id, { totpConfirm: e.target.value })
|
|
3561
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3562
|
+
className: "ae-totpHint",
|
|
3563
|
+
children: "扫码或手动录入后,点「保存」即完成绑定"
|
|
3574
3564
|
}),
|
|
3575
3565
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3576
3566
|
type: "button",
|
package/lib/index.js
CHANGED
|
@@ -6831,9 +6831,10 @@ function applyWirePatch(wire) {
|
|
|
6831
6831
|
const pass = a.pass;
|
|
6832
6832
|
const totp = a.totpSecret;
|
|
6833
6833
|
const totpReset = a.totpReset === true;
|
|
6834
|
-
|
|
6835
|
-
|
|
6836
|
-
|
|
6834
|
+
if (typeof totp === "string" && totp !== "") try {
|
|
6835
|
+
base32Decode(totp);
|
|
6836
|
+
} catch {
|
|
6837
|
+
throw new Error(`Account "${a.user}" TOTP secret is not valid base32`);
|
|
6837
6838
|
}
|
|
6838
6839
|
const nextTotp = totpReset ? void 0 : typeof totp === "string" && totp !== "" ? totp : existing?.totpSecret;
|
|
6839
6840
|
const withTotp = {
|
|
@@ -8456,9 +8457,9 @@ function startGateway(config, getAccounts) {
|
|
|
8456
8457
|
const cookieCsrf = cookieValue(req.headers.cookie, "serenity_csrf");
|
|
8457
8458
|
const formCsrf = csrfFromRequest(req, params);
|
|
8458
8459
|
if (cookieCsrf === void 0 || formCsrf === null || !safeEqual(cookieCsrf, formCsrf)) {
|
|
8459
|
-
console.warn(`[serenity-hooks] 登录拒绝(CSRF 校验失败):user=${user} ip=${remote}`);
|
|
8460
|
+
console.warn(`[serenity-hooks] 登录拒绝(CSRF 校验失败):user=${user} ip=${remote} cookieSecure=${cookieSecure ? "on" : "off"} cookieCsrf=${cookieCsrf === void 0 ? "missing" : "present"} formCsrf=${formCsrf === null ? "missing" : "present"}`);
|
|
8460
8461
|
res.writeHead(403, { "content-type": "text/html; charset=utf-8" });
|
|
8461
|
-
res.end(loginPageHtml("会话校验失败,请刷新页面重试"));
|
|
8462
|
+
res.end(loginPageHtml("会话校验失败,请刷新页面重试" + (cookieSecure ? "(若仍失败:设置面板关闭 Secure Cookie——明文 HTTP 下必须关闭)" : "")));
|
|
8462
8463
|
return;
|
|
8463
8464
|
}
|
|
8464
8465
|
const lockedRemaining = accountLockRemaining(user);
|
|
@@ -8502,7 +8503,7 @@ function startGateway(config, getAccounts) {
|
|
|
8502
8503
|
const csrf = newCsrfToken();
|
|
8503
8504
|
res.writeHead(200, {
|
|
8504
8505
|
"content-type": "text/html; charset=utf-8",
|
|
8505
|
-
"set-cookie": `serenity_csrf=${csrf}; HttpOnly; SameSite=Strict; Path
|
|
8506
|
+
"set-cookie": `serenity_csrf=${csrf}; HttpOnly; SameSite=Strict; Path=/`
|
|
8506
8507
|
});
|
|
8507
8508
|
res.end(loginPageHtml("", csrf));
|
|
8508
8509
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shgroup/dsh-serenity-hooks",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.8",
|
|
4
4
|
"description": "宁静号 ACC harness — Native Cordis 插件(DeepSeek Harness 运行时)。真实 DSH 工具注册(cc_fs/session/acc_msm 等 9 工具)+ 拦截缝机械约束(safe-mode/路径守卫/会话落盘)+ 系统提示词注入(ACC/CCE/Constraints/SKILL/Session 五块)。适配 DSH 公开版(deepseek-ai/deepseek-harness 0.1.0-rc)。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|