this repo has no description
at fix-ts-uint8array 92 lines 2.8 kB view raw
1use axum::extract::State; 2use axum::Json; 3use serde_json::json; 4 5use crate::auth::AuthUser; 6use crate::config::AppState; 7use crate::errors::AppError; 8use crate::models::{PushPreferencesRequest, PushPreferencesResponse, PushSubscribeRequest}; 9 10/// GET /api/push/vapid-key 11pub async fn vapid_key(State(state): State<AppState>) -> Json<serde_json::Value> { 12 Json(json!({ "vapid_public_key": state.vapid_public_key })) 13} 14 15/// POST /api/push/subscribe 16pub async fn subscribe( 17 AuthUser(user_id): AuthUser, 18 State(state): State<AppState>, 19 Json(req): Json<PushSubscribeRequest>, 20) -> Result<Json<serde_json::Value>, AppError> { 21 let id = uuid::Uuid::new_v4().to_string(); 22 23 sqlx::query( 24 "INSERT INTO push_subscriptions (id, user_id, endpoint, p256dh, auth) 25 VALUES (?, ?, ?, ?, ?) 26 ON CONFLICT(endpoint) DO UPDATE SET p256dh = excluded.p256dh, auth = excluded.auth, user_id = excluded.user_id", 27 ) 28 .bind(&id) 29 .bind(&user_id) 30 .bind(&req.endpoint) 31 .bind(&req.p256dh) 32 .bind(&req.auth) 33 .execute(&state.db) 34 .await?; 35 36 Ok(Json(json!({ "ok": true }))) 37} 38 39/// DELETE /api/push/subscribe 40pub async fn unsubscribe( 41 AuthUser(user_id): AuthUser, 42 State(state): State<AppState>, 43) -> Result<Json<serde_json::Value>, AppError> { 44 sqlx::query("DELETE FROM push_subscriptions WHERE user_id = ?") 45 .bind(&user_id) 46 .execute(&state.db) 47 .await?; 48 49 Ok(Json(json!({ "ok": true }))) 50} 51 52/// GET /api/push/preferences 53pub async fn get_preferences( 54 AuthUser(user_id): AuthUser, 55 State(state): State<AppState>, 56) -> Result<Json<PushPreferencesResponse>, AppError> { 57 let row = sqlx::query_as::<_, (i32, String)>( 58 "SELECT COALESCE(reminder_enabled, 0), COALESCE(reminder_time, '20:00') FROM user_stats WHERE user_id = ?", 59 ) 60 .bind(&user_id) 61 .fetch_optional(&state.db) 62 .await?; 63 64 match row { 65 Some((enabled, time)) => Ok(Json(PushPreferencesResponse { 66 reminder_enabled: enabled != 0, 67 reminder_time: time, 68 })), 69 None => Ok(Json(PushPreferencesResponse { 70 reminder_enabled: false, 71 reminder_time: "20:00".to_string(), 72 })), 73 } 74} 75 76/// PUT /api/push/preferences 77pub async fn update_preferences( 78 AuthUser(user_id): AuthUser, 79 State(state): State<AppState>, 80 Json(req): Json<PushPreferencesRequest>, 81) -> Result<Json<serde_json::Value>, AppError> { 82 let enabled = i32::from(req.reminder_enabled); 83 84 sqlx::query("UPDATE user_stats SET reminder_enabled = ?, reminder_time = ? WHERE user_id = ?") 85 .bind(enabled) 86 .bind(&req.reminder_time) 87 .bind(&user_id) 88 .execute(&state.db) 89 .await?; 90 91 Ok(Json(json!({ "ok": true }))) 92}