use crate::{auth::Auth, state::ReqState}; use axum::{ extract::{Multipart, State}, response::IntoResponse, Json, }; use hyper::StatusCode; use serde::Serialize; #[derive(Serialize)] struct UploadResponse { id: String, revocation_key: String, } pub async fn post( State(state): ReqState, Auth(_): Auth, mut multipart: Multipart, ) -> impl IntoResponse { let mut file = None; while let Some(field) = multipart.next_field().await.unwrap() { let bytes = field.bytes().await; if bytes.is_ok() { file = Some(bytes.unwrap()); } } if file.is_none() { return Err(StatusCode::BAD_REQUEST); } let file = file.unwrap(); let mut id = crate::utils::gen_filename(); while state.files_dir.join(&id).exists() { id = crate::utils::gen_filename(); } let path = state.files_dir.join(id.clone()); tokio::fs::write(path, file) .await .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; let revocation_key = crate::utils::gen_revocation_key(); sqlx::query!( "insert into files (id, revocation_key) values ($1, $2)", id, revocation_key ) .execute(&state.db) .await .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; Ok(Json(UploadResponse { id, revocation_key })) }