Skip to content

feat: apple-app-site-association for mold pairing links - #46

Merged
jamesbrink merged 1 commit into
mainfrom
feat/mold-pairing-universal-link
Sep 28, 2026
Merged

jamesbrink merged 1 commit into
mainfrom
feat/mold-pairing-universal-link

Conversation

@jamesbrink

Copy link
Copy Markdown
Member

Serves /.well-known/apple-app-site-association so Mold Studio Companion (28X9H69QGE.io.utensils.mold.companion) claims https://utensils.io/mold/pair universal links (utensils/mold#1776).

  • Only /mold/pair (and /mold/pair/) are claimed; every other path still opens in the browser.
  • The pairing code rides in the URL fragment, which browsers never send to this site.
  • The fallback page for phones without the app is utensils.io/mold/pair, published from the mold repo's VitePress site.
  • Verified locally: next build copies public/.well-known/ into out/, and peaceiris/actions-gh-pages writes .nojekyll, so the dot-directory is served.

Lets Mold Studio Companion (28X9H69QGE.io.utensils.mold.companion) claim
https://utensils.io/mold/pair links, so an iPhone's Camera opens the app
from a pairing QR. The code rides in the fragment, which never reaches
this site; the fallback page lives in utensils/mold at /mold/pair.
@jamesbrink
jamesbrink merged commit f2cde6f into main Sep 28, 2026
1 check passed
@jamesbrink
jamesbrink deleted the feat/mold-pairing-universal-link branch September 28, 2026 20:13
jamesbrink added a commit that referenced this pull request Sep 28, 2026
actions/upload-artifact v4.4+ skips hidden files unless include-hidden-files
is set, so public/.well-known/apple-app-site-association (#46) never reached
the gh-pages branch.
jamesbrink added a commit to utensils/mold that referenced this pull request Sep 28, 2026
)

Closes #1776.

Pairing QRs from Mold Studio for Mac, the desktop app and web Settings ▸
Mobile pairing are now universal links:
`https://utensils.io/mold/pair#version=1&base_url=…&token=…`.

- **Companion**: `applinks:utensils.io` entitlement. An opened link
lands in the new `PairingLinkSheet` ("Pair This Phone?" with the
machine's name and address); nothing is claimed until **Pair**, so a
link anyone can send never pairs the phone by itself. An expired or
unreadable code says so there.
- **Privacy**: the payload rides in the URL fragment, which browsers
never send to utensils.io; the fallback page also strips it from the
address bar.
- **Fallback** `website/pair.md` → `utensils.io/mold/pair`: says what to
install, never shows the token, and offers **Open in Mold**, which hands
the code to the Tauri app as `mold://pair?…`.
- **Association file**: utensils/utensils.github.io#46 serves
`/.well-known/apple-app-site-association` for
`28X9H69QGE.io.utensils.mold.companion`, `/mold/pair` only.
- **One contract**: `studio/api/pairing.ts` and MoldClient's
`MobilePairingPayload` both test against
`studio/api/pairing.fixtures.json`. Older `mold://pair` codes still
parse everywhere.
- **Bug fix**: the Swift parser read `+` literally (`queryItems`), so
"Studio Mac" became "Studio+Mac"; it now decodes like `URLSearchParams`.
- The Mac's Pair a Phone sheet says the Camera app can read the code.

Signing: automatic App Store Connect signing
(`-allowProvisioningUpdates`) enables Associated Domains on the App ID
on the next TestFlight run.

Tests: studio 2204 pass; desktop MobileApp 394 pass; MoldClient pairing
suites pass; iOS 92 unit tests pass; web/desktop/studio vue-tsc clean;
website builds; the fallback page was checked in a browser (name shown,
token never displayed, fragment cleared, link equals the legacy form).
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