Files
Arcrun/cypher-executor/src/routes/register.ts
T
Leo 500d796573 feat: 15 logic component Workers + cypher-executor auth/credentials routing
Component Workers:
- Deploys if_control, switch, filter, merge, try_catch, wait, set,
  array_ops, string_ops, number_ops, date_ops, validate_json,
  ai_transform_compile, ai_transform_run, foreach_control as
  independent Workers, backing cypher-executor's SVC_* service
  bindings (fast internal RPC for logic components).

cypher-executor routing:
- New routes: /auth (recipe resolution), /credentials (CRUD),
  /webhooks/named (user-friendly alias for cmp_/rec_ hashes).
- auth-recipe-seeds.ts: 20 pre-built platform auth recipes
  (Google Sheets, Gmail, Telegram, etc.) seeded into RECIPES KV.
- graph-executor + cypher-handlers + search-nodes updated for
  the new resolution chain.
- scripts/seed-auth-recipes.ts: one-shot tool to push seeds to KV.
- wrangler.toml: 15 SVC_* bindings wired to the new logic Workers.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 17:40:02 +08:00

47 lines
1.7 KiB
TypeScript

// POST /register — API Key 發放
// email → HMAC-SHA256(email, ENCRYPTION_KEY) → api_key (ak_ 前綴)
// 同一個 email 永遠得到相同的 Key,無需資料庫
import { Hono } from 'hono';
import type { Bindings } from '../types';
export const registerRouter = new Hono<{ Bindings: Bindings }>();
registerRouter.post('/register', async (c) => {
let email: string;
try {
const body = await c.req.json() as { email?: string };
email = (body.email ?? '').trim().toLowerCase();
} catch {
return c.json({ success: false, error: 'request body 必須為 JSON' }, 400);
}
if (!email || !email.includes('@')) {
return c.json({ success: false, error: 'email 格式不正確' }, 400);
}
const encryptionKey = c.env.ENCRYPTION_KEY;
if (!encryptionKey || encryptionKey.length < 32) {
return c.json({ success: false, error: 'server configuration error' }, 500);
}
// HMAC-SHA256(email, ENCRYPTION_KEY) → hex → 取前 32 字元 → ak_ 前綴
const keyData = new TextEncoder().encode(encryptionKey.slice(0, 32));
const msgData = new TextEncoder().encode(email);
const cryptoKey = await crypto.subtle.importKey(
'raw', keyData, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']
);
const sig = await crypto.subtle.sign('HMAC', cryptoKey, msgData);
const hex = Array.from(new Uint8Array(sig)).map(b => b.toString(16).padStart(2, '0')).join('');
const apiKey = 'ak_' + hex.slice(0, 32);
return c.json({
success: true,
api_key: apiKey,
encryption_key: encryptionKey, // 用戶需要此 key 才能加密上傳 credential
email,
message: 'API Key 已發放,請妥善保存。相同 email 永遠得到相同的 Key。',
});
});