let page s b =
Printf.sprintf {|
WebAuthn Demo
%s|} s b
let overview notes authenticated_as users =
let authenticated_as =
match authenticated_as with
| None -> "Not authenticated
"
| Some user -> Printf.sprintf {|Authenticated as %s
|} user
and links =
{|Register
|}
and users =
String.concat ""
("Users
" ::
Hashtbl.fold (fun name keys acc ->
let handles = List.map (fun (_, h, _) -> h) keys in
(Printf.sprintf "- %s [authenticate] (%s)
" name name (String.concat ", " handles)) :: acc)
users [] @ [ "
" ])
in
page "" (String.concat "" (notes @ [authenticated_as;links;users]))
let register_view user challenge userid =
let script = Printf.sprintf {|
var publicKey = {
challenge: Uint8Array.from(window.atob("%s"), c=>c.charCodeAt(0)),
rp: {
id: "webauthn-demo.robur.coop",
name: "WebAuthn Demo from robur.coop"
},
user: {
id: Uint8Array.from(window.atob("%s"), c=>c.charCodeAt(0)),
displayName: "%s",
name: "%s"
},
pubKeyCredParams: [
{
type: "public-key",
alg: -7
}
]
};
navigator.credentials.create({ publicKey })
.then(function (credential) {
// send attestation response and client extensions
// to the server to proceed with the registration
// of the credential
console.log(credential);
// Move data into Arrays incase it is super long
let response = credential.response;
let attestationObject = new Uint8Array(response.attestationObject);
let clientDataJSON = new Uint8Array(response.clientDataJSON);
let rawId = new Uint8Array(credential.rawId);
var body =
JSON.stringify({
id: credential.id,
rawId: bufferEncode(rawId),
type: credential.type,
response: {
attestationObject: bufferEncode(attestationObject),
clientDataJSON: bufferEncode(clientDataJSON),
},
});
console.log(body);
let headers = {'Content-type': "application/json; charset=utf-8"};
let request = new Request('/register_finish', { method: 'POST', body: body, headers: headers } );
fetch(request)
.then(function (response) {
console.log(response);
if (!response.ok) {
console.log("bad response: " + response.status);
};
});
}).catch(function (err) {
console.error(err);
});
|} challenge userid user user
and body =
Printf.sprintf {|
Welcome %s.
|} user
in
page script body
let authenticate_view data user =
let script =
Printf.sprintf {|
var request = JSON.parse('%s');
setTimeout(function() {
u2f.sign(
request.appId,
request.challenge,
request.registeredKeys,
function(data) {
if(data.errorCode) {
switch (data.errorCode) {
case 4:
alert("This device is not registered for this account.");
break;
default:
alert("U2F failed with error code: " + data.errorCode);
}
return;
} else {
document.getElementById('token').value = JSON.stringify(data);
document.getElementById('form').submit();
}
}
);
}, 1000);
|} data
and body =
Printf.sprintf {|
Touch your U2F token to authenticate as %S.
|} user
in
page script body