|  |  | @ -173,59 +173,65 @@ | 
			
		
	
		
			
				
					|  |  |  |     <div class="mt-8"> | 
			
		
	
		
			
				
					|  |  |  |       <h2 class="text-xl font-bold mb-4">Passkeys</h2> | 
			
		
	
		
			
				
					|  |  |  |       See console for results. | 
			
		
	
		
			
				
					|  |  |  |       <br/> | 
			
		
	
		
			
				
					|  |  |  |       <br /> | 
			
		
	
		
			
				
					|  |  |  |       See existing passkeys in Chrome at: chrome://settings/passkeys | 
			
		
	
		
			
				
					|  |  |  |       <br /> | 
			
		
	
		
			
				
					|  |  |  |       Active DID: {{ activeDid }} | 
			
		
	
		
			
				
					|  |  |  |       {{ credIdHex ? "has passkey ID" : "has no passkey ID" }} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |       <div> | 
			
		
	
		
			
				
					|  |  |  |         Register | 
			
		
	
		
			
				
					|  |  |  |         Register Passkey | 
			
		
	
		
			
				
					|  |  |  |         <button | 
			
		
	
		
			
				
					|  |  |  |           @click="register()" | 
			
		
	
		
			
				
					|  |  |  |           class="font-bold uppercase bg-slate-600 text-white px-3 py-2 rounded-md mr-2" | 
			
		
	
		
			
				
					|  |  |  |           class="font-bold uppercase bg-slate-500 text-white px-3 py-2 rounded-md mr-2" | 
			
		
	
		
			
				
					|  |  |  |         > | 
			
		
	
		
			
				
					|  |  |  |           Simplewebauthn | 
			
		
	
		
			
				
					|  |  |  |         </button> | 
			
		
	
		
			
				
					|  |  |  |       </div> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |       <div> | 
			
		
	
		
			
				
					|  |  |  |         Create | 
			
		
	
		
			
				
					|  |  |  |         Create JWT | 
			
		
	
		
			
				
					|  |  |  |         <button | 
			
		
	
		
			
				
					|  |  |  |           @click="createJwtSimplewebauthn()" | 
			
		
	
		
			
				
					|  |  |  |           class="font-bold uppercase bg-slate-600 text-white px-3 py-2 rounded-md mr-2" | 
			
		
	
		
			
				
					|  |  |  |           class="font-bold uppercase bg-slate-500 text-white px-3 py-2 rounded-md mr-2" | 
			
		
	
		
			
				
					|  |  |  |         > | 
			
		
	
		
			
				
					|  |  |  |           Simplewebauthn | 
			
		
	
		
			
				
					|  |  |  |         </button> | 
			
		
	
		
			
				
					|  |  |  |         <button | 
			
		
	
		
			
				
					|  |  |  |           @click="createJwtNavigator()" | 
			
		
	
		
			
				
					|  |  |  |           class="font-bold uppercase bg-slate-600 text-white px-3 py-2 rounded-md mr-2" | 
			
		
	
		
			
				
					|  |  |  |           class="font-bold uppercase bg-slate-500 text-white px-3 py-2 rounded-md mr-2" | 
			
		
	
		
			
				
					|  |  |  |         > | 
			
		
	
		
			
				
					|  |  |  |           Navigator | 
			
		
	
		
			
				
					|  |  |  |         </button> | 
			
		
	
		
			
				
					|  |  |  |       </div> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |       <div v-if="jwt"> | 
			
		
	
		
			
				
					|  |  |  |         Verify | 
			
		
	
		
			
				
					|  |  |  |         Verify New JWT | 
			
		
	
		
			
				
					|  |  |  |         <button | 
			
		
	
		
			
				
					|  |  |  |           @click="verifySimplewebauthn()" | 
			
		
	
		
			
				
					|  |  |  |           class="font-bold uppercase bg-slate-600 text-white px-3 py-2 rounded-md mr-2" | 
			
		
	
		
			
				
					|  |  |  |           class="font-bold uppercase bg-slate-500 text-white px-3 py-2 rounded-md mr-2" | 
			
		
	
		
			
				
					|  |  |  |         > | 
			
		
	
		
			
				
					|  |  |  |           Simplewebauthn | 
			
		
	
		
			
				
					|  |  |  |         </button> | 
			
		
	
		
			
				
					|  |  |  |         <button | 
			
		
	
		
			
				
					|  |  |  |           @click="verifyWebCrypto()" | 
			
		
	
		
			
				
					|  |  |  |           class="font-bold uppercase bg-slate-600 text-white px-3 py-2 rounded-md mr-2" | 
			
		
	
		
			
				
					|  |  |  |           class="font-bold uppercase bg-slate-500 text-white px-3 py-2 rounded-md mr-2" | 
			
		
	
		
			
				
					|  |  |  |         > | 
			
		
	
		
			
				
					|  |  |  |           WebCrypto | 
			
		
	
		
			
				
					|  |  |  |         </button> | 
			
		
	
		
			
				
					|  |  |  |         <button | 
			
		
	
		
			
				
					|  |  |  |           @click="verifyP256()" | 
			
		
	
		
			
				
					|  |  |  |           class="font-bold uppercase bg-slate-600 text-white px-3 py-2 rounded-md mr-2" | 
			
		
	
		
			
				
					|  |  |  |           class="font-bold uppercase bg-slate-500 text-white px-3 py-2 rounded-md mr-2" | 
			
		
	
		
			
				
					|  |  |  |         > | 
			
		
	
		
			
				
					|  |  |  |           p256 - broken | 
			
		
	
		
			
				
					|  |  |  |         </button> | 
			
		
	
		
			
				
					|  |  |  |       </div> | 
			
		
	
		
			
				
					|  |  |  |       <div v-else>Verify New JWT -- requires creation first</div> | 
			
		
	
		
			
				
					|  |  |  |       <button | 
			
		
	
		
			
				
					|  |  |  |         @click="verifyMyJwt()" | 
			
		
	
		
			
				
					|  |  |  |         class="font-bold uppercase bg-slate-600 text-white px-3 py-2 rounded-md mr-2" | 
			
		
	
		
			
				
					|  |  |  |         class="font-bold uppercase bg-slate-500 text-white px-3 py-2 rounded-md mr-2" | 
			
		
	
		
			
				
					|  |  |  |       > | 
			
		
	
		
			
				
					|  |  |  |         Verify Mine | 
			
		
	
		
			
				
					|  |  |  |         Verify Hard-Coded JWT | 
			
		
	
		
			
				
					|  |  |  |       </button> | 
			
		
	
		
			
				
					|  |  |  |     </div> | 
			
		
	
		
			
				
					|  |  |  |   </section> | 
			
		
	
	
		
			
				
					|  |  | @ -335,7 +341,7 @@ export default class Help extends Vue { | 
			
		
	
		
			
				
					|  |  |  |       did: this.activeDid, | 
			
		
	
		
			
				
					|  |  |  |       passkeyCredIdHex: this.credIdHex, | 
			
		
	
		
			
				
					|  |  |  |       publicKeyHex: Buffer.from(publicKeyBytes).toString("hex"), | 
			
		
	
		
			
				
					|  |  |  |     });`` | 
			
		
	
		
			
				
					|  |  |  |     }); | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   public async createJwtSimplewebauthn() { | 
			
		
	
	
		
			
				
					|  |  | @ -360,44 +366,46 @@ export default class Help extends Vue { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   public async verifyP256() { | 
			
		
	
		
			
				
					|  |  |  |     const decoded = await verifyJwtP256( | 
			
		
	
		
			
				
					|  |  |  |       this.credIdHex as Base64URLString, | 
			
		
	
		
			
				
					|  |  |  |       this.credIdHex as string, | 
			
		
	
		
			
				
					|  |  |  |       this.activeDid as string, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup.authenticatorData as ArrayBuffer, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup.challenge as Uint8Array, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup.clientDataJsonBase64Url as Base64URLString, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup.signature as Base64URLString, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup?.authenticatorData as ArrayBuffer, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup?.challenge as Uint8Array, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup?.clientDataJsonBase64Url as Base64URLString, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup?.signature as Base64URLString, | 
			
		
	
		
			
				
					|  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |     console.log("decoded", decoded); | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   public async verifySimplewebauthn() { | 
			
		
	
		
			
				
					|  |  |  |     const decoded = await verifyJwtSimplewebauthn( | 
			
		
	
		
			
				
					|  |  |  |       this.credIdHex as Base64URLString, | 
			
		
	
		
			
				
					|  |  |  |       this.credIdHex as string, | 
			
		
	
		
			
				
					|  |  |  |       this.activeDid as string, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup.authenticatorData as ArrayBuffer, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup.challenge as Uint8Array, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup.clientDataJsonBase64Url as Base64URLString, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup.signature as Base64URLString, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup?.authenticatorData as ArrayBuffer, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup?.challenge as Uint8Array, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup?.clientDataJsonBase64Url as Base64URLString, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup?.signature as Base64URLString, | 
			
		
	
		
			
				
					|  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |     console.log("decoded", decoded); | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   public async verifyWebCrypto() { | 
			
		
	
		
			
				
					|  |  |  |     const decoded = await verifyJwtWebCrypto( | 
			
		
	
		
			
				
					|  |  |  |       this.credIdHex as Base64URLString, | 
			
		
	
		
			
				
					|  |  |  |       this.credIdHex as string, | 
			
		
	
		
			
				
					|  |  |  |       this.activeDid as string, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup.authenticatorData as ArrayBuffer, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup.challenge as Uint8Array, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup.clientDataJsonBase64Url as Base64URLString, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup.signature as Base64URLString, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup?.authenticatorData as ArrayBuffer, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup?.challenge as Uint8Array, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup?.clientDataJsonBase64Url as Base64URLString, | 
			
		
	
		
			
				
					|  |  |  |       this.peerSetup?.signature as Base64URLString, | 
			
		
	
		
			
				
					|  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |     console.log("decoded", decoded); | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   public async verifyMyJwt() { | 
			
		
	
		
			
				
					|  |  |  |     const did = | 
			
		
	
		
			
				
					|  |  |  |       "did:peer:0zKMFjvUgYrM1hXwDciYHiA9MxXtJPXnRLJvqoMNAKoDLX9pKMWLb3VDsgua1p2zW1xXRsjZSTNsfvMnNyMS7dB4k7NAhFwL3pXBrBXgyYJ9ri"; | 
			
		
	
		
			
				
					|  |  |  |     const jwt = | 
			
		
	
		
			
				
					|  |  |  |       "eyJ0eXAiOiJKV0FOVCIsImFsZyI6IkVTMjU2In0.eyJBdXRoZW50aWNhdGlvbkRhdGFCNjRVUkwiOiJTWllONVlnT2pHaDBOQmNQWkhaZ1c0X2tycm1paGpMSG1Wenp1b01kbDJNRkFBQUFBQSIsIkNsaWVudERhdGFKU09OQjY0VVJMIjoiZXlKMGVYQmxJam9pZDJWaVlYVjBhRzR1WjJWMElpd2lZMmhoYkd4bGJtZGxJam9pWlhsS01sbDVTVFpsZVVwcVkyMVdhMXBYTlRCaFYwWnpWVE5XYVdGdFZtcGtRMGsyWlhsS1FWa3lPWFZrUjFZMFpFTkpOa2x0YURCa1NFSjZUMms0ZG1NeVRtOWFWekZvVEcwNWVWcDVTWE5KYTBJd1pWaENiRWxxYjJsU01td3lXbFZHYW1SSGJIWmlhVWx6U1cxU2JHTXlUbmxoV0VJd1lWYzVkVWxxYjJsalIydzJaVzFGYVdaWU1ITkpiV3hvWkVOSk5rMVVZM2hQUkZVMFRtcHJOVTFEZDJsaFdFNTZTV3B2YVZwSGJHdFBia0pzV2xoSk5rMUljRXhVVlZweFpHeFdibGRZU2s1TlYyaFpaREJTYW1GV2JFbGhWVVUxVkZob1dXUkZjRkZYUnpWVFZFVndNbU5YT1U1VWEwWk1ZakJTVFZkRWJIZFRNREZZVkVkSmVsWnJVbnBhTTFab1RWaEJlV1ZzWTNobFJtaFRZekp3WVZVeFVrOWpNbG95VkZjMVQyVlZNVlJPTWxKRFRrZHpNMVJyUm05U2JtUk5UVE5DV1ZGdVNrTlhSMlExVjFWdk5XTnRhMmxtVVNJc0ltOXlhV2RwYmlJNkltaDBkSEE2THk5c2IyTmhiR2h2YzNRNk9EQTRNQ0lzSW1OeWIzTnpUM0pwWjJsdUlqcG1ZV3h6WlgwIiwiaWF0IjoxNzE4NTg2OTkyLCJpc3MiOiJkaWQ6cGVlcjowektNRmp2VWdZck0xaFh3RGNpWUhpQTlNeFh0SlBYblJMSnZxb01OQUtvRExYOXBLTVdMYjNWRHNndWExcDJ6VzF4WFJzalpTVE5zZnZNbk55TVM3ZEI0azdOQWhGd0wzcFhCckJYZ3lZSjlyaSJ9.MEUCIQDJyCTbMPIFnuBoW3FYnlgtDEIHZ2OrkCEvqVnHU7kJDQIgVxjBjfW1TwQfcSOYwK8Z7AdCWGJlyxtLEsrnPif7caE"; | 
			
		
	
		
			
				
					|  |  |  |     const pieces = jwt.split("."); | 
			
		
	
		
			
				
					|  |  |  |     console.log("pieces", typeof pieces[1], pieces); | 
			
		
	
		
			
				
					|  |  |  |     const payload = JSON.parse(Buffer.from(pieces[1], "base64").toString()); | 
			
		
	
		
			
				
					|  |  |  |     const authData = Buffer.from(payload["AuthenticationDataB64URL"], "base64"); | 
			
		
	
		
			
				
					|  |  |  |     const clientJSON = Buffer.from( | 
			
		
	
	
		
			
				
					|  |  | @ -408,8 +416,8 @@ export default class Help extends Vue { | 
			
		
	
		
			
				
					|  |  |  |     const challenge = clientData.challenge; | 
			
		
	
		
			
				
					|  |  |  |     const signatureB64URL = pieces[2]; | 
			
		
	
		
			
				
					|  |  |  |     const decoded = await verifyJwtWebCrypto( | 
			
		
	
		
			
				
					|  |  |  |       this.credIdHex as Base64URLString, | 
			
		
	
		
			
				
					|  |  |  |       this.activeDid as string, | 
			
		
	
		
			
				
					|  |  |  |       this.credIdHex as string, | 
			
		
	
		
			
				
					|  |  |  |       did, | 
			
		
	
		
			
				
					|  |  |  |       authData, | 
			
		
	
		
			
				
					|  |  |  |       challenge, | 
			
		
	
		
			
				
					|  |  |  |       payload["ClientDataJSONB64URL"], | 
			
		
	
	
		
			
				
					|  |  | 
 |