diff --git a/Cargo.lock b/Cargo.lock index 8ea5a0b..02f2de9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1674,7 +1674,7 @@ dependencies = [ [[package]] name = "nostr" version = "0.32.0" -source = "git+https://github.com/dcadenas/nostr.git?branch=add-malware-report-variant#749f580f8a3b2479df41e49a3c48e68de1c3244e" +source = "git+https://github.com/rust-nostr/nostr.git#d244d10f53bf0ad2a1e84fffdf658c84d7bcce0c" dependencies = [ "aes", "base64 0.21.7", @@ -1703,7 +1703,7 @@ dependencies = [ [[package]] name = "nostr-database" version = "0.32.0" -source = "git+https://github.com/dcadenas/nostr.git?branch=add-malware-report-variant#749f580f8a3b2479df41e49a3c48e68de1c3244e" +source = "git+https://github.com/rust-nostr/nostr.git#d244d10f53bf0ad2a1e84fffdf658c84d7bcce0c" dependencies = [ "async-trait", "lru", @@ -1716,7 +1716,7 @@ dependencies = [ [[package]] name = "nostr-relay-pool" version = "0.32.0" -source = "git+https://github.com/dcadenas/nostr.git?branch=add-malware-report-variant#749f580f8a3b2479df41e49a3c48e68de1c3244e" +source = "git+https://github.com/rust-nostr/nostr.git#d244d10f53bf0ad2a1e84fffdf658c84d7bcce0c" dependencies = [ "async-utility", "async-wsocket", @@ -1731,7 +1731,7 @@ dependencies = [ [[package]] name = "nostr-sdk" version = "0.32.0" -source = "git+https://github.com/dcadenas/nostr.git?branch=add-malware-report-variant#749f580f8a3b2479df41e49a3c48e68de1c3244e" +source = "git+https://github.com/rust-nostr/nostr.git#d244d10f53bf0ad2a1e84fffdf658c84d7bcce0c" dependencies = [ "async-utility", "atomic-destructor", @@ -1750,7 +1750,7 @@ dependencies = [ [[package]] name = "nostr-signer" version = "0.32.0" -source = "git+https://github.com/dcadenas/nostr.git?branch=add-malware-report-variant#749f580f8a3b2479df41e49a3c48e68de1c3244e" +source = "git+https://github.com/rust-nostr/nostr.git#d244d10f53bf0ad2a1e84fffdf658c84d7bcce0c" dependencies = [ "async-utility", "nostr", @@ -1763,7 +1763,7 @@ dependencies = [ [[package]] name = "nostr-zapper" version = "0.32.0" -source = "git+https://github.com/dcadenas/nostr.git?branch=add-malware-report-variant#749f580f8a3b2479df41e49a3c48e68de1c3244e" +source = "git+https://github.com/rust-nostr/nostr.git#d244d10f53bf0ad2a1e84fffdf658c84d7bcce0c" dependencies = [ "async-trait", "nostr", @@ -1827,7 +1827,7 @@ dependencies = [ [[package]] name = "nwc" version = "0.32.0" -source = "git+https://github.com/dcadenas/nostr.git?branch=add-malware-report-variant#749f580f8a3b2479df41e49a3c48e68de1c3244e" +source = "git+https://github.com/rust-nostr/nostr.git#d244d10f53bf0ad2a1e84fffdf658c84d7bcce0c" dependencies = [ "async-utility", "nostr", diff --git a/Cargo.toml b/Cargo.toml index f071bb8..ab38d34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ libc = "0.2.155" log = "0.4.21" metrics = "0.23.0" metrics-exporter-prometheus = "0.15.0" -nostr-sdk = { git = "https://github.com/dcadenas/nostr.git", branch = "add-malware-report-variant" } +nostr-sdk = { git = "https://github.com/rust-nostr/nostr.git", ref = "d244d10f53bf0ad2a1e84fffdf658c84d7bcce0c" } ractor = { git = "https://github.com/planetary-social/ractor.git", branch = "output_ports" } regex = "1.10.4" reqwest = "0.12.4" diff --git a/src/adapters.rs b/src/adapters.rs index 9c45249..bccdf29 100644 --- a/src/adapters.rs +++ b/src/adapters.rs @@ -6,3 +6,38 @@ pub mod nostr_service; pub use nostr_service::NostrService; pub mod slack_client_adapter; pub use slack_client_adapter::SlackClientAdapterBuilder; + +use crate::actors::messages::SupervisorMessage; +use nostr_sdk::prelude::{nip19::*, PublicKey}; +use ractor::{call_t, ActorRef}; + +// This function attempts to generate an njump link for a given public key, +// following a specific order of preference: +// 1. Njump link with nip05 +// https://njump.me/daniel@nos.social +// 2. Njump link with npub (Bech32-encoded public key) +// https://njump.me/npub138he9w0tumwpun4rnrmywlez06259938kz3nmjymvs8px7e9d0js8lrdr2 +// 3. Plain public key if both previous attempts fail +// 89ef92b9ebe6dc1e4ea398f6477f227e95429627b0a33dc89b640e137b256be5 +async fn njump_or_pubkey( + message_dispatcher: ActorRef, + pubkey: PublicKey, +) -> String { + let Ok(maybe_reporter_nip05) = + call_t!(message_dispatcher, SupervisorMessage::GetNip05, 100, pubkey) + else { + return pubkey + .to_bech32() + .map(|npub| format!("https://njump.me/{}", npub)) + .unwrap_or_else(|_| pubkey.to_string()); + }; + + if let Some(nip05) = maybe_reporter_nip05 { + format!("https://njump.me/{}", nip05) + } else { + pubkey + .to_bech32() + .map(|npub| format!("https://njump.me/{}", npub)) + .unwrap_or_else(|_| pubkey.to_string()) + } +} diff --git a/src/adapters/http_server/slack_interactions_route.rs b/src/adapters/http_server/slack_interactions_route.rs index 0f724bc..214d3df 100644 --- a/src/adapters/http_server/slack_interactions_route.rs +++ b/src/adapters/http_server/slack_interactions_route.rs @@ -1,11 +1,12 @@ use super::app_errors::AppError; use super::WebAppState; use crate::actors::messages::SupervisorMessage; +use crate::adapters::njump_or_pubkey; use crate::domain_objects::{ReportRequest, ReportTarget}; -use anyhow::{anyhow, bail, Context, Result}; +use anyhow::{anyhow, Context, Result}; use axum::{extract::State, routing::post, Extension, Router}; use nostr_sdk::prelude::*; -use ractor::{call_t, cast, ActorRef}; +use ractor::{cast, ActorRef}; use reqwest::Client as ReqwestClient; use serde_json::{json, Value}; use slack_morphism::prelude::*; @@ -79,27 +80,14 @@ async fn slack_message( maybe_category: Option, slack_username: String, ) -> Result { - let reporter_nip05_markdown = - match try_njump(message_dispatcher.clone(), report_request.reporter_pubkey()).await { - Ok(nip05) => nip05, - Err(e) => { - info!("Failed to get nip05 link for reporter: {}", e); - format!("`{}`", report_request.reporter_pubkey()) - } - }; - - let reported_nip05_markdown = match try_njump( + let reporter_nip05_markdown = njump_or_pubkey( message_dispatcher.clone(), - &report_request.target().pubkey(), + *report_request.reporter_pubkey(), ) - .await - { - Ok(nip05) => nip05, - Err(e) => { - info!("Failed to get nip05 link for reported: {}", e); - format!("`{}`", report_request.target().pubkey()) - } - }; + .await; + + let reported_nip05_markdown = + njump_or_pubkey(message_dispatcher.clone(), report_request.target().pubkey()).await; if let Some(moderated_report) = report_request.report(maybe_category.clone())? { let report_id = moderated_report.id(); @@ -255,31 +243,6 @@ fn slack_skipped_message( trimmed_string } -async fn try_njump( - message_dispatcher: ActorRef, - pubkey: &PublicKey, -) -> Result { - let maybe_reporter_nip05 = match call_t!( - message_dispatcher, - SupervisorMessage::GetNip05, - 100, - *pubkey - ) { - Ok(nip05) => nip05, - Err(e) => { - bail!("Failed to get nip05 link {}", e); - } - }; - - Ok(maybe_reporter_nip05 - .as_ref() - .map(|nip05| format!("https://njump.me/{}", nip05)) - .unwrap_or(format!( - "`{}`", - pubkey.to_bech32().unwrap_or(pubkey.to_string()) - ))) -} - fn parse_slack_action( block_actions_event: SlackInteractionBlockActionsEvent, ) -> Result<(Url, String, ReportRequest, Option), AppError> { @@ -459,8 +422,8 @@ mod tests { .unwrap(); let slack_actions_event = create_slack_actions_event( - &slack_username, - &category_name, + slack_username, + category_name, &reporter_pubkey, &reporter_text, &reported_event, @@ -495,8 +458,8 @@ mod tests { .unwrap(); let slack_actions_event = create_slack_actions_event( - &slack_username, - &category_name, + slack_username, + category_name, &reporter_pubkey, &reporter_text, &reported_event, diff --git a/src/adapters/slack_client_adapter.rs b/src/adapters/slack_client_adapter.rs index 5c38bdd..d6bcc55 100644 --- a/src/adapters/slack_client_adapter.rs +++ b/src/adapters/slack_client_adapter.rs @@ -1,16 +1,14 @@ use crate::actors::messages::SupervisorMessage; use crate::actors::{SlackClientPort, SlackClientPortBuilder}; +use crate::adapters::njump_or_pubkey; use crate::domain_objects::ReportRequest; use anyhow::Result; use hyper_rustls::HttpsConnector; use hyper_util::client::legacy::connect::HttpConnector; use nostr_sdk::nips::nip56::Report; -use nostr_sdk::prelude::PublicKey; -use nostr_sdk::ToBech32; -use ractor::{call_t, ActorRef}; +use ractor::ActorRef; use slack_morphism::prelude::*; use std::env; -use tracing::info; #[derive(Clone)] pub struct SlackClientAdapter { @@ -41,43 +39,15 @@ impl SlackClientAdapter { Ok(()) } - - // This fn is currently duplicated and lives too in the http client adapter. - // It should be moved to a shared place at some point - async fn try_njump(&self, pubkey: PublicKey) -> Result { - let maybe_reporter_nip05 = - call_t!(self.nostr_actor, SupervisorMessage::GetNip05, 100, pubkey)?; - - Ok(maybe_reporter_nip05 - .as_ref() - .map(|nip05| format!("https://njump.me/{}", nip05)) - .unwrap_or(format!( - "`{}`", - pubkey.to_bech32().unwrap_or(pubkey.to_string()) - ))) - } } #[ractor::async_trait] impl SlackClientPort for SlackClientAdapter { async fn write_message(&self, report_request: &ReportRequest) -> Result<()> { let reported_pubkey_or_nip05_link = - match self.try_njump(report_request.target().pubkey()).await { - Ok(link) => link, - Err(e) => { - info!("Failed to get nip05 link: {}", e); - format!("`{}`", report_request.target().pubkey()) - } - }; - + njump_or_pubkey(self.nostr_actor.clone(), report_request.target().pubkey()).await; let reporter_pubkey_or_nip05_link = - match self.try_njump(*report_request.reporter_pubkey()).await { - Ok(link) => link, - Err(e) => { - info!("Failed to get nip05 link: {}", e); - format!("`{}`", report_request.target().pubkey()) - } - }; + njump_or_pubkey(self.nostr_actor.clone(), *report_request.reporter_pubkey()).await; let message = PubkeyReportRequestMessage::new( report_request, diff --git a/src/domain_objects/report_request.rs b/src/domain_objects/report_request.rs index c5840f8..1672755 100644 --- a/src/domain_objects/report_request.rs +++ b/src/domain_objects/report_request.rs @@ -131,7 +131,7 @@ impl Display for ReportRequest { #[cfg(test)] mod tests { use super::*; - use nostr::nips::nip56::Report; + use nostr_sdk::nips::nip56::Report; use serde_json::json; use std::str::FromStr;