converted all thrown errors to PromiseA.OperationalError

this is to prevent walnut from logging the entire stack trace for errors
that aren't really bugs that need to be traced down
This commit is contained in:
tigerbot 2017-07-24 11:52:06 -06:00
parent 2b07b0e6ae
commit 73a0c72c5a
1 changed files with 19 additions and 18 deletions

37
rest.js
View File

@ -2,6 +2,7 @@
var PromiseA = require('bluebird');
var crypto = require('crypto');
var OpErr = PromiseA.OperationalError;
function makeB64UrlSafe(b64) {
return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=*$/, '');
@ -35,26 +36,26 @@ module.exports.create = function (bigconf, deps, app) {
// Now that we've confirmed the token is valid we also need to make sure the issuer, audience,
// and authorized party are all us, because no other app should be managing user identity.
if (token.iss !== req.experienceId || token.aud !== token.iss || token.azp !== token.iss) {
throw new Error("token does not allow access to requested resource");
throw new OpErr("token does not allow access to requested resource");
}
var sub = token.sub || token.ppid || (token.acx && (token.acx.id || token.acx.appScopedId));
if (!sub) {
if (!Array.isArray(token.axs) || !token.axs.length) {
throw new Error("no account pairwise identifier");
throw new OpErr("no account pairwise identifier");
}
var allowed = token.axs.some(function (acc) {
return req.params.sub === (acc.id || acc.ppid || acc.appScopedId);
});
if (!allowed) {
throw new Error("no account pairwise identifier matching '" + req.params.sub + "'");
throw new OpErr("no account pairwise identifier matching '" + req.params.sub + "'");
}
sub = req.params.sub;
}
if (req.params.sub !== sub) {
throw new Error("token does not allow access to resources for '"+req.params.sub+"'");
throw new OpErr("token does not allow access to resources for '"+req.params.sub+"'");
}
next();
});
@ -101,20 +102,20 @@ module.exports.create = function (bigconf, deps, app) {
return store.IssuerOauth3OrgGrants.find({ azpSub: req.params.sub }).then(function (results) {
if (!results.length) {
throw new Error("unknown PPID '"+req.params.sub+"'");
throw new OpErr("unknown PPID '"+req.params.sub+"'");
}
if (results.length > 1) {
// This should not ever happen since there is a check for PPID collisions when saving
// grants, but it's probably better to have this check anyway just incase something
// happens that isn't currently accounted for.
throw new Error('PPID collision - unable to safely retrieve keys');
throw new OpErr('PPID collision - unable to safely retrieve keys');
}
return store.IssuerOauth3OrgJwks.get(results[0].sub+'/'+req.params.kid);
});
}).then(function (jwk) {
if (!jwk) {
throw new Error("no keys stored with kid '"+req.params.kid+"' for PPID "+req.params.sub);
throw new OpErr("no keys stored with kid '"+req.params.kid+"' for PPID "+req.params.sub);
}
// We need to sanitize the key to make sure we don't deliver any private keys fields if
@ -140,7 +141,7 @@ module.exports.create = function (bigconf, deps, app) {
var jwk = req.body;
var promise = Jwks.thumbprint(jwk).then(function (kid) {
if (jwk.kid && jwk.kid !== kid) {
throw new Error('provided kid "'+jwk.kid+'" does not match calculated "'+kid+'"');
throw new OpErr('provided kid "'+jwk.kid+'" does not match calculated "'+kid+'"');
}
jwk.kid = kid;
jwk.sub = req.params.sub;
@ -167,7 +168,7 @@ module.exports.create = function (bigconf, deps, app) {
Grants.restful.getOne = function (req, res) {
var promise = req.Store.get(req.params.sub+'/'+req.params.azp).then(function (grant) {
if (!grant) {
throw new Error('no grants found');
throw new OpErr('no grants found');
}
return Grants.trim(grant);
});
@ -186,15 +187,15 @@ module.exports.create = function (bigconf, deps, app) {
Grants.restful.saveNew = function (req, res) {
var promise = PromiseA.resolve().then(function () {
if (typeof req.body.scope !== 'string' || typeof req.body.sub !== 'string') {
throw new Error("malformed request: 'sub' and 'scope' must be strings");
throw new OpErr("malformed request: 'sub' and 'scope' must be strings");
}
return req.Store.find({ azpSub: req.body.sub });
}).then(function (existing) {
if (existing.length) {
if (existing.length > 1) {
throw new Error("pre-existing PPID collision detected");
throw new OpErr("pre-existing PPID collision detected");
} else if (existing[0].sub !== req.params.sub || existing[0].azp !== req.params.azp) {
throw new Error("PPID collision detected, cannot save authorized party's sub");
throw new OpErr("PPID collision detected, cannot save authorized party's sub");
}
}
@ -237,16 +238,16 @@ module.exports.create = function (bigconf, deps, app) {
}
return codeStore.get(codeId).then(function (code) {
if (!code) {
throw new Error('authcode specified does not exist or has expired');
throw new OpErr('authcode specified does not exist or has expired');
}
return PromiseA.resolve().then(function () {
var attemptsLeft = 3 - (code.attempts && code.attempts.length || 0);
if (attemptsLeft <= 0) {
throw new Error('you have tried to authorize this code too many times');
throw new OpErr('you have tried to authorize this code too many times');
}
if (code.code !== token) {
throw new Error('you have entered the code incorrectly. '+attemptsLeft+' attempts remaining');
throw new OpErr('you have entered the code incorrectly. '+attemptsLeft+' attempts remaining');
}
// TODO: maybe impose a rate limit, although going fast doesn't help you break the
// system when you can only try 3 times total.
@ -293,10 +294,10 @@ module.exports.create = function (bigconf, deps, app) {
var params = req.body;
var promise = PromiseA.resolve().then(function () {
if (!params || !params.username) {
throw new Error("must provide the email address as 'username' in the body");
throw new OpErr("must provide the email address as 'username' in the body");
}
if ((params.username_type && 'email' !== params.username_type) || !/@/.test(params.username)) {
throw new Error("only email one-time login codes are supported at this time");
throw new OpErr("only email one-time login codes are supported at this time");
}
params.username_type = 'email';
@ -356,7 +357,7 @@ module.exports.create = function (bigconf, deps, app) {
return store.IssuerOauth3OrgGrants.get(req.params.sub+'/'+req.params.azp);
}).then(function (grant) {
if (!grant) {
throw new Error("'"+req.params.azp+"' not given any grants from '"+req.params.sub+"'");
throw new OpErr("'"+req.params.azp+"' not given any grants from '"+req.params.sub+"'");
}
return Tokens.getPrivKey(store, req.experienceId).then(function (jwk) {
var pem = require('jwk-to-pem')(jwk, { private: true });