ework-web 0.10.29 → 0.10.30
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/package.json +1 -1
- package/src/auth.ts +11 -1
- package/src/config.ts +2 -0
- package/src/index.ts +3 -3
package/package.json
CHANGED
package/src/auth.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Config } from "./config";
|
|
2
2
|
import { getUserByLogin, ensureUser, verifyPat, type UserRow } from "./store";
|
|
3
3
|
import { runAuthHook } from "./auth-hook";
|
|
4
|
+
import { readFileSync, existsSync } from "fs";
|
|
4
5
|
|
|
5
6
|
// Per-user token-cookie auth. Cookie value is HMAC-signed and carries login +
|
|
6
7
|
// issued-at, so the server is stateless (no session table). Two cookie formats
|
|
@@ -191,7 +192,16 @@ function esc(s: string): string {
|
|
|
191
192
|
.replace(/"/g, """);
|
|
192
193
|
}
|
|
193
194
|
|
|
194
|
-
export function loginHTML(next: string, error?: string): string {
|
|
195
|
+
export function loginHTML(next: string, error?: string, cfg?: Config): string {
|
|
196
|
+
if (cfg?.loginPage && existsSync(cfg.loginPage)) {
|
|
197
|
+
try {
|
|
198
|
+
const tpl = readFileSync(cfg.loginPage, "utf-8");
|
|
199
|
+
return tpl
|
|
200
|
+
.replace(/\{\{next\}\}/g, esc(sanitizeNext(next)))
|
|
201
|
+
.replace(/\{\{error\}\}/g, error ? esc(error) : "");
|
|
202
|
+
} catch {
|
|
203
|
+
}
|
|
204
|
+
}
|
|
195
205
|
const err = error ? `<div class="err">${esc(error)}</div>` : "";
|
|
196
206
|
return `<!doctype html><html lang="zh"><head><meta charset="utf-8">
|
|
197
207
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
package/src/config.ts
CHANGED
|
@@ -81,6 +81,7 @@ export const configSchema = z.object({
|
|
|
81
81
|
routerAdminToken: z.string().default(""),
|
|
82
82
|
internalAuthHook: z.string().default(""),
|
|
83
83
|
userAuthHook: z.string().default(""),
|
|
84
|
+
loginPage: z.string().default(""),
|
|
84
85
|
// Default "provider/model" string passed to `opencode run --model <X>`.
|
|
85
86
|
// Empty = let opencode pick per its own opencode.json + env. ework-daemon
|
|
86
87
|
// pushes this (or the per-project override) on every spawn to defend
|
|
@@ -183,6 +184,7 @@ export async function loadConfig(): Promise<Config> {
|
|
|
183
184
|
routerAdminToken: process.env.WORK_ROUTER_ADMIN_TOKEN ?? "",
|
|
184
185
|
internalAuthHook: process.env.WORK_INTERNAL_AUTH_HOOK ?? "",
|
|
185
186
|
userAuthHook: process.env.WORK_USER_AUTH_HOOK ?? "",
|
|
187
|
+
loginPage: process.env.WORK_LOGIN_PAGE ?? "",
|
|
186
188
|
defaultModel: db.defaultModel ?? process.env.WORK_DEFAULT_MODEL,
|
|
187
189
|
autowireActive: process.env.WORK_AUTOWIRE_ACTIVE !== "false",
|
|
188
190
|
webhookMaxConcurrent: Number(process.env.WORK_WEBHOOK_MAX_CONCURRENT ?? "6"),
|
package/src/index.ts
CHANGED
|
@@ -481,7 +481,7 @@ async function handle(req: Request, url: URL, ip: string, ctx: { authed: boolean
|
|
|
481
481
|
const form = await req.formData().catch(() => new FormData());
|
|
482
482
|
const next = sanitizeNext(String(form.get("next") ?? "/"));
|
|
483
483
|
if (!rateLimit(`login:${ip}`, 5, 5 / (15 * 60))) {
|
|
484
|
-
return html(loginHTML(next, "尝试过多,15 分钟后再试"), 429);
|
|
484
|
+
return html(loginHTML(next, "尝试过多,15 分钟后再试", cfg), 429);
|
|
485
485
|
}
|
|
486
486
|
const login = String(form.get("login") ?? "").trim();
|
|
487
487
|
const password = String(form.get("password") ?? "");
|
|
@@ -516,10 +516,10 @@ async function handle(req: Request, url: URL, ip: string, ctx: { authed: boolean
|
|
|
516
516
|
: login || password
|
|
517
517
|
? "用户名或密码错误"
|
|
518
518
|
: "请填写用户名密码或共享 token";
|
|
519
|
-
return html(loginHTML(next, err), 401);
|
|
519
|
+
return html(loginHTML(next, err, cfg), 401);
|
|
520
520
|
}
|
|
521
521
|
const next = sanitizeNext(url.searchParams.get("next") ?? "/");
|
|
522
|
-
return html(loginHTML(next));
|
|
522
|
+
return html(loginHTML(next, undefined, cfg));
|
|
523
523
|
}
|
|
524
524
|
|
|
525
525
|
if (url.pathname === "/logout" && req.method === "POST") {
|