diff --git a/lib/db/api.js b/lib/db/api.js index 2d80a9e6..0785d293 100644 --- a/lib/db/api.js +++ b/lib/db/api.js @@ -138,8 +138,13 @@ dbapi.createBootStrap = function(env) { , email: group.owner.email , ip: '127.0.0.1' }) - .then(function() { - return updateUsersForMigration(group) + .then(function(stats) { + if (stats) { + return updateUsersForMigration(group) + } + return dbapi.deleteGroup(group.id).then(function() { + throw new Error('Found the same user with a different name') + }) }) .then(function() { return updateDevicesForMigration(group) @@ -1018,18 +1023,28 @@ dbapi.createUser = function(email, name, ip) { }) } +dbapi.checkUserBeforeLogin = function(user) { + return db.run(r.table('users').get(user.email)).then(function(oldUser) { + if (!oldUser || oldUser.name === user.name) { + return true + } + return false + }) +} + dbapi.saveUserAfterLogin = function(user) { - return db.run(r.table('users').get(user.email).update({ - name: user.name - , ip: user.ip + return db.run(r.table('users').get(user.email)).then(function(oldUser) { + if (!oldUser) { + return dbapi.createUser(user.email, user.name, user.ip) + } + if (oldUser.name !== user.name) { + return null + } + return db.run(r.table('users').get(user.email).update({ + ip: user.ip , lastLoggedInAt: r.now() - })) - .then(function(stats) { - if (stats.skipped) { - return dbapi.createUser(user.email, user.name, user.ip) - } - return stats - }) + }, {returnChanges: true})) + }) } dbapi.loadUser = function(email) { diff --git a/lib/units/auth/mock.js b/lib/units/auth/mock.js index f3ed4932..ad19cab1 100644 --- a/lib/units/auth/mock.js +++ b/lib/units/auth/mock.js @@ -1,5 +1,5 @@ /** -* Copyright © 2019 contains code contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0 +* Copyright © 2019-2024 contains code contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0 **/ var http = require('http') @@ -117,6 +117,15 @@ module.exports = function(options) { req.checkBody('name').notEmpty() req.checkBody('email').isEmail() }) + .then(function() { + return dbapi.checkUserBeforeLogin(req.body) + }) + .then(function(isValidCredential) { + if (!isValidCredential) { + return Promise.reject('InvalidCredentialsError') + } + return isValidCredential + }) .then(function() { log.info('Authenticated "%s"', req.body.email) var token = jwtutil.encode({ @@ -146,12 +155,22 @@ module.exports = function(options) { }) }) .catch(function(err) { - log.error('Unexpected error', err.stack) - res.status(500) - .json({ - success: false - , error: 'ServerError' - }) + if (err === 'InvalidCredentialsError') { + log.warn('Authentication failure for "%s"', req.body.email) + res.status(400) + .json({ + success: false + , error: 'InvalidCredentialsError' + }) + } + else { + log.error('Unexpected error', err.stack) + res.status(500) + .json({ + success: false + , error: 'ServerError' + }) + } }) break default: