jsonld-signatures-merkleproof2019
Version:
A jsonld signature implementation to support MerkleProof2019 verification in Verifiable Credential context
94 lines (93 loc) • 4.77 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getUnmappedFields = getUnmappedFields;
exports.default = computeLocalHash;
const jsonld_1 = __importDefault(require("jsonld"));
const sha256_1 = __importDefault(require("sha256"));
const preloadedContexts_1 = __importDefault(require("../constants/contexts/preloadedContexts"));
const data_1 = require("../utils/data");
const object_1 = require("../utils/object");
const VerifierError_1 = __importDefault(require("../models/VerifierError"));
const getText_1 = __importDefault(require("../helpers/getText"));
function getUnmappedFields(normalized) {
const normalizedArray = normalized.split('\n');
const myRegexp = /<http:\/\/fallback\.org\/(.*)>/;
const matches = normalizedArray
.map(normalizedString => myRegexp.exec(normalizedString))
.filter(match => match != null);
if (matches.length > 0) {
const unmappedFields = matches.map(match => match[1]).sort(); // only return name of unmapped key
return Array.from(new Set(unmappedFields)); // dedup
}
return null;
}
function computeLocalHash(document_1) {
return __awaiter(this, arguments, void 0, function* (document, targetProof = null, documentLoader = (url) => __awaiter(this, void 0, void 0, function* () { return Promise; })) {
// the previous implementation was using a reference of @context, thus always adding @vocab to @context,
// thus passing the information down to jsonld regardless of the configuration option. We explicitly do that now,
// since we want to make sure unmapped fields are detected.
if (!document['@context'].find((context) => (0, object_1.isObject)(context) && '@vocab' in context)) {
document['@context'].push({ '@vocab': 'http://fallback.org/' });
}
const theDocument = JSON.parse(JSON.stringify(document));
if (!Array.isArray(theDocument.proof)) {
// compute the document as it was signed, so without proof
delete theDocument.proof;
}
else {
if (!targetProof) {
throw new VerifierError_1.default('computeLocalHash', (0, getText_1.default)('errors', 'noProofSpecified'));
}
const proofIndex = theDocument.proof.findIndex(proof => proof.proofValue === targetProof.proofValue);
theDocument.proof = theDocument.proof.slice(0, proofIndex);
}
const customLoader = function (url) {
return __awaiter(this, void 0, void 0, function* () {
if (documentLoader != null) {
yield documentLoader(url);
}
if (url in preloadedContexts_1.default) {
return {
contextUrl: null,
document: preloadedContexts_1.default[url],
documentUrl: url
};
}
return jsonld_1.default.documentLoader(url);
});
};
const normalizeArgs = {
algorithm: 'URDNA2015',
format: 'application/nquads',
documentLoader: customLoader,
safe: false
};
let normalizedDocument;
try {
normalizedDocument = yield jsonld_1.default.normalize(theDocument, normalizeArgs);
}
catch (e) {
console.error(e);
throw new VerifierError_1.default('computeLocalHash', (0, getText_1.default)('errors', 'failedJsonLdNormalization'));
}
const unmappedFields = getUnmappedFields(normalizedDocument);
if (unmappedFields) {
throw new VerifierError_1.default('computeLocalHash', `${(0, getText_1.default)('errors', 'foundUnmappedFields')}: ${unmappedFields.join(', ')}`);
}
else {
return (0, sha256_1.default)((0, data_1.toUTF8Data)(normalizedDocument));
}
});
}