feat: Apple Wallet passes for bookings

"Add to Apple Wallet" on a booking in the iOS app turns it into a TREK pass:
a boarding pass from and to for flights, trains, buses and boats, check-in and
check-out for a stay, pickup and drop-off for a car, the time for anything
else, with the confirmation code as a QR code. Wallet brings it up on the lock
screen around its time and place: times carry the offset of the endpoint's zone
(looked up from the coordinates where the endpoint has none), stays and
restaurants their place's coordinates. The labels come from the booking forms'
own strings, so nothing new to translate on the pass.

Only liketrek holds the Pass Type ID certificate, so the server sends the pass's
texts to the TREK services' signer (TREK_WALLET_PASS_URL, push.liketrek.com)
once per tap; it stores nothing, and TREK_SERVICES=off turns it off with the
other services. Texts are cleaned of links and shortened here, the answer must
be a .pkpass within 512 KB, and a user gets 20 passes a minute.

- New wallet-pass domain: GET /api/trips/:tripId/reservations/:id/wallet-pass
  behind the trip guard, the booking checked to belong to the trip; trip title
  and place come from the reservations domain (findPassContext)
- MWalletButton in the transport and booking sheets, only where the app binary
  has the wallet feature; undated bookings and failures are told apart
- TREK_WALLET_PASS_URL in .env.example, compose, Helm and the wiki
This commit is contained in:
Maurice
2026-11-07 10:40:41 +01:00
parent 794da3be72
commit 37a4e84360
56 changed files with 1873 additions and 113 deletions
+1
View File
@@ -76,6 +76,7 @@ DEMO_MODE=false # Demo mode: resets data hourly
# TREK_SERVICES_HOSTS=places.liketrek.com,photon.liketrek.com,valhalla.liketrek.com # Comma-separated hosts that receive the installation key over https. No other host ever sees it. (default: places.liketrek.com,photon.liketrek.com,valhalla.liketrek.com)
# TREK_PHOTON_URL=https://photon.liketrek.com # The address search (Photon) of the TREK services. Once the installation holds a key, search and reverse lookups ask it before Nominatim and fall back to Nominatim whenever it does not answer. Never asked with TREK_SERVICES=off, without a key, or when NOMINATIM_URL is set. (default: https://photon.liketrek.com)
# TREK_VALHALLA_URL=https://valhalla.liketrek.com # The Valhalla of the TREK services. Routes and elevation are asked of it unless Admin > Default user settings picks another routing service; the browser never talks to it, this server relays its questions with the installation key. (default: https://valhalla.liketrek.com)
# TREK_WALLET_PASS_URL=https://push.liketrek.com/v1/wallet/pass # Signs the Apple Wallet pass of a booking when someone taps "Add to Apple Wallet" in the iOS app. Only liketrek holds the pass certificate, so the pass's texts (the booking's name, times, places, seat or room and confirmation code, nothing else) go there once per tap and are not stored. Never asked with TREK_SERVICES=off. (default: https://push.liketrek.com/v1/wallet/pass)
# PLACES_API_KEY= # Google Maps API key (Places API (New) enabled) for place search, photos, details and Google transit. Overrides the key set in Admin > Settings > API Keys, whose field then shows this variable read-only. The value never reaches the browser.
# GOOGLE_LIST_DATA_BASE= # Optional HTTP(S) base URL of a list-data service, e.g. https://maps.example.com. Paste a URL beginning with this base to fetch and parse it directly. Unset keeps the original Google list import flow.