From e6a5dbd90ca105e029e2394caa0e6374ac899851 Mon Sep 17 00:00:00 2001 From: SirBlobby Date: Sat, 18 Jul 2026 18:04:20 -0400 Subject: [PATCH] Add account files to desktop API --- server/src/desktop.rs | 83 +++++++++++++++++++++++++++++++++++++++++++ server/src/main.rs | 2 ++ 2 files changed, 85 insertions(+) diff --git a/server/src/desktop.rs b/server/src/desktop.rs index 86d8406..c11c366 100644 --- a/server/src/desktop.rs +++ b/server/src/desktop.rs @@ -973,3 +973,86 @@ pub async fn push_document( updated_at: now, }))) } + +#[derive(Serialize)] +pub struct CloudFile { + pub id: String, + pub name: String, + pub mime_type: String, + pub folder_id: Option, + pub created_at: String, +} + +pub async fn list_account_files( + State(state): State, + headers: HeaderMap, + Query(query): Query, +) -> Result>, (StatusCode, String)> { + let user_id = authenticate(&state, &headers).await?; + + let rows = match &query.folder_id { + Some(folder_id) => sqlx::query_as::<_, (String, String, String, Option, String)>( + "SELECT id, name, mime_type, folder_id, created_at FROM files \ + WHERE owner_id = ? AND folder_id = ? ORDER BY name ASC", + ) + .bind(&user_id) + .bind(folder_id) + .fetch_all(&state.db) + .await, + None => sqlx::query_as::<_, (String, String, String, Option, String)>( + "SELECT id, name, mime_type, folder_id, created_at FROM files \ + WHERE owner_id = ? AND folder_id IS NULL ORDER BY name ASC", + ) + .bind(&user_id) + .fetch_all(&state.db) + .await, + } + .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?; + + Ok(Json( + rows.into_iter() + .map(|(id, name, mime_type, folder_id, created_at)| CloudFile { + id, + name, + mime_type, + folder_id, + created_at, + }) + .collect(), + )) +} + +#[derive(Serialize)] +pub struct CloudFileContent { + pub name: String, + pub mime_type: String, + pub encoding: String, + pub content: String, +} + +pub async fn pull_account_file( + State(state): State, + headers: HeaderMap, + Path(id): Path, +) -> Result, (StatusCode, String)> { + let user_id = authenticate(&state, &headers).await?; + + let row = sqlx::query_as::<_, (String, String, Vec)>( + "SELECT name, mime_type, data FROM files WHERE id = ? AND owner_id = ?", + ) + .bind(&id) + .bind(&user_id) + .fetch_optional(&state.db) + .await + .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))? + .ok_or((StatusCode::NOT_FOUND, "File not found".to_string()))?; + + let (name, mime_type, data) = row; + + Ok(Json(CloudFileContent { + name, + mime_type, + encoding: "base64".to_string(), + content: BASE64.encode(&data), + })) +} diff --git a/server/src/main.rs b/server/src/main.rs index 6a10d24..a5a9828 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -152,6 +152,8 @@ async fn main() { .route("/documents", get(desktop::list_documents)) .route("/documents/{id}", get(desktop::pull_document).put(desktop::push_document)) .route("/shared", get(desktop::list_shared)) + .route("/files", get(desktop::list_account_files)) + .route("/files/{id}", get(desktop::pull_account_file)) .route("/spaces/{id}/file", get(desktop::pull_file).put(desktop::push_file).delete(desktop::delete_file)); let v1_routes = Router::new()