Commit Graph
4 Commits
Author SHA1 Message Date
SnapOtter e358634f8b fix: production CSP blocking PostHog/Sentry/Scalar and silent failure hardening
The production CSP had connect-src/script-src/font-src set to 'self' only,
silently blocking all analytics and error reporting in production while
working fine in dev (where CSP is not applied).

CSP fixes:
- Add PostHog ingest + assets origins to connect-src and script-src
- Add Sentry ingest origin to connect-src
- Add Scalar fonts origin to font-src for API docs pages
- Extract CSP construction into testable buildCsp() function

Silent failure hardening:
- Settings/features stores now set loadError flag and allow retry on
  subsequent fetch() calls instead of permanently caching failed state
- Analytics init no longer sets initialized=true before the try block,
  allowing retry on failure
- Settings dialog Tools section disables save button when settings
  failed to load, preventing accidental config wipe
- Branding logo storage moved from process.cwd() to FILES_STORAGE_PATH
  so logos persist across Docker container recreation

Test coverage:
- 16 CSP directive tests covering all external service domains
- Store retry-on-error behavior tests for settings and features stores
- Analytics init retry-after-failure test
2026-05-05 17:16:19 +08:00
SnapOtter 4d3e5e9c02 fix: defer PostHog/Sentry loading until user consents to telemetry
PostHog SDK was initialized on app mount based only on the server-level
config flag, ignoring user consent. This caused network requests to
us-assets.i.posthog.com (config.js, web-vitals.js, dead-clicks-autocapture.js)
even when the user had not opted in or had explicitly declined telemetry.

- Replace static imports of posthog-js and @sentry/react with dynamic
  import() so the SDK bundles are not downloaded until consent is granted
- Gate initAnalytics on analyticsConsent.analyticsEnabled === true,
  not just server config.enabled
- Add consent re-check after each await import() to handle revocation
  during the async load
- Add shutdownAnalytics() that calls opt_out_capturing() + reset()
  for mid-session consent revocation
- setAnalyticsConsent(false) now triggers full SDK shutdown automatically
- Rewrite analytics test suite with 44 tests covering init gating,
  shutdown lifecycle, consent toggle, race conditions, and Sentry callbacks

Closes #98
2026-04-29 14:16:38 +08:00
SnapOtter 03f82567d0 test: expand API and GUI test coverage across all tools
Add ~500 new E2E tests and ~300 new integration tests covering:

- 24 new GUI E2E specs: navigation, responsive layout, keyboard shortcuts,
  tool UI for all 35 non-AI tools, batch/pipeline workflows, settings/RBAC,
  visual regression, accessibility, and performance budgets
- 3 new E2E-Docker specs: batch workflows, advanced pipelines, cross-format
- 1 new adversarial integration test: memory pressure, corrupted files,
  unicode filenames, extreme dimensions, pipeline/batch edge cases
- 29 expanded integration test files: HEIC/HEIF input, large files, parameter
  boundaries, batch processing, format edge cases across all tools
- Cross-format matrix expanded: 641 tests covering every tool x 18 formats
- AI bridge unit tests expanded: lifecycle, tool modules, error propagation
- Unit test gaps filled: analytics, tool-registry, web stores

Also fixes:
- vitest.config.ts: exclude e2e-docs and e2e-landing from Vitest runner
- AI E2E specs: add sidecar health check to skip gracefully when Python
  AI backend is not running instead of timing out
2026-04-29 01:39:25 +08:00
SnapOtter 733ebe8010 test: major coverage expansion — 18 new test files, ~830 new tests
Unit tests: 1354 → 1781 (+427)
- 11 new AI bridge module tests (packages/ai/ from 2/13 → 13/13 files)
- files-page-store (0% → full), pdf-to-image-store, features-store expanded
- saturation and edit-metadata image-engine operations
- analytics route, features route, web analytics lib, api-extended

Integration tests: ~2070 → 2320 (+250)
- 31 integration files expanded with branch-coverage-targeted tests
- progress.ts SSE endpoints (28% → comprehensive, +18 tests)
- gif-tools all modes (+18), pdf-to-image format variants (+13)
- Cross-format matrix expanded to 17 tools × 17 formats (467 tests)
- Adversarial: concurrent, memory pressure, unicode filenames, pipeline limits

E2E-Docker: +1020 lines across 6 spec files
- Info, colors, sharpening, base64, QR read, JXL/ICO/SVG formats
- Strip-metadata, image-enhancement, content-aware-resize expanded
- Batch pipelines, multi-format batches, HEIC input coverage
2026-04-26 12:03:08 +08:00