summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMatthew Miller <matthew@millerti.me>2021-07-08 22:01:45 -0700
committerGitHub <noreply@github.com>2021-07-08 22:01:45 -0700
commit3e1f9cf3d41f509a387d7cba3f44a7a93f90e07c (patch)
treed21b1c98b4e0d8a621a6d5ec385203e9253656d0
parentb883160cdaf6de9cc734cbbdcf65a8f14f662706 (diff)
parent5dd46a5324f43883914b0c7d168ba1f02bb56b51 (diff)
Merge pull request #135 from MasterKale/feat/example-debug-console
feat/example-debug-console
-rw-r--r--example/index.ts7
-rw-r--r--example/public/index.html32
-rw-r--r--example/public/styles.css53
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;
}
}