forked from coolaj86/goldilocks.js
AJ ONeal
7 years ago
9 changed files with 392 additions and 86 deletions
@ -1,18 +1,124 @@ |
|||
'use strict'; |
|||
|
|||
module.exports.create = function (opts) { |
|||
module.exports.dependencies = [ 'storage.owners' ]; |
|||
module.exports.create = function (deps) { |
|||
var scmp = require('scmp'); |
|||
var crypto = require('crypto'); |
|||
var jwt = require('jsonwebtoken'); |
|||
var bodyParser = require('body-parser'); |
|||
var jsonParser = bodyParser.json({ |
|||
inflate: true, limit: '100kb', reviver: null, strict: true /* type, verify */ |
|||
}); |
|||
|
|||
return function (req, res) { |
|||
jsonParser(req, res, function () { |
|||
|
|||
console.log('req.body', req.body); |
|||
/* |
|||
var owners; |
|||
deps.storage.owners.on('set', function (_owners) { |
|||
owners = _owners; |
|||
}); |
|||
*/ |
|||
deps.storage.owners.exists = function (id) { |
|||
return deps.storage.owners.all().then(function (owners) { |
|||
return owners.some(function (owner) { |
|||
return scmp(id, owner.id); |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
function isAuthorized(req, res, fn) { |
|||
var auth = jwt.decode((req.headers.authorization||'').replace(/^bearer\s+/i, '')); |
|||
if (!auth) { |
|||
res.setHeader('Content-Type', 'application/json;'); |
|||
res.end(JSON.stringify({ error: { message: "Not Implemented", code: "E_NO_IMPL" } })); |
|||
res.end(JSON.stringify({ error: { message: "no token", code: 'E_NO_TOKEN', uri: undefined } })); |
|||
return; |
|||
} |
|||
|
|||
var id = crypto.createHash('sha256').update(auth.sub).digest('hex'); |
|||
return deps.storage.owners.exists(id).then(function (exists) { |
|||
if (!exists) { |
|||
res.setHeader('Content-Type', 'application/json;'); |
|||
res.end(JSON.stringify({ error: { message: "not authorized", code: 'E_NO_AUTHZ', uri: undefined } })); |
|||
return; |
|||
} |
|||
|
|||
fn(); |
|||
}); |
|||
} |
|||
|
|||
return { |
|||
init: function (req, res) { |
|||
jsonParser(req, res, function () { |
|||
|
|||
console.log('req.body', req.body); |
|||
var auth = jwt.decode((req.headers.authorization||'').replace(/^bearer\s+/i, '')); |
|||
var token = jwt.decode(req.body.access_token); |
|||
var refresh = jwt.decode(req.body.refresh_token); |
|||
auth.sub = auth.sub || auth.acx.id; |
|||
token.sub = token.sub || token.acx.id; |
|||
refresh.sub = refresh.sub || refresh.acx.id; |
|||
|
|||
// TODO validate token with issuer, but as-is the sub is already a secret
|
|||
var id = crypto.createHash('sha256').update(auth.sub).digest('hex'); |
|||
var tid = crypto.createHash('sha256').update(token.sub).digest('hex'); |
|||
var rid = crypto.createHash('sha256').update(refresh.sub).digest('hex'); |
|||
|
|||
console.log('ids', id, tid, rid); |
|||
return deps.storage.owners.all().then(function (results) { |
|||
console.log('results', results); |
|||
var err; |
|||
|
|||
// There is no owner yet. First come, first serve.
|
|||
if (!results || !results.length) { |
|||
if (tid !== id || rid !== id) { |
|||
err = new Error("When creating an owner the Authorization Bearer and Token and Refresh must all match"); |
|||
return deps.PromiseA.reject(err); |
|||
} |
|||
console.log('no owner, creating'); |
|||
return deps.storage.owners.set(id, { token: token, refresh: refresh }); |
|||
} |
|||
console.log('has results'); |
|||
|
|||
// There are onwers. Is this one of them?
|
|||
if (!results.some(function (token) { |
|||
return scmp(id, token.id); |
|||
})) { |
|||
err = new Error("Authorization token does not belong to an existing owner."); |
|||
return deps.PromiseA.reject(err); |
|||
} |
|||
console.log('has correct owner'); |
|||
|
|||
// We're adding an owner, unless it already exists
|
|||
if (!results.some(function (token) { |
|||
return scmp(tid, token.id); |
|||
})) { |
|||
console.log('adds new owner with existing owner'); |
|||
return deps.storage.owners.set(id, { token: token, refresh: refresh }); |
|||
} |
|||
}).then(function () { |
|||
res.setHeader('Content-Type', 'application/json;'); |
|||
res.end(JSON.stringify({ success: true })); |
|||
}, function (err) { |
|||
res.setHeader('Content-Type', 'application/json;'); |
|||
res.end(JSON.stringify({ error: { message: err.message, code: err.code, uri: err.uri } })); |
|||
}); |
|||
|
|||
}); |
|||
} |
|||
, config: function (req, res) { |
|||
isAuthorized(req, res, function () { |
|||
if ('POST' !== req.method) { |
|||
res.setHeader('Content-Type', 'application/json;'); |
|||
res.end(JSON.stringify(deps.recase.snakeCopy(deps.options))); |
|||
return; |
|||
} |
|||
|
|||
jsonParser(req, res, function () { |
|||
|
|||
console.log('req.body', req.body); |
|||
|
|||
deps.storage.config.merge(req.body); |
|||
deps.storage.config.save(); |
|||
}); |
|||
}); |
|||
} |
|||
}; |
|||
}; |
|||
|
@ -1 +1 @@ |
|||
Subproject commit eff1fd11272472e8f6d03ac8b897a9853810672e |
|||
Subproject commit f179cfe3c9553718676db24f1203f67ea0427662 |
Loading…
Reference in new issue