diff --git a/cypher-executor/src/lib/auth-recipe-seeds.ts b/cypher-executor/src/lib/auth-recipe-seeds.ts index bae1201..ea1ad38 100644 --- a/cypher-executor/src/lib/auth-recipe-seeds.ts +++ b/cypher-executor/src/lib/auth-recipe-seeds.ts @@ -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)──────── { diff --git a/cypher-executor/src/routes/recipes.ts b/cypher-executor/src/routes/recipes.ts index af22f9e..76bed0c 100644 --- a/cypher-executor/src/routes/recipes.ts +++ b/cypher-executor/src/routes/recipes.ts @@ -460,6 +460,11 @@ export interface AuthInjectSpec { header?: Record; // e.g. { Authorization: "Bearer {{secret.token}}" } query?: Record; body?: Record; + // 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; } export interface AuthRecipeDefinition {