- EndpointPageClient: full migration including cloud proxy modals,
endpoint sections (chat, embeddings, images, rerank, audio, moderations),
enable/disable cloud flows, sync steps, and status messages
- Expanded endpoint namespace from 10 to 55 keys in en.json and pt-BR.json
- CombosPage, ComboCard, ComboFormModal, TestResultsView: full migration
- Headers, model tags, metrics, strategy descriptions, validation
- Form labels, advanced settings, drag-and-drop model list, actions
- Expanded combos namespace from 19 to 65 keys in en.json and pt-BR.json
- ApiManagerPageClient: full migration including stats cards, table headers,
modals, permissions system, validation messages, and usage tips
- PermissionsModal: search, model selection, allow/restrict toggles
- Expanded apiManager namespace from 18 to 67 keys in en.json and pt-BR.json
- Added ApiKeyMetadata interface to replace 'any' types in apiKeyPolicy.ts
- Added error logging in catch blocks for getApiKeyMetadata() and checkBudget()
- Fixed claude-sonnet-4-6-thinking → claude-sonnet-4-6 mismatch in usage.ts importantModels
Follow-up fixes for merged PRs #131 and #128
isModelAllowedForKey() existed in src/lib/db/apiKeys.ts but was never
called anywhere. API keys with allowedModels restrictions could access
any model through any endpoint.
Changes:
- Add shared enforceApiKeyPolicy() middleware (model restriction + budget)
- Wire it into chat handler (replacing inline budget-only check)
- Wire it into all /v1/* endpoints: embeddings, images/generations,
audio/speech, audio/transcriptions, moderations, rerank
- Wire it into provider-specific endpoints: /v1/providers/[provider]/embeddings,
/v1/providers/[provider]/images/generations
The middleware checks:
1. Model restriction — if key has allowedModels, verify the model is permitted
2. Budget limit — if key has budget configured, verify it hasn't been exceeded
Fixes#130
- Combo cards now resolve UUID-based provider IDs to user-defined names using providerNodes
- API key names shown in full instead of masked (Op***w → OpenAI-Prod-Key); key IDs remain masked
- Logs/Analytics: OAI-compatible and ANT-compatible providers now show user-defined names from providerNodes instead of generic OAI-COMPAT labels
- All views (combo cards, combos form modal, logs table, quick filters, dropdowns, analytics) updated consistently
- Wrap exchangeTokens calls with runWithProxyContext in both 'exchange' and 'poll-callback' actions
- Resolve proxy via provider-level → global → direct fallback chain
- Fixes region-restricted providers (e.g. OpenAI Codex) failing during OAuth setup with unsupported_country_region_territory error
- Use Anthropic's registered redirect_uri (platform.claude.com/oauth/code/callback) instead of dynamic server URL
- Add missing OAuth scopes: user:sessions:claude_code, user:mcp_servers (5 total, matching Claude CLI)
- Make redirect_uri configurable via CLAUDE_CODE_REDIRECT_URI env var
- Override redirectUri in both buildAuthUrl and exchangeToken to use config value
Includes security hardening and UX improvements:
- Authentication on /api/provider-models via isAuthenticated
- URL parameter injection prevention (encodeURIComponent)
- Replaced alert() with notify.error/notify.success toasts
- Transactional save: DB first, then alias creation
- Consistent error handling across all model operations
- Fix URL parameter injection: apply encodeURIComponent on providerStorageAlias and providerId in all API calls
- Replace blocking alert() with non-blocking notify.error/notify.success toast notifications
- Add success feedback for model add and delete operations
- Improve error handling: use console.error consistently and add user-facing notifications for import failures
- Check DELETE response status before proceeding with alias removal