nom-nom-nix-gc/src/templates/webauthn-login.js

69 lines
2.3 KiB
JavaScript

async function fetch_challenge () {
const username = document.getElementById("user-name").value;
const init_data = {
username: username,
};
const challenge = await fetch("/login/init", {
method: 'POST',
body: JSON.stringify(init_data),
headers: {
'Content-Type': 'application/json'
}
});
return await challenge.json();
}
async function solve_challenge (challenge) {
// Decode challenge and credential ID base64 strings into JS arrays.
challenge.publicKey.challenge = Base64.toUint8Array(challenge.publicKey.challenge);
challenge.publicKey.allowCredentials = challenge.publicKey.allowCredentials.map((cred) => {
return Object.assign({}, cred, {
id: Base64.toUint8Array(cred.id)
});
});
return navigator.credentials.get(challenge);
}
function encodeSolvedChallenge(solvedChallenge) {
const uinttobase64 = (array) => Base64.fromUint8Array(new Uint8Array(array), true);
return {
id: solvedChallenge.id,
rawId: uinttobase64(solvedChallenge.rawId),
response: {
authenticatorData: uinttobase64(solvedChallenge.response.authenticatorData),
clientDataJSON: uinttobase64(solvedChallenge.response.clientDataJSON),
signature: uinttobase64(solvedChallenge.response.signature),
userHandle: solvedChallenge.response.userHandle
},
type: solvedChallenge.type
};
}
async function finish_auth (challengeUuid, solvedChallenge) {
// Encode challenge response
console.log(solvedChallenge);
const encodedSolvedChallenge = encodeSolvedChallenge(solvedChallenge);
console.log(encodedSolvedChallenge);
const resp = await fetch("/login/finish", {
method: 'POST',
body: JSON.stringify({uuid: challengeUuid, challenge: encodedSolvedChallenge}),
headers: { 'Content-Type': 'application/json' }
});
return resp;
}
async function perform_webauthn_dance () {
const challenge = await fetch_challenge()
let solved = await solve_challenge(challenge.challenge);
let finished = await finish_auth(challenge.uuid, solved);
}
// Main
(async () => {
const button = document.getElementById("key-form");
button.addEventListener("submit", async (e) => {
e.preventDefault();
await perform_webauthn_dance();
});
}) ();