refactor(quota): secure managed provider credentials (#2160)
- add shared owner-only credential storage for OpenCode Go, Ollama Cloud, and Cursor - validate credentials before atomic writes using 0700 directories and 0600 files - replace provider-specific credential routes with an allowlisted lifecycle API - stop automatically reading Ollama's legacy cookie file - stop reading or modifying Cursor's database during regular quota requests - add explicit one-time Cursor credential import without mutating Cursor storage - persist refreshed Cursor credentials only in OpenChamber-managed storage - add Ollama Cloud and Cursor credential controls to provider settings - preserve OpenCode Go tracking through the shared credential flow - add VS Code credential management and Cursor quota parity - reject authentication redirects, enforce request timeouts, and fail on unparseable usage pages - mask stored secrets in API responses and extend quota security coverage - update quota provider documentation
This commit is contained in:
committed by
GitHub
parent
3b92d97795
commit
b09614fd68
@@ -1041,11 +1041,12 @@ const handleLocalApiRequest = async (input: RequestInfo | URL, url: URL, init: R
|
||||
}
|
||||
}
|
||||
|
||||
if (pathname === '/api/quota/credentials/opencode-go' || pathname === '/api/quota/credentials/opencode-go/validate') {
|
||||
const quotaCredentialMatch = pathname.match(/^\/api\/quota\/credentials\/(opencode-go|ollama-cloud|cursor)(?:\/(validate|import))?$/);
|
||||
if (quotaCredentialMatch) {
|
||||
try {
|
||||
const body = method === 'PUT' ? await extractJsonBody(input, init, method) : undefined;
|
||||
const bridgeMethod = pathname.endsWith('/validate') ? 'VALIDATE' : method;
|
||||
const data = await sendBridgeMessage('api:quota:opencode-go-credentials', { method: bridgeMethod, credential: body });
|
||||
const bridgeMethod = quotaCredentialMatch[2]?.toUpperCase() || method;
|
||||
const data = await sendBridgeMessage('api:quota:credentials', { providerId: quotaCredentialMatch[1], method: bridgeMethod, credential: body });
|
||||
return new Response(JSON.stringify(data), { status: 200, headers: { 'Content-Type': 'application/json' } });
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
|
||||
Reference in New Issue
Block a user