Commit Graph
50 Commits
Author SHA1 Message Date
ashim-hq babca4cf97 test: comprehensive test coverage expansion (+965 tests)
Add 42 new test files covering all untested tool routes, image engine
internals, AI sidecar bridge, Zustand stores, and cross-format
compatibility. Expand e2e-docker suite with 7 spec files covering all
48 tools against a real Docker container.

Unit tests:
- Image engine: format detection, MIME mapping, metadata parsing, pipeline
- AI bridge: sidecar lifecycle, all 11 tool functions (mocked)
- Web stores: 14 Zustand stores (collage, settings, features, analytics, etc.)
- API helpers: format decoders, page range, file validation

Integration tests:
- 25 tool routes that had zero dedicated tests
- Cross-format matrix: 17 input formats x 3 tools
- Edge cases: zero-byte files, corrupted headers, path traversal, XSS, SQL injection
- Concurrent request handling and pipeline edge cases

E2E-Docker (Playwright against real container):
- 7 spec files: essential, adjustment, conversion, creative, utility, AI, pipeline
- Custom buildMultipart helper for multi-file tool uploads
- AI tools gracefully skip when sidecar not installed

Fixtures:
- Organized test media: formats/ (18 formats) + content/ (17 content types)
- Reduced from 3.1 GB unorganized samples to 33 MB structured fixtures

Bug fix:
- color-adjustments: gamma exposure used invalid single-param gamma() for
  positive values; fixed to use two-param gamma(gammaIn, gammaOut) form
2026-04-23 17:12:02 +08:00
AshimandGitHub 5a45bcbc8f feat: production-grade RBAC with editor role, custom roles, API key scoping, and audit log (#89)
* feat(rbac): add editor role, 3 new permissions, ownership helper

* feat(rbac): add audit_log table, apiKeys.permissions column, editor role to schema

* feat(rbac): wire requirePermission into all routes, add editor role support

* refactor(rbac): replace ad-hoc role checks with permission-based ownership

* feat(rbac): add audit log DB writes + query endpoint

Dual-write audit events to stdout (existing) and SQLite audit_log table.
Add GET /api/v1/audit-log with pagination, action filter, and date range
filtering, gated behind audit:read permission.

* feat(rbac): add API key permission scoping with ceiling enforcement

* feat(rbac): add escalation prevention and last-admin protection

* feat(rbac): add editor role to UI, API key permission scoping in settings

* test(rbac): add full permission matrix integration test

* test(rbac): add editor role E2E tests

* feat(rbac): add custom roles with CRUD API and DB-backed permission lookup

* feat(rbac): add API key expiration

* feat(rbac): add roles management UI and API key expiration to settings

* feat(rbac): add audit log UI to settings

* fix: remove any cast in API key permission validation

* test(rbac): add unit tests for username validation rules

* test(rbac): add unit tests for effective permissions and ownership

* test(rbac): add comprehensive route permission matrix (all routes × all roles)

* test(rbac): add auth route edge case tests (login failures, session expiry, password side effects)

* test(rbac): add escalation prevention tests (register, update, self-demote, last-admin)

* test(rbac): add ownership enforcement tests (files, pipelines, editor access, cross-user isolation)

* test(rbac): add API key edge cases (name validation, delete behavior, key revocation)

* test(rbac): add audit log edge cases (all events, pagination clamping, structure)

* test(rbac): add custom roles edge case tests (validation, CRUD, functional permissions)

* test(rbac): add comprehensive E2E tests (roles UI, audit log, custom role, API key scoping)
2026-04-22 18:10:04 +08:00
AshimandClaude Opus 4.6 01d30cfb61 fix: pin torch cu126 for GPU compatibility and fix cross-platform bugs
- Pin torch==2.6.0+cu126 and torchvision==0.21.0+cu126 in feature
  manifest to prevent NCCL symbol mismatch on CUDA 12.6 base images
- Move lpips after torch in install order to prevent wrong version
  resolution from PyPI
- Add einops to upscale-enhance common deps (required by SCUNet)
- Update cpu_fallback_packages to handle multi-package CUDA torch
  entries on amd64 without GPU
- Fix gpu.py ONNX CUDA detection: replace hardcoded .so path with
  cross-platform session smoke-test
- Fix os.dup(1) crashes on Windows in upscale, enhance_faces, and
  noise_removal by wrapping in try/except with sys.stderr fallback
- Guard top-level numpy/cv2 imports in colorize.py and restore.py
  with helpful error messages
- Add weights_only=False fallback for torch.load in noise_removal
- Fix integration tests to accept 501 for uninstalled AI features
  and 422 for missing system tools (exiftool, libheif)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 15:17:08 +08:00
Siddharth Kumar Sah a4c63855d4 fix(docker): fix TDZ crash, icon bundle bloat, rate-limit on static assets
- Fix "Cannot access 'a' before initialization" TDZ error after login
  caused by manualChunks splitting react-vendor + lucide icons into
  circular ES-module chunks. Removed manualChunks entirely.

- Replace `import * as icons from "lucide-react"` (pulls all ~1000 icons)
  with a targeted icon-map of ~50 icons actually used by tool definitions.
  Reduces shared icons chunk from 745KB to 62KB (132KB→16KB gzip).

- Exclude static files from @fastify/rate-limit via allowList so rapid
  page navigations don't 429 on JS/CSS chunk requests.

- Move Docker auth defaults (AUTH_ENABLED, DEFAULT_USERNAME,
  DEFAULT_PASSWORD) from Dockerfile ENV to entrypoint.sh runtime exports
  to avoid SecretsUsedInArgOrEnv warnings.

- Fix Docker CMD to use pnpm --filter for workspace-scoped tsx binary.

- Set COREPACK_HOME system-wide so non-root user can access pnpm cache.

- Lazy-load all pages in App.tsx and all controls in
  pipeline-step-settings.tsx to keep main bundle under 300KB.
2026-04-15 18:52:36 +08:00
Siddharth Kumar Sah 85b1cfc10a chore: rename Stirling-Image to ashim across entire codebase
Complete rebrand from Stirling-Image to ashim following the project
move to https://github.com/ashim-hq/ashim.

Changes across 117 files:
- Package scope: @stirling-image/* → @ashim/*
- GitHub URLs: stirling-image/stirling-image → ashim-hq/ashim
- Docker Hub: stirlingimage/stirling-image → ashimhq/ashim
- GitHub Pages: stirling-image.github.io → ashim-hq.github.io
- All branding text: "Stirling Image" → "ashim"
- Docker service/volumes/user: stirling → ashim
- Database: stirling.db → ashim.db
- localStorage keys: stirling-token → ashim-token
- Environment variables: STIRLING_GPU → ASHIM_GPU
- Python cache dirs: .cache/stirling-image → .cache/ashim
- SVG filter IDs, test prefixes, and all other references
2026-04-14 20:55:42 +08:00
dfffc0a8cc feat(noise-removal): SOTA noise removal with 4 quality tiers (#57)
* feat(noise-removal): register tool in shared constants and i18n

* feat(noise-removal): add SCUNet and NAFNet model architectures

* feat(noise-removal): add Python denoising engine with 4 quality tiers

* feat(noise-removal): add TypeScript bridge for Python sidecar

* feat(noise-removal): add frontend settings with 4-tier selector

* feat(noise-removal): register in tool registry and pipeline

* feat(noise-removal): add Fastify API route with Zod validation

* feat(noise-removal): add SCUNet and NAFNet model downloads to Docker build

* test(noise-removal): add to e2e tool page rendering tests

* test(noise-removal): add integration tests for API endpoint

* style: fix biome formatting and import ordering

* fix(noise-removal): use correct model download URLs

NAFNet model is hosted on HuggingFace, not GitHub releases.
Also align SCUNet URL to use the KAIR releases (same as Docker build).

* fix(noise-removal): remove emojis from tier selector, simplify labels

Drop emoji icons from Quick/Balanced/Quality/Maximum buttons. Replace
technical algorithm names with plain descriptions users can understand.

---------

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 19:50:23 +08:00
a8c7b92ca5 feat: SOTA image enhancement with one-click auto-improve (#55)
* feat(image-enhancement): add analysis and correction types

* feat(image-enhancement): implement auto-enhance analysis and correction engine

* test(image-enhancement): add unit tests for auto-enhance engine

* feat(image-enhancement): add API route with analyze endpoint and register in constants/i18n

* feat(image-enhancement): add UI component with mode selector, intensity slider, and analysis badges

* test(image-enhancement): add integration and e2e tests

* fix(image-enhancement): use modulate instead of gamma for exposure correction

Sharp's gamma() only accepts values between 1.0 and 3.0, but brightening
underexposed images computed gamma < 1.0. Switch to modulate({ brightness })
which handles both brightening and darkening correctly.

---------

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 17:48:53 +08:00
a1e11dff74 feat(gif-tools): SOTA upgrade with 6 processing modes (#52)
* feat(find-duplicates): upgrade to 128-bit dHash with metadata and thumbnails

* feat(find-duplicates): add custom-results display mode and duplicate store

* feat(find-duplicates): add results overview grid and detail comparison view

* feat(find-duplicates): overhaul settings with sensitivity presets and download actions

* feat(find-duplicates): update i18n description

* chore: replace jsqr with zxing-wasm for barcode reading

* feat(barcode-read): rewrite backend with zxing-wasm for all barcode types

* feat(barcode-read): rewrite frontend with multi-file, results table, progress, export

- Multi-file sequential processing with per-file progress
- Structured results table with type badges and copy per-result
- Copy All and Export CSV functionality
- Thorough scan toggle (maps to tryHarder in zxing-wasm)
- Before/after view shows annotated image with bounding boxes
- Updated tool description in constants and i18n

* feat(stitch): update tool name and description for redesign

* feat(stitch): add grid layout, alignment, border, radius, quality, and new resize modes

* feat(stitch): redesign settings UI with grid, alignment, border, radius, quality

* test(stitch): add stitch to e2e tool navigation suite

* feat(vectorize): redesign with dual-engine backend and preset-driven UI

- Backend: potrace for B&W, VTracer (@neplex/vectorizer) for full-color vectorization
- Frontend: 5 presets (logo, illustration, photo, sketch, custom)
- Settings: color precision, gradient step, detail, smoothing, corner threshold, invert
- Updated OpenAPI spec and i18n description

* feat(border): redesign with presets, shadow, padding color, swatches

- Add 8 one-click presets (Clean White, Gallery Black, Shadow, Rounded, Polaroid, Vintage, Minimal, Cinematic)
- Implement proper shadow rendering with blur, offset X/Y, color, opacity
- Add padding color control (was hardcoded white)
- Add color swatches for quick color selection
- Wrap in form for Enter key submission
- Add smart validation (requires at least one effect active)
- Align frontend/backend slider ranges
- Organize UI with sections and collapsible shadow toggle

* feat(split): overhaul image splitting with live grid overlay and tile preview

- Add interactive-split display mode with SplitCanvas component
- Live SVG grid overlay on uploaded image showing split boundaries
- Two split modes: Grid (NxM) and Tile Size (px dimensions)
- 9 grid presets (2x1, 1x2, 2x2, 3x1, 1x3, 3x3, 2x3, 3x2, 4x4)
- Output format selection (original/PNG/JPG/WebP) with quality slider
- Post-split tile preview thumbnails with individual download
- Download All as ZIP button
- HEIC/HEIF preview with loading spinner
- Backend: tile-size mode, output format conversion, quality control
- Zustand store for split state management

* feat(split): rewrite backend and frontend settings

Backend: tile-size mode, output format conversion, quality control.
Frontend: split modes, presets, format selector, tile preview grid.

* feat(border): add live CSS preview and remove before/after slider

- Add imageWrapperStyle prop to ImageViewer for live border preview
- Add onImageStyle callback through tool-page to settings components
- Change border displayMode to no-comparison (no slider)
- BorderControls sends live CSS styles (border, padding, radius, shadow)
- Preview updates instantly as user adjusts sliders or clicks presets

* fix: repair i18n file corrupted by formatter during merge conflict resolution

* feat(border): enable live CSS preview in right pane as settings change

* fix(border): keep CSS preview visible after processing for WYSIWYG consistency

* chore(gif-tools): scaffold for SOTA upgrade

- Add animated GIF test fixture (3 frames, 100x100)
- Update tool description to reflect new capabilities
- Add fflate dependency to API for ZIP creation

* feat(gif-tools): rewrite backend with 6 processing modes

Modes: resize (with percentage), optimize (colors/dither/effort),
speed (delay manipulation), reverse (frame reorder), extract
(single/range/all with ZIP), rotate (90/180/270 + flip).

Adds /api/v1/tools/gif-tools/info metadata endpoint.

* test(gif-tools): add integration tests for all 6 modes

Tests metadata endpoint, resize (pixel + percentage), optimize,
speed, reverse, extract (single/range/all), and rotate (angle + flip).

Fix animated.gif fixture to be a real 3-frame animation (was a single
100x300 frame). Fix reverse and rotate modes to process frames
individually and reassemble via GIF binary concatenation, since
Sharp 0.33.x loses page-height metadata when reconstructing from raw
pixel data.

* feat(gif-tools): rewrite frontend with tabbed 6-mode UI

- useGifInfo hook for metadata (frame count, dimensions, duration)
- Info bar showing GIF properties
- 3x2 mode grid: Resize, Optimize, Speed, Reverse, Extract, Rotate
- Animation modes disabled for static images
- Loop control (infinite/once/custom)
- Batch processing support

* test(gif-tools): add to representative tools in e2e suite

---------

Co-authored-by: Siddharth Kumar Sah <siddharth123sk@gmail.com>
2026-04-13 16:23:07 +08:00
Siddharth Kumar Sah 570de25a2f chore: resolve merge conflicts with main (keep convertSvg helper) 2026-04-13 14:20:46 +08:00
Siddharth Kumar Sah d9704fda82 feat(pdf-to-image): redesign with thumbnails, page selection, color mode, and expanded formats
- Add preview endpoint for page thumbnails with clickable selection
- Add 8 output formats (PNG, JPEG, WebP, AVIF, TIFF, GIF, HEIC, HEIF)
- Add quality slider for lossy formats, color mode (Color/Grayscale/B&W)
- Add custom DPI input (36-1200) alongside preset buttons
- Replace reply.hijack() ZIP streaming with JSON response + server-side ZIP
- Add dedicated Zustand store with bidirectional page range sync
- Add ResultsPanel with per-page download, format/size badges
- Update integration tests (16 cases) and e2e tests (3 cases)
2026-04-13 13:43:07 +08:00
Siddharth Kumar Sah 8b974e0ab6 test(svg-to-raster): extend integration tests for all formats, quality, DPI, preview
Expand the svg-to-raster dedicated endpoint test suite from 3 to 10 tests:
- All 7 output formats (png, jpg, webp, avif, tiff, gif, heif)
- Quality setting verification (low vs high quality jpg file sizes)
- DPI setting verification (72 vs 300 dpi png file sizes)
- Preview URL generation for non-browser formats (tiff)

HEIF test skips gracefully if heif-enc is not installed (422 response).
2026-04-13 12:51:56 +08:00
Siddharth Kumar Sah d6d65b6b61 fix(test): correct edit-metadata assertion from toBeUndefined to toBeNull
The inspectMetadata function returns null (not undefined) when no EXIF
data is present. Fix the test assertion to match.
2026-04-13 01:13:30 +08:00
Siddharth Kumar Sah 92d4d2d9c6 feat(smart-crop): overhaul with face detection, social presets, and 3 modes
Replace the confusing 2-mode smart crop with a clear 3-mode system:
- Subject Focus: Sharp attention/entropy saliency crop with social media presets
- Face Focus: MediaPipe face detection with headshot framing presets
- Auto Trim: Border removal with optional pad-to-square

Adds detectFaces() to AI package, face preset constants, backward
compatibility for old mode names, and comprehensive integration tests.
2026-04-13 00:47:53 +08:00
Siddharth Kumar Sah fa3451631c test(ocr): add integration tests for quality tiers and backward compat 2026-04-12 18:42:08 +08:00
Siddharth Kumar Sah 1707521f3a feat: replace Python seam carving with caire Go binary
Replace the Python seam-carving library with caire (esimov/caire v1.5.0),
a Go-based content-aware resize engine that is faster and supports both
shrinking and enlarging via seam insertion.

- Add Go builder stage in Dockerfile to compile caire from source
- Rewrite seam-carving.ts to call caire via execFile (no Python sidecar)
- Remove content-aware-resize from PYTHON_SIDECAR_TOOLS (60s timeout)
- Add new options: blur radius, edge sensitivity, square mode, face detection
- Move content-aware toggle below standard resize in UI (subtler placement)
- Rename "Don't enlarge" to "Limit to original size" with hover tooltip
- Add smooth progress bar for medium-duration tools
- Delete seam_carve.py and remove seam-carving pip dependency
- Update integration tests and visual regression screenshots
2026-04-11 17:49:28 +08:00
Siddharth Kumar Sah bbae319333 Merge branch 'refactor/remove-lite-variant' 2026-04-10 22:36:39 +08:00
Siddharth Kumar Sah cc8a27239b fix: complete RBAC implementation lost during merge
Several RBAC features from feat/rbac-permissions were silently lost
during the merge into main. This restores and completes them:

- Add permissions and teamName to login/session API responses
- Export Permission and Role types from shared package
- Filter settings tabs by user permissions in frontend
- Extend useAuth hook with role, permissions, and hasPermission
- Restrict teams listing to admin only
- Add admin override for API keys, files, and pipelines listing
- Add ownership scoping to file access, download, and delete routes
- Register userFileRoutes in integration test server
- Mock auth import in unit permissions test to avoid SQLite lock
2026-04-10 21:25:30 +08:00
Siddharth Kumar Sah 59f40dbfd4 feat: add permission checks and admin override to pipeline routes
Replace requireAuth with requirePermission("pipelines:own") on pipeline
save/list/delete routes. Admin users with pipelines:all can see and
delete all pipelines. Unauthorized delete returns 404 to avoid leaking
resource existence.
2026-04-10 21:25:30 +08:00
Siddharth Kumar Sah 86ba69825a feat: add permission checks and ownership scoping to user-files routes
Replace getAuthUser (optional auth) with requirePermission("files:own") on all
user-files routes, enforcing mandatory authentication and ownership checks.
Admin users with files:all permission bypass ownership restrictions. Returns 404
(not 403) for ownership failures to avoid leaking resource existence.
2026-04-10 21:25:30 +08:00
Siddharth Kumar Sah d776680f2d feat: add permission checks and admin override to API key routes
Replace requireAuth with requirePermission(apikeys:own). Admin users
with apikeys:all can see and delete any user's keys.
2026-04-10 21:25:30 +08:00
Siddharth Kumar Sah 885ace54f0 feat: add tools:use permission check to tool, batch, pipeline, and upload routes 2026-04-10 21:25:30 +08:00
Siddharth Kumar Sah 49431772ec feat: include permissions and teamName in login/session responses 2026-04-10 21:25:30 +08:00
Siddharth Kumar Sah 1a99571153 feat: add backend permission map and requirePermission middleware
Create the RBAC permission module that maps roles to permissions and
provides a requirePermission middleware to replace requireAdmin. Update
the test server to use requirePermission for the admin health check.
2026-04-10 21:25:30 +08:00
Siddharth Kumar Sah 48cf919fb7 test: add integration tests for pdf-to-image endpoints 2026-04-10 20:56:13 +08:00
Siddharth Kumar Sah 958b10cb45 refactor: remove lite variant, fix release workflow
- Remove all lite/full variant logic from frontend, API, shared constants,
  docs, and tests (single unified Docker image only)
- Replace single QEMU multi-arch Docker build with per-architecture native
  builds (amd64 + arm64) and manifest merge to fix disk space exhaustion
- Add disk cleanup step and per-platform build cache scopes
- Switch release trigger from push to workflow_dispatch
- Add GitHub issue templates and PR template
2026-04-10 17:38:54 +08:00
Siddharth Kumar Sah fc7d355d08 test: add integration tests for content-aware resize endpoint 2026-04-07 23:36:51 +08:00
Siddharth Kumar Sah eda151faf3 test: add integration tests for stitch API endpoint 2026-04-07 21:53:42 +08:00
Siddharth Kumar Sah 5284d5ece5 feat: add edit-metadata API route with inspect and edit endpoints 2026-04-06 19:27:33 +08:00
5d8556254f fix: batch file ordering and format preservation for image tools (#20)
* feat: add resolveOutputFormat utility for input format preservation

* fix: preserve file order in batch processing with X-File-Results header

Collect all results before streaming the ZIP to guarantee upload order.
Replace X-File-Order with index-based X-File-Results header that maps
each upload index to its processed filename, handling failures and
duplicate filenames correctly.

Closes #13

* fix: use X-File-Results for index-based batch file matching

The frontend now matches processed files to entries by upload index
instead of fragile name/position matching.

* feat: preserve input format in smart-crop with quality control

Smart crop now outputs in the same format as the input (JPG in, JPG out)
instead of always converting to PNG. Adds an optional quality setting
(default 95) for lossy formats.

Closes #14

* feat: add output quality slider to smart crop settings UI

* feat: preserve input format in crop tool

* feat: preserve input format in color adjustment tools

Applies to brightness-contrast, saturation, color-channels, and
color-effects tool routes.

* refactor: avoid double encode in smart-crop content mode

For the simple trim path (no pad-to-square), chain .toFormat() on the
trim pipeline directly instead of creating a second Sharp instance.
This eliminates a redundant intermediate encode that degraded quality
for lossy formats. Also use trimmed.info dimensions instead of a
separate metadata() call for the pad-to-square path.

---------

Co-authored-by: Siddharth Kumar Sah <siddharth123sk@gmail.com>
2026-04-06 12:53:53 +08:00
stirling-imageandGitHub 449a2fc319 feat: lightweight Docker image without AI/ML tools (:lite tag)
Closes #1
2026-04-05 00:23:21 +08:00
Siddharth Kumar Sah 6717c17a26 feat: add HEIC/HEIF format support for input and output
Add bidirectional HEIC support using system libheif CLI tools (heif-enc/heif-dec)
for HEVC encoding/decoding, since Sharp's bundled libheif only supports AV1.

- HEIC input: all tools now accept iPhone HEIC photos via heif-dec pre-processing
- HEIC output: convert tool produces true HEIC (HEVC) via heif-enc
- Docker: adds libheif-examples package for heif-enc/heif-dec CLI tools
- Tests: full conversion matrix (7x7), unit tests, and Playwright e2e tests
- Docs: updated OpenAPI spec, image-engine docs, getting-started, llms-full.txt
2026-04-04 21:33:48 +08:00
Siddharth Kumar Sah 9d621734c3 fix: resolve multiple API and e2e test bugs
- Health endpoint returns "healthy" instead of "ok" for consistency
- MAX_USERS now configurable via env var (default 5)
- People API returns team names instead of UUIDs in register/list
- PUT user update accepts team names (name-first lookup, fallback to ID)
- Login rate limit follows global rate limit when RATE_LIMIT_PER_MIN > 1000
- Strip-metadata preserves original format encoding instead of always PNG
- Fix e2e tests: rotate/crop/border button selectors match actual UI
- Fix e2e tests: create Engineering/Design teams in people test setup
- Fix e2e tests: people UI uses select for team field, not text input
- Update visual regression baseline for tablet home page
2026-04-04 17:44:51 +08:00
Siddharth Kumar Sah 4fa8dd0780 fix: allow SVG files in the convert tool
SVG files were rejected by the convert endpoint because
validateImageBuffer only recognized raster magic bytes. This adds
text-based SVG detection, sanitization in the tool factory, and
proper Sharp density handling so SVG-to-raster conversion works
through the standard convert route.
2026-03-30 11:37:09 +08:00
Siddharth Kumar Sah 4577d5c30e fix: simplify public health to static response, add 403 test
Remove DB probe from public health endpoint - it only needs to confirm
the process is alive. Add test for non-admin user getting 403 on admin
health endpoint.
2026-03-28 19:08:17 +08:00
Siddharth Kumar Sah 818e5877a7 fix: move health diagnostics behind admin auth
Public GET /api/v1/health now returns only status and version.
Full diagnostics (uptime, storage, database, queue) moved to
GET /api/v1/admin/health which requires admin authentication.
2026-03-28 19:08:17 +08:00
Siddharth Kumar Sah 813fa6b7e8 fix: use two-pass validation in settings PUT to prevent partial writes
Validation now runs on all entries before any database writes.
Previously, clean entries could be written before a later malicious
entry triggered a 400 response.
2026-03-28 19:08:17 +08:00
Siddharth Kumar Sah 8a62093130 fix: reject HTML tags in settings API to prevent stored XSS
PUT /api/v1/settings now returns 400 if any key or value contains HTML
tags. Settings are configuration values - there is no legitimate use
case for HTML in them.
2026-03-28 19:08:17 +08:00
Siddharth Kumar Sah c48bfba879 feat: make AI tools pipeline-compatible and add search to tool picker
Register remove-background, upscale, and blur-faces in the pipeline
tool registry via registerToolProcessFn(). These tools keep their
custom HTTP routes (with progress callbacks) for direct use, but now
also provide a simple process function for pipeline/batch execution.

Add a search bar to the pipeline tool picker so users can quickly
find tools by name or description. Uses the existing SearchBar
component and the same filtering pattern as the main tool panel.

Update tests to reflect that these 3 AI tools are now pipeline-
compatible (moved from excluded to included assertions).
2026-03-28 15:09:23 +08:00
Siddharth Kumar Sah 4a504281a3 fix: surface hidden errors and add batch rejection tests
Fix empty catch blocks in settings dialog (logo upload/delete) and
automate page (pipeline save) that silently swallowed errors. Users
now see error messages when these operations fail.

Add 5 integration tests verifying batch endpoint returns 404 for
custom-route tools (remove-background, upscale, ocr, blur-faces,
erase-object), matching the pipeline rejection tests.
2026-03-28 14:45:14 +08:00
Siddharth Kumar Sah fa01388742 test: add pipeline tool compatibility tests
Add 8 tests that would have caught the pipeline bug where custom-route
tools (remove-background, upscale, ocr, etc.) were shown in the
pipeline picker but failed silently when executed.

New tests:
- GET /api/v1/pipeline/tools returns factory-registered tool IDs
- Verify resize, crop, convert, compress, rotate are included
- Verify remove-background, upscale, ocr, blur-faces, erase-object,
  info, collage, compare are excluded
- Pipeline execution returns 400 for each custom-route tool
2026-03-28 14:42:27 +08:00
Siddharth Kumar Sah b08e006512 fix(tests): remove temp DB cleanup that races with other test files
The integration test cleanup was deleting the shared temp directory
(rmSync on dirname(DB_PATH)), which causes SQLITE_IOERR_FSTAT in
other test files that still reference the same database. The temp
directory uses a random UUID under /tmp and is cleaned up by the OS.
2026-03-28 12:49:23 +08:00
Siddharth Kumar Sah 655398e184 test(api): add integration tests for API docs endpoint
Also update GitHub Pages REST API doc to link to /api/docs.
2026-03-27 13:50:03 +08:00
Siddharth Kumar Sah 849878e72f feat(api): register docs route in server and test helper 2026-03-27 13:50:03 +08:00
Siddharth Kumar Sah 6a13065706 feat(api): add logo upload/serve/delete routes with tests
Add branding API at /api/v1/settings/logo supporting:
- POST: admin uploads PNG/SVG/JPEG (max 500KB), auto-converts to 128x128 PNG
- GET: public endpoint serves custom logo (404 if none)
- DELETE: admin removes custom logo

Includes 13 integration tests covering upload, conversion, size/type
validation, auth enforcement, resize, and idempotent deletion.
2026-03-26 01:10:51 +08:00
Siddharth Kumar Sah acfff754b5 feat(api): add tool filtering and DB-backed cleanup settings
Add feature flag support to skip disabled/experimental tools at startup
by reading disabledTools and enableExperimentalTools from the settings
table. Refactor cleanup.ts to read tempFileMaxAgeHours from DB settings
(with env var fallback) and respect the startupCleanup setting.
2026-03-26 01:10:51 +08:00
Siddharth Kumar Sah 585d66f0c9 refactor: rename Tool.alpha to Tool.experimental 2026-03-26 01:10:51 +08:00
Siddharth Kumar Sah ab370a74fe feat(api): add teams CRUD routes and update auth team references 2026-03-26 01:10:51 +08:00
Siddharth Kumar Sah 432cc92471 feat: harden auth, security headers, SVG sanitization, and pipeline ownership
- Add password strength validation (8+ chars, uppercase, lowercase, number)
- Add username validation rules
- Optimize API key lookup with SHA-256 prefix (O(1) vs O(n) scan)
- Require password change on default admin first login
- Revoke API keys on password change
- Add session cleanup cron (hourly expired session purge)
- Add Permissions-Policy, HSTS, and CSP security headers in production
- Strengthen SVG sanitizer: block XInclude, foreignObject, processing
  instructions, javascript/data/file URI schemes
- Add userId ownership to pipelines with authorization checks
- Add keyPrefix column to api_keys table
- Update integration tests for new auth behavior
2026-03-24 21:38:06 +08:00
Siddharth Kumar Sah e5086ada6e feat: extract auto-orient utility and expand test coverage
Extract EXIF auto-orientation logic into a shared auto-orient module
used by both single-tool and batch routes. This ensures camera photos
display correctly after processing regardless of entry point.

Also expands e2e and integration tests significantly.
2026-03-24 20:37:14 +08:00
Siddharth Kumar Sah 80e536bcf8 chore: remove dead code, add test infrastructure, update docs
- Delete 3 dead files: use-batch-processor.ts, use-i18n.ts, smart-crop.ts (AI package)
- Remove dead getJobProgress function and unused runPythonScript wrapper
- Remove 6 unused imports across API and web apps
- Remove unused shared types (ImageFormat, AppConfig, ApiError, HealthResponse, JobProgress)
  and constants (SUPPORTED_INPUT_FORMATS/OUTPUT_FORMATS, DEFAULT_OUTPUT_FORMAT)
- Remove unused store method (setOriginalBlobUrl) and clean AI package re-exports
- Add test infrastructure: vitest config, unit/integration/e2e tests, fixtures, screenshots
- Add Docker test infrastructure: Dockerfile.test, docker-compose.test.yml
- Add download_models.py for pre-baking AI model weights in Docker
- Add filename sanitization utility (apps/api/src/lib/filename.ts)
- Update .gitignore to exclude coverage/, *.tsbuildinfo, .superpowers/, test artifacts
- Update .dockerignore to exclude test/coverage/IDE artifacts from builds
- Update docs: remove smart crop from AI docs (uses Sharp directly), update bridge docs
2026-03-23 11:46:45 +08:00