Skip to content

feat(sync): carry the Mac's SSH route to iPhone and iPad - #3769

Merged
datlechin merged 3 commits into
mainfrom
feat/ssh-route-sync
Oct 22, 2026
Merged

datlechin merged 3 commits into
mainfrom
feat/ssh-route-sync

Conversation

@datlechin

Copy link
Copy Markdown
Member

Summary

  • ConnectionSyncField.sshRouteJson is declared and verified; the Production schema snapshot carries the field the maintainer deployed.
  • The Mac writes the route it dialed from ~/.ssh/config (hosts, ports, usernames, a hash of the tunnel fields) to the Connection record; both apps read it. iOS never writes it and dials it only while the hash matches the tunnel fields. No keys, key paths or config text are in it.
  • The Mac no longer keeps the route out of sync in adoptingDeviceLocalState.
  • Only the Mac that published a route clears it: a copy that cached the record before this build read the field keeps another Mac's route on push and in the dirty-copy merge.
  • The Mac writes the route only when it changed: one another build wrote and this one cannot read, the same route spelled differently, or a record rebuilt after the cache was dropped leaves the server's route alone.
  • Each app fetches the zone once after updating, so a record pulled by an older build brings its route.
  • iOS: a copy with an edit waiting to go up still takes a pulled route. Import replace keeps the stored route on both apps. Duplicate on iOS starts without the route, which its record would never carry.
  • Two Macs that name the same hops differently in ~/.ssh/config no longer overwrite each other's route on every connect, which dropped the iOS session and moved the hop key.
  • Found on the way: a dirty Mac copy reverted another device's SSH, SSL and additional-field changes in the merge, since unsorted JSON compared unequal byte for byte. The Mac now writes sorted JSON and compares against the base as it would write it.
  • iOS form: Route from Mac shows routes from any Mac; a hop only the Mac's config names gets its key on the device, as before.

Test plan

  • SyncFieldParityTests now pins sshRouteJson as written by the Mac only and read by both; ConnectionSyncSchemaTests and ProductionSchemaParityTests pass against the new snapshot.
  • New: SSHRouteSyncRecordTests (round trip, key set of the synced JSON, clear, fresh record names no route, unreadable route kept, re-spelling kept, foreign route kept, one full fetch), SSHRouteSyncCoordinatorTests (push and merge keep another Mac's route), SyncCoordinatorEchoTests.mergeComparesValuesNotSpelling, SyncRecordMapperSSHRouteTests (pull reads and dials the route, iOS edit keeps it), IOSSyncCoordinatorTests (full fetch once, dirty copy takes the route), import replace and duplicate cases on both apps, PublishedSSHRouteTests.aliasesDoNotMatter.
  • Changed on purpose: SSHRouteSyncRecordTests.routeStaysOffTheRecord is replaced by the round trip; SyncRecordMapperConnectionTests moves sshRoute from kept-on-this-Mac to written-to-record.
  • verify.sh: package TableProCore (273), macOS sync and SSH suites (179), iOS sync, import and SSH form suites (254), lint, l10n.

Follows #3697.

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