Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | 3x 3x 3x 3x 3x 3x 3x 3x | import { decodeToken, TokenInterface, TokenVerifier, publicKeyToStxAddress, } from 'micro-stacks/crypto'; /** * Verifies a profile token * @param {String} token - the token to be verified * @param {String} publicKeyOrAddress - the public key or address of the * keypair that is thought to have signed the token * @returns {Object} - the verified, decoded profile token * @throws {Error} - throws an error if token verification fails */ export function verifyProfileToken(token: string, publicKeyOrAddress: string): TokenInterface { const decodedToken = decodeToken(token); Iif (!decodedToken) throw Error('no decoded token'); const payload = decodedToken.payload; Iif (typeof payload === 'string') { throw new Error('Unexpected token payload type of string'); } // Inspect and verify the subject if (payload.hasOwnProperty('subject') && payload.subject) { Iif (!payload.subject.hasOwnProperty('publicKey')) { throw new Error("Token doesn't have a subject public key"); } } else { throw new Error("Token doesn't have a subject"); } // Inspect and verify the issuer if (payload.hasOwnProperty('issuer') && payload.issuer) { Iif (!payload.issuer.hasOwnProperty('publicKey')) { throw new Error("Token doesn't have an issuer public key"); } } else { throw new Error("Token doesn't have an issuer"); } // Inspect and verify the claim Iif (!payload.hasOwnProperty('claim')) { throw new Error("Token doesn't have a claim"); } const issuerPublicKey = (payload.issuer as Record<string, string>).publicKey; const address = publicKeyToStxAddress(issuerPublicKey); if (publicKeyOrAddress === issuerPublicKey) { // pass } else if (publicKeyOrAddress === address) { // pass } else { throw new Error('Token issuer public key does not match the verifying value'); } const tokenVerifier = new TokenVerifier(decodedToken.header.alg as string, issuerPublicKey); Iif (!tokenVerifier) { throw new Error('Invalid token verifier'); } const tokenVerified = tokenVerifier.verify(token); Iif (!tokenVerified) { throw new Error('Token verification failed'); } return decodedToken; } /** * Extracts a profile from an encoded token and optionally verifies it, * if `publicKeyOrAddress` is provided. * * @param {String} token - the token to be extracted * @param {String} publicKeyOrAddress - the public key or address of the * keypair that is thought to have signed the token * @returns {Object} - the profile extracted from the encoded token * @throws {Error} - if the token isn't signed by the provided `publicKeyOrAddress` */ export function extractProfile(token: string, publicKeyOrAddress?: string): Record<string, any> { const decodedToken = publicKeyOrAddress ? verifyProfileToken(token, publicKeyOrAddress) : decodeToken(token); if (decodedToken && decodedToken.hasOwnProperty('payload')) { const payload = decodedToken.payload; Iif (typeof payload === 'string') throw new Error('[micro-stacks] extractProfile: Unexpected token payload type of string'); if (payload.hasOwnProperty('claim')) return payload.claim as object; } return {}; } |