use crate::database; use crate::models::ids::NotificationId; use crate::models::notifications::{Notification, NotificationAction}; use crate::routes::ApiError; use crate::util::auth::get_user_from_headers; use actix_web::{delete, get, web, HttpRequest, HttpResponse}; use serde::{Deserialize, Serialize}; use sqlx::PgPool; #[derive(Serialize, Deserialize)] pub struct NotificationIds { pub ids: String, } #[get("notifications")] pub async fn notifications_get( req: HttpRequest, web::Query(ids): web::Query, pool: web::Data, ) -> Result { let user = get_user_from_headers(req.headers(), &**pool).await?; let notification_ids = serde_json::from_str::>(&*ids.ids)? .into_iter() .map(|x| x.into()) .collect(); let notifications_data = database::models::notification_item::Notification::get_many(notification_ids, &**pool) .await?; let mut notifications: Vec = Vec::new(); for notification in notifications_data { if notification.user_id == user.id.into() || user.role.is_mod() { notifications.push(convert_notification(notification)); } } Ok(HttpResponse::Ok().json(notifications)) } #[get("{id}")] pub async fn notification_get( req: HttpRequest, info: web::Path<(NotificationId,)>, pool: web::Data, ) -> Result { let user = get_user_from_headers(req.headers(), &**pool).await?; let id = info.into_inner().0; let notification_data = database::models::notification_item::Notification::get(id.into(), &**pool).await?; if let Some(data) = notification_data { if user.id == data.user_id.into() || user.role.is_mod() { Ok(HttpResponse::Ok().json(convert_notification(data))) } else { Ok(HttpResponse::NotFound().body("")) } } else { Ok(HttpResponse::NotFound().body("")) } } pub fn convert_notification( notif: database::models::notification_item::Notification, ) -> Notification { Notification { id: notif.id.into(), user_id: notif.user_id.into(), type_: notif.notification_type, title: notif.title, text: notif.text, link: notif.link, read: notif.read, created: notif.created, actions: notif .actions .into_iter() .map(|x| NotificationAction { title: x.title, action_route: (x.action_route_method, x.action_route), }) .collect(), } } #[delete("{id}")] pub async fn notification_delete( req: HttpRequest, info: web::Path<(NotificationId,)>, pool: web::Data, ) -> Result { let user = get_user_from_headers(req.headers(), &**pool).await?; let id = info.into_inner().0; let notification_data = database::models::notification_item::Notification::get(id.into(), &**pool).await?; if let Some(data) = notification_data { if data.user_id == user.id.into() || user.role.is_mod() { let mut transaction = pool.begin().await?; database::models::notification_item::Notification::remove(id.into(), &mut transaction) .await?; transaction.commit().await?; Ok(HttpResponse::NoContent().body("")) } else { Err(ApiError::CustomAuthenticationError( "You are not authorized to delete this notification!".to_string(), )) } } else { Ok(HttpResponse::NotFound().body("")) } } #[delete("notifications")] pub async fn notifications_delete( req: HttpRequest, web::Query(ids): web::Query, pool: web::Data, ) -> Result { let user = get_user_from_headers(req.headers(), &**pool).await?; let notification_ids = serde_json::from_str::>(&*ids.ids)? .into_iter() .map(|x| x.into()) .collect(); let mut transaction = pool.begin().await?; let notifications_data = database::models::notification_item::Notification::get_many(notification_ids, &**pool) .await?; let mut notifications: Vec = Vec::new(); for notification in notifications_data { if notification.user_id == user.id.into() || user.role.is_mod() { notifications.push(notification.id); } } database::models::notification_item::Notification::remove_many(notifications, &mut transaction) .await?; transaction.commit().await?; Ok(HttpResponse::NoContent().body("")) }