perfect-postcode/server-rs/src/routes/newsletter.rs
2026-03-15 17:38:26 +00:00

70 lines
1.9 KiB
Rust

use std::sync::Arc;
use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use axum::{Extension, Json};
use serde::Deserialize;
use tracing::warn;
use crate::auth::OptionalUser;
use crate::pocketbase::auth_superuser;
use crate::state::AppState;
#[derive(Deserialize)]
pub struct UpdateNewsletterRequest {
newsletter: bool,
}
pub async fn patch_newsletter(
state: Arc<AppState>,
Extension(user): Extension<OptionalUser>,
Json(req): Json<UpdateNewsletterRequest>,
) -> Response {
let user = match user.0 {
Some(u) => u,
None => return StatusCode::UNAUTHORIZED.into_response(),
};
let pb_url = state.pocketbase_url.trim_end_matches('/');
let token = match auth_superuser(
&state.http_client,
pb_url,
&state.pocketbase_admin_email,
&state.pocketbase_admin_password,
)
.await
{
Ok(t) => t,
Err(err) => {
warn!("Failed to authenticate as PocketBase superuser: {err}");
return StatusCode::BAD_GATEWAY.into_response();
}
};
let url = format!("{pb_url}/api/collections/users/records/{}", user.id);
let res = state
.http_client
.patch(&url)
.header("Authorization", format!("Bearer {token}"))
.json(&serde_json::json!({ "newsletter": req.newsletter }))
.send()
.await;
match res {
Ok(resp) if resp.status().is_success() => {
state.token_cache.invalidate_by_user_id(&user.id);
StatusCode::OK.into_response()
}
Ok(resp) => {
let status = resp.status();
let text = resp.text().await.unwrap_or_default();
warn!("PocketBase user update failed ({status}): {text}");
StatusCode::BAD_GATEWAY.into_response()
}
Err(err) => {
warn!("PocketBase request error: {err}");
StatusCode::BAD_GATEWAY.into_response()
}
}
}