fix(auth-recipe): 回灌 telegram/line_notify/kbdb 種子,補 AuthInjectSpec.path(修 source/live 漂移)
issue #13 升級:根因不只 acr parts 殘留,是 auth-recipe-seeds.ts source 漏了 3 個 static_key auth recipe(telegram/line_notify/kbdb),但 prod KV 手動 seed 過 → 任何全新 self-hosted `POST /init/seed` 只 seed 23 個、漏 telegram → self-host(leo21c/mira)telegram_send 的 auth_service:'telegram' resolve 不到 → {{auth.bot_token}} 注入空 → telegram 發訊壞掉。 實測 smoking gun(2026-06-29): - prod cypher.arcrun.dev/auth-recipes = 27 個(含 telegram) - self-host arcrun-cypher-executor.leo21c.workers.dev = 23 個(無 telegram/line_notify/kbdb) 修法(資料/型別,非業務邏輯,守 mindset §1 不建 component): - auth-recipe-seeds.ts 補 telegram(inject.path bot_token)/line_notify(header Bearer)/kbdb(header Bearer) - recipes.ts AuthInjectSpec 補 path?(WASM auth_static_key + SDD §六早有此欄、source 介面漏 → tsc 擋) - google_user(oauth2)暫不回灌:內嵌 client_secret 不可進 git + 介面無 oauth2 欄 → 留 Phase D 形態取自 prod GET /auth-recipes/{service};設計權威 auth-recipe.md §六(telegram path)/§七(kbdb 共用)。 telegram 自此與 notion(header)/gsheets(service_account) 同一條 recipe+auth-recipe 鏈,一致。 tsc 全綠;local 模擬 token-in-path 注入 PASS。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,13 @@ import type { AuthRecipeDefinition } from '../routes/recipes';
|
||||
|
||||
const now = Date.now();
|
||||
|
||||
// ⚠️ 已知 source/live drift(2026-06-29 盤點,未在此檔修):
|
||||
// prod RECIPES KV 另有 `auth_recipe:google_user`(primitive: oauth2)。**故意不回灌 source**,原因:
|
||||
// (1) 它內嵌 client_secret(GOCSPX-...)= 機密,不可進 git(wiki-secret-scan / 一般安全);
|
||||
// (2) 本檔的 AuthRecipeDefinition 介面尚無 oauth2 欄位(client_id/secret/token_endpoint/scopes),
|
||||
// 回灌前需先擴 schema + 把 secret 改成部署期注入(wrangler secret / env),屬獨立工作。
|
||||
// → google_user 留待 oauth2 seed 機制(含 secret 注入)獨立處理;本次只修無機密的 static_key 漂移。
|
||||
|
||||
export const AUTH_RECIPE_SEEDS: AuthRecipeDefinition[] = [
|
||||
// ── Static Key 類 ──────────────────────────────────────────────────────────
|
||||
|
||||
@@ -556,6 +563,94 @@ export const AUTH_RECIPE_SEEDS: AuthRecipeDefinition[] = [
|
||||
updated_at: now,
|
||||
},
|
||||
|
||||
// ── 訊息 / URL-path 注入類(static_key)────────────────────────────────────
|
||||
//
|
||||
// 2026-06-29 補:以下三個 static_key auth recipe 一直存在於 prod RECIPES KV(手動 seed 過),
|
||||
// 但**從未進 source seed**(auth-recipe-seeds.ts)→ 任何全新 self-hosted `POST /init/seed`
|
||||
// 只會 seed 23 個、漏掉 telegram/line_notify/kbdb → self-host(mira/leo21c)的 telegram 發訊
|
||||
// 走不通(telegram_send 的 auth_service:'telegram' 找不到 auth recipe → {{auth.bot_token}} 注入空)。
|
||||
// 這正是「source vs live drift = 假綠」(總管反覆踩的同一類)。把 prod 現役定義回灌 source,
|
||||
// 讓 official 與 self-host 共用同一份種子。形態取自 prod GET /auth-recipes/{service}(2026-06-29)。
|
||||
// 設計權威:auth-recipe.md §六(line 70-71, telegram path 注入) + §七(line 150-151, kbdb 共用)。
|
||||
|
||||
{
|
||||
kind: 'auth_recipe',
|
||||
service: 'telegram',
|
||||
version: 1,
|
||||
primitive: 'static_key',
|
||||
base_url: 'https://api.telegram.org',
|
||||
display_name: 'Telegram Bot',
|
||||
description: 'Telegram Bot API — sendMessage 等(bot token 注入 URL path /bot{token}/)',
|
||||
required_secrets: [
|
||||
{
|
||||
key: 'telegram_bot_token',
|
||||
label: 'Bot Token(從 @BotFather 取得)',
|
||||
help: '在 Telegram 對 @BotFather 送 /newbot 建立 bot,取得格式為 123456:ABC... 的 token',
|
||||
help_url: 'https://core.telegram.org/bots/features#botfather',
|
||||
},
|
||||
],
|
||||
// path 注入:recipe:telegram_send 的 endpoint 用 {{auth.bot_token}} 從 _auth_path 取值
|
||||
// (auth_static_key WASM 解密後輸出 auth_path → auth-dispatcher 帶進 _auth_path
|
||||
// → makeRecipeRunner interpolate)。token 不落 header/query/body,符合 Telegram 的 URL-path 慣例。
|
||||
inject: {
|
||||
path: {
|
||||
bot_token: '{{secret.telegram_bot_token}}',
|
||||
},
|
||||
},
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
|
||||
{
|
||||
kind: 'auth_recipe',
|
||||
service: 'line_notify',
|
||||
version: 1,
|
||||
primitive: 'static_key',
|
||||
base_url: 'https://notify-api.line.me',
|
||||
display_name: 'LINE Notify',
|
||||
description: 'LINE Notify — 推播訊息(static_key Bearer)',
|
||||
required_secrets: [
|
||||
{
|
||||
key: 'line_token',
|
||||
label: 'LINE Notify Token',
|
||||
help: '至 https://notify-bot.line.me/my/ 發行個人存取權杖',
|
||||
help_url: 'https://notify-bot.line.me/my/',
|
||||
},
|
||||
],
|
||||
inject: {
|
||||
header: {
|
||||
Authorization: 'Bearer {{secret.line_token}}',
|
||||
},
|
||||
},
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
|
||||
{
|
||||
kind: 'auth_recipe',
|
||||
service: 'kbdb',
|
||||
version: 1,
|
||||
primitive: 'static_key',
|
||||
base_url: 'https://kbdb.finally.click',
|
||||
display_name: 'KBDB',
|
||||
description: 'KBDB partner API — block 讀寫(static_key Bearer)。kbdb_* recipe 共用此把 auth。',
|
||||
required_secrets: [
|
||||
{
|
||||
key: 'kbdb_api_key',
|
||||
label: 'KBDB API Key(至 arcrun 取統一 API Key 當 credential)',
|
||||
help: 'KBDB 採 Supabase 模式:要用 → 去 arcrun 取統一 API Key 當此 credential',
|
||||
help_url: 'https://arcrun.dev',
|
||||
},
|
||||
],
|
||||
inject: {
|
||||
header: {
|
||||
Authorization: 'Bearer {{secret.kbdb_api_key}}',
|
||||
},
|
||||
},
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
|
||||
// ── Service Account 類(Google 家族,共用同一份 service_account_json)────────
|
||||
|
||||
{
|
||||
|
||||
@@ -460,6 +460,11 @@ export interface AuthInjectSpec {
|
||||
header?: Record<string, string>; // e.g. { Authorization: "Bearer {{secret.token}}" }
|
||||
query?: Record<string, string>;
|
||||
body?: Record<string, string>;
|
||||
// path:注入 endpoint URL path 的 secret(auth-recipe.md §六,2026-05-29 加)。
|
||||
// 解 telegram 類「token 在 URL path」(/bot{token}/)—— header/query/body 都不適用。
|
||||
// key = 模板變數名(recipe endpoint 用 {{auth.K}} 引用),value = {{secret.X}} 模板。
|
||||
// auth_static_key WASM 解密後輸出為 auth_path → auth-dispatcher 帶進 _auth_path → makeRecipeRunner interpolate。
|
||||
path?: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface AuthRecipeDefinition {
|
||||
|
||||
Reference in New Issue
Block a user