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:
parent
2b07b0e6ae
commit
73a0c72c5a
37
rest.js
37
rest.js
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
var PromiseA = require('bluebird');
|
var PromiseA = require('bluebird');
|
||||||
var crypto = require('crypto');
|
var crypto = require('crypto');
|
||||||
|
var OpErr = PromiseA.OperationalError;
|
||||||
|
|
||||||
function makeB64UrlSafe(b64) {
|
function makeB64UrlSafe(b64) {
|
||||||
return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=*$/, '');
|
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,
|
// 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.
|
// 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) {
|
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));
|
var sub = token.sub || token.ppid || (token.acx && (token.acx.id || token.acx.appScopedId));
|
||||||
if (!sub) {
|
if (!sub) {
|
||||||
if (!Array.isArray(token.axs) || !token.axs.length) {
|
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) {
|
var allowed = token.axs.some(function (acc) {
|
||||||
return req.params.sub === (acc.id || acc.ppid || acc.appScopedId);
|
return req.params.sub === (acc.id || acc.ppid || acc.appScopedId);
|
||||||
});
|
});
|
||||||
if (!allowed) {
|
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;
|
sub = req.params.sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.params.sub !== 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();
|
next();
|
||||||
});
|
});
|
||||||
@ -101,20 +102,20 @@ module.exports.create = function (bigconf, deps, app) {
|
|||||||
|
|
||||||
return store.IssuerOauth3OrgGrants.find({ azpSub: req.params.sub }).then(function (results) {
|
return store.IssuerOauth3OrgGrants.find({ azpSub: req.params.sub }).then(function (results) {
|
||||||
if (!results.length) {
|
if (!results.length) {
|
||||||
throw new Error("unknown PPID '"+req.params.sub+"'");
|
throw new OpErr("unknown PPID '"+req.params.sub+"'");
|
||||||
}
|
}
|
||||||
if (results.length > 1) {
|
if (results.length > 1) {
|
||||||
// This should not ever happen since there is a check for PPID collisions when saving
|
// 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
|
// grants, but it's probably better to have this check anyway just incase something
|
||||||
// happens that isn't currently accounted for.
|
// 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);
|
return store.IssuerOauth3OrgJwks.get(results[0].sub+'/'+req.params.kid);
|
||||||
});
|
});
|
||||||
}).then(function (jwk) {
|
}).then(function (jwk) {
|
||||||
if (!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
|
// 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 jwk = req.body;
|
||||||
var promise = Jwks.thumbprint(jwk).then(function (kid) {
|
var promise = Jwks.thumbprint(jwk).then(function (kid) {
|
||||||
if (jwk.kid && jwk.kid !== 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.kid = kid;
|
||||||
jwk.sub = req.params.sub;
|
jwk.sub = req.params.sub;
|
||||||
@ -167,7 +168,7 @@ module.exports.create = function (bigconf, deps, app) {
|
|||||||
Grants.restful.getOne = function (req, res) {
|
Grants.restful.getOne = function (req, res) {
|
||||||
var promise = req.Store.get(req.params.sub+'/'+req.params.azp).then(function (grant) {
|
var promise = req.Store.get(req.params.sub+'/'+req.params.azp).then(function (grant) {
|
||||||
if (!grant) {
|
if (!grant) {
|
||||||
throw new Error('no grants found');
|
throw new OpErr('no grants found');
|
||||||
}
|
}
|
||||||
return Grants.trim(grant);
|
return Grants.trim(grant);
|
||||||
});
|
});
|
||||||
@ -186,15 +187,15 @@ module.exports.create = function (bigconf, deps, app) {
|
|||||||
Grants.restful.saveNew = function (req, res) {
|
Grants.restful.saveNew = function (req, res) {
|
||||||
var promise = PromiseA.resolve().then(function () {
|
var promise = PromiseA.resolve().then(function () {
|
||||||
if (typeof req.body.scope !== 'string' || typeof req.body.sub !== 'string') {
|
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 });
|
return req.Store.find({ azpSub: req.body.sub });
|
||||||
}).then(function (existing) {
|
}).then(function (existing) {
|
||||||
if (existing.length) {
|
if (existing.length) {
|
||||||
if (existing.length > 1) {
|
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) {
|
} 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) {
|
return codeStore.get(codeId).then(function (code) {
|
||||||
if (!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 () {
|
return PromiseA.resolve().then(function () {
|
||||||
var attemptsLeft = 3 - (code.attempts && code.attempts.length || 0);
|
var attemptsLeft = 3 - (code.attempts && code.attempts.length || 0);
|
||||||
if (attemptsLeft <= 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) {
|
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
|
// TODO: maybe impose a rate limit, although going fast doesn't help you break the
|
||||||
// system when you can only try 3 times total.
|
// 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 params = req.body;
|
||||||
var promise = PromiseA.resolve().then(function () {
|
var promise = PromiseA.resolve().then(function () {
|
||||||
if (!params || !params.username) {
|
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)) {
|
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';
|
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);
|
return store.IssuerOauth3OrgGrants.get(req.params.sub+'/'+req.params.azp);
|
||||||
}).then(function (grant) {
|
}).then(function (grant) {
|
||||||
if (!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) {
|
return Tokens.getPrivKey(store, req.experienceId).then(function (jwk) {
|
||||||
var pem = require('jwk-to-pem')(jwk, { private: true });
|
var pem = require('jwk-to-pem')(jwk, { private: true });
|
||||||
|
Loading…
x
Reference in New Issue
Block a user