Webauthn: init

This commit is contained in:
Félix Baylac Jacqué 2023-01-22 18:12:45 +01:00
parent f54b4e591d
commit 448476fda9
6 changed files with 39 additions and 7 deletions

View File

@ -17,7 +17,7 @@ pub fn landing(state: models::AppState) -> impl Filter<Extract = impl warp::Repl
}
pub fn start_webauthn_registration(state: models::AppState) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone + '_ {
warp::path!("webauthn" / "start-registration")
warp::path!("account" / "register-init")
.and(warp::post())
.and(json_body())
.and(warp::any().map(move || state.clone()))

View File

@ -11,11 +11,9 @@ pub async fn landing_page (app_state: AppState<'_>) -> Result<impl Reply, Infall
pub async fn start_webauthn_registration(user: User, app_state: AppState<'_>) -> Result<impl warp::Reply, Infallible> {
let mut db = app_state.db.lock().await;
// TODO: query the user
let mut user = db.users.first_mut().unwrap();
let user = db.users.first_mut().unwrap();
let (creation_challenge_response, passkey_registration) = app_state.webauthn.start_passkey_registration(user.uuid, &user.user_name, &user.display_name, None).unwrap();
user.creation_challenge_response = Some(creation_challenge_response);
Ok(warp::reply::json(&"hello".to_string()))
Ok(warp::reply::json(&creation_challenge_response))
}

View File

@ -19,7 +19,6 @@ pub struct User {
pub uuid: Uuid,
pub user_name: String,
pub display_name: String,
pub creation_challenge_response: Option<webauthn_rs::prelude::CreationChallengeResponse>,
}
#[derive(Clone)]
@ -40,7 +39,6 @@ impl AppState<'_> {
uuid: Uuid::new_v4(),
user_name: "felix".to_string(),
display_name: "Félix".to_string(),
creation_challenge_response: None,
};
let db: Db = Arc::new(Mutex::new(Database {
users: Vec::from([user])

View File

@ -17,5 +17,8 @@
Hello world
</div>
</main>
<script>
{{> js}}
</script>
</body>
</html>

View File

@ -11,8 +11,11 @@ pub fn new<'a>() -> Result<Handlebars<'a>, RenderError> {
let landing_path = rootpath.join("src/templates/landing.hbs");
let mut hbs = handlebars::Handlebars::new();
let css = rootpath.join("src/templates/main.css");
let js = rootpath.join("src/templates/webauthn.js");
hbs.register_template_file("landing", landing_path.to_str().unwrap())?;
hbs.register_template_file("css", css.to_str().unwrap())?;
hbs.register_template_file("js", js.to_str().unwrap())?;
return Ok(hbs)
}

30
src/templates/webauthn.js Normal file
View File

@ -0,0 +1,30 @@
const start_webauthn = async () => {
const init_data = {
uuid: self.crypto.randomUUID(),
user_name: "ninjatrappeur",
display_name: "ninjatrappeur"
};
const challenge_resp = await fetch("/account/register-init", {
method: 'POST',
body: JSON.stringify(init_data),
headers: {
'Content-Type': 'application/json'
}
});
return await challenge_resp.json();
}
const solve_challenge = async (publicKey) => {
const encoder = new TextEncoder();
publicKey.publicKey.challenge = encoder.encode(publicKey.publicKey.challenge);
publicKey.publicKey.user.id = encoder.encode(publicKey.publicKey.user.id);
return await navigator.credentials.create(publicKey);
}
// Main
(async () => {
const publicKey = await start_webauthn()
let solved = await solve_challenge(publicKey);
// TODO: send back to server
console.log(solved);
}) ();