UNPKG

@payburner/payburner-payid-client-core

Version:
215 lines 10.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.VerifiedPayIDUtils = void 0; const jose = __importStar(require("node-jose")); const node_jose_1 = require("node-jose"); const UnsignedPayIDAddressImpl_1 = require("../model/impl/UnsignedPayIDAddressImpl"); const ResolvedPayID_1 = require("../model/impl/ResolvedPayID"); const VerificationResult_1 = require("../model/impl/VerificationResult"); const VerificationErrorCode_1 = require("../model/interfaces/VerificationErrorCode"); const AddressDetailsType_1 = require("../model/interfaces/AddressDetailsType"); const __1 = require(".."); const ResolvedCryptoAddressWithThumbprintResponse_1 = require("../model/impl/ResolvedCryptoAddressWithThumbprintResponse"); var base64url = node_jose_1.util.base64url; class VerifiedPayIDUtils { newKeyStore() { return jose.JWK.createKeyStore(); } newKey() { return this.newKeyStore().generate("EC", "P-256", { alg: "ES256", key_ops: ["sign", "verify"] }); } fromPEM(pem) { return jose.JWK.createKeyStore().add(pem, 'pem'); } signPayID(key, input) { const self = this; const promises = new Array(); input.addresses.forEach((address) => { const unsigned = new UnsignedPayIDAddressImpl_1.UnsignedPayIDAddressImpl(input.payId, address); promises.push(self.signPayIDAddress(key, unsigned)); }); return new Promise((resolve, reject) => { Promise.all(promises).then((values) => { resolve(new ResolvedPayID_1.ResolvedPayID(input.addresses, input.payId, input.memo, input.proofOfControlSignature, values)); }); }); } matchAddress(address, payloadAddress) { const parsedPayloadAddress = JSON.parse(Buffer.from(payloadAddress, 'base64').toString("ascii")); if (address.environment !== parsedPayloadAddress.payIdAddress.environment) { return false; } if (address.paymentNetwork !== parsedPayloadAddress.payIdAddress.paymentNetwork) { return false; } if (address.addressDetailsType !== parsedPayloadAddress.payIdAddress.addressDetailsType) { return false; } if (address.addressDetailsType === AddressDetailsType_1.AddressDetailsType.CryptoAddress) { const cryptoAddressDetails = address.addressDetails; const payloadAddressDetails = parsedPayloadAddress.payIdAddress.addressDetails; if (cryptoAddressDetails.address !== payloadAddressDetails.address) { return false; } if (cryptoAddressDetails.tag !== payloadAddressDetails.tag) { return false; } } return true; } getThumbprint(key) { return new Promise((resolve, reject) => { key.thumbprint('SHA-256').then((buff) => { resolve(base64url.encode(buff, 'base64')); }); }); } getResolvedCryptoAddressWithThumbprint(input, network, environment) { const self = this; return new Promise((resolve, reject) => { if (typeof input.verifiedAddresses === 'undefined' || input.verifiedAddresses === null || input.verifiedAddresses.length === 0) { resolve(new ResolvedCryptoAddressWithThumbprintResponse_1.ResolvedCryptoAddressWithThumbprintResponse()); } else { try { let count = 0; input.verifiedAddresses.forEach((verifiedAddress) => { const address = JSON.parse(verifiedAddress.payload).payIdAddress; if (address.environment === environment && address.paymentNetwork === network) { self.verifySignedPayIDAddress(verifiedAddress) .then((verificationResult) => { self.getThumbprint(verificationResult.key) .then((thumbprint) => { resolve(new ResolvedCryptoAddressWithThumbprintResponse_1.ResolvedCryptoAddressWithThumbprintResponse(new __1.ResolvedCryptoAddressWithThumbprint(network, environment, address, verificationResult.key, thumbprint, Buffer.from(thumbprint, 'utf8').toString('hex').toUpperCase(), self.thumbprintToHexMatrix(thumbprint)))); }); }); count++; } }); if (count === 0) { resolve(new ResolvedCryptoAddressWithThumbprintResponse_1.ResolvedCryptoAddressWithThumbprintResponse()); } } catch (error) { resolve(new ResolvedCryptoAddressWithThumbprintResponse_1.ResolvedCryptoAddressWithThumbprintResponse()); } } }); } thumbprintToHexMatrix(thumbprint) { const hexified = Buffer.from(thumbprint, 'utf8').toString('hex'); const chunked = hexified.match(/.{1,4}/g); if (chunked === null) { return new Array(); } const response = new Array(); for (let idx = 0; idx < chunked.length; idx++) { if (idx % 4 === 0) { response.push([]); } const chunk = chunked[idx]; response[response.length - 1].push(chunk.toUpperCase()); } return response; } verifyPayID(thumbprint, input) { const self = this; return new Promise((resolve, reject) => { if (typeof input.verifiedAddresses === 'undefined' || input.verifiedAddresses === null || input.verifiedAddresses.length === 0) { resolve(new VerificationResult_1.VerificationResult(true)); } else if (typeof thumbprint === 'undefined' || thumbprint === null) { resolve(new VerificationResult_1.VerificationResult(false, VerificationErrorCode_1.VerificationErrorCode.VERIFIED_ADDRESSES_BUT_NO_THUMBPRINT, 'The payID has verified addresses, but no thumbprint was provided')); } else { const promises = new Array(); input.verifiedAddresses.forEach((verifiedAddress) => { promises.push(self.verifySignedPayIDAddress(verifiedAddress)); }); Promise.all(promises).then((values) => { const thumbprintPromises = new Array(); values.forEach((verificationResult) => { console.log('Verification Result from Address:' + JSON.stringify(verificationResult)); thumbprintPromises.push(this.getThumbprint(verificationResult.key)); }); Promise.all(thumbprintPromises).then((thumbprintValues) => { let verifiedAllThumbprints = true; thumbprintValues.forEach((buffer) => { const buff = buffer; if (thumbprint !== buff) { console.log('Failed Thumbprint Verification. Calculated:' + buff + ', Provided:' + thumbprint); verifiedAllThumbprints = false; } }); if (!verifiedAllThumbprints) { resolve(new VerificationResult_1.VerificationResult(false, VerificationErrorCode_1.VerificationErrorCode.VERIFIED_ADDRESSES_KEYS_DO_NOT_MATCH_THUMBPRINT, 'The payID has verified addresses and the thumbprint does not match the embedded keys')); } else { resolve(new VerificationResult_1.VerificationResult(true)); } }); }).catch((error) => { console.log('ERROR:' + error); console.log('ERROR:' + JSON.stringify(error)); resolve(new VerificationResult_1.VerificationResult(false, VerificationErrorCode_1.VerificationErrorCode.SYSTEM_ERROR_VERIFYING, 'We encountered a system error verifying the addresses -- ' + (typeof error === 'string' ? error : JSON.stringify(error)))); }); } }); } verifySignedPayIDAddress(input) { console.log('Verifying payID Address:' + JSON.stringify(input, null, 2)); return jose.JWS.createVerify().verify(input, { allowEmbeddedKey: true, handlers: { name: true, b64: true } }); } signPayIDAddress(key, input) { const opts = { compact: false, fields: { name: 'identityKey', alg: 'ES256', typ: 'JOSE+JSON', crit: ['name'] }, handlers: { name: true } }; return new Promise((resolve, reject) => { jose.JWS.createSign(opts, { key, reference: 'jwk' }).update(JSON.stringify(input), "utf-8").final().then((signed) => { const unknownData = signed; resolve(unknownData); }).catch((error) => { reject(error); }); }); } } exports.VerifiedPayIDUtils = VerifiedPayIDUtils; //# sourceMappingURL=VerifiedPayIDUtils.js.map