From 5b8d77a555cc6d720d3983a24e1a8eba8450c0a6 Mon Sep 17 00:00:00 2001 From: tigerbot Date: Wed, 28 Jun 2017 17:51:24 -0600 Subject: [PATCH] changed the id used to store JWKs --- models.js | 2 +- rest.js | 38 ++++++++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/models.js b/models.js index 47d54eb..f07fe96 100644 --- a/models.js +++ b/models.js @@ -8,6 +8,6 @@ module.exports = [ tablename: apiname + '_jwks', idname: 'id', unique: ['id'], - indices: baseFields.concat([ 'kty', 'kid' ]), + indices: baseFields.concat([ 'kty', 'kid', 'sub' ]), } ]; diff --git a/rest.js b/rest.js index 09788b9..da4b57e 100644 --- a/rest.js +++ b/rest.js @@ -6,12 +6,18 @@ var crypto = require('crypto'); module.exports.create = function (bigconf, deps, app) { var Jwks = { restful: {} }; - function attachModels(req, res, next) { - return req.getSiteStore().then(function (models) { - req.Models = models; + // This tablename is based on the tablename found in the objects in model.js. + // Instead of the snake_case the name with be UpperCammelCase, converted by masterquest-sqlite3. + function attachSiteStore(tablename, req, res, next) { + return req.getSiteStore().then(function (store) { + req.Store = store[tablename]; next(); }); } + function detachSiteStore(req, res, next) { + delete req.Store; + next(); + } Jwks.thumbprint = function (jwk) { // To produce a thumbprint we need to create a JSON string with only the required keys for @@ -42,10 +48,15 @@ module.exports.create = function (bigconf, deps, app) { }; Jwks.restful.get = function (req, res) { - var promise = req.Models.IssuerOauth3OrgJwks.find({ kid: req.params.kid }, { limit: 1 }).then(function (jwkArr) { - var jwk = jwkArr[0]; + var promise = req.Store.find({ kid: req.params.kid }, { limit: 1 }).then(function (results) { + if (!results.length) { + throw new Error('no keys stored with kid "'+req.params.kid+'"'); + } + var jwk = results[0]; + // We need to sanitize the key to make sure we don't deliver any private keys fields if - // we were given a key we could use to sign tokens on behalf of the user. + // we were given a key we could use to sign tokens on behalf of the user. We also don't + // want to deliver the sub or any other PPIDs. var whitelist = [ 'kty', 'alg', 'kid', 'use' ]; if (jwk.kty === 'EC') { whitelist = whitelist.concat([ 'crv', 'x', 'y' ]); @@ -69,8 +80,17 @@ module.exports.create = function (bigconf, deps, app) { throw new Error('provided kid "'+jwk.kid+'" does not match calculated "'+kid+'"'); } jwk.kid = kid; + jwk.sub = req.params.sub; - return req.Models.IssuerOauth3OrgJwks.upsert(req.params.sub, jwk); + return req.Store.find({ kid: jwk.kid, sub: jwk.sub}).then(function (results) { + if (!results.length) { + return crypto.randomBytes(32).toString('hex'); + } else { + return results[0].id; + } + }).then(function (id) { + return req.Store.upsert(id, jwk); + }); }).then(function () { return { success: true }; }); @@ -78,7 +98,9 @@ module.exports.create = function (bigconf, deps, app) { app.handlePromise(req, res, promise, "[issuer@oauth3.org] create JWK"); }; - app.use( '/jwks', attachModels); + app.use( '/jwks', attachSiteStore.bind(null, 'IssuerOauth3OrgJwks')); app.get( '/jwks/:kid.json', Jwks.restful.get); app.post( '/jwks/:sub', Jwks.restful.saveNew); + + app.use(detachSiteStore); };