Socket
Socket
Sign inDemoInstall

openid-client

Package Overview
Dependencies
Maintainers
1
Versions
181
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

openid-client - npm Package Compare versions

Comparing version 1.4.0 to 1.5.0

lib/passport_strategy.js

14

CHANGELOG.md

@@ -8,2 +8,3 @@ # openid-client CHANGELOG

<!-- TOC START min:2 max:2 link:true update:true -->
- [Version 1.5.0](#version-150)
- [Version 1.4.0](#version-140)

@@ -19,2 +20,15 @@ - [Version 1.3.0](#version-130)

## Version 1.5.0
- [DIFF](https://github.com/panva/node-openid-client/compare/v1.4.0...v1.5.0)
- added a passport.js strategy
- added missing max_age, default_max_age related functionality
- authorizationCallback now supports max_age check
- clients with default_max_age use this default value automatically
- when max_age is checked auth_time claim is mandatory and must be a number
- added missing require_auth_time related functionality
- clients with require_auth_time = true have the presence and format of auth_time claim validated
- authorizationUrl and authorizationPost now removes null and undefined values and ensures parameters
are stringified before passed to url.format
- added client.CLOCK_TOLERANCE property, to allow for clock skew (in seconds)
## Version 1.4.0

@@ -21,0 +35,0 @@ - [DIFF](https://github.com/panva/node-openid-client/compare/v1.3.1...v1.4.0)

56

lib/client.js

@@ -20,2 +20,3 @@ 'use strict';

const OpenIdConnectError = require('./open_id_connect_error');
const now = require('./unix_timestamp');

@@ -93,7 +94,15 @@ const CALLBACK_PROPERTIES = require('./consts').CALLBACK_PROPERTIES;

const authParams = _.defaults(params, {
const authParams = _.chain(params).defaults({
client_id: this.client_id,
scope: 'openid',
response_type: 'code',
});
}).forEach((value, key, object) => {
if (value === null || value === undefined) {
delete object[key];
} else if (key === 'claims' && typeof value === 'object') {
object[key] = JSON.stringify(value);
} else if (typeof value !== 'string') {
object[key] = String(value);
}
}).value();

@@ -103,6 +112,2 @@ assert(authParams.response_type === 'code' || authParams.nonce,

if (typeof authParams.claims === 'object') {
authParams.claims = JSON.stringify(authParams.claims);
}
return authParams;

@@ -157,2 +162,4 @@ }

}
this.CLOCK_TOLERANCE = 0;
}

@@ -220,3 +227,3 @@

return url.parse(uri, true).query;
return _.pick(url.parse(uri, true).query, CALLBACK_PROPERTIES);
}

@@ -228,2 +235,4 @@

if (this.default_max_age && !toCheck.max_age) toCheck.max_age = this.default_max_age;
if (toCheck.state !== parameters.state) {

@@ -242,3 +251,3 @@ return Promise.reject(new Error('state mismatch'));

.then(tokenset => this.decryptIdToken(tokenset, 'id_token'))
.then(tokenset => this.validateIdToken(tokenset, toCheck.nonce, 'id_token'));
.then(tokenset => this.validateIdToken(tokenset, toCheck.nonce, 'id_token', toCheck.max_age));
}

@@ -253,3 +262,3 @@

.then(tokenset => this.decryptIdToken(tokenset, 'id_token'))
.then(tokenset => this.validateIdToken(tokenset, toCheck.nonce, 'id_token'))
.then(tokenset => this.validateIdToken(tokenset, toCheck.nonce, 'id_token', toCheck.max_age))
.then((tokenset) => {

@@ -319,3 +328,3 @@ if (params.session_state) tokenset.session_state = params.session_state;

validateIdToken(token, nonce, intent) {
validateIdToken(token, nonce, intent, maxAge) {
let idToken = token;

@@ -350,3 +359,3 @@

const now = Math.ceil(Date.now() / 1000);
const timestamp = now();
const parts = idToken.split('.');

@@ -376,3 +385,3 @@ const header = parts[0];

assert.equal(typeof payloadObject.iat, 'number', 'iat is not a number');
assert(payloadObject.iat <= now, 'id_token issued in the future');
assert(payloadObject.iat <= timestamp + this.CLOCK_TOLERANCE, 'id_token issued in the future');
}

@@ -382,5 +391,14 @@

assert.equal(typeof payloadObject.nbf, 'number', 'nbf is not a number');
assert(payloadObject.nbf <= now, 'id_token not active yet');
assert(payloadObject.nbf <= timestamp + this.CLOCK_TOLERANCE, 'id_token not active yet');
}
if (maxAge || (maxAge !== null && this.require_auth_time)) {
assert(payloadObject.auth_time, 'missing required JWT property auth_time');
assert.equal(typeof payloadObject.auth_time, 'number', 'auth_time is not a number');
}
if (maxAge) {
assert(payloadObject.auth_time + maxAge >= timestamp - this.CLOCK_TOLERANCE, 'too much time has elapsed since the last End-User authentication');
}
if (nonce !== null && (payloadObject.nonce || nonce !== undefined)) {

@@ -392,3 +410,3 @@ assert.equal(payloadObject.nonce, nonce, 'nonce mismatch');

assert.equal(typeof payloadObject.exp, 'number', 'exp is not a number');
assert(now < payloadObject.exp, 'id_token expired');
assert(timestamp - this.CLOCK_TOLERANCE < payloadObject.exp, 'id_token expired');
}

@@ -450,3 +468,3 @@

return this.decryptIdToken(tokenset, 'id_token')
.then(() => this.validateIdToken(tokenset, null, 'id_token'));
.then(() => this.validateIdToken(tokenset, null, 'id_token', null));
});

@@ -493,3 +511,3 @@ }

if (!this.userinfo_signed_response_alg) return JSON.parse(jwt);
return this.validateIdToken(jwt, null, 'userinfo')
return this.validateIdToken(jwt, null, 'userinfo', null)
.then(valid => JSON.parse(base64url.decode(valid.split('.')[1])));

@@ -664,6 +682,6 @@ });

case 'client_secret_jwt' : {
const now = Math.floor(Date.now() / 1000);
const timestamp = now();
return this.createSign().then(sign => sign.update(JSON.stringify({
iat: now,
exp: now + 60,
iat: timestamp,
exp: timestamp + 60,
jti: uuid(),

@@ -670,0 +688,0 @@ iss: this.client_id,

@@ -5,2 +5,3 @@ 'use strict';

const Registry = require('./issuer_registry');
const Strategy = require('./passport_strategy');

@@ -10,2 +11,3 @@ module.exports = {

Registry,
Strategy,
};
{
"name": "openid-client",
"version": "1.4.0",
"description": "OpenID Connect Relying Party (RP, Client) implementation for Node.js",
"version": "1.5.0",
"description": "OpenID Connect Relying Party (RP, Client) implementation for Node.js servers, supports passportjs",
"main": "lib/index.js",

@@ -28,2 +28,5 @@ "scripts": {

"oauth",
"passport",
"passportjs",
"strategy",
"certified",

@@ -30,0 +33,0 @@ "dynamic",

@@ -6,3 +6,3 @@ # openid-client

openid-client is a server side [OpenID][openid-connect] Relying Party (RP, Client) implementation for
Node.js
Node.js, supports [passport][passport-url].

@@ -17,2 +17,3 @@ **Table of Contents**

- [Usage](#usage)
- [Usage with passport](#usage-with-passport)
- [Configuration](#configuration)

@@ -146,3 +147,3 @@

### Processing callback with state or nonce check
### Processing callback with state, nonce or max_age check
```js

@@ -152,3 +153,3 @@ const state = session.state;

client.authorizationCallback('https://client.example.com/callback', request.query, { state, nonce }) // => Promise
client.authorizationCallback('https://client.example.com/callback', request.query, { state, nonce, max_age }) // => Promise
.then(function (tokenSet) {

@@ -161,3 +162,3 @@ console.log('received and validated tokens %j', tokenSet);

### Handling multiple response modes
When handling multiple response modes with one single pass you can use `#authorizationParams`
When handling multiple response modes with one single pass you can use `#callbackParams`
to get the params object from the koa/express/node request object or a url string.

@@ -167,4 +168,4 @@ (http.IncomingMessage). If form_post is your response_type you need to include a body parser prior.

```js
client.authorizationParams('https://client.example.com/cb?code=code'); // => { code: 'code' };
client.authorizationParams('/cb?code=code'); // => { code: 'code' };
client.callbackParams('https://client.example.com/cb?code=code'); // => { code: 'code' };
client.callbackParams('/cb?code=code'); // => { code: 'code' };

@@ -174,3 +175,3 @@ // koa v1.x w/ koa-body

app.use(function* (next) {
const params = client.authorizationParams(this.request.req); // => parsed url query, url fragment or body object
const params = client.callbackParams(this.request.req); // => parsed url query, url fragment or body object
// ...

@@ -182,3 +183,3 @@ });

app.use(function (req, res, next) {
const params = client.authorizationParams(req); // => parsed url query, url fragment or body object
const params = client.callbackParams(req); // => parsed url query, url fragment or body object
// ...

@@ -193,3 +194,3 @@ });

console.log('refreshed and validated tokens %j', tokenSet);
console.log('refreshed id_token claims %j' tokenSet.claims);
console.log('refreshed id_token claims %j', tokenSet.claims);
});

@@ -358,4 +359,49 @@ ```

## Usage with passport
Once you have a Client instance, just pass it to the Strategy. Issuer is best discovered, Client
passed properties manually or via an uri (see [get-started](#get-started)).
Verify function is invoked with a TokenSet, userinfo only when requested, last argument is always
the done function which you invoke once you found your user.
```js
const Strategy = require('openid-client').Strategy;
const params = {
// ... any authorization params
// client_id defaults to client.client_id
// redirect_uri defaults to redirect_uris[0]
// response type defaults to client.response_types[0], then 'code'
// scope defaults to 'openid'
}
passport.use('oidc', new Strategy({ client, [params] }, (tokenset, userinfo, done) => {
console.log('tokenset', tokenset);
console.log('access_token', tokenset.access_token);
console.log('id_token', tokenset.id_token);
console.log('claims', tokenset.claims);
console.log('userinfo', userinfo);
User.findOne({ id: tokenset.claims.sub }, function (err, user) {
if (err) return done(err);
return done(null, user);
});
}));
// start authentication request
// options [optional], extra authentication parameters
app.get('/auth', passport.authenticate('oidc', [options]));
// authentication callback
app.get('/auth/cb', passport.authenticate('oidc', { successRedirect: '/', failureRedirect: '/login' }));
```
## Configuration
### Allow for system clock skew
It is possible the RP or OP environment has a system clock skew, to set a clock tolerance (in seconds)
```js
client.CLOCK_TOLERANCE = 5; // to allow a 5 second skew
```
### Changing HTTP request defaults

@@ -404,1 +450,2 @@ Setting `defaultHttpOptions` on `Issuer` always merges your passed options with the default.

[openid-certified-logo]: https://cdn.rawgit.com/panva/node-openid-client/master/OpenID_Certified.png
[passport-url]: http://passportjs.org
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc