diff --git a/src/main.rs b/src/main.rs index 44cccd2..ba5d6c3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,9 +17,9 @@ use crate::{ invoice::handle_pending_invoices, mint::{setup_multimint, MultiMintWrapperTrait}, routes::{ - change_federation, check_pubkey, check_registration_info, check_username, health_check, - lnurl_callback_route, lnurl_verify_route, register_route, root, validate_cors, - well_known_lnurlp_route, well_known_nip5_route, + change_federation, check_pubkey, check_registration_info, check_username, disable_zaps, + health_check, lnurl_callback_route, lnurl_verify_route, register_route, root, + validate_cors, well_known_lnurlp_route, well_known_nip5_route, }, }; @@ -172,6 +172,7 @@ async fn main() -> anyhow::Result<()> { .route("/v1/check-pubkey/:pubkey", get(check_pubkey)) // DEPRECATED for check-registration .route("/v1/check-registration", post(check_registration_info)) .route("/v1/change-federation", post(change_federation)) + .route("/v1/disable-zaps", post(disable_zaps)) .route("/v1/register", post(register_route)) .route("/.well-known/nostr.json", get(well_known_nip5_route)) .route( diff --git a/src/register.rs b/src/register.rs index 932500f..2475246 100644 --- a/src/register.rs +++ b/src/register.rs @@ -50,6 +50,10 @@ pub fn change_user_federation( .update_user_federation(user, federation_id, federation_invite_code) } +pub fn disable_user_zaps(state: &State, user: AppUser) -> anyhow::Result<()> { + state.db.disable_user_zaps(user) +} + pub fn generate_random_name(state: &State) -> anyhow::Result { loop { let new_name = Generator::with_naming(names::Name::Numbered) diff --git a/src/routes.rs b/src/routes.rs index 473f91a..8b301ff 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -2,8 +2,8 @@ use crate::{ lnurlp::{lnurl_callback, verify, well_known_lnurlp}, nostr::well_known_nip5, register::{ - change_user_federation, check_available, check_registered_pubkey, ensure_added_federation, - get_user_by_pubkey, register, + change_user_federation, check_available, check_registered_pubkey, disable_user_zaps, + ensure_added_federation, get_user_by_pubkey, register, }, State, ALLOWED_LOCALHOST, ALLOWED_ORIGINS, ALLOWED_SUBDOMAIN, API_VERSION, }; @@ -25,6 +25,7 @@ use url::Url; const REGISTRATION_CHECK_EVENT_KIND: Kind = Kind::Custom(93_186); const NEW_FEDERATION_EVENT_KIND: Kind = Kind::Custom(93_187); +const DISABLE_ZAPS_EVENT_KIND: Kind = Kind::Custom(93_188); #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct LnUrlErrorResponse { @@ -199,6 +200,57 @@ pub async fn change_federation( } } +pub async fn disable_zaps( + origin: Option>, + Extension(state): Extension, + Json(event): Json, +) -> Result<(), (StatusCode, String)> { + validate_cors(origin)?; + + let pubkey = event.author(); + info!("disable_zaps: {}", pubkey); + + if event.verify().is_err() && event.kind() != DISABLE_ZAPS_EVENT_KIND { + error!("error in disable_zaps: bad event"); + return Err((StatusCode::BAD_REQUEST, "Bad event".to_string())); + } + + // make sure it was made recently + let created_at = event.created_at(); + let now = nostr::Timestamp::now(); + if created_at < now - 120_i64 && created_at > now + 120_i64 { + error!("error in disable_zaps: event time not in range"); + return Err(( + StatusCode::BAD_REQUEST, + "Event time not in range".to_string(), + )); + } + + match get_user_by_pubkey(&state, pubkey.to_string()) { + Ok(Some(u)) => { + info!("disable_zaps found user for pubkey: {}", pubkey); + + // got the user, now change the federation + match disable_user_zaps(&state, u) { + Ok(_) => { + info!( + "disable_zaps changed user federation for pubkey: {}", + pubkey + ); + Ok(()) + } + Err(e) => Err(handle_anyhow_error("disable_zaps", e)), + } + } + Ok(None) => { + error!("disable_zaps not found: {}", pubkey); + + Err((StatusCode::NOT_FOUND, "User not found".to_string())) + } + Err(e) => Err(handle_anyhow_error("disable_zaps", e)), + } +} + #[derive(Deserialize, Clone)] pub struct RegisterRequest { pub name: Option,