main
use crate::AuthService;
use crate::errors::AuthResult;
use crate::events::{Labels, label};
use crate::session::Session;
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
pub const SESSION_CHALLENGE: &str = "challenge";
#[derive(Clone, Debug, Deserialize, Serialize, ToSchema)]
pub struct ChallengeResponse {
pub context: String,
pub difficulty: u32,
pub issued_at: u64,
pub expires_at: u64,
}
#[derive(Clone, Debug, Deserialize, Serialize, ToSchema)]
pub struct PowProofRequest {
pub nonce: u64,
pub payload: Vec<u8>,
}
impl AuthService {
#[tracing::instrument(skip_all, fields(request_id = %request_id, client_ip = ?session.client_ip().ok().flatten()))]
pub async fn challenge(
&self,
session: Session,
request_id: String,
) -> AuthResult<ChallengeResponse> {
let response = crate::pow::store::issue(&session, self.pow()).await?;
self.emit_labeled(
label::AUTH_CHALLENGE_CREATE,
Labels::new()
.with_opt(label::USER_ID, session.user_id().ok().flatten())
.with(label::REQUEST_ID, &request_id),
&response,
Some(request_id.as_str()),
)
.await;
Ok(response)
}
#[tracing::instrument(skip_all, fields(request_id = %request_id, client_ip = ?session.client_ip().ok().flatten()))]
pub async fn challenge_verify_pow(
&self,
session: Session,
proof: &PowProofRequest,
expected_payload: &[u8],
request_id: String,
) -> AuthResult<()> {
crate::pow::store::verify(&session, self.cache(), proof, expected_payload).await?;
self.emit_labeled(
label::AUTH_CHALLENGE_USED,
Labels::new()
.with_opt(label::USER_ID, session.user_id().ok().flatten())
.with(label::REQUEST_ID, &request_id),
serde_json::json!({
"user_id": session.user_id().ok().flatten(),
}),
Some(request_id.as_str()),
)
.await;
Ok(())
}
}