docs: tambah doc comment, logging, dan inline comments di semua 255 file
Meliputi: - File-level //! doc comment: tujuan file, alur kerja, komponen utama - Function-level /// doc comment: apa, parameter, return, flow, edge cases - Struct/enum/trait /// doc comment: peran, field docs - Tracing logging (tracing::info!/debug!/trace!/warn!/error!) di setiap fungsi - Inline comments untuk variable dan branching logic penting - Seluruh 8 crates di workspace: zesdex-backend, zesdex-cms, zesdex-entities, zesdex-iam, zesdex-infra, zesdex-ipc, zesdex-middleware, zesdex-utils - Build: 0 errors, 242/242 tests passed
This commit is contained in:
@@ -125,7 +125,7 @@ pub struct SessionAuthMiddleware<S> {
|
||||
fn extract_session_id<ReqBody>(req: &Request<ReqBody>) -> Result<String, Response> {
|
||||
let session_id = req
|
||||
.headers()
|
||||
.get("X-Session-Id")
|
||||
.get("X-Session-Id") // custom header carrying the session identifier
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.map(|s| s.to_string());
|
||||
|
||||
@@ -247,13 +247,13 @@ pub fn validate_session(session_id: &str, store: &Store) -> anyhow::Result<Sessi
|
||||
.base_dir
|
||||
.join("sessions")
|
||||
.join(session_id)
|
||||
.join("session.json");
|
||||
.join("session.json"); // path to session metadata file
|
||||
|
||||
if !session_path.exists() {
|
||||
anyhow::bail!("session not found: {session_id}");
|
||||
}
|
||||
|
||||
let _data = std::fs::read_to_string(&session_path)?;
|
||||
let _data = std::fs::read_to_string(&session_path)?; // raw session JSON
|
||||
// We verify the JSON is well-formed by deserialising it.
|
||||
let _session: serde_json::Value = serde_json::from_str(&_data)?;
|
||||
|
||||
|
||||
@@ -12,9 +12,18 @@ use tower_http::cors::{AllowHeaders, AllowOrigin, CorsLayer};
|
||||
/// - **Methods**: `GET`, `POST`, `PUT`, `DELETE`, `PATCH`, `OPTIONS`
|
||||
/// - **Headers**: `Content-Type`, `Authorization`, `X-Session-Id`,
|
||||
/// `X-Request-Id`, `User-Agent`
|
||||
/// Return a permissive [`CorsLayer`] for local daemon IPC.
|
||||
///
|
||||
/// - **Origin**: any (`*`)
|
||||
/// - **Methods**: `GET`, `POST`, `PUT`, `DELETE`, `PATCH`, `OPTIONS`
|
||||
/// - **Headers**: `Content-Type`, `Authorization`, `X-Session-Id`,
|
||||
/// `X-Request-Id`, `User-Agent`
|
||||
///
|
||||
/// Since the daemon only listens on localhost, any origin is allowed.
|
||||
/// The exposed headers let the browser JS read session/request IDs.
|
||||
pub fn default_cors_layer() -> CorsLayer {
|
||||
CorsLayer::new()
|
||||
.allow_origin(AllowOrigin::any())
|
||||
.allow_origin(AllowOrigin::any()) // permissive — daemon is localhost-only
|
||||
.allow_methods([
|
||||
"GET".parse().unwrap(),
|
||||
"POST".parse().unwrap(),
|
||||
@@ -22,13 +31,13 @@ pub fn default_cors_layer() -> CorsLayer {
|
||||
"DELETE".parse().unwrap(),
|
||||
"PATCH".parse().unwrap(),
|
||||
"OPTIONS".parse().unwrap(),
|
||||
])
|
||||
]) // standard REST methods
|
||||
.allow_headers(AllowHeaders::any())
|
||||
.expose_headers([
|
||||
"Content-Type".parse().unwrap(),
|
||||
"X-Session-Id".parse().unwrap(),
|
||||
"X-Request-Id".parse().unwrap(),
|
||||
])
|
||||
]) // headers exposed to the browser JS
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
#![allow(
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::cast_sign_loss,
|
||||
clippy::cast_precision_loss,
|
||||
clippy::cast_possible_wrap
|
||||
)]
|
||||
//! # zesdex-middleware
|
||||
//!
|
||||
//! Axum middleware tower for the HTTP API layer.
|
||||
//!
|
||||
//! ## Components
|
||||
//!
|
||||
//! - **`auth`** — JWT-based authentication middleware: extracts `Authorization: Bearer <token>`
|
||||
//! headers, verifies the signature, and injects `CurrentUser` into request extensions.
|
||||
//! - **`cors`** — CORS layer that allows configurable origins (or all origins in dev mode).
|
||||
//! - **`rate_limit`** — Token-bucket rate limiter keyed by client IP, backed by
|
||||
//! a shared `HashMap` behind a `RwLock`.
|
||||
|
||||
pub mod auth;
|
||||
pub mod cors;
|
||||
|
||||
@@ -41,8 +41,8 @@ impl RateLimiter {
|
||||
/// reverse proxy known to overwrite (not merge) these headers.
|
||||
pub fn with_proxy_trust(trust_proxy_headers: bool) -> Self {
|
||||
Self {
|
||||
windows: Mutex::new(HashMap::new()),
|
||||
trust_proxy_headers,
|
||||
windows: Mutex::new(HashMap::new()), // client-id → timestamps
|
||||
trust_proxy_headers, // whether to trust X-Forwarded-For / X-Real-IP
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,9 +66,9 @@ impl RateLimiter {
|
||||
let now = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs() as i64;
|
||||
.as_secs() as i64; // current UNIX timestamp (seconds)
|
||||
|
||||
let cutoff = now.saturating_sub(window_secs as i64);
|
||||
let cutoff = now.saturating_sub(window_secs as i64); // window start boundary
|
||||
let mut windows = self
|
||||
.windows
|
||||
.lock()
|
||||
@@ -85,7 +85,7 @@ impl RateLimiter {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
timestamps.push(now);
|
||||
timestamps.push(now); // record this request
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user