Skip to content

Security hardening, DRY cleanup, and bug fixes (v0.8.1)#8

Merged
atomantic merged 7 commits intomainfrom
dev
Feb 21, 2026
Merged

Security hardening, DRY cleanup, and bug fixes (v0.8.1)#8
atomantic merged 7 commits intomainfrom
dev

Conversation

@atomantic
Copy link
Copy Markdown
Owner

Summary

Comprehensive code quality remediation addressing 95 findings from a full codebase review across ~54k LOC. Net result: 99 files changed, -227 lines (1691 added, 1918 removed).

Security Hardening

  • Path traversal defense-in-depth: All file-serving endpoints now validate resolved paths against base directories and sanitize person IDs
  • FTS5 injection fix: Search queries sanitized to escape SQLite FTS5 operators
  • CORS restriction: Replaced origin: '*' with configurable CORS_ORIGIN env var (defaults to http://localhost:6373)
  • Request body whitelisting: Provider and browser routes use pickFields() instead of spreading req.body
  • URL validation: Replaced url.includes('domain') with proper URL constructor-based validation

DRY Cleanup (12 shared server utils + 2 client hooks)

  • paths.ts — centralized DATA_DIR, PHOTOS_DIR, findPhoto(), getPhotoPath() (replaces 20+ local declarations)
  • downloadImage.ts — unified image downloader (replaces 3 implementations)
  • parseYear.ts — year parsing with BC/formal date support (replaces 4 duplications)
  • validation.ts — ID, URL, FTS sanitization utilities
  • asyncHandler.ts — Express async route wrapper
  • sseHelpers.ts — SSE header setup (replaces 7 duplicate blocks)
  • operationTracker.ts — cancellable operation lifecycle (replaces 3 duplicate patterns)
  • resolveCanonical.ts — ULID validation + ID resolution (replaces 15 blocks in person routes)
  • browserConnect.ts — browser verify/reconnect/launch (replaces 3 blocks)
  • useBrowserConnection + useSSE client hooks

Bug Fixes

  • fetcher.ts: Replaced process.exit(1) with typed error (was crashing the entire server)
  • path.service.ts: Added chunking + infinite loop guard with MAX_ITERATIONS
  • id-mapping.service.ts: Fixed FIFO→LRU cache eviction
  • ai-discovery.service.ts: Bounded discoveryRuns/Results Maps with oldest-eviction
  • 002_expanded_facts.ts: Fixed person_computed view multi-row bug in vital event joins
  • PersonDetail.tsx: Added AbortController cleanup, safe localStorage JSON.parse
  • SparseTreePage.tsx: Added D3 zoom cleanup on unmount
  • useSocket.ts: Fixed spread in deps array + stale snapshot state
  • IntegrityPage.tsx: Wrapped loader functions in useCallback
  • logPerson.ts: Fixed typeof gen !== '?'gen != null && gen !== '?'
  • purge.ts: Whole-token matching, binary file skip, --dry-run flag
  • migrate-to-sqlite.ts: Wrapped migration in transaction

CI/CD

  • Removed auto-increment of version numbers from CI (now handled in dev commits)
  • Removed post-release version bump from release workflow (changelog archiving preserved)
  • Downgraded CI permissions from contents: write to contents: read

Other

  • Added PWA support: favicon, manifest, apple-touch-icon, theme-color meta tags
  • Error handler now logs stack traces
  • Wired up requestTimeout middleware
  • Fixed Person.parents type: string[](string | null)[]
  • Scripts standardized on import.meta.dirname and shared type imports

Self-Review Checklist

  • No leftover debug code (console.log, debugger, TODO/FIXME)
  • No hardcoded secrets or credentials
  • No files that shouldn't be committed
  • No unused imports or variables
  • Consistent naming and style
  • Error handling present at system boundaries
  • No obvious logic bugs

Test Plan

  • npm run build passes across all packages
  • npm run test:unit passes
  • npm run test:integration passes
  • Verify path traversal blocked: curl http://localhost:6374/api/augment/..%2F..%2Fetc%2Fpasswd/wiki-photo returns 404/400
  • Verify FTS injection safe: search for test OR 1=1 returns results without errors
  • Verify CORS: fetch from non-localhost origin is rejected (unless CORS_ORIGIN set)
  • Smoke test: person detail page loads, search works, photo display works

github-actions Bot and others added 3 commits February 12, 2026 01:33
…removal

Remediate 95 code review findings across 7 phases:
- Add 12 shared server utils and 2 client hooks to eliminate duplication
- Harden security: path traversal, FTS injection, CORS, URL validation, body whitelisting
- Fix bugs: infinite loops, memory leaks, stale closures, missing cleanup, type errors
- Wrap async routes with error handler, wire up request timeout middleware
- Remove CI auto-increment of version numbers (now handled in dev commits)
- Add PWA support (favicon, manifest, apple-touch-icon)
Copilot AI review requested due to automatic review settings February 21, 2026 07:59
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements comprehensive security hardening, code deduplication, and bug fixes across the SparseTree genealogy application. The changes address 95 findings from a codebase review, reducing code by 227 net lines while improving security posture and maintainability.

Changes:

  • Security hardening: path traversal defense, FTS5 injection prevention, CORS restrictions, request body whitelisting, URL validation
  • DRY cleanup: 12 shared server utilities and 2 client hooks to eliminate duplicate code patterns
  • Bug fixes: database transaction wrapping, infinite loop guards, cache eviction fixes, client-side cleanup improvements
  • CI/CD improvements: removed auto-versioning, downgraded permissions
  • PWA support: added manifest, icons, and meta tags

Reviewed changes

Copilot reviewed 92 out of 99 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
server/src/utils/validation.ts New security utilities for ID, URL, and FTS sanitization
server/src/utils/paths.ts Centralized path constants and helpers
server/src/routes/augmentation.routes.ts Path traversal defense with resolve().startsWith() checks
server/src/routes/browser.routes.ts Request sanitization and path validation
server/src/db/migrations/002_expanded_facts.ts Fixed multi-row bug in vital event joins
server/src/services/path.service.ts Added infinite loop guard with MAX_ITERATIONS
scripts/migrate-to-sqlite.ts Wrapped migration in transactions
client/src/components/person/PersonDetail.tsx AbortController cleanup and null parent filtering
server/src/index.ts CORS origin restriction via environment variable
shared/src/index.ts Fixed Person.parents type to allow null values

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server/src/index.ts Outdated
Comment thread server/src/utils/validation.ts
Comment thread server/src/utils/validation.ts Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 92 out of 99 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server/src/utils/validation.ts
Comment thread server/src/utils/validation.ts
Comment thread server/src/services/path.service.ts
Comment thread server/src/services/multi-platform-comparison.service.ts Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 92 out of 99 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@atomantic atomantic merged commit de7d57b into main Feb 21, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants