Skip to content
Clone
5ef202e
37 lines 1.3 KB Rust
use axum::extract::{Extension, State};
use crate::error::AuthError;
use crate::features::AuthService;
use crate::pow::Challenge;
use export::data::AppResponseData;
/// A freshly issued, client-bound PoW challenge for the caller to solve.
#[derive(Debug, Clone, serde::Serialize, utoipa::ToSchema)]
pub struct PowChallengeResp {
/// The signed challenge to solve (echoed back verbatim in `PowProof`).
#[schema(value_type = String)]
pub challenge: Challenge,
/// How long the challenge remains valid, in seconds.
pub ttl_seconds: u64,
}
#[utoipa::path(
get,
path = "/auth/pow/challenge",
tag = "auth",
responses(
(status = 200, description = "A fresh PoW challenge bound to this client.", body = AppResponseData<PowChallengeResp>),
(status = 400, description = "PoW not configured.", body = super::openapi::ErrorBody),
(status = 429, description = "Rate limited.", body = super::openapi::ErrorBody),
),
)]
pub(crate) async fn handler(
State(svc): State<AuthService>,
Extension(cid): Extension<rate_limit::ClientId>,
) -> Result<AppResponseData<PowChallengeResp>, AuthError> {
let (challenge, ttl) = svc.pow.issue_challenge_bound(&cid.0).await?;
Ok(AppResponseData::ok(PowChallengeResp {
challenge,
ttl_seconds: ttl,
}))
}