@shgroup/dsh-serenity-hooks 1.24.5 → 1.24.7
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 +2562 -20
- package/lib/index.js +15 -32
- package/package.json +9 -2
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 = {
|
|
@@ -7944,23 +7945,6 @@ function registerOpencodeSkills(ctx) {
|
|
|
7944
7945
|
};
|
|
7945
7946
|
ctx.skills.registerProvider(() => provider);
|
|
7946
7947
|
}
|
|
7947
|
-
//#endregion
|
|
7948
|
-
//#region src/gateway-auth.ts
|
|
7949
|
-
/**
|
|
7950
|
-
* gateway-auth.ts — F1 双端口网关:认证域纯逻辑(v1.22.4 安全加固)
|
|
7951
|
-
*
|
|
7952
|
-
* 从 gateway.ts 拆分(S142 熵点治理,v1.22.8):认证纯逻辑独立成模块——
|
|
7953
|
-
* 登录验证(scrypt)/ 会话 token(滑动 TTL + 吊销)/ 失败锁定(账号维度指数退避)/
|
|
7954
|
-
* CSRF(双提交 + Origin 校验)/ cookie 解析 / 登录页 HTML。
|
|
7955
|
-
* gateway.ts 保留 HTTP 装配(startGateway/registerGateway)并从本模块 import。
|
|
7956
|
-
*
|
|
7957
|
-
* 纯函数设计(可单测):无 socket/无 HTTP 依赖,全部导出可注入测试。
|
|
7958
|
-
*/
|
|
7959
|
-
function verifyGatewayLogin(accounts, user, password) {
|
|
7960
|
-
const account = accounts.find((a) => a.user === user);
|
|
7961
|
-
if (!account) return false;
|
|
7962
|
-
return verifyPassword(password, account.passHash);
|
|
7963
|
-
}
|
|
7964
7948
|
/** 内存会话表(重启即清空——用户决策) */
|
|
7965
7949
|
const sessions = /* @__PURE__ */ new Map();
|
|
7966
7950
|
/** 颁发会话 token(Hex 32 字节) */
|
|
@@ -8127,13 +8111,13 @@ button:active{background:#2563eb}
|
|
|
8127
8111
|
${csrf ? `<input type="hidden" name="csrf" value="${csrf}">` : ""}
|
|
8128
8112
|
<label for="f-user">用户名</label>
|
|
8129
8113
|
<input id="f-user" type="text" name="user" placeholder="用户名" autocomplete="username" autocapitalize="none" autocorrect="off" required autofocus enterkeyhint="next">
|
|
8130
|
-
<label for="f-pass"
|
|
8131
|
-
<input id="f-pass" type="password" name="password" placeholder="密码" autocomplete="current-password"
|
|
8114
|
+
<label for="f-pass">密码(或下方验证码,二选一)</label>
|
|
8115
|
+
<input id="f-pass" type="password" name="password" placeholder="密码" autocomplete="current-password" enterkeyhint="next">
|
|
8132
8116
|
<label for="f-code">验证码(已绑定 Authenticator 时填写)</label>
|
|
8133
8117
|
<input id="f-code" type="text" name="code" placeholder="6 位验证码" inputmode="numeric" pattern="[0-9]{6}" maxlength="6" autocomplete="one-time-code" enterkeyhint="go">
|
|
8134
8118
|
<button type="submit">登录</button>
|
|
8135
8119
|
<div class="error">${extra}</div>
|
|
8136
|
-
<p class="hint"
|
|
8120
|
+
<p class="hint">已绑定验证器的账号:密码 或 6 位验证码任一即可登录(二选一)</p>
|
|
8137
8121
|
</form>
|
|
8138
8122
|
<p class="foot">Serenity ACC · dsh-serenity-hooks</p>
|
|
8139
8123
|
</div></body></html>`;
|
|
@@ -8488,17 +8472,16 @@ function startGateway(config, getAccounts) {
|
|
|
8488
8472
|
res.end(loginPageHtml(`账号已锁定,请 ${Math.ceil(lockedRemaining / 6e4)} 分钟后再试`));
|
|
8489
8473
|
return;
|
|
8490
8474
|
}
|
|
8491
|
-
const
|
|
8492
|
-
const
|
|
8493
|
-
|
|
8494
|
-
|
|
8495
|
-
if (totpEnabled && passOk && account !== void 0 && typeof account.totpSecret === "string" && account.totpSecret !== "") {
|
|
8475
|
+
const account = getAccounts().find((a) => a.user === user);
|
|
8476
|
+
const passOk = account !== void 0 && password !== "" && verifyPassword(password, account.passHash);
|
|
8477
|
+
let totpOk = false;
|
|
8478
|
+
if (totpEnabled && account !== void 0 && typeof account.totpSecret === "string" && account.totpSecret !== "") {
|
|
8496
8479
|
const hit = verifyTotpCode(account.totpSecret, code);
|
|
8497
8480
|
totpOk = hit !== null;
|
|
8498
8481
|
if (totpOk && hit !== null && lastTotpCounter.get(account.id) === hit) totpOk = false;
|
|
8499
8482
|
if (totpOk && hit !== null) lastTotpCounter.set(account.id, hit);
|
|
8500
8483
|
}
|
|
8501
|
-
if (passOk
|
|
8484
|
+
if (passOk || totpOk) {
|
|
8502
8485
|
resetFailState(user);
|
|
8503
8486
|
const token = issueToken(user);
|
|
8504
8487
|
res.writeHead(302, {
|
|
@@ -8506,12 +8489,12 @@ function startGateway(config, getAccounts) {
|
|
|
8506
8489
|
"set-cookie": `${cookieName}=${token}; HttpOnly; SameSite=Strict; Path=/${cookieSecure ? "; Secure" : ""}`
|
|
8507
8490
|
});
|
|
8508
8491
|
res.end();
|
|
8509
|
-
console.log(`[serenity-hooks] 登录成功: user=${user} ip=${remote}`);
|
|
8492
|
+
console.log(`[serenity-hooks] 登录成功: user=${user} ip=${remote} via=${passOk ? "password" : "totp"}`);
|
|
8510
8493
|
return;
|
|
8511
8494
|
}
|
|
8512
8495
|
const lockMs = recordLoginFailure(user);
|
|
8513
|
-
console.warn(`[serenity-hooks] 登录失败: user=${user} ip=${remote}
|
|
8514
|
-
const msg = lockMs > 0 ? `尝试过多,账号已锁定 ${Math.ceil(lockMs / 6e4)} 分钟` :
|
|
8496
|
+
console.warn(`[serenity-hooks] 登录失败: user=${user} ip=${remote}${lockMs > 0 ? ` 锁定=${Math.ceil(lockMs / 6e4)}min` : ""}`);
|
|
8497
|
+
const msg = lockMs > 0 ? `尝试过多,账号已锁定 ${Math.ceil(lockMs / 6e4)} 分钟` : "用户名、密码或验证码错误";
|
|
8515
8498
|
res.writeHead(401, { "content-type": "text/html; charset=utf-8" });
|
|
8516
8499
|
res.end(loginPageHtml(msg));
|
|
8517
8500
|
});
|
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.7",
|
|
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": {
|
|
@@ -55,9 +55,9 @@
|
|
|
55
55
|
"@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.5",
|
|
56
56
|
"@deepseek-ai/dsh-llm": "^0.1.0-rc.5",
|
|
57
57
|
"@deepseek-ai/dsh-session": "^0.1.0-rc.5",
|
|
58
|
+
"@deepseek-ai/dsh-session-title": "^0.1.0-rc.5",
|
|
58
59
|
"@deepseek-ai/dsh-shell": "^0.1.0-rc.5",
|
|
59
60
|
"@deepseek-ai/dsh-shell-env": "^0.1.0-rc.5",
|
|
60
|
-
"@deepseek-ai/dsh-session-title": "^0.1.0-rc.5",
|
|
61
61
|
"@deepseek-ai/dsh-skill": "^0.1.0-rc.5",
|
|
62
62
|
"@deepseek-ai/dsh-system-prompt": "^0.1.0-rc.5",
|
|
63
63
|
"@deepseek-ai/dsh-tools": "^0.1.0-rc.5",
|
|
@@ -86,11 +86,18 @@
|
|
|
86
86
|
},
|
|
87
87
|
"devDependencies": {
|
|
88
88
|
"@types/node": "^20.0.0",
|
|
89
|
+
"@types/qrcode-generator": "^1.0.6",
|
|
89
90
|
"@types/react": "^18.2.0",
|
|
91
|
+
"qrcode-generator": "^2.0.4",
|
|
90
92
|
"react": "^18.2.0",
|
|
91
93
|
"tsdown": "^0.22.14",
|
|
92
94
|
"typescript": "^5.4.0",
|
|
93
95
|
"unrun": "^0.3.1",
|
|
94
96
|
"vitest": "^1.6.0"
|
|
97
|
+
},
|
|
98
|
+
"pnpm": {
|
|
99
|
+
"onlyBuiltDependencies": [
|
|
100
|
+
"esbuild"
|
|
101
|
+
]
|
|
95
102
|
}
|
|
96
103
|
}
|