diff --git a/lib/models/user.js b/lib/models/user.js index 357c70f2..a6e413fd 100644 --- a/lib/models/user.js +++ b/lib/models/user.js @@ -358,18 +358,25 @@ User.confirm = function (uid, token, redirect, fn) { if(err) { fn(err); } else { - if(user.verificationToken === token) { + if(user && user.verificationToken === token) { user.verificationToken = undefined; user.emailVerified = true; user.save(function (err) { if(err) { - fn(err) + fn(err); } else { fn(); } }); } else { - fn(new Error('invalid token')); + if (user) { + err = new Error('Invalid token: ' + token); + err.statusCode = 400; + } else { + err = new Error('User not found: ' + uid); + err.statusCode = 404; + } + fn(err); } } }); diff --git a/test/user.test.js b/test/user.test.js index ccfb0c8b..b7588779 100644 --- a/test/user.test.js +++ b/test/user.test.js @@ -435,7 +435,7 @@ describe('User', function(){ }); describe('Verification', function(){ - + describe('user.verify(options, fn)', function(){ it('Verify a user\'s email address', function(done) { User.afterRemote('create', function(ctx, user, next) { @@ -454,8 +454,6 @@ describe('User', function(){ assert(result.email); assert(result.email.response); assert(result.token); - - assert(~result.email.response.toString('utf-8').indexOf('To: bar@bat.com')); done(); }); @@ -471,13 +469,15 @@ describe('User', function(){ }); }); }); - - describe('User.confirm(options, fn)', function(){ - it('Confirm a user verification', function(done) { - User.afterRemote('create', function(ctx, user, next) { + + describe('User.confirm(options, fn)', function () { + var options; + + function testConfirm(testFunc, done) { + User.afterRemote('create', function (ctx, user, next) { assert(user, 'afterRemote should include result'); - - var options = { + + options = { type: 'email', to: user.email, from: 'noreply@myapp.org', @@ -485,29 +485,73 @@ describe('User', function(){ protocol: ctx.req.protocol, host: ctx.req.get('host') }; - + user.verify(options, function (err, result) { - if(err) return done(err); - - request(app) - .get('/users/confirm?uid=' + result.uid + '&token=' + encodeURIComponent(result.token) + '&redirect=' + encodeURIComponent(options.redirect)) - .expect(302) - .expect('location', options.redirect) - .end(function(err, res){ - if(err) return done(err); - done(); - }); + if (err) { + return done(err); + } + testFunc(result, done); }); }); - + request(app) .post('/users') .expect('Content-Type', /json/) .expect(302) .send({email: 'bar@bat.com', password: 'bar'}) - .end(function(err, res){ - if(err) return done(err); + .end(function (err, res) { + if (err) { + return done(err); + } }); + } + + it('Confirm a user verification', function (done) { + testConfirm(function (result, done) { + request(app) + .get('/users/confirm?uid=' + (result.uid ) + + '&token=' + encodeURIComponent(result.token) + + '&redirect=' + encodeURIComponent(options.redirect)) + .expect(302) + .end(function (err, res) { + if (err) { + return done(err); + } + done(); + }); + }, done); + }); + + it('Report error for invalid user id during verification', function (done) { + testConfirm(function (result, done) { + request(app) + .get('/users/confirm?uid=' + (result.uid + '_invalid') + + '&token=' + encodeURIComponent(result.token) + + '&redirect=' + encodeURIComponent(options.redirect)) + .expect(404) + .end(function (err, res) { + if (err) { + return done(err); + } + assert(res.body.error); + done(); + }); + }, done); + }); + + it('Report error for invalid token during verification', function (done) { + testConfirm(function (result, done) { + request(app) + .get('/users/confirm?uid=' + result.uid + + '&token=' + encodeURIComponent(result.token) + '_invalid' + + '&redirect=' + encodeURIComponent(options.redirect)) + .expect(400) + .end(function (err, res) { + if (err) return done(err); + assert(res.body.error); + done(); + }); + }, done); }); }); });