Bind accepted npub requests to peer identities and serialize cancellation

This commit is contained in:
archipelago
2026-10-05 23:52:44 -04:00
parent fefcbfdbc4
commit 9af49291e9
4 changed files with 116 additions and 13 deletions
@@ -1430,16 +1430,7 @@ impl RpcHandler {
.and_then(|v| v.as_bool())
.unwrap_or(true);
let req = pending::find_by_id(&self.config.data_dir, id)
.await?
.ok_or_else(|| anyhow::anyhow!("Pending request not found: {}", id))?;
if !req.outbound || !matches!(req.state, pending::PendingState::Sent) {
anyhow::bail!(
"Can only cancel outbound requests in Sent state (outbound={}, state={:?})",
req.outbound,
req.state
);
}
let req = pending::cancel_outbound(&self.config.data_dir, id).await?;
if notify {
let identity_dir = self.config.data_dir.join("identity");
@@ -1462,7 +1453,6 @@ impl RpcHandler {
}
}
pending::delete(&self.config.data_dir, id).await?;
info!(id = %id, to = %req.from_nostr_pubkey, notified = notify, "Cancelled outbound peer request");
Ok(serde_json::json!({ "cancelled": true, "id": id, "notified": notify }))
}
@@ -434,6 +434,14 @@ async fn npub_only_request_accepts_bound_reply_but_rejects_other_sender_and_forg
.state,
PendingState::Approved
);
assert_eq!(
pending::find_by_id(dir.path(), &row.id)
.await
.unwrap()
.unwrap()
.from_did,
remote_did
);
let duplicate = handler.handle_handshake_poll().await.unwrap();
assert!(duplicate["applied_invites"].as_array().unwrap().is_empty());
assert_eq!(
+5 -2
View File
@@ -345,6 +345,7 @@ impl RpcHandler {
}
}
HandshakeMessage::PeerInvite { invite_code } => {
let _decision = pending::outbound_decision_guard().await;
// Match against an outbound Sent request from this nostr
// pubkey. If we never sent them anything, ignore — we
// don't accept unsolicited invites over Nostr.
@@ -431,10 +432,11 @@ impl RpcHandler {
.await;
}
pending::set_state(
pending::complete_outbound(
&self.config.data_dir,
&row_id,
PendingState::Approved,
&hs.from_nostr_pubkey,
&node.did,
)
.await?;
applied_invites.push(node.did);
@@ -449,6 +451,7 @@ impl RpcHandler {
}
}
HandshakeMessage::PeerReject { reason } => {
let _decision = pending::outbound_decision_guard().await;
let pendings = pending::load_pending(&self.config.data_dir).await?;
if let Some(row) = pendings.iter().find(|r| {
r.outbound