Commit Graph
2 Commits
Author SHA1 Message Date
bonaminandClaude Opus 5.5 18f13f12dd feat(waiter): encrypted, key-pinned connection to the venue server (native app)
- Android: MainActivity installs a WebViewClient whose onReceivedSslError
  proceeds only when the server's SPKI SHA-256 is in TrustStore (pins of all
  paired venues, SharedPreferences); XeniaTlsPlugin lets JS set that list.
  Spike showed this one callback covers fetch/XHR, images AND WebSockets.
  Pins are per key, not per address: IP changes, renewals and expiry never
  need action; a different key is always refused.
- Pairing: QR key (k=) must equal the server's advertised pin, else refused;
  typed addresses trust the advertised key on first use. Then the venue moves
  to https://<ip>:<tls.port> (stays on HTTP if that port isn't reachable yet).
- upgradeToTls(): on every start, a plain-HTTP venue moves onto TLS once the
  server offers it (never accepting a key different from the stored one).
- main.jsx pushes the venues' pins to native before the first request.
- Rediscovery made proactive: checks the saved address at start and every
  minute while the live connection is down, instead of waiting for requests
  to an unanswered IP to time out (minutes). HTTPS probes get 5s: the first
  TLS connection in a fresh process takes ~2s (measured).

E2E on the emulator vs an isolated stack: wrong-key QR refused; pairing on
TLS; tables + wss live; impostor server with another key refused natively;
HTTP venue upgraded on start; server cert renewed (same key) - app keeps
working without re-pairing; rediscovery over TLS (11s). Step 5 HTTP
rediscovery (now 2.7s/4.8s) and cold-start login tests, and web modes, pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 17:41:25 +03:00
bonaminandClaude Opus 5.5 0b0f5c60c3 feat(waiter): Capacitor 8 Android project, native build mode, signed APK tooling
- capacitor.config.json: appId gr.bonamin.xenia, webDir dist-native,
  androidScheme http (origin http://localhost - no mixed-content block when
  calling venue servers over plain HTTP on the LAN)
- vite: `--mode native` builds to dist-native with the PWA plugin disabled
  (no service worker inside the app)
- Android: minSdk 24 / target 36; CAMERA permission for QR pairing;
  cleartext allowed via network_security_config (LAN IPs can't be listed
  per-domain); allowBackup=false so backups never carry login tokens
- Release signing reads ~/.xenia/keystore.properties (override with
  XENIA_KEYSTORE_PROPS) - the key never enters the repo; versionName 1.0.0 /
  versionCode 1 with a bump-both rule for sideloaded updates
- npm scripts build:native, apk:debug, apk:release (scripts/build-apk.mjs);
  APKs land in releases/ (gitignored); release APK is also copied to
  public/downloads/ so venue servers serve it at /downloads/xenia-waiter.apk
- waiter nginx: /downloads/ served as application/vnd.android.package-archive,
  real 404 when missing (never falls through to index.html)
- launcher icons + splash generated from the app icon (assets/ is the source)
- .gitattributes: gradlew LF, *.bat CRLF

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 13:31:23 +03:00