From 73a0c72c5ac404ed69c2e038a44ed017e1e5d21f Mon Sep 17 00:00:00 2001 From: tigerbot Date: Mon, 24 Jul 2017 11:52:06 -0600 Subject: [PATCH] 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 --- rest.js | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/rest.js b/rest.js index e713574..79bb634 100644 --- a/rest.js +++ b/rest.js @@ -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 });