use anyhow::{Result, anyhow}; use crate::{ http::{ context::WebContext, errors::{CommonError, WebError}, utils::url_from_aturi, }, storage::{ event::{Event, event_get}, identity_profile::handle_for_did, }, }; /// Verify that the current user is the organizer of the specified event. /// Returns the Event if authorized, or an error if not found or not authorized. pub(crate) async fn verify_event_organizer_authorization( web_context: &WebContext, event_aturi: &str, organizer_did: &str, ) -> Result { // Get the event from storage let event = event_get(&web_context.pool, event_aturi) .await .map_err(|e| anyhow!("Failed to get event: {}", e))?; // Verify the current user is the event organizer if event.did != organizer_did { return Err(CommonError::NotAuthorized.into()); } Ok(event) } /// Send an email notification to the subject about their RSVP acceptance. /// This function never fails - errors are logged but the function always returns successfully. pub async fn send_acceptance_email_notification( web_context: &WebContext, subject_did: &str, event_name: &str, event_aturi: &str, ) { // Get the subject's profile for email notification let subject_profile = match handle_for_did(&web_context.pool, subject_did).await { Ok(profile) => profile, Err(e) => { tracing::warn!( "Failed to get profile for DID {} to send acceptance notification: {:?}", subject_did, e ); return; } }; // Generate event URL let event_url = match url_from_aturi(&web_context.config.external_base, event_aturi) { Ok(url) => url, Err(e) => { tracing::error!( "Failed to generate event URL from AT-URI {}: {:?}", event_aturi, e ); return; } }; // Send email notification if email is available if let Some(email) = &subject_profile.email && let Some(emailer) = &web_context.emailer { if let Err(e) = emailer .notify_rsvp_accepted(email, subject_did, event_name, &event_url) .await { tracing::error!("Failed to send RSVP accepted email to {}: {:?}", email, e); } else { tracing::info!( "Sent RSVP acceptance notification to {} for event {}", email, event_name ); } } } /// Format an error message as an HTML notification for HTMX responses. pub fn format_error_html(title: &str, message: &str, details: Option<&str>) -> String { if let Some(details) = details { format!( r#"

Error! {}

{}

Details: {}

"#, title, message, details ) } else { format!( r#"

Error! {}

{}

"#, title, message ) } } /// Format a success message as an HTML notification for HTMX responses. pub fn format_success_html( title: &str, message: &str, additional_info: Option>, ) -> String { let mut html = format!( r#"

Success! {}

{}

"#, title, message ); if let Some(info) = additional_info { for line in info { html.push_str(&format!("\n

{}

", line)); } } html.push_str("\n
"); html }