misc syntactic & type-checking clean-up
This commit is contained in:
@@ -55,8 +55,8 @@ export function isoUint8ArrayConcat(arrays: Uint8Array[]): Uint8Array {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// from https://github.com/MasterKale/SimpleWebAuthn/blob/master/packages/server/src/helpers/iso/isoCrypto/getWebCrypto.ts
|
// from https://github.com/MasterKale/SimpleWebAuthn/blob/master/packages/server/src/helpers/iso/isoCrypto/getWebCrypto.ts
|
||||||
let webCrypto: unknown = undefined;
|
let webCrypto: { subtle: SubtleCrypto } | undefined = undefined;
|
||||||
export function getWebCrypto() {
|
export function getWebCrypto(): Promise<{ subtle: SubtleCrypto }> {
|
||||||
/**
|
/**
|
||||||
* Hello there! If you came here wondering why this method is asynchronous when use of
|
* Hello there! If you came here wondering why this method is asynchronous when use of
|
||||||
* `globalThis.crypto` is not, it's to minimize a bunch of refactor related to making this
|
* `globalThis.crypto` is not, it's to minimize a bunch of refactor related to making this
|
||||||
@@ -67,22 +67,25 @@ export function getWebCrypto() {
|
|||||||
* TODO: If it's after February 2025 when you read this then consider whether it still makes sense
|
* TODO: If it's after February 2025 when you read this then consider whether it still makes sense
|
||||||
* to keep this method asynchronous.
|
* to keep this method asynchronous.
|
||||||
*/
|
*/
|
||||||
const toResolve = new Promise((resolve, reject) => {
|
const toResolve: Promise<{ subtle: SubtleCrypto }> = new Promise(
|
||||||
if (webCrypto) {
|
(resolve, reject) => {
|
||||||
return resolve(webCrypto);
|
if (webCrypto) {
|
||||||
}
|
return resolve(webCrypto);
|
||||||
/**
|
}
|
||||||
* Naively attempt to access Crypto as a global object, which popular ESM-centric run-times
|
/**
|
||||||
* support (and Node v20+)
|
* Naively attempt to access Crypto as a global object, which popular ESM-centric run-times
|
||||||
*/
|
* support (and Node v20+)
|
||||||
const _globalThisCrypto = _getWebCryptoInternals.stubThisGlobalThisCrypto();
|
*/
|
||||||
if (_globalThisCrypto) {
|
const _globalThisCrypto =
|
||||||
webCrypto = _globalThisCrypto;
|
_getWebCryptoInternals.stubThisGlobalThisCrypto();
|
||||||
return resolve(webCrypto);
|
if (_globalThisCrypto) {
|
||||||
}
|
webCrypto = _globalThisCrypto;
|
||||||
// We tried to access it both in Node and globally, so bail out
|
return resolve(webCrypto);
|
||||||
return reject(new MissingWebCrypto());
|
}
|
||||||
});
|
// We tried to access it both in Node and globally, so bail out
|
||||||
|
return reject(new MissingWebCrypto());
|
||||||
|
},
|
||||||
|
);
|
||||||
return toResolve;
|
return toResolve;
|
||||||
}
|
}
|
||||||
export class MissingWebCrypto extends Error {
|
export class MissingWebCrypto extends Error {
|
||||||
@@ -96,7 +99,7 @@ export class MissingWebCrypto extends Error {
|
|||||||
export const _getWebCryptoInternals = {
|
export const _getWebCryptoInternals = {
|
||||||
stubThisGlobalThisCrypto: () => globalThis.crypto,
|
stubThisGlobalThisCrypto: () => globalThis.crypto,
|
||||||
// Make it possible to reset the `webCrypto` at the top of the file
|
// Make it possible to reset the `webCrypto` at the top of the file
|
||||||
setCachedCrypto: (newCrypto: unknown) => {
|
setCachedCrypto: (newCrypto: { subtle: SubtleCrypto }) => {
|
||||||
webCrypto = newCrypto;
|
webCrypto = newCrypto;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export async function registerCredential(passkeyName?: string) {
|
|||||||
|
|
||||||
const credIdBase64Url = verification.registrationInfo?.credentialID as string;
|
const credIdBase64Url = verification.registrationInfo?.credentialID as string;
|
||||||
if (attResp.rawId !== credIdBase64Url) {
|
if (attResp.rawId !== credIdBase64Url) {
|
||||||
console.log("Warning! The raw ID does not match the credential ID.")
|
console.log("Warning! The raw ID does not match the credential ID.");
|
||||||
}
|
}
|
||||||
const credIdHex = Buffer.from(
|
const credIdHex = Buffer.from(
|
||||||
base64URLStringToArrayBuffer(credIdBase64Url),
|
base64URLStringToArrayBuffer(credIdBase64Url),
|
||||||
@@ -237,8 +237,9 @@ export class PeerSetup {
|
|||||||
.replace(/\//g, "_")
|
.replace(/\//g, "_")
|
||||||
.replace(/=+$/, "");
|
.replace(/=+$/, "");
|
||||||
|
|
||||||
const origSignature = Buffer.from(credential?.response.signature)
|
const origSignature = Buffer.from(credential?.response.signature).toString(
|
||||||
.toString("base64")
|
"base64",
|
||||||
|
);
|
||||||
this.signature = origSignature
|
this.signature = origSignature
|
||||||
.replace(/\+/g, "-")
|
.replace(/\+/g, "-")
|
||||||
.replace(/\//g, "_")
|
.replace(/\//g, "_")
|
||||||
@@ -423,6 +424,7 @@ export async function verifyJwtWebCrypto(
|
|||||||
return verified;
|
return verified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
async function peerDidToDidDocument(did: string): Promise<DIDResolutionResult> {
|
async function peerDidToDidDocument(did: string): Promise<DIDResolutionResult> {
|
||||||
if (!did.startsWith("did:peer:0z")) {
|
if (!did.startsWith("did:peer:0z")) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@@ -463,12 +465,15 @@ async function peerDidToDidDocument(did: string): Promise<DIDResolutionResult> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// convert COSE public key to PEM format
|
// convert COSE public key to PEM format
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
function COSEtoPEM(cose: Buffer) {
|
function COSEtoPEM(cose: Buffer) {
|
||||||
// const alg = cose.get(3); // Algorithm
|
// const alg = cose.get(3); // Algorithm
|
||||||
const x = cose[-2]; // x-coordinate
|
const x = cose[-2]; // x-coordinate
|
||||||
const y = cose[-3]; // y-coordinate
|
const y = cose[-3]; // y-coordinate
|
||||||
|
|
||||||
// Ensure the coordinates are in the correct format
|
// Ensure the coordinates are in the correct format
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-expect-error because it complains about the type of x and y
|
||||||
const pubKeyBuffer = Buffer.concat([Buffer.from([0x04]), x, y]);
|
const pubKeyBuffer = Buffer.concat([Buffer.from([0x04]), x, y]);
|
||||||
|
|
||||||
// Convert to PEM format
|
// Convert to PEM format
|
||||||
@@ -479,6 +484,7 @@ ${pubKeyBuffer.toString("base64")}
|
|||||||
return pem;
|
return pem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
function base64urlDecode(input: string) {
|
function base64urlDecode(input: string) {
|
||||||
input = input.replace(/-/g, "+").replace(/_/g, "/");
|
input = input.replace(/-/g, "+").replace(/_/g, "/");
|
||||||
const pad = input.length % 4 === 0 ? "" : "====".slice(input.length % 4);
|
const pad = input.length % 4 === 0 ? "" : "====".slice(input.length % 4);
|
||||||
@@ -490,13 +496,14 @@ function base64urlDecode(input: string) {
|
|||||||
return bytes.buffer;
|
return bytes.buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
function base64urlEncode(buffer: ArrayBuffer) {
|
function base64urlEncode(buffer: ArrayBuffer) {
|
||||||
const str = String.fromCharCode(...new Uint8Array(buffer));
|
const str = String.fromCharCode(...new Uint8Array(buffer));
|
||||||
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// from @simplewebauthn/browser
|
// from @simplewebauthn/browser
|
||||||
function arrayBufferToBase64URLString(buffer) {
|
function arrayBufferToBase64URLString(buffer: ArrayBuffer) {
|
||||||
const bytes = new Uint8Array(buffer);
|
const bytes = new Uint8Array(buffer);
|
||||||
let str = "";
|
let str = "";
|
||||||
for (const charCode of bytes) {
|
for (const charCode of bytes) {
|
||||||
@@ -545,6 +552,7 @@ function cborToKeys(publicKeyBytes: Uint8Array) {
|
|||||||
return { publicKeyJwk, publicKeyBuffer };
|
return { publicKeyJwk, publicKeyBuffer };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
async function pemToCryptoKey(pem: string) {
|
async function pemToCryptoKey(pem: string) {
|
||||||
const binaryDerString = atob(
|
const binaryDerString = atob(
|
||||||
pem
|
pem
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p class="text-center text-xl mb-4 font-light">
|
<p class="text-center text-xl mb-4 font-light">
|
||||||
Will increment the maximum derivation path from the existing seed.
|
Will increment the maximum known derivation path from the existing seed.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p v-if="didArrays.length > 1">
|
<p v-if="didArrays.length > 1">
|
||||||
@@ -75,7 +75,7 @@ import {
|
|||||||
deriveAddress,
|
deriveAddress,
|
||||||
newIdentifier,
|
newIdentifier,
|
||||||
nextDerivationPath,
|
nextDerivationPath,
|
||||||
} from "../libs/crypto";
|
} from "@/libs/crypto";
|
||||||
import { accountsDB, db } from "@/db/index";
|
import { accountsDB, db } from "@/db/index";
|
||||||
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||||
|
|
||||||
|
|||||||
@@ -173,59 +173,65 @@
|
|||||||
<div class="mt-8">
|
<div class="mt-8">
|
||||||
<h2 class="text-xl font-bold mb-4">Passkeys</h2>
|
<h2 class="text-xl font-bold mb-4">Passkeys</h2>
|
||||||
See console for results.
|
See console for results.
|
||||||
<br/>
|
<br />
|
||||||
|
See existing passkeys in Chrome at: chrome://settings/passkeys
|
||||||
|
<br />
|
||||||
Active DID: {{ activeDid }}
|
Active DID: {{ activeDid }}
|
||||||
{{ credIdHex ? "has passkey ID" : "has no passkey ID" }}
|
{{ credIdHex ? "has passkey ID" : "has no passkey ID" }}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
Register
|
Register Passkey
|
||||||
<button
|
<button
|
||||||
@click="register()"
|
@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
|
Simplewebauthn
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
Create
|
Create JWT
|
||||||
<button
|
<button
|
||||||
@click="createJwtSimplewebauthn()"
|
@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
|
Simplewebauthn
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
@click="createJwtNavigator()"
|
@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
|
Navigator
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="jwt">
|
<div v-if="jwt">
|
||||||
Verify
|
Verify New JWT
|
||||||
<button
|
<button
|
||||||
@click="verifySimplewebauthn()"
|
@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
|
Simplewebauthn
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
@click="verifyWebCrypto()"
|
@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
|
WebCrypto
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
@click="verifyP256()"
|
@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
|
p256 - broken
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else>Verify New JWT -- requires creation first</div>
|
||||||
<button
|
<button
|
||||||
@click="verifyMyJwt()"
|
@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>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -335,7 +341,7 @@ export default class Help extends Vue {
|
|||||||
did: this.activeDid,
|
did: this.activeDid,
|
||||||
passkeyCredIdHex: this.credIdHex,
|
passkeyCredIdHex: this.credIdHex,
|
||||||
publicKeyHex: Buffer.from(publicKeyBytes).toString("hex"),
|
publicKeyHex: Buffer.from(publicKeyBytes).toString("hex"),
|
||||||
});``
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createJwtSimplewebauthn() {
|
public async createJwtSimplewebauthn() {
|
||||||
@@ -360,44 +366,46 @@ export default class Help extends Vue {
|
|||||||
|
|
||||||
public async verifyP256() {
|
public async verifyP256() {
|
||||||
const decoded = await verifyJwtP256(
|
const decoded = await verifyJwtP256(
|
||||||
this.credIdHex as Base64URLString,
|
this.credIdHex as string,
|
||||||
this.activeDid as string,
|
this.activeDid as string,
|
||||||
this.peerSetup.authenticatorData as ArrayBuffer,
|
this.peerSetup?.authenticatorData as ArrayBuffer,
|
||||||
this.peerSetup.challenge as Uint8Array,
|
this.peerSetup?.challenge as Uint8Array,
|
||||||
this.peerSetup.clientDataJsonBase64Url as Base64URLString,
|
this.peerSetup?.clientDataJsonBase64Url as Base64URLString,
|
||||||
this.peerSetup.signature as Base64URLString,
|
this.peerSetup?.signature as Base64URLString,
|
||||||
);
|
);
|
||||||
console.log("decoded", decoded);
|
console.log("decoded", decoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async verifySimplewebauthn() {
|
public async verifySimplewebauthn() {
|
||||||
const decoded = await verifyJwtSimplewebauthn(
|
const decoded = await verifyJwtSimplewebauthn(
|
||||||
this.credIdHex as Base64URLString,
|
this.credIdHex as string,
|
||||||
this.activeDid as string,
|
this.activeDid as string,
|
||||||
this.peerSetup.authenticatorData as ArrayBuffer,
|
this.peerSetup?.authenticatorData as ArrayBuffer,
|
||||||
this.peerSetup.challenge as Uint8Array,
|
this.peerSetup?.challenge as Uint8Array,
|
||||||
this.peerSetup.clientDataJsonBase64Url as Base64URLString,
|
this.peerSetup?.clientDataJsonBase64Url as Base64URLString,
|
||||||
this.peerSetup.signature as Base64URLString,
|
this.peerSetup?.signature as Base64URLString,
|
||||||
);
|
);
|
||||||
console.log("decoded", decoded);
|
console.log("decoded", decoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async verifyWebCrypto() {
|
public async verifyWebCrypto() {
|
||||||
const decoded = await verifyJwtWebCrypto(
|
const decoded = await verifyJwtWebCrypto(
|
||||||
this.credIdHex as Base64URLString,
|
this.credIdHex as string,
|
||||||
this.activeDid as string,
|
this.activeDid as string,
|
||||||
this.peerSetup.authenticatorData as ArrayBuffer,
|
this.peerSetup?.authenticatorData as ArrayBuffer,
|
||||||
this.peerSetup.challenge as Uint8Array,
|
this.peerSetup?.challenge as Uint8Array,
|
||||||
this.peerSetup.clientDataJsonBase64Url as Base64URLString,
|
this.peerSetup?.clientDataJsonBase64Url as Base64URLString,
|
||||||
this.peerSetup.signature as Base64URLString,
|
this.peerSetup?.signature as Base64URLString,
|
||||||
);
|
);
|
||||||
console.log("decoded", decoded);
|
console.log("decoded", decoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async verifyMyJwt() {
|
public async verifyMyJwt() {
|
||||||
|
const did =
|
||||||
|
"did:peer:0zKMFjvUgYrM1hXwDciYHiA9MxXtJPXnRLJvqoMNAKoDLX9pKMWLb3VDsgua1p2zW1xXRsjZSTNsfvMnNyMS7dB4k7NAhFwL3pXBrBXgyYJ9ri";
|
||||||
const jwt =
|
const jwt =
|
||||||
"eyJ0eXAiOiJKV0FOVCIsImFsZyI6IkVTMjU2In0.eyJBdXRoZW50aWNhdGlvbkRhdGFCNjRVUkwiOiJTWllONVlnT2pHaDBOQmNQWkhaZ1c0X2tycm1paGpMSG1Wenp1b01kbDJNRkFBQUFBQSIsIkNsaWVudERhdGFKU09OQjY0VVJMIjoiZXlKMGVYQmxJam9pZDJWaVlYVjBhRzR1WjJWMElpd2lZMmhoYkd4bGJtZGxJam9pWlhsS01sbDVTVFpsZVVwcVkyMVdhMXBYTlRCaFYwWnpWVE5XYVdGdFZtcGtRMGsyWlhsS1FWa3lPWFZrUjFZMFpFTkpOa2x0YURCa1NFSjZUMms0ZG1NeVRtOWFWekZvVEcwNWVWcDVTWE5KYTBJd1pWaENiRWxxYjJsU01td3lXbFZHYW1SSGJIWmlhVWx6U1cxU2JHTXlUbmxoV0VJd1lWYzVkVWxxYjJsalIydzJaVzFGYVdaWU1ITkpiV3hvWkVOSk5rMVVZM2hQUkZVMFRtcHJOVTFEZDJsaFdFNTZTV3B2YVZwSGJHdFBia0pzV2xoSk5rMUljRXhVVlZweFpHeFdibGRZU2s1TlYyaFpaREJTYW1GV2JFbGhWVVUxVkZob1dXUkZjRkZYUnpWVFZFVndNbU5YT1U1VWEwWk1ZakJTVFZkRWJIZFRNREZZVkVkSmVsWnJVbnBhTTFab1RWaEJlV1ZzWTNobFJtaFRZekp3WVZVeFVrOWpNbG95VkZjMVQyVlZNVlJPTWxKRFRrZHpNMVJyUm05U2JtUk5UVE5DV1ZGdVNrTlhSMlExVjFWdk5XTnRhMmxtVVNJc0ltOXlhV2RwYmlJNkltaDBkSEE2THk5c2IyTmhiR2h2YzNRNk9EQTRNQ0lzSW1OeWIzTnpUM0pwWjJsdUlqcG1ZV3h6WlgwIiwiaWF0IjoxNzE4NTg2OTkyLCJpc3MiOiJkaWQ6cGVlcjowektNRmp2VWdZck0xaFh3RGNpWUhpQTlNeFh0SlBYblJMSnZxb01OQUtvRExYOXBLTVdMYjNWRHNndWExcDJ6VzF4WFJzalpTVE5zZnZNbk55TVM3ZEI0azdOQWhGd0wzcFhCckJYZ3lZSjlyaSJ9.MEUCIQDJyCTbMPIFnuBoW3FYnlgtDEIHZ2OrkCEvqVnHU7kJDQIgVxjBjfW1TwQfcSOYwK8Z7AdCWGJlyxtLEsrnPif7caE";
|
"eyJ0eXAiOiJKV0FOVCIsImFsZyI6IkVTMjU2In0.eyJBdXRoZW50aWNhdGlvbkRhdGFCNjRVUkwiOiJTWllONVlnT2pHaDBOQmNQWkhaZ1c0X2tycm1paGpMSG1Wenp1b01kbDJNRkFBQUFBQSIsIkNsaWVudERhdGFKU09OQjY0VVJMIjoiZXlKMGVYQmxJam9pZDJWaVlYVjBhRzR1WjJWMElpd2lZMmhoYkd4bGJtZGxJam9pWlhsS01sbDVTVFpsZVVwcVkyMVdhMXBYTlRCaFYwWnpWVE5XYVdGdFZtcGtRMGsyWlhsS1FWa3lPWFZrUjFZMFpFTkpOa2x0YURCa1NFSjZUMms0ZG1NeVRtOWFWekZvVEcwNWVWcDVTWE5KYTBJd1pWaENiRWxxYjJsU01td3lXbFZHYW1SSGJIWmlhVWx6U1cxU2JHTXlUbmxoV0VJd1lWYzVkVWxxYjJsalIydzJaVzFGYVdaWU1ITkpiV3hvWkVOSk5rMVVZM2hQUkZVMFRtcHJOVTFEZDJsaFdFNTZTV3B2YVZwSGJHdFBia0pzV2xoSk5rMUljRXhVVlZweFpHeFdibGRZU2s1TlYyaFpaREJTYW1GV2JFbGhWVVUxVkZob1dXUkZjRkZYUnpWVFZFVndNbU5YT1U1VWEwWk1ZakJTVFZkRWJIZFRNREZZVkVkSmVsWnJVbnBhTTFab1RWaEJlV1ZzWTNobFJtaFRZekp3WVZVeFVrOWpNbG95VkZjMVQyVlZNVlJPTWxKRFRrZHpNMVJyUm05U2JtUk5UVE5DV1ZGdVNrTlhSMlExVjFWdk5XTnRhMmxtVVNJc0ltOXlhV2RwYmlJNkltaDBkSEE2THk5c2IyTmhiR2h2YzNRNk9EQTRNQ0lzSW1OeWIzTnpUM0pwWjJsdUlqcG1ZV3h6WlgwIiwiaWF0IjoxNzE4NTg2OTkyLCJpc3MiOiJkaWQ6cGVlcjowektNRmp2VWdZck0xaFh3RGNpWUhpQTlNeFh0SlBYblJMSnZxb01OQUtvRExYOXBLTVdMYjNWRHNndWExcDJ6VzF4WFJzalpTVE5zZnZNbk55TVM3ZEI0azdOQWhGd0wzcFhCckJYZ3lZSjlyaSJ9.MEUCIQDJyCTbMPIFnuBoW3FYnlgtDEIHZ2OrkCEvqVnHU7kJDQIgVxjBjfW1TwQfcSOYwK8Z7AdCWGJlyxtLEsrnPif7caE";
|
||||||
const pieces = jwt.split(".");
|
const pieces = jwt.split(".");
|
||||||
console.log("pieces", typeof pieces[1], pieces);
|
|
||||||
const payload = JSON.parse(Buffer.from(pieces[1], "base64").toString());
|
const payload = JSON.parse(Buffer.from(pieces[1], "base64").toString());
|
||||||
const authData = Buffer.from(payload["AuthenticationDataB64URL"], "base64");
|
const authData = Buffer.from(payload["AuthenticationDataB64URL"], "base64");
|
||||||
const clientJSON = Buffer.from(
|
const clientJSON = Buffer.from(
|
||||||
@@ -408,8 +416,8 @@ export default class Help extends Vue {
|
|||||||
const challenge = clientData.challenge;
|
const challenge = clientData.challenge;
|
||||||
const signatureB64URL = pieces[2];
|
const signatureB64URL = pieces[2];
|
||||||
const decoded = await verifyJwtWebCrypto(
|
const decoded = await verifyJwtWebCrypto(
|
||||||
this.credIdHex as Base64URLString,
|
this.credIdHex as string,
|
||||||
this.activeDid as string,
|
did,
|
||||||
authData,
|
authData,
|
||||||
challenge,
|
challenge,
|
||||||
payload["ClientDataJSONB64URL"],
|
payload["ClientDataJSONB64URL"],
|
||||||
|
|||||||
Reference in New Issue
Block a user