feat: REST API v1 + API key management + Swagger docs
**API system** - ApiKey model: SHA-256-hashed tokens (gw_<hex>), per-family, scoped - Migration: 20260615210000_api_keys - src/lib/api-auth.ts: verifyApiKey(), hasScope(), generateApiKey(), prepareKey() **V1 endpoints** (all require Bearer gw_ token): - GET /api/v1/babies — list family babies (any read scope) - GET /api/v1/events — query events (events:read), babyId/type/from/to/limit/offset - POST /api/v1/events — log event (events:write), full metadata support - GET /api/v1/growth — growth logs (growth:read) - POST /api/v1/growth — add measurement (growth:write), weight in grams - GET /api/v1/summary — today's counts + sleep + last feed (summary:read) - GET /api/v1/milk — stock lots + totalMl (milk:read) **API key management** - GET /api/api-keys — list keys (session auth) - POST /api/api-keys — create key, returns raw token once (session auth) - DELETE /api/api-keys/[id] — revoke key (session auth) **Documentation** - GET /api/v1/openapi.json — OpenAPI 3.0 spec (CORS open) - GET /api-docs — Swagger UI (CDN, dark themed) **Settings UI** — "Clés API" section: create key with scope checkboxes, copy token banner (shown once), revoke, link to /api-docs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
export async function GET(req: Request) {
|
||||
const base = new URL(req.url).origin;
|
||||
const html = `<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Grow API — Documentation</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" />
|
||||
<style>
|
||||
body { margin: 0; background: #0f172a; }
|
||||
.swagger-ui .topbar { background: #1e293b; border-bottom: 1px solid #334155; }
|
||||
.swagger-ui .topbar .download-url-wrapper { display: none; }
|
||||
.swagger-ui .info .title { color: #e2e8f0; }
|
||||
.swagger-ui .scheme-container { background: #1e293b; border-bottom: 1px solid #334155; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
||||
<script>
|
||||
SwaggerUIBundle({
|
||||
url: "${base}/api/v1/openapi.json",
|
||||
dom_id: "#swagger-ui",
|
||||
presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],
|
||||
layout: "StandaloneLayout",
|
||||
deepLinking: true,
|
||||
persistAuthorization: true,
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>`;
|
||||
return new Response(html, { headers: { "Content-Type": "text/html" } });
|
||||
}
|
||||
Reference in New Issue
Block a user