From 07cc7f51b5841855990965f68f06789bcd4a4bf6 Mon Sep 17 00:00:00 2001 From: uncle6me-web Date: Sat, 8 Aug 2026 20:47:32 +0800 Subject: [PATCH] =?UTF-8?q?fix(cypher):=20=E5=90=8C=E4=B8=80=E5=8F=B0?= =?UTF-8?q?=E5=AF=A6=E4=BE=8B=E7=9A=84=20portal=20=E4=B8=80=E5=BE=8B?= =?UTF-8?q?=E8=87=AA=E5=8B=95=E6=94=BE=E8=A1=8C=EF=BC=8C=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E4=BE=9D=E8=B3=B4=20UI=5FORIGINS=20=E8=A2=AB=E6=B3=A8=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2026-08-08 事故根因:leo 的 youlin 實例登入整個斷掉,瀏覽器實證 blocked by CORS policy: No 'Access-Control-Allow-Origin' header 真因=該台 UI_ORIGINS 沒被設。 同一天發生兩次同款:這些變數只有安裝器會注入,任何手動 wrangler deploy 就會漏掉,而漏掉時系統看起來完全正常(worker 上線、200、版本號對), 只有真人點下去才會發現。leo:「這麼危險的問題已經發生 2 次,不可以再有一次。」 ⇒ 治法不是「記得注入」,是讓它不需要被注入:portal 與 cypher 是同一個 workers.dev 子網域下的兄弟,位址推導得出來。少一個必須注入的變數, 就少一個會被漏掉的東西。UI_ORIGINS 仍有效(自訂網域用),只是不再是 「登得進去」的前提。 對照:改動前後 tsc 錯誤數同為 7(皆為既有、不在本檔)。 Co-Authored-By: Claude Opus 5 --- cypher-executor/src/index.ts | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/cypher-executor/src/index.ts b/cypher-executor/src/index.ts index 6d7a6bb..a61ede1 100644 --- a/cypher-executor/src/index.ts +++ b/cypher-executor/src/index.ts @@ -48,7 +48,28 @@ app.use('*', cors({ extra = String((c.env as Record).UI_ORIGINS || '') .split(',').map((s: string) => s.trim()).filter(Boolean); } catch { /* UI_ORIGINS 未設定=只用靜態白名單 */ } - return [...STATIC_ORIGINS, ...extra].includes(origin) ? origin : null; + + // 🔴 2026-08-08 事故根因修復:**同一台實例的 portal 一律自動放行,不再依賴注入**。 + // + // 那天發生什麼:leo 的 youlin 實例 portal 整個不能用——先是畫面頂端紅字 + // 「設定檔沒載入(config.js)」(UI worker 缺 WORKER_SUBDOMAIN),修好之後**登入仍然失敗**。 + // 瀏覽器 console 實證: + // Access to fetch at '…/portal/login' … blocked by CORS policy: + // No 'Access-Control-Allow-Origin' header is present + // 真因=這台的 `UI_ORIGINS` 沒被設。 + // + // 兩次同一個病:**這些變數只有安裝器那條路會注入,任何人手動 `wrangler deploy` 就會漏掉—— + // 而漏掉時系統看起來完全正常**(worker 上線、HTTP 200、版本號還是對的), + // 只有真人點下去才會發現。leo:「這麼危險的問題已經發生 2 次,不可以再有一次。」 + // + // ⇒ 治法不是「記得要注入」,是**讓它不需要被注入**: + // portal 與本 worker 是同一個 workers.dev 子網域下的兄弟,位址推導得出來。 + // **少一個必須注入的變數,就少一個會被漏掉的東西。** + // `UI_ORIGINS` 仍然有效(自訂網域/額外前端還是靠它),只是不再是「登得進去」的前提。 + const sub = String((c.env as Record).WORKER_SUBDOMAIN || '').trim(); + const sibling = sub ? [`https://arcrun-rag-ui.${sub}.workers.dev`] : []; + + return [...STATIC_ORIGINS, ...sibling, ...extra].includes(origin) ? origin : null; }, allowMethods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], allowHeaders: ['Content-Type', 'Authorization', 'X-Arcrun-API-Key'],