Comparing version 0.0.5 to 0.0.6
@@ -30,3 +30,3 @@ 'use strict'; | ||
var NOW = 1485321133; | ||
_mockdate2.default.set(NOW * 1000); | ||
_mockdate2.default.set(NOW * 1000 + 123); | ||
@@ -73,2 +73,3 @@ var audMnid = '2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqY'; | ||
return (0, _JWT.createJWT)({ requested: ['name', 'phone'] }, { issuer: did, signer: signer }).then(function (jwt) { | ||
console.log(verifier.verify(jwt)); | ||
return expect(verifier.verify(jwt)).toBeTruthy(); | ||
@@ -222,3 +223,3 @@ }); | ||
it('accepts a valid exp', function () { | ||
return (0, _JWT.createJWT)({ exp: NOW + 1 }, { issuer: did, signer: signer, expiresIn: 1 }).then(function (jwt) { | ||
return (0, _JWT.createJWT)({ exp: NOW - _JWT.IAT_SKEW + 1 }, { issuer: did, signer: signer, expiresIn: 1 }).then(function (jwt) { | ||
return (0, _JWT.verifyJWT)(jwt).then(function (_ref9) { | ||
@@ -232,5 +233,5 @@ var payload = _ref9.payload; | ||
it('rejects an expired JWT', function () { | ||
return (0, _JWT.createJWT)({ exp: NOW - 1 }, { issuer: did, signer: signer }).then(function (jwt) { | ||
return (0, _JWT.createJWT)({ exp: NOW - _JWT.IAT_SKEW - 1 }, { issuer: did, signer: signer }).then(function (jwt) { | ||
return (0, _JWT.verifyJWT)(jwt).catch(function (error) { | ||
return expect(error.message).toEqual('JWT has expired: exp: 1485321132 < now: 1485321133'); | ||
return expect(error.message).toEqual('JWT has expired: exp: 1485321072 < now: 1485321133'); | ||
}).then(function (p) { | ||
@@ -251,6 +252,15 @@ return expect(p).toBeFalsy(); | ||
it('accepts a valid MNID audience', function () { | ||
return (0, _JWT.createJWT)({ aud: aud }, { issuer: did, signer: signer }).then(function (jwt) { | ||
return (0, _JWT.verifyJWT)(jwt, { audience: audMnid }).then(function (_ref11) { | ||
var payload = _ref11.payload; | ||
return expect(payload).toMatchSnapshot(); | ||
}); | ||
}); | ||
}); | ||
it('accepts a valid audience using callback_url', function () { | ||
return (0, _JWT.createJWT)({ aud: 'http://pututu.uport.me/unique' }, { issuer: did, signer: signer }).then(function (jwt) { | ||
return (0, _JWT.verifyJWT)(jwt, { callbackUrl: 'http://pututu.uport.me/unique' }).then(function (_ref11) { | ||
var payload = _ref11.payload; | ||
return (0, _JWT.verifyJWT)(jwt, { callbackUrl: 'http://pututu.uport.me/unique' }).then(function (_ref12) { | ||
var payload = _ref12.payload; | ||
return expect(payload).toMatchSnapshot(); | ||
@@ -257,0 +267,0 @@ }); |
@@ -115,3 +115,3 @@ 'use strict'; | ||
* @example | ||
* verifyJWT('did:uport:eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJyZXF1Z....', {aud: '5A8bRWU3F7j3REx3vkJ...', callbackUrl: 'https://...}).then(obj => { | ||
* verifyJWT('did:uport:eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJyZXF1Z....', {audience: '5A8bRWU3F7j3REx3vkJ...', callbackUrl: 'https://...}).then(obj => { | ||
const did = obj.did // DID of signer | ||
@@ -128,4 +128,4 @@ * const payload = obj.payload | ||
* @param {Boolean} config.auth Require signer to be listed in the authentication section of the DID document (for Authentication purposes) | ||
* @param {String} config.aud DID of the recipient of the JWT | ||
* @param {String} config.callbackUrl callback url in JWT | ||
* @param {String} config.audience DID of the recipient of the JWT | ||
* @param {String} config.callbackUrl callback url in JWT | ||
* @return {Promise<Object, Error>} a promise which resolves with a response object or rejects with an error | ||
@@ -139,3 +139,3 @@ */ | ||
var aud, _decodeJWT, payload, header, signature, data, _ref4, doc, authenticators, issuer, signer; | ||
var aud, _decodeJWT, payload, header, signature, data, _ref4, doc, authenticators, issuer, signer, now; | ||
@@ -157,31 +157,32 @@ return _regenerator2.default.wrap(function _callee2$(_context2) { | ||
signer = (0, _VerifierAlgorithm2.default)(header.alg)(data, signature, authenticators); | ||
now = Math.floor(Date.now() / 1000); | ||
if (!signer) { | ||
_context2.next = 29; | ||
_context2.next = 30; | ||
break; | ||
} | ||
if (!(payload.iat && payload.iat > Date.now() / 1000 + IAT_SKEW)) { | ||
_context2.next = 12; | ||
if (!(payload.iat && payload.iat > now + IAT_SKEW)) { | ||
_context2.next = 13; | ||
break; | ||
} | ||
throw new Error('JWT not valid yet (issued in the future): iat: ' + payload.iat + ' > now: ' + Date.now() / 1000); | ||
throw new Error('JWT not valid yet (issued in the future): iat: ' + payload.iat + ' > now: ' + now); | ||
case 12: | ||
if (!(payload.exp && payload.exp <= Date.now() / 1000)) { | ||
_context2.next = 14; | ||
case 13: | ||
if (!(payload.exp && payload.exp <= now - IAT_SKEW)) { | ||
_context2.next = 15; | ||
break; | ||
} | ||
throw new Error('JWT has expired: exp: ' + payload.exp + ' < now: ' + Date.now() / 1000); | ||
throw new Error('JWT has expired: exp: ' + payload.exp + ' < now: ' + now); | ||
case 14: | ||
case 15: | ||
if (!payload.aud) { | ||
_context2.next = 26; | ||
_context2.next = 27; | ||
break; | ||
} | ||
if (!payload.aud.match(/^did:/)) { | ||
_context2.next = 22; | ||
if (!isDIDOrMNID(payload.aud)) { | ||
_context2.next = 23; | ||
break; | ||
@@ -191,3 +192,3 @@ } | ||
if (aud) { | ||
_context2.next = 18; | ||
_context2.next = 19; | ||
break; | ||
@@ -198,5 +199,5 @@ } | ||
case 18: | ||
if (!(aud !== payload.aud)) { | ||
_context2.next = 20; | ||
case 19: | ||
if (!(aud !== normalizeDID(payload.aud))) { | ||
_context2.next = 21; | ||
break; | ||
@@ -207,9 +208,9 @@ } | ||
case 20: | ||
_context2.next = 26; | ||
case 21: | ||
_context2.next = 27; | ||
break; | ||
case 22: | ||
case 23: | ||
if (options.callbackUrl) { | ||
_context2.next = 24; | ||
_context2.next = 25; | ||
break; | ||
@@ -220,5 +221,5 @@ } | ||
case 24: | ||
case 25: | ||
if (!(payload.aud !== options.callbackUrl)) { | ||
_context2.next = 26; | ||
_context2.next = 27; | ||
break; | ||
@@ -229,6 +230,6 @@ } | ||
case 26: | ||
case 27: | ||
return _context2.abrupt('return', { payload: payload, doc: doc, issuer: issuer, signer: signer, jwt: jwt }); | ||
case 29: | ||
case 30: | ||
case 'end': | ||
@@ -382,2 +383,6 @@ return _context2.stop(); | ||
function isDIDOrMNID(mnidOrDid) { | ||
return mnidOrDid && (mnidOrDid.match(/^did:/) || (0, _mnid.isMNID)(mnidOrDid)); | ||
} | ||
function normalizeDID(mnidOrDid) { | ||
@@ -384,0 +389,0 @@ if (mnidOrDid.match(/^did:/)) return mnidOrDid; |
{ | ||
"name": "did-jwt", | ||
"version": "0.0.5", | ||
"version": "0.0.6", | ||
"description": "Library for Signing and Verifying JWTs compatible uPort and DID standards", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -109,3 +109,3 @@ # did-jwt | ||
`options.auth` | Require signer to be listed in the authentication section of the DID document (for Authentication of a user with DID-AUTH) | ||
`options.aud` | The [DID](https://w3c-ccg.github.io/did-spec/#decentralized-identifiers-dids) of the audience of the JWT | no | ||
`options.audience` | The [DID](https://w3c-ccg.github.io/did-spec/#decentralized-identifiers-dids) of the audience of the JWT | no | ||
`options.callbackUrl` | The the URL receiving the JWT | no | ||
@@ -112,0 +112,0 @@ |
@@ -7,3 +7,3 @@ import { createJWT, verifyJWT, decodeJWT, resolveAuthenticator, IAT_SKEW } from '../JWT' | ||
const NOW = 1485321133 | ||
MockDate.set(NOW * 1000) | ||
MockDate.set(NOW * 1000 + 123) | ||
@@ -52,2 +52,3 @@ const audMnid = '2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqY' | ||
return createJWT({requested: ['name', 'phone']}, {issuer: did, signer}).then((jwt) => { | ||
console.log(verifier.verify(jwt)) | ||
return expect(verifier.verify(jwt)).toBeTruthy() | ||
@@ -168,3 +169,3 @@ }) | ||
it('accepts a valid exp', () => { | ||
return createJWT({exp: NOW + 1}, {issuer: did, signer, expiresIn: 1}).then(jwt => | ||
return createJWT({exp: NOW - IAT_SKEW + 1}, {issuer: did, signer, expiresIn: 1}).then(jwt => | ||
verifyJWT(jwt).then(({payload}) => | ||
@@ -177,5 +178,5 @@ expect(payload).toMatchSnapshot() | ||
it('rejects an expired JWT', () => { | ||
return createJWT({exp: NOW - 1}, {issuer: did, signer}).then(jwt => | ||
return createJWT({exp: NOW - IAT_SKEW - 1}, {issuer: did, signer}).then(jwt => | ||
verifyJWT(jwt).catch(error => | ||
expect(error.message).toEqual('JWT has expired: exp: 1485321132 < now: 1485321133') | ||
expect(error.message).toEqual('JWT has expired: exp: 1485321072 < now: 1485321133') | ||
).then((p) => expect(p).toBeFalsy()) | ||
@@ -191,2 +192,8 @@ ) | ||
it('accepts a valid MNID audience', () => { | ||
return createJWT({aud}, {issuer: did, signer}).then(jwt => | ||
verifyJWT(jwt, {audience: audMnid}).then(({payload}) => expect(payload).toMatchSnapshot()) | ||
) | ||
}) | ||
it('accepts a valid audience using callback_url', () => { | ||
@@ -193,0 +200,0 @@ return createJWT({ aud: 'http://pututu.uport.me/unique' }, {issuer: did, signer}).then(jwt => |
@@ -26,2 +26,6 @@ import { isMNID } from 'mnid' | ||
function isDIDOrMNID (mnidOrDid) { | ||
return mnidOrDid && (mnidOrDid.match(/^did:/) || isMNID(mnidOrDid)) | ||
} | ||
function normalizeDID (mnidOrDid) { | ||
@@ -89,3 +93,3 @@ if (mnidOrDid.match(/^did:/)) return mnidOrDid | ||
* @example | ||
* verifyJWT('did:uport:eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJyZXF1Z....', {aud: '5A8bRWU3F7j3REx3vkJ...', callbackUrl: 'https://...}).then(obj => { | ||
* verifyJWT('did:uport:eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJyZXF1Z....', {audience: '5A8bRWU3F7j3REx3vkJ...', callbackUrl: 'https://...}).then(obj => { | ||
const did = obj.did // DID of signer | ||
@@ -102,4 +106,4 @@ * const payload = obj.payload | ||
* @param {Boolean} config.auth Require signer to be listed in the authentication section of the DID document (for Authentication purposes) | ||
* @param {String} config.aud DID of the recipient of the JWT | ||
* @param {String} config.callbackUrl callback url in JWT | ||
* @param {String} config.audience DID of the recipient of the JWT | ||
* @param {String} config.callbackUrl callback url in JWT | ||
* @return {Promise<Object, Error>} a promise which resolves with a response object or rejects with an error | ||
@@ -112,11 +116,12 @@ */ | ||
const signer = VerifierAlgorithm(header.alg)(data, signature, authenticators) | ||
const now = Math.floor(Date.now() / 1000) | ||
if (signer) { | ||
if (payload.iat && payload.iat > (Date.now() / 1000 + IAT_SKEW)) { | ||
throw new Error(`JWT not valid yet (issued in the future): iat: ${payload.iat} > now: ${Date.now() / 1000}`) | ||
if (payload.iat && payload.iat > (now + IAT_SKEW)) { | ||
throw new Error(`JWT not valid yet (issued in the future): iat: ${payload.iat} > now: ${now}`) | ||
} | ||
if (payload.exp && (payload.exp <= Date.now() / 1000)) { | ||
throw new Error(`JWT has expired: exp: ${payload.exp} < now: ${Date.now() / 1000}`) | ||
if (payload.exp && (payload.exp <= (now - IAT_SKEW))) { | ||
throw new Error(`JWT has expired: exp: ${payload.exp} < now: ${now}`) | ||
} | ||
if (payload.aud) { | ||
if (payload.aud.match(/^did:/)) { | ||
if (isDIDOrMNID(payload.aud)) { | ||
if (!aud) { | ||
@@ -126,3 +131,3 @@ throw new Error('JWT audience is required but your app address has not been configured') | ||
if (aud !== payload.aud) { | ||
if (aud !== normalizeDID(payload.aud)) { | ||
throw new Error(`JWT audience does not match your DID: aud: ${payload.aud} !== yours: ${aud}`) | ||
@@ -129,0 +134,0 @@ } |
Sorry, the diff of this file is too big to display
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
598956
16698