Skip to content

Commit e59240b

Browse files
committed
Merge upstream/main (wesm/msgvault) into fork
Merges 71 upstream commits including: - Security fixes (command injection, path traversal, SQL injection, bounds checks) - MCP integration with stage_deletion tool - Windows support (installer, config paths, CI) - NAS/Docker deployment support with HTTP API server - Apple Mail and MBOX import commands - FTS5 index population during sync - Account management (remove-account, force reauth) - Hide-deleted filter, label search, pagination fixes - Nix flake support - Dependency updates Fork additions preserved: - SQLCipher encryption (go-sqlcipher replacing mattn/go-sqlite3) - Web UI (React/TypeScript SPA) - iMessage sync support - Google Voice Takeout import - Obsidian vault export - Backup/restore commands - Email validation in add-account Conflict resolution: unified on go-sqlcipher driver, combined struct fields, kept upstream's refactored store_resolver pattern.
2 parents 99eda11 + 21d4633 commit e59240b

168 files changed

Lines changed: 33781 additions & 2566 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.

.dockerignore

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Git
2+
.git
3+
.gitignore
4+
5+
# Build artifacts
6+
msgvault
7+
mimeshootout
8+
bin/
9+
dist/
10+
11+
# IDE/editor
12+
.idea/
13+
.vscode/
14+
*.swp
15+
*.swo
16+
*~
17+
18+
# OS
19+
.DS_Store
20+
Thumbs.db
21+
22+
# Local data (should not be in image)
23+
*.db
24+
*.db-journal
25+
*.db-wal
26+
*.db-shm
27+
tokens/
28+
attachments/
29+
analytics/
30+
31+
# Sensitive config files (prevent secrets in build context)
32+
config.toml
33+
client_secret*.json
34+
*.pem
35+
*.key
36+
37+
# Documentation (exclude most .md files but keep embedded assets)
38+
*.md
39+
!cmd/msgvault/cmd/quickstart.md
40+
!go.mod
41+
LICENSE
42+
43+
# CI/CD
44+
.github/
45+
.githooks/
46+
47+
# Nix
48+
flake.nix
49+
flake.lock
50+
result
51+
52+
# Test data
53+
testdata/
54+
*_test.go

.githooks/pre-commit

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ if [ -n "$UNFORMATTED" ]; then
1818
exit 1
1919
fi
2020

21-
# Run linter
21+
# Run linter (only check new issues vs HEAD)
2222
echo "Running linter..."
23-
if ! golangci-lint run ./... 2>&1; then
23+
if ! golangci-lint run --new-from-rev=HEAD ./... 2>&1; then
2424
echo ""
2525
echo "Lint failed. Fix errors before committing."
2626
exit 1

.github/CODEOWNERS

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# CODEOWNERS - Require approval from repo owners for critical files
2+
#
3+
# This is a security measure to prevent unauthorized changes to:
4+
# - GitHub Actions workflows (could steal secrets)
5+
# - Go module dependencies (supply chain entry point)
6+
7+
# All GitHub Actions workflows require owner approval
8+
.github/workflows/** @wesm
9+
10+
# Security-critical configuration
11+
.github/CODEOWNERS @wesm
12+
.github/dependabot.yml @wesm
13+
14+
# Supply chain: Go dependency changes require owner approval
15+
go.mod @wesm
16+
go.sum @wesm
17+
18+
# Security documentation
19+
SECURITY.md @wesm

.github/dependabot.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
version: 2
2+
updates:
3+
# Go module dependencies
4+
- package-ecosystem: "gomod"
5+
directory: "/"
6+
schedule:
7+
interval: "weekly"
8+
day: "monday"
9+
open-pull-requests-limit: 10
10+
reviewers:
11+
- "wesm"
12+
groups:
13+
minor-and-patch:
14+
update-types:
15+
- "minor"
16+
- "patch"
17+
18+
# GitHub Actions dependencies (keeps pinned SHAs current)
19+
- package-ecosystem: "github-actions"
20+
directory: "/"
21+
schedule:
22+
interval: "weekly"
23+
day: "monday"
24+
open-pull-requests-limit: 5
25+
reviewers:
26+
- "wesm"

.github/workflows/ci.yml

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ jobs:
99
test:
1010
runs-on: macos-15
1111
steps:
12-
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
12+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
1313

14-
- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
14+
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
1515
with:
1616
go-version-file: go.mod
1717

@@ -23,3 +23,43 @@ jobs:
2323

2424
- name: Lint
2525
run: make lint
26+
27+
- name: Install govulncheck
28+
run: go install golang.org/x/vuln/cmd/govulncheck@v1.1.4
29+
30+
- name: Vulnerability check
31+
run: govulncheck -tags fts5 ./...
32+
33+
test-windows:
34+
runs-on: windows-latest
35+
steps:
36+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
37+
38+
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
39+
with:
40+
go-version-file: go.mod
41+
42+
- name: Build
43+
env:
44+
CGO_ENABLED: "1"
45+
run: go build -tags fts5 -o msgvault.exe ./cmd/msgvault
46+
47+
- name: Test
48+
env:
49+
CGO_ENABLED: "1"
50+
run: go test -tags fts5 ./...
51+
52+
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
53+
with:
54+
name: msgvault-windows-amd64
55+
path: msgvault.exe
56+
57+
nix-build:
58+
runs-on: ubuntu-latest
59+
steps:
60+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
61+
62+
- uses: DeterminateSystems/nix-installer-action@c5a866b6ab867e88becbed4467b93592bce69f8a # v21
63+
64+
- name: Build
65+
run: nix build

.github/workflows/docker.yml

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
name: Docker
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags:
7+
- 'v*'
8+
pull_request:
9+
paths:
10+
- 'Dockerfile'
11+
- '.dockerignore'
12+
- '.github/workflows/docker.yml'
13+
- 'go.mod'
14+
- 'go.sum'
15+
- '**/*.go'
16+
17+
env:
18+
REGISTRY: ghcr.io
19+
IMAGE_NAME: ${{ github.repository }}
20+
21+
jobs:
22+
build:
23+
runs-on: ubuntu-latest
24+
permissions:
25+
contents: read
26+
# Only allow package writes for pushes to main/tags, not PRs
27+
packages: ${{ github.event_name != 'pull_request' && 'write' || 'read' }}
28+
29+
steps:
30+
- name: Checkout
31+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
32+
33+
- name: Set up QEMU
34+
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
35+
36+
- name: Set up Docker Buildx
37+
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
38+
39+
- name: Log in to Container Registry
40+
if: github.event_name != 'pull_request'
41+
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
42+
with:
43+
registry: ${{ env.REGISTRY }}
44+
username: ${{ github.actor }}
45+
password: ${{ secrets.GITHUB_TOKEN }}
46+
47+
- name: Extract metadata for Docker
48+
id: meta
49+
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
50+
with:
51+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
52+
tags: |
53+
# latest tag for main branch
54+
type=raw,value=latest,enable={{is_default_branch}}
55+
# version tags (v1.2.3 -> 1.2.3, v1.2.3 -> 1.2, v1.2.3 -> 1)
56+
type=semver,pattern={{version}}
57+
type=semver,pattern={{major}}.{{minor}}
58+
type=semver,pattern={{major}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.') }}
59+
# sha tag for traceability
60+
type=sha,prefix=sha-
61+
62+
- name: Prepare build args
63+
id: build_args
64+
run: |
65+
if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
66+
VERSION="${GITHUB_REF#refs/tags/}"
67+
else
68+
VERSION="dev-$(echo $GITHUB_SHA | cut -c1-8)"
69+
fi
70+
echo "version=$VERSION" >> $GITHUB_OUTPUT
71+
echo "commit=$(echo $GITHUB_SHA | cut -c1-8)" >> $GITHUB_OUTPUT
72+
echo "build_date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> $GITHUB_OUTPUT
73+
74+
- name: Build and push
75+
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
76+
with:
77+
context: .
78+
platforms: linux/amd64,linux/arm64
79+
push: ${{ github.event_name != 'pull_request' }}
80+
tags: ${{ steps.meta.outputs.tags }}
81+
labels: ${{ steps.meta.outputs.labels }}
82+
build-args: |
83+
VERSION=${{ steps.build_args.outputs.version }}
84+
COMMIT=${{ steps.build_args.outputs.commit }}
85+
BUILD_DATE=${{ steps.build_args.outputs.build_date }}
86+
cache-from: type=gha
87+
cache-to: type=gha,mode=max
88+
89+
- name: Test image (amd64)
90+
if: github.event_name == 'pull_request'
91+
run: |
92+
# Build single-arch for testing
93+
docker buildx build \
94+
--platform linux/amd64 \
95+
--load \
96+
--tag msgvault:test \
97+
--build-arg VERSION=test \
98+
--build-arg COMMIT=$(echo $GITHUB_SHA | cut -c1-8) \
99+
--build-arg BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ) \
100+
.
101+
102+
# Smoke test: version command
103+
echo "--- Version test ---"
104+
docker run --rm msgvault:test version
105+
106+
# Smoke test: help command
107+
echo "--- Help test ---"
108+
docker run --rm msgvault:test --help
109+
110+
# Smoke test: init-db (creates database)
111+
echo "--- Init DB test ---"
112+
mkdir -p /tmp/msgvault-test && chmod 777 /tmp/msgvault-test
113+
docker run --rm -v /tmp/msgvault-test:/data msgvault:test init-db
114+
test -f /tmp/msgvault-test/msgvault.db || { echo "FATAL: database not created"; exit 1; }
115+
echo "Database created successfully"
116+
117+
# Cleanup
118+
rm -rf /tmp/msgvault-test

.github/workflows/release.yml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
apt-get update
3333
apt-get install -y gcc g++ make git curl tar gzip file binutils
3434
35-
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
35+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
3636

3737
- name: Install Go
3838
run: |
@@ -75,7 +75,7 @@ jobs:
7575
tar czf "$ARCHIVE" msgvault
7676
rm msgvault
7777
78-
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
78+
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
7979
with:
8080
name: msgvault-linux-${{ matrix.goarch }}
8181
path: dist/*.tar.gz
@@ -91,9 +91,9 @@ jobs:
9191
runs-on: ${{ matrix.runner }}
9292

9393
steps:
94-
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
94+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
9595

96-
- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
96+
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
9797
with:
9898
go-version-file: go.mod
9999

@@ -136,7 +136,7 @@ jobs:
136136
tar czf "$ARCHIVE" msgvault
137137
rm msgvault
138138
139-
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
139+
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
140140
with:
141141
name: msgvault-darwin-${{ matrix.goarch }}
142142
path: dist/*.tar.gz
@@ -147,9 +147,9 @@ jobs:
147147
run:
148148
shell: bash
149149
steps:
150-
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
150+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
151151

152-
- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
152+
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
153153
with:
154154
go-version-file: go.mod
155155

@@ -177,7 +177,7 @@ jobs:
177177
powershell -Command "Compress-Archive -Path msgvault.exe -DestinationPath '$ARCHIVE'"
178178
rm msgvault.exe
179179
180-
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
180+
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
181181
with:
182182
name: msgvault-windows-amd64
183183
path: dist/*.zip
@@ -186,9 +186,9 @@ jobs:
186186
needs: [build-linux, build-darwin, build-windows]
187187
runs-on: ubuntu-latest
188188
steps:
189-
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
189+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
190190

191-
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
191+
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
192192
with:
193193
path: artifacts
194194
merge-multiple: true
@@ -259,7 +259,7 @@ jobs:
259259
fi
260260
261261
- name: Create Release
262-
uses: softprops/action-gh-release@26994186c0ac3ef5cae75ac16aa32e8153525f77 # v1
262+
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
263263
with:
264264
files: |
265265
artifacts/*.tar.gz

.gitignore

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,24 @@ oauth_client*.json
2323
# Local development state
2424
.beads/
2525
.githooks/post-commit
26+
.githooks/post-rewrite
27+
.mcp.json
28+
29+
# Python
30+
__pycache__/
31+
32+
# Go caches
33+
.gocache/
34+
.gopath/
2635

2736
# IDE
2837
.idea/
2938
.vscode/
3039
*.swp
3140
*.swo
41+
.projects/
3242

33-
# Frontend
43+
# Claude Code
44+
.claude/
3445
web/node_modules/
3546
internal/web/dist/
36-
37-
# Obsidian
38-
.obsidian/

0 commit comments

Comments
 (0)