From f937b1ef696721eb3ceef778322cbc30fd1642dd Mon Sep 17 00:00:00 2001 From: Lloyd Hilaiel <lloyd@hilaiel.com> Date: Tue, 1 Nov 2011 18:38:14 -0600 Subject: [PATCH] break 'checkParams' feature out into a separate file so it can be shared by multiple processes - issue #460 --- lib/browserid/wsapi.js | 42 ++++++------------------ lib/validate.js | 72 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 32 deletions(-) create mode 100644 lib/validate.js diff --git a/lib/browserid/wsapi.js b/lib/browserid/wsapi.js index c46c514b1..410c8e285 100644 --- a/lib/browserid/wsapi.js +++ b/lib/browserid/wsapi.js @@ -47,30 +47,8 @@ bcrypt = require('bcrypt'), crypto = require('crypto'), logger = require('logging.js').logger, ca = require('./ca.js'), -config = require('configuration.js'); - -function checkParams(params) { - return function(req, resp, next) { - var params_in_request=null; - if (req.method === "POST") { - params_in_request = req.body; - } else { - params_in_request = req.query; - } - - try { - params.forEach(function(k) { - if (!params_in_request.hasOwnProperty(k) || typeof params_in_request[k] !== 'string') { - throw k; - } - }); - } catch(e) { - logger.error(e.toString()); - return httputils.badRequest(resp, "missing '" + e + "' argument"); - } - next(); - }; -} +config = require('configuration.js'), +validate = require('validate'); // log a user out, clearing everything from their session except the csrf token function clearAuthenticatedUser(session) { @@ -172,7 +150,7 @@ function setup(app) { * user via their claimed email address. Upon timeout expiry OR clickthrough * the staged user account transitions to a valid user account */ - app.post('/wsapi/stage_user', checkParams([ "email", "site" ]), function(req, resp) { + app.post('/wsapi/stage_user', validate([ "email", "site" ]), function(req, resp) { // staging a user logs you out. clearAuthenticatedUser(req.session); @@ -259,7 +237,7 @@ function setup(app) { }); }; - app.post('/wsapi/complete_user_creation', checkParams(["token", "pass"]), function(req, resp) { + app.post('/wsapi/complete_user_creation', validate(["token", "pass"]), function(req, resp) { // issue #155, valid password length is between 8 and 80 chars. if (req.body.pass.length < 8 || req.body.pass.length > 80) { httputils.badRequest(resp, "valid passwords are between 8 and 80 chars"); @@ -299,7 +277,7 @@ function setup(app) { }); }); - app.post('/wsapi/stage_email', checkAuthed, checkParams(["email", "site"]), function (req, resp) { + app.post('/wsapi/stage_email', checkAuthed, validate(["email", "site"]), function (req, resp) { db.lastStaged(req.body.email, function (last) { if (last && (new Date() - last) < config.get('min_time_between_emails_ms')) { logger.warn('throttling request to stage email address ' + req.body.email + ', only ' + @@ -326,7 +304,7 @@ function setup(app) { }); }); - app.get('/wsapi/email_for_token', checkParams(["token"]), function(req,resp) { + app.get('/wsapi/email_for_token', validate(["token"]), function(req,resp) { db.emailForVerificationSecret(req.query.token, function(email) { resp.json({ email: email }); }); @@ -372,7 +350,7 @@ function setup(app) { }); }); - app.post('/wsapi/complete_email_addition', checkParams(["token"]), function(req, resp) { + app.post('/wsapi/complete_email_addition', validate(["token"]), function(req, resp) { db.gotVerificationSecret(req.body.token, undefined, function(e) { if (e) { logger.warn("couldn't complete email verification: " + e); @@ -383,7 +361,7 @@ function setup(app) { }); }); - app.post('/wsapi/authenticate_user', checkParams(["email", "pass"]), function(req, resp) { + app.post('/wsapi/authenticate_user', validate(["email", "pass"]), function(req, resp) { db.checkAuth(req.body.email, function(hash) { if (typeof hash !== 'string' || typeof req.body.pass !== 'string') @@ -418,7 +396,7 @@ function setup(app) { }); }); - app.post('/wsapi/remove_email', checkAuthed, checkParams(["email"]), function(req, resp) { + app.post('/wsapi/remove_email', checkAuthed, validate(["email"]), function(req, resp) { var email = req.body.email; db.removeEmail(req.session.authenticatedUser, email, function(error) { @@ -440,7 +418,7 @@ function setup(app) { }}); }); - app.post('/wsapi/cert_key', checkAuthed, checkParams(["email", "pubkey"]), function(req, resp) { + app.post('/wsapi/cert_key', checkAuthed, validate(["email", "pubkey"]), function(req, resp) { db.emailsBelongToSameAccount(req.session.authenticatedUser, req.body.email, function(sameAccount) { // not same account? big fat error if (!sameAccount) return httputils.badRequest(resp, "that email does not belong to you"); diff --git a/lib/validate.js b/lib/validate.js new file mode 100644 index 000000000..281b57691 --- /dev/null +++ b/lib/validate.js @@ -0,0 +1,72 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla BrowserID. + * + * The Initial Developer of the Original Code is Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Lloyd Hilaiel <lloyd@hilaiel.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// a teensy tinsy module to do parameter validation. A good candiate for future +// librification. +// +// usage: +// +// const validate = require('validate.js'); +// +// app.post('/wsapi/foo', validate([ "email", "site" ]), function(req, resp) { +// }); + +const +logger = require('./logging.js').logger, +httputils = require('httputils.js'); + +module.exports = function (params) { + return function(req, resp, next) { + var params_in_request=null; + if (req.method === "POST") { + params_in_request = req.body; + } else { + params_in_request = req.query; + } + + try { + params.forEach(function(k) { + if (!params_in_request.hasOwnProperty(k) || typeof params_in_request[k] !== 'string') { + throw k; + } + }); + } catch(e) { + logger.error(e.toString()); + return httputils.badRequest(resp, "missing '" + e + "' argument"); + } + next(); + }; +}; -- GitLab