@yezack/dsh-remote-mobile 1.9.2 → 1.10.0
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/CHANGELOG.md +64 -2
- package/README.md +109 -34
- package/README_EN.md +115 -40
- package/lib/auth/crypto.js +3 -1
- package/lib/auth/gate.d.ts +39 -9
- package/lib/auth/gate.js +231 -33
- package/lib/auth/tailscale.d.ts +24 -2
- package/lib/auth/tailscale.js +38 -3
- package/lib/auth/token.d.ts +22 -0
- package/lib/auth/token.js +58 -2
- package/lib/bridge/compat.d.ts +22 -2
- package/lib/bridge/compat.js +579 -336
- package/lib/client.js +67 -14
- package/lib/gateway/detector.d.ts +42 -0
- package/lib/gateway/detector.js +88 -0
- package/lib/gateway/secret.d.ts +23 -0
- package/lib/gateway/secret.js +65 -0
- package/lib/gateway/server.d.ts +108 -0
- package/lib/gateway/server.js +568 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +143 -15
- package/lib/routes/api.js +16 -10
- package/lib/routes/login-page.js +399 -398
- package/lib/styles/style-snippets.js +639 -639
- package/package.json +3 -3
package/lib/bridge/compat.d.ts
CHANGED
|
@@ -32,6 +32,8 @@
|
|
|
32
32
|
*/
|
|
33
33
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
34
34
|
import type { SessionStore } from '../auth/token.js';
|
|
35
|
+
import { extractBareHostname, extractPortString } from '../auth/gate.js';
|
|
36
|
+
export { extractBareHostname, extractPortString };
|
|
35
37
|
import { type StyleSnippetStore } from '../styles/style-snippets.js';
|
|
36
38
|
/**
|
|
37
39
|
* 注入到 index.html <head> 最前列的 Polyfill 脚本代码片段
|
|
@@ -70,20 +72,30 @@ export declare const DRAGGABLE_NAV_SNIPPET = "\n(function() {\n if (typeof wind
|
|
|
70
72
|
* 两种环境行为一致。折叠状态沿用官方写入的 data-sidebar-collapsed 属性。
|
|
71
73
|
*/
|
|
72
74
|
export declare const MOBILE_DISMISS_SNIPPET = "\n(function() {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") return;\n\n var frameSelector = '[class*=\"_frame\"]';\n var sidebarSelector = '[class*=\"_sidebarCol\"]';\n\n function webUiOwnsDrawer() {\n return !!document.querySelector('style[data-dsh-compat=\"responsive\"]');\n }\n\n function findToggle(frame) {\n return frame.querySelector('[class*=\"_toggle\"]') ||\n Array.prototype.filter.call(frame.querySelectorAll('button'), function (b) {\n return /\u6536\u8D77\u4FA7\u8FB9\u680F|Collapse sidebar|Open sidebar/i.test(b.getAttribute('aria-label') || '');\n })[0] || null;\n }\n\n function install(frame) {\n if (frame.__dshRmDismissInstalled__) return;\n frame.__dshRmDismissInstalled__ = true;\n var raf = 0;\n\n frame.addEventListener('click', function (event) {\n try {\n // web-ui \u53EF\u80FD\u8FD0\u884C\u4E2D\u624D\u6CE8\u5165 responsive style\uFF1A\u6BCF\u6B21\u4E8B\u4EF6\u90FD\u590D\u67E5\uFF0C\u52A8\u6001\u8BA9\u4F4D\n if (webUiOwnsDrawer()) return;\n var target = event.target;\n if (!target || !(target instanceof Element)) return;\n if (typeof window.matchMedia !== 'function' || !window.matchMedia('(max-width: 900px)').matches) return;\n var sidebar = frame.querySelector(sidebarSelector);\n var toggle = findToggle(frame);\n if (!sidebar || !toggle) return;\n\n // \u62BD\u5C49\u5C55\u5F00\u65F6\u70B9\u51FB\u6B63\u6587\uFF08sidebar \u5916\uFF09\u2192 \u89E6\u53D1\u5B98\u65B9\u6536\u8D77\u6309\u94AE\uFF0C\u5E76\u62E6\u622A\u88AB\u541E\u6389\u7684\u70B9\u51FB\uFF1B\n // \u627E\u4E0D\u5230\u6536\u8D77\u6309\u94AE\u65F6\u4E0A\u9762\u5DF2 return\uFF0C\u7EDD\u4E0D\u8BEF\u62E6\u6B63\u6587\u4EA4\u4E92\uFF1B\n // \u589E\u52A0\u5BF9 sidebar \u5185\u90E8 _collapsed \u7684\u72B6\u6001\u6821\u9A8C\uFF0C\u53CC\u91CD\u4FDD\u8BC1\u4EC5\u5728\u4FA7\u8FB9\u680F\u771F\u6B63\u5C55\u5F00\u65F6\u624D\u62E6\u622A\u6B63\u6587\u70B9\u51FB\n var isSidebarOpen = !frame.hasAttribute('data-sidebar-collapsed') && !sidebar.querySelector('[class*=\"_collapsed\"]');\n if (isSidebarOpen && !sidebar.contains(target)) {\n event.preventDefault();\n event.stopPropagation();\n toggle.click();\n return;\n }\n // \u70B9\u51FB\u4FA7\u8FB9\u680F\u5185\u6B21\u7EA7\u64CD\u4F5C\u56FE\u6807\uFF08\u66F4\u591A\u64CD\u4F5C \u22EF / \u5C55\u5F00\u7BAD\u5934\u7B49\uFF09\u3001\u5DE5\u4F5C\u533A\u884C\uFF08_projectRow\uFF09\u6216\u539F\u751F\u5207\u6362\u6309\u94AE \u2192 \u4E0D\u6536\u8D77\u62BD\u5C49\n if (target.closest('[class*=\"_toggle\"], [class*=\"_rowActions\"], [class*=\"_projectRow\"], [class*=\"_chevron\"], [class*=\"_arrow\"], button, [role=\"button\"]')) return;\n // \u70B9\u51FB\u4F1A\u8BDD\u6761\u76EE\uFF08_sessionRow\uFF09\u4E3B\u4F53\uFF08\u9009\u4E2D\u4F1A\u8BDD\u540E\u56DE\u4E3B\u533A\uFF09\u2192 \u4E0B\u4E00\u5E27\u7A0B\u5E8F\u5316\u6536\u8D77\n if (!target.closest('[class*=\"_sessionRow\"], [role=\"treeitem\"], [data-dsh-part=\"sidebar-entry\"]')) return;\n if (raf !== 0) cancelAnimationFrame(raf);\n raf = requestAnimationFrame(function () {\n raf = 0;\n if (!frame.hasAttribute('data-sidebar-collapsed')) toggle.click();\n });\n } catch (err) {}\n }, true);\n }\n\n function ensure() {\n if (webUiOwnsDrawer()) return;\n var frame = document.querySelector(frameSelector);\n if (frame) install(frame);\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', ensure);\n } else {\n ensure();\n }\n setInterval(ensure, 800);\n})();\n";
|
|
75
|
+
/**
|
|
76
|
+
* 向 HTML 文档的 <head> 顶部安全注入样式片段与 Polyfill 脚本(自带幂等防重守卫)
|
|
77
|
+
*
|
|
78
|
+
* @param html - 待注入的原始 HTML 字符串
|
|
79
|
+
* @param isMobile - 是否为移动端(用于追加 data-dsh-mobile 标记)
|
|
80
|
+
* @param mobileStyleCss - 动态收集的样式片段 CSS(支持按视口宽度生效)
|
|
81
|
+
*/
|
|
82
|
+
export declare function injectHtmlPayload(html: string, isMobile?: boolean, mobileStyleCss?: string): string;
|
|
73
83
|
/**
|
|
74
84
|
* 挂载底层 http.Server 门禁劫持与回环上下文虚拟化代理
|
|
75
85
|
*
|
|
76
86
|
* @param server - 底层 Node.js http.Server 实例
|
|
77
87
|
* @param gateMiddleware - 全局安全门禁拦截器函数
|
|
78
88
|
* @param store - 会话与配置管理器实例
|
|
89
|
+
* @param styleStore - 样式片段管理器实例
|
|
79
90
|
*/
|
|
80
91
|
export declare function patchHttpServerWithVirtualizer(server: any, gateMiddleware: (req: IncomingMessage, res: ServerResponse, next?: () => void) => boolean, _store: SessionStore, styleStore?: StyleSnippetStore): void;
|
|
81
92
|
/**
|
|
82
|
-
* 注册 WebServer HTML
|
|
93
|
+
* 注册 WebServer HTML 模板层的样式与 Polyfill 注入钩子(在 Gzip 压缩前执行)
|
|
83
94
|
*
|
|
84
95
|
* @param ctx - Cordis 上下文对象
|
|
96
|
+
* @param styleStore - 样式片段管理器实例
|
|
85
97
|
*/
|
|
86
|
-
export declare function mountIndexInjections(ctx: any): void;
|
|
98
|
+
export declare function mountIndexInjections(ctx: any, styleStore?: StyleSnippetStore): void;
|
|
87
99
|
/**
|
|
88
100
|
* 配对桥接服务的运行时裁决状态(供 /status 接口与设置页横幅读取)
|
|
89
101
|
*
|
|
@@ -143,3 +155,11 @@ export declare function isRequestAuthorizedByGate(req: any, store: SessionStore)
|
|
|
143
155
|
* @param store - 会话与配置管理器实例
|
|
144
156
|
*/
|
|
145
157
|
export declare function takeOverConnectionAuth(connection: any, store: SessionStore): void;
|
|
158
|
+
/**
|
|
159
|
+
* 向 DSH 运行时(webRuntime、connection、webStartup)的 trustedHosts 数组注入受信任的主机与端口
|
|
160
|
+
*
|
|
161
|
+
* @param target - Cordis 上下文对象或包含 trustedHosts 的服务对象
|
|
162
|
+
* @param ports - 允许访问的活跃端口(包含底座端口与网关实际绑定端口)
|
|
163
|
+
* @param staticTrustedHosts - 用户静态配置的白名单(如 Tailscale MagicDNS 域名等)
|
|
164
|
+
*/
|
|
165
|
+
export declare function injectTrustedHosts(target: any, ports?: number[], staticTrustedHosts?: string[]): void;
|