Repository navigation
iOS: account sign-in, and local + public server addresses - #7
Merged
Merged
Conversation
The app could reach https://sonder.stoverparc.org but never load the library: since account auth landed on the server (643cdc1, 2026-09-24) every API route answers 401 unless the request carries an account session, and the iOS client only knew how to send a legacy pairing token. There was no way to sign in from the phone. Sign-in - New sign-in sheet, shown when the server answers 401. It calls POST /api/auth/login, takes the sonder_session cookie value from the response and stores it per server in the Keychain, then sends it as a Bearer token. The same token works on both addresses. - Requests no longer send shared cookies: the server reads a cookie before the Authorization header, so a stale cookie could hide a valid token. - Sign out in Settings; wrong password, throttling and "no account yet" get their own messages. 403 (LAN access off) no longer asks to sign in. Local + public addresses - Settings and onboarding take a public address and an optional local one. On launch, on network change (NWPathMonitor) and on demand the app probes the local address's /api/auth/session with a 1.5 s timeout and requires the X-Sonder-Server header; otherwise it uses public. A transport error on the local route falls back to public at once. - Settings shows which address is active. - Downloads, queued progress, caches and the token stay keyed by the server's identity (its public address), so switching routes does not hide offline copies. Older single-URL settings migrate to the public address. - No ATS exception is needed: plain http to a LAN IP loads under the default ATS policy (checked in the iOS 27.2 simulator). Tests: 20 new unit tests (address parsing, route selection, probe, sign-in responses, date parsing); swift test passes (29 tests). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why the iPhone app stopped working
The app reaches
https://sonder.stoverparc.orgfine (TLS is OK and the server answers), but the library never loads. Since account auth landed on the server (643cdc1, 2026-09-24), every API route answers 401 unless the request carries an account session. The iOS client could only send a legacy pairing token and had no sign-in screen, so it showed "No Titles" and "This server is restricted. Add a token…".Reproduced in the iOS 27.2 simulator against the live public URL before the change.
What changed
Sign-in
POST /api/auth/login, takes thesonder_sessionvalue fromSet-Cookie, and stores it in the Keychain per server. Requests send it asAuthorization: Bearer, which the server already accepts. One sign-in works on both the local and the public address.sessionUsernamereads a cookie before the Authorization header, so a stale cookie could hide a valid token.Retry-After) and "no account yet" (409) each get their own message. A 403 (LAN access off) no longer asks you to sign in.Local + public addresses
NWPathMonitor) and from a "check again" button, the app probes<local>/api/auth/sessionwith a 1.5 s timeout and requiresX-Sonder-Server: tm-sonder, so a captive portal doesn't count. If the probe fails, it uses public. A network error on the local route mid-sync falls back to public at once.sonder.serverBaseURLsetting migrates to the public address.http://to a LAN IP loaded under the default ATS policy in the simulator, so none was needed.Testing
swift test --package-path IOS_Client_Xcode/TM_Sonder_Client: 29 tests pass, 20 of them new (address parsing, local/public selection, probe identity check, sign-in response handling, Go timestamp parsing).Note for the local address on the current network
On ser8's LAN, Caddy answers only for the hostname
sonder.stoverparc.orgon 10.20.0.117:443, because the certificate needs that name.:8096and:8098aren't reachable from the LAN (8098 is host loopback). Sohttp://10.20.0.117:…won't work as a local address yet. Two ways to get one, neither done here:sonder.stoverparc.org → 10.20.0.117. The public address then goes direct at home, and no local address is needed.http://10.20.0.117:8096 → 127.0.0.1:8098, entered as the local address.🤖 Generated with Claude Code