Skip to content

Commit

Permalink
Added delete (message/all) api endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
marlonbaeten committed Apr 15, 2024
1 parent 8b9c976 commit b380da4
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 6 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ docker run --rm -p 1080:1080 -p 1025:1025 marlonb/mailcrab:latest

Both the backend server and the frontend are written in Rust. The backend receives email over an unencrypted connection on a configurable port. All email is stored in memory while the application is running. An API exposes all received email:

- `/api/messages` return all message metadata
- `/api/message/[id]` returns a complete message, given its `id`
- `/api/version` returns version information about the executable
- `/ws` send email metadata to each connected client when a new email is received
- `GET /api/messages` return all message metadata
- `GET /api/message/[id]` returns a complete message, given its `id`
- `POST /api/delete/[id]` deletes a message, given its `id`
- `POST /api/delete-all` deletes all messages
- `GET /api/version` returns version information about the executable
- `GET /ws` send email metadata to each connected client when a new email is received

The frontend initially performs a call to `/api/messages` to receive all existing email metadata and then subscribes for new messages using the websocket connection. When opening a message, the `/api/message/[id]` endpoint is used to retrieve the complete message body and raw email.

Expand Down
2 changes: 1 addition & 1 deletion backend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ async fn send_message(
.join("\n");
let html: String = format!(
"{}\n<p><a href=\"https://github.com/tweedegolf/mailcrab\">external link</a></p>",
body.replace("\n", "<br>\n")
body.replace('\n', "<br>\n")
);

let builder = Message::builder()
Expand Down
36 changes: 35 additions & 1 deletion backend/src/web_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use axum::{
},
http::{header, StatusCode, Uri},
response::{Html, IntoResponse, Response},
routing::get,
routing::{get, post},
Extension, Json, Router,
};
use serde::Serialize;
Expand Down Expand Up @@ -165,6 +165,38 @@ async fn message_body_handler(
}
}

/// delete a message
async fn message_delete_handler(
Path(id): Path<Uuid>,
Extension(state): Extension<Arc<AppState>>,
) -> Result<StatusCode, StatusCode> {
if let Ok(mut storage) = state.storage.write() {
if storage.remove(&id).is_some() {
info!("message {} removed", &id);

Ok(StatusCode::OK)
} else {
Err(StatusCode::NOT_FOUND)
}
} else {
Err(StatusCode::INTERNAL_SERVER_ERROR)
}
}

/// delete all messages
async fn message_delete_all_handler(
Extension(state): Extension<Arc<AppState>>,
) -> Result<StatusCode, StatusCode> {
if let Ok(mut storage) = state.storage.write() {
storage.clear();
info!("storage cleared");

Ok(StatusCode::OK)
} else {
Err(StatusCode::INTERNAL_SERVER_ERROR)
}
}

/// return version
async fn version_handler() -> Result<Json<VersionInfo>, StatusCode> {
let vi = VersionInfo {
Expand Down Expand Up @@ -220,6 +252,8 @@ pub async fn web_server(
.route("/api/messages", get(messages_handler))
.route("/api/message/:id", get(message_handler))
.route("/api/message/:id/body", get(message_body_handler))
.route("/api/delete/:id", post(message_delete_handler))
.route("/api/delete-all", post(message_delete_all_handler))
.route("/api/version", get(version_handler))
.nest_service("/static", get(static_handler));

Expand Down

0 comments on commit b380da4

Please sign in to comment.