Skip to content

Commit de7d57b

Browse files
authored
Merge pull request #8 from atomantic/dev
Security hardening, DRY cleanup, and bug fixes (v0.8.1)
2 parents 10b8c90 + c0dd0d3 commit de7d57b

98 files changed

Lines changed: 1695 additions & 1915 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changelog/v0.8.x.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# v0.8.x
2+
3+
## Added
4+
- 12 shared server utilities (`paths`, `downloadImage`, `parseYear`, `lifespan`, `validation`, `asyncHandler`, `sseHelpers`, `operationTracker`, `resolveCanonical`, `browserConnect`, `applyOverrides`, `batchFetchPersons`)
5+
- `useBrowserConnection` and `useSSE` client hooks for deduplication
6+
- Path traversal defense-in-depth across all file-serving endpoints
7+
- FTS5 query sanitization for search
8+
- CORS origin restriction via `CORS_ORIGIN` env var
9+
- Request body whitelisting on provider/browser routes
10+
- URL validation replacing string `includes()` checks
11+
- `--dry-run` flag for purge script
12+
- AbortController cleanup on PersonDetail navigation
13+
- PWA support: favicon, manifest, apple-touch-icon, theme-color
14+
15+
## Changed
16+
- CI no longer auto-increments version on push to dev
17+
- Release workflow no longer bumps version after release (changelog archiving preserved)
18+
- CI permissions downgraded from `contents: write` to `contents: read`
19+
- `process.exit(1)` in fetcher replaced with typed error
20+
- ID mapping cache changed from FIFO to LRU eviction
21+
- AI discovery runs bounded with MAX_STORED_RUNS limit
22+
- Path finding guarded against infinite loops
23+
- Error handler now logs stack traces
24+
- `requestTimeout` middleware wired up
25+
- `Person.parents` type corrected to `(string | null)[]`
26+
- Scripts standardized on `import.meta.dirname` and shared types
27+
28+
## Fixed
29+
- `person_computed` view multi-row bug in vital event joins
30+
- `typeof gen !== '?'` bug in logPerson
31+
- Stale closures in IntegrityPage loader functions
32+
- D3 zoom cleanup missing in SparseTreePage
33+
- `useSocket` spread in deps array causing re-renders
34+
- `useSocketConnection` returning stale snapshot instead of reactive state
35+
- Dead state (`setScrapedData`, `setImportFile`) removed
36+
- Safe JSON.parse on localStorage in PersonDetail
37+
- Purge script whole-token matching (prevents partial ID matches)
38+
- Migration script wrapped in transaction
39+
40+
## Removed
41+
- 20+ duplicate `DATA_DIR` declarations across services
42+
- 3 duplicate `downloadImage` implementations
43+
- 7 duplicate SSE header setup blocks
44+
- 15 duplicate ULID validation blocks in person routes
45+
- 3 duplicate browser connection blocks
46+
- 3 duplicate operation tracker implementations
47+
- 6 duplicate photo-serve route handlers
48+
- Duplicate `BrowserStatus` interface in IndexerPage

.github/workflows/ci.yml

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ concurrency:
1212
cancel-in-progress: true
1313

1414
permissions:
15-
contents: write
15+
contents: read
1616

1717
jobs:
1818
build:
@@ -151,41 +151,3 @@ jobs:
151151
name: scraper-test-results
152152
path: test-results/
153153
retention-days: 7
154-
155-
bump-version:
156-
name: Bump Version
157-
runs-on: ubuntu-latest
158-
needs: [unit-tests, integration-tests, scraper-tests]
159-
# Only on push to dev, not PRs, and only if all tests passed
160-
if: |
161-
github.event_name == 'push' &&
162-
github.ref == 'refs/heads/dev' &&
163-
!contains(github.event.head_commit.message, '[skip ci]')
164-
165-
steps:
166-
- uses: actions/checkout@v4
167-
with:
168-
token: ${{ secrets.GITHUB_TOKEN }}
169-
170-
- name: Configure git
171-
run: |
172-
git config user.name "github-actions[bot]"
173-
git config user.email "github-actions[bot]@users.noreply.github.com"
174-
175-
- name: Bump patch version
176-
run: |
177-
CURRENT_VERSION=$(node -p "require('./package.json').version")
178-
MAJOR=$(echo $CURRENT_VERSION | cut -d. -f1)
179-
MINOR=$(echo $CURRENT_VERSION | cut -d. -f2)
180-
PATCH=$(echo $CURRENT_VERSION | cut -d. -f3)
181-
NEW_PATCH=$((PATCH + 1))
182-
NEW_VERSION="$MAJOR.$MINOR.$NEW_PATCH"
183-
184-
npm version $NEW_VERSION --no-git-tag-version
185-
cd shared && npm version $NEW_VERSION --no-git-tag-version && cd ..
186-
cd client && npm version $NEW_VERSION --no-git-tag-version && cd ..
187-
cd server && npm version $NEW_VERSION --no-git-tag-version && cd ..
188-
189-
git add package.json package-lock.json shared/package.json client/package.json server/package.json
190-
git commit -m "build: bump version to $NEW_VERSION [skip ci]"
191-
git push

.github/workflows/release.yml

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -100,19 +100,14 @@ jobs:
100100
env:
101101
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
102102

103-
- name: Prep dev branch for next release
103+
- name: Archive changelog on dev branch
104104
if: steps.tag-check.outputs.exists == 'false'
105105
run: |
106-
# Get current version (the one we just released)
107106
CURRENT_VERSION=${{ steps.package-version.outputs.version }}
108107
MAJOR=$(echo $CURRENT_VERSION | cut -d. -f1)
109108
MINOR=$(echo $CURRENT_VERSION | cut -d. -f2)
110109
MAJOR_MINOR="$MAJOR.$MINOR"
111110
112-
# Increment minor, reset patch to 0
113-
NEW_MINOR=$((MINOR + 1))
114-
NEW_VERSION="$MAJOR.$NEW_MINOR.0"
115-
116111
# Checkout dev branch
117112
git fetch origin dev
118113
git checkout dev
@@ -143,14 +138,3 @@ jobs:
143138
git push origin main
144139
git checkout dev
145140
fi
146-
147-
# Update package.json files for next version
148-
npm version $NEW_VERSION --no-git-tag-version
149-
cd shared && npm version $NEW_VERSION --no-git-tag-version && cd ..
150-
cd client && npm version $NEW_VERSION --no-git-tag-version && cd ..
151-
cd server && npm version $NEW_VERSION --no-git-tag-version && cd ..
152-
153-
# Commit and push version bump
154-
git add package.json package-lock.json shared/package.json client/package.json server/package.json
155-
git commit -m "build: prep v$NEW_VERSION for next release [skip ci]"
156-
git push origin dev

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,7 @@ client/public/playwright-report/
2525

2626
# Screenshots (may contain personal family data)
2727
images/
28-
.playwright-mcp
28+
.playwright-mcp
29+
30+
# Terminal themes
31+
.ghostty-theme

client/index.html

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,16 @@
22
<html lang="en">
33
<head>
44
<meta charset="UTF-8" />
5-
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
65
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
76
<title>SparseTree</title>
7+
<meta name="theme-color" content="#3b82f6" />
8+
<meta name="apple-mobile-web-app-capable" content="yes" />
9+
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
10+
<meta name="apple-mobile-web-app-title" content="SparseTree" />
11+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
12+
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
13+
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
14+
<link rel="manifest" href="/manifest.json" />
815
<script>
916
// Apply theme class immediately to prevent flash
1017
(function() {

client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@fsf/client",
3-
"version": "0.7.12",
3+
"version": "0.8.3",
44
"type": "module",
55
"scripts": {
66
"dev": "vite --port 6373",

client/public/apple-touch-icon.png

12.4 KB
Loading

client/public/favicon.ico

4.19 KB
Binary file not shown.

client/public/favicon.svg

Lines changed: 55 additions & 0 deletions
Loading

client/public/icon-192.png

11.8 KB
Loading

0 commit comments

Comments
 (0)