brewlog/src/application/routes/app/webauthn.rs
Jon Seager 58b551afac
refactor(routes): split account, checkin, and webauthn into api/app
Split each mixed file along the api/page boundary:
- account.rs: page handler + view types to app/, API handlers to api/
- checkin.rs: checkin_page to app/, submit_checkin to api/
- webauthn.rs: register_page + cli_callback_page to app/
2026-02-05 19:04:52 +00:00

80 lines
2 KiB
Rust

use askama::Template;
use axum::extract::{Path, State};
use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use tracing::warn;
use crate::application::routes::render_html;
use crate::application::server::AppState;
use crate::infrastructure::auth::hash_token;
// --- Templates ---
#[derive(Template)]
#[template(path = "pages/register.html")]
struct RegisterTemplate {
nav_active: &'static str,
is_authenticated: bool,
version_info: &'static crate::VersionInfo,
token: String,
}
#[derive(Template)]
#[template(path = "pages/cli_callback.html")]
struct CliCallbackTemplate {
nav_active: &'static str,
is_authenticated: bool,
version_info: &'static crate::VersionInfo,
token: Option<String>,
error: Option<String>,
}
// --- Registration page (bootstrap flow) ---
#[tracing::instrument(skip(state))]
pub(crate) async fn register_page(
State(state): State<AppState>,
Path(token): Path<String>,
) -> Result<Response, StatusCode> {
// Validate the token exists and is usable
let token_hash = hash_token(&token);
let reg_token = state
.registration_token_repo
.get_by_token_hash(&token_hash)
.await
.map_err(|err| {
warn!(
%err,
token_hash_prefix = &token_hash[..8],
"registration token lookup failed"
);
StatusCode::NOT_FOUND
})?;
if !reg_token.is_valid() {
return Err(StatusCode::GONE);
}
let template = RegisterTemplate {
nav_active: "",
is_authenticated: false,
version_info: &crate::VERSION_INFO,
token,
};
render_html(template).map(IntoResponse::into_response)
}
// --- CLI callback page ---
pub(crate) async fn cli_callback_page() -> Result<Response, StatusCode> {
let template = CliCallbackTemplate {
nav_active: "",
is_authenticated: false,
version_info: &crate::VERSION_INFO,
token: None,
error: None,
};
render_html(template).map(IntoResponse::into_response)
}