feat: add /register endpoint + fix acr run Mode 1 (inline YAML execution)
- POST /register on cypher.arcrun.dev: HMAC-SHA256(email, ENCRYPTION_KEY) → ak_{32hex}, no DB needed
- acr run: Mode 1 (standard/local) now finds local YAML and POSTs to /cypher/execute inline
- acr init: fix register URL → cypher.arcrun.dev/register; fix local mode description
- acr init --local: creates hello.yaml example workflow
- cli v1.0.3 published
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import { docsRouter } from './routes/docs';
|
||||
import { webhooksRouter } from './routes/webhooks';
|
||||
import { webhooksCrudRouter } from './routes/webhooks-crud';
|
||||
import { webhooksListRouter } from './routes/webhooks-list';
|
||||
import { registerRouter } from './routes/register';
|
||||
|
||||
const app = new Hono<{ Bindings: Bindings }>();
|
||||
|
||||
@@ -25,6 +26,7 @@ app.route('/', validateRouter);
|
||||
app.route('/', webhooksRouter);
|
||||
app.route('/', webhooksCrudRouter);
|
||||
app.route('/', webhooksListRouter);
|
||||
app.route('/', registerRouter);
|
||||
|
||||
// Worker 導出
|
||||
export default app;
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
// 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,
|
||||
email,
|
||||
message: 'API Key 已發放,請妥善保存。相同 email 永遠得到相同的 Key。',
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user