Mobile: QR pairing fails at credential import for private/VPN-only relays (relay URL must be HTTPS + public host)
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Summary
Buzz Desktop fully supports private, VPN-only relays, and the NIP-AB pairing flow (including the `buzz-pair-relay` sidecar from #467/#470/#1799) works end-to-end against them. But the mobile app rejects the community credentials at the final import step, making mobile unusable for private-relay deployments.
## Environment
- Self-hosted relay (docker compose, image `ghcr.io/block/buzz:sha-3e48f1b`), NIP-43 auth enabled
- Relay reachable only inside a WireGuard tunnel: `ws://10.88.0.1:3000`
- `buzz-pair-relay` sidecar deployed and advertised via NIP-11 `pairing_relay_url`
- Mobile: current release build (iOS)
## What happens
1. Desktop shows QR → phone (on the VPN) connects to the pairing sidecar
2. NIP-AB handshake completes, SAS codes match and confirm
3. Credential payload transfer starts, then mobile errors:
`Failed to import credentials: FormatException: Relay URL must use HTTPS`
## Why
`mobile/lib/features/pairing/pairing_provider.dart` → `_validateRelayUrl()` requires `https` scheme in release builds, and `_isPrivateHost()` rejects RFC1918 addresses. A VPN-only relay URL like `ws://10.88.0.1:3000` fails both, with no way to override. `mobile/lib/shared/relay/relay_validation.dart` enforces the same policy for invites (`wss` + no non-public addresses).
The SSRF motivation for these checks makes sense for untrusted invite links, but at the end of a NIP-AB pairing the user has just cryptographically verified the source device via SAS — the relay URL comes from their own desktop, not an untrusted third party.
## Ask
A supported path for private/VPN-only relays on mobile. Possible shapes:
- Treat SAS-verified pairing payloads as trusted enough to accept `ws://` + private-range relay URLs (perhaps behind an explicit "this is a private relay — connect anyway?" confirmation), or
- A user-visible setting/build flag to allow private relay origins, or
- Documented guidance if the intended answer is "front the relay with WSS + public DNS" — including how an existing community keyed by a `ws://` URL is supposed to migrate, since docs state the relay URL keys the community and must never change.
Happy to test a patch against our deployment.
Contributor guide
Research direction
Start in mobile/lib/features/pairing/pairing_provider.dart at _validateRelayUrl(), then compare its release-build checks with mobile/lib/shared/relay/relay_validation.dart. Reproduce the final credential import using the documented ws://10.88.0.1:3000 VPN relay and review how SAS verification relates to the SSRF protections. Done means a supported private-relay path is defined and works, or the required public WSS migration guidance is documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- dart, flutter, ios
- Domain
- mobile, networking, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100