oidc-provider
Advanced tools
Comparing version 0.8.2 to 0.9.0
Following semver, 1.0.0 will mark the first API stable release and commence of this file, | ||
until then please use the compare views of github for reference. | ||
- https://github.com/panva/node-oidc-provider/compare/v0.8.1...v0.9.0 | ||
- added: (no)cache headers according to specs | ||
- fix: consent_required error now returned when consent prompt is not resolved | ||
- fix: now validates payload of none-signed id_token_hints | ||
- fix: signed userinfo token expiration | ||
- fix: unsigned (when id_token_signed_response_alg is not defined, not when none) are now properly unsigned, jwe payload is the userinfo response, not a jwt | ||
- https://github.com/panva/node-oidc-provider/compare/v0.7.2...v0.8.1 | ||
@@ -5,0 +11,0 @@ - fixed a bug that allowed userinfo and idtoken encrypting clients to pass validation |
@@ -625,3 +625,3 @@ 'use strict'; | ||
return { | ||
error: 'interaction_required', | ||
error: missed === 'consent' ? 'consent_required' : 'interaction_required', | ||
error_description: `prompt ${missed} was not resolved`, | ||
@@ -655,3 +655,4 @@ reason: `${missed}_prompt`, | ||
} catch (err) { | ||
this.throw(new errors.InvalidRequestError('could not validate id_token_hint')); | ||
this.throw(new errors.InvalidRequestError( | ||
`could not validate id_token_hint (${err.message})`)); | ||
} | ||
@@ -658,0 +659,0 @@ |
@@ -7,3 +7,3 @@ 'use strict'; | ||
const crypto = require('crypto'); | ||
const uuid = require('node-uuid'); | ||
const uuid = require('uuid'); | ||
@@ -10,0 +10,0 @@ const noCache = require('../middlewares/no_cache'); |
'use strict'; | ||
const _ = require('lodash'); | ||
const uuid = require('node-uuid').v4; | ||
const uuid = require('uuid').v4; | ||
const assert = require('assert'); | ||
@@ -6,0 +6,0 @@ |
@@ -78,5 +78,36 @@ 'use strict'; | ||
static assertPayload(payload, options) { | ||
const timestamp = Math.ceil(Date.now() / 1000); | ||
const opts = options || /* istanbul ignore next */ {}; | ||
assert(typeof payload === 'object', | ||
'payload is not of JWT type (JSON serialized object)'); | ||
if (typeof payload.nbf !== 'undefined' && !opts.ignoreNotBefore) { | ||
assert(typeof payload.nbf === 'number', 'invalid nbf value'); | ||
assert(payload.nbf <= timestamp, 'jwt not active yet'); | ||
} | ||
if (typeof payload.iat !== 'undefined' && !opts.ignoreIssued) { | ||
assert(typeof payload.iat === 'number', 'invalid iat value'); | ||
assert(payload.iat <= timestamp, 'jwt issued in the future'); | ||
} | ||
if (typeof payload.exp !== 'undefined' && !opts.ignoreExpiration) { | ||
assert(typeof payload.exp === 'number', 'invalid exp value'); | ||
assert(timestamp < payload.exp, 'jwt expired'); | ||
} | ||
if (opts.audience) { | ||
verifyAudience(payload, Array.isArray(opts.audience) ? | ||
opts.audience : [opts.audience]); | ||
} | ||
if (opts.issuer) { | ||
assert(payload.iss === opts.issuer, `jwt issuer invalid. expected: ${opts.issuer}`); | ||
} | ||
} | ||
static verify(jwt, keyOrStore, options) { | ||
const opts = options || /* istanbul ignore next */ {}; | ||
const timestamp = Math.ceil(Date.now() / 1000); | ||
@@ -90,29 +121,3 @@ return createVerify(keyOrStore, jwt).catch((err) => { | ||
const payload = jws.payload = JSON.parse(jws.payload); | ||
assert(typeof payload === 'object', | ||
'payload is not of JWT type (JSON serialized object)'); | ||
if (typeof payload.nbf !== 'undefined' && !opts.ignoreNotBefore) { | ||
assert(typeof payload.nbf === 'number', 'invalid nbf value'); | ||
assert(payload.nbf <= timestamp, 'jwt not active yet'); | ||
} | ||
if (typeof payload.iat !== 'undefined' && !opts.ignoreIssued) { | ||
assert(typeof payload.iat === 'number', 'invalid iat value'); | ||
assert(payload.iat <= timestamp, 'jwt issued in the future'); | ||
} | ||
if (typeof payload.exp !== 'undefined' && !opts.ignoreExpiration) { | ||
assert(typeof payload.exp === 'number', 'invalid exp value'); | ||
assert(timestamp < payload.exp, 'jwt expired'); | ||
} | ||
if (opts.audience) { | ||
verifyAudience(payload, Array.isArray(opts.audience) ? | ||
opts.audience : [opts.audience]); | ||
} | ||
if (opts.issuer) { | ||
assert(payload.iss === opts.issuer, `jwt issuer invalid. expected: ${opts.issuer}`); | ||
} | ||
this.assertPayload(payload, opts); | ||
return jws; | ||
@@ -119,0 +124,0 @@ }); |
@@ -5,3 +5,3 @@ 'use strict'; | ||
const url = require('url'); | ||
const uuid = require('node-uuid').v4; | ||
const uuid = require('uuid').v4; | ||
@@ -8,0 +8,0 @@ const errors = require('./errors'); |
@@ -47,3 +47,3 @@ 'use strict'; | ||
if (opts.expiresAt) { | ||
expiresIn = (opts.expiresAt - Date.now()) / 1000 | 0; | ||
expiresIn = opts.expiresAt - (Date.now() / 1000 | 0); | ||
} | ||
@@ -54,22 +54,28 @@ | ||
const keystore = alg && alg.startsWith('HS') ? client.keystore : provider.keystore; | ||
const key = keystore && keystore.get({ alg }); | ||
const payload = this.payload(); | ||
const flags = { | ||
audience: client.clientId, | ||
expiresIn: expiresIn || this.constructor.expiresIn, | ||
issuer: provider.issuer, | ||
subject: payload.sub, | ||
}; | ||
let promise; | ||
hashes.forEach((claim) => { | ||
if (payload[claim]) { | ||
payload[claim] = tokenHash(payload[claim], alg); | ||
} | ||
}); | ||
if (alg) { | ||
const keystore = alg && alg.startsWith('HS') ? client.keystore : provider.keystore; | ||
const key = keystore && keystore.get({ alg }); | ||
const promise = JWT.sign(payload, key, alg, flags); | ||
hashes.forEach((claim) => { | ||
if (payload[claim]) { | ||
payload[claim] = tokenHash(payload[claim], alg); | ||
} | ||
}); | ||
promise = JWT.sign(payload, key, alg, { | ||
audience: client.clientId, | ||
expiresIn: expiresIn || this.constructor.expiresIn, | ||
issuer: provider.issuer, | ||
subject: payload.sub, | ||
}); | ||
} else { | ||
promise = Promise.resolve(JSON.stringify(payload)); | ||
} | ||
const encryption = opts.use === 'userinfo' ? { | ||
@@ -119,9 +125,15 @@ alg: client.userinfoEncryptedResponseAlg, | ||
if (!_.isUndefined(keyOrStore)) { | ||
if (keyOrStore !== undefined) { | ||
return JWT.verify(jwt, keyOrStore, options); | ||
} | ||
return Promise.resolve(JWT.decode(jwt)); | ||
const decode = JWT.decode(jwt); | ||
try { | ||
JWT.assertPayload(decode.payload, options); | ||
} catch (err) { | ||
return Promise.reject(err); | ||
} | ||
return Promise.resolve(decode); | ||
} | ||
}; | ||
}; |
@@ -19,3 +19,3 @@ 'use strict'; | ||
const assert = require('assert'); | ||
const uuid = require('node-uuid'); | ||
const uuid = require('uuid'); | ||
@@ -22,0 +22,0 @@ const errors = require('../helpers/errors'); |
'use strict'; | ||
const uuid = require('node-uuid'); | ||
const uuid = require('uuid'); | ||
const _ = require('lodash'); | ||
@@ -5,0 +5,0 @@ |
@@ -212,2 +212,10 @@ 'use strict'; | ||
this.app.use(error(this)); | ||
this.app.use(function * invalidRoute(next) { | ||
yield next; | ||
if (this.status === 404 && this.message === 'Not Found') { | ||
this.throw(new errors.InvalidRequestError('unrecognized route', 404)); | ||
} | ||
}); | ||
this.app.use(router.allowedMethods({ | ||
@@ -214,0 +222,0 @@ throw: true, |
@@ -16,3 +16,3 @@ { | ||
"node-jose": "^0.9.0", | ||
"node-uuid": "^1.4.7", | ||
"uuid": "^2.0.2", | ||
"valid-url": "^1.0.9" | ||
@@ -33,3 +33,3 @@ }, | ||
"koa-rewrite": "^1.1.1", | ||
"mocha": "^2.4.5", | ||
"mocha": "^3.0.0", | ||
"mocha-generators": "^1.2.0", | ||
@@ -39,3 +39,3 @@ "moment": "^2.14.1", | ||
"sinon": "^1.17.3", | ||
"supertest": "^1.2.0" | ||
"supertest": "^2.0.0" | ||
}, | ||
@@ -60,5 +60,6 @@ "main": "lib/index.js", | ||
"test": "make test", | ||
"lint": "eslint lib example test --fix" | ||
"lint": "eslint lib example test --fix", | ||
"heroku-postbuild": "npm install mongodb" | ||
}, | ||
"version": "0.8.2", | ||
"version": "0.9.0", | ||
"files": [ | ||
@@ -65,0 +66,0 @@ "lib" |
# oidc-provider | ||
[![build][travis-image]][travis-url] [![codecov][codecov-image]][codecov-url] [![npm][npm-image]][npm-url] [![licence][licence-image]][licence-url] | ||
[![build][travis-image]][travis-url] [![dependencies][david-image]][david-url] [![codecov][codecov-image]][codecov-url] [![npm][npm-image]][npm-url] [![licence][licence-image]][licence-url] | ||
@@ -454,2 +454,4 @@ oidc-provider is an OpenID Provider implementation of [OpenID Connect][openid-connect]. It allows to | ||
[travis-url]: https://travis-ci.org/panva/node-oidc-provider | ||
[david-image]: https://img.shields.io/david/panva/node-oidc-provider.svg?style=flat-square&maxAge=7200 | ||
[david-url]: https://david-dm.org/panva/node-oidc-provider | ||
[codecov-image]: https://img.shields.io/codecov/c/github/panva/node-oidc-provider/master.svg?style=flat-square&maxAge=7200 | ||
@@ -456,0 +458,0 @@ [codecov-url]: https://codecov.io/gh/panva/node-oidc-provider |
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
151943
3592
481
+ Addeduuid@^2.0.2
+ Addeduuid@2.0.3(transitive)
- Removednode-uuid@^1.4.7
- Removednode-uuid@1.4.8(transitive)