did-jwt-vc
Advanced tools
Comparing version 2.0.2 to 2.1.0
@@ -0,1 +1,8 @@ | ||
# [2.1.0](https://github.com/decentralized-identity/did-jwt-vc/compare/2.0.2...2.1.0) (2021-04-08) | ||
### Features | ||
* add ability to add to the JWT header of the VC/VP ([#71](https://github.com/decentralized-identity/did-jwt-vc/issues/71)) ([79d2d76](https://github.com/decentralized-identity/did-jwt-vc/commit/79d2d7696a5e929a574d2e0671fc1258f768e90e)), closes [#69](https://github.com/decentralized-identity/did-jwt-vc/issues/69) | ||
## [2.0.2](https://github.com/decentralized-identity/did-jwt-vc/compare/2.0.1...2.0.2) (2021-03-26) | ||
@@ -2,0 +9,0 @@ |
@@ -125,6 +125,7 @@ "use strict"; | ||
function createVerifiableCredentialJwt(payload, issuer, options) { | ||
var _a; | ||
if (options === void 0) { options = {}; } | ||
return __awaiter(this, void 0, void 0, function () { | ||
var parsedPayload; | ||
return __generator(this, function (_a) { | ||
return __generator(this, function (_b) { | ||
parsedPayload = __assign({ iat: undefined }, converters_1.transformCredentialInput(payload, options.removeOriginalFields)); | ||
@@ -134,5 +135,4 @@ validateJwtCredentialPayload(parsedPayload); | ||
issuer: issuer.did || parsedPayload.iss, | ||
signer: issuer.signer, | ||
alg: issuer.alg || constants_1.JWT_ALG | ||
})]; | ||
signer: issuer.signer | ||
}, __assign(__assign({}, options.header), { alg: issuer.alg || ((_a = options.header) === null || _a === void 0 ? void 0 : _a.alg) || constants_1.JWT_ALG }))]; | ||
}); | ||
@@ -158,6 +158,7 @@ }); | ||
function createVerifiablePresentationJwt(payload, holder, options) { | ||
var _a; | ||
if (options === void 0) { options = {}; } | ||
return __awaiter(this, void 0, void 0, function () { | ||
var parsedPayload, audience; | ||
return __generator(this, function (_a) { | ||
return __generator(this, function (_b) { | ||
parsedPayload = __assign({ iat: undefined }, converters_1.transformPresentationInput(payload, options === null || options === void 0 ? void 0 : options.removeOriginalFields)); | ||
@@ -176,5 +177,4 @@ // add challenge to nonce | ||
issuer: holder.did || parsedPayload.iss, | ||
signer: holder.signer, | ||
alg: holder.alg || constants_1.JWT_ALG | ||
})]; | ||
signer: holder.signer | ||
}, __assign(__assign({}, options.header), { alg: holder.alg || ((_a = options.header) === null || _a === void 0 ? void 0 : _a.alg) || constants_1.JWT_ALG }))]; | ||
}); | ||
@@ -181,0 +181,0 @@ }); |
@@ -1,2 +0,2 @@ | ||
import { Signer, JWTVerified } from 'did-jwt'; | ||
import { Signer, JWTVerified, JWTHeader } from 'did-jwt'; | ||
export interface JwtCredentialSubject { | ||
@@ -190,3 +190,14 @@ [x: string]: any; | ||
export interface CreateCredentialOptions { | ||
/** | ||
* Determines whether the JSON->JWT transformation will remove the original fields from the input payload. | ||
* See https://www.w3.org/TR/vc-data-model/#jwt-encoding | ||
* | ||
* @default true | ||
*/ | ||
removeOriginalFields?: boolean; | ||
/** | ||
* Allows including or overriding some header parameters for the resulting JWT. | ||
* If the issuer or holder does not list an `alg`, then the one specified in `header` will be used | ||
*/ | ||
header?: Partial<JWTHeader>; | ||
[x: string]: any; | ||
@@ -193,0 +204,0 @@ } |
{ | ||
"name": "did-jwt-vc", | ||
"version": "2.0.2", | ||
"version": "2.1.0", | ||
"description": "Create and verify W3C Verifiable Credentials and Presentations in JWT format", | ||
@@ -58,8 +58,8 @@ "main": "lib/index.js", | ||
"@semantic-release/git": "9.0.0", | ||
"@types/faker": "5.1.7", | ||
"@types/faker": "5.5.0", | ||
"@types/jest": "26.0.22", | ||
"@types/node": "14.14.36", | ||
"@types/node": "14.14.37", | ||
"codecov": "3.8.1", | ||
"ethr-did": "1.3.0", | ||
"faker": "5.5.0", | ||
"faker": "5.5.2", | ||
"jest": "26.6.3", | ||
@@ -72,4 +72,4 @@ "prettier": "2.2.1", | ||
"tslint-eslint-rules": "5.4.0", | ||
"typescript": "4.2.3" | ||
"typescript": "4.2.4" | ||
} | ||
} |
@@ -47,3 +47,3 @@ import EthrDID from 'ethr-did' | ||
const did = (new EthrDID({ | ||
const ethrDidIssuer = (new EthrDID({ | ||
address: '0xf1232f840f3ad7d23fcdaa84d6c66dac24efb198', | ||
@@ -99,5 +99,6 @@ privateKey: 'd8b595680851765f38ea5405129244ba3cbad84467d190859f4c8b20c1ff6c75' | ||
describe('createVerifiableCredential', () => { | ||
const issuer = ethrDidIssuer | ||
it('creates a valid Verifiable Credential JWT with required fields', async () => { | ||
expect.assertions(1) | ||
const vcJwt = await createVerifiableCredentialJwt(verifiableCredentialPayload, did) | ||
const vcJwt = await createVerifiableCredentialJwt(verifiableCredentialPayload, issuer) | ||
const decodedVc = await decodeJWT(vcJwt) | ||
@@ -109,3 +110,3 @@ const { iat, ...payload } = decodedVc.payload | ||
expect.assertions(1) | ||
const vcJwt = await createVerifiableCredentialJwt({ ...verifiableCredentialPayload, extra: 42 }, did) | ||
const vcJwt = await createVerifiableCredentialJwt({ ...verifiableCredentialPayload, extra: 42 }, issuer) | ||
const decodedVc = await decodeJWT(vcJwt) | ||
@@ -115,5 +116,20 @@ const { iat, ...payload } = decodedVc.payload | ||
}) | ||
it('creates a Verifiable Credential JWT with custom JWT alg', async () => { | ||
expect.assertions(1) | ||
const customIssuer = { ...issuer, alg: 'ES256K-R' } | ||
const vcJwt = await createVerifiableCredentialJwt({ ...verifiableCredentialPayload, extra: 42 }, customIssuer) | ||
const decodedVc = await decodeJWT(vcJwt) | ||
expect(decodedVc.header).toEqual({ alg: 'ES256K-R', typ: 'JWT' }) | ||
}) | ||
it('creates a Verifiable Credential JWT with custom JWT header fields', async () => { | ||
expect.assertions(1) | ||
const vcJwt = await createVerifiableCredentialJwt({ ...verifiableCredentialPayload, extra: 42 }, issuer, { | ||
header: { alg: 'ES256K-R', custom: 'field' } | ||
}) | ||
const decodedVc = await decodeJWT(vcJwt) | ||
expect(decodedVc.header).toEqual({ alg: 'ES256K-R', custom: 'field', typ: 'JWT' }) | ||
}) | ||
it('calls functions to validate required fields', async () => { | ||
expect.assertions(4) | ||
await createVerifiableCredentialJwt(verifiableCredentialPayload, did) | ||
await createVerifiableCredentialJwt(verifiableCredentialPayload, issuer) | ||
expect(mockValidateTimestamp).toHaveBeenCalledWith(verifiableCredentialPayload.nbf) | ||
@@ -127,3 +143,3 @@ expect(mockValidateContext).toHaveBeenCalledWith(verifiableCredentialPayload.vc['@context']) | ||
const timestamp = Math.floor(new Date().getTime()) | ||
await createVerifiableCredentialJwt({ ...verifiableCredentialPayload, exp: timestamp }, did) | ||
await createVerifiableCredentialJwt({ ...verifiableCredentialPayload, exp: timestamp }, issuer) | ||
expect(mockValidateTimestamp).toHaveBeenCalledWith(timestamp) | ||
@@ -134,5 +150,7 @@ }) | ||
describe('createPresentation', () => { | ||
const holder = ethrDidIssuer | ||
it('creates a valid Presentation JWT with required fields', async () => { | ||
expect.assertions(1) | ||
const presentationJwt = await createVerifiablePresentationJwt(presentationPayload, did) | ||
const presentationJwt = await createVerifiablePresentationJwt(presentationPayload, holder) | ||
const decodedPresentation = await decodeJWT(presentationJwt) | ||
@@ -145,3 +163,3 @@ const { iat, ...payload } = decodedPresentation.payload | ||
expect.assertions(2) | ||
const presentationJwt = await createVerifiablePresentationJwt({ ...presentationPayload, extra: 42 }, did) | ||
const presentationJwt = await createVerifiablePresentationJwt({ ...presentationPayload, extra: 42 }, holder) | ||
const decodedPresentation = await decodeJWT(presentationJwt) | ||
@@ -159,3 +177,7 @@ const { iat, ...payload } = decodedPresentation.payload | ||
const presentationJwt = await createVerifiablePresentationJwt({ ...presentationPayload, extra: 42 }, did, options) | ||
const presentationJwt = await createVerifiablePresentationJwt( | ||
{ ...presentationPayload, extra: 42 }, | ||
holder, | ||
options | ||
) | ||
const decodedPresentation = await decodeJWT(presentationJwt) | ||
@@ -177,3 +199,3 @@ const { iat, ...payload } = decodedPresentation.payload | ||
{ ...presentationPayload, aud: ['EXISTING_AUD'] }, | ||
did, | ||
holder, | ||
options | ||
@@ -194,3 +216,7 @@ ) | ||
const presentationJwt = await createVerifiablePresentationJwt({ ...presentationPayload, extra: 42 }, did, options) | ||
const presentationJwt = await createVerifiablePresentationJwt( | ||
{ ...presentationPayload, extra: 42 }, | ||
holder, | ||
options | ||
) | ||
const decodedPresentation = await decodeJWT(presentationJwt) | ||
@@ -204,2 +230,32 @@ const { iat, ...payload } = decodedPresentation.payload | ||
it('creates a Presentation JWT with custom holder alg', async () => { | ||
const customHolder = { ...holder, alg: 'ES256K-R' } | ||
expect.assertions(1) | ||
const presentationJwt = await createVerifiablePresentationJwt({ ...presentationPayload, extra: 42 }, customHolder) | ||
const decodedPresentation = await decodeJWT(presentationJwt) | ||
expect(decodedPresentation.header).toEqual({ alg: 'ES256K-R', typ: 'JWT' }) | ||
}) | ||
it('creates a Presentation JWT with custom header options', async () => { | ||
expect.assertions(1) | ||
const options: CreatePresentationOptions = { | ||
header: { | ||
alg: 'ES256K-R', | ||
custom: 'field' | ||
} | ||
} | ||
const presentationJwt = await createVerifiablePresentationJwt( | ||
{ ...presentationPayload, extra: 42 }, | ||
holder, | ||
options | ||
) | ||
const decodedPresentation = await decodeJWT(presentationJwt) | ||
expect(decodedPresentation.header).toEqual({ | ||
alg: 'ES256K-R', | ||
custom: 'field', | ||
typ: 'JWT' | ||
}) | ||
}) | ||
it('creates a valid Presentation JWT and does not overwrite an existing nonce property', async () => { | ||
@@ -213,3 +269,3 @@ expect.assertions(3) | ||
{ ...presentationPayload, nonce: 'EXISTING_NONCE' }, | ||
did, | ||
holder, | ||
options | ||
@@ -226,3 +282,3 @@ ) | ||
expect.assertions(2 + presentationPayload.vp.verifiableCredential.length) | ||
await createVerifiablePresentationJwt(presentationPayload, did) | ||
await createVerifiablePresentationJwt(presentationPayload, holder) | ||
expect(mockValidateContext).toHaveBeenCalledWith(presentationPayload.vp['@context']) | ||
@@ -246,3 +302,3 @@ expect(mockValidateVpType).toHaveBeenCalledWith(presentationPayload.vp.type) | ||
}, | ||
did | ||
holder | ||
) | ||
@@ -259,3 +315,3 @@ ).rejects.toThrow(TypeError) | ||
}, | ||
did | ||
holder | ||
) | ||
@@ -262,0 +318,0 @@ expect(mockValidateTimestamp).toHaveBeenCalledWith(timestamp) |
@@ -75,7 +75,13 @@ import { createJWT, verifyJWT } from 'did-jwt' | ||
validateJwtCredentialPayload(parsedPayload) | ||
return createJWT(parsedPayload, { | ||
issuer: issuer.did || parsedPayload.iss, | ||
signer: issuer.signer, | ||
alg: issuer.alg || JWT_ALG | ||
}) | ||
return createJWT( | ||
parsedPayload, | ||
{ | ||
issuer: issuer.did || parsedPayload.iss, | ||
signer: issuer.signer | ||
}, | ||
{ | ||
...options.header, | ||
alg: issuer.alg || options.header?.alg || JWT_ALG | ||
} | ||
) | ||
} | ||
@@ -120,7 +126,13 @@ | ||
validateJwtPresentationPayload(parsedPayload) | ||
return createJWT(parsedPayload, { | ||
issuer: holder.did || parsedPayload.iss, | ||
signer: holder.signer, | ||
alg: holder.alg || JWT_ALG | ||
}) | ||
return createJWT( | ||
parsedPayload, | ||
{ | ||
issuer: holder.did || parsedPayload.iss, | ||
signer: holder.signer | ||
}, | ||
{ | ||
...options.header, | ||
alg: holder.alg || options.header?.alg || JWT_ALG | ||
} | ||
) | ||
} | ||
@@ -127,0 +139,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { Signer, JWTVerified } from 'did-jwt' | ||
import { Signer, JWTVerified, JWTHeader } from 'did-jwt' | ||
@@ -205,3 +205,16 @@ export interface JwtCredentialSubject { | ||
export interface CreateCredentialOptions { | ||
/** | ||
* Determines whether the JSON->JWT transformation will remove the original fields from the input payload. | ||
* See https://www.w3.org/TR/vc-data-model/#jwt-encoding | ||
* | ||
* @default true | ||
*/ | ||
removeOriginalFields?: boolean | ||
/** | ||
* Allows including or overriding some header parameters for the resulting JWT. | ||
* If the issuer or holder does not list an `alg`, then the one specified in `header` will be used | ||
*/ | ||
header?: Partial<JWTHeader> | ||
[x: string]: any | ||
@@ -208,0 +221,0 @@ } |
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
256461
4219