diff --git a/package-lock.json b/package-lock.json index fa6cb4456..f4fc74e0d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4692,6 +4692,11 @@ "is-typedarray": "^1.0.0" } }, + "ua-parser-js": { + "version": "0.7.28", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz", + "integrity": "sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g==" + }, "uid-safe": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", diff --git a/package.json b/package.json index 463527649..92732d634 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "tar-fs": "github:cloudron-io/tar-fs#ignore_stat_error", "tar-stream": "^2.2.0", "tldjs": "^2.3.1", + "ua-parser-js": "^0.7.28", "underscore": "^1.13.1", "uuid": "^8.3.2", "validator": "^13.6.0", diff --git a/src/users.js b/src/users.js index fe87c28ff..13936184a 100644 --- a/src/users.js +++ b/src/users.js @@ -74,6 +74,7 @@ let assert = require('assert'), tokens = require('./tokens.js'), userdb = require('./userdb.js'), uuid = require('uuid'), + uaParser = require('ua-parser-js'), superagent = require('superagent'), validator = require('validator'), _ = require('underscore'); @@ -545,15 +546,18 @@ function checkLoginLocation(user, ip, userAgent) { if (!city || !country) return; + const ua = uaParser(userAgent); + const simplifiedUserAgent = ua.browser.name + ' - ' + ua.os.name; + const knownLogin = user.loginLocations.find(function (l) { - return l.userAgent === userAgent && l.country === country && l.city === city; + return l.userAgent === simplifiedUserAgent && l.country === country && l.city === city; }); if (knownLogin) return; // purge potentially old locations where ts > now() - 6 months const sixMonthsBack = Date.now() - 6 * 30 * 24 * 60 * 60 * 1000; - const newLoginLocation = { ts: Date.now(), ip, userAgent, country, city }; + const newLoginLocation = { ts: Date.now(), ip, simplifiedUserAgent, country, city }; let loginLocations = user.loginLocations.filter(function (l) { return l.ts > sixMonthsBack; }); loginLocations.push(newLoginLocation);