diff --git a/lib/db/json.js b/lib/db/json.js index e49615c1fb4f5c2f495c9246cb8bcb4dbb695684..376a2a791cae9a968949a202772df5c2193d552f 100644 --- a/lib/db/json.js +++ b/lib/db/json.js @@ -236,7 +236,7 @@ exports.emailForVerificationSecret = function(secret, cb) { process.nextTick(function() { sync(); if (!db.staged[secret]) return cb("no such secret"); - cb(null, db.staged[secret].email, db.staged[secret].existing_user); + cb(null, db.staged[secret].email, db.staged[secret].existing_user, db.staged[secret].passwd); }); }; diff --git a/lib/db/mysql.js b/lib/db/mysql.js index b2e123ae6667e7c150963f627f0af30ba9c491bc..6a7b6f94700d94086262e329dc4821507bcc0fbf 100644 --- a/lib/db/mysql.js +++ b/lib/db/mysql.js @@ -265,14 +265,14 @@ exports.haveVerificationSecret = function(secret, cb) { exports.emailForVerificationSecret = function(secret, cb) { client.query( - "SELECT email, existing_user FROM staged WHERE secret = ?", [ secret ], + "SELECT email, existing_user, passwd FROM staged WHERE secret = ?", [ secret ], function(err, rows) { if (err) return cb("database unavailable"); // if the record was not found, fail out if (!rows || rows.length != 1) return cb("no such secret"); - cb(null, rows[0].email, rows[0].existing_user); + cb(null, rows[0].email, rows[0].existing_user, rows[0].passwd); }); }; diff --git a/lib/wsapi/email_for_token.js b/lib/wsapi/email_for_token.js index f492bcff595e0978c7f96e24f31b287fdceb8851..ac0a5d9543514ac4cb74c1ab3986eded0ad63421 100644 --- a/lib/wsapi/email_for_token.js +++ b/lib/wsapi/email_for_token.js @@ -19,7 +19,7 @@ exports.args = ['token']; exports.i18n = false; exports.process = function(req, res) { - db.emailForVerificationSecret(req.query.token, function(err, email, uid) { + db.emailForVerificationSecret(req.query.token, function(err, email, uid, hash) { if (err) { if (err === 'database unavailable') { httputils.serviceUnavailable(res, err); @@ -30,24 +30,64 @@ exports.process = function(req, res) { }); } } else { - // 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 - // browser as the initiator - var must_auth = true; + 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 + // browser as the initiator + var must_auth = true; - if (uid && req.session.userid === uid) { - must_auth = false; + if (uid && req.session.userid === uid) { + must_auth = false; + } + else if (!uid && typeof req.session.pendingCreation === 'string' && + req.query.token === req.session.pendingCreation) { + must_auth = false; + } + + res.json({ + success: true, + email: email, + must_auth: must_auth + }); + } + + // backwards compatibility - issue #1592 + // if there is no password in the user record, and no password in the staged + // table, then we require a password be fetched from the user upon verification. + // these checks are temporary and should disappear in 1 trains time. + function needsPassword() { + // no password is set neither in the user table nor in the staged record. + // the user must pick a password + res.json({ + success: true, + email: email, + needs_password: true + }); } - else if (!uid && typeof req.session.pendingCreation === 'string' && - req.query.token === req.session.pendingCreation) { - must_auth = false; + + if (!hash) { + if (!uid) { + needsPassword(); + } else { + db.checkAuth(uid, function(err, hash) { + if (err) { + return res.json({ + success: false, + reason: err + }); + } + + if (!hash) { + needsPassword(); + } else { + checkMustAuth(); + } + }); + } + } else { + checkMustAuth(); } - res.json({ - success: true, - email: email, - must_auth: must_auth - }); } }); };