From 620552569e1b6b163df66ee824a480e6d5750abb Mon Sep 17 00:00:00 2001 From: SnapOtter Date: Wed, 17 Jun 2026 14:33:09 +0800 Subject: [PATCH] feat!: SnapOtter 2.0.0 Bump all workspace package versions and APP_VERSION to 2.0.0, marking the official 2.0 release. Removes the stale 1.x .release-notes.md artifact (semantic-release regenerates release notes). The 2.0/multimodality docs and rebrand already landed on main via #254 and #261, so this carries only the version designation forward from the rebrand branch. BREAKING CHANGE: SnapOtter 2.0 - the platform re-architecture (Postgres 17 + Redis 8 + BullMQ durable jobs, 157 tools across five modalities) is the 2.0 release line, replacing the 1.x SQLite single-container architecture. --- .release-notes.md | 71 ------------------------------ apps/api/package.json | 2 +- apps/demo/package.json | 2 +- apps/docs/package.json | 2 +- apps/landing/package.json | 2 +- apps/web/package.json | 2 +- package.json | 2 +- packages/ai/package.json | 2 +- packages/doc-engine/package.json | 2 +- packages/enterprise/package.json | 2 +- packages/image-engine/package.json | 2 +- packages/media-engine/package.json | 2 +- packages/shared/package.json | 2 +- packages/shared/src/constants.ts | 2 +- 14 files changed, 13 insertions(+), 84 deletions(-) delete mode 100644 .release-notes.md diff --git a/.release-notes.md b/.release-notes.md deleted file mode 100644 index abfa1dd4..00000000 --- a/.release-notes.md +++ /dev/null @@ -1,71 +0,0 @@ -## Highlights - -This release adds a new **HTML to Image** tool (tool #53), full **WCAG 2.2 AA accessibility** compliance, and a comprehensive **security hardening** pass based on external penetration testing. The Docker image also received 5 critical fixes that resolve container startup failures, broken HEIC decoding on ARM, and missing AI tool dependencies. - -## New Features - -- **HTML to Image**: Capture screenshots of URLs or raw HTML as PNG/JPEG/WebP. Supports full-page captures, custom viewports, and dark mode. Built on Playwright Chromium with SSRF protection. -- **Docker _FILE secret convention**: Mount sensitive environment variables (passwords, API keys, OIDC secrets) as files instead of plain-text env vars. Supported for `DEFAULT_PASSWORD_FILE`, `S3_ACCESS_KEY_ID_FILE`, `S3_SECRET_ACCESS_KEY_FILE`, `OIDC_CLIENT_SECRET_FILE`, `COOKIE_SECRET_FILE`, and `SNAPOTTER_LICENSE_KEY_FILE`. (#205) -- **Enterprise licensing and S3 storage**: Optional commercial license key and S3-compatible object storage backend for enterprise deployments. -- **Shape editor improvements**: Fill/stroke transparency, RGBA color picker, and dash line styles in the image editor. -- **Pre-built release archives**: Download `snapotter-vX.Y.Z-linux-amd64.tar.gz` and `snapotter-vX.Y.Z-linux-arm64.tar.gz` from GitHub Releases for non-Docker installs (Proxmox, bare metal, LXC). (#202) -- **Community roadmap**: Feature requests and prioritization now tracked via GitHub Discussions with `now`/`next`/`later` labels. - -## Improvements - -- **WCAG 2.2 AA accessibility**: Skip navigation, route announcer, focus trapping on all modals, `aria-live` regions for processing status, `prefers-reduced-motion` support, correct contrast ratios, and 44px minimum touch targets. All 49 hardcoded `aria-label` strings replaced with i18n keys across 25 components. (#209) -- **Mobile responsiveness**: Responsive settings dialog, homepage, navigation, and toast notifications. SSE connections now automatically reconnect when returning from a backgrounded mobile tab. (#203, #204) -- **Background removal quality**: Edge smoothing, color decontamination, and output format selection added to the remove-background tool. -- **Italian translation**: ~145 newly translated strings contributed by @albanobattistella. (#206) -- **Per-tool API documentation**: 53 individual VitePress doc pages with accurate parameters, example requests, and response formats. Root `llms.txt` added for LLM-friendly repo browsing. -- **AI model downloads**: Retry logic with exponential backoff for HuggingFace model downloads, preventing transient failures from blocking bundle installation. (#201) - -## Bug Fixes - -- **Docker: fresh containers were completely unusable**: `RATE_LIMIT_PER_MIN=0` in the Dockerfile caused `@fastify/rate-limit` to block all API requests (including health checks) with HTTP 429. Fixed by treating 0 as unlimited (50,000/min). -- **Docker: face detection AI tools failed on all platforms**: blur-faces, red-eye-removal, enhance-faces, and passport-photo failed with "libGLESv2.so.2 not found". Fixed by adding `libgles2` to the Docker image. -- **Docker: HEIC files broken on ARM**: `heif-convert` crashed with "undefined symbol: heif_get_plugin_directories" on arm64 due to library version mismatch. Fixed with `LD_LIBRARY_PATH=/usr/local/lib` to prioritize the custom libheif 1.21.2 build. -- **Docker: upscale and restore-photo AI bundles failed on ARM**: `basicsr` could not build from source on arm64 because `wheel` and `setuptools` were missing from the Python venv. Fixed by pre-installing both packages. -- **Docker: OCR used wrong CUDA version on GPU**: PaddlePaddle resolved from PyPI (CUDA 11) instead of the CUDA 12.6 index, causing symbol errors on GPU containers. Fixed by changing `--extra-index-url` to `--index-url` for the cu126 package source. -- **SSRF guard bypass via hex IPv4-mapped IPv6**: The URL-fetch SSRF guard only handled the dotted form of `::ffff:` addresses. Hex-compressed forms like `[::ffff:7f00:1]` (127.0.0.1) bypassed the private IP check, allowing access to internal services and cloud metadata endpoints. (Reported by **@tonghuaroot** via coordinated disclosure) -- **iPhone HEIC support**: Built libheif 1.21.2 from source to fix decoding of iPhone HEIC files with auxiliary images (depth maps, HDR gain maps). (#183, #199) -- **Real-ESRGAN CUDA OOM on 8GB GPUs**: Enabled tiling to prevent out-of-memory crashes when upscaling on GPUs with limited VRAM. (#200) -- **6 production Sentry errors resolved**: Fixed crashes from malformed inputs, edge cases in metadata handling, and error response formatting. -- **7 bugs from QA sweep**: Selective metadata stripping, meme font mapping, content type detection, and missing i18n keys. (#208) -- **Cryptographic password generation**: Replaced `Math.random()` with `crypto.getRandomValues()` for password generation. -- **Docker Compose image name**: Corrected the image name in `docker-compose.yml`. (#198) - -## Security - -- **Penetration test hardening**: 10 findings from external security testing addressed: XFF rate-limit bypass (PT-01), malformed JSON 500 errors (PT-03), unbounded pipeline steps DoS (PT-04), clientJobId validation (PT-06), missing security headers on SSE streams (PT-07), audit log XSS (PT-08), TRACE method enabled (PT-10), missing 429 in OpenAPI spec (PT-12), unbounded SVGZ decompression (PT-13). (#207) -- **SSRF hex IPv6 bypass**: Blocked hex-compressed IPv4-mapped IPv6 addresses in the URL-fetch guard. (Credit: **@tonghuaroot**) -- **SVG XXE protection**: Added test fixtures and validation for SVG XML external entity attacks. -- **Dockerfile base images pinned by digest**: Prevents supply chain attacks from mutable tags. - -## Acknowledgements - -- **@tonghuaroot**: For responsibly disclosing the SSRF guard bypass via hex IPv4-mapped IPv6 addresses. The detailed proof-of-concept and suggested fix made for a quick turnaround. -- **@rudedog7106**: For reporting HEIC decoding failures on TrueNAS/Docker. (#183) -- **@electricmessiah**: For reporting missing shape fill transparency (#193) and the Docker Compose image name issue (#182). -- **@florentineprinzessinzusachsen**: For reporting CUDA out-of-memory on NVIDIA 3070 8GB. (#191) -- **@albanobattistella**: For contributing ~145 Italian translation strings. (#206) - -## Upgrade - -```bash -docker pull snapotter/snapotter:1.17.2 -``` - -Or with Docker Compose: - -```bash -docker compose pull && docker compose up -d -``` - -Also available from GitHub Container Registry: - -```bash -docker pull ghcr.io/snapotter-hq/snapotter:1.17.2 -``` - -**Full Changelog**: https://github.com/snapotter-hq/SnapOtter/compare/v1.17.1...v1.17.2 diff --git a/apps/api/package.json b/apps/api/package.json index d9760300..fc93b4df 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -1,6 +1,6 @@ { "name": "@snapotter/api", - "version": "1.17.1", + "version": "2.0.0", "private": true, "type": "module", "scripts": { diff --git a/apps/demo/package.json b/apps/demo/package.json index 4b537677..6f5d0f98 100644 --- a/apps/demo/package.json +++ b/apps/demo/package.json @@ -1,6 +1,6 @@ { "name": "@snapotter/demo", - "version": "1.17.1", + "version": "2.0.0", "private": true, "type": "module", "scripts": { diff --git a/apps/docs/package.json b/apps/docs/package.json index 7b160321..856f8362 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -1,6 +1,6 @@ { "name": "@snapotter/docs", - "version": "1.17.2", + "version": "2.0.0", "private": true, "scripts": { "docs:dev": "vitepress dev .", diff --git a/apps/landing/package.json b/apps/landing/package.json index 067af9df..732ace15 100644 --- a/apps/landing/package.json +++ b/apps/landing/package.json @@ -1,6 +1,6 @@ { "name": "@snapotter/landing", - "version": "1.17.1", + "version": "2.0.0", "private": true, "type": "module", "scripts": { diff --git a/apps/web/package.json b/apps/web/package.json index 32c10e62..7e540c23 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@snapotter/web", - "version": "1.17.1", + "version": "2.0.0", "private": true, "type": "module", "scripts": { diff --git a/package.json b/package.json index d934706d..811c6f1c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "snapotter", - "version": "1.17.2", + "version": "2.0.0", "private": true, "description": "Self-hosted file processing suite with 157 tools across image, video, audio, document, and data, plus local AI. Runs as a Docker Compose stack with Postgres and Redis.", "homepage": "https://snapotter.com", diff --git a/packages/ai/package.json b/packages/ai/package.json index 019f8648..ee749239 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "@snapotter/ai", - "version": "1.17.1", + "version": "2.0.0", "private": true, "type": "module", "main": "./src/index.ts", diff --git a/packages/doc-engine/package.json b/packages/doc-engine/package.json index 64ffd863..99203e5c 100644 --- a/packages/doc-engine/package.json +++ b/packages/doc-engine/package.json @@ -1,6 +1,6 @@ { "name": "@snapotter/doc-engine", - "version": "1.17.1", + "version": "2.0.0", "private": true, "type": "module", "main": "./src/index.ts", diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index 6a988b15..0a78fb53 100644 --- a/packages/enterprise/package.json +++ b/packages/enterprise/package.json @@ -1,6 +1,6 @@ { "name": "@snapotter/enterprise", - "version": "1.17.1", + "version": "2.0.0", "private": true, "type": "module", "main": "./src/index.ts", diff --git a/packages/image-engine/package.json b/packages/image-engine/package.json index c5960f05..7a868e6a 100644 --- a/packages/image-engine/package.json +++ b/packages/image-engine/package.json @@ -1,6 +1,6 @@ { "name": "@snapotter/image-engine", - "version": "1.17.1", + "version": "2.0.0", "private": true, "type": "module", "main": "./src/index.ts", diff --git a/packages/media-engine/package.json b/packages/media-engine/package.json index 604e2a3e..14cc33bb 100644 --- a/packages/media-engine/package.json +++ b/packages/media-engine/package.json @@ -1,6 +1,6 @@ { "name": "@snapotter/media-engine", - "version": "1.17.1", + "version": "2.0.0", "private": true, "type": "module", "main": "./src/index.ts", diff --git a/packages/shared/package.json b/packages/shared/package.json index 70625e39..df193117 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@snapotter/shared", - "version": "1.17.1", + "version": "2.0.0", "private": true, "type": "module", "main": "./src/index.ts", diff --git a/packages/shared/src/constants.ts b/packages/shared/src/constants.ts index d68c745f..01850c30 100644 --- a/packages/shared/src/constants.ts +++ b/packages/shared/src/constants.ts @@ -2581,7 +2581,7 @@ export const PRINT_LAYOUTS: PrintLayout[] = [ { id: "none", label: "None", width: 0, height: 0 }, ]; -export const APP_VERSION = "1.17.2"; +export const APP_VERSION = "2.0.0"; /** * Tool IDs that require the Python sidecar (AI/ML tools).