@shgroup/dsh-serenity-hooks 1.24.4 → 1.24.6

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/lib/index.js CHANGED
@@ -7944,23 +7944,6 @@ function registerOpencodeSkills(ctx) {
7944
7944
  };
7945
7945
  ctx.skills.registerProvider(() => provider);
7946
7946
  }
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
7947
  /** 内存会话表(重启即清空——用户决策) */
7965
7948
  const sessions = /* @__PURE__ */ new Map();
7966
7949
  /** 颁发会话 token(Hex 32 字节) */
@@ -8127,13 +8110,13 @@ button:active{background:#2563eb}
8127
8110
  ${csrf ? `<input type="hidden" name="csrf" value="${csrf}">` : ""}
8128
8111
  <label for="f-user">用户名</label>
8129
8112
  <input id="f-user" type="text" name="user" placeholder="用户名" autocomplete="username" autocapitalize="none" autocorrect="off" required autofocus enterkeyhint="next">
8130
- <label for="f-pass">密码</label>
8131
- <input id="f-pass" type="password" name="password" placeholder="密码" autocomplete="current-password" required enterkeyhint="next">
8113
+ <label for="f-pass">密码(或下方验证码,二选一)</label>
8114
+ <input id="f-pass" type="password" name="password" placeholder="密码" autocomplete="current-password" enterkeyhint="next">
8132
8115
  <label for="f-code">验证码(已绑定 Authenticator 时填写)</label>
8133
8116
  <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
8117
  <button type="submit">登录</button>
8135
8118
  <div class="error">${extra}</div>
8136
- <p class="hint">未绑定验证器的账号只需用户名 + 密码</p>
8119
+ <p class="hint">已绑定验证器的账号:密码 或 6 位验证码任一即可登录(二选一)</p>
8137
8120
  </form>
8138
8121
  <p class="foot">Serenity ACC · dsh-serenity-hooks</p>
8139
8122
  </div></body></html>`;
@@ -8488,17 +8471,16 @@ function startGateway(config, getAccounts) {
8488
8471
  res.end(loginPageHtml(`账号已锁定,请 ${Math.ceil(lockedRemaining / 6e4)} 分钟后再试`));
8489
8472
  return;
8490
8473
  }
8491
- const accounts = getAccounts();
8492
- const account = accounts.find((a) => a.user === user);
8493
- const passOk = account !== void 0 && verifyGatewayLogin(accounts, user, password);
8494
- let totpOk = true;
8495
- if (totpEnabled && passOk && account !== void 0 && typeof account.totpSecret === "string" && account.totpSecret !== "") {
8474
+ const account = getAccounts().find((a) => a.user === user);
8475
+ const passOk = account !== void 0 && password !== "" && verifyPassword(password, account.passHash);
8476
+ let totpOk = false;
8477
+ if (totpEnabled && account !== void 0 && typeof account.totpSecret === "string" && account.totpSecret !== "") {
8496
8478
  const hit = verifyTotpCode(account.totpSecret, code);
8497
8479
  totpOk = hit !== null;
8498
8480
  if (totpOk && hit !== null && lastTotpCounter.get(account.id) === hit) totpOk = false;
8499
8481
  if (totpOk && hit !== null) lastTotpCounter.set(account.id, hit);
8500
8482
  }
8501
- if (passOk && totpOk) {
8483
+ if (passOk || totpOk) {
8502
8484
  resetFailState(user);
8503
8485
  const token = issueToken(user);
8504
8486
  res.writeHead(302, {
@@ -8506,12 +8488,12 @@ function startGateway(config, getAccounts) {
8506
8488
  "set-cookie": `${cookieName}=${token}; HttpOnly; SameSite=Strict; Path=/${cookieSecure ? "; Secure" : ""}`
8507
8489
  });
8508
8490
  res.end();
8509
- console.log(`[serenity-hooks] 登录成功: user=${user} ip=${remote}`);
8491
+ console.log(`[serenity-hooks] 登录成功: user=${user} ip=${remote} via=${passOk ? "password" : "totp"}`);
8510
8492
  return;
8511
8493
  }
8512
8494
  const lockMs = recordLoginFailure(user);
8513
- console.warn(`[serenity-hooks] 登录失败: user=${user} ip=${remote} reason=${!passOk ? "bad-password" : "bad-totp"}${lockMs > 0 ? ` 锁定=${Math.ceil(lockMs / 6e4)}min` : ""}`);
8514
- const msg = lockMs > 0 ? `尝试过多,账号已锁定 ${Math.ceil(lockMs / 6e4)} 分钟` : passOk ? "验证码错误" : "用户名或密码错误";
8495
+ console.warn(`[serenity-hooks] 登录失败: user=${user} ip=${remote}${lockMs > 0 ? ` 锁定=${Math.ceil(lockMs / 6e4)}min` : ""}`);
8496
+ const msg = lockMs > 0 ? `尝试过多,账号已锁定 ${Math.ceil(lockMs / 6e4)} 分钟` : "用户名、密码或验证码错误";
8515
8497
  res.writeHead(401, { "content-type": "text/html; charset=utf-8" });
8516
8498
  res.end(loginPageHtml(msg));
8517
8499
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shgroup/dsh-serenity-hooks",
3
- "version": "1.24.4",
3
+ "version": "1.24.6",
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
  }