diff --git a/migrations/20210430120936-users-add-locationsJson.js b/migrations/20210430120936-users-add-loginLocationsJson.js similarity index 58% rename from migrations/20210430120936-users-add-locationsJson.js rename to migrations/20210430120936-users-add-loginLocationsJson.js index e53947eb9..a93d2b633 100644 --- a/migrations/20210430120936-users-add-locationsJson.js +++ b/migrations/20210430120936-users-add-loginLocationsJson.js @@ -1,14 +1,14 @@ 'use strict'; exports.up = function(db, callback) { - db.runSql('ALTER TABLE users ADD COLUMN locationJson TEXT', function (error) { + db.runSql('ALTER TABLE users ADD COLUMN loginLocationsJson TEXT', function (error) { if (error) console.error(error); callback(error); }); }; exports.down = function(db, callback) { - db.runSql('ALTER TABLE users DROP COLUMN locationJson', function (error) { + db.runSql('ALTER TABLE users DROP COLUMN loginLocationsJson', function (error) { if (error) console.error(error); callback(error); }); diff --git a/src/test/database-test.js b/src/test/database-test.js index 31056a5d2..c273f19cd 100644 --- a/src/test/database-test.js +++ b/src/test/database-test.js @@ -41,7 +41,7 @@ var USER_0 = { role: 'user', active: true, source: '', - locations: [], + loginLocations: [], resetTokenCreationTime: Date.now() }; @@ -60,7 +60,7 @@ var USER_1 = { role: 'user', active: true, source: '', - locations: [], + loginLocations: [], resetTokenCreationTime: Date.now() }; @@ -79,7 +79,7 @@ var USER_2 = { role: 'user', active: true, source: '', - locations: [], + loginLocations: [], resetTokenCreationTime: Date.now() }; diff --git a/src/userdb.js b/src/userdb.js index cc18e2b3d..921801011 100644 --- a/src/userdb.js +++ b/src/userdb.js @@ -32,7 +32,7 @@ var assert = require('assert'), // the avatar field is special and not added here to reduce response sizes const USERS_FIELDS = [ 'id', 'username', 'email', 'fallbackEmail', 'password', 'salt', 'createdAt', 'resetToken', 'displayName', - 'twoFactorAuthenticationEnabled', 'twoFactorAuthenticationSecret', 'active', 'source', 'role', 'resetTokenCreationTime', 'locationJson' ].join(','); + 'twoFactorAuthenticationEnabled', 'twoFactorAuthenticationSecret', 'active', 'source', 'role', 'resetTokenCreationTime', 'loginLocationsJson' ].join(','); const APP_PASSWORD_FIELDS = [ 'id', 'name', 'userId', 'identifier', 'hashedPassword', 'creationTime' ].join(','); @@ -42,10 +42,8 @@ function postProcess(result) { result.twoFactorAuthenticationEnabled = !!result.twoFactorAuthenticationEnabled; result.active = !!result.active; - // we remove the JSON first locations property, it is only there to have a valid JSON, no toplevel array - const tmp = safe.JSON.parse(result.locationJson) || { locations: [] }; - result.locations = tmp.locations || []; - delete result.locationJson; + result.loginLocations = safe.JSON.parse(result.loginLocationsJson) || []; + delete result.loginLocationsJson; return result; } @@ -244,7 +242,7 @@ function update(userId, user, callback) { assert(!('twoFactorAuthenticationEnabled' in user) || (typeof user.twoFactorAuthenticationEnabled === 'boolean')); assert(!('role' in user) || (typeof user.role === 'string')); assert(!('active' in user) || (typeof user.active === 'boolean')); - assert(!('locations' in user) || (Array.isArray(user.locations))); + assert(!('loginLocations' in user) || (Array.isArray(user.loginLocations))); var args = [ ]; var fields = [ ]; @@ -252,9 +250,9 @@ function update(userId, user, callback) { if (k === 'twoFactorAuthenticationEnabled' || k === 'active') { fields.push(k + ' = ?'); args.push(user[k] ? 1 : 0); - } else if (k === 'locations') { - fields.push('locationJson = ?'); - args.push(JSON.stringify({ locations: user[k] || []})); + } else if (k === 'loginLocations') { + fields.push('loginLocationsJson = ?'); + args.push(JSON.stringify({ loginLocations: user[k] })); } else { fields.push(k + ' = ?'); args.push(user[k]); diff --git a/src/users.js b/src/users.js index 4d93c3730..ed5eb0126 100644 --- a/src/users.js +++ b/src/users.js @@ -545,7 +545,7 @@ function checkLoginLocation(user, ip, userAgent) { if (!city || !country) return; - const knownLogin = user.locations.find(function (l) { + const knownLogin = user.loginLocations.find(function (l) { return l.userAgent === userAgent && l.country === country && l.city === city; }); @@ -553,10 +553,10 @@ function checkLoginLocation(user, ip, userAgent) { // purge potentially old locations where ts > now() - 6 months const sixMonthsBack = Date.now() - 6 * 30 * 24 * 60 * 60 * 1000; - let locations = user.locations.filter(function (l) { return l.ts > sixMonthsBack; }); + let loginLocations = user.loginLocations.filter(function (l) { return l.ts > sixMonthsBack; }); - locations.push({ ts: Date.now(), ip, userAgent, country, city }); - userdb.update(user.id, { locations }, function (error) { + loginLocations.push({ ts: Date.now(), ip, userAgent, country, city }); + userdb.update(user.id, { loginLocations }, function (error) { if (error) console.error('checkLoginLocation: Failed to update user location.', error); mailer.sendNewLoginLocation(user, ip, userAgent, country, city);