diff --git a/browserid/lib/db_json.js b/browserid/lib/db_json.js index 89cc299fec1cd2a95668976ec4c42916e34cdc4a..3bfa8991b9eeb67894d6be4f03fa2545c650c64a 100644 --- a/browserid/lib/db_json.js +++ b/browserid/lib/db_json.js @@ -196,7 +196,7 @@ exports.gotVerificationSecret = function(secret, hash, cb) { emails: [ o.email ] }); flush(); - cb(); + cb(undefined, o.email); } // if this email address is known and a user has completed a re-verification of this email diff --git a/browserid/lib/db_mysql.js b/browserid/lib/db_mysql.js index 4f1264ce27a9f07d3ebddbc32a2137c2d81037d4..3700a7f4dc2006790516375a39132ea453d76607 100644 --- a/browserid/lib/db_mysql.js +++ b/browserid/lib/db_mysql.js @@ -199,7 +199,7 @@ exports.stageUser = function(email, cb) { exports.haveVerificationSecret = function(secret, cb) { client.query( - "SELECT COUNT(*) as N FROM staged WHERE secret = ?", [ email ], + "SELECT COUNT(*) as N FROM staged WHERE secret = ?", [ secret ], function(err, rows) { if (err) logUnexpectedError(err); cb(rows && rows.length > 0 && rows[0].N > 0); @@ -235,7 +235,7 @@ exports.gotVerificationSecret = function(secret, hash, cb) { [ userID, o.email ], function(err, info) { if (err) logUnexpectedError(err); - cb(err ? err : undefined); + cb(err ? err : undefined, o.email); }); } }); diff --git a/browserid/lib/wsapi.js b/browserid/lib/wsapi.js index f26ea4822e0664e21a89e6337348877d79abffce..3a9ba0edc841ffddf80074541a61fd133ad215b1 100644 --- a/browserid/lib/wsapi.js +++ b/browserid/lib/wsapi.js @@ -72,7 +72,7 @@ function checkParams(params) { } function isAuthed(req) { - var result= (req.session && typeof req.session.authenticatedUser === 'string'); + var result = (req.session && typeof req.session.authenticatedUser === 'string'); return result; } @@ -129,107 +129,180 @@ 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", "pass", "site" ]), function(req, resp) { + app.post('/wsapi/stage_user', checkParams([ "email", "site" ]), function(req, resp) { + // staging a user logs you out. + clearAuthenticatedUser(req.session); + + try { + // upon success, stage_user returns a secret (that'll get baked into a url + // and given to the user), on failure it throws + db.stageUser(req.body.email, function(secret) { + // store the email being registered in the session data + if (!req.session) req.session = {}; + + // store the secret we're sending via email in the users session, as checking + // that it still exists in the database is the surest way to determine the + // status of the email verification. + req.session.pendingCreation = secret; + + resp.json(true); + + // let's now kick out a verification email! + email.sendVerificationEmail(req.body.email, req.body.site, secret); + }); + } catch(e) { + // we should differentiate tween' 400 and 500 here. + httputils.badRequest(resp, e.toString()); + } + }); - // we should be cloning this object here. - var stageParams = req.body; + app.get('/wsapi/user_creation_status', function(req, resp) { + var email = req.query.email; + if (typeof email !== 'string') { + logger.warn("user_creation_status called without 'email' parameter"); + httputils.badRequest(resp, "no 'email' parameter"); + return; + } + + // if the user is authenticated as the user in question, we're done + if (isAuthed(req) && req.session.authenticatedUser === email) { + return resp.json('complete'); + } + // if the user isn't authenticated and there's no pendingCreation token, + // then they must authenticate + else if (!req.session.pendingCreation) { + return resp.json('mustAuth'); + } + + // if the secret is still in the database, it hasn't yet been verified and + // verification is still pending + db.haveVerificationSecret(req.session.pendingCreation, function (haveSecret) { + if (haveSecret) return resp.json('pending'); + // if the secret isn't known, and we're not authenticated, then the user must authenticate + // (maybe they verified the URL on a different browser, or maybe they canceled the account + // creation) + else { + delete req.session.pendingCreation; + resp.json('mustAuth'); + } + }); + }); + app.post('/wsapi/complete_user_creation', checkParams(["token", "pass"]), function(req, resp) { // issue #155, valid password length is between 8 and 80 chars. - if (stageParams.pass.length < 8 || stageParams.pass.length > 80) { + if (req.body.pass.length < 8 || req.body.pass.length > 80) { httputils.badRequest(resp, "valid passwords are between 8 and 80 chars"); return; } - // bcrypt the password - bcrypt.gen_salt(10, function (err, salt) { - if (err) { - winston.error("error generating salt with bcrypt: " + err); - return resp.json(false); - } + // at the time the email verification is performed, we'll clear the pendingCreation + // data on the session. + delete req.session.pendingCreation; + + // We should check to see if the verification secret is valid *before* + // bcrypting the password (which is expensive), to prevent a possible + // DoS attack. + db.haveVerificationSecret(req.body.token, function(valid) { + if (!valid) return resp.json(false); - bcrypt.encrypt(stageParams.pass, salt, function(err, hash) { + // now bcrypt the password + bcrypt.gen_salt(10, function (err, salt) { if (err) { - winston.error("error generating password hash with bcrypt: " + err); + logger.error("error generating salt with bcrypt: " + err); return resp.json(false); } - - stageParams['hash'] = hash; - - try { - // upon success, stage_user returns a secret (that'll get baked into a url - // and given to the user), on failure it throws - db.stageUser(stageParams, function(secret) { - // store the email being registered in the session data - if (!req.session) req.session = {}; - - // store inside the session the details of this pending verification - req.session.pendingVerification = { - email: stageParams.email, - hash: stageParams.hash // we must store both email and password to handle the case where - // a user re-creates an account - specifically, registration status - // must ensure the new credentials work to properly verify that - // the user has clicked throught the email link. note, this salted, bcrypted - // representation of a user's password will get thrust into an encrypted cookie - // served over an encrypted (SSL) session. guten, yah. - }; - - resp.json(true); - - // let's now kick out a verification email! - email.sendVerificationEmail(stageParams.email, stageParams.site, secret); + bcrypt.encrypt(req.body.pass, salt, function(err, hash) { + if (err) { + logger.error("error generating password hash with bcrypt: " + err); + return resp.json(false); + } + + db.gotVerificationSecret(req.body.token, hash, function(err, email) { + if (err) { + logger.error("error completing the verification: " + err); + resp.json(false); + } else { + // at this point the user has set a password associated with an email address + // that they've verified. We create an authenticated session. + req.session.authenticatedUser = email; + resp.json(true); + } }); - } catch(e) { - // we should differentiate tween' 400 and 500 here. - httputils.badRequest(resp, e.toString()); - } + }); }); }); }); - app.get('/wsapi/registration_status', function(req, resp) { - if (!req.session || - (!(typeof req.session.pendingVerification === 'object') && - !(typeof req.session.pendingAddition === 'string'))) + app.post('/wsapi/stage_email', checkAuthed, checkParams(["email", "site"]), function (req, resp) { + try { + // on failure stageEmail may throw + db.stageEmail(req.session.authenticatedUser, req.body.email, function(secret) { + + // store the email being added in session data + req.session.pendingAddition = secret; + + resp.json(true); + + // let's now kick out a verification email! + email.sendVerificationEmail(req.body.email, req.body.site, secret); + }); + } catch(e) { + // we should differentiate tween' 400 and 500 here. + httputils.badRequest(resp, e.toString()); + } + }); + + + app.get('/wsapi/email_addition_status', function(req, resp) { + + var email = req.query.email; + if (typeof email !== 'string') { - httputils.badRequest(resp, "api abuse: registration_status called without a pending email addition/verification"); + logger.warn("email_addition_status called without an 'email' parameter"); + httputils.badRequest(resp, "missing 'email' parameter"); return; } - // Is the current session trying to add an email, or register a new one? - if (req.session.pendingAddition) { - // this is a pending email addition, it requires authentication - if (!isAuthed(req, resp)) { - return httputils.badRequest(resp, "requires authentication"); - } + // this is a pending email addition, it requires authentication + if (!isAuthed(req, resp)) { + delete req.session.pendingAddition; + return httputils.badRequest(resp, "requires authentication"); + } - // check if the currently authenticated user has the email stored under pendingAddition - // in their acct. - db.emailsBelongToSameAccount(req.session.pendingAddition, - req.session.authenticatedUser, - function(registered) { - if (registered) { - delete req.session.pendingAddition; - resp.json('complete'); - } else { - resp.json('pending'); - } - }); - } else { - // this is a pending registration, let's check if the creds stored on the - // session are good yet. - var v = req.session.pendingVerification; - db.checkAuth(v.email, function(hash) { - if (hash === v.hash) { - delete req.session.pendingVerification; - req.session.authenticatedUser = v.email; + // check if the currently authenticated user has the email stored under pendingAddition + // in their acct. + db.emailsBelongToSameAccount( + email, + req.session.authenticatedUser, + function(registered) { + if (registered) { + delete req.session.pendingAddition; resp.json('complete'); + } else if (!req.session.pendingAddition) { + resp.json('failed'); } else { - resp.json('pending'); + db.haveVerificationSecret(req.session.pendingAddition, function (haveSecret) { + if (haveSecret) { + return resp.json('pending'); + } else { + delete req.session.pendingAddition; + resp.json('failed'); + } + }); } }); - } }); + app.post('/wsapi/complete_email_addition', checkParams(["token"]), function(req, resp) { + db.gotVerificationSecret(req.body.token, undefined, function(e) { + if (e) { + logger.error("error completing the verification: " + e); + resp.json(false); + } else { + resp.json(true); + } + }); + }); app.post('/wsapi/authenticate_user', checkParams(["email", "pass"]), function(req, resp) { db.checkAuth(req.body.email, function(hash) { @@ -241,7 +314,7 @@ function setup(app) { bcrypt.compare(req.body.pass, hash, function (err, success) { if (err) { - winston.warn("error comparing passwords with bcrypt: " + err); + logger.warn("error comparing passwords with bcrypt: " + err); success = false; } if (success) { @@ -253,25 +326,6 @@ function setup(app) { }); }); - app.post('/wsapi/add_email', checkAuthed, checkParams(["email", "site"]), function (req, resp) { - try { - // on failure stageEmail may throw - db.stageEmail(req.session.authenticatedUser, req.body.email, function(secret) { - - // store the email being added in session data - req.session.pendingAddition = req.body.email; - - resp.json(true); - - // let's now kick out a verification email! - email.sendVerificationEmail(req.body.email, req.body.site, secret); - }); - } catch(e) { - // we should differentiate tween' 400 and 500 here. - httputils.badRequest(resp, e.toString()); - } - }); - app.post('/wsapi/remove_email', checkAuthed, checkParams(["email"]), function(req, resp) { var email = req.body.email; @@ -307,7 +361,7 @@ function setup(app) { var expiration = new Date(); expiration.setTime(new Date().valueOf() + (24*3600*1000)); var cert = ca.certify(req.body.email, pk, expiration); - + resp.writeHead(200, {'Content-Type': 'text/plain'}); resp.write(cert); resp.end(); @@ -353,17 +407,6 @@ function setup(app) { }); }); - app.get('/wsapi/prove_email_ownership', checkParams(["token"]), function(req, resp) { - db.gotVerificationSecret(req.query.token, function(e) { - if (e) { - logger.error("error completing the verification: " + e); - resp.json(false); - } else { - resp.json(true); - } - }); - }); - // if the BROWSERID_FAKE_VERIFICATION env var is defined, we'll include // fake_verification.js. This is used during testing only and should // never be included in a production deployment diff --git a/browserid/tests/ca-test.js b/browserid/tests/ca-test.js index 58841957aec1115a1c305b9ac466caf5fef61523..2dfd984ee4120a048df26965b0b3537c76941316 100755 --- a/browserid/tests/ca-test.js +++ b/browserid/tests/ca-test.js @@ -57,7 +57,7 @@ var kp = jwk.KeyPair.generate("RS",64); var email_addr = "foo@foo.com"; -// create a new account via the api with (first address) +// certify a key suite.addBatch({ "certify a public key": { topic: function() { diff --git a/browserid/tests/cert-emails-test.js b/browserid/tests/cert-emails-test.js index ad6feeef65d7caae5f786af39501fdf4ea25aca9..afdf9a5d069ee08c1010e9267a6271861a4f7f13 100755 --- a/browserid/tests/cert-emails-test.js +++ b/browserid/tests/cert-emails-test.js @@ -68,7 +68,6 @@ suite.addBatch({ "stage an account": { topic: wsapi.post('/wsapi/stage_user', { email: 'syncer@somehost.com', - pass: 'fakepass', pubkey: 'fakekey', site:'fakesite.com' }), @@ -81,7 +80,7 @@ suite.addBatch({ suite.addBatch({ "verifying account ownership": { topic: function() { - wsapi.get('/wsapi/prove_email_ownership', { token: token }).call(this); + wsapi.post('/wsapi/complete_user_creation', { token: token, pass: 'fakepass' }).call(this); }, "works": function(r, err) { assert.equal(r.code, 200); @@ -90,18 +89,6 @@ suite.addBatch({ } }); -suite.addBatch({ - "calling registration_status after a registration is complete": { - topic: wsapi.get("/wsapi/registration_status"), - "yields a HTTP 200": function (r, err) { - assert.strictEqual(r.code, 200); - }, - "returns a json encoded string - `complete`": function (r, err) { - assert.strictEqual(JSON.parse(r.body), "complete"); - } - } -}); - var cert_key_url = "/wsapi/cert_key"; // generate a keypair, we'll use this to sign assertions, as if diff --git a/browserid/tests/forgotten-email-test.js b/browserid/tests/forgotten-email-test.js index a93608a45aebc3f127320d57f68e5ae790062320..13da60e37e146986010e9c7407ccd0a4c7ad59a8 100755 --- a/browserid/tests/forgotten-email-test.js +++ b/browserid/tests/forgotten-email-test.js @@ -60,8 +60,6 @@ suite.addBatch({ "stage first account": { topic: wsapi.post('/wsapi/stage_user', { email: 'first@fakeemail.com', - pass: 'firstfakepass', - pubkey: 'fakepubkey', site:'fakesite.com' }), "the token is sane": function(r, err) { @@ -73,7 +71,7 @@ suite.addBatch({ suite.addBatch({ "create first account": { topic: function() { - wsapi.get('/wsapi/prove_email_ownership', { token: token }).call(this); + wsapi.post('/wsapi/complete_user_creation', { token: token, pass: 'firstfakepass' }).call(this); }, "account created": function(r, err) { assert.equal(r.code, 200); @@ -84,7 +82,7 @@ suite.addBatch({ suite.addBatch({ "email created": { - topic: wsapi.get('/wsapi/registration_status'), + topic: wsapi.get('/wsapi/user_creation_status', { email: 'first@fakeemail.com' } ), "should exist": function(r, err) { assert.strictEqual(r.code, 200); assert.strictEqual(JSON.parse(r.body), "complete"); @@ -95,7 +93,7 @@ suite.addBatch({ // add a new email address to the account (second address) suite.addBatch({ "add a new email address to our account": { - topic: wsapi.post('/wsapi/add_email', { + topic: wsapi.post('/wsapi/stage_email', { email: 'second@fakeemail.com', site:'fakesite.com' }), @@ -109,7 +107,7 @@ suite.addBatch({ suite.addBatch({ "create second account": { topic: function() { - wsapi.get('/wsapi/prove_email_ownership', { token: token }).call(this); + wsapi.post('/wsapi/complete_email_addition', { token: token }).call(this); }, "account created": function(r, err) { assert.equal(r.code, 200); @@ -146,8 +144,6 @@ suite.addBatch({ "re-stage first account": { topic: wsapi.post('/wsapi/stage_user', { email: 'first@fakeemail.com', - pass: 'secondfakepass', - pubkey: 'fakepubkey2', site:'otherfakesite.com' }), "the token is sane": function(r, err) { @@ -177,7 +173,7 @@ suite.addBatch({ suite.addBatch({ "re-create first email address": { topic: function() { - wsapi.get('/wsapi/prove_email_ownership', { token: token }).call(this); + wsapi.post('/wsapi/complete_user_creation', { token: token, pass: 'secondfakepass' }).call(this); }, "account created": function(r, err) { assert.equal(r.code, 200); diff --git a/browserid/tests/list-emails-wsapi-test.js b/browserid/tests/list-emails-wsapi-test.js index e243445b070d6a0cfcb7106c58f0154362c3e564..a995323183bdc582d5d1edd3d075a63218f3aa37 100755 --- a/browserid/tests/list-emails-wsapi-test.js +++ b/browserid/tests/list-emails-wsapi-test.js @@ -60,7 +60,6 @@ suite.addBatch({ "stage an account": { topic: wsapi.post('/wsapi/stage_user', { email: 'syncer@somehost.com', - pass: 'fakepass', site:'fakesite.com' }), "yields a sane token": function(r, err) { @@ -72,18 +71,18 @@ suite.addBatch({ suite.addBatch({ "verifying account ownership": { topic: function() { - wsapi.get('/wsapi/prove_email_ownership', { token: token }).call(this); + wsapi.post('/wsapi/complete_user_creation', { token: token, pass: 'fakepass' }).call(this); }, "works": function(r, err) { assert.equal(r.code, 200); - assert.strictEqual(true, JSON.parse(r.body)); + assert.strictEqual(JSON.parse(r.body), true); } } }); suite.addBatch({ - "calling registration_status after a registration is complete": { - topic: wsapi.get("/wsapi/registration_status"), + "calling user_creation_status after a creation is complete": { + topic: wsapi.get("/wsapi/user_creation_status", { email: 'syncer@somehost.com' }), "yields a HTTP 200": function (r, err) { assert.strictEqual(r.code, 200); }, @@ -107,7 +106,6 @@ suite.addBatch({ } }); - start_stop.addShutdownBatches(suite); // run or export the suite. diff --git a/browserid/tests/password-length-test.js b/browserid/tests/password-length-test.js index c6da2d8a97fcf8190e86d2e27563909d42becb78..478e572a5a98d652817df8a0665239c0a0eefe47 100755 --- a/browserid/tests/password-length-test.js +++ b/browserid/tests/password-length-test.js @@ -52,7 +52,8 @@ suite.options.error = false; start_stop.addStartupBatches(suite); // surpress console output of emails with a noop email interceptor -email.setInterceptor(function(email, site, secret) { }); +var token = undefined; +email.setInterceptor(function(email, site, secret) { token = secret; }); suite.addBatch({ "get csrf token": { @@ -63,38 +64,47 @@ suite.addBatch({ } }); -// create a new account via the api with (first address) +// first stage the account suite.addBatch({ - "a password that is too short": { + "account staging": { topic: wsapi.post('/wsapi/stage_user', { email: 'first@fakeemail.com', - pass: '0123456', // less than 8 chars, invalid - pubkey: 'fakepubkey', site:'fakesite.com' }), + "works": function(r, err) { + assert.equal(r.code, 200); + } + } +}) + +// create a new account via the api with (first address) +suite.addBatch({ + "a password that is too short": { + topic: wsapi.post('/wsapi/complete_user_creation', { + token: token, + pass: '0123456' // less than 8 chars, invalid + }), "causes a HTTP error response": function(r, err) { assert.equal(r.code, 400); + assert.equal(r.body, "Bad Request: valid passwords are between 8 and 80 chars"); } }, "a password that is too long": { - topic: wsapi.post('/wsapi/stage_user', { - email: 'second@fakeemail.com', + topic: wsapi.post('/wsapi/complete_user_creation', { + token: token, pass: '012345678901234567890123456789012345678901234567890123456789012345678901234567891', // more than 81 chars, invalid. - pubkey: 'fakepubkey', - site:'fakesite.com' }), "causes a HTTP error response": function(r, err) { assert.equal(r.code, 400); + assert.equal(r.body, "Bad Request: valid passwords are between 8 and 80 chars"); } }, "but a password that is just right": { - topic: wsapi.post('/wsapi/stage_user', { - email: 'third@fakeemail.com', - pass: 'ahhh. this is just right.', // valid. - pubkey: 'fakepubkey', - site:'fakesite.com' + topic: wsapi.post('/wsapi/complete_user_creation', { + token: token, + pass: 'ahhh. this is just right.' }), - "causes a HTTP error response": function(r, err) { + "works just fine": function(r, err) { assert.equal(r.code, 200); } } diff --git a/browserid/tests/registration-status-wsapi-test.js b/browserid/tests/registration-status-wsapi-test.js index 54d6a4b3ee000723c8b78bf7319bce6a1a7813ae..a250d1aba8c10616ce122589aba610484aeff0a1 100755 --- a/browserid/tests/registration-status-wsapi-test.js +++ b/browserid/tests/registration-status-wsapi-test.js @@ -59,7 +59,7 @@ start_stop.addStartupBatches(suite); suite.addBatch({ "calling registration_status without a pending reg is an error": { - topic: wsapi.get("/wsapi/registration_status"), + topic: wsapi.get("/wsapi/user_creation_status"), "HTTP 400": function (r, err) { assert.equal(400, r.code); } @@ -80,8 +80,6 @@ suite.addBatch({ "start registration": { topic: wsapi.post('/wsapi/stage_user', { email: 'first@fakeemail.com', - pass: 'firstfakepass', - pubkey: 'fakepubkey', site:'fakesite.com' }), "the token is sane": function(r, err) { @@ -91,8 +89,20 @@ suite.addBatch({ }); suite.addBatch({ - "calling registration_status when a reg is really pending": { - topic: wsapi.get("/wsapi/registration_status"), + "calling user_creation_status without an email argument": { + topic: wsapi.get("/wsapi/user_creation_status"), + "yields a HTTP 400": function (r, err) { + assert.strictEqual(r.code, 400); + }, + "returns an error string": function (r, err) { + assert.strictEqual(r.body, "Bad Request: no 'email' parameter"); + } + } +}); + +suite.addBatch({ + "calling user_creation_status when a reg is really pending": { + topic: wsapi.get("/wsapi/user_creation_status", { email: 'first@fakeemail.com' }), "yields a HTTP 200": function (r, err) { assert.strictEqual(r.code, 200); }, @@ -103,19 +113,19 @@ suite.addBatch({ }); suite.addBatch({ - "proving email ownership causes account creation": { + "completing user creation": { topic: function() { - wsapi.get('/wsapi/prove_email_ownership', { token: token }).call(this); + wsapi.post('/wsapi/complete_user_creation', { token: token, pass: 'firstfakepass' }).call(this); }, - "and returns a 200 code": function(r, err) { + "works": function(r, err) { assert.equal(r.code, 200); } } }); suite.addBatch({ - "calling registration_status after a registration is complete": { - topic: wsapi.get("/wsapi/registration_status"), + "calling user_creation_status after a registration is complete": { + topic: wsapi.get("/wsapi/user_creation_status", { email: 'first@fakeemail.com' }), "yields a HTTP 200": function (r, err) { assert.strictEqual(r.code, 200); }, @@ -127,9 +137,12 @@ suite.addBatch({ suite.addBatch({ "calling registration_status a second time after a registration is complete": { - topic: wsapi.get("/wsapi/registration_status"), - "yields a HTTP 400, it's meaningless": function (r, err) { - assert.strictEqual(r.code, 400); + topic: wsapi.get("/wsapi/user_creation_status", { email: 'first@fakeemail.com' }), + "still yields a HTTP 200": function (r, err) { + assert.strictEqual(r.code, 200); + }, + "and still returns a json encoded string - `complete`": function (r, err) { + assert.strictEqual(JSON.parse(r.body), "complete"); } } }); @@ -161,8 +174,6 @@ suite.addBatch({ "re-registering an existing email": { topic: wsapi.post('/wsapi/stage_user', { email: 'first@fakeemail.com', - pass: 'secondfakepass', - pubkey: 'secondfakepubkey', site:'secondfakesite.com' }), "yields a valid token": function(r, err) { @@ -173,7 +184,7 @@ suite.addBatch({ suite.addBatch({ "calling registration_status when a reg is pending for an email that is already verified": { - topic: wsapi.get("/wsapi/registration_status"), + topic: wsapi.get("/wsapi/user_creation_status", { email: 'first@fakeemail.com' }), "should yield a HTTP 200": function (r, err) { assert.strictEqual(r.code, 200); }, @@ -184,9 +195,9 @@ suite.addBatch({ }); suite.addBatch({ - "proving email ownership causes account creation": { + "proving email ownership causes account re-creation": { topic: function() { - wsapi.get('/wsapi/prove_email_ownership', { token: token }).call(this); + wsapi.post('/wsapi/complete_user_creation', { token: token, pass: 'secondfakepass' }).call(this); }, "and returns a 200 code": function(r, err) { assert.equal(r.code, 200); @@ -196,7 +207,7 @@ suite.addBatch({ suite.addBatch({ "calling registration_status after proving a re-registration": { - topic: wsapi.get("/wsapi/registration_status"), + topic: wsapi.get("/wsapi/user_creation_status", { email: 'first@fakeemail.com' }), "yields a HTTP 200": function (r, err) { assert.strictEqual(r.code, 200); }, @@ -208,9 +219,9 @@ suite.addBatch({ suite.addBatch({ "again, calling registration_status a second time after a registration is complete": { - topic: wsapi.get("/wsapi/registration_status"), - "yields a HTTP 400, it's meaningless": function (r, err) { - assert.strictEqual(r.code, 400); + topic: wsapi.get("/wsapi/user_creation_status", { email: 'first@fakeemail.com' }), + "yields a HTTP 200": function (r, err) { + assert.strictEqual(r.code, 200); } } });