feat: zentrale selfhost-dienste bereitstellen

This commit is contained in:
2026-08-02 16:34:10 +02:00
parent d3ad53bcf0
commit 8b8e0c97d3
30 changed files with 1818 additions and 74 deletions

View File

@@ -1,4 +1,4 @@
import { createHash, createHmac } from "node:crypto"
import { createHash, createHmac, randomUUID } from "node:crypto"
import { secrets } from "../utils/secrets"
@@ -54,13 +54,14 @@ function signature(method: string, path: string, timestamp: string, body: string
return createHmac("sha256", secrets.PUSH_SERVER_SECRET).update(canonical).digest("hex")
}
async function requestPushServer<T>(method: "POST" | "DELETE", path: string, payload?: unknown): Promise<T> {
async function requestPushServer<T>(method: "GET" | "POST" | "DELETE", path: string, payload?: unknown): Promise<T> {
if (!configured()) {
throw new Error("Zentraler Push-Server ist nicht konfiguriert")
}
const body = payload === undefined ? "" : JSON.stringify(payload)
const timestamp = new Date().toISOString()
const signedPath = path.split("?")[0]
const response = await fetch(`${normalizeBaseUrl()}${path}`, {
method,
headers: {
@@ -68,7 +69,8 @@ async function requestPushServer<T>(method: "POST" | "DELETE", path: string, pay
"Content-Type": "application/json",
"X-Fedeo-Instance-Id": secrets.PUSH_SERVER_INSTANCE_ID,
"X-Fedeo-Timestamp": timestamp,
"X-Fedeo-Signature": signature(method, path, timestamp, body),
"X-Fedeo-Signature": signature(method, signedPath, timestamp, body),
"X-Fedeo-Request-Id": randomUUID(),
},
body: body || undefined,
})
@@ -99,3 +101,35 @@ export const pushServerClient = {
})
},
}
export const centralServicesClient = {
configured,
aiChatCompletions(payload: Record<string, unknown>) {
return requestPushServer<any>("POST", "/v1/services/ai/chat-completions", payload)
},
bankingInstitutions(country = "DE") {
return requestPushServer<any[]>("GET", `/v1/services/banking/institutions?country=${encodeURIComponent(country)}`)
},
createBankingRequisition(input: { institutionId: string; redirect: string; userLanguage?: string }) {
return requestPushServer<any>("POST", "/v1/services/banking/requisitions", input)
},
getBankingRequisition(id: string) {
return requestPushServer<any>("GET", `/v1/services/banking/requisitions/${encodeURIComponent(id)}`)
},
getBankingAccount(id: string) {
return requestPushServer<any>("GET", `/v1/services/banking/accounts/${encodeURIComponent(id)}`)
},
getBankingBalances(id: string) {
return requestPushServer<any>("GET", `/v1/services/banking/accounts/${encodeURIComponent(id)}/balances`)
},
getBankingTransactions(id: string) {
return requestPushServer<any>("GET", `/v1/services/banking/accounts/${encodeURIComponent(id)}/transactions`)
},
}