@payburner/payburner-payid-client-core
Version:
Models library for Core Payburner
215 lines • 10.4 kB
JavaScript
;
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