started on TOTP

This commit is contained in:
2025-10-09 11:46:41 +01:00
parent 4f72cc6abe
commit f38a4f688a
6 changed files with 225 additions and 47 deletions
+40
View File
@@ -3,6 +3,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
use rand::Rng;
use rocket::{
Request,
fs::NamedFile,
http::{CookieJar, Status},
outcome::Outcome,
post,
@@ -17,6 +18,7 @@ use rocket_dyn_templates::{Template, context};
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use sqlx::postgres::PgQueryResult;
use totp_rs::{Algorithm, Secret, TOTP};
use crate::db::DbConn;
@@ -91,6 +93,29 @@ pub async fn login(
Err("login failed".to_string())
}
#[get("/totp")]
pub async fn mfa_page(session: Session) -> Template {
Template::render("2fa", context!())
}
#[get("/api/totp.jpg")]
pub async fn gen_totp(s: Session) -> Option<QrCodeImage> {
let totp = TOTP::new(
Algorithm::SHA1,
6,
1,
30,
Secret::generate_secret().to_bytes().unwrap(),
Some("Github".to_string()),
format!("{}", s.user_id),
)
.unwrap();
let qr = totp.get_qr_base64().unwrap();
Some(QrCodeImage(qr.into()))
}
#[derive(Debug)]
pub struct Session {
pub token: String,
@@ -153,3 +178,18 @@ impl<'r> FromRequest<'r> for Session {
}
}
}
use rocket::http::ContentType;
use rocket::response::{self, Responder, Response};
use std::io::Cursor;
pub struct QrCodeImage(Vec<u8>);
impl<'r> Responder<'r, 'static> for QrCodeImage {
fn respond_to(self, _: &'r rocket::Request<'_>) -> response::Result<'static> {
Response::build()
.header(ContentType::PNG)
.sized_body(self.0.len(), Cursor::new(self.0))
.ok()
}
}