diff --git a/CHANGELOG.md b/CHANGELOG.md index d09c005a42..5cbce68457 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 --- -## [Unreleased] +## [2.2.1] โ€” 2026-03-10 + +> ### ๐Ÿ› Bug Fixes ยท ๐Ÿ” Security ยท ๐Ÿ”ง CI + +### Bug Fixes + +- **Gemini image routing (#273)** โ€” `gemini-3.1-flash-image-preview` was missing from the `antigravity` image provider registry in `imageRegistry.ts`, causing image generation to fall through to the chat handler. Added alongside `gemini-2.5-flash-preview-image-generation`. +- **Ollama Cloud model listing (#276)** โ€” `ollama-cloud` was absent from `PROVIDER_MODELS_CONFIG` in the models route, causing 400 errors when listing models from `api.ollama.com`. Entry added. +- **Missing apiKey error clarity (#277)** โ€” When login is disabled and a provider has no API key configured, the model import route now returns `400` with a clear message instead of a generic `401 Unauthorized`. + +### Security + +- **TLS validation re-enabled (GHSA-50)** โ€” `mitm/server.ts`: `rejectUnauthorized` now defaults to `true`. Opt-out only via `MITM_DISABLE_TLS_VERIFY=1`. +- **Path traversal hardening (GHSA-41โ€“49)** โ€” Added `safePath()`, `safeProfilePath()`, `safeLogPath()` helpers across `backupService.ts`, `db/backup.ts`, `codex-profiles/route.ts`, and `mitm/server.ts`. All user-supplied IDs/filenames are now anchored within their allowed directories using `path.resolve()` + bounds check. +- **Prototype pollution fix (GHSA-18โ€“20)** โ€” `usageHistory.ts`: `pendingRequests` maps now use `Object.create(null)` + `hasOwnProperty` guards, preventing `__proto__` / `constructor` injection via crafted provider IDs. +- **Dependency: dompurify updated to ^3.3.2** โ€” Resolves CVE-2026-0540 (XSS in rendered HTML). +- **GitHub Actions: added `permissions: contents: read`** โ€” Prevents token over-permission in CI jobs. + +### CI + +- **Lock file sync** โ€” Added `@swc/helpers: "^0.5.19"` override in `package.json`; regenerated `package-lock.json`. Fixes `npm ci` failures across `ci.yml` and `docker-publish.yml`. +- **npm-publish: skip if version exists** โ€” Workflow now checks registry before publishing; exits cleanly with a warning instead of failing with `E403` if the version is already on npm. +- **npm-publish: use `npm install` instead of `npm ci`** โ€” Prevents publish failures when a tag commit's lock file is slightly out of sync. +- **Lint: `cursor.ts` any-budget** โ€” Replaced `any` with `unknown` + type narrowing in `isToolBoundaryAbort()`. --- diff --git a/package-lock.json b/package-lock.json index 5f46984526..3864a06af2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "omniroute", - "version": "2.2.0", + "version": "2.2.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "omniroute", - "version": "2.2.0", + "version": "2.2.1", "hasInstallScript": true, "license": "MIT", "workspaces": [ diff --git a/package.json b/package.json index ea5bcc08b7..6ddb0e52b4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "omniroute", - "version": "2.2.0", + "version": "2.2.1", "description": "Smart AI Router with auto fallback โ€” route to FREE & cheap models, zero downtime. Works with Cursor, Cline, Claude Desktop, Codex, and any OpenAI-compatible tool.", "type": "module", "bin": {