feat: initial commit

This commit is contained in:
2023-11-15 20:38:25 +01:00
commit e199fe3d26
67 changed files with 4152 additions and 0 deletions

3
public/css/style.css Normal file
View File

@ -0,0 +1,3 @@
body {
background-color: hsla(217, 15%, 95%, 1);
}

View File

@ -0,0 +1,91 @@
(function(HydraWebAuthn) {
HydraWebAuthn.base64ToArrayBuffer = function(base64) {
var binaryString = HydraWebAuthn.fromBase64URL(base64);
var bytes = new Uint8Array(binaryString.length);
for (var i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
HydraWebAuthn.arrayBufferToBase64 = function( buffer ) {
var binary = '';
var bytes = new Uint8Array( buffer );
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] );
}
return window.btoa( binary );
}
HydraWebAuthn.toJSONCredentials = function(credentials) {
return {
id: credentials.id,
rawId: HydraWebAuthn.toBase64URL(credentials.rawId),
authenticatorAttachment: credentials.authenticatorAttachment,
type: "public-key",
clientExtensionResults: (() => {
const results = credentials.getClientExtensionResults();
return Object.keys(results).reduce((json, key) => {
json[key] = HydraWebAuthn.urlsafe(HydraWebAuthn.arrayBufferToBase64(results[key]))
return json;
}, {})
})(),
response: {
attestationObject: HydraWebAuthn.urlsafe(HydraWebAuthn.arrayBufferToBase64(credentials.response.attestationObject)),
clientDataJSON: HydraWebAuthn.urlsafe(HydraWebAuthn.arrayBufferToBase64(credentials.response.clientDataJSON))
}
}
}
HydraWebAuthn.toJSONAssertion = function(assertion) {
return {
id: assertion.id,
rawId: HydraWebAuthn.urlsafe(HydraWebAuthn.arrayBufferToBase64(assertion.rawId)),
type: "public-key",
response: {
authenticatorData: HydraWebAuthn.urlsafe(HydraWebAuthn.arrayBufferToBase64(assertion.response.authenticatorData)),
clientDataJSON: HydraWebAuthn.urlsafe(HydraWebAuthn.arrayBufferToBase64(assertion.response.clientDataJSON)),
signature: HydraWebAuthn.urlsafe(HydraWebAuthn.arrayBufferToBase64(assertion.response.signature)),
userHandle: assertion.response.userHandle
}
}
}
HydraWebAuthn.base64 = function(str) {
return HydraWebAuthn.bytesToBase64(new TextEncoder().encode(str));
}
HydraWebAuthn.toBase64URL = function(str) {
return HydraWebAuthn.urlsafe(HydraWebAuthn.base64(str));
}
HydraWebAuthn.fromBase64URL = function(str) {
str = str
.replace(/-/g, '+')
.replace(/_/g, '/');
var pad = str.length % 4;
if(pad) {
if(pad === 1) {
throw new Error('InvalidLengthError: Input base64url string is the wrong length to determine padding');
}
str += new Array(5-pad).join('=');
}
return atob(str);
}
HydraWebAuthn.urlsafe = function(base64) {
return base64.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '')
}
HydraWebAuthn.bytesToBase64 = function(bytes) {
const binString = String.fromCodePoint(...bytes);
return btoa(binString);
}
}(window.HydraWebAuthn = {}))

20
public/js/login.js Normal file
View File

@ -0,0 +1,20 @@
const rawAssertionRequest = HydraWebAuthn.fromBase64URL(document.currentScript.dataset.assertionRequest);
const assertionRequest = JSON.parse(rawAssertionRequest);
assertionRequest.publicKey.challenge = HydraWebAuthn.base64ToArrayBuffer(assertionRequest.publicKey.challenge)
assertionRequest.publicKey.allowCredentials.forEach(credential => credential.id = HydraWebAuthn.base64ToArrayBuffer(credential.id))
console.log("Assertion request", assertionRequest)
navigator.credentials.get(assertionRequest)
.then(assertion => {
console.log("Assertion", assertion)
if (assertion) {
const jsonAssertion = JSON.stringify(HydraWebAuthn.toJSONAssertion(assertion), null, 2);
console.log(jsonAssertion);
document.getElementById("assertion").value = HydraWebAuthn.toBase64URL(jsonAssertion);
}
}).catch(err => {
console.error(err);
}).finally(() => {
document.getElementById("login").submit();
})

17
public/js/register.js Normal file
View File

@ -0,0 +1,17 @@
const rawWebAuthnOptions = HydraWebAuthn.fromBase64URL(document.currentScript.dataset.webAuthnOptions);
const webAuthnOptions = JSON.parse(rawWebAuthnOptions);
webAuthnOptions.publicKey.challenge = HydraWebAuthn.base64ToArrayBuffer(webAuthnOptions.publicKey.challenge);
webAuthnOptions.publicKey.user.id = HydraWebAuthn.base64ToArrayBuffer(webAuthnOptions.publicKey.user.id);
console.log(webAuthnOptions)
function generateCredentials() {
navigator.credentials.create(webAuthnOptions).then(credentials => {
if (!credentials) return;
const jsonCredentials = JSON.stringify(HydraWebAuthn.toJSONCredentials(credentials), null, 2);
console.log(jsonCredentials);
document.getElementById("credentials").value = HydraWebAuthn.toBase64URL(jsonCredentials);
document.getElementById("register").submit();
}).catch(err => console.error(err));
}