diff options
-rw-r--r-- | example/index.ts | 7 | ||||
-rw-r--r-- | example/public/index.html | 32 | ||||
-rw-r--r-- | example/public/styles.css | 53 |
3 files changed, 84 insertions, 8 deletions
diff --git a/example/index.ts b/example/index.ts index 5c24880..6609fdb 100644 --- a/example/index.ts +++ b/example/index.ts @@ -133,6 +133,10 @@ app.get('/generate-attestation-options', (req, res) => { userVerification: 'preferred', requireResidentKey: false, }, + /** + * Support the two most common algorithms: ES256, and RS256 + */ + supportedAlgorithmIDs: [-7, -257], }; const options = generateAttestationOptions(opts); @@ -182,6 +186,7 @@ app.post('/verify-attestation', async (req, res) => { credentialPublicKey, credentialID, counter, + transports: body.transports, }; user.devices.push(newDevice); } @@ -202,7 +207,7 @@ app.get('/generate-assertion-options', (req, res) => { allowCredentials: user.devices.map(dev => ({ id: dev.credentialID, type: 'public-key', - transports: ['usb', 'ble', 'nfc', 'internal'], + transports: dev.transports ?? ['usb', 'ble', 'nfc', 'internal'], })), /** * This optional value controls whether or not the authenticator needs be able to uniquely diff --git a/example/public/index.html b/example/public/index.html index 442ad13..8e6b46a 100644 --- a/example/public/index.html +++ b/example/public/index.html @@ -18,6 +18,10 @@ </button> <p id="regSuccess" class="success"></p> <p id="regError" class="error"></p> + <details open> + <summary>Console</summary> + <textarea id="regDebug" spellcheck="false"></textarea> + </details> </section> <section id="authentication"> @@ -26,6 +30,10 @@ </button> <p id="authSuccess" class="success"></p> <p id="authError" class="error"></p> + <details open> + <summary>Console</summary> + <textarea id="authDebug" spellcheck="false"></textarea> + </details> </section> </div> @@ -34,6 +42,17 @@ <script> const { supportsWebauthn, startAttestation, startAssertion } = SimpleWebAuthnBrowser; + /** + * A simple way to control how debug content is written to a debug console element + */ + function printDebug(elemDebug, title, output) { + if (elemDebug.innerHTML !== '') { + elemDebug.innerHTML += '\n'; + } + elemDebug.innerHTML += `// ${title}\n`; + elemDebug.innerHTML += `${output}\n`; + } + // Hide the Begin button if the browser is incapable of using WebAuthn if (!supportsWebauthn()) { document.querySelector('.controls').style.display = 'none'; @@ -46,16 +65,21 @@ document.querySelector('#btnRegBegin').addEventListener('click', async () => { const elemSuccess = document.querySelector('#regSuccess'); const elemError = document.querySelector('#regError'); + const elemDebug = document.querySelector('#regDebug'); // Reset success/error messages elemSuccess.innerHTML = ''; elemError.innerHTML = ''; + elemDebug.innerHTML = ''; const resp = await fetch('/generate-attestation-options'); let attResp; try { - attResp = await startAttestation(await resp.json()); + const opts = await resp.json(); + printDebug(elemDebug, 'Registration Options', JSON.stringify(opts, null, 2)); + attResp = await startAttestation(opts); + printDebug(elemDebug, 'Registration Response', JSON.stringify(attResp, null, 2)); } catch (error) { if (error.name === 'InvalidStateError') { elemError.innerText = 'Error: Authenticator was probably already registered by user'; @@ -75,6 +99,7 @@ }); const verificationJSON = await verificationResp.json(); + printDebug(elemDebug, 'Server Response', JSON.stringify(verificationJSON, null, 2)); if (verificationJSON && verificationJSON.verified) { elemSuccess.innerHTML = `Authenticator registered!`; @@ -91,17 +116,21 @@ document.querySelector('#btnAuthBegin').addEventListener('click', async () => { const elemSuccess = document.querySelector('#authSuccess'); const elemError = document.querySelector('#authError'); + const elemDebug = document.querySelector('#authDebug'); // Reset success/error messages elemSuccess.innerHTML = ''; elemError.innerHTML = ''; + elemDebug.innerHTML = ''; const resp = await fetch('/generate-assertion-options'); let asseResp; try { const opts = await resp.json(); + printDebug(elemDebug, 'Authentication Options', JSON.stringify(opts, null, 2)); asseResp = await startAssertion(opts); + printDebug(elemDebug, 'Authentication Response', JSON.stringify(asseResp, null, 2)); } catch (error) { elemError.innerText = error; throw new Error(error); @@ -116,6 +145,7 @@ }); const verificationJSON = await verificationResp.json(); + printDebug(elemDebug, 'Server Response', JSON.stringify(verificationJSON, null, 2)); if (verificationJSON && verificationJSON.verified) { elemSuccess.innerHTML = `User authenticated!`; diff --git a/example/public/styles.css b/example/public/styles.css index cbaa811..684cad5 100644 --- a/example/public/styles.css +++ b/example/public/styles.css @@ -1,3 +1,11 @@ +:root { + --background: #f7f7f7; + --text: black; + --button: white; + --button-active: #eeeeee; + --button-hover: #efefef; +} + * { font-size: 16px; font-family: 'Courier New', Courier, monospace; @@ -10,7 +18,8 @@ body { justify-content: center; align-items: center; height: 100vh; - background: #f7f7f7; + background: var(--background); + color: var(--text); } h1 { @@ -19,23 +28,29 @@ h1 { button { padding: 0.5rem; - background: white; + background: var(--button); + color: var(--text); border-radius: 0.25rem; width: 13rem; } button:active { - background: #eeeeee; + background: var(--button-active); } button:hover { - background: #efefef; + background: var(--button-hover); +} + +details { + margin: 0.75rem 0; } .container { - max-width: 70rem; + width: 95%; margin: auto; text-align: center; + padding: 0.5rem; } .error { @@ -46,9 +61,35 @@ button:hover { color: #11a000; } +#regDebug, #authDebug { + background: var(--button-hover); + color: var(--text); + border-radius: 0.25rem; + text-align: left; + font-size: 0.7rem; + padding: 0.5rem; + height: 15rem; + width: 95%; + overflow-y: auto; +} + /* Desktop Styles */ @media (min-width: 75rem) { * { - font-size: 24px; + font-size: 20px; + } + + .container { + width: 45rem; + } +} + +@media (prefers-color-scheme: dark) { + :root { + --background: #1c2128; + --text: #adbac7; + --button: #373e47; + --button-active: #eeeeee; + --button-hover: #444c56; } } |