Skip to content

Implement SSH Git Sync with TOFU Host Key Verification and UI Changes#29

Merged
johnwmail merged 11 commits into
mainfrom
feature/sshgit
Jun 16, 2026
Merged

Implement SSH Git Sync with TOFU Host Key Verification and UI Changes#29
johnwmail merged 11 commits into
mainfrom
feature/sshgit

Conversation

@johnwmail

Copy link
Copy Markdown
Owner

No description provided.

ocode and others added 11 commits June 15, 2026 10:07
- New DB migration 007: adds auth_type, encrypted_ssh_key to git_config,
  plus git_known_hosts table for TOFU
- sqlc queries updated: UpsertGitConfig includes new fields,
  new queries for known hosts CRUD
- Backend git.go: SSH auth via go-git/plumbing/transport/ssh,
  TOFU HostKeyCallback with structured error types
  (HostKeyUnknownError, HostKeyChangedError)
- Backend server.go: updated config handlers for SSH fields,
  new endpoints for trust-hostkey, list-trusted-hosts, delete-trusted-host,
  structured host key errors returned from push/pull
- Frontend crypto: encryptSSHKey/decryptSSHKey helpers
- Frontend api: updated types, new trusted hosts API calls,
  push/pull handle structured host key errors
- Frontend GitSync: SSH key config auto-detected from URL (git@/ssh://),
  TOFU prompt on first connection, changed-key warning,
  trusted hosts management UI, passphrase-protected SSH key support

Co-authored-by: Shelley <shelley@exe.dev>
Comprehensive end-to-end test of SSH git sync with TOFU host key
verification. Uses an in-process SSH server (golang.org/x/crypto/ssh)
serving a local bare git repository. Tests:

1. Push with unknown host → HostKeyUnknownError
2. Trust host key via TrustHostKey
3. Push succeeds after trust
4. Push entries and verify content in remote
5. Pull from remote restores DB entries
6. Host key changed → HostKeyChangedError
7. Trust new key, push works again
8. Verify all 3 entries + .gpg-id in remote after re-push
9. Delete trusted host → HostKeyUnknownError again

All existing tests continue to pass.

Co-authored-by: Shelley <shelley@exe.dev>
Replaces URL-based auto-detection of auth type with explicit
two-tab interface: left tab for HTTPS (PAT), right tab for SSH (key).

- Removes detectAuthType() function
- handleUrlChange now only sets repoUrl, not authType
- Tab bar at top of config form with 🔐 HTTPS / 🔑 SSH buttons
- URL placeholder adapts to selected auth type
- Same pattern in both initial config and update config sections
- Help text updated to remove 'auto-detected' language

Co-authored-by: Shelley <shelley@exe.dev>
- Updated openGitSync helper in both test files to explicitly
  click the HTTPS tab for robustness
- Updated configureGit helper to click HTTPS tab before filling
- Extended Basic UI test to verify tab visibility (HTTPS/SSH)
- Added new test 'git sync tab switching shows correct auth fields'
  verifying tab toggling shows/hides the right credential fields
- All existing tests remain compatible: HTTPS is default tab,
  URL/PAT placeholders unchanged

Co-authored-by: Shelley <shelley@exe.dev>
Commit 5e031c0 removed the optional registration code input from the
setup UI in open mode (only shows in protected mode). E2E tests still
unconditionally tried to fill a non-existent placeholder, causing all
registerAndLogin helpers to time out.

- Updated placeholder selector from '6-digit code from admin' to
  '6-digit code from admin (required)' (new UI text)
- Added .catch(() => {}) on fill calls so open mode tests silently
  skip the field when absent (registration-protected tests keep the
  strict fill for proper coverage)
- Added test.beforeAll mode check in registration-protected.spec.ts
  to skip when server is not in protected mode

Co-authored-by: Shelley <shelley@exe.dev>
- Remove reuseExistingServer: true from playwright config so each
  npx playwright test gets a fresh server with correct env vars
- Remove all kill_port_18080 calls from script (dead code now)
- Fix openGitSync helper in git-sync-one-way test to look for both
  git-auth-https-tab (initial config) and git-auth-https-tab-update
  (after git is configured) using auto-retrying click to avoid
  race conditions with component re-render

Co-authored-by: Shelley <shelley@exe.dev>
golangci-lint v2.12.2 errcheck flagged 7 unchecked error returns in
git_ssh_integration_test.go: listener.Close, conn.Close,
newChannel.Reject, channel.Close, and three req.Reply calls.
Prefix with explicit discard (_ =) to satisfy the linter.

Co-authored-by: Shelley <shelley@exe.dev>
Fix 3 audit issues in transitive deps:
- @babel/core (low): arbitrary file read via sourceMappingURL
- form-data (high): CRLF injection
- ws (high): memory disclosure + DoS

Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
One more errcheck violation that was missed — the success-path
req.Reply after cmd.Start().

Co-authored-by: Shelley <shelley@exe.dev>
@johnwmail johnwmail merged commit bde8979 into main Jun 16, 2026
4 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.

1 participant