diff --git a/mnemonic-hash-checker/src/index.html b/mnemonic-hash-checker/src/index.html new file mode 100644 index 0000000..a6ecc55 --- /dev/null +++ b/mnemonic-hash-checker/src/index.html @@ -0,0 +1,41 @@ + + + + + + Milk Sad Lookup + + + +
+

MilkSad Lookup Service

+

+ Input a SHA256 hash of your mnemonic phrase. DO NOT ENTER your + mnemonic phrase in cleartext. +

+ +
+
+ Lookup +
+
+ +
+
+
+ +
+
+
+ + diff --git a/mnemonic-hash-checker/src/main.rs b/mnemonic-hash-checker/src/main.rs index c0a436a..caff246 100644 --- a/mnemonic-hash-checker/src/main.rs +++ b/mnemonic-hash-checker/src/main.rs @@ -2,8 +2,9 @@ use std::net::SocketAddr; use std::sync::Arc; use axum::{ - http::StatusCode, - extract::{Path, State}, + extract::{Query, State}, + http::{header::CONTENT_TYPE, StatusCode}, + response::{AppendHeaders, IntoResponse}, routing::get, Json, Router, }; @@ -15,6 +16,8 @@ use clap::Parser; use deadpool_postgres::{Config, ManagerConfig, Pool, RecyclingMethod, Runtime}; use tokio_postgres::NoTls; +use serde::Deserialize; + use tower_http::catch_panic::CatchPanicLayer; use tower_http::trace::TraceLayer; @@ -68,15 +71,20 @@ fn setup_registry() { .init(); } +async fn index() -> impl IntoResponse { + ( + AppendHeaders([(CONTENT_TYPE, "text/html")]), + include_str!("index.html"), + ) +} + #[tracing::instrument(skip(state))] async fn check_hash(hash: &str, state: &AppState) -> Result { let client = state.pool.get().await?; let column = &state.database_column; let table = &state.database_table; let formatted_query = format!("SELECT {column} FROM {table} WHERE hash = $1"); - let query = client - .prepare_cached(formatted_query.as_str()) - .await?; + let query = client.prepare_cached(formatted_query.as_str()).await?; let rows = client.query(&query, &[&hash]).await?; if let Some(row) = rows.get(0) { let retrieved_hash: String = row.try_get(0)?; @@ -86,13 +94,18 @@ async fn check_hash(hash: &str, state: &AppState) -> Result { } } +#[derive(Deserialize)] +struct CheckQuery { + sha256: String, +} + // Note: Exposes *zero* information of potential errors to clients. -#[tracing::instrument(skip(hash, state))] +#[tracing::instrument(skip(query, state))] async fn check_hash_slug( - Path(hash): Path, + query: Query, State(state): State>, ) -> (StatusCode, Json>) { - let result = check_hash(&hash, &state).await; + let result = check_hash(&query.sha256, &state).await; let status_code = match result.as_ref() { Ok(true) => StatusCode::OK, Ok(false) => StatusCode::NOT_FOUND, @@ -125,7 +138,8 @@ async fn main() -> Result<()> { .unwrap_or_else(|| (std::net::Ipv4Addr::new(127, 0, 0, 1), 8000).into()); let app = Router::new() - .route("/check/:hash", get(check_hash_slug)) + .route("/", get(index)) + .route("/check", get(check_hash_slug)) .with_state(Arc::new(AppState { pool, database_table: cli_config.database_table,