Description
Support LocalSend's PIN flow, both directions:
- Send to a peer that requires a PIN — today the send just fails (
OutboundPhase::Failed("peer requires a PIN (not supported yet)"), src/transfer/outbound.rs:142).
- Require a PIN on your own receives, so a passer-by on the same Wi-Fi can't push files without the code.
Plan
Send side
- On
PrepareError::PinRequired (HTTP 401, src/net/client.rs:65), prompt for the PIN via the OSK instead of failing.
- Retry
prepare_upload with the PIN as a ?pin=XXXX query param; on repeated 401, re-prompt or give up with a clear message.
Receive side
3. Add an optional [network] pin (config + a Settings row). When set, handle_prepare_upload (src/net/server.rs:236) reads request.query_param("pin") (same accessor used for upload tokens) and answers 401 when missing/wrong, before parking for accept/decline.
4. Brute-force protection: cap wrong attempts and answer 429 past the cap, matching the official app.
Notes
- Interop is the main win — verify against the official app both ways (it enables PIN per-device).
- Decide the PIN's scope: per-session challenge vs a standing device PIN (LocalSend validates per prepare-upload).
- Don't log the PIN; it'd live in
config.toml (plain text today — note it's not a secret store).
429 isn't handled on the client yet (src/net/client.rs maps 401/403/409) — add it for the attempt-limit response.
Description
Support LocalSend's PIN flow, both directions:
OutboundPhase::Failed("peer requires a PIN (not supported yet)"),src/transfer/outbound.rs:142).Plan
Send side
PrepareError::PinRequired(HTTP 401,src/net/client.rs:65), prompt for the PIN via the OSK instead of failing.prepare_uploadwith the PIN as a?pin=XXXXquery param; on repeated 401, re-prompt or give up with a clear message.Receive side
3. Add an optional
[network] pin(config + a Settings row). When set,handle_prepare_upload(src/net/server.rs:236) readsrequest.query_param("pin")(same accessor used for upload tokens) and answers 401 when missing/wrong, before parking for accept/decline.4. Brute-force protection: cap wrong attempts and answer 429 past the cap, matching the official app.
Notes
config.toml(plain text today — note it's not a secret store).429isn't handled on the client yet (src/net/client.rsmaps 401/403/409) — add it for the attempt-limit response.