did-jwt-vc
Advanced tools
Comparing version 1.0.3 to 1.0.4
@@ -0,1 +1,8 @@ | ||
## [1.0.4](https://github.com/decentralized-identity/did-jwt-vc/compare/1.0.3...1.0.4) (2020-07-20) | ||
### Bug Fixes | ||
* **build:** use commonjs module format ([#46](https://github.com/decentralized-identity/did-jwt-vc/issues/46)) ([76e503b](https://github.com/decentralized-identity/did-jwt-vc/commit/76e503bc4307d313681a245665250932c98bcd64)), closes [#47](https://github.com/decentralized-identity/did-jwt-vc/issues/47) | ||
## [1.0.3](https://github.com/decentralized-identity/did-jwt-vc/compare/1.0.2...1.0.3) (2020-07-02) | ||
@@ -2,0 +9,0 @@ |
@@ -1,21 +0,11 @@ | ||
(function (factory) { | ||
if (typeof module === "object" && typeof module.exports === "object") { | ||
var v = factory(require, exports); | ||
if (v !== undefined) module.exports = v; | ||
} | ||
else if (typeof define === "function" && define.amd) { | ||
define(["require", "exports"], factory); | ||
} | ||
})(function (require, exports) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.DEFAULT_JWT_PROOF_TYPE = exports.DEFAULT_VP_TYPE = exports.DEFAULT_VC_TYPE = exports.DEFAULT_CONTEXT = exports.JWT_FORMAT = exports.DID_FORMAT = exports.JWT_ALG = void 0; | ||
exports.JWT_ALG = 'ES256K'; | ||
exports.DID_FORMAT = /^did:([a-zA-Z0-9_]+):([:[a-zA-Z0-9_.-]+)(\/[^#]*)?(#.*)?$/; | ||
exports.JWT_FORMAT = /^[A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.?[A-Za-z0-9-_.+/=]*$/; | ||
exports.DEFAULT_CONTEXT = 'https://www.w3.org/2018/credentials/v1'; | ||
exports.DEFAULT_VC_TYPE = 'VerifiableCredential'; | ||
exports.DEFAULT_VP_TYPE = 'VerifiablePresentation'; | ||
exports.DEFAULT_JWT_PROOF_TYPE = 'JwtProof2020'; | ||
}); | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.DEFAULT_JWT_PROOF_TYPE = exports.DEFAULT_VP_TYPE = exports.DEFAULT_VC_TYPE = exports.DEFAULT_CONTEXT = exports.JWT_FORMAT = exports.DID_FORMAT = exports.JWT_ALG = void 0; | ||
exports.JWT_ALG = 'ES256K'; | ||
exports.DID_FORMAT = /^did:([a-zA-Z0-9_]+):([:[a-zA-Z0-9_.-]+)(\/[^#]*)?(#.*)?$/; | ||
exports.JWT_FORMAT = /^[A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.?[A-Za-z0-9-_.+/=]*$/; | ||
exports.DEFAULT_CONTEXT = 'https://www.w3.org/2018/credentials/v1'; | ||
exports.DEFAULT_VC_TYPE = 'VerifiableCredential'; | ||
exports.DEFAULT_VP_TYPE = 'VerifiablePresentation'; | ||
exports.DEFAULT_JWT_PROOF_TYPE = 'JwtProof2020'; | ||
//# sourceMappingURL=constants.js.map |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
var __assign = (this && this.__assign) || function () { | ||
@@ -54,395 +55,384 @@ __assign = Object.assign || function(t) { | ||
}; | ||
(function (factory) { | ||
if (typeof module === "object" && typeof module.exports === "object") { | ||
var v = factory(require, exports); | ||
if (v !== undefined) module.exports = v; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.transformPresentationInput = exports.normalizePresentation = exports.transformCredentialInput = exports.normalizeCredential = exports.attestationToVcFormat = exports.isLegacyAttestationFormat = exports.asArray = void 0; | ||
var did_jwt_1 = require("did-jwt"); | ||
var constants_1 = require("./constants"); | ||
function asArray(input) { | ||
return Array.isArray(input) ? input : [input]; | ||
} | ||
exports.asArray = asArray; | ||
function deepCopy(obj) { | ||
var e_1, _a; | ||
var copy; | ||
// Handle the 3 simple types, and null or undefined | ||
if (null === obj || 'object' !== typeof obj) | ||
return obj; | ||
// Handle Date | ||
if (obj instanceof Date) { | ||
copy = new Date(); | ||
copy.setTime(obj.getTime()); | ||
return copy; | ||
} | ||
else if (typeof define === "function" && define.amd) { | ||
define(["require", "exports", "did-jwt", "./constants"], factory); | ||
// Handle Array | ||
if (obj instanceof Array) { | ||
copy = obj.map(deepCopy); | ||
return copy; | ||
} | ||
})(function (require, exports) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.transformPresentationInput = exports.normalizePresentation = exports.transformCredentialInput = exports.normalizeCredential = exports.attestationToVcFormat = exports.isLegacyAttestationFormat = exports.asArray = void 0; | ||
var did_jwt_1 = require("did-jwt"); | ||
var constants_1 = require("./constants"); | ||
function asArray(input) { | ||
return Array.isArray(input) ? input : [input]; | ||
} | ||
exports.asArray = asArray; | ||
function deepCopy(obj) { | ||
var e_1, _a; | ||
var copy; | ||
// Handle the 3 simple types, and null or undefined | ||
if (null === obj || 'object' !== typeof obj) | ||
return obj; | ||
// Handle Date | ||
if (obj instanceof Date) { | ||
copy = new Date(); | ||
copy.setTime(obj.getTime()); | ||
return copy; | ||
// Handle Object | ||
if (obj instanceof Object) { | ||
copy = {}; | ||
try { | ||
for (var _b = __values(Object.keys(obj)), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var key = _c.value; | ||
copy[key] = deepCopy(obj[key]); | ||
} | ||
} | ||
// Handle Array | ||
if (obj instanceof Array) { | ||
copy = obj.map(deepCopy); | ||
return copy; | ||
} | ||
// Handle Object | ||
if (obj instanceof Object) { | ||
copy = {}; | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
for (var _b = __values(Object.keys(obj)), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var key = _c.value; | ||
copy[key] = deepCopy(obj[key]); | ||
} | ||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b); | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
return copy; | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
throw new Error("Unable to copy obj! Its type isn't supported."); | ||
return copy; | ||
} | ||
function notEmpty(value) { | ||
return value !== null && value !== undefined; | ||
throw new Error("Unable to copy obj! Its type isn't supported."); | ||
} | ||
function notEmpty(value) { | ||
return value !== null && value !== undefined; | ||
} | ||
function cleanUndefined(input) { | ||
if (typeof input !== 'object') { | ||
return input; | ||
} | ||
function cleanUndefined(input) { | ||
if (typeof input !== 'object') { | ||
return input; | ||
var obj = __assign({}, input); | ||
Object.keys(obj).forEach(function (key) { return obj[key] === undefined && delete obj[key]; }); | ||
return obj; | ||
} | ||
function isLegacyAttestationFormat(payload) { | ||
// payload is an object and has all the required fields of old attestation format | ||
return payload instanceof Object && payload.sub && payload.iss && payload.claim && payload.iat; | ||
} | ||
exports.isLegacyAttestationFormat = isLegacyAttestationFormat; | ||
function attestationToVcFormat(payload) { | ||
var iat = payload.iat, nbf = payload.nbf, claim = payload.claim, vc = payload.vc, rest = __rest(payload, ["iat", "nbf", "claim", "vc"]); | ||
var result = __assign(__assign({}, rest), { nbf: nbf ? nbf : iat, vc: { | ||
'@context': [constants_1.DEFAULT_CONTEXT], | ||
type: [constants_1.DEFAULT_VC_TYPE], | ||
credentialSubject: payload.claim | ||
} }); | ||
if (vc) | ||
payload.issVc = vc; | ||
return result; | ||
} | ||
exports.attestationToVcFormat = attestationToVcFormat; | ||
function normalizeJwtCredentialPayload(input) { | ||
var _a, _b, _c, _d, _e, _f, _g, _h; | ||
var result = deepCopy(input); | ||
if (isLegacyAttestationFormat(input)) { | ||
result = attestationToVcFormat(input); | ||
} | ||
// FIXME: handle case when credentialSubject(s) are not object types | ||
result.credentialSubject = __assign(__assign({}, input.credentialSubject), (_a = input.vc) === null || _a === void 0 ? void 0 : _a.credentialSubject); | ||
if (input.sub && !((_b = input.credentialSubject) === null || _b === void 0 ? void 0 : _b.id)) { | ||
result.credentialSubject.id = input.sub; | ||
delete result.sub; | ||
} | ||
(_c = result.vc) === null || _c === void 0 ? true : delete _c.credentialSubject; | ||
if (typeof input.issuer === 'undefined' || typeof input.issuer === 'object') { | ||
result.issuer = cleanUndefined(__assign({ id: input.iss }, input.issuer)); | ||
if (!((_d = input.issuer) === null || _d === void 0 ? void 0 : _d.id)) { | ||
delete result.iss; | ||
} | ||
var obj = __assign({}, input); | ||
Object.keys(obj).forEach(function (key) { return obj[key] === undefined && delete obj[key]; }); | ||
return obj; | ||
} | ||
function isLegacyAttestationFormat(payload) { | ||
// payload is an object and has all the required fields of old attestation format | ||
return payload instanceof Object && payload.sub && payload.iss && payload.claim && payload.iat; | ||
if (!input.id && input.jti) { | ||
result.id = result.id || result.jti; | ||
delete result.jti; | ||
} | ||
exports.isLegacyAttestationFormat = isLegacyAttestationFormat; | ||
function attestationToVcFormat(payload) { | ||
var iat = payload.iat, nbf = payload.nbf, claim = payload.claim, vc = payload.vc, rest = __rest(payload, ["iat", "nbf", "claim", "vc"]); | ||
var result = __assign(__assign({}, rest), { nbf: nbf ? nbf : iat, vc: { | ||
'@context': [constants_1.DEFAULT_CONTEXT], | ||
type: [constants_1.DEFAULT_VC_TYPE], | ||
credentialSubject: payload.claim | ||
} }); | ||
if (vc) | ||
payload.issVc = vc; | ||
return result; | ||
} | ||
exports.attestationToVcFormat = attestationToVcFormat; | ||
function normalizeJwtCredentialPayload(input) { | ||
var _a, _b, _c, _d, _e, _f, _g, _h; | ||
var result = deepCopy(input); | ||
if (isLegacyAttestationFormat(input)) { | ||
result = attestationToVcFormat(input); | ||
var types = __spread(asArray(result.type), asArray((_e = result.vc) === null || _e === void 0 ? void 0 : _e.type)).filter(notEmpty); | ||
result.type = __spread(new Set(types)); | ||
(_f = result.vc) === null || _f === void 0 ? true : delete _f.type; | ||
var contextArray = __spread(asArray(input.context), asArray(input['@context']), asArray((_g = input.vc) === null || _g === void 0 ? void 0 : _g['@context'])).filter(notEmpty); | ||
result['@context'] = __spread(new Set(contextArray)); | ||
delete result.context; | ||
(_h = result.vc) === null || _h === void 0 ? true : delete _h['@context']; | ||
if (!input.issuanceDate && (input.iat || input.nbf)) { | ||
result.issuanceDate = new Date((input.nbf || input.iat) * 1000).toISOString(); | ||
if (input.nbf) { | ||
delete result.nbf; | ||
} | ||
// FIXME: handle case when credentialSubject(s) are not object types | ||
result.credentialSubject = __assign(__assign({}, input.credentialSubject), (_a = input.vc) === null || _a === void 0 ? void 0 : _a.credentialSubject); | ||
if (input.sub && !((_b = input.credentialSubject) === null || _b === void 0 ? void 0 : _b.id)) { | ||
result.credentialSubject.id = input.sub; | ||
delete result.sub; | ||
else { | ||
delete result.iat; | ||
} | ||
(_c = result.vc) === null || _c === void 0 ? true : delete _c.credentialSubject; | ||
if (typeof input.issuer === 'undefined' || typeof input.issuer === 'object') { | ||
result.issuer = cleanUndefined(__assign({ id: input.iss }, input.issuer)); | ||
if (!((_d = input.issuer) === null || _d === void 0 ? void 0 : _d.id)) { | ||
delete result.iss; | ||
} | ||
} | ||
if (!input.expirationDate && input.exp) { | ||
result.expirationDate = new Date(input.exp * 1000).toISOString(); | ||
delete result.exp; | ||
} | ||
if (result.vc && Object.keys(result.vc).length === 0) { | ||
delete result.vc; | ||
} | ||
// FIXME: interpret `aud` property as `verifier` | ||
return result; | ||
} | ||
function normalizeJwtCredential(input) { | ||
var decoded; | ||
try { | ||
decoded = did_jwt_1.decodeJWT(input); | ||
} | ||
catch (e) { | ||
throw new TypeError('unknown credential format'); | ||
} | ||
return __assign(__assign({}, normalizeJwtCredentialPayload(decoded.payload)), { proof: { | ||
type: constants_1.DEFAULT_JWT_PROOF_TYPE, | ||
jwt: input | ||
} }); | ||
} | ||
/** | ||
* Normalizes a credential payload into an unambiguous W3C credential data type | ||
* In case of conflict, Existing W3C Credential specific properties take precedence, | ||
* except for arrays and object types which get merged. | ||
* @param input either a JWT or JWT payload, or a VerifiableCredential | ||
*/ | ||
function normalizeCredential(input) { | ||
var _a; | ||
if (typeof input === 'string') { | ||
if (constants_1.JWT_FORMAT.test(input)) { | ||
return normalizeJwtCredential(input); | ||
} | ||
if (!input.id && input.jti) { | ||
result.id = result.id || result.jti; | ||
delete result.jti; | ||
} | ||
var types = __spread(asArray(result.type), asArray((_e = result.vc) === null || _e === void 0 ? void 0 : _e.type)).filter(notEmpty); | ||
result.type = __spread(new Set(types)); | ||
(_f = result.vc) === null || _f === void 0 ? true : delete _f.type; | ||
var contextArray = __spread(asArray(input.context), asArray(input['@context']), asArray((_g = input.vc) === null || _g === void 0 ? void 0 : _g['@context'])).filter(notEmpty); | ||
result['@context'] = __spread(new Set(contextArray)); | ||
delete result.context; | ||
(_h = result.vc) === null || _h === void 0 ? true : delete _h['@context']; | ||
if (!input.issuanceDate && (input.iat || input.nbf)) { | ||
result.issuanceDate = new Date((input.nbf || input.iat) * 1000).toISOString(); | ||
if (input.nbf) { | ||
delete result.nbf; | ||
else { | ||
var parsed = void 0; | ||
try { | ||
parsed = JSON.parse(input); | ||
} | ||
else { | ||
delete result.iat; | ||
catch (e) { | ||
throw new TypeError('unknown credential format'); | ||
} | ||
return normalizeCredential(parsed); | ||
} | ||
if (!input.expirationDate && input.exp) { | ||
result.expirationDate = new Date(input.exp * 1000).toISOString(); | ||
delete result.exp; | ||
} | ||
else if ((_a = input.proof) === null || _a === void 0 ? void 0 : _a.jwt) { | ||
// TODO: test that it correctly propagates app specific proof properties | ||
return deepCopy(__assign(__assign({}, normalizeJwtCredential(input.proof.jwt)), { proof: input.proof })); | ||
} | ||
else { | ||
// TODO: test that it accepts JWT payload, CredentialPayload, VerifiableCredential | ||
// TODO: test that it correctly propagates proof, if any | ||
return __assign({ proof: {} }, normalizeJwtCredentialPayload(input)); | ||
} | ||
} | ||
exports.normalizeCredential = normalizeCredential; | ||
/** | ||
* Transforms a W3C Credential payload into a JWT compatible encoding. | ||
* The method accepts app specific fields and in case of collision, existing JWT properties will take precedence. | ||
* Also, `nbf`, `exp` and `jti` properties can be explicitly set to `undefined` and they will be kept intact. | ||
* @param input either a JWT payload or a CredentialPayloadInput | ||
*/ | ||
function transformCredentialInput(input) { | ||
var _a, _b, _c, _d, _e; | ||
if (Array.isArray(input.credentialSubject)) | ||
throw Error('credentialSubject of type array not supported'); | ||
var result = deepCopy(__assign({ vc: __assign({}, input.vc) }, input)); | ||
var credentialSubject = __assign(__assign({}, input.credentialSubject), (_a = input.vc) === null || _a === void 0 ? void 0 : _a.credentialSubject); | ||
if (!input.sub) { | ||
result.sub = (_b = input.credentialSubject) === null || _b === void 0 ? void 0 : _b.id; | ||
delete credentialSubject.id; | ||
} | ||
result.vc.credentialSubject = credentialSubject; | ||
delete result.credentialSubject; | ||
var contextEntries = __spread(asArray(input.context), asArray(input['@context']), asArray((_c = input.vc) === null || _c === void 0 ? void 0 : _c['@context'])).filter(notEmpty); | ||
result.vc['@context'] = __spread(new Set(contextEntries)); | ||
delete result.context; | ||
delete result['@context']; | ||
var types = __spread(asArray(input.type), asArray((_d = input.vc) === null || _d === void 0 ? void 0 : _d.type)).filter(notEmpty); | ||
result.vc.type = __spread(new Set(types)); | ||
delete result.type; | ||
if (input.id && Object.getOwnPropertyNames(input).indexOf('jti') === -1) { | ||
result.jti = input.id; | ||
delete result.id; | ||
} | ||
if (input.issuanceDate && Object.getOwnPropertyNames(input).indexOf('nbf') === -1) { | ||
var converted = Date.parse(input.issuanceDate); | ||
if (!isNaN(converted)) { | ||
result.nbf = Math.floor(converted / 1000); | ||
delete result.issuanceDate; | ||
} | ||
if (result.vc && Object.keys(result.vc).length === 0) { | ||
delete result.vc; | ||
} | ||
// FIXME: interpret `aud` property as `verifier` | ||
return result; | ||
} | ||
function normalizeJwtCredential(input) { | ||
var decoded; | ||
try { | ||
decoded = did_jwt_1.decodeJWT(input); | ||
if (input.expirationDate && Object.getOwnPropertyNames(input).indexOf('exp') === -1) { | ||
var converted = Date.parse(input.expirationDate); | ||
if (!isNaN(converted)) { | ||
result.exp = Math.floor(converted / 1000); | ||
delete result.expirationDate; | ||
} | ||
catch (e) { | ||
throw new TypeError('unknown credential format'); | ||
} | ||
return __assign(__assign({}, normalizeJwtCredentialPayload(decoded.payload)), { proof: { | ||
type: constants_1.DEFAULT_JWT_PROOF_TYPE, | ||
jwt: input | ||
} }); | ||
} | ||
/** | ||
* Normalizes a credential payload into an unambiguous W3C credential data type | ||
* In case of conflict, Existing W3C Credential specific properties take precedence, | ||
* except for arrays and object types which get merged. | ||
* @param input either a JWT or JWT payload, or a VerifiableCredential | ||
*/ | ||
function normalizeCredential(input) { | ||
var _a; | ||
if (typeof input === 'string') { | ||
if (constants_1.JWT_FORMAT.test(input)) { | ||
return normalizeJwtCredential(input); | ||
if (input.issuer && Object.getOwnPropertyNames(input).indexOf('iss') === -1) { | ||
if (typeof input.issuer === 'object') { | ||
result.iss = (_e = input.issuer) === null || _e === void 0 ? void 0 : _e.id; | ||
delete result.issuer.id; | ||
if (Object.keys(result.issuer).length === 0) { | ||
delete result.issuer; | ||
} | ||
else { | ||
var parsed = void 0; | ||
try { | ||
parsed = JSON.parse(input); | ||
} | ||
catch (e) { | ||
throw new TypeError('unknown credential format'); | ||
} | ||
return normalizeCredential(parsed); | ||
} | ||
} | ||
else if ((_a = input.proof) === null || _a === void 0 ? void 0 : _a.jwt) { | ||
// TODO: test that it correctly propagates app specific proof properties | ||
return deepCopy(__assign(__assign({}, normalizeJwtCredential(input.proof.jwt)), { proof: input.proof })); | ||
else if (typeof input.issuer === 'string') { | ||
result.iss = input.iss || '' + input.issuer; | ||
delete result.issuer; | ||
} | ||
else { | ||
// TODO: test that it accepts JWT payload, CredentialPayload, VerifiableCredential | ||
// TODO: test that it correctly propagates proof, if any | ||
return __assign({ proof: {} }, normalizeJwtCredentialPayload(input)); | ||
// nop | ||
} | ||
} | ||
exports.normalizeCredential = normalizeCredential; | ||
/** | ||
* Transforms a W3C Credential payload into a JWT compatible encoding. | ||
* The method accepts app specific fields and in case of collision, existing JWT properties will take precedence. | ||
* Also, `nbf`, `exp` and `jti` properties can be explicitly set to `undefined` and they will be kept intact. | ||
* @param input either a JWT payload or a CredentialPayloadInput | ||
*/ | ||
function transformCredentialInput(input) { | ||
var _a, _b, _c, _d, _e; | ||
if (Array.isArray(input.credentialSubject)) | ||
throw Error('credentialSubject of type array not supported'); | ||
var result = deepCopy(__assign({ vc: __assign({}, input.vc) }, input)); | ||
var credentialSubject = __assign(__assign({}, input.credentialSubject), (_a = input.vc) === null || _a === void 0 ? void 0 : _a.credentialSubject); | ||
if (!input.sub) { | ||
result.sub = (_b = input.credentialSubject) === null || _b === void 0 ? void 0 : _b.id; | ||
delete credentialSubject.id; | ||
return result; | ||
} | ||
exports.transformCredentialInput = transformCredentialInput; | ||
function normalizeJwtPresentationPayload(input) { | ||
var _a, _b, _c, _d, _e, _f; | ||
var result = deepCopy(input); | ||
result.verifiableCredential = __spread(asArray(input.verifiableCredential), asArray((_a = input.vp) === null || _a === void 0 ? void 0 : _a.verifiableCredential)).filter(notEmpty); | ||
result.verifiableCredential = result.verifiableCredential.map(normalizeCredential); | ||
(_b = result.vp) === null || _b === void 0 ? true : delete _b.verifiableCredential; | ||
if (input.iss && !input.holder) { | ||
result.holder = input.iss; | ||
delete result.iss; | ||
} | ||
if (input.aud) { | ||
result.verifier = __spread(asArray(input.verifier), asArray(input.aud)).filter(notEmpty); | ||
result.verifier = __spread(new Set(result.verifier)); | ||
delete result.aud; | ||
} | ||
if (input.jti && Object.getOwnPropertyNames(input).indexOf('id') === -1) { | ||
result.id = input.id || input.jti; | ||
delete result.jti; | ||
} | ||
var types = __spread(asArray(input.type), asArray((_c = input.vp) === null || _c === void 0 ? void 0 : _c.type)).filter(notEmpty); | ||
result.type = __spread(new Set(types)); | ||
(_d = result.vp) === null || _d === void 0 ? true : delete _d.type; | ||
var contexts = __spread(asArray(input.context), asArray(input['@context']), asArray((_e = input.vp) === null || _e === void 0 ? void 0 : _e['@context'])).filter(notEmpty); | ||
result['@context'] = __spread(new Set(contexts)); | ||
delete result.context; | ||
(_f = result.vp) === null || _f === void 0 ? true : delete _f['@context']; | ||
if (!input.issuanceDate && (input.iat || input.nbf)) { | ||
result.issuanceDate = new Date((input.nbf || input.iat) * 1000).toISOString(); | ||
if (input.nbf) { | ||
delete result.nbf; | ||
} | ||
result.vc.credentialSubject = credentialSubject; | ||
delete result.credentialSubject; | ||
var contextEntries = __spread(asArray(input.context), asArray(input['@context']), asArray((_c = input.vc) === null || _c === void 0 ? void 0 : _c['@context'])).filter(notEmpty); | ||
result.vc['@context'] = __spread(new Set(contextEntries)); | ||
delete result.context; | ||
delete result['@context']; | ||
var types = __spread(asArray(input.type), asArray((_d = input.vc) === null || _d === void 0 ? void 0 : _d.type)).filter(notEmpty); | ||
result.vc.type = __spread(new Set(types)); | ||
delete result.type; | ||
if (input.id && Object.getOwnPropertyNames(input).indexOf('jti') === -1) { | ||
result.jti = input.id; | ||
delete result.id; | ||
else { | ||
delete result.iat; | ||
} | ||
if (input.issuanceDate && Object.getOwnPropertyNames(input).indexOf('nbf') === -1) { | ||
var converted = Date.parse(input.issuanceDate); | ||
if (!isNaN(converted)) { | ||
result.nbf = Math.floor(converted / 1000); | ||
delete result.issuanceDate; | ||
} | ||
} | ||
if (!input.expirationDate && input.exp) { | ||
result.expirationDate = new Date(input.exp * 1000).toISOString(); | ||
delete result.exp; | ||
} | ||
if (result.vp && Object.keys(result.vp).length === 0) { | ||
delete result.vp; | ||
} | ||
return result; | ||
} | ||
function normalizeJwtPresentation(input) { | ||
var decoded; | ||
try { | ||
decoded = did_jwt_1.decodeJWT(input); | ||
} | ||
catch (e) { | ||
throw new TypeError('unknown presentation format'); | ||
} | ||
return __assign(__assign({}, normalizeJwtPresentationPayload(decoded.payload)), { proof: { | ||
type: constants_1.DEFAULT_JWT_PROOF_TYPE, | ||
jwt: input | ||
} }); | ||
} | ||
/** | ||
* Normalizes a presentation payload into an unambiguous W3C Presentation data type | ||
* @param input either a JWT or JWT payload, or a VerifiablePresentation | ||
*/ | ||
function normalizePresentation(input) { | ||
var _a; | ||
if (typeof input === 'string') { | ||
if (constants_1.JWT_FORMAT.test(input)) { | ||
return normalizeJwtPresentation(input); | ||
} | ||
if (input.expirationDate && Object.getOwnPropertyNames(input).indexOf('exp') === -1) { | ||
var converted = Date.parse(input.expirationDate); | ||
if (!isNaN(converted)) { | ||
result.exp = Math.floor(converted / 1000); | ||
delete result.expirationDate; | ||
else { | ||
var parsed = void 0; | ||
try { | ||
parsed = JSON.parse(input); | ||
} | ||
} | ||
if (input.issuer && Object.getOwnPropertyNames(input).indexOf('iss') === -1) { | ||
if (typeof input.issuer === 'object') { | ||
result.iss = (_e = input.issuer) === null || _e === void 0 ? void 0 : _e.id; | ||
delete result.issuer.id; | ||
if (Object.keys(result.issuer).length === 0) { | ||
delete result.issuer; | ||
} | ||
catch (e) { | ||
throw new TypeError('unknown presentation format'); | ||
} | ||
else if (typeof input.issuer === 'string') { | ||
result.iss = input.iss || '' + input.issuer; | ||
delete result.issuer; | ||
} | ||
else { | ||
// nop | ||
} | ||
return normalizePresentation(parsed); | ||
} | ||
return result; | ||
} | ||
exports.transformCredentialInput = transformCredentialInput; | ||
function normalizeJwtPresentationPayload(input) { | ||
var _a, _b, _c, _d, _e, _f; | ||
var result = deepCopy(input); | ||
result.verifiableCredential = __spread(asArray(input.verifiableCredential), asArray((_a = input.vp) === null || _a === void 0 ? void 0 : _a.verifiableCredential)).filter(notEmpty); | ||
result.verifiableCredential = result.verifiableCredential.map(normalizeCredential); | ||
(_b = result.vp) === null || _b === void 0 ? true : delete _b.verifiableCredential; | ||
if (input.iss && !input.holder) { | ||
result.holder = input.iss; | ||
delete result.iss; | ||
else if ((_a = input.proof) === null || _a === void 0 ? void 0 : _a.jwt) { | ||
// TODO: test that it correctly propagates app specific proof properties | ||
return __assign(__assign({}, normalizeJwtPresentation(input.proof.jwt)), { proof: input.proof }); | ||
} | ||
else { | ||
// TODO: test that it accepts JWT payload, PresentationPayload, VerifiablePresentation | ||
// TODO: test that it correctly propagates proof, if any | ||
return __assign({ proof: {} }, normalizeJwtPresentationPayload(input)); | ||
} | ||
} | ||
exports.normalizePresentation = normalizePresentation; | ||
/** | ||
* Transforms a W3C Presentation payload into a JWT compatible encoding. | ||
* The method accepts app specific fields and in case of collision, existing JWT properties will take precedence. | ||
* Also, `nbf`, `exp` and `jti` properties can be explicitly set to `undefined` and they will be kept intact. | ||
* @param input either a JWT payload or a CredentialPayloadInput | ||
*/ | ||
function transformPresentationInput(input) { | ||
var _a, _b, _c; | ||
var result = deepCopy(__assign({ vp: __assign({}, input.vp) }, input)); | ||
var contextEntries = __spread(asArray(input.context), asArray(input['@context']), asArray((_a = input.vp) === null || _a === void 0 ? void 0 : _a['@context'])).filter(notEmpty); | ||
result.vp['@context'] = __spread(new Set(contextEntries)); | ||
delete result.context; | ||
delete result['@context']; | ||
var types = __spread(asArray(input.type), asArray((_b = input.vp) === null || _b === void 0 ? void 0 : _b.type)).filter(notEmpty); | ||
result.vp.type = __spread(new Set(types)); | ||
delete result.type; | ||
if (input.id && Object.getOwnPropertyNames(input).indexOf('jti') === -1) { | ||
result.jti = input.id; | ||
delete result.id; | ||
} | ||
if (input.issuanceDate && Object.getOwnPropertyNames(input).indexOf('nbf') === -1) { | ||
var converted = Date.parse(input.issuanceDate); | ||
if (!isNaN(converted)) { | ||
result.nbf = Math.floor(converted / 1000); | ||
delete result.issuanceDate; | ||
} | ||
if (input.aud) { | ||
result.verifier = __spread(asArray(input.verifier), asArray(input.aud)).filter(notEmpty); | ||
result.verifier = __spread(new Set(result.verifier)); | ||
delete result.aud; | ||
} | ||
if (input.jti && Object.getOwnPropertyNames(input).indexOf('id') === -1) { | ||
result.id = input.id || input.jti; | ||
delete result.jti; | ||
} | ||
var types = __spread(asArray(input.type), asArray((_c = input.vp) === null || _c === void 0 ? void 0 : _c.type)).filter(notEmpty); | ||
result.type = __spread(new Set(types)); | ||
(_d = result.vp) === null || _d === void 0 ? true : delete _d.type; | ||
var contexts = __spread(asArray(input.context), asArray(input['@context']), asArray((_e = input.vp) === null || _e === void 0 ? void 0 : _e['@context'])).filter(notEmpty); | ||
result['@context'] = __spread(new Set(contexts)); | ||
delete result.context; | ||
(_f = result.vp) === null || _f === void 0 ? true : delete _f['@context']; | ||
if (!input.issuanceDate && (input.iat || input.nbf)) { | ||
result.issuanceDate = new Date((input.nbf || input.iat) * 1000).toISOString(); | ||
if (input.nbf) { | ||
delete result.nbf; | ||
} | ||
else { | ||
delete result.iat; | ||
} | ||
} | ||
if (!input.expirationDate && input.exp) { | ||
result.expirationDate = new Date(input.exp * 1000).toISOString(); | ||
delete result.exp; | ||
} | ||
if (result.vp && Object.keys(result.vp).length === 0) { | ||
delete result.vp; | ||
} | ||
return result; | ||
} | ||
function normalizeJwtPresentation(input) { | ||
var decoded; | ||
try { | ||
decoded = did_jwt_1.decodeJWT(input); | ||
if (input.expirationDate && Object.getOwnPropertyNames(input).indexOf('exp') === -1) { | ||
var converted = Date.parse(input.expirationDate); | ||
if (!isNaN(converted)) { | ||
result.exp = Math.floor(converted / 1000); | ||
delete result.expirationDate; | ||
} | ||
catch (e) { | ||
throw new TypeError('unknown presentation format'); | ||
} | ||
return __assign(__assign({}, normalizeJwtPresentationPayload(decoded.payload)), { proof: { | ||
type: constants_1.DEFAULT_JWT_PROOF_TYPE, | ||
jwt: input | ||
} }); | ||
} | ||
/** | ||
* Normalizes a presentation payload into an unambiguous W3C Presentation data type | ||
* @param input either a JWT or JWT payload, or a VerifiablePresentation | ||
*/ | ||
function normalizePresentation(input) { | ||
result.vp.verifiableCredential = __spread(asArray(result.verifiableCredential), asArray((_c = result.vp) === null || _c === void 0 ? void 0 : _c.verifiableCredential)).filter(notEmpty) | ||
.map(function (credential) { | ||
var _a; | ||
if (typeof input === 'string') { | ||
if (constants_1.JWT_FORMAT.test(input)) { | ||
return normalizeJwtPresentation(input); | ||
} | ||
else { | ||
var parsed = void 0; | ||
try { | ||
parsed = JSON.parse(input); | ||
} | ||
catch (e) { | ||
throw new TypeError('unknown presentation format'); | ||
} | ||
return normalizePresentation(parsed); | ||
} | ||
if (typeof credential === 'object' && ((_a = credential.proof) === null || _a === void 0 ? void 0 : _a.jwt)) { | ||
return credential.proof.jwt; | ||
} | ||
else if ((_a = input.proof) === null || _a === void 0 ? void 0 : _a.jwt) { | ||
// TODO: test that it correctly propagates app specific proof properties | ||
return __assign(__assign({}, normalizeJwtPresentation(input.proof.jwt)), { proof: input.proof }); | ||
} | ||
else { | ||
// TODO: test that it accepts JWT payload, PresentationPayload, VerifiablePresentation | ||
// TODO: test that it correctly propagates proof, if any | ||
return __assign({ proof: {} }, normalizeJwtPresentationPayload(input)); | ||
return credential; | ||
} | ||
} | ||
exports.normalizePresentation = normalizePresentation; | ||
/** | ||
* Transforms a W3C Presentation payload into a JWT compatible encoding. | ||
* The method accepts app specific fields and in case of collision, existing JWT properties will take precedence. | ||
* Also, `nbf`, `exp` and `jti` properties can be explicitly set to `undefined` and they will be kept intact. | ||
* @param input either a JWT payload or a CredentialPayloadInput | ||
*/ | ||
function transformPresentationInput(input) { | ||
var _a, _b, _c; | ||
var result = deepCopy(__assign({ vp: __assign({}, input.vp) }, input)); | ||
var contextEntries = __spread(asArray(input.context), asArray(input['@context']), asArray((_a = input.vp) === null || _a === void 0 ? void 0 : _a['@context'])).filter(notEmpty); | ||
result.vp['@context'] = __spread(new Set(contextEntries)); | ||
delete result.context; | ||
delete result['@context']; | ||
var types = __spread(asArray(input.type), asArray((_b = input.vp) === null || _b === void 0 ? void 0 : _b.type)).filter(notEmpty); | ||
result.vp.type = __spread(new Set(types)); | ||
delete result.type; | ||
if (input.id && Object.getOwnPropertyNames(input).indexOf('jti') === -1) { | ||
result.jti = input.id; | ||
delete result.id; | ||
}); | ||
delete result.verifiableCredential; | ||
if (input.holder && Object.getOwnPropertyNames(input).indexOf('iss') === -1) { | ||
if (typeof input.holder === 'string') { | ||
result.iss = input.holder; | ||
delete result.holder; | ||
} | ||
if (input.issuanceDate && Object.getOwnPropertyNames(input).indexOf('nbf') === -1) { | ||
var converted = Date.parse(input.issuanceDate); | ||
if (!isNaN(converted)) { | ||
result.nbf = Math.floor(converted / 1000); | ||
delete result.issuanceDate; | ||
} | ||
else { | ||
// nop | ||
} | ||
if (input.expirationDate && Object.getOwnPropertyNames(input).indexOf('exp') === -1) { | ||
var converted = Date.parse(input.expirationDate); | ||
if (!isNaN(converted)) { | ||
result.exp = Math.floor(converted / 1000); | ||
delete result.expirationDate; | ||
} | ||
} | ||
result.vp.verifiableCredential = __spread(asArray(result.verifiableCredential), asArray((_c = result.vp) === null || _c === void 0 ? void 0 : _c.verifiableCredential)).filter(notEmpty) | ||
.map(function (credential) { | ||
var _a; | ||
if (typeof credential === 'object' && ((_a = credential.proof) === null || _a === void 0 ? void 0 : _a.jwt)) { | ||
return credential.proof.jwt; | ||
} | ||
else { | ||
return credential; | ||
} | ||
}); | ||
delete result.verifiableCredential; | ||
if (input.holder && Object.getOwnPropertyNames(input).indexOf('iss') === -1) { | ||
if (typeof input.holder === 'string') { | ||
result.iss = input.holder; | ||
delete result.holder; | ||
} | ||
else { | ||
// nop | ||
} | ||
} | ||
if (input.verifier) { | ||
var audience = __spread(asArray(input.verifier), asArray(input.aud)).filter(notEmpty); | ||
result.aud = __spread(new Set(audience)); | ||
delete result.verifier; | ||
} | ||
return result; | ||
} | ||
exports.transformPresentationInput = transformPresentationInput; | ||
}); | ||
if (input.verifier) { | ||
var audience = __spread(asArray(input.verifier), asArray(input.aud)).filter(notEmpty); | ||
result.aud = __spread(new Set(audience)); | ||
delete result.verifier; | ||
} | ||
return result; | ||
} | ||
exports.transformPresentationInput = transformPresentationInput; | ||
//# sourceMappingURL=converters.js.map |
372
lib/index.js
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
var __assign = (this && this.__assign) || function () { | ||
@@ -78,207 +79,196 @@ __assign = Object.assign || function(t) { | ||
}; | ||
(function (factory) { | ||
if (typeof module === "object" && typeof module.exports === "object") { | ||
var v = factory(require, exports); | ||
if (v !== undefined) module.exports = v; | ||
} | ||
else if (typeof define === "function" && define.amd) { | ||
define(["require", "exports", "did-jwt", "./constants", "./validators", "./converters"], factory); | ||
} | ||
})(function (require, exports) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.verifyPresentation = exports.verifyCredential = exports.validatePresentationPayload = exports.validateJwtPresentationPayload = exports.validateCredentialPayload = exports.validateJwtCredentialPayload = exports.createVerifiablePresentationJwt = exports.createVerifiableCredentialJwt = exports.normalizePresentation = exports.normalizeCredential = exports.transformPresentationInput = exports.transformCredentialInput = void 0; | ||
var did_jwt_1 = require("did-jwt"); | ||
var constants_1 = require("./constants"); | ||
var validators = __importStar(require("./validators")); | ||
var converters_1 = require("./converters"); | ||
Object.defineProperty(exports, "transformCredentialInput", { enumerable: true, get: function () { return converters_1.transformCredentialInput; } }); | ||
Object.defineProperty(exports, "transformPresentationInput", { enumerable: true, get: function () { return converters_1.transformPresentationInput; } }); | ||
Object.defineProperty(exports, "normalizeCredential", { enumerable: true, get: function () { return converters_1.normalizeCredential; } }); | ||
Object.defineProperty(exports, "normalizePresentation", { enumerable: true, get: function () { return converters_1.normalizePresentation; } }); | ||
/** | ||
* Creates a VerifiableCredential given a `CredentialPayload` or `JwtCredentialPayload` and an `Issuer`. | ||
* | ||
* This method transforms the payload into the [JWT encoding](https://www.w3.org/TR/vc-data-model/#jwt-encoding) | ||
* described in the [W3C VC spec](https://www.w3.org/TR/vc-data-model) and then validated to conform to the minimum spec | ||
* required spec. | ||
* | ||
* The `issuer` is then used to assign an algorithm, override the `iss` field of the payload and then sign the JWT. | ||
* | ||
* @param payload `CredentialPayload` or `JwtCredentialPayload` | ||
* @param issuer `Issuer` the DID, signer and algorithm that will sign the token | ||
* @return a `Promise` that resolves to the JWT encoded verifiable credential or rejects with `TypeError` if the | ||
* `payload` is not W3C compliant | ||
*/ | ||
function createVerifiableCredentialJwt(payload, issuer) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var parsedPayload; | ||
return __generator(this, function (_a) { | ||
parsedPayload = __assign({ iat: undefined }, converters_1.transformCredentialInput(payload)); | ||
validateJwtCredentialPayload(parsedPayload); | ||
return [2 /*return*/, did_jwt_1.createJWT(parsedPayload, { | ||
issuer: issuer.did || parsedPayload.iss, | ||
signer: issuer.signer, | ||
alg: issuer.alg || constants_1.JWT_ALG | ||
})]; | ||
}); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.verifyPresentation = exports.verifyCredential = exports.validatePresentationPayload = exports.validateJwtPresentationPayload = exports.validateCredentialPayload = exports.validateJwtCredentialPayload = exports.createVerifiablePresentationJwt = exports.createVerifiableCredentialJwt = exports.normalizePresentation = exports.normalizeCredential = exports.transformPresentationInput = exports.transformCredentialInput = void 0; | ||
var did_jwt_1 = require("did-jwt"); | ||
var constants_1 = require("./constants"); | ||
var validators = __importStar(require("./validators")); | ||
var converters_1 = require("./converters"); | ||
Object.defineProperty(exports, "transformCredentialInput", { enumerable: true, get: function () { return converters_1.transformCredentialInput; } }); | ||
Object.defineProperty(exports, "transformPresentationInput", { enumerable: true, get: function () { return converters_1.transformPresentationInput; } }); | ||
Object.defineProperty(exports, "normalizeCredential", { enumerable: true, get: function () { return converters_1.normalizeCredential; } }); | ||
Object.defineProperty(exports, "normalizePresentation", { enumerable: true, get: function () { return converters_1.normalizePresentation; } }); | ||
/** | ||
* Creates a VerifiableCredential given a `CredentialPayload` or `JwtCredentialPayload` and an `Issuer`. | ||
* | ||
* This method transforms the payload into the [JWT encoding](https://www.w3.org/TR/vc-data-model/#jwt-encoding) | ||
* described in the [W3C VC spec](https://www.w3.org/TR/vc-data-model) and then validated to conform to the minimum spec | ||
* required spec. | ||
* | ||
* The `issuer` is then used to assign an algorithm, override the `iss` field of the payload and then sign the JWT. | ||
* | ||
* @param payload `CredentialPayload` or `JwtCredentialPayload` | ||
* @param issuer `Issuer` the DID, signer and algorithm that will sign the token | ||
* @return a `Promise` that resolves to the JWT encoded verifiable credential or rejects with `TypeError` if the | ||
* `payload` is not W3C compliant | ||
*/ | ||
function createVerifiableCredentialJwt(payload, issuer) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var parsedPayload; | ||
return __generator(this, function (_a) { | ||
parsedPayload = __assign({ iat: undefined }, converters_1.transformCredentialInput(payload)); | ||
validateJwtCredentialPayload(parsedPayload); | ||
return [2 /*return*/, did_jwt_1.createJWT(parsedPayload, { | ||
issuer: issuer.did || parsedPayload.iss, | ||
signer: issuer.signer, | ||
alg: issuer.alg || constants_1.JWT_ALG | ||
})]; | ||
}); | ||
} | ||
exports.createVerifiableCredentialJwt = createVerifiableCredentialJwt; | ||
/** | ||
* Creates a VerifiablePresentation JWT given a `PresentationPayload` or `JwtPresentationPayload` and an `Issuer`. | ||
* | ||
* This method transforms the payload into the [JWT encoding](https://www.w3.org/TR/vc-data-model/#jwt-encoding) | ||
* described in the [W3C VC spec](https://www.w3.org/TR/vc-data-model) and then validated to conform to the minimum spec | ||
* required spec. | ||
* | ||
* The `issuer` is then used to assign an algorithm, override the `iss` field of the payload and then sign the JWT. | ||
* | ||
* @param payload `PresentationPayload` or `JwtPresentationPayload` | ||
* @param issuer `Issuer` the DID, signer and algorithm that will sign the token | ||
* @return a `Promise` that resolves to the JWT encoded verifiable presentation or rejects with `TypeError` if the | ||
* `payload` is not W3C compliant | ||
*/ | ||
function createVerifiablePresentationJwt(payload, issuer) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var parsedPayload; | ||
return __generator(this, function (_a) { | ||
parsedPayload = __assign({ iat: undefined }, converters_1.transformPresentationInput(payload)); | ||
validateJwtPresentationPayload(parsedPayload); | ||
return [2 /*return*/, did_jwt_1.createJWT(parsedPayload, { | ||
issuer: issuer.did || parsedPayload.iss, | ||
signer: issuer.signer, | ||
alg: issuer.alg || constants_1.JWT_ALG | ||
})]; | ||
}); | ||
}); | ||
} | ||
exports.createVerifiableCredentialJwt = createVerifiableCredentialJwt; | ||
/** | ||
* Creates a VerifiablePresentation JWT given a `PresentationPayload` or `JwtPresentationPayload` and an `Issuer`. | ||
* | ||
* This method transforms the payload into the [JWT encoding](https://www.w3.org/TR/vc-data-model/#jwt-encoding) | ||
* described in the [W3C VC spec](https://www.w3.org/TR/vc-data-model) and then validated to conform to the minimum spec | ||
* required spec. | ||
* | ||
* The `issuer` is then used to assign an algorithm, override the `iss` field of the payload and then sign the JWT. | ||
* | ||
* @param payload `PresentationPayload` or `JwtPresentationPayload` | ||
* @param issuer `Issuer` the DID, signer and algorithm that will sign the token | ||
* @return a `Promise` that resolves to the JWT encoded verifiable presentation or rejects with `TypeError` if the | ||
* `payload` is not W3C compliant | ||
*/ | ||
function createVerifiablePresentationJwt(payload, issuer) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var parsedPayload; | ||
return __generator(this, function (_a) { | ||
parsedPayload = __assign({ iat: undefined }, converters_1.transformPresentationInput(payload)); | ||
validateJwtPresentationPayload(parsedPayload); | ||
return [2 /*return*/, did_jwt_1.createJWT(parsedPayload, { | ||
issuer: issuer.did || parsedPayload.iss, | ||
signer: issuer.signer, | ||
alg: issuer.alg || constants_1.JWT_ALG | ||
})]; | ||
}); | ||
}); | ||
} | ||
exports.createVerifiablePresentationJwt = createVerifiablePresentationJwt; | ||
function validateJwtCredentialPayload(payload) { | ||
validators.validateContext(payload.vc['@context']); | ||
validators.validateVcType(payload.vc.type); | ||
validators.validateCredentialSubject(payload.vc.credentialSubject); | ||
if (payload.nbf) | ||
validators.validateTimestamp(payload.nbf); | ||
if (payload.exp) | ||
validators.validateTimestamp(payload.exp); | ||
} | ||
exports.validateJwtCredentialPayload = validateJwtCredentialPayload; | ||
function validateCredentialPayload(payload) { | ||
validators.validateContext(payload['@context']); | ||
validators.validateVcType(payload.type); | ||
validators.validateCredentialSubject(payload.credentialSubject); | ||
if (payload.issuanceDate) | ||
validators.validateTimestamp(payload.issuanceDate); | ||
if (payload.expirationDate) | ||
validators.validateTimestamp(payload.expirationDate); | ||
} | ||
exports.validateCredentialPayload = validateCredentialPayload; | ||
function validateJwtPresentationPayload(payload) { | ||
var e_1, _a; | ||
validators.validateContext(payload.vp['@context']); | ||
validators.validateVpType(payload.vp.type); | ||
if (payload.vp.verifiableCredential.length < 1) { | ||
throw new TypeError('vp.verifiableCredential must not be empty'); | ||
} | ||
exports.createVerifiablePresentationJwt = createVerifiablePresentationJwt; | ||
function validateJwtCredentialPayload(payload) { | ||
validators.validateContext(payload.vc['@context']); | ||
validators.validateVcType(payload.vc.type); | ||
validators.validateCredentialSubject(payload.vc.credentialSubject); | ||
if (payload.nbf) | ||
validators.validateTimestamp(payload.nbf); | ||
if (payload.exp) | ||
validators.validateTimestamp(payload.exp); | ||
} | ||
exports.validateJwtCredentialPayload = validateJwtCredentialPayload; | ||
function validateCredentialPayload(payload) { | ||
validators.validateContext(payload['@context']); | ||
validators.validateVcType(payload.type); | ||
validators.validateCredentialSubject(payload.credentialSubject); | ||
if (payload.issuanceDate) | ||
validators.validateTimestamp(payload.issuanceDate); | ||
if (payload.expirationDate) | ||
validators.validateTimestamp(payload.expirationDate); | ||
} | ||
exports.validateCredentialPayload = validateCredentialPayload; | ||
function validateJwtPresentationPayload(payload) { | ||
var e_1, _a; | ||
validators.validateContext(payload.vp['@context']); | ||
validators.validateVpType(payload.vp.type); | ||
if (payload.vp.verifiableCredential.length < 1) { | ||
throw new TypeError('vp.verifiableCredential must not be empty'); | ||
} | ||
try { | ||
for (var _b = __values(converters_1.asArray(payload.vp.verifiableCredential)), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var vc = _c.value; | ||
if (typeof vc === 'string') { | ||
validators.validateJwtFormat(vc); | ||
} | ||
else { | ||
validateCredentialPayload(vc); | ||
} | ||
try { | ||
for (var _b = __values(converters_1.asArray(payload.vp.verifiableCredential)), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var vc = _c.value; | ||
if (typeof vc === 'string') { | ||
validators.validateJwtFormat(vc); | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b); | ||
else { | ||
validateCredentialPayload(vc); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
if (payload.exp) | ||
validators.validateTimestamp(payload.exp); | ||
} | ||
exports.validateJwtPresentationPayload = validateJwtPresentationPayload; | ||
function validatePresentationPayload(payload) { | ||
var e_2, _a; | ||
validators.validateContext(payload['@context']); | ||
validators.validateVpType(payload.type); | ||
if (payload.verifiableCredential.length < 1) { | ||
throw new TypeError('vp.verifiableCredential must not be empty'); | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
for (var _b = __values(payload.verifiableCredential), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var vc = _c.value; | ||
if (typeof vc === 'string') { | ||
validators.validateJwtFormat(vc); | ||
} | ||
else { | ||
validateCredentialPayload(vc); | ||
} | ||
} | ||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b); | ||
} | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
finally { | ||
try { | ||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b); | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
if (payload.exp) | ||
validators.validateTimestamp(payload.exp); | ||
} | ||
exports.validateJwtPresentationPayload = validateJwtPresentationPayload; | ||
function validatePresentationPayload(payload) { | ||
var e_2, _a; | ||
validators.validateContext(payload['@context']); | ||
validators.validateVpType(payload.type); | ||
if (payload.verifiableCredential.length < 1) { | ||
throw new TypeError('vp.verifiableCredential must not be empty'); | ||
} | ||
try { | ||
for (var _b = __values(payload.verifiableCredential), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var vc = _c.value; | ||
if (typeof vc === 'string') { | ||
validators.validateJwtFormat(vc); | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
else { | ||
validateCredentialPayload(vc); | ||
} | ||
} | ||
if (payload.expirationDate) | ||
validators.validateTimestamp(payload.expirationDate); | ||
} | ||
exports.validatePresentationPayload = validatePresentationPayload; | ||
/** | ||
* Verifies and validates a VerifiableCredential that is encoded as a JWT according to the W3C spec. | ||
* | ||
* @return a `Promise` that resolves to a `VerifiedCredential` or rejects with `TypeError` if the input is not | ||
* W3C compliant | ||
* @param vc the credential to be verified. Currently only the JWT encoding is supported by this library | ||
* @param resolver a configured `Resolver` that can provide the DID document of the JWT issuer | ||
*/ | ||
function verifyCredential(vc, resolver) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var verified; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, did_jwt_1.verifyJWT(vc, { resolver: resolver })]; | ||
case 1: | ||
verified = _a.sent(); | ||
verified.verifiableCredential = converters_1.normalizeCredential(verified.jwt); | ||
validateCredentialPayload(verified.verifiableCredential); | ||
return [2 /*return*/, verified]; | ||
} | ||
}); | ||
}); | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
finally { | ||
try { | ||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b); | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
} | ||
exports.verifyCredential = verifyCredential; | ||
/** | ||
* Verifies and validates a VerifiablePresentation that is encoded as a JWT according to the W3C spec. | ||
* | ||
* @return a `Promise` that resolves to a `VerifiedPresentation` or rejects with `TypeError` if the input is | ||
* not W3C compliant | ||
* @param presentation the presentation to be verified. Currently only the JWT encoding is supported by this library | ||
* @param resolver a configured `Resolver` that can provide the DID document of the JWT issuer (presentation holder) | ||
*/ | ||
function verifyPresentation(presentation, resolver) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var verified; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, did_jwt_1.verifyJWT(presentation, { resolver: resolver })]; | ||
case 1: | ||
verified = _a.sent(); | ||
verified.verifiablePresentation = converters_1.normalizePresentation(verified.jwt); | ||
validatePresentationPayload(verified.verifiablePresentation); | ||
return [2 /*return*/, verified]; | ||
} | ||
}); | ||
if (payload.expirationDate) | ||
validators.validateTimestamp(payload.expirationDate); | ||
} | ||
exports.validatePresentationPayload = validatePresentationPayload; | ||
/** | ||
* Verifies and validates a VerifiableCredential that is encoded as a JWT according to the W3C spec. | ||
* | ||
* @return a `Promise` that resolves to a `VerifiedCredential` or rejects with `TypeError` if the input is not | ||
* W3C compliant | ||
* @param vc the credential to be verified. Currently only the JWT encoding is supported by this library | ||
* @param resolver a configured `Resolver` that can provide the DID document of the JWT issuer | ||
*/ | ||
function verifyCredential(vc, resolver) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var verified; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, did_jwt_1.verifyJWT(vc, { resolver: resolver })]; | ||
case 1: | ||
verified = _a.sent(); | ||
verified.verifiableCredential = converters_1.normalizeCredential(verified.jwt); | ||
validateCredentialPayload(verified.verifiableCredential); | ||
return [2 /*return*/, verified]; | ||
} | ||
}); | ||
} | ||
exports.verifyPresentation = verifyPresentation; | ||
}); | ||
}); | ||
} | ||
exports.verifyCredential = verifyCredential; | ||
/** | ||
* Verifies and validates a VerifiablePresentation that is encoded as a JWT according to the W3C spec. | ||
* | ||
* @return a `Promise` that resolves to a `VerifiedPresentation` or rejects with `TypeError` if the input is | ||
* not W3C compliant | ||
* @param presentation the presentation to be verified. Currently only the JWT encoding is supported by this library | ||
* @param resolver a configured `Resolver` that can provide the DID document of the JWT issuer (presentation holder) | ||
*/ | ||
function verifyPresentation(presentation, resolver) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var verified; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, did_jwt_1.verifyJWT(presentation, { resolver: resolver })]; | ||
case 1: | ||
verified = _a.sent(); | ||
verified.verifiablePresentation = converters_1.normalizePresentation(verified.jwt); | ||
validatePresentationPayload(verified.verifiablePresentation); | ||
return [2 /*return*/, verified]; | ||
} | ||
}); | ||
}); | ||
} | ||
exports.verifyPresentation = verifyPresentation; | ||
//# sourceMappingURL=index.js.map |
@@ -1,13 +0,3 @@ | ||
(function (factory) { | ||
if (typeof module === "object" && typeof module.exports === "object") { | ||
var v = factory(require, exports); | ||
if (v !== undefined) module.exports = v; | ||
} | ||
else if (typeof define === "function" && define.amd) { | ||
define(["require", "exports"], factory); | ||
} | ||
})(function (require, exports) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
}); | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
//# sourceMappingURL=types.js.map |
@@ -1,73 +0,63 @@ | ||
(function (factory) { | ||
if (typeof module === "object" && typeof module.exports === "object") { | ||
var v = factory(require, exports); | ||
if (v !== undefined) module.exports = v; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.validateCredentialSubject = exports.validateVpType = exports.validateVcType = exports.validateContext = exports.validateTimestamp = exports.validateJwtFormat = void 0; | ||
var constants_1 = require("./constants"); | ||
var converters_1 = require("./converters"); | ||
function isDateObject(input) { | ||
return input && Object.prototype.toString.call(input) === '[object Date]' && !isNaN(input); | ||
} | ||
function validateJwtFormat(value) { | ||
if (typeof value === 'string' && !value.match(constants_1.JWT_FORMAT)) { | ||
throw new TypeError("\"" + value + "\" is not a valid JWT format"); | ||
} | ||
else if (typeof define === "function" && define.amd) { | ||
define(["require", "exports", "./constants", "./converters"], factory); | ||
} | ||
exports.validateJwtFormat = validateJwtFormat; | ||
// The main scenario we want to guard against is having a timestamp in milliseconds | ||
// instead of seconds (ex: from new Date().getTime()). | ||
// We will check the number of digits and assume that any number with 12 or more | ||
// digits is a millisecond timestamp. | ||
// 10 digits max is 9999999999 -> 11/20/2286 @ 5:46pm (UTC) | ||
// 11 digits max is 99999999999 -> 11/16/5138 @ 9:46am (UTC) | ||
// 12 digits max is 999999999999 -> 09/27/33658 @ 1:46am (UTC) | ||
function validateTimestamp(value) { | ||
if (typeof value === 'number') { | ||
if (!(Number.isInteger(value) && value < 100000000000)) { | ||
throw new TypeError("\"" + value + "\" is not a unix timestamp in seconds"); | ||
} | ||
} | ||
})(function (require, exports) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.validateCredentialSubject = exports.validateVpType = exports.validateVcType = exports.validateContext = exports.validateTimestamp = exports.validateJwtFormat = void 0; | ||
var constants_1 = require("./constants"); | ||
var converters_1 = require("./converters"); | ||
function isDateObject(input) { | ||
return input && Object.prototype.toString.call(input) === '[object Date]' && !isNaN(input); | ||
else if (typeof value === 'string') { | ||
validateTimestamp(Math.floor(new Date(value).valueOf() / 1000)); | ||
} | ||
function validateJwtFormat(value) { | ||
if (typeof value === 'string' && !value.match(constants_1.JWT_FORMAT)) { | ||
throw new TypeError("\"" + value + "\" is not a valid JWT format"); | ||
} | ||
else if (!isDateObject(value)) { | ||
throw new TypeError("\"" + value + "\" is not a valid time"); | ||
} | ||
exports.validateJwtFormat = validateJwtFormat; | ||
// The main scenario we want to guard against is having a timestamp in milliseconds | ||
// instead of seconds (ex: from new Date().getTime()). | ||
// We will check the number of digits and assume that any number with 12 or more | ||
// digits is a millisecond timestamp. | ||
// 10 digits max is 9999999999 -> 11/20/2286 @ 5:46pm (UTC) | ||
// 11 digits max is 99999999999 -> 11/16/5138 @ 9:46am (UTC) | ||
// 12 digits max is 999999999999 -> 09/27/33658 @ 1:46am (UTC) | ||
function validateTimestamp(value) { | ||
if (typeof value === 'number') { | ||
if (!(Number.isInteger(value) && value < 100000000000)) { | ||
throw new TypeError("\"" + value + "\" is not a unix timestamp in seconds"); | ||
} | ||
} | ||
else if (typeof value === 'string') { | ||
validateTimestamp(Math.floor(new Date(value).valueOf() / 1000)); | ||
} | ||
else if (!isDateObject(value)) { | ||
throw new TypeError("\"" + value + "\" is not a valid time"); | ||
} | ||
} | ||
exports.validateTimestamp = validateTimestamp; | ||
function validateContext(value) { | ||
var input = converters_1.asArray(value); | ||
if (input.length < 1 || input.indexOf(constants_1.DEFAULT_CONTEXT) === -1) { | ||
throw new TypeError("@context is missing default context \"" + constants_1.DEFAULT_CONTEXT + "\""); | ||
} | ||
exports.validateTimestamp = validateTimestamp; | ||
function validateContext(value) { | ||
var input = converters_1.asArray(value); | ||
if (input.length < 1 || input.indexOf(constants_1.DEFAULT_CONTEXT) === -1) { | ||
throw new TypeError("@context is missing default context \"" + constants_1.DEFAULT_CONTEXT + "\""); | ||
} | ||
} | ||
exports.validateContext = validateContext; | ||
function validateVcType(value) { | ||
var input = converters_1.asArray(value); | ||
if (input.length < 1 || input.indexOf(constants_1.DEFAULT_VC_TYPE) === -1) { | ||
throw new TypeError("type is missing default \"" + constants_1.DEFAULT_VC_TYPE + "\""); | ||
} | ||
exports.validateContext = validateContext; | ||
function validateVcType(value) { | ||
var input = converters_1.asArray(value); | ||
if (input.length < 1 || input.indexOf(constants_1.DEFAULT_VC_TYPE) === -1) { | ||
throw new TypeError("type is missing default \"" + constants_1.DEFAULT_VC_TYPE + "\""); | ||
} | ||
} | ||
exports.validateVcType = validateVcType; | ||
function validateVpType(value) { | ||
var input = converters_1.asArray(value); | ||
if (input.length < 1 || input.indexOf(constants_1.DEFAULT_VP_TYPE) === -1) { | ||
throw new TypeError("type is missing default \"" + constants_1.DEFAULT_VP_TYPE + "\""); | ||
} | ||
exports.validateVcType = validateVcType; | ||
function validateVpType(value) { | ||
var input = converters_1.asArray(value); | ||
if (input.length < 1 || input.indexOf(constants_1.DEFAULT_VP_TYPE) === -1) { | ||
throw new TypeError("type is missing default \"" + constants_1.DEFAULT_VP_TYPE + "\""); | ||
} | ||
} | ||
exports.validateVpType = validateVpType; | ||
function validateCredentialSubject(value) { | ||
if (Object.keys(value).length === 0) { | ||
throw new TypeError('credentialSubject must not be empty'); | ||
} | ||
exports.validateVpType = validateVpType; | ||
function validateCredentialSubject(value) { | ||
if (Object.keys(value).length === 0) { | ||
throw new TypeError('credentialSubject must not be empty'); | ||
} | ||
} | ||
exports.validateCredentialSubject = validateCredentialSubject; | ||
}); | ||
} | ||
exports.validateCredentialSubject = validateCredentialSubject; | ||
//# sourceMappingURL=validators.js.map |
{ | ||
"name": "did-jwt-vc", | ||
"version": "1.0.3", | ||
"version": "1.0.4", | ||
"description": "Create and verify W3C Verifiable Credentials and Presentations in JWT format", | ||
@@ -58,4 +58,4 @@ "main": "lib/index.js", | ||
"@types/faker": "4.1.12", | ||
"@types/jest": "26.0.3", | ||
"codecov": "3.7.0", | ||
"@types/jest": "26.0.5", | ||
"codecov": "3.7.1", | ||
"did-resolver": "2.0.1", | ||
@@ -67,8 +67,8 @@ "ethr-did": "1.1.0", | ||
"semantic-release": "17.1.1", | ||
"ts-jest": "26.1.1", | ||
"ts-jest": "26.1.3", | ||
"tslint": "6.1.2", | ||
"tslint-config-prettier": "1.18.0", | ||
"tslint-eslint-rules": "5.4.0", | ||
"typescript": "3.9.6" | ||
"typescript": "3.9.7" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
202096
3251