mirror of
https://github.com/block/buzz.git
synced 2026-10-30 14:01:37 +00:00
feat(pairing): auto-detect NIP-43 relay and route target to /pair sidecar (#470)
This commit is contained in:
@@ -67,7 +67,7 @@ const overrides = new Map([
|
||||
["src-tauri/src/huddle/relay_api.rs", 510], // audio relay recv task + per-peer frame counting for remote human TTS interrupt
|
||||
["src-tauri/src/huddle/tts.rs", 1030], // TTS pipeline + session warmup + cancel/shutdown handling + apply_fades + 18 unit tests for remote interrupt mechanism
|
||||
["src-tauri/src/relay.rs", 510], // +4 lines for NIP-OA auth tag injection in profile sync (build_profile_event) + verification test
|
||||
["src-tauri/src/commands/pairing.rs", 550], // NIP-AB pairing actor: 3 Tauri commands + background WS task + NIP-42 auth + event parsing helpers
|
||||
["src-tauri/src/commands/pairing.rs", 600], // NIP-AB pairing actor: 3 Tauri commands + background WS task + NIP-42 auth + NIP-43 probe + event parsing helpers
|
||||
["src-tauri/src/lib.rs", 715], // +4 lines for PairingHandle managed state + 3 pairing command registrations
|
||||
["src/shared/api/tauri.ts", 1210], // pairing command wrappers + applyWorkspace + NIP-44 encrypt/decrypt wrappers + observer_url field + relay member API functions (list/get/add/remove/change-role)
|
||||
]);
|
||||
|
||||
@@ -122,7 +122,18 @@ pub async fn start_pairing(
|
||||
let ws_url = relay_ws_url_with_override(&state);
|
||||
let http_url = relay_api_base_url_with_override(&state);
|
||||
|
||||
let (session, qr_payload) = PairingSession::new_source(ws_url.clone());
|
||||
// Detect NIP-43: if the relay requires auth, the target device should
|
||||
// connect to the /pair sidecar instead of the main relay.
|
||||
let qr_relay_url = if probe_relay_requires_auth(&ws_url).await {
|
||||
let mut url = url::Url::parse(&ws_url).map_err(|e| format!("invalid relay URL: {e}"))?;
|
||||
let path = url.path().trim_end_matches('/').to_string();
|
||||
url.set_path(&format!("{path}/pair"));
|
||||
url.to_string()
|
||||
} else {
|
||||
ws_url.clone()
|
||||
};
|
||||
|
||||
let (session, qr_payload) = PairingSession::new_source(qr_relay_url);
|
||||
let qr_uri = encode_qr(&qr_payload);
|
||||
|
||||
let payload_json = serde_json::json!({
|
||||
@@ -445,6 +456,49 @@ fn parse_relay_event(text: &str, sub_id: &str) -> Option<nostr_compat::Event> {
|
||||
serde_json::from_value(arr[2].clone()).ok()
|
||||
}
|
||||
|
||||
/// Check the relay's NIP-11 information document to determine if auth is
|
||||
/// required (indicating NIP-43 access control). Returns `true` if the relay
|
||||
/// advertises `limitation.auth_required: true`, `false` otherwise.
|
||||
///
|
||||
/// Converts the WebSocket URL to HTTP(S) and fetches `GET /` with
|
||||
/// `Accept: application/nostr+json` per NIP-11.
|
||||
async fn probe_relay_requires_auth(relay_url: &str) -> bool {
|
||||
// Convert ws(s):// to http(s):// for the NIP-11 fetch.
|
||||
let http_url = if let Some(rest) = relay_url.strip_prefix("wss://") {
|
||||
format!("https://{rest}")
|
||||
} else if let Some(rest) = relay_url.strip_prefix("ws://") {
|
||||
format!("http://{rest}")
|
||||
} else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let client = reqwest::Client::builder()
|
||||
.timeout(Duration::from_secs(5))
|
||||
.build()
|
||||
.unwrap_or_default();
|
||||
|
||||
let resp = match client
|
||||
.get(&http_url)
|
||||
.header("Accept", "application/nostr+json")
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(r) => r,
|
||||
Err(_) => return false, // can't reach relay — assume open
|
||||
};
|
||||
|
||||
let json: serde_json::Value = match resp.json().await {
|
||||
Ok(v) => v,
|
||||
Err(_) => return false,
|
||||
};
|
||||
|
||||
// Check limitation.auth_required per NIP-11.
|
||||
json.get("limitation")
|
||||
.and_then(|l| l.get("auth_required"))
|
||||
.and_then(|v| v.as_bool())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn parse_auth_challenge(text: &str) -> Option<String> {
|
||||
let arr: serde_json::Value = serde_json::from_str(text).ok()?;
|
||||
let arr = arr.as_array()?;
|
||||
|
||||
Reference in New Issue
Block a user