Something went wrong. Try again.
currently proxies requests for owned games, since that is hidden behind a steam developer key and not entirely public
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546use axum::{ extract::FromRequestParts, http::{request::Parts, StatusCode},};
use crate::AppState;
/// Extractor that gates a route behind the `X-Api-Token` header, checked/// against the shared secret in config. A header (not a query param) so the/// token never ends up in nginx access logs or gets pasted around in URLs.pub struct ApiToken;
#[axum::async_trait]impl FromRequestParts<AppState> for ApiToken { type Rejection = (StatusCode, &'static str);
async fn from_request_parts( parts: &mut Parts, state: &AppState, ) -> Result<Self, Self::Rejection> { let provided = parts .headers .get("X-Api-Token") .and_then(|v| v.to_str().ok());
match provided { Some(token) if constant_time_eq(token.as_bytes(), state.config.auth.token.as_bytes()) => { Ok(ApiToken) } _ => Err((StatusCode::UNAUTHORIZED, "missing or invalid X-Api-Token header")), } }}
/// Avoids leaking the token's length/prefix via response-timing side channels.fn constant_time_eq(a: &[u8], b: &[u8]) -> bool { if a.len() != b.len() { return false; } let mut diff = 0u8; for (x, y) in a.iter().zip(b.iter()) { diff |= x ^ y; } diff == 0}