@dsh-plus/access-gate 0.2.4 → 0.3.1
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/client.js +119 -41
- package/lib/index.d.ts +10 -0
- package/lib/index.js +231 -5
- package/lib/style.css +72 -72
- package/package.json +10 -10
- package/src/client/card.tsx +24 -0
- package/src/client/i18n.ts +14 -0
- package/src/config.ts +7 -0
- package/src/cookie.ts +208 -0
- package/src/decision.ts +12 -4
- package/src/index.ts +52 -1
- package/src/interceptor.ts +81 -2
- package/src/routes.ts +4 -0
package/lib/client.js
CHANGED
|
@@ -18000,16 +18000,16 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
18000
18000
|
init_shellscript();
|
|
18001
18001
|
init_json();
|
|
18002
18002
|
var DiffBlock_module_default = {
|
|
18003
|
-
"add": "
|
|
18004
|
-
"block": "
|
|
18005
|
-
"body": "
|
|
18006
|
-
"copyButton": "
|
|
18007
|
-
"del": "
|
|
18008
|
-
"expand": "
|
|
18009
|
-
"footer": "
|
|
18010
|
-
"gap": "
|
|
18011
|
-
"line": "
|
|
18012
|
-
"path": "
|
|
18003
|
+
"add": "nVxsMW_add",
|
|
18004
|
+
"block": "nVxsMW_block",
|
|
18005
|
+
"body": "nVxsMW_body",
|
|
18006
|
+
"copyButton": "nVxsMW_copyButton",
|
|
18007
|
+
"del": "nVxsMW_del",
|
|
18008
|
+
"expand": "nVxsMW_expand",
|
|
18009
|
+
"footer": "nVxsMW_footer",
|
|
18010
|
+
"gap": "nVxsMW_gap",
|
|
18011
|
+
"line": "nVxsMW_line",
|
|
18012
|
+
"path": "nVxsMW_path"
|
|
18013
18013
|
};
|
|
18014
18014
|
//#endregion
|
|
18015
18015
|
//#region ../../node_modules/.pnpm/mdast-util-to-string@4.0.0/node_modules/mdast-util-to-string/lib/index.js
|
|
@@ -59244,27 +59244,27 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
59244
59244
|
chunkString: "chunkString"
|
|
59245
59245
|
};
|
|
59246
59246
|
//#endregion
|
|
59247
|
-
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-client-ui-primitives@0.1.
|
|
59247
|
+
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-client-ui-primitives@0.1.5-alpha.1_@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/dsh-client-ui-primitives/lib/markdown/CodeBlock.module.css
|
|
59248
59248
|
var CodeBlock_module_default = {
|
|
59249
|
-
"action": "
|
|
59250
|
-
"banner": "
|
|
59251
|
-
"bannerWrap": "
|
|
59252
|
-
"block": "
|
|
59253
|
-
"copyButton": "
|
|
59254
|
-
"infostring": "
|
|
59255
|
-
"plain": "
|
|
59256
|
-
"shiki": "
|
|
59249
|
+
"action": "Hbqh2W_action",
|
|
59250
|
+
"banner": "Hbqh2W_banner",
|
|
59251
|
+
"bannerWrap": "Hbqh2W_bannerWrap",
|
|
59252
|
+
"block": "Hbqh2W_block",
|
|
59253
|
+
"copyButton": "Hbqh2W_copyButton",
|
|
59254
|
+
"infostring": "Hbqh2W_infostring",
|
|
59255
|
+
"plain": "Hbqh2W_plain",
|
|
59256
|
+
"shiki": "Hbqh2W_shiki"
|
|
59257
59257
|
};
|
|
59258
59258
|
//#endregion
|
|
59259
|
-
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-client-ui-primitives@0.1.
|
|
59259
|
+
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-client-ui-primitives@0.1.5-alpha.1_@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/dsh-client-ui-primitives/lib/markdown/MarkdownText.module.css
|
|
59260
59260
|
var MarkdownText_module_default = {
|
|
59261
|
-
"fileMention": "
|
|
59262
|
-
"image": "
|
|
59263
|
-
"imageAlt": "
|
|
59264
|
-
"linkIcon": "
|
|
59265
|
-
"markdown": "
|
|
59266
|
-
"tableFill": "
|
|
59267
|
-
"tableScroll": "
|
|
59261
|
+
"fileMention": "BL43XG_fileMention",
|
|
59262
|
+
"image": "BL43XG_image",
|
|
59263
|
+
"imageAlt": "BL43XG_imageAlt",
|
|
59264
|
+
"linkIcon": "BL43XG_linkIcon",
|
|
59265
|
+
"markdown": "BL43XG_markdown",
|
|
59266
|
+
"tableFill": "BL43XG_tableFill",
|
|
59267
|
+
"tableScroll": "BL43XG_tableScroll"
|
|
59268
59268
|
};
|
|
59269
59269
|
//#endregion
|
|
59270
59270
|
//#region ../../node_modules/.pnpm/@shikijs+langs@4.4.3/node_modules/@shikijs/langs/dist/python.mjs
|
|
@@ -59584,7 +59584,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
59584
59584
|
less_default = [lang];
|
|
59585
59585
|
}));
|
|
59586
59586
|
//#endregion
|
|
59587
|
-
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-client-ui-primitives@0.1.
|
|
59587
|
+
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-client-ui-primitives@0.1.5-alpha.1_@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/dsh-client-ui-primitives/lib/index.js
|
|
59588
59588
|
init_typescript();
|
|
59589
59589
|
init_shellscript();
|
|
59590
59590
|
init_json();
|
|
@@ -61284,6 +61284,30 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
61284
61284
|
return;
|
|
61285
61285
|
}
|
|
61286
61286
|
}
|
|
61287
|
+
/** Protocols a vocabulary-rewritten image destination may carry. */
|
|
61288
|
+
function vocabularyImageUrl(url) {
|
|
61289
|
+
try {
|
|
61290
|
+
const protocol = new URL(url).protocol;
|
|
61291
|
+
return protocol === "http:" || protocol === "https:" || protocol === "blob:" || protocol === "data:" ? url : void 0;
|
|
61292
|
+
} catch {
|
|
61293
|
+
return;
|
|
61294
|
+
}
|
|
61295
|
+
}
|
|
61296
|
+
/**
|
|
61297
|
+
* The displayable source for one image destination: absolute HTTP(S) as
|
|
61298
|
+
* authored, otherwise the context's local-path vocabulary when it vouches for
|
|
61299
|
+
* the destination. Either miss leaves the authored fallback (alt text) to the
|
|
61300
|
+
* caller.
|
|
61301
|
+
* @param url - The authored markdown destination.
|
|
61302
|
+
* @param pathImages - Rewriting vocabulary, when the render pass has one.
|
|
61303
|
+
* @returns The displayable image URL, or undefined.
|
|
61304
|
+
*/
|
|
61305
|
+
function imageSource(url, pathImages) {
|
|
61306
|
+
const remote = remoteImageUrl(sanitizeUrl(normalizeUri(url)));
|
|
61307
|
+
if (remote !== void 0) return remote;
|
|
61308
|
+
const rewritten = pathImages?.resolve(url);
|
|
61309
|
+
return rewritten === void 0 ? void 0 : vocabularyImageUrl(rewritten);
|
|
61310
|
+
}
|
|
61287
61311
|
/**
|
|
61288
61312
|
* Create an empty {@link ReferenceTargets}.
|
|
61289
61313
|
* @returns Fresh empty maps.
|
|
@@ -61398,7 +61422,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
61398
61422
|
inLink: true
|
|
61399
61423
|
}), key, !anchorWrapsOnlyImages(node.children));
|
|
61400
61424
|
case "linkReference": return renderLinkReference(node, key, context);
|
|
61401
|
-
case "image": return renderImage(node.url, node.alt ?? "", key);
|
|
61425
|
+
case "image": return renderImage(node.url, node.alt ?? "", key, context);
|
|
61402
61426
|
case "imageReference": return renderImageReference(node, key, context);
|
|
61403
61427
|
case "footnoteReference": return renderFootnoteReference(node, key, context);
|
|
61404
61428
|
case "definition":
|
|
@@ -61532,20 +61556,36 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
61532
61556
|
return;
|
|
61533
61557
|
}
|
|
61534
61558
|
}
|
|
61535
|
-
function renderImage(url, alt, key) {
|
|
61536
|
-
const imageSrc =
|
|
61559
|
+
function renderImage(url, alt, key, context) {
|
|
61560
|
+
const imageSrc = imageSource(url, context.pathImages);
|
|
61537
61561
|
if (imageSrc === void 0) return (0, react_jsx_runtime.jsx)("span", {
|
|
61538
61562
|
className: MarkdownText_module_default.imageAlt,
|
|
61539
61563
|
children: alt
|
|
61540
61564
|
}, key);
|
|
61565
|
+
return (0, react_jsx_runtime.jsx)(MarkdownImage, {
|
|
61566
|
+
src: imageSrc,
|
|
61567
|
+
alt,
|
|
61568
|
+
destination: url
|
|
61569
|
+
}, `${key}:${imageSrc}`);
|
|
61570
|
+
}
|
|
61571
|
+
/** Failed loads retain the authored alt or destination; a new source remounts the image. */
|
|
61572
|
+
function MarkdownImage({ src, alt, destination }) {
|
|
61573
|
+
const [failed, setFailed] = (0, react.useState)(false);
|
|
61574
|
+
if (failed) return (0, react_jsx_runtime.jsx)("span", {
|
|
61575
|
+
className: MarkdownText_module_default.imageAlt,
|
|
61576
|
+
children: alt || destination
|
|
61577
|
+
});
|
|
61541
61578
|
return (0, react_jsx_runtime.jsx)("img", {
|
|
61542
61579
|
className: MarkdownText_module_default.image,
|
|
61543
|
-
src
|
|
61580
|
+
src,
|
|
61544
61581
|
alt,
|
|
61582
|
+
onError: () => {
|
|
61583
|
+
setFailed(true);
|
|
61584
|
+
},
|
|
61545
61585
|
loading: "lazy",
|
|
61546
61586
|
decoding: "async",
|
|
61547
61587
|
referrerPolicy: "no-referrer"
|
|
61548
|
-
}
|
|
61588
|
+
});
|
|
61549
61589
|
}
|
|
61550
61590
|
/** The bracketed source text a reference reverts to when its definition is missing. */
|
|
61551
61591
|
function referenceSuffix(node) {
|
|
@@ -61569,7 +61609,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
61569
61609
|
function renderImageReference(node, key, context) {
|
|
61570
61610
|
const definition = context.targets.definitions.get(node.identifier.toUpperCase());
|
|
61571
61611
|
if (definition === void 0) return `![${node.alt ?? ""}${referenceSuffix(node)}`;
|
|
61572
|
-
return renderImage(definition.url, node.alt ?? "", key);
|
|
61612
|
+
return renderImage(definition.url, node.alt ?? "", key, context);
|
|
61573
61613
|
}
|
|
61574
61614
|
function renderFootnoteReference(node, key, context) {
|
|
61575
61615
|
const id = node.identifier.toUpperCase();
|
|
@@ -61630,7 +61670,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
61630
61670
|
* full parse self-heals it.
|
|
61631
61671
|
*/
|
|
61632
61672
|
/** One settled full render: parse with math, resolve references, append the footnote section. */
|
|
61633
|
-
function renderSettled(text, labels, fileMentions) {
|
|
61673
|
+
function renderSettled(text, labels, fileMentions, pathImages) {
|
|
61634
61674
|
const root = parseGfmWithMath(text);
|
|
61635
61675
|
const targets = createReferenceTargets();
|
|
61636
61676
|
collectReferenceTargets(root.children, targets);
|
|
@@ -61638,6 +61678,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
61638
61678
|
streaming: false,
|
|
61639
61679
|
labels,
|
|
61640
61680
|
fileMentions,
|
|
61681
|
+
pathImages,
|
|
61641
61682
|
targets,
|
|
61642
61683
|
footnoteOrder: [],
|
|
61643
61684
|
footnoteCounts: /* @__PURE__ */ new Map()
|
|
@@ -61704,6 +61745,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
61704
61745
|
streaming: true,
|
|
61705
61746
|
labels: this.labels,
|
|
61706
61747
|
fileMentions: void 0,
|
|
61748
|
+
pathImages: void 0,
|
|
61707
61749
|
targets: frameTargets,
|
|
61708
61750
|
footnoteOrder: this.frozenFootnoteOrder,
|
|
61709
61751
|
footnoteCounts: this.frozenFootnoteCounts
|
|
@@ -61720,6 +61762,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
61720
61762
|
streaming: true,
|
|
61721
61763
|
labels: this.labels,
|
|
61722
61764
|
fileMentions: void 0,
|
|
61765
|
+
pathImages: void 0,
|
|
61723
61766
|
targets: frameTargets,
|
|
61724
61767
|
footnoteOrder: [...this.frozenFootnoteOrder],
|
|
61725
61768
|
footnoteCounts: new Map(this.frozenFootnoteCounts)
|
|
@@ -61736,13 +61779,13 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
61736
61779
|
return this.lastRendered;
|
|
61737
61780
|
}
|
|
61738
61781
|
};
|
|
61739
|
-
(0, react.memo)(function MarkdownText({ text, streaming = false, labels, fileMentions }) {
|
|
61782
|
+
(0, react.memo)(function MarkdownText({ text, streaming = false, labels, fileMentions, pathImages }) {
|
|
61740
61783
|
const streamRef = (0, react.useRef)(null);
|
|
61741
61784
|
const streamLabelsRef = (0, react.useRef)(labels);
|
|
61742
61785
|
const children = (0, react.useMemo)(() => {
|
|
61743
61786
|
if (!streaming) {
|
|
61744
61787
|
streamRef.current = null;
|
|
61745
|
-
return renderSettled(text, labels, fileMentions);
|
|
61788
|
+
return renderSettled(text, labels, fileMentions, pathImages);
|
|
61746
61789
|
}
|
|
61747
61790
|
if (streamRef.current === null || streamLabelsRef.current !== labels) {
|
|
61748
61791
|
streamRef.current = new StreamingRenderer(labels);
|
|
@@ -61753,7 +61796,8 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
61753
61796
|
text,
|
|
61754
61797
|
streaming,
|
|
61755
61798
|
labels,
|
|
61756
|
-
fileMentions
|
|
61799
|
+
fileMentions,
|
|
61800
|
+
pathImages
|
|
61757
61801
|
]);
|
|
61758
61802
|
return (0, react_jsx_runtime.jsx)("div", {
|
|
61759
61803
|
className: MarkdownText_module_default.markdown,
|
|
@@ -62111,25 +62155,29 @@ ${extra}
|
|
|
62111
62155
|
return {
|
|
62112
62156
|
enabled: value.enabled,
|
|
62113
62157
|
allowedIpsText: value.allowedIps.join("\n"),
|
|
62114
|
-
trustForwardedFor: value.trustForwardedFor
|
|
62158
|
+
trustForwardedFor: value.trustForwardedFor,
|
|
62159
|
+
autoLoginTrustedIps: value.autoLoginTrustedIps
|
|
62115
62160
|
};
|
|
62116
62161
|
}
|
|
62117
62162
|
function toPatch(draft) {
|
|
62118
62163
|
return {
|
|
62119
62164
|
enabled: draft.enabled,
|
|
62120
62165
|
allowedIps: draft.allowedIpsText.split("\n").map((s) => s.trim()).filter((s) => s.length > 0),
|
|
62121
|
-
trustForwardedFor: draft.trustForwardedFor
|
|
62166
|
+
trustForwardedFor: draft.trustForwardedFor,
|
|
62167
|
+
autoLoginTrustedIps: draft.autoLoginTrustedIps
|
|
62122
62168
|
};
|
|
62123
62169
|
}
|
|
62124
62170
|
/** reason 枚举 → 文案 key。 */
|
|
62125
62171
|
const REASON_KEYS = {
|
|
62126
62172
|
local: "diagLocal",
|
|
62127
|
-
cookie: "diagCookie"
|
|
62173
|
+
cookie: "diagCookie",
|
|
62174
|
+
"trusted-ip": "diagTrustedIp"
|
|
62128
62175
|
};
|
|
62129
62176
|
function verdictLabel(t, diag) {
|
|
62130
62177
|
if (!diag.enabled) return t("diagOff");
|
|
62131
62178
|
if (diag.verdict === "pass") return t("diagPass");
|
|
62132
62179
|
if (diag.verdict === "token-page") return t("diagTokenPage");
|
|
62180
|
+
if (diag.verdict === "autologin") return t("diagAutoLogin");
|
|
62133
62181
|
return t("diagBlock");
|
|
62134
62182
|
}
|
|
62135
62183
|
function AccessGateCard(props) {
|
|
@@ -62254,6 +62302,14 @@ ${extra}
|
|
|
62254
62302
|
})
|
|
62255
62303
|
]
|
|
62256
62304
|
}),
|
|
62305
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CheckRow, {
|
|
62306
|
+
prefix: "dag",
|
|
62307
|
+
id: "dag-autologin",
|
|
62308
|
+
label: t("autoLoginHint"),
|
|
62309
|
+
checked: draft.autoLoginTrustedIps,
|
|
62310
|
+
disabled,
|
|
62311
|
+
onEdit: (v) => edit("autoLoginTrustedIps", v)
|
|
62312
|
+
}),
|
|
62257
62313
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CheckRow, {
|
|
62258
62314
|
prefix: "dag",
|
|
62259
62315
|
id: "dag-xff",
|
|
@@ -62309,6 +62365,16 @@ ${extra}
|
|
|
62309
62365
|
children: diag.officialAuthed ? t("diagOfficialYes") : t("diagOfficialNo")
|
|
62310
62366
|
})]
|
|
62311
62367
|
}),
|
|
62368
|
+
diag.autoLoginActive ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
62369
|
+
className: "dag-diagRow",
|
|
62370
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
62371
|
+
className: "dag-diagKey",
|
|
62372
|
+
children: t("diagAutoLogin")
|
|
62373
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
62374
|
+
className: "dag-diagVal",
|
|
62375
|
+
children: diag.autoLoginReady ? t("diagAutoLoginReady") : t("diagAutoLoginNoSecret")
|
|
62376
|
+
})]
|
|
62377
|
+
}) : null,
|
|
62312
62378
|
diag.invalidEntries.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
62313
62379
|
className: "dag-diagRow",
|
|
62314
62380
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -62340,6 +62406,7 @@ ${extra}
|
|
|
62340
62406
|
mergedHint: "登录凭据由官方认证持有(启动令牌换 30 天 cookie)。获取当前令牌:服务器执行 dshctl url,或本机访问 /dsh-plus/gate/launch-url。",
|
|
62341
62407
|
allowedIps: "附加 IP 围栏白名单",
|
|
62342
62408
|
allowedIpsHint: "每行一个:精确 IP 或 CIDR(IPv4/IPv6 皆可)。非空时仅白名单来源可通行与登录;留空 = 不限制来源 IP(仅官方登录保护)。",
|
|
62409
|
+
autoLoginHint: "IP 信任自动登录:白名单来源未认证时自动签发官方登录 cookie,免输启动令牌。开启即视为信任白名单内全部设备(tailnet 内),请确保白名单准确。",
|
|
62343
62410
|
trustForwardedFor: "信任 x-forwarded-for 还原客户端 IP",
|
|
62344
62411
|
trustForwardedForHint: "仅当入口代理强制覆盖该头时开启(tailscale serve 满足);直连暴露场景必须关闭。",
|
|
62345
62412
|
diagTitle: "当前页面诊断",
|
|
@@ -62348,12 +62415,17 @@ ${extra}
|
|
|
62348
62415
|
diagReason: "放行原因",
|
|
62349
62416
|
diagLocal: "本机直连",
|
|
62350
62417
|
diagCookie: "官方 cookie",
|
|
62418
|
+
diagTrustedIp: "IP 信任白名单",
|
|
62351
62419
|
diagOfficial: "官方登录状态",
|
|
62352
62420
|
diagOfficialYes: "已登录",
|
|
62353
62421
|
diagOfficialNo: "未登录",
|
|
62354
62422
|
diagPass: "放行",
|
|
62355
62423
|
diagBlock: "拦截",
|
|
62356
62424
|
diagTokenPage: "令牌输入页",
|
|
62425
|
+
diagAutoLogin: "自动登录",
|
|
62426
|
+
diagAutoLoginVerdict: "自动登录(免 token 进入)",
|
|
62427
|
+
diagAutoLoginReady: "已就绪(签名密钥可读)",
|
|
62428
|
+
diagAutoLoginNoSecret: "不可用(签名密钥读取失败,已降级)",
|
|
62357
62429
|
diagOff: "围栏未启用",
|
|
62358
62430
|
diagInvalid: "白名单存在无法解析的条目:"
|
|
62359
62431
|
};
|
|
@@ -62365,6 +62437,7 @@ ${extra}
|
|
|
62365
62437
|
mergedHint: "Credentials are owned by official auth (launch token exchange, 30-day cookie). Get the current token: run dshctl url on the server, or visit /dsh-plus/gate/launch-url locally.",
|
|
62366
62438
|
allowedIps: "Additional IP fence allowlist",
|
|
62367
62439
|
allowedIpsHint: "One per line: exact IP or CIDR (IPv4/IPv6). When non-empty only listed sources may pass or log in; empty = no IP restriction (official login only).",
|
|
62440
|
+
autoLoginHint: "Trusted-IP auto login: mint the official login cookie automatically for unauthenticated allowlisted sources, no launch token needed. Enabling trusts every allowlisted device (inside the tailnet); keep the allowlist accurate.",
|
|
62368
62441
|
trustForwardedFor: "Trust x-forwarded-for for client IP",
|
|
62369
62442
|
trustForwardedForHint: "Enable only when the entry proxy overwrites that header (tailscale serve does); must be off for direct exposure.",
|
|
62370
62443
|
diagTitle: "This page",
|
|
@@ -62373,12 +62446,17 @@ ${extra}
|
|
|
62373
62446
|
diagReason: "Reason",
|
|
62374
62447
|
diagLocal: "loopback",
|
|
62375
62448
|
diagCookie: "official cookie",
|
|
62449
|
+
diagTrustedIp: "trusted IP allowlist",
|
|
62376
62450
|
diagOfficial: "Official login",
|
|
62377
62451
|
diagOfficialYes: "authenticated",
|
|
62378
62452
|
diagOfficialNo: "not authenticated",
|
|
62379
62453
|
diagPass: "pass",
|
|
62380
62454
|
diagBlock: "blocked",
|
|
62381
62455
|
diagTokenPage: "token page",
|
|
62456
|
+
diagAutoLogin: "Auto login",
|
|
62457
|
+
diagAutoLoginVerdict: "auto login (token-free entry)",
|
|
62458
|
+
diagAutoLoginReady: "ready (signing secret readable)",
|
|
62459
|
+
diagAutoLoginNoSecret: "unavailable (signing secret unreadable, degraded)",
|
|
62382
62460
|
diagOff: "gate disabled",
|
|
62383
62461
|
diagInvalid: "Allowlist entries that failed to parse:"
|
|
62384
62462
|
};
|
package/lib/index.d.ts
CHANGED
|
@@ -5,10 +5,12 @@ declare const Config: z<Schemastery.ObjectS<{
|
|
|
5
5
|
enabled: z<boolean, boolean>;
|
|
6
6
|
allowedIps: z<string[], string[]>;
|
|
7
7
|
trustForwardedFor: z<boolean, boolean>;
|
|
8
|
+
autoLoginTrustedIps: z<boolean, boolean>;
|
|
8
9
|
}>, Schemastery.ObjectT<{
|
|
9
10
|
enabled: z<boolean, boolean>;
|
|
10
11
|
allowedIps: z<string[], string[]>;
|
|
11
12
|
trustForwardedFor: z<boolean, boolean>;
|
|
13
|
+
autoLoginTrustedIps: z<boolean, boolean>;
|
|
12
14
|
}>>;
|
|
13
15
|
type AccessGateConfig = Schemastery.TypeT<typeof Config>;
|
|
14
16
|
//#endregion
|
|
@@ -23,9 +25,17 @@ declare module '@deepseek-ai/cordis' {
|
|
|
23
25
|
/** 围栏服务:持有当前配置读取器(settings 用户层热更新经 setSource 注入)。 */
|
|
24
26
|
declare class AccessGateService extends Service {
|
|
25
27
|
private current;
|
|
28
|
+
/** 官方 browser-auth 签名密钥(惰性读取缓存;读取失败 = null,autoLogin fail-safe 降级)。 */
|
|
29
|
+
private signingSecret;
|
|
26
30
|
constructor(ctx: Context, config: AccessGateConfig);
|
|
27
31
|
/** 当前生效配置(诊断用)。 */
|
|
28
32
|
policy(): AccessGateConfig;
|
|
33
|
+
/** 官方签名密钥(惰性缓存;失败返回 null 并记录,autoLogin 降级 fail-safe)。 */
|
|
34
|
+
private readSigningSecret;
|
|
35
|
+
/** IP 信任自动登录可用性(诊断用):签名密钥可读即为可用。 */
|
|
36
|
+
autoLoginSecretReady(logger: {
|
|
37
|
+
warn(message: string): void;
|
|
38
|
+
}): boolean;
|
|
29
39
|
}
|
|
30
40
|
declare function apply(ctx: Context, config: AccessGateConfig): void;
|
|
31
41
|
//#endregion
|