@aalis/plugin-webui-server 0.15.0 → 0.16.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/dist/attention.d.ts +2 -2
- package/dist/attention.d.ts.map +1 -1
- package/dist/attention.js +5 -4
- package/dist/attention.js.map +1 -1
- package/dist/auth.d.ts +13 -4
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +77 -27
- package/dist/auth.js.map +1 -1
- package/dist/client-switch-page.d.ts +25 -3
- package/dist/client-switch-page.d.ts.map +1 -1
- package/dist/client-switch-page.js +49 -19
- package/dist/client-switch-page.js.map +1 -1
- package/dist/gate.d.ts.map +1 -1
- package/dist/gate.js +2 -1
- package/dist/gate.js.map +1 -1
- package/dist/html.d.ts +15 -0
- package/dist/html.d.ts.map +1 -0
- package/dist/html.js +38 -0
- package/dist/html.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +223 -244
- package/dist/index.js.map +1 -1
- package/dist/layout.d.ts +2 -1
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +5 -3
- package/dist/layout.js.map +1 -1
- package/dist/locales/en.d.ts +191 -0
- package/dist/locales/en.d.ts.map +1 -0
- package/dist/locales/en.js +191 -0
- package/dist/locales/en.js.map +1 -0
- package/dist/localize.d.ts +24 -0
- package/dist/localize.d.ts.map +1 -0
- package/dist/localize.js +68 -0
- package/dist/localize.js.map +1 -0
- package/dist/page-check.d.ts.map +1 -1
- package/dist/page-check.js +32 -25
- package/dist/page-check.js.map +1 -1
- package/dist/pages.d.ts +9 -7
- package/dist/pages.d.ts.map +1 -1
- package/dist/pages.js +77 -61
- package/dist/pages.js.map +1 -1
- package/dist/route.d.ts +5 -2
- package/dist/route.d.ts.map +1 -1
- package/dist/route.js +5 -2
- package/dist/route.js.map +1 -1
- package/dist/routes/files.d.ts.map +1 -1
- package/dist/routes/files.js +4 -3
- package/dist/routes/files.js.map +1 -1
- package/dist/routes/frames.js +3 -3
- package/dist/routes/frames.js.map +1 -1
- package/dist/routes/i18n.d.ts +20 -0
- package/dist/routes/i18n.d.ts.map +1 -0
- package/dist/routes/i18n.js +78 -0
- package/dist/routes/i18n.js.map +1 -0
- package/dist/routes/marketplace.d.ts.map +1 -1
- package/dist/routes/marketplace.js +27 -29
- package/dist/routes/marketplace.js.map +1 -1
- package/dist/routes/media.d.ts +3 -0
- package/dist/routes/media.d.ts.map +1 -1
- package/dist/routes/media.js +29 -26
- package/dist/routes/media.js.map +1 -1
- package/dist/routes/pages.d.ts +4 -2
- package/dist/routes/pages.d.ts.map +1 -1
- package/dist/routes/pages.js +36 -18
- package/dist/routes/pages.js.map +1 -1
- package/dist/routes/plugins.d.ts +5 -9
- package/dist/routes/plugins.d.ts.map +1 -1
- package/dist/routes/plugins.js +114 -129
- package/dist/routes/plugins.js.map +1 -1
- package/dist/routes/proxy.d.ts +3 -2
- package/dist/routes/proxy.d.ts.map +1 -1
- package/dist/routes/proxy.js +62 -41
- package/dist/routes/proxy.js.map +1 -1
- package/dist/texts.d.ts +381 -0
- package/dist/texts.d.ts.map +1 -0
- package/dist/texts.js +194 -0
- package/dist/texts.js.map +1 -0
- package/package.json +26 -23
package/dist/attention.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Approval } from '@aalis/api-approval';
|
|
2
2
|
import type { HostConfig } from '@aalis/api-host-config';
|
|
3
|
-
import type
|
|
3
|
+
import { type SessionManagerService } from '@aalis/api-session-manager';
|
|
4
4
|
import type { AttentionItem, Notice, PluginBlockers, WebuiAdminEvent } from '@aalis/api-webui';
|
|
5
5
|
import type { PluginManagerService, PluginStatusEntry, ServiceSelection, Services } from '@aalis/core';
|
|
6
6
|
/** 算插件没起来的原因要读的:插件状态与定义、当前有提供者的服务名、配置文档(宿主不提供时读运行态配置) */
|
|
@@ -14,7 +14,7 @@ export declare function blockedStatus({ plugins, services, doc }: BlockerSources
|
|
|
14
14
|
interface AttentionDeps {
|
|
15
15
|
/** 推出未结的审批;审批服务不在时没有 */
|
|
16
16
|
approvals(): readonly Approval[];
|
|
17
|
-
/**
|
|
17
|
+
/** 会话管理:审批所在会话的标题(没有标题时是会话的显示名称) */
|
|
18
18
|
sessions: Pick<ServiceSelection<Pick<SessionManagerService, 'getSession'>>, 'present' | 'use'>;
|
|
19
19
|
/** 插件状态与没起来的原因;插件管理服务不在时为空 */
|
|
20
20
|
plugins(): ReadonlyArray<PluginStatusEntry & PluginBlockers>;
|
package/dist/attention.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attention.d.ts","sourceRoot":"","sources":["../src/attention.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"attention.d.ts","sourceRoot":"","sources":["../src/attention.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,KAAK,qBAAqB,EAAgB,MAAM,4BAA4B,CAAC;AACtF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvG,yDAAyD;AACzD,UAAU,cAAc;IACtB,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE,WAAW,GAAG,WAAW,CAAC,CAAC;IAC/D,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClC,GAAG,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;CAC3C;AAED,0BAA0B;AAC1B,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,cAAc,GAAG,KAAK,CAAC,iBAAiB,GAAG,cAAc,CAAC,CAgBnH;AAED,UAAU,aAAa;IACrB,wBAAwB;IACxB,SAAS,IAAI,SAAS,QAAQ,EAAE,CAAC;IACjC,oCAAoC;IACpC,QAAQ,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,qBAAqB,EAAE,YAAY,CAAC,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,CAAC;IAC/F,8BAA8B;IAC9B,OAAO,IAAI,aAAa,CAAC,iBAAiB,GAAG,cAAc,CAAC,CAAC;IAC7D,mBAAmB;IACnB,OAAO,IAAI,aAAa,CAAC,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,IAAI,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;CACpC;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa;IA2B/C,2BAA2B;iBAChB,aAAa,EAAE;IAQ1B,eAAe;;IAEf,6BAA6B;sBACX,IAAI;EAOzB"}
|
package/dist/attention.js
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
// 经 GET /api/attention 给出。变了就经 /admin 推 attention.changed:审批推出或结算是变化,提示的登记与撤回由页面登记表推
|
|
9
9
|
// (pages.ts);插件登记表每次重算之后比一次故障(连同链与根),变了才推(重算很频繁,多数与故障无关)。
|
|
10
10
|
// ============================================================
|
|
11
|
-
import { unmetDependencies } from '@aalis/api-doctor';
|
|
11
|
+
import { failureText, unmetDependencies } from '@aalis/api-doctor';
|
|
12
|
+
import { sessionLabel } from '@aalis/api-session-manager';
|
|
12
13
|
import { validateConfig } from '@aalis/schema-config';
|
|
13
14
|
/** 插件状态快照,每个实例带上没起来的原因 */
|
|
14
15
|
export function blockedStatus({ plugins, services, doc }) {
|
|
@@ -29,13 +30,13 @@ export function blockedStatus({ plugins, services, doc }) {
|
|
|
29
30
|
}));
|
|
30
31
|
}
|
|
31
32
|
export function createAttention(deps) {
|
|
32
|
-
const faults = () => deps.plugins().flatMap(({ instanceId, state, error, lacking, waiting, unconfigured }) => state === 'error' || (state === 'pending' && lacking.length > 0)
|
|
33
|
+
const faults = () => deps.plugins().flatMap(({ instanceId, state, error, failure, lacking, waiting, unconfigured }) => state === 'error' || (state === 'pending' && lacking.length > 0)
|
|
33
34
|
? [
|
|
34
35
|
{
|
|
35
36
|
kind: 'plugin',
|
|
36
37
|
instance: instanceId,
|
|
37
38
|
state,
|
|
38
|
-
...(error !== undefined && { error }),
|
|
39
|
+
...(error !== undefined && { error: failureText({ failure, error }) }),
|
|
39
40
|
lacking,
|
|
40
41
|
waiting,
|
|
41
42
|
unconfigured,
|
|
@@ -44,7 +45,7 @@ export function createAttention(deps) {
|
|
|
44
45
|
: []);
|
|
45
46
|
const titleOf = (sessionId) => {
|
|
46
47
|
const info = deps.sessions.present ? deps.sessions.use.getSession(sessionId) : undefined;
|
|
47
|
-
return info && (info.title || info
|
|
48
|
+
return info && (info.title || sessionLabel(info));
|
|
48
49
|
};
|
|
49
50
|
let reported = JSON.stringify(faults());
|
|
50
51
|
const changed = () => deps.send({ type: 'attention.changed' });
|
package/dist/attention.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attention.js","sourceRoot":"","sources":["../src/attention.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,iCAAiC;AACjC,EAAE;AACF,oEAAoE;AACpE,8DAA8D;AAC9D,EAAE;AACF,+DAA+D;AAC/D,qFAAqF;AACrF,0DAA0D;AAC1D,+DAA+D;AAG/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"attention.js","sourceRoot":"","sources":["../src/attention.ts"],"names":[],"mappings":"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"}
|
package/dist/auth.d.ts
CHANGED
|
@@ -2,8 +2,14 @@ import type { IncomingMessage } from 'node:http';
|
|
|
2
2
|
import type { UserIdentity } from '@aalis/api-authority';
|
|
3
3
|
import type { ProcessService } from '@aalis/api-process';
|
|
4
4
|
import type express from 'express';
|
|
5
|
+
import type { Localizer } from './localize.js';
|
|
5
6
|
/** 失败计数表最多记这么多个地址:满了再记新地址时丢掉最早的那条,内存有界,也不因此变成全局锁定 */
|
|
6
7
|
export declare const LOGIN_FAILURE_ADDRESSES_MAX = 10000;
|
|
8
|
+
/**
|
|
9
|
+
* 配置里的一项是不是主机名(allowedHosts 的写法):可带端口,不带协议、用户名、路径、查询与片段,去掉首尾空白后解析得出。
|
|
10
|
+
* 带协议的照 Host 头的写法拼出来会把协议名当主机名(`https://x` 成了 `https`),真正要认的主机名照旧被拒
|
|
11
|
+
*/
|
|
12
|
+
export declare function isHostName(entry: string): boolean;
|
|
7
13
|
/**
|
|
8
14
|
* 请求的来源能不能收,WebSocket 升级与改状态的请求(非 GET)共用。浏览器发起的握手与 POST 一律带 Origin,只收与本服务同源的:
|
|
9
15
|
* Origin 的主机与端口等于请求的 Host。同一主机别的端口上的网页与本服务同站,SameSite cookie 会随它的请求发出,
|
|
@@ -14,8 +20,8 @@ export declare const LOGIN_FAILURE_ADDRESSES_MAX = 10000;
|
|
|
14
20
|
export declare function originAllowed(req: Pick<IncomingMessage, 'headers'>): boolean;
|
|
15
21
|
export interface AuthSystem {
|
|
16
22
|
/**
|
|
17
|
-
* 挂上认证,要在 JSON
|
|
18
|
-
*
|
|
23
|
+
* 挂上认证,要在 JSON 解析之后、其余路由之前:先核 Host,再是改状态的请求核来源,然后是登录页的脚本、`?token=` 一键登录、
|
|
24
|
+
* 登录、登录状态与注销,其余未登录的请求一律拦下(API 回 401,GET 页面回登录页)
|
|
19
25
|
*/
|
|
20
26
|
install(expressApp: express.Express): void;
|
|
21
27
|
/** 校验 WebSocket 升级请求是否已认证(cookie 读取) */
|
|
@@ -29,15 +35,18 @@ export interface AuthSystem {
|
|
|
29
35
|
* - token 由调用方经 getToken 提供,每次校验现取:persist 模式下 storage 晚上线时,调用方会把
|
|
30
36
|
* 启动时的临时 token 换成读回的持久化 token(见 index.ts 的 token 解析)
|
|
31
37
|
* - HttpOnly + SameSite=Strict cookie;`?token=` 一键登录;同源 POST /api/auth/login 提交
|
|
38
|
+
* - 请求的 Host 先按 {@link hostAllowed} 核对,hostNames 是 IP 地址与 localhost 之外认的主机名(监听地址与 allowedHosts);
|
|
39
|
+
* 不认的回 421,不进登录的比对与计数,带着 cookie 也不放行
|
|
32
40
|
* - 改状态的请求(非 GET、HEAD、OPTIONS)按 {@link originAllowed} 校验来源,与 WebSocket 升级同一个判定:SameSite 按站判、
|
|
33
41
|
* 不分端口,同一主机别的端口上的网页发一个简单 POST 就会带上 cookie
|
|
34
42
|
* - `?token=` 与登录接口按来源地址限速:失败计数见 LOGIN_MAX_FAILURES、LOGIN_FAILURE_WINDOW_MS,成功清零。
|
|
35
|
-
* 别的网页借 owner 的浏览器发起的登录(跨源的 POST、别的站点打开的 `?token
|
|
43
|
+
* 别的网页借 owner 的浏览器发起的登录(跨源的 POST、别的站点打开的 `?token=`、DNS 重绑定)不比对也不计数,免得别人替 owner 把
|
|
36
44
|
* 地址锁住。带 cookie 的请求不计数:各种模式的 token 都够长(随机生成的 24 字节,固定的至少 32 个字符),
|
|
37
45
|
* 按 cookie 逐个猜猜不中;对 cookie 也锁定的话,共用一个来源地址(同一个反向代理)的已登录页面会被别人一起锁住
|
|
38
46
|
* - 身份恒为 `webui:console`(owner 级,单人模式语义)
|
|
47
|
+
* - 登录页与回应里的文字按全局层的语言(localizer)
|
|
39
48
|
*/
|
|
40
|
-
export declare function createAuthSystem(getToken: () => string): AuthSystem;
|
|
49
|
+
export declare function createAuthSystem(getToken: () => string, localizer: Pick<Localizer, 'render' | 'languages'>, hostNames: readonly string[]): AuthSystem;
|
|
41
50
|
/**
|
|
42
51
|
* 跨平台打开默认浏览器到指定 URL(无外部依赖)
|
|
43
52
|
* 失败静默;此为便利功能,不影响服务启动。
|
package/dist/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAU/C,qDAAqD;AACrD,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAiBlD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEjD;AAgBD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,GAAG,OAAO,CAO5E;AA2GD,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAC3C,wCAAwC;IACxC,cAAc,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC;IAC9C,0EAA0E;IAC1E,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,GAAG,YAAY,GAAG,SAAS,CAAC;CAC3E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,MAAM,EACtB,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,GAAG,WAAW,CAAC,EAClD,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,UAAU,CA0JZ;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CAwBnE"}
|
package/dist/auth.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { createHash, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
import { isIP } from 'node:net';
|
|
2
3
|
import { BUILTIN_THEMES, DEFAULT_THEMES } from '@aalis/api-webui';
|
|
4
|
+
import { escapeHtml, pageLanguageOf, textsBlock } from './html.js';
|
|
3
5
|
import { route } from './route.js';
|
|
6
|
+
import { t } from './texts.js';
|
|
4
7
|
const TOKEN_COOKIE = 'aalis_webui_token';
|
|
5
8
|
/** 同一来源地址在一个窗口内登录失败满这么多次,到窗口结束前它的登录一律回 429(正确的 token 也不收) */
|
|
6
9
|
const LOGIN_MAX_FAILURES = 10;
|
|
@@ -16,6 +19,29 @@ function tokenEquals(given, expected) {
|
|
|
16
19
|
const digest = (s) => createHash('sha256').update(s).digest();
|
|
17
20
|
return timingSafeEqual(digest(given), digest(expected));
|
|
18
21
|
}
|
|
22
|
+
/** Host 头(或配置里同样写法)的主机名:小写,国际化域名转成 punycode,IPv6 带方括号;解析不了的没有 */
|
|
23
|
+
function hostnameOf(host) {
|
|
24
|
+
const url = `http://${host}`;
|
|
25
|
+
return URL.canParse(url) ? new URL(url).hostname : undefined;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 配置里的一项是不是主机名(allowedHosts 的写法):可带端口,不带协议、用户名、路径、查询与片段,去掉首尾空白后解析得出。
|
|
29
|
+
* 带协议的照 Host 头的写法拼出来会把协议名当主机名(`https://x` 成了 `https`),真正要认的主机名照旧被拒
|
|
30
|
+
*/
|
|
31
|
+
export function isHostName(entry) {
|
|
32
|
+
return !/[/\\?#@]/.test(entry) && hostnameOf(entry.trim()) !== undefined;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 请求的 Host 能不能收:主机名是 IP 地址、localhost 或 names 里的一个(监听地址与 allowedHosts)。DNS 重绑定的网页把自己的
|
|
36
|
+
* 域名解析到本机后,借 owner 的浏览器发来的请求 Origin 与 Host 都是那个域名,同源判定拦不住,靠这一关拦下;
|
|
37
|
+
* IP 地址重绑定不了,局域网按 IP 访问照常。
|
|
38
|
+
*/
|
|
39
|
+
function hostAllowed(req, names) {
|
|
40
|
+
const name = req.headers.host === undefined ? undefined : hostnameOf(req.headers.host);
|
|
41
|
+
if (name === undefined)
|
|
42
|
+
return false;
|
|
43
|
+
return name === 'localhost' || isIP(name.replace(/^\[(.*)\]$/, '$1')) !== 0 || names.has(name);
|
|
44
|
+
}
|
|
19
45
|
/** 不改状态的请求方法:不校验来源 */
|
|
20
46
|
const SAFE_METHODS = new Set(['GET', 'HEAD', 'OPTIONS']);
|
|
21
47
|
/**
|
|
@@ -70,14 +96,15 @@ function buildClearCookie(name) {
|
|
|
70
96
|
}
|
|
71
97
|
/** 登录页的脚本:文档级 CSP 只许同源脚本,不内联,由这个地址给出(不需登录) */
|
|
72
98
|
const LOGIN_SCRIPT_PATH = '/api/auth/login.js';
|
|
73
|
-
/** 提交 POST /api/auth/login,成功后刷新到
|
|
74
|
-
const LOGIN_SCRIPT = `const
|
|
99
|
+
/** 提交 POST /api/auth/login,成功后刷新到 /;给人看的文字取自页面的 texts 块 */
|
|
100
|
+
const LOGIN_SCRIPT = `const T=JSON.parse(document.getElementById('texts').textContent);
|
|
101
|
+
const f=document.getElementById('f'),t=document.getElementById('t'),b=document.getElementById('b'),e=document.getElementById('e');
|
|
75
102
|
f.addEventListener('submit',async ev=>{
|
|
76
103
|
ev.preventDefault();e.textContent='';b.disabled=true;
|
|
77
104
|
try{
|
|
78
105
|
const r=await fetch('/api/auth/login',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({token:t.value.trim()})});
|
|
79
|
-
if(r.ok){location.replace('/');}else{const j=await r.json().catch(()=>({}));e.textContent=j.error||
|
|
80
|
-
}catch(err){e.textContent=
|
|
106
|
+
if(r.ok){location.replace('/');}else{const j=await r.json().catch(()=>({}));e.textContent=j.error||T.tokenWrong;b.disabled=false;t.select();}
|
|
107
|
+
}catch(err){e.textContent=T.networkError;b.disabled=false;}
|
|
81
108
|
});
|
|
82
109
|
`;
|
|
83
110
|
/** 一个内置主题的颜色令牌,写成 CSS 自定义属性的声明 */
|
|
@@ -102,44 +129,55 @@ button{height:2.25rem;font:inherit;font-weight:500;color:var(--color-on-accent);
|
|
|
102
129
|
button:hover{background:var(--color-accent-hover)}
|
|
103
130
|
button:disabled{opacity:0.6;cursor:wait}
|
|
104
131
|
.err{min-height:1.375rem;color:var(--color-danger-text)}`;
|
|
105
|
-
/**
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
132
|
+
/** 登录页的文字;pageLanguage 是渲染时实际用的语言,写进 <html lang> */
|
|
133
|
+
const LOGIN_TEXTS = {
|
|
134
|
+
lang: t('pageLanguage'),
|
|
135
|
+
title: t('loginTitle'),
|
|
136
|
+
hint: t('loginHint'),
|
|
137
|
+
placeholder: t('tokenPlaceholder'),
|
|
138
|
+
button: t('loginButton'),
|
|
139
|
+
script: { tokenWrong: t('tokenWrong'), networkError: t('networkError') },
|
|
140
|
+
};
|
|
141
|
+
/** 登录页:只引用同源的登录脚本,不引入别的资源。text 是渲染过的文字,note 是这次要说明的一句 */
|
|
142
|
+
function loginPageHtml(text) {
|
|
143
|
+
const note = text.note ? `<p class="note">${escapeHtml(text.note)}</p>` : '';
|
|
144
|
+
return `<!DOCTYPE html><html lang="${escapeHtml(text.lang)}"><head>
|
|
145
|
+
<meta charset="utf-8"><title>${escapeHtml(text.title)}</title>
|
|
110
146
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
111
147
|
<style>
|
|
112
148
|
${LOGIN_STYLE}
|
|
113
149
|
</style></head>
|
|
114
150
|
<body><form id="f">
|
|
115
151
|
<h1>Aalis WebUI</h1>
|
|
116
|
-
<p
|
|
152
|
+
<p>${escapeHtml(text.hint)}</p>
|
|
117
153
|
${note}
|
|
118
|
-
<input id="t" type="password" autocomplete="off" placeholder="
|
|
119
|
-
<button type="submit" id="b"
|
|
154
|
+
<input id="t" type="password" autocomplete="off" placeholder="${escapeHtml(text.placeholder)}" autofocus required>
|
|
155
|
+
<button type="submit" id="b">${escapeHtml(text.button)}</button>
|
|
120
156
|
<div class="err" id="e"></div>
|
|
121
157
|
</form>
|
|
158
|
+
${textsBlock(text.script)}
|
|
122
159
|
<script src="${LOGIN_SCRIPT_PATH}"></script></body></html>`;
|
|
123
160
|
}
|
|
124
|
-
function escapeHtml(s) {
|
|
125
|
-
return s.replace(/[&<>"']/g, c => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' })[c]);
|
|
126
|
-
}
|
|
127
161
|
/**
|
|
128
162
|
* 创建单 token 认证系统(单 owner)。
|
|
129
163
|
*
|
|
130
164
|
* - token 由调用方经 getToken 提供,每次校验现取:persist 模式下 storage 晚上线时,调用方会把
|
|
131
165
|
* 启动时的临时 token 换成读回的持久化 token(见 index.ts 的 token 解析)
|
|
132
166
|
* - HttpOnly + SameSite=Strict cookie;`?token=` 一键登录;同源 POST /api/auth/login 提交
|
|
167
|
+
* - 请求的 Host 先按 {@link hostAllowed} 核对,hostNames 是 IP 地址与 localhost 之外认的主机名(监听地址与 allowedHosts);
|
|
168
|
+
* 不认的回 421,不进登录的比对与计数,带着 cookie 也不放行
|
|
133
169
|
* - 改状态的请求(非 GET、HEAD、OPTIONS)按 {@link originAllowed} 校验来源,与 WebSocket 升级同一个判定:SameSite 按站判、
|
|
134
170
|
* 不分端口,同一主机别的端口上的网页发一个简单 POST 就会带上 cookie
|
|
135
171
|
* - `?token=` 与登录接口按来源地址限速:失败计数见 LOGIN_MAX_FAILURES、LOGIN_FAILURE_WINDOW_MS,成功清零。
|
|
136
|
-
* 别的网页借 owner 的浏览器发起的登录(跨源的 POST、别的站点打开的 `?token
|
|
172
|
+
* 别的网页借 owner 的浏览器发起的登录(跨源的 POST、别的站点打开的 `?token=`、DNS 重绑定)不比对也不计数,免得别人替 owner 把
|
|
137
173
|
* 地址锁住。带 cookie 的请求不计数:各种模式的 token 都够长(随机生成的 24 字节,固定的至少 32 个字符),
|
|
138
174
|
* 按 cookie 逐个猜猜不中;对 cookie 也锁定的话,共用一个来源地址(同一个反向代理)的已登录页面会被别人一起锁住
|
|
139
175
|
* - 身份恒为 `webui:console`(owner 级,单人模式语义)
|
|
176
|
+
* - 登录页与回应里的文字按全局层的语言(localizer)
|
|
140
177
|
*/
|
|
141
|
-
export function createAuthSystem(getToken) {
|
|
178
|
+
export function createAuthSystem(getToken, localizer, hostNames) {
|
|
142
179
|
const cookieMaxAge = 30 * 24 * 3600; // 30d;进程重启 token 轮换后无效
|
|
180
|
+
const names = new Set(hostNames.flatMap(name => hostnameOf(name.trim()) ?? []));
|
|
143
181
|
// 登录失败按来源地址计数。本机回环也计数:经同机反向代理来的请求全是回环地址,豁免回环等于不限速;
|
|
144
182
|
// owner 自己输错满额也只等到窗口结束,已登录的页面不受影响。
|
|
145
183
|
// 时间取单调时钟,键的插入顺序就是窗口结束的先后,过期的从表头剪掉;表满时也从表头丢,最多 LOGIN_FAILURE_ADDRESSES_MAX 条。
|
|
@@ -170,7 +208,12 @@ export function createAuthSystem(getToken) {
|
|
|
170
208
|
function rejectLocked(res, waitMs) {
|
|
171
209
|
res.status(429);
|
|
172
210
|
res.setHeader('Retry-After', String(Math.ceil(waitMs / 1000)));
|
|
173
|
-
return
|
|
211
|
+
return t('tooManyFailures', { minutes: Math.ceil(waitMs / 60_000) });
|
|
212
|
+
}
|
|
213
|
+
/** 登录页,note 是要说明的一句 */
|
|
214
|
+
function loginPage(note) {
|
|
215
|
+
const text = localizer.render({ ...LOGIN_TEXTS, note });
|
|
216
|
+
return loginPageHtml({ ...text, lang: pageLanguageOf(text.lang, localizer.languages()) });
|
|
174
217
|
}
|
|
175
218
|
function tokenAuthed(req) {
|
|
176
219
|
const cookieToken = parseCookieValue(req.headers.cookie, TOKEN_COOKIE);
|
|
@@ -181,13 +224,17 @@ export function createAuthSystem(getToken) {
|
|
|
181
224
|
}
|
|
182
225
|
const addressOf = (req) => req.socket.remoteAddress ?? '';
|
|
183
226
|
function install(expressApp) {
|
|
184
|
-
//
|
|
227
|
+
// 先核 Host:DNS 重绑定的网页发来的请求在这里拦下
|
|
228
|
+
expressApp.use((req, res, next) => {
|
|
229
|
+
if (hostAllowed(req, names))
|
|
230
|
+
return next();
|
|
231
|
+
res.status(421).json({ error: t('hostNotAllowed') });
|
|
232
|
+
});
|
|
233
|
+
// 改状态的请求再看来源:别的网页借 owner 的浏览器发来的(带着 cookie)一律拒,登录与注销也一样
|
|
185
234
|
expressApp.use((req, res, next) => {
|
|
186
235
|
if (SAFE_METHODS.has(req.method) || originAllowed(req))
|
|
187
236
|
return next();
|
|
188
|
-
res
|
|
189
|
-
.status(403)
|
|
190
|
-
.json({ error: '请求来源与本服务不同源(经反向代理访问时,代理要转发原始的 Host)' });
|
|
237
|
+
res.status(403).json({ error: t('crossOrigin') });
|
|
191
238
|
});
|
|
192
239
|
// 登录页的脚本不需登录
|
|
193
240
|
route(expressApp, 'GET /api/auth/login.js', (_req, res) => {
|
|
@@ -203,7 +250,7 @@ export function createAuthSystem(getToken) {
|
|
|
203
250
|
const waitMs = lockedFor(address);
|
|
204
251
|
if (waitMs > 0) {
|
|
205
252
|
const note = rejectLocked(res, waitMs);
|
|
206
|
-
res.type('html').send(
|
|
253
|
+
res.type('html').send(loginPage(note));
|
|
207
254
|
return;
|
|
208
255
|
}
|
|
209
256
|
const token = getToken();
|
|
@@ -217,7 +264,10 @@ export function createAuthSystem(getToken) {
|
|
|
217
264
|
return;
|
|
218
265
|
}
|
|
219
266
|
recordFailure(address);
|
|
220
|
-
res
|
|
267
|
+
res
|
|
268
|
+
.status(401)
|
|
269
|
+
.type('html')
|
|
270
|
+
.send(loginPage(t('urlTokenWrong')));
|
|
221
271
|
});
|
|
222
272
|
// 登录:{ token }。跨源的已在上面拒掉,不计数
|
|
223
273
|
route(expressApp, 'POST /api/auth/login', (req, res) => {
|
|
@@ -236,7 +286,7 @@ export function createAuthSystem(getToken) {
|
|
|
236
286
|
}
|
|
237
287
|
else {
|
|
238
288
|
recordFailure(address);
|
|
239
|
-
res.status(401).json({ error: '
|
|
289
|
+
res.status(401).json({ error: t('tokenWrong') });
|
|
240
290
|
}
|
|
241
291
|
});
|
|
242
292
|
// 登录状态(含当前身份,供前端顶栏展示)
|
|
@@ -254,11 +304,11 @@ export function createAuthSystem(getToken) {
|
|
|
254
304
|
if (tokenAuthed(req))
|
|
255
305
|
return next();
|
|
256
306
|
if (req.path.startsWith('/api/')) {
|
|
257
|
-
res.status(401).json({ error: 'unauthenticated' });
|
|
307
|
+
res.status(401).json({ error: t('unauthenticated') });
|
|
258
308
|
return;
|
|
259
309
|
}
|
|
260
310
|
if (req.method === 'GET') {
|
|
261
|
-
res.status(401).type('html').send(
|
|
311
|
+
res.status(401).type('html').send(loginPage());
|
|
262
312
|
return;
|
|
263
313
|
}
|
|
264
314
|
res.status(401).end();
|
package/dist/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,27 @@
|
|
|
1
|
+
import type { Localized } from '@aalis/schema-i18n';
|
|
1
2
|
/** 前端切换恢复页的脚本:文档级 CSP 只许同源脚本,由 `/__clients.js` 给出 */
|
|
2
|
-
export declare const CLIENT_SWITCH_SCRIPT = "(function () {\n var SVC = 'webui-client';\n var PREFER = '/api/services/' + SVC + '/prefer';\n var sel = document.getElementById('client');\n var btn = document.getElementById('go');\n var msg = document.getElementById('msg');\n function setMsg(t, err) { msg.textContent = t; msg.className = err ? 'err' : 'ok'; }\n function load() {\n fetch('/api/services', { headers: { Accept: 'application/json' } })\n .then(function (r) {\n if (!r.ok) throw new Error(
|
|
3
|
-
/**
|
|
4
|
-
export declare
|
|
3
|
+
export declare const CLIENT_SWITCH_SCRIPT = "(function () {\n var SVC = 'webui-client';\n var PREFER = '/api/services/' + SVC + '/prefer';\n var T = JSON.parse(document.getElementById('texts').textContent);\n var sel = document.getElementById('client');\n var btn = document.getElementById('go');\n var msg = document.getElementById('msg');\n function fill(text, values) {\n return text.replace(/\\{(\\w+)\\}/g, function (m, k) { return k in values ? String(values[k]) : m; });\n }\n function setMsg(t, err) { msg.textContent = t; msg.className = err ? 'err' : 'ok'; }\n function load() {\n fetch('/api/services', { headers: { Accept: 'application/json' } })\n .then(function (r) {\n if (!r.ok) throw new Error(fill(T.listFailed, { status: r.status }));\n return r.json();\n })\n .then(function (data) {\n var svc = data && data.services && data.services[SVC];\n var providers = (svc && svc.providers) || [];\n if (!providers.length) {\n setMsg(T.noClients, true);\n btn.disabled = true;\n sel.innerHTML = '';\n return;\n }\n var active = (svc && svc.preferred) || providers[0].contextId;\n sel.innerHTML = '';\n providers.forEach(function (p) {\n var o = document.createElement('option');\n var name = p.displayName || p.label || p.contextId;\n o.value = p.contextId;\n o.textContent = p.contextId === active ? fill(T.current, { name: name }) : name;\n if (p.contextId === active) o.selected = true;\n sel.appendChild(o);\n });\n })\n .catch(function (e) { setMsg(String((e && e.message) || e), true); });\n }\n btn.addEventListener('click', function () {\n var contextId = sel.value;\n if (!contextId) return;\n btn.disabled = true;\n setMsg(T.switching, false);\n fetch(PREFER, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ contextId: contextId })\n })\n .then(function (r) {\n if (r.ok) { setMsg(T.switched, false); location.href = '/'; return; }\n return r.json().catch(function () { return {}; }).then(function (j) {\n var detail = (j && j.error) || ('HTTP ' + r.status);\n var hint = (r.status === 401 || r.status === 403) ? T.ownerHint : '';\n setMsg(fill(T.failed, { detail: detail, hint: hint }), true);\n btn.disabled = false;\n });\n })\n .catch(function (e) { setMsg(fill(T.error, { error: String((e && e.message) || e) }), true); btn.disabled = false; });\n });\n load();\n})();\n";
|
|
4
|
+
/** 恢复页的文字;带参数的以 {名} 占位交给脚本填。pageLanguage 是渲染时实际用的语言,写进 <html lang> */
|
|
5
|
+
export declare const CLIENT_SWITCH_TEXTS: {
|
|
6
|
+
lang: import("@aalis/schema-i18n").TextRef;
|
|
7
|
+
title: import("@aalis/schema-i18n").TextRef;
|
|
8
|
+
heading: import("@aalis/schema-i18n").TextRef;
|
|
9
|
+
intro: import("@aalis/schema-i18n").TextRef;
|
|
10
|
+
label: import("@aalis/schema-i18n").TextRef;
|
|
11
|
+
loading: import("@aalis/schema-i18n").TextRef;
|
|
12
|
+
button: import("@aalis/schema-i18n").TextRef;
|
|
13
|
+
back: import("@aalis/schema-i18n").TextRef;
|
|
14
|
+
script: {
|
|
15
|
+
listFailed: import("@aalis/schema-i18n").TextRef;
|
|
16
|
+
noClients: import("@aalis/schema-i18n").TextRef;
|
|
17
|
+
current: import("@aalis/schema-i18n").TextRef;
|
|
18
|
+
switching: import("@aalis/schema-i18n").TextRef;
|
|
19
|
+
switched: import("@aalis/schema-i18n").TextRef;
|
|
20
|
+
ownerHint: import("@aalis/schema-i18n").TextRef;
|
|
21
|
+
failed: import("@aalis/schema-i18n").TextRef;
|
|
22
|
+
error: import("@aalis/schema-i18n").TextRef;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
/** 渲染前端切换恢复页的完整 HTML 文档:text 是渲染过的文字,数据由页面自身 fetch */
|
|
26
|
+
export declare function renderClientSwitchPage(text: Localized<typeof CLIENT_SWITCH_TEXTS>): string;
|
|
5
27
|
//# sourceMappingURL=client-switch-page.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-switch-page.d.ts","sourceRoot":"","sources":["../src/client-switch-page.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client-switch-page.d.ts","sourceRoot":"","sources":["../src/client-switch-page.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAIpD,qDAAqD;AACrD,eAAO,MAAM,oBAAoB,sjFA8DhC,CAAC;AAEF,sEAAsE;AACtE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;CAmB/B,CAAC;AAEF,sDAAsD;AACtD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,mBAAmB,CAAC,GAAG,MAAM,CAmC1F"}
|
|
@@ -8,26 +8,33 @@
|
|
|
8
8
|
// · 列表:GET /api/services (取 webui-client 服务的 providers + preferred)
|
|
9
9
|
// · 切换:POST /api/services/webui-client/prefer (owner 闸,body {contextId})
|
|
10
10
|
// 全局 auth 中间件已要求登录方可到达本路由(未认证 GET 直接回登录页),故本页无需自加 gate;
|
|
11
|
-
// 切换动作仍受既有 owner 闸约束。抽成纯函数仅为便于单测——route
|
|
11
|
+
// 切换动作仍受既有 owner 闸约束。抽成纯函数仅为便于单测——route 按全局层的语言渲染文字后交给它。
|
|
12
|
+
// 文字按全局层的语言:页面上的在服务端写进 HTML,脚本要的放进 texts 块,带参数的留着 {名} 占位,由脚本填(见 html.ts)。
|
|
13
|
+
import { escapeHtml, textsBlock } from './html.js';
|
|
14
|
+
import { t } from './texts.js';
|
|
12
15
|
/** 前端切换恢复页的脚本:文档级 CSP 只许同源脚本,由 `/__clients.js` 给出 */
|
|
13
16
|
export const CLIENT_SWITCH_SCRIPT = `(function () {
|
|
14
17
|
var SVC = 'webui-client';
|
|
15
18
|
var PREFER = '/api/services/' + SVC + '/prefer';
|
|
19
|
+
var T = JSON.parse(document.getElementById('texts').textContent);
|
|
16
20
|
var sel = document.getElementById('client');
|
|
17
21
|
var btn = document.getElementById('go');
|
|
18
22
|
var msg = document.getElementById('msg');
|
|
23
|
+
function fill(text, values) {
|
|
24
|
+
return text.replace(/\\{(\\w+)\\}/g, function (m, k) { return k in values ? String(values[k]) : m; });
|
|
25
|
+
}
|
|
19
26
|
function setMsg(t, err) { msg.textContent = t; msg.className = err ? 'err' : 'ok'; }
|
|
20
27
|
function load() {
|
|
21
28
|
fetch('/api/services', { headers: { Accept: 'application/json' } })
|
|
22
29
|
.then(function (r) {
|
|
23
|
-
if (!r.ok) throw new Error(
|
|
30
|
+
if (!r.ok) throw new Error(fill(T.listFailed, { status: r.status }));
|
|
24
31
|
return r.json();
|
|
25
32
|
})
|
|
26
33
|
.then(function (data) {
|
|
27
34
|
var svc = data && data.services && data.services[SVC];
|
|
28
35
|
var providers = (svc && svc.providers) || [];
|
|
29
36
|
if (!providers.length) {
|
|
30
|
-
setMsg(
|
|
37
|
+
setMsg(T.noClients, true);
|
|
31
38
|
btn.disabled = true;
|
|
32
39
|
sel.innerHTML = '';
|
|
33
40
|
return;
|
|
@@ -36,8 +43,9 @@ export const CLIENT_SWITCH_SCRIPT = `(function () {
|
|
|
36
43
|
sel.innerHTML = '';
|
|
37
44
|
providers.forEach(function (p) {
|
|
38
45
|
var o = document.createElement('option');
|
|
46
|
+
var name = p.displayName || p.label || p.contextId;
|
|
39
47
|
o.value = p.contextId;
|
|
40
|
-
o.textContent =
|
|
48
|
+
o.textContent = p.contextId === active ? fill(T.current, { name: name }) : name;
|
|
41
49
|
if (p.contextId === active) o.selected = true;
|
|
42
50
|
sel.appendChild(o);
|
|
43
51
|
});
|
|
@@ -48,34 +56,55 @@ export const CLIENT_SWITCH_SCRIPT = `(function () {
|
|
|
48
56
|
var contextId = sel.value;
|
|
49
57
|
if (!contextId) return;
|
|
50
58
|
btn.disabled = true;
|
|
51
|
-
setMsg(
|
|
59
|
+
setMsg(T.switching, false);
|
|
52
60
|
fetch(PREFER, {
|
|
53
61
|
method: 'POST',
|
|
54
62
|
headers: { 'Content-Type': 'application/json' },
|
|
55
63
|
body: JSON.stringify({ contextId: contextId })
|
|
56
64
|
})
|
|
57
65
|
.then(function (r) {
|
|
58
|
-
if (r.ok) { setMsg(
|
|
66
|
+
if (r.ok) { setMsg(T.switched, false); location.href = '/'; return; }
|
|
59
67
|
return r.json().catch(function () { return {}; }).then(function (j) {
|
|
60
68
|
var detail = (j && j.error) || ('HTTP ' + r.status);
|
|
61
|
-
var hint = (r.status === 401 || r.status === 403) ?
|
|
62
|
-
setMsg(
|
|
69
|
+
var hint = (r.status === 401 || r.status === 403) ? T.ownerHint : '';
|
|
70
|
+
setMsg(fill(T.failed, { detail: detail, hint: hint }), true);
|
|
63
71
|
btn.disabled = false;
|
|
64
72
|
});
|
|
65
73
|
})
|
|
66
|
-
.catch(function (e) { setMsg(
|
|
74
|
+
.catch(function (e) { setMsg(fill(T.error, { error: String((e && e.message) || e) }), true); btn.disabled = false; });
|
|
67
75
|
});
|
|
68
76
|
load();
|
|
69
77
|
})();
|
|
70
78
|
`;
|
|
71
|
-
/**
|
|
72
|
-
export
|
|
79
|
+
/** 恢复页的文字;带参数的以 {名} 占位交给脚本填。pageLanguage 是渲染时实际用的语言,写进 <html lang> */
|
|
80
|
+
export const CLIENT_SWITCH_TEXTS = {
|
|
81
|
+
lang: t('pageLanguage'),
|
|
82
|
+
title: t('switchTitle'),
|
|
83
|
+
heading: t('switchHeading'),
|
|
84
|
+
intro: t('switchIntro'),
|
|
85
|
+
label: t('switchLabel'),
|
|
86
|
+
loading: t('switchLoading'),
|
|
87
|
+
button: t('switchButton'),
|
|
88
|
+
back: t('switchBack'),
|
|
89
|
+
script: {
|
|
90
|
+
listFailed: t('switchListFailed', { status: '{status}' }),
|
|
91
|
+
noClients: t('switchNoClients'),
|
|
92
|
+
current: t('switchCurrent', { name: '{name}' }),
|
|
93
|
+
switching: t('switching'),
|
|
94
|
+
switched: t('switched'),
|
|
95
|
+
ownerHint: t('switchOwnerHint'),
|
|
96
|
+
failed: t('switchFailed', { detail: '{detail}', hint: '{hint}' }),
|
|
97
|
+
error: t('switchError', { error: '{error}' }),
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
/** 渲染前端切换恢复页的完整 HTML 文档:text 是渲染过的文字,数据由页面自身 fetch */
|
|
101
|
+
export function renderClientSwitchPage(text) {
|
|
73
102
|
return `<!doctype html>
|
|
74
|
-
<html lang="
|
|
103
|
+
<html lang="${escapeHtml(text.lang)}">
|
|
75
104
|
<head>
|
|
76
105
|
<meta charset="utf-8" />
|
|
77
106
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
78
|
-
<title
|
|
107
|
+
<title>${escapeHtml(text.title)}</title>
|
|
79
108
|
<style>
|
|
80
109
|
:root { color-scheme: light dark; }
|
|
81
110
|
body { font: 15px/1.6 system-ui, -apple-system, sans-serif; max-width: 32rem; margin: 8vh auto; padding: 0 1.2rem; }
|
|
@@ -93,13 +122,14 @@ export function renderClientSwitchPage() {
|
|
|
93
122
|
</style>
|
|
94
123
|
</head>
|
|
95
124
|
<body>
|
|
96
|
-
<h1
|
|
97
|
-
<p class="hint"
|
|
98
|
-
<label for="client"
|
|
99
|
-
<select id="client"><option
|
|
100
|
-
<button id="go" type="button"
|
|
125
|
+
<h1>${escapeHtml(text.heading)}</h1>
|
|
126
|
+
<p class="hint">${escapeHtml(text.intro)}</p>
|
|
127
|
+
<label for="client">${escapeHtml(text.label)}</label>
|
|
128
|
+
<select id="client"><option>${escapeHtml(text.loading)}</option></select>
|
|
129
|
+
<button id="go" type="button">${escapeHtml(text.button)}</button>
|
|
101
130
|
<div id="msg"></div>
|
|
102
|
-
<p class="hint"
|
|
131
|
+
<p class="hint">${escapeHtml(text.back)}</p>
|
|
132
|
+
${textsBlock(text.script)}
|
|
103
133
|
<script src="/__clients.js"></script>
|
|
104
134
|
</body>
|
|
105
135
|
</html>`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-switch-page.js","sourceRoot":"","sources":["../src/client-switch-page.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,gDAAgD;AAChD,wDAAwD;AACxD,8DAA8D;AAC9D,EAAE;AACF,yEAAyE;AACzE,6FAA6F;AAC7F,8EAA8E;AAC9E,wDAAwD;AACxD,
|
|
1
|
+
{"version":3,"file":"client-switch-page.js","sourceRoot":"","sources":["../src/client-switch-page.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,gDAAgD;AAChD,wDAAwD;AACxD,8DAA8D;AAC9D,EAAE;AACF,yEAAyE;AACzE,6FAA6F;AAC7F,8EAA8E;AAC9E,wDAAwD;AACxD,yDAAyD;AACzD,0EAA0E;AAG1E,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAE/B,qDAAqD;AACrD,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8DnC,CAAC;AAEF,sEAAsE;AACtE,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,IAAI,EAAE,CAAC,CAAC,cAAc,CAAC;IACvB,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC;IACvB,OAAO,EAAE,CAAC,CAAC,eAAe,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC;IACvB,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC;IACvB,OAAO,EAAE,CAAC,CAAC,eAAe,CAAC;IAC3B,MAAM,EAAE,CAAC,CAAC,cAAc,CAAC;IACzB,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC;IACrB,MAAM,EAAE;QACN,UAAU,EAAE,CAAC,CAAC,kBAAkB,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;QACzD,SAAS,EAAE,CAAC,CAAC,iBAAiB,CAAC;QAC/B,OAAO,EAAE,CAAC,CAAC,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC/C,SAAS,EAAE,CAAC,CAAC,WAAW,CAAC;QACzB,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC;QACvB,SAAS,EAAE,CAAC,CAAC,iBAAiB,CAAC;QAC/B,MAAM,EAAE,CAAC,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QACjE,KAAK,EAAE,CAAC,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;KAC9C;CACF,CAAC;AAEF,sDAAsD;AACtD,MAAM,UAAU,sBAAsB,CAAC,IAA2C;IAChF,OAAO;cACK,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;;;;SAI1B,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;QAkBvB,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;oBACZ,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;wBAClB,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;gCACd,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;kCACtB,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;;oBAErC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;EACvC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;;;QAGjB,CAAC;AACT,CAAC"}
|
package/dist/gate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../src/gate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../src/gate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzD,gDAAgD;AAChD,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE;IAAE,OAAO,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,KAAK,YAAY,GAAG,SAAS,CAAC;AAKtF,UAAU,WAAW;IACnB,OAAO,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9B;AACD,UAAU,YAAY;IACpB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;KAAE,CAAC;CACxD;AACD,KAAK,cAAc,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;AAEtF;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,UAAU,SACvC,cAAc,CAO1B;AAED,kDAAkD;AAClD,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC"}
|
package/dist/gate.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { t } from './texts.js';
|
|
1
2
|
/**
|
|
2
3
|
* REST 路由 owner 闸工厂(单 owner 终态)。
|
|
3
4
|
*
|
|
@@ -12,7 +13,7 @@
|
|
|
12
13
|
export function createRouteGate(identify) {
|
|
13
14
|
return () => (req, res, next) => {
|
|
14
15
|
if (!identify(req)) {
|
|
15
|
-
res.status(403).json({ error: '
|
|
16
|
+
res.status(403).json({ error: t('ownerRequired') });
|
|
16
17
|
return;
|
|
17
18
|
}
|
|
18
19
|
next();
|