app/public/sign.js in clarion-0.3.0 vs app/public/sign.js in clarion-1.0.0

- old
+ new

@@ -1,105 +1,125 @@ "use strict"; -document.addEventListener("DOMContentLoaded", function() { +document.addEventListener("DOMContentLoaded", async function() { let processionElem = document.getElementById("procession"); let handleUnsupported = () => { processionElem.className = 'procession_unsupported'; }; - let unsupportedTimer = setTimeout(handleUnsupported, 3000); + if (!navigator.credentials) return handleUnsupported(); - window.u2f.getApiVersion((ver) => { - console.log(ver); - clearTimeout(unsupportedTimer); + const requestOptions = JSON.parse(processionElem.attributes['data-webauthn-request'].value); + requestOptions.publicKey.challenge = new Uint8Array(requestOptions.publicKey.challenge).buffer; + requestOptions.publicKey.allowCredentials = requestOptions.publicKey.allowCredentials.map((v) => ({type: v.type, id: new Uint8Array(v.id).buffer})); + console.log(requestOptions); + const authnId = processionElem.attributes['data-authn-id'].value; + const reqId = processionElem.attributes['data-req-id'].value; - let authnId = processionElem.attributes['data-authn-id'].value; - let appId = processionElem.attributes['data-app-id'].value; - let reqId = processionElem.attributes['data-req-id'].value; - let requests = JSON.parse(processionElem.attributes['data-requests'].value); - let challenge = JSON.parse(processionElem.attributes['data-challenge'].value); + const cancelRequest = async function (e) { + if (e) e.preventDefault(); + const payload = JSON.stringify({ + req_id: reqId, + }); - let requestCancel = (e) => { - if (e) e.preventDefault(); - let payload = JSON.stringify({ - req_id: reqId, - }); - - let handleError = (err) => { - console.log(err); + try { + const resp = await fetch(`/ui/cancel/${authnId}`, {credentials: 'include', method: 'POST', body: payload}); + console.log(resp); + if (!resp.ok) { processionElem.className = 'procession_error'; - }; - - fetch(`/ui/cancel/${authnId}`, {credentials: 'include', method: 'POST', body: payload}).then((resp) => { - console.log(resp); - if (!resp.ok) { - processionElem.className = 'procession_error'; - return; - } - return resp.json().then((json) => { - console.log(json); - if (json.ok) { - processionElem.className = 'procession_cancel'; - } else { - processionElem.className = 'procession_error'; - } - }); - }).catch(handleError); - }; - document.getElementById("cancel_link").addEventListener("click", requestCancel); - - let processCallback = (json) => { - processionElem.className = 'procession_ok'; - if (window.opener) window.close(); + return; + } + const json = await resp.json(); + console.log(json); + if (json.ok) { + processionElem.className = 'procession_cancel'; + } else { + processionElem.className = 'procession_error'; + } + } catch (e) { + console.log(err); + processionElem.className = 'procession_error'; } + }; + document.getElementById("cancel_link").addEventListener("click", cancelRequest); - let cb = (response) => { - console.log(response); + const startAssertionRequest = async function() { + processionElem.className = 'procession_wait'; - if (response.errorCode == window.u2f.ErrorCodes.TIMEOUT) { - processionElem.className = 'procession_timeout'; + let assertion; + try { + assertion = await navigator.credentials.get(requestOptions); + console.log(assertion); + if (!assertion) { + processionElem.className = 'procession_unambigious'; return; - } else if (response.errorCode) { - processionElem.className = 'procession_error'; - return; } - processionElem.className = 'procession_contact'; + } catch (e) { + document.getElementById("error_message").innerHTML = `WebAuthn (${e.toString()})`; + processionElem.className = 'procession_error'; + console.log(e); - let payload = JSON.stringify({ - req_id: reqId, - response: JSON.stringify(response), - }); - - let handleError = (err) => { - console.log(err); - processionElem.className = 'procession_error'; - }; - - fetch(`/ui/verify/${authnId}`, {credentials: 'include', method: 'POST', body: payload}).then((resp) => { - console.log(resp); - if (!resp.ok) { - processionElem.className = 'procession_error'; + if (e instanceof DOMException) { + if (e.name == 'NotAllowedError') { + processionElem.className = 'procession_timeout'; return; } - return resp.json().then((json) => { - console.log(json); - if (json.ok) { - processCallback(json); - } else { - processionElem.className = 'procession_error'; - } - }); - }).catch(handleError); - }; + if (e.name == 'NotSupportedError') { + handleUnsupported(); + return; + } + if (e.name == 'InvalidStateError') { + processionElem.className = 'procession_invalid'; + return; + } + } + return; + } - let startRequest = () => { - processionElem.className = 'procession_wait'; - window.u2f.sign(appId, challenge, requests, cb); - }; - document.getElementById("retry_button").addEventListener("click", (e) => { - startRequest(); + processionElem.className = 'procession_contact'; + + const b64 = (buf) => btoa(String.fromCharCode(...new Uint8Array(buf))); + const payload = JSON.stringify({ + req_id: reqId, + credential_id: assertion.id, + authenticator_data: b64(assertion.response.authenticatorData), + client_data_json: b64(assertion.response.clientDataJSON), + signature: b64(assertion.response.signature), + user_handle: b64(assertion.response.userHandle), + extension_results: assertion.getClientExtensionResults(), }); - startRequest(); - }); + try { + const resp = await fetch(`/ui/verify/${authnId}`, {credentials: 'include', method: 'POST', body: payload}); + const json = await resp.json(); + console.log(json); + if (resp.ok) { + if (json.ok) { + processionElem.className = 'procession_ok'; + if (window.opener) { + window.close(); + } else { + setTimeout(() => window.close(), 2000); + } + } else { + processionElem.className = 'procession_error'; + } + } else { + if (resp.status == 401) { + processionElem.className = 'procession_invalid'; + } else { + processionElem.className = 'procession_error'; + } + } + } catch (e) { + document.getElementById("error_message").innerHTML = `Contact Error`; + console.log(e); + processionElem.className = 'procession_error'; + return; + } + } + document.getElementById("retry_button").addEventListener("click", (e) => { + startAssertionRequest(); + }); + return startAssertionRequest(); });