Add API key provisioning to accounts page
This commit is contained in:
+91
@@ -2145,6 +2145,97 @@ fn handle_request_inner(method: String, path: String, headers: Map, body: String
|
||||
return "{\"ok\":true}"
|
||||
}
|
||||
|
||||
// ── API key provisioning — POST /api/api-keys ────────────────────────────
|
||||
// Returns user's stored provider keys (masked) for display on /account.
|
||||
// Body: { access_token: "<jwt>" }
|
||||
if str_eq(path, "/api/api-keys") && str_eq(method, "POST") {
|
||||
let ak_jwt: String = json_get_string(body, "access_token")
|
||||
if str_eq(ak_jwt, "") {
|
||||
return "{\"__status__\":401,\"error\":\"missing_jwt\"}"
|
||||
}
|
||||
let ak_url: String = state_get("__supabase_project_url__")
|
||||
let ak_anon: String = state_get("__supabase_anon_key__")
|
||||
let ak_service: String = state_get("__supabase_service_key__")
|
||||
if str_eq(ak_url, "") {
|
||||
return "{\"__status__\":503,\"error\":\"supabase_not_configured\"}"
|
||||
}
|
||||
let ak_user: String = supabase_auth_user(ak_url, ak_anon, ak_jwt)
|
||||
let ak_uid: String = json_get(ak_user, "id")
|
||||
if str_eq(ak_uid, "") {
|
||||
return "{\"__status__\":401,\"error\":\"invalid_jwt\"}"
|
||||
}
|
||||
let ak_q: String = "user_api_keys?select=provider,key_value&user_id=eq." + ak_uid
|
||||
let ak_rows: String = supabase_get(ak_url, ak_service, ak_q)
|
||||
return "{\"rows\":" + ak_rows + "}"
|
||||
}
|
||||
|
||||
// ── API key provisioning — POST /api/api-keys/save ───────────────────────
|
||||
// Upserts a single provider key for the authenticated user.
|
||||
// Body: { access_token: "<jwt>", provider: "openai"|"anthropic"|"gemini"|"grok", key: "<value>" }
|
||||
if str_eq(path, "/api/api-keys/save") {
|
||||
let aks_jwt: String = json_get_string(body, "access_token")
|
||||
let aks_provider: String = json_get_string(body, "provider")
|
||||
let aks_key: String = json_get_string(body, "key")
|
||||
if str_eq(aks_jwt, "") {
|
||||
return "{\"__status__\":401,\"error\":\"missing_jwt\"}"
|
||||
}
|
||||
if str_eq(aks_provider, "") || str_eq(aks_key, "") {
|
||||
return "{\"__status__\":400,\"error\":\"missing_provider_or_key\"}"
|
||||
}
|
||||
let aks_valid_provider: Bool = str_eq(aks_provider, "openai")
|
||||
|| str_eq(aks_provider, "anthropic")
|
||||
|| str_eq(aks_provider, "gemini")
|
||||
|| str_eq(aks_provider, "grok")
|
||||
if !aks_valid_provider {
|
||||
return "{\"__status__\":400,\"error\":\"invalid_provider\"}"
|
||||
}
|
||||
let aks_url: String = state_get("__supabase_project_url__")
|
||||
let aks_anon: String = state_get("__supabase_anon_key__")
|
||||
let aks_service: String = state_get("__supabase_service_key__")
|
||||
if str_eq(aks_url, "") {
|
||||
return "{\"__status__\":503,\"error\":\"supabase_not_configured\"}"
|
||||
}
|
||||
let aks_user: String = supabase_auth_user(aks_url, aks_anon, aks_jwt)
|
||||
let aks_uid: String = json_get(aks_user, "id")
|
||||
if str_eq(aks_uid, "") {
|
||||
return "{\"__status__\":401,\"error\":\"invalid_jwt\"}"
|
||||
}
|
||||
let aks_row: String = "{\"user_id\":\"" + aks_uid + "\",\"provider\":\"" + aks_provider + "\",\"key_value\":\"" + aks_key + "\",\"updated_at\":\"now()\"}"
|
||||
let _aks_resp: String = supabase_insert(aks_url, aks_service, "user_api_keys?on_conflict=user_id,provider", aks_row)
|
||||
let aks_klen: Int = str_len(aks_key)
|
||||
let aks_masked: String = if aks_klen <= 10 {
|
||||
str_repeat("•", aks_klen)
|
||||
} else {
|
||||
str_slice(aks_key, 0, 6) + "••••" + str_slice(aks_key, aks_klen - 4, aks_klen)
|
||||
}
|
||||
return "{\"ok\":true,\"masked\":\"" + aks_masked + "\"}"
|
||||
}
|
||||
|
||||
// ── API key provisioning — POST /api/api-keys/delete ─────────────────────
|
||||
// Soft-deletes a provider key by clearing key_value for the authenticated user.
|
||||
// Body: { access_token: "<jwt>", provider: "openai"|"anthropic"|"gemini"|"grok" }
|
||||
if str_eq(path, "/api/api-keys/delete") {
|
||||
let akd_jwt: String = json_get_string(body, "access_token")
|
||||
let akd_provider: String = json_get_string(body, "provider")
|
||||
if str_eq(akd_jwt, "") {
|
||||
return "{\"__status__\":401,\"error\":\"missing_jwt\"}"
|
||||
}
|
||||
let akd_url: String = state_get("__supabase_project_url__")
|
||||
let akd_anon: String = state_get("__supabase_anon_key__")
|
||||
let akd_service: String = state_get("__supabase_service_key__")
|
||||
if str_eq(akd_url, "") {
|
||||
return "{\"__status__\":503,\"error\":\"supabase_not_configured\"}"
|
||||
}
|
||||
let akd_user: String = supabase_auth_user(akd_url, akd_anon, akd_jwt)
|
||||
let akd_uid: String = json_get(akd_user, "id")
|
||||
if str_eq(akd_uid, "") {
|
||||
return "{\"__status__\":401,\"error\":\"invalid_jwt\"}"
|
||||
}
|
||||
let akd_row: String = "{\"user_id\":\"" + akd_uid + "\",\"provider\":\"" + akd_provider + "\",\"key_value\":\"\",\"updated_at\":\"now()\"}"
|
||||
let _akd_resp: String = supabase_insert(akd_url, akd_service, "user_api_keys?on_conflict=user_id,provider", akd_row)
|
||||
return "{\"ok\":true}"
|
||||
}
|
||||
|
||||
// ── Fallback ──────────────────────────────────────────────────────────────
|
||||
return "{\"__status__\":404,\"error\":\"not found\"}"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user