Socket
Socket
Sign inDemoInstall

oidc-provider

Package Overview
Dependencies
Maintainers
1
Versions
337
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

oidc-provider - npm Package Compare versions

Comparing version 0.6.0 to 0.7.0

lib/actions/authorization.js

2

CHANGELOG.md
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.6.0...v0.7.0
- all things `authentication` renamed to `authorization`
- https://github.com/panva/node-oidc-provider/compare/v0.5.0...v0.6.0

@@ -5,0 +7,0 @@ - https://github.com/panva/node-oidc-provider/compare/v0.4.0...v0.5.0

4

lib/actions/discovery.js
'use strict';
module.exports = function discoveryAction(provider) {
const config = provider.configuration;
const config = provider.configuration();

@@ -9,3 +9,3 @@ return function * renderConfiguration(next) {

acr_values_supported: config.acrValues,
authorization_endpoint: this.oidc.urlFor('authentication'),
authorization_endpoint: this.oidc.urlFor('authorization'),
claims_parameter_supported: !!config.features.claimsParameter,

@@ -12,0 +12,0 @@ claims_supported: config.claimsSupported,

@@ -10,4 +10,4 @@ 'use strict';

const dupesMiddleware = require('../middlewares/check_dupes');
const bodyMiddleware = require('../middlewares/selective_body');
const rejectDupes = require('../middlewares/check_dupes');
const bodyParser = require('../middlewares/conditional_body');
const paramsMiddleware = require('../middlewares/get_params');

@@ -22,3 +22,3 @@

const getParams = paramsMiddleware(PARAM_LIST);
const body = bodyMiddleware('application/x-www-form-urlencoded');
const parseBody = bodyParser('application/x-www-form-urlencoded');

@@ -28,3 +28,3 @@ module.exports = function endSessionAction(provider) {

// Validate: client_id param
const client = yield provider.Client.find(clientId);
const client = yield provider.get('Client').find(clientId);

@@ -39,13 +39,7 @@ this.assert(client,

function * parseBody(next) {
if (this.method === 'POST') {
yield body.call(this, next);
} else {
yield next;
}
},
parseBody,
getParams,
dupesMiddleware,
rejectDupes,

@@ -72,3 +66,3 @@ function * validateIdTokenHintPresence(next) {

client = yield loadClient.call(this, clientId);
yield provider.IdToken.validate(params.id_token_hint, client);
yield provider.get('IdToken').validate(params.id_token_hint, client);
} catch (err) {

@@ -75,0 +69,0 @@ this.throw(new errors.InvalidRequestError(

@@ -14,3 +14,3 @@ 'use strict';

module.exports = function introspectionAction(provider) {
const Claims = mask(provider.configuration);
const Claims = mask(provider.configuration());

@@ -36,3 +36,3 @@ return compose([

try {
payload = provider.OAuthToken.decode(params.token).decoded;
payload = provider.get('OAuthToken').decode(params.token).decoded;

@@ -50,3 +50,3 @@ Object.assign(this.body, {

this.body.token_type = 'access_token';
token = yield provider.AccessToken.find(params.token, {
token = yield provider.get('AccessToken').find(params.token, {
ignoreExpiration: true,

@@ -58,3 +58,3 @@ });

this.body.token_type = 'client_credentials';
token = yield provider.ClientCredentials.find(params.token, {
token = yield provider.get('ClientCredentials').find(params.token, {
ignoreExpiration: true,

@@ -66,3 +66,3 @@ });

this.body.token_type = 'refresh_token';
token = yield provider.RefreshToken.find(params.token, {
token = yield provider.get('RefreshToken').find(params.token, {
ignoreExpiration: true,

@@ -69,0 +69,0 @@ });

@@ -9,7 +9,6 @@ 'use strict';

const bodyMiddleware = require('../middlewares/selective_body');
const getBearer = require('../middlewares/get_bearer');
const bodyParser = require('../middlewares/selective_body');
const errors = require('../helpers/errors');
const body = bodyMiddleware('application/json');
const parseBody = bodyParser('application/json');

@@ -19,7 +18,7 @@ module.exports = function registrationAction(provider) {

post: compose([
body,
parseBody,
function * registrationResponse() {
const params = {};
const properties = {};
Object.assign(params, this.request.body, {
Object.assign(properties, this.request.body, {
client_id: uuid.v4(),

@@ -31,16 +30,13 @@ client_secret: crypto.randomBytes(48).toString('base64'),

const client = yield provider.addClient(params);
const client = yield provider.addClient(properties);
const dumpable = _.mapKeys(client, (value, key) => _.snakeCase(key));
yield provider.get('Client').adapter.upsert(client.clientId, dumpable);
yield provider.Client.adapter.upsert(client.clientId, dumpable);
const response = Object.assign({
registration_client_uri: this.oidc.urlFor('registration_client', {
clientId: params.client_id,
clientId: properties.client_id,
}),
}, _.mapKeys(client, (value, key) => _.snakeCase(key)));
}, dumpable);
this.body = response;
this.status = 201;

@@ -52,9 +48,6 @@ },

getBearer,
function * validateAccessToken(next) {
const client = yield provider.Client.find(this.params.clientId);
const client = yield provider.get('Client').find(this.params.clientId);
this.assert(client,
new errors.InvalidClientError());
this.assert(client, new errors.InvalidClientError());

@@ -68,3 +61,2 @@ const valid = bufferEqualsConstant(

this.assert(valid, new errors.InvalidTokenError());
this.oidc.client = client;

@@ -76,8 +68,6 @@

function * clientResponse() {
this.body = _.mapKeys(this.oidc.client, (value, key) => _.snakeCase(key));
this.body.registration_client_uri =
this.oidc.urlFor('registration_client', {
clientId: this.params.clientId,
});
this.body = this.oidc.client.metadata();
this.body.registration_client_uri = this.oidc.urlFor('registration_client', {
clientId: this.params.clientId,
});
},

@@ -84,0 +74,0 @@ ]),

@@ -32,3 +32,3 @@ 'use strict';

try {
payload = provider.OAuthToken.decode(params.token).decoded;
payload = provider.get('OAuthToken').decode(params.token).decoded;
} catch (err) {

@@ -41,3 +41,3 @@ return;

try {
const token = yield provider.AccessToken.find(params.token);
const token = yield provider.get('AccessToken').find(params.token);
yield token.destroy();

@@ -51,3 +51,3 @@ } catch (err) {

try {
const token = yield provider.ClientCredentials.find(params.token);
const token = yield provider.get('ClientCredentials').find(params.token);
yield token.destroy();

@@ -61,3 +61,3 @@ } catch (err) {

try {
const token = yield provider.RefreshToken.find(params.token);
const token = yield provider.get('RefreshToken').find(params.token);
yield token.destroy();

@@ -64,0 +64,0 @@ } catch (err) {

@@ -25,3 +25,3 @@ 'use strict';

const handlers = {};
const grantTypes = provider.configuration.grantTypes;
const grantTypes = provider.configuration('grantTypes');

@@ -32,3 +32,3 @@ if (grantTypes.indexOf('authorization_code') !== -1) {

const code = yield provider.AuthorizationCode.find(this.oidc.params.code, {
const code = yield provider.get('AuthorizationCode').find(this.oidc.params.code, {
ignoreExpiration: true,

@@ -60,3 +60,3 @@ });

const account = yield provider.Account.findById(code.accountId);
const account = yield provider.get('Account').findById(code.accountId);

@@ -67,4 +67,4 @@ this.assert(account,

));
const at = new provider.AccessToken({
const AccessToken = provider.get('AccessToken');
const at = new AccessToken({
accountId: account.accountId,

@@ -79,11 +79,12 @@ claims: code.claims,

const tokenType = 'Bearer';
const expiresIn = provider.AccessToken.expiresIn;
const expiresIn = AccessToken.expiresIn;
let refreshToken;
const clientAllowed = this.oidc.client.grantTypes.indexOf('refresh_token') !== -1;
const grantAllowed = provider.configuration.features.refreshToken ||
const grantAllowed = provider.configuration('features.refreshToken') ||
code.scope.split(' ').indexOf('offline_access') !== -1;
if (clientAllowed && grantAllowed) {
const rt = new provider.RefreshToken({
const RefreshToken = provider.get('RefreshToken');
const rt = new RefreshToken({
accountId: account.accountId,

@@ -101,3 +102,4 @@ acr: code.acr,

const token = new provider.IdToken(Object.assign({}, account.claims(), {
const IdToken = provider.get('IdToken');
const token = new IdToken(Object.assign({}, account.claims(), {
acr: code.acr,

@@ -129,3 +131,4 @@ auth_time: code.authTime,

handlers.client_credentials = function * clientCredentialsResponse(next) {
const at = new provider.ClientCredentials({
const ClientCredentials = provider.get('ClientCredentials');
const at = new ClientCredentials({
clientId: this.oidc.client.clientId,

@@ -137,3 +140,3 @@ scope: this.oidc.params.scope,

const tokenType = 'Bearer';
const expiresIn = provider.ClientCredentials.expiresIn;
const expiresIn = ClientCredentials.expiresIn;

@@ -154,3 +157,8 @@ this.body = {

const refreshToken = yield provider.RefreshToken.find(
const RefreshToken = provider.get('RefreshToken');
const Account = provider.get('Account');
const AccessToken = provider.get('AccessToken');
const IdToken = provider.get('IdToken');
const refreshToken = yield RefreshToken.find(
this.oidc.params.refresh_token, {

@@ -179,3 +187,3 @@ ignoreExpiration: true,

const account = yield provider.Account.findById(refreshToken.accountId);
const account = yield Account.findById(refreshToken.accountId);

@@ -186,3 +194,3 @@ this.assert(account,

const at = new provider.AccessToken({
const at = new AccessToken({
accountId: account.accountId,

@@ -197,5 +205,5 @@ claims: refreshToken.claims,

const tokenType = 'Bearer';
const expiresIn = provider.AccessToken.expiresIn;
const expiresIn = AccessToken.expiresIn;
const token = new provider.IdToken(Object.assign({}, account.claims(), {
const token = new IdToken(Object.assign({}, account.claims(), {
acr: refreshToken.acr,

@@ -232,3 +240,3 @@ auth_time: refreshToken.authTime,

const supported = provider.configuration.grantTypes;
const supported = provider.configuration('grantTypes');
const value = supported.indexOf(this.oidc.params.grant_type) !== -1;

@@ -235,0 +243,0 @@

@@ -9,5 +9,4 @@ 'use strict';

const body = require('../middlewares/selective_body');
const dupes = require('../middlewares/check_dupes');
const getBearer = require('../middlewares/get_bearer');
const bodyParser = require('../middlewares/conditional_body');
const rejectDupes = require('../middlewares/check_dupes');
const params = require('../middlewares/get_params');

@@ -21,7 +20,7 @@ const errorHandler = require('../middlewares/api_error_handler');

const bodyMiddleware = body('application/x-www-form-urlencoded');
const parseBody = bodyParser('application/x-www-form-urlencoded');
const getParams = params(PARAM_LIST);
module.exports = function userinfoAction(provider) {
const Claims = getMask(provider.configuration);
const Claims = getMask(provider.configuration());

@@ -46,18 +45,10 @@ return compose([

function * parseBody(next) {
if (this.method === 'POST') {
yield bodyMiddleware.call(this, next);
} else {
yield next;
}
},
parseBody,
getParams,
dupes,
rejectDupes,
getBearer,
function * validateBearer(next) {
const accessToken = yield provider.AccessToken.find(this.oidc.bearer);
const accessToken = yield provider.get('AccessToken').find(this.oidc.bearer);
this.assert(accessToken,

@@ -85,3 +76,3 @@ new errors.InvalidTokenError());

function * loadClient(next) {
const client = yield provider.Client.find(this.oidc.accessToken.clientId);
const client = yield provider.get('Client').find(this.oidc.accessToken.clientId);

@@ -97,3 +88,3 @@ this.assert(client,

function * loadAccount(next) {
const account = yield provider.Account.findById(this.oidc.accessToken.accountId);
const account = yield provider.get('Account').findById(this.oidc.accessToken.accountId);

@@ -113,3 +104,4 @@ this.assert(account, new errors.InvalidTokenError());

if (client.userinfoSignedResponseAlg || client.userinfoEncryptedResponseAlg) {
const token = new provider.IdToken(this.oidc.account.claims(), client.sectorIdentifier);
const IdToken = provider.get('IdToken');
const token = new IdToken(this.oidc.account.claims(), client.sectorIdentifier);

@@ -116,0 +108,0 @@ token.scope = scope;

'use strict';
const LRU = require('lru-cache');
const storage = new LRU({});
const client = new LRU({});
class MemoryAdapter {

@@ -22,5 +21,5 @@ constructor(name) {

const key = this.key(id);
const grantId = client.get(key) && client.get(key).grantId;
const grantId = storage.get(key) && storage.get(key).grantId;
client.del(key);
storage.del(key);

@@ -30,3 +29,3 @@ if (grantId) {

client.get(grantKey).forEach(token => client.del(token));
storage.get(grantKey).forEach(token => storage.del(token));
}

@@ -38,3 +37,3 @@

consume(id) {
client.get(this.key(id)).consumed = Date.now() / 1000 | 0;
storage.get(this.key(id)).consumed = Date.now() / 1000 | 0;
return Promise.resolve();

@@ -44,3 +43,3 @@ }

find(id) {
return Promise.resolve(client.get(this.key(id)));
return Promise.resolve(storage.get(this.key(id)));
}

@@ -54,5 +53,5 @@

const grantKey = this.grantKey(grantId);
const grant = client.get(grantKey);
const grant = storage.get(grantKey);
if (!grant) {
client.set(grantKey, [key]);
storage.set(grantKey, [key]);
} else {

@@ -63,3 +62,3 @@ grant.push(key);

client.set(key, payload, expiresIn * 1000);
storage.set(key, payload, expiresIn * 1000);

@@ -66,0 +65,0 @@ return Promise.resolve();

'use strict';
const _ = require('lodash');
const defaults = require('./defaults');
const MemoryAdapter = require('../adapters/memory_adapter');
const ConfigurationSchema = require('./configuration_schema');
class Configuration {
constructor(config) {
_.mergeWith(this, defaults, config, (objValue, srcValue) => {
if (_.isArray(objValue)) {
return srcValue;
const schema = new ConfigurationSchema(config);
Object.assign(this, schema);
this.subjectTypes.forEach((type) => {
/* istanbul ignore if */
if (['public', 'pairwise'].indexOf(type) === -1) {
throw new Error('only public and pairwise subjectTypes are supported');
}
return undefined;
});
const encryptionEnc = [
'A128CBC-HS256',
'A128GCM',
'A192CBC-HS384',
'A192GCM',
'A256CBC-HS512',
'A256GCM',
];
const secretSig = [
'none',
'HS256',
'HS384',
'HS512',
];
const fullSig = [
'none',
'HS256',
'HS384',
'HS512',
'RS256',
'RS384',
'RS512',
'PS256',
'PS384',
'PS512',
'ES256',
'ES384',
'ES512',
];
const fullEncAlg = [
'RSA-OAEP',
'RSA-OAEP-256',
'RSA1_5',
'ECDH-ES',
'ECDH-ES+A128KW',
'ECDH-ES+A192KW',
'ECDH-ES+A256KW',
];
this.idTokenEncryptionAlgValues = fullEncAlg;
this.idTokenEncryptionEncValues = this.features.encryption ? encryptionEnc : [];
this.idTokenSigningAlgValues = secretSig;
this.requestObjectEncryptionAlgValues = [];
this.requestObjectEncryptionEncValues = this.features.encryption ? encryptionEnc : [];
this.requestObjectSigningAlgValues = fullSig;
this.tokenEndpointAuthSigningAlgValues = _.without(fullSig, 'none');
this.userinfoEncryptionAlgValues = fullEncAlg;
this.userinfoEncryptionEncValues = this.features.encryption ? encryptionEnc : [];
this.userinfoSigningAlgValues = secretSig;
if (this.subjectTypes.indexOf('pairwise') !== -1 && !this.pairwiseSalt) {
const msg = 'pairwiseSalt must be configured when pairwise subjectType is to be supported';
throw new Error(msg);
throw new Error(
'pairwiseSalt must be configured when pairwise subjectType is to be supported');
}
this.claimsSupported = _.chain(this.scopes)
.map(scope => _.keys(_.get(this.claims, scope, {})))
.union(_.chain(this.claims)
.pickBy(_.isNull)
.keys()
.value())
.flatten()
.sort()
.value();
const grantTypes = [];
_.forEach(this.responseTypes, (responseType) => {
if (responseType.indexOf('token') !== -1) {
grantTypes.push('implicit');
}
if (responseType.indexOf('code') !== -1) {
grantTypes.push('authorization_code');
}
});
if (this.features.refreshToken || this.scopes.indexOf('offline_access') !== -1) {
grantTypes.push('refresh_token');
}
if (this.features.clientCredentials) {
grantTypes.push('client_credentials');
}
this.grantTypes = _.uniq(grantTypes);
if (!this.adapter) {

@@ -107,0 +24,0 @@ this.adapter = MemoryAdapter;

@@ -73,3 +73,3 @@ 'use strict';

routes: {
authentication: '/auth',
authorization: '/auth',
certificates: '/certs',

@@ -92,3 +92,3 @@ check_session: '/session/check',

],
subjectTypes: ['public', 'pairwise'],
subjectTypes: ['public'],
pairwiseSalt: '',

@@ -104,7 +104,7 @@ tokenEndpointAuthMethods: [

acr: 1 * 60,
accessToken: 5 * 60,
authorizationCode: 1 * 60,
clientCredentials: 1 * 60,
idToken: 5 * 60,
refreshToken: 30 * 60,
AccessToken: 5 * 60,
AuthorizationCode: 1 * 60,
ClientCredentials: 1 * 60,
IdToken: 5 * 60,
RefreshToken: 30 * 60,
},

@@ -111,0 +111,0 @@ uniqueness: function uniqueness() {

@@ -38,6 +38,6 @@ 'use strict';

function InvalidClientMetadata(description, key) {
return createError(400, key || 'invalid_client_metadata', {
error_description: description,
});
function InvalidClientMetadata(description) {
const message = description.startsWith('redirect_uris') ?
'invalid_redirect_uri' : 'invalid_client_metadata';
return createError(400, message, { error_description: description });
}

@@ -44,0 +44,0 @@

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

this.type = 'html';
this.status = 200;

@@ -7,0 +8,0 @@ const formInputs = Object.keys(inputs)

@@ -24,3 +24,3 @@ 'use strict';

},
timeout: this.provider.configuration.timeouts.request_uri,
timeout: this.provider.configuration('timeouts.request_uri'),
retries: 0,

@@ -27,0 +27,0 @@ followRedirect: false,

@@ -7,3 +7,3 @@ 'use strict';

module.exports = function validatePresence(required) {
const missing = _.difference(required, _.keys(this.oidc.params));
const missing = _.difference(required, _.keys(_.omitBy(this.oidc.params, _.isUndefined)));

@@ -10,0 +10,0 @@ this.assert(_.isEmpty(missing),

'use strict';
const koa = require('koa');
const pkg = require('../package.json');
const events = require('events');
const _ = require('lodash');
const url = require('url');
const Router = require('koa-router');
const jose = require('node-jose');
const Provider = require('./provider');
const AdapterTest = require('./adapter_test');
const getClient = require('./models/client');
const getIdToken = require('./models/id_token');
const getOauthToken = require('./models/oauth_token');
const getSession = require('./models/session');
const getAccessToken = require('./models/access_token');
const getAuthorizationCode = require('./models/authorization_code');
const getClientCredentials = require('./models/client_credentials');
const getRefreshToken = require('./models/refresh_token');
const getAuthentication = require('./actions/authentication');
const getUserinfo = require('./actions/userinfo');
const getToken = require('./actions/token');
const getCertificates = require('./actions/certificates');
const getRegistration = require('./actions/registration');
const getRevocation = require('./actions/revocation');
const getIntrospection = require('./actions/introspection');
const getWebfinger = require('./actions/webfinger');
const getDiscovery = require('./actions/discovery');
const getCheckSession = require('./actions/check_session');
const getEndSession = require('./actions/end_session');
const getResumeMiddleware = require('./middlewares/resume');
const getSessionMiddleware = require('./middlewares/session');
const apiErrorHandlerMiddleware = require('./middlewares/api_error_handler');
const getConfiguration = require('./helpers/configuration');
class Provider extends events.EventEmitter {
constructor(issuer, setup) {
super();
this.issuer = issuer;
Object.defineProperty(this, 'configuration', {
value: getConfiguration(setup),
});
Object.defineProperties(this, {
Client: {
value: getClient(this),
},
IdToken: {
value: getIdToken(this),
},
OAuthToken: {
value: getOauthToken(this),
},
Session: {
value: getSession(this),
},
app: {
value: koa(),
},
keystore: {
writable: process.env.NODE_ENV === 'test',
value: jose.JWK.createKeyStore(),
},
router: {
value: new Router(),
},
});
this.mountPath = url.parse(this.issuer).pathname;
Object.defineProperties(this, {
AccessToken: {
value: getAccessToken(this.OAuthToken),
},
AuthorizationCode: {
value: getAuthorizationCode(this.OAuthToken),
},
ClientCredentials: {
value: getClientCredentials(this.OAuthToken),
},
RefreshToken: {
value: getRefreshToken(this.OAuthToken),
},
});
this.AccessToken.expiresIn = this.configuration.ttl.accessToken;
this.AuthorizationCode.expiresIn = this.configuration.ttl.authorizationCode;
this.ClientCredentials.expiresIn = this.configuration.ttl.clientCredentials;
this.IdToken.expiresIn = this.configuration.ttl.idToken;
this.RefreshToken.expiresIn = this.configuration.ttl.refreshToken;
const session = getSessionMiddleware(this);
const errorHandler = apiErrorHandlerMiddleware;
const authentication = getAuthentication(this);
const authMountPath = url.resolve('/',
this.configuration.routes.authentication);
this.router.get('authentication', authMountPath, session, authentication);
this.router.post('authentication', authMountPath, session, authentication);
const resume = getResumeMiddleware(this);
const resumeMountPath = url.resolve('/', `${authMountPath}/:grant`);
this.router.get('resume', resumeMountPath, session, resume, authentication);
const userinfo = getUserinfo(this);
const userinfoMountPath = url.resolve('/', this.configuration.routes.userinfo);
this.router.get('userinfo', userinfoMountPath, userinfo);
this.router.post('userinfo', userinfoMountPath, userinfo);
const token = getToken(this);
const tokenMountPath = url.resolve('/', this.configuration.routes.token);
this.router.post('token', tokenMountPath, errorHandler(this, 'grant.error'), token);
const certificates = getCertificates(this);
const certMountPath = url.resolve('/', this.configuration.routes.certificates);
this.router.get('certificates', certMountPath, errorHandler(this, 'certificates.error'),
certificates);
if (this.configuration.features.registration) {
const registration = getRegistration(this);
const regMountPath = url.resolve('/', this.configuration.routes.registration);
const regClientMountPath = `${regMountPath}/:clientId`;
this.router.post('registration', regMountPath, errorHandler(this, 'registration.error'),
registration.post);
this.router.get('registration_client', regClientMountPath, errorHandler(this,
'registration.error'), registration.get);
}
if (this.configuration.features.revocation) {
const revocation = getRevocation(this);
const revokeMountPath = url.resolve('/', this.configuration.routes.revocation);
this.router.post('revocation', revokeMountPath, errorHandler(this, 'revocation.error'),
revocation);
}
if (this.configuration.features.introspection) {
const introspection = getIntrospection(this);
const introMountPath = url.resolve('/', this.configuration.routes.introspection);
this.router.post('introspection', introMountPath, errorHandler(this, 'introspection.error'),
introspection);
}
if (this.configuration.features.discovery) {
const webfinger = getWebfinger(this);
const discovery = getDiscovery(this);
this.router.get('webfinger', '/.well-known/webfinger', errorHandler(this, 'webfinger.error'),
webfinger);
this.router.get('discovery', '/.well-known/openid-configuration', errorHandler(this,
'discovery.error'), discovery);
}
if (this.configuration.features.sessionManagement) {
const checkFrame = getCheckSession(this);
const checkFrameMountPath = url.resolve('/', this.configuration.routes.check_session);
this.router.get('check_session', checkFrameMountPath, errorHandler(this,
'check_session.error'), checkFrame);
const endSession = getEndSession(this);
const endSessionMountPath = url.resolve('/', this.configuration.routes.end_session);
this.router.get('end_session', endSessionMountPath, errorHandler(this, 'end_session.error'),
session, endSession);
this.router.post('end_session', endSessionMountPath, errorHandler(this, 'end_session.error'),
session, endSession);
}
const self = this;
this.app.use(function * contextEnsureOidc(next) {
this.oidc = {};
this.oidc.pathFor = (name, opt) => self.pathFor(name, opt);
this.oidc.urlFor = (name, opt) => url.resolve(this.href, this.oidc.pathFor(name, opt));
yield next;
});
this.app.use(this.router.routes());
this.app.use(this.router.allowedMethods());
}
}
Provider.prototype.pathFor = function pathFor(name, opts) {
return [
this.mountPath !== '/' ? this.mountPath : undefined,
this.router.url(name, opts),
].join('');
};
/* istanbul ignore next */
Provider.prototype.resume = function resume(ctx, grant, result) {
const resumePath = this.pathFor('resume', { grant });
ctx.cookies.set('_grant_result', JSON.stringify(result), _.merge({ path: resumePath },
this.configuration.cookies.short));
ctx.redirect(resumePath);
};
Provider.prototype.addClient = function addClient(client) {
return this.Client.add(client);
};
Provider.prototype.userAgent = function userAgent() {
return `${pkg.name}/${pkg.version} (${this.issuer}; ${pkg.homepage})`;
};
Provider.prototype.addKey = function addKey(key) {
return this.keystore.add(key).then((jwk) => {
// check if private key was added
try {
jwk.toPEM(true);
} catch (err) {
this.keystore.remove(jwk);
throw new Error('only private keys should be added');
}
if (this.configuration.features.encryption) {
const encryptionAlgs = jwk.algorithms('wrap');
[
// 'idTokenEncryptionAlgValues',
'requestObjectEncryptionAlgValues',
// 'userinfoEncryptionAlgValues',
].forEach((prop) => {
this.configuration[prop] = _.union(this.configuration[prop],
encryptionAlgs);
});
}
const signingAlgs = jwk.algorithms('sign');
[
'idTokenSigningAlgValues',
// 'requestObjectSigningAlgValues',
// 'tokenEndpointAuthSigningAlgValues',
'userinfoSigningAlgValues',
].forEach((prop) => {
this.configuration[prop] = _.union(this.configuration[prop], signingAlgs);
});
return Promise.resolve(jwk);
});
};
module.exports.Provider = Provider;
module.exports.AdapterTest = AdapterTest;

@@ -5,6 +5,6 @@ 'use strict';

const body = require('../selective_body');
const bodyParser = require('../selective_body');
const params = require('../get_params');
const dupes = require('../check_dupes');
const client = require('../find_client_id');
const rejectDupes = require('../check_dupes');
const getClientId = require('../find_client_id');
const loadClient = require('../load_client');

@@ -15,10 +15,10 @@ const tokenAuth = require('../token_auth');

const auth = tokenAuth(provider);
const bodyMiddleware = body('application/x-www-form-urlencoded');
const getParams = params(whitelist);
const parseBody = bodyParser('application/x-www-form-urlencoded');
const buildParams = params(whitelist);
return compose([
bodyMiddleware,
getParams,
dupes,
client,
parseBody,
buildParams,
rejectDupes,
getClientId,
loadClient(provider),

@@ -25,0 +25,0 @@ auth,

@@ -14,6 +14,5 @@ 'use strict';

this.assert(_.isEmpty(dupes),
new errors.InvalidRequestError(
`parameters must not be provided twice. ${dupes.join(',')}`));
new errors.InvalidRequestError(`parameters must not be provided twice. ${dupes.join(',')}`));
yield next;
};

@@ -10,10 +10,9 @@ 'use strict';

if (this.headers.authorization) {
this.assert(!this.oidc.params.client_id,
new errors.InvalidRequestError(
'combining multiple client authentication mechanism is no good'));
// client_secret_basic
this.assert(!this.oidc.params.client_id, new errors.InvalidRequestError(
'combining multiple client authentication mechanism is no good'));
const parts = this.headers.authorization.split(' ');
this.assert(parts.length === 2 && parts[0] === 'Basic',
new errors.InvalidRequestError(
'invalid authorization header value format'));
new errors.InvalidRequestError('invalid authorization header value format'));

@@ -24,4 +23,3 @@ const basic = new Buffer(parts[1], 'base64').toString('utf8');

this.assert(i !== -1,
new errors.InvalidRequestError(
'invalid authorization header value format'));
new errors.InvalidRequestError('invalid authorization header value format'));

@@ -31,4 +29,6 @@ this.oidc.authorization.clientId = basic.slice(0, i);

} else if (this.oidc.params.client_id && !this.oidc.params.client_assertion) {
// client_secret_post
this.oidc.authorization.clientId = this.oidc.params.client_id;
} else if (this.oidc.params.client_assertion) {
// client_secret_jwt and private_key_jwt
let assertionSub;

@@ -41,10 +41,7 @@

} catch (err) {
this.throw(new errors.InvalidRequestError(
'invalid client_assertion'));
this.throw(new errors.InvalidRequestError('invalid client_assertion'));
}
this.assert(!this.oidc.params.client_id ||
assertionSub === this.oidc.params.client_id,
new errors.InvalidRequestError(
'subject of client_assertion must be the same as client_id'));
this.assert(!this.oidc.params.client_id || assertionSub === this.oidc.params.client_id,
new errors.InvalidRequestError('subject of client_assertion must be the same as client_id'));

@@ -55,6 +52,5 @@ this.oidc.authorization.clientId = assertionSub;

this.assert(this.oidc.authorization.clientId,
new errors.InvalidClientError(
'no client authentication mechanism provided'));
new errors.InvalidClientError('no client authentication mechanism provided'));
yield next;
};
'use strict';
const _ = require('lodash');
const assert = require('assert');

@@ -9,7 +8,16 @@

class Params {
constructor(params) {
whitelist.forEach((prop) => {
this[prop] = params[prop];
});
Object.seal(this);
}
}
return function * assembleParams(next) {
const params = this.method === 'POST' ? this.request.body : this.query;
this.oidc.params = _.pick(params, whitelist);
this.oidc.params = new Params(params);
yield next;
};
};

@@ -7,7 +7,6 @@ 'use strict';

return function * loadClient(next) {
const client = yield provider.Client.find(this.oidc.authorization.clientId);
const client = yield provider.get('Client').find(this.oidc.authorization.clientId);
this.assert(client,
new errors.InvalidClientError(
'invalid client authentication provided (client not found)'));
this.assert(client, new errors.InvalidClientError(
'invalid client authentication provided (client not found)'));

@@ -14,0 +13,0 @@ this.oidc.client = client;

'use strict';
const j = JSON.parse;
const errors = require('../helpers/errors');

@@ -9,8 +10,8 @@ module.exports = function getResumeAction(provider) {

const cookieOptions = provider.configuration('cookies.short');
try {
this.query = j(this.cookies.get('_grant', provider.configuration.cookies.short));
this.query = j(this.cookies.get('_grant', cookieOptions));
} catch (err) {
this.body = 'authentication request has expired';
this.status = 400;
return;
throw new errors.InvalidRequestError('authorization request has expired');
}

@@ -20,3 +21,3 @@

try {
result = j(this.cookies.get('_grant_result', provider.configuration.cookies.short));
result = j(this.cookies.get('_grant_result', cookieOptions));
} catch (err) {

@@ -28,5 +29,5 @@ result = {};

if (!result.login.remember) {
// clear the existing session and create a fake one.
// clear the existing session and create a temp one.
yield this.oidc.session.destroy();
this.oidc.session = new provider.Session();
this.oidc.session = new (provider.get('Session'))();
}

@@ -39,6 +40,5 @@

// TODO: finish this
// if (result.consent) {
//
// }
if (result.consent && result.consent.scope !== undefined) {
this.query.scope = String(result.consent.scope);
}

@@ -45,0 +45,0 @@ this.oidc.result = result;

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

return function * sessionHandler(next) {
this.oidc.session = yield provider.Session.get(this);
this.oidc.session = yield provider.get('Session').get(this);
yield next;

@@ -8,0 +8,0 @@ yield this.oidc.session.save();

@@ -15,4 +15,3 @@ 'use strict';

this.throw(new errors.InvalidRequestError(
'client not supposed to access token endpoint'));
this.throw(new errors.InvalidRequestError('client not supposed to access token endpoint'));

@@ -30,4 +29,3 @@ /* istanbul ignore next */

yield tokenCredentialAuth.call(this, this.oidc.client.clientSecret,
params.client_secret);
yield tokenCredentialAuth.call(this, this.oidc.client.clientSecret, params.client_secret);

@@ -40,4 +38,3 @@ break;

this.oidc.client.tokenEndpointAuthSigningAlg ?
[this.oidc.client.tokenEndpointAuthSigningAlg] : ['HS256', 'HS384',
'HS512']);
[this.oidc.client.tokenEndpointAuthSigningAlg] : ['HS256', 'HS384', 'HS512']);

@@ -49,4 +46,4 @@ break;

this.oidc.client.tokenEndpointAuthSigningAlg ?
[this.oidc.client.tokenEndpointAuthSigningAlg] : ['ES256', 'ES384',
'ES512', 'RS256', 'RS384', 'RS512', 'PS256', 'PS384', 'PS512']);
[this.oidc.client.tokenEndpointAuthSigningAlg] : ['ES256', 'ES384', 'ES512', 'RS256',
'RS384', 'RS512', 'PS256', 'PS384', 'PS512']);

@@ -63,4 +60,3 @@ break;

yield tokenCredentialAuth.call(this, this.oidc.client.clientSecret,
auth.clientSecret);
yield tokenCredentialAuth.call(this, this.oidc.client.clientSecret, auth.clientSecret);
}

@@ -67,0 +63,0 @@ }

@@ -65,4 +65,4 @@ 'use strict';

'sub (JWT subject) must be the client id'));
const unique = yield provider.configuration.uniqueness(payload.jti, payload.exp);
const uniqueCheck = provider.configuration('uniqueness');
const unique = yield uniqueCheck(payload.jti, payload.exp);
this.assert(unique, new errors.InvalidRequestError(

@@ -69,0 +69,0 @@ 'jwt-bearer tokens must only be used once'));

'use strict';
module.exports = function getAccessToken(BaseOauthToken) {
module.exports = function getAccessToken(provider) {
const BaseOauthToken = provider.get('OAuthToken');
return class AccessToken extends BaseOauthToken {};
};
'use strict';
module.exports = function getAuthorizationCode(BaseOauthToken) {
module.exports = function getAuthorizationCode(provider) {
const BaseOauthToken = provider.get('OAuthToken');
return class AuthorizationCode extends BaseOauthToken {};
};
'use strict';
module.exports = function getClientCredentials(BaseOauthToken) {
module.exports = function getClientCredentials(provider) {
const BaseOauthToken = provider.get('OAuthToken');
return class ClientCredentials extends BaseOauthToken {};
};

@@ -5,3 +5,2 @@ /* eslint-disable newline-per-chained-call */

const _ = require('lodash');
const Joi = require('joi');
const url = require('url');

@@ -14,223 +13,39 @@ const jose = require('node-jose');

const errors = require('../helpers/errors');
const getSchema = require('../helpers/client_schema');
const KEY_ATTRIBUTES = ['crv', 'e', 'kid', 'kty', 'n', 'use', 'x', 'y'];
const KEY_TYPES = ['RSA', 'EC'];
const RECOGNIZED_METADATA = [
'application_type',
'client_id',
'client_name',
'client_secret',
'client_secret_expires_at',
'client_uri',
'contacts',
'default_acr_values',
'default_max_age',
'grant_types',
'id_token_encrypted_response_alg',
'id_token_encrypted_response_enc',
'id_token_signed_response_alg',
'initiate_login_uri',
'jwks',
'jwks_uri',
'logo_uri',
'policy_uri',
'post_logout_redirect_uris',
'redirect_uris',
'registration_access_token',
'request_object_encryption_alg',
'request_object_encryption_enc',
'request_object_signing_alg',
'request_uris',
'require_auth_time',
'response_types',
'sector_identifier_uri',
'subject_type',
'token_endpoint_auth_method',
'token_endpoint_auth_signing_alg',
'tos_uri',
'userinfo_encrypted_response_alg',
'userinfo_encrypted_response_enc',
'userinfo_signed_response_alg',
];
const SECRET_LENGTH_REQUIRED = [
'id_token_signed_response_alg',
'request_object_signing_alg',
'token_endpoint_auth_signing_alg',
'userinfo_signed_response_alg',
];
function handled(kty) {
return KEY_TYPES.indexOf(kty) !== -1;
}
// TODO: validate all
module.exports = function getClient(provider) {
const webUri = Joi.string().uri({
scheme: ['http', 'https'],
});
const Schema = getSchema(provider);
const cache = new Map();
function presenceDependant(field, value) {
return (client) => {
if (_.isUndefined(client[field])) {
return undefined;
}
return value;
};
}
function baseSchema() {
const conf = provider.configuration;
return Joi.object().keys({
application_type: Joi.string().valid('web', 'native').default('web'),
client_id: Joi.string().required(),
client_name: Joi.string(),
// TODO: validate secret length
client_secret: Joi.string().required(),
client_uri: webUri,
contacts: Joi.array().items(Joi.string().email()),
default_acr_values: Joi.array().items(Joi.string()),
default_max_age: Joi.number().integer().positive().strict(),
grant_types: Joi.array().min(1).items(conf.grantTypes)
.default(['authorization_code']),
id_token_signed_response_alg: Joi.string().when('response_types', {
is: Joi.array().items(Joi.string().regex(/token/).forbidden()),
then: Joi.string().valid(
conf.idTokenSigningAlgValues),
otherwise: Joi.string().valid(_.without(
conf.idTokenSigningAlgValues, 'none')),
}).default('RS256'),
initiate_login_uri: webUri,
redirect_uris: Joi.array().min(1).items(
Joi.string().regex(/#/).forbidden()).when('application_type', {
is: 'web',
then: Joi.array().items(webUri),
otherwise: Joi.array().items(Joi.string().uri()),
}).required(),
jwks_uri: webUri,
logo_uri: webUri,
policy_uri: webUri,
post_logout_redirect_uris: Joi.array().items(webUri).default([]),
request_object_signing_alg: Joi.string(
conf.requestObjectSigningAlgValues),
request_uris: Joi.array().items(Joi.string().uri({ scheme: ['https'] })).default(
conf.features.requestUri.requireRequestUriRegistration ? [] : undefined
),
require_auth_time: Joi.boolean().default(false),
response_types: Joi.array().min(1).items(conf.responseTypes)
.default(['code']),
sector_identifier_uri: Joi.string().uri({
scheme: ['https'],
}),
subject_type: Joi.string().valid(conf.subjectTypes)
.default('public'),
token_endpoint_auth_method: Joi.string().valid(
conf.tokenEndpointAuthMethods).default('client_secret_basic'),
tos_uri: webUri,
userinfo_signed_response_alg: Joi.string().valid(
conf.userinfoSigningAlgValues).default(undefined),
id_token_encrypted_response_alg: Joi.string()
.valid(conf.idTokenEncryptionAlgValues).default(undefined),
id_token_encrypted_response_enc: Joi.string()
.valid(conf.idTokenEncryptionEncValues)
.default(presenceDependant(
'id_token_encrypted_response_alg', 'A128CBC-HS256'),
'id_token_encrypted_response_alg dependant default'),
userinfo_encrypted_response_alg: Joi.string()
.valid(conf.userinfoEncryptionAlgValues).default(undefined),
userinfo_encrypted_response_enc: Joi.string()
.valid(conf.userinfoEncryptionEncValues)
.default(presenceDependant(
'userinfo_encrypted_response_alg', 'A128CBC-HS256'),
'userinfo_encrypted_response_alg dependant default'),
})
.with('id_token_encrypted_response_enc', 'id_token_encrypted_response_alg')
.with('userinfo_encrypted_response_enc', 'userinfo_encrypted_response_alg')
.unknown();
}
function schemaValidate(meta) {
let metadata = meta;
let schema = baseSchema();
function schemaValidate(client, metadata) {
try {
const signingAlg = metadata.request_object_signing_alg;
const requireJwks =
metadata.token_endpoint_auth_method === 'private_key_jwt' ||
(signingAlg && signingAlg.startsWith('RS')) ||
(signingAlg && signingAlg.startsWith('ES'));
const schema = new Schema(metadata);
if (requireJwks) {
schema = schema.or('jwks', 'jwks_uri');
}
metadata = Joi.attempt(_.chain(metadata).omitBy(_.isNull)
.pick(RECOGNIZED_METADATA).value(), schema);
const hsLengths = SECRET_LENGTH_REQUIRED.map((prop) => {
if (metadata[prop] && metadata[prop].startsWith('HS')) {
return parseInt(metadata[prop].slice(-3) / 8, 10);
}
return undefined;
Object.defineProperty(client, 'sectorIdentifier', {
enumerable: false,
writable: true,
});
const validateSecretLength = _.max(hsLengths);
Object.assign(client, _.mapKeys(schema, (value, key) => _.camelCase(key)));
if (validateSecretLength) {
Joi.assert(metadata, Joi.object().keys({
client_secret: Joi.string().min(validateSecretLength),
}).unknown());
}
const rts = _.chain(metadata.response_types).map(rt => rt.split(' '))
.flatten().uniq().value();
if (_.includes(rts, 'code')) {
Joi.assert(metadata.grant_types,
Joi.array().items(
Joi.string().valid('authorization_code').required(),
Joi.string()));
}
if (_.includes(rts, 'token') || _.includes(rts, 'id_token')) {
Joi.assert(metadata.grant_types,
Joi.array().items(
Joi.string().valid('implicit').required(),
Joi.string()));
}
if (metadata.subject_type === 'pairwise' &&
!metadata.sector_identifier_uri) {
const hosts = _.chain(metadata.redirect_uris)
.map(uri => url.parse(uri).host).uniq().value();
if (hosts.length === 1) {
metadata.sector_identifier = hosts[0];
} else {
throw new Error('sector_identifier_uri is required when using ' +
'multiple hosts in your redirect_uris');
}
} else if (metadata.sector_identifier_uri) {
metadata.sector_identifier =
url.parse(metadata.sector_identifier_uri).host;
}
return Promise.resolve(metadata);
return Promise.resolve(client);
} catch (err) {
const redirectUriError = err.details && err.details.length === 1 &&
err.details[0].path.startsWith('redirect_uri');
const message = _.map(err.details,
member => `Validation error '${member.message}' in path '${member.path}'`).join('. ');
return Promise.reject(new errors.InvalidClientMetadata(
message || err.message, redirectUriError ?
'invalid_redirect_uri' : undefined));
return Promise.reject(err);
}
}
function sectorValidate(metadata) {
if (metadata.sector_identifier_uri !== undefined) {
return got(metadata.sector_identifier_uri, {
function sectorValidate(client) {
if (client.sectorIdentifierUri !== undefined) {
return got(client.sectorIdentifierUri, {
headers: {
'User-Agent': provider.userAgent(),
},
timeout: provider.configuration.timeouts.sector_identifier_uri,
timeout: provider.configuration('timeouts.sector_identifier_uri'),
retries: 0,

@@ -245,3 +60,3 @@ followRedirect: false,

'sector_identifier_uri must return single JSON array');
const missing = metadata.redirect_uris.find((uri) => body.indexOf(uri) === -1);
const missing = client.redirectUris.find((uri) => body.indexOf(uri) === -1);
assert(!missing,

@@ -253,3 +68,3 @@ 'all registered redirect_uris must be included in the sector_identifier_uri');

return metadata;
return client;
}, (error) => {

@@ -261,15 +76,2 @@ throw new errors.InvalidClientMetadata(

return metadata;
}
function buildClient(metadata) {
const client = new Client(); // eslint-disable-line no-use-before-define
Object.defineProperty(client, 'sectorIdentifier', {
enumerable: false,
writable: true,
});
Object.assign(client, _.mapKeys(metadata, (value, key) => _.camelCase(key)));
return client;

@@ -283,5 +85,3 @@ }

client.keystore.refresh = function refreshKeyStore() {
if (!this.jwksUri) {
return Promise.resolve();
}
if (!this.jwksUri) return Promise.resolve();

@@ -292,3 +92,3 @@ return got(this.jwksUri, {

},
timeout: provider.configuration.timeouts.jwks_uri,
timeout: provider.configuration('timeouts.jwks_uri'),
retries: 0,

@@ -302,5 +102,3 @@ followRedirect: false,

if (!Array.isArray(body.keys)) {
throw new Error('invalid jwks_uri response');
}
if (!Array.isArray(body.keys)) throw new Error('invalid jwks_uri response');

@@ -311,3 +109,3 @@ const promises = [];

body.keys.forEach((key) => {
if (KEY_TYPES.indexOf(key.kty) !== -1 && !this.get(key.kid)) {
if (handled(key.kty) && !this.get(key.kid)) {
promises.push(this.add(_.pick(key, KEY_ATTRIBUTES)));

@@ -318,3 +116,3 @@ }

this.all().forEach((key) => {
if (KEY_TYPES.indexOf(key.kty) !== -1 && kids.indexOf(key.kid) === -1) {
if (handled(key.kty) && kids.indexOf(key.kid) === -1) {
promises.push(this.remove(key));

@@ -334,3 +132,3 @@ }

client.jwks.keys.forEach((key) => {
if (KEY_TYPES.indexOf(key.kty) !== -1) {
if (handled(key.kty)) {
promises.push(client.keystore.add(_.pick(key, KEY_ATTRIBUTES)));

@@ -356,5 +154,3 @@ }

function register(client) {
client.constructor.clients = client.constructor.clients || /* istanbul ignore next */ {};
client.constructor.clients[client.clientId] = client;
cache.set(client.clientId, client);
return client;

@@ -366,3 +162,3 @@ }

static get adapter() {
const Adapter = provider.configuration.adapter;
const Adapter = provider.configuration('adapter');
if (!this._adapter) {

@@ -402,6 +198,9 @@ this._adapter = new Adapter(this.name);

metadata() {
return _.mapKeys(this, (value, key) => _.snakeCase(key));
}
static add(metadata) {
return schemaValidate(metadata)
return schemaValidate(new this(), metadata)
.then(sectorValidate)
.then(buildClient)
.then(buildKeyStore)

@@ -412,11 +211,13 @@ .then(register);

static remove(id) {
this.clients = this.clients || /* istanbul ignore next */ {};
delete this.clients[id];
cache.delete(id);
return this.adapter.destroy(id);
}
static purge() {
cache.clear();
}
static find(id) {
this.clients = this.clients || /* istanbul ignore next */ {};
if (this.clients[id]) {
return Promise.resolve(this.clients[id]);
if (cache.has(id)) {
return Promise.resolve(cache.get(id));
}

@@ -423,0 +224,0 @@

@@ -12,3 +12,3 @@ 'use strict';

module.exports = function getIdToken(provider) {
const Claims = getMask(provider.configuration);
const Claims = getMask(provider.configuration());

@@ -23,13 +23,5 @@ return class IdToken {

static get expiresIn() {
/* istanbul ignore if */
if (!this.ttl) {
throw new Error('expiresIn not set');
}
return this.ttl;
return provider.configuration(`ttl.${this.name}`);
}
static set expiresIn(ttl) {
this.ttl = ttl;
}
set(key, value) {

@@ -62,4 +54,4 @@ this.extra[key] = value;

const key = alg &&
alg.startsWith('HS') ? client.keystore.get({ alg }) : provider.keystore.get({ alg });
const keystore = alg && alg.startsWith('HS') ? client.keystore : provider.keystore;
const key = keystore && keystore.get({ alg });

@@ -92,3 +84,2 @@ const payload = this.payload();

if (encryption.enc) {
// TODO: refresh when?
return promise.then((signed) => client.keystore.refresh().then(() => signed))

@@ -95,0 +86,0 @@ .then((signed) => {

@@ -37,3 +37,3 @@ 'use strict';

static get adapter() {
const Adapter = provider.configuration.adapter;
const Adapter = provider.configuration('adapter');
if (!this._adapter) {

@@ -50,13 +50,5 @@ this._adapter = new Adapter(this.name);

static get expiresIn() {
/* istanbul ignore if */
if (!this.ttl) {
throw new Error('expiresIn not set');
}
return this.ttl;
return provider.configuration(`ttl.${this.name}`);
}
static set expiresIn(ttl) {
this.ttl = ttl;
}
get standardPayload() {

@@ -63,0 +55,0 @@ return IN_PAYLOAD;

'use strict';
module.exports = function getRefreshToken(BaseOauthToken) {
module.exports = function getRefreshToken(provider) {
const BaseOauthToken = provider.get('OAuthToken');
return class RefreshToken extends BaseOauthToken {};
};

@@ -14,3 +14,3 @@ 'use strict';

static get adapter() {
const Adapter = provider.configuration.adapter;
const Adapter = provider.configuration('adapter');
if (!this._adapter) {

@@ -36,3 +36,3 @@ this._adapter = new Adapter(this.name);

acr() {
const conf = provider.configuration;
const conf = provider.configuration();
if ((Date.now() / 1000 | 0) - this.authTime() < conf.ttl.acr) {

@@ -55,5 +55,8 @@ return _.get(this, 'acrValue', conf.acrValues[0]);

save() {
if (this.id) {
return this.adapter.upsert(this.id, Object.assign({}, this),
provider.configuration.cookies.long.maxAge / 1000);
const payload = Object.assign({}, this);
delete payload.id;
if (this.id && !_.isEmpty(payload)) {
return this.adapter.upsert(this.id, payload,
provider.configuration('cookies.long.maxAge') / 1000);
}

@@ -72,15 +75,13 @@

static * get(ctx) {
static get(ctx) {
// is there supposed to be a session bound? generate if not
const sessionId = ctx.cookies.get('_session', {
signed: provider.configuration.cookies.long.signed,
signed: provider.configuration('cookies.long.signed'),
}) || uuid.v4();
const session = yield this.find(sessionId);
// refresh the session duration
ctx.cookies.set('_session', sessionId,
provider.configuration.cookies.long);
return session;
return this.find(sessionId).then((session) => {
// refresh the session duration
ctx.cookies.set('_session', sessionId, provider.configuration('cookies.long'));
return session;
});
}

@@ -87,0 +88,0 @@ }

@@ -9,3 +9,2 @@ {

"http-errors": "^1.4.0",
"joi": "^8.0.5",
"koa": "^1.0.0",

@@ -18,3 +17,4 @@ "koa-body": "^1.2.1",

"node-jose": "^0.8.0",
"node-uuid": "^1.4.7"
"node-uuid": "^1.4.7",
"valid-url": "^1.0.9"
},

@@ -60,3 +60,3 @@ "description": "OpenID Provider (OP) implementation for Node.js OpenID Connect servers.",

},
"version": "0.6.0",
"version": "0.7.0",
"files": [

@@ -63,0 +63,0 @@ "lib"

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