diff --git a/lib/routes/account.js b/lib/routes/account.js index 85ec9909..a92774fa 100644 --- a/lib/routes/account.js +++ b/lib/routes/account.js @@ -439,6 +439,7 @@ module.exports = function ( } function checkUnblockCode (e) { + request.emitMetricsEvent('account.login.blocked') var method = e.output.payload.verificationMethod if (method === 'email-captcha') { // only set `unblockCode` if it is required from customs @@ -476,7 +477,8 @@ module.exports = function ( ) .catch( (err) => { - if (err.errno === error.ERRNO.UNBLOCK_CODE_INVALID) { + if (err.errno === error.ERRNO.INVALID_UNBLOCK_CODE) { + request.emitMetricsEvent('account.login.invalidUnblockCode') customs.flag(request.app.clientAddress, { email: email, errno: err.errno diff --git a/test/local/account_routes.js b/test/local/account_routes.js index 652ebd9e..4d99476c 100644 --- a/test/local/account_routes.js +++ b/test/local/account_routes.js @@ -885,7 +885,8 @@ test('/account/login', function (t) { var mockMailer = mocks.mockMailer() var mockPush = mocks.mockPush() var mockCustoms = { - check: () => P.resolve() + check: () => P.resolve(), + flag: () => P.resolve() } var accountRoutes = makeRoutes({ checkPassword: function () { @@ -1437,38 +1438,52 @@ test('/account/login', function (t) { t.plan(2) mockCustoms.check = () => P.reject(error.requestBlocked(true)) t.test('signin unblock disabled', (t) => { - t.plan(4) + t.plan(6) config.signinUnblock.enabled = false + mockLog.flowEvent.reset() return runTest(route, mockRequest, (err) => { t.equal(err.errno, error.ERRNO.REQUEST_BLOCKED, 'correct errno is returned') t.equal(err.output.statusCode, 400, 'correct status code is returned') t.equal(err.output.payload.verificationMethod, undefined, 'no verificationMethod') t.equal(err.output.payload.verificationReason, undefined, 'no verificationReason') + t.equal(mockLog.flowEvent.callCount, 1, 'log.flowEvent called once') + t.equal(mockLog.flowEvent.args[0][0], 'account.login.blocked', 'first event is blocked') + + mockLog.flowEvent.reset() }) }) t.test('signin unblock enabled', (t) => { t.plan(2) config.signinUnblock.enabled = true + mockLog.flowEvent.reset() t.test('without unblock code', (t) => { - t.plan(4) + t.plan(6) return runTest(route, mockRequest, (err) => { t.equal(err.errno, error.ERRNO.REQUEST_BLOCKED, 'correct errno is returned') t.equal(err.output.statusCode, 400, 'correct status code is returned') t.equal(err.output.payload.verificationMethod, 'email-captcha', 'with verificationMethod') t.equal(err.output.payload.verificationReason, 'login', 'with verificationReason') + t.equal(mockLog.flowEvent.callCount, 1, 'log.flowEvent called once') + t.equal(mockLog.flowEvent.args[0][0], 'account.login.blocked', 'first event is blocked') + mockLog.flowEvent.reset() }) }) t.test('with unblock code', (t) => { t.plan(3) + mockLog.flowEvent.reset() + t.test('invalid code', (t) => { - t.plan(2) mockDB.consumeUnblockCode = () => P.reject(error.invalidUnblockCode()) return runTest(route, mockRequestWithUnblockCode, (err) => { t.equal(err.errno, error.ERRNO.INVALID_UNBLOCK_CODE, 'correct errno is returned') t.equal(err.output.statusCode, 400, 'correct status code is returned') + t.equal(mockLog.flowEvent.callCount, 2, 'log.flowEvent called twice') + t.equal(mockLog.flowEvent.args[1][0], 'account.login.invalidUnblockCode', 'second event is invalid') + + mockLog.flowEvent.reset() }) }) @@ -1478,19 +1493,23 @@ test('/account/login', function (t) { t.equal(err.errno, error.ERRNO.INVALID_UNBLOCK_CODE, 'correct errno is returned') t.equal(err.output.statusCode, 400, 'correct status code is returned') + t.equal(mockLog.flowEvent.callCount, 2, 'log.flowEvent called twice') + t.equal(mockLog.flowEvent.args[1][0], 'account.login.invalidUnblockCode', 'second event is invalid') + mockLog.activityEvent.reset() mockLog.flowEvent.reset() }) }) t.test('valid code', (t) => { - t.plan(4) + t.plan(5) mockDB.consumeUnblockCode = () => P.resolve({ createdAt: Date.now() }) return runTest(route, mockRequestWithUnblockCode, (res) => { t.ok(!(res instanceof Error), 'successful login') - t.equal(mockLog.flowEvent.callCount, 2, 'log.flowEvent was called twice') - t.equal(mockLog.flowEvent.args[0][0], 'account.login.confirmedUnblockCode', 'first event was account.login.confirmedUnblockCode') - t.equal(mockLog.flowEvent.args[1][0], 'account.login', 'second event was account.login') + t.equal(mockLog.flowEvent.callCount, 3, 'log.flowEvent was called three times') + t.equal(mockLog.flowEvent.args[0][0], 'account.login.blocked', 'first event was account.login.blocked') + t.equal(mockLog.flowEvent.args[1][0], 'account.login.confirmedUnblockCode', 'second event was account.login.confirmedUnblockCode') + t.equal(mockLog.flowEvent.args[2][0], 'account.login', 'third event was account.login') mockLog.flowEvent.reset() })