From 8bcb30a85b2d79bd98d31c71947f42dcecf91f10 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Wed, 29 Apr 2026 15:51:09 +0800 Subject: [PATCH] feat: tambah API Key Desa Plus ke Settings panel dan proxy - Tambah kolom API_KEY_DESA_PLUS di CONFIG_DEFINITIONS (ditampilkan sebagai password field) - Proxy otomatis menyertakan X-API-Key header jika API key sudah dikonfigurasi Co-Authored-By: Claude Sonnet 4.6 --- src/app.ts | 6 +++++- src/frontend/routes/dev.tsx | 10 +++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/app.ts b/src/app.ts index 5922574..8401f78 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1583,13 +1583,17 @@ export function createApp() { // ─── Desa Plus Proxy ─────────────────────────────────────────────────────── .all('/api/proxy/desa-plus/*', async ({ request, set }) => { - const baseConfig = await prisma.appConfig.findUnique({ where: { key: 'URL_API_DESA_PLUS' } }) + const [baseConfig, apiKeyConfig] = await Promise.all([ + prisma.appConfig.findUnique({ where: { key: 'URL_API_DESA_PLUS' } }), + prisma.appConfig.findUnique({ where: { key: 'API_KEY_DESA_PLUS' } }), + ]) if (!baseConfig?.value) { set.status = 503; return { error: 'URL_API_DESA_PLUS belum dikonfigurasi. Set di /dev → Settings.' } } const base = baseConfig.value.replace(/\/$/, '') const url = new URL(request.url) const upstream = `${base}${url.pathname.replace('/api/proxy/desa-plus', '')}${url.search}` const headers = new Headers(request.headers) headers.delete('host') + if (apiKeyConfig?.value) headers.set('X-API-Key', apiKeyConfig.value) try { const res = await fetch(upstream, { method: request.method, headers, body: request.method !== 'GET' && request.method !== 'HEAD' ? request.body : undefined }) const contentType = res.headers.get('content-type') ?? 'application/json' diff --git a/src/frontend/routes/dev.tsx b/src/frontend/routes/dev.tsx index 8e99dd6..f42e028 100644 --- a/src/frontend/routes/dev.tsx +++ b/src/frontend/routes/dev.tsx @@ -1463,13 +1463,20 @@ function StaticFlowPanel({ graph, flowKey }: { graph: { nodes: Node[]; edges: Ed interface AppConfigEntry { key: string; value: string; updatedAt: string } -const CONFIG_DEFINITIONS: { key: string; label: string; description: string; placeholder: string }[] = [ +const CONFIG_DEFINITIONS: { key: string; label: string; description: string; placeholder: string; secret?: boolean }[] = [ { key: 'URL_API_DESA_PLUS', label: 'URL API Desa Plus', description: 'Base URL untuk API eksternal Desa Plus. Semua request dari frontend akan diproxy melalui server ke URL ini.', placeholder: 'https://api.desa-plus.example.com', }, + { + key: 'API_KEY_DESA_PLUS', + label: 'API Key Desa Plus', + description: 'API key untuk autentikasi ke API Desa Plus. Dikirim otomatis sebagai header X-API-Key pada setiap request proxy.', + placeholder: 'your-secret-api-key', + secret: true, + }, ] function SettingsPanel() { @@ -1535,6 +1542,7 @@ function SettingsPanel() {