Files
openchamber/packages/web/server/lib/quota/credentials/providers.js
T
Bohdan Triapitsyn b09614fd68 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
2026-07-12 16:21:38 +03:00

44 lines
1.9 KiB
JavaScript

import { deleteQuotaCredential, readQuotaCredential, writeQuotaCredential } from './store.js';
const clean = (value) => typeof value === 'string' && !/[\r\n]/.test(value) ? value.trim() : '';
export const normalizers = {
'opencode-go': (value) => {
const workspaceId = clean(value?.workspaceId);
let authCookie = clean(value?.authCookie);
if (authCookie.startsWith('auth=')) authCookie = authCookie.slice(5).trim();
return workspaceId && authCookie ? { workspaceId, authCookie } : null;
},
'ollama-cloud': (value) => {
const cookie = clean(value?.cookie);
return cookie ? { cookie } : null;
},
cursor: (value) => {
const accessToken = clean(value?.accessToken);
const refreshToken = clean(value?.refreshToken);
return accessToken || refreshToken ? { accessToken, refreshToken } : null;
},
};
export const readManagedCredential = (providerId) => {
const normalize = normalizers[providerId];
return normalize ? readQuotaCredential(providerId, normalize) : null;
};
export const writeManagedCredential = (providerId, value) => {
const credential = normalizers[providerId]?.(value);
if (!credential) throw new Error('Invalid credential');
writeQuotaCredential(providerId, credential);
return getManagedCredentialStatus(providerId);
};
export const getManagedCredentialStatus = (providerId) => {
const credential = readManagedCredential(providerId);
if (!credential) return { configured: false };
if (providerId === 'opencode-go') return { configured: true, workspaceId: credential.workspaceId, secretMasked: '••••••••' };
if (providerId === 'cursor') return { configured: true, hasRefreshToken: Boolean(credential.refreshToken), secretMasked: '••••••••' };
return { configured: true, secretMasked: '••••••••' };
};
export const deleteManagedCredential = (providerId) => deleteQuotaCredential(providerId);