From ff37329a6ee77b1f4cd2700003643d6d150cdf90 Mon Sep 17 00:00:00 2001 From: Zachary Carter <zack.carter@gmail.com> Date: Thu, 19 Jul 2012 16:31:49 -0700 Subject: [PATCH] Ensure that when a user verifies in a different browser than what they reset their password with, they must authenticate to complete the verification --- lib/wsapi/email_for_token.js | 10 +++--- tests/forgotten-pass-test.js | 62 ++++++++++++++++++++++++++++++++++++ tests/lib/wsapi.js | 11 ++++++- 3 files changed, 77 insertions(+), 6 deletions(-) diff --git a/lib/wsapi/email_for_token.js b/lib/wsapi/email_for_token.js index 3aed92174..66f9a6398 100644 --- a/lib/wsapi/email_for_token.js +++ b/lib/wsapi/email_for_token.js @@ -42,20 +42,20 @@ exports.process = function(req, res) { function checkMustAuth() { // must the user authenticate? This is true if they are not authenticated - // as the uid who initiated the verification, and they are not on the same + // as the uid who initiated the verification, or they are not on the same // browser as the initiator var must_auth = true; - if (uid && req.session.userid === uid) { + if (uid && req.session.userid === uid && + typeof req.session.pendingReset === 'string' && + req.params.token === req.session.pendingReset) { must_auth = false; } else if (!uid && typeof req.session.pendingCreation === 'string' && req.params.token === req.session.pendingCreation) { must_auth = false; } - else if (typeof req.session.pendingReset === 'string' && - req.params.token === req.session.pendingReset) - { + else if (typeof req.session.pendingReverification === 'string') { must_auth = false; } // NOTE: for reverification, we require you're authenticated. it's not enough diff --git a/tests/forgotten-pass-test.js b/tests/forgotten-pass-test.js index 7e9aae487..fff015c37 100755 --- a/tests/forgotten-pass-test.js +++ b/tests/forgotten-pass-test.js @@ -286,6 +286,68 @@ suite.addBatch({ }, }); +// Test issue #2104: when using a second browser to initiate password reset, first +// browser should be prompted to authenticate + +// New context for a second client +var oldContext; +suite.addBatch({ + "change context": function () { + oldContext = wsapi.getContext(); + wsapi.setContext({}); + } +}); + +// Run the "forgot_email" flow with first address. +suite.addBatch({ + "reset password on first account": { + topic: wsapi.post('/wsapi/stage_reset', { + email: 'first@fakeemail.com', + pass: 'secondfakepass', + site:'https://otherfakesite.com' + }), + "works": function(err, r) { + assert.strictEqual(r.code, 200); + } + } +}); + +// wait for the token +suite.addBatch({ + "a token": { + topic: function() { + start_stop.waitForToken(this.callback); + }, + "is obtained": function (t) { + assert.strictEqual(typeof t, 'string'); + token = t; + } + } +}); + +// restore context of first client +suite.addBatch({ + "restore context": function () { + wsapi.setContext(oldContext); + } +}); + +suite.addBatch({ + "given a token, getting an email": { + topic: function() { + wsapi.get('/wsapi/email_for_token', { token: token }).call(this); + }, + "account created": function(err, r) { + assert.equal(r.code, 200); + var body = JSON.parse(r.body); + assert.strictEqual(body.success, true); + assert.strictEqual(body.email, 'first@fakeemail.com'); + assert.strictEqual(body.must_auth, true); + } + } +}); + + // test list emails suite.addBatch({ "list emails API": { diff --git a/tests/lib/wsapi.js b/tests/lib/wsapi.js index 868c86d02..cd35cb64b 100644 --- a/tests/lib/wsapi.js +++ b/tests/lib/wsapi.js @@ -42,4 +42,13 @@ exports.getCSRF = function() { return context.session.csrf_token; } return null; -}; \ No newline at end of file +}; + +// allows for multiple clients +exports.setContext = function (cxt) { + context = cxt; +}; + +exports.getContext = function () { + return context; +}; -- GitLab