regions + city

pull/885/head
Nisarg 2021-10-10 23:08:28 -07:00
parent 2575cbfc11
commit 117d7c4400
6 changed files with 23 additions and 18 deletions

View File

@ -1,8 +1,7 @@
import path from 'path';
import requestIp from 'request-ip'; import requestIp from 'request-ip';
import { browserName, detectOS } from 'detect-browser'; import { browserName, detectOS } from 'detect-browser';
import isLocalhost from 'is-localhost-ip'; import isLocalhost from 'is-localhost-ip';
import maxmind from 'maxmind'; import geoip from 'fast-geoip';
import { import {
DESKTOP_OS, DESKTOP_OS,
@ -12,8 +11,6 @@ import {
MOBILE_SCREEN_WIDTH, MOBILE_SCREEN_WIDTH,
} from './constants'; } from './constants';
let lookup;
export function getIpAddress(req) { export function getIpAddress(req) {
// Cloudflare // Cloudflare
if (req.headers['cf-connecting-ip']) { if (req.headers['cf-connecting-ip']) {
@ -51,7 +48,7 @@ export function getDevice(screen, browser, os) {
} }
} }
export async function getCountry(req, ip) { export async function getLocation(req, ip) {
// Cloudflare // Cloudflare
if (req.headers['cf-ipcountry']) { if (req.headers['cf-ipcountry']) {
return req.headers['cf-ipcountry']; return req.headers['cf-ipcountry'];
@ -62,23 +59,24 @@ export async function getCountry(req, ip) {
return; return;
} }
// Database lookup const result = await geoip.lookup(ip);
if (!lookup) {
lookup = await maxmind.open(path.resolve('./public/geo/GeoLite2-Country.mmdb'));
}
const result = lookup.get(ip); return {
country: result?.country,
return result?.country?.iso_code; region: result?.region,
city: result?.city,
};
} }
export async function getClientInfo(req, { screen }) { export async function getClientInfo(req, { screen }) {
const userAgent = req.headers['user-agent']; const userAgent = req.headers['user-agent'];
const ip = getIpAddress(req); const ip = getIpAddress(req);
const country = await getCountry(req, ip); const country = await getLocation(req, ip).country;
const region = await getLocation(req, ip).region;
const city = await getLocation(req, ip).city;
const browser = browserName(userAgent); const browser = browserName(userAgent);
const os = detectOS(userAgent); const os = detectOS(userAgent);
const device = getDevice(screen, browser, os); const device = getDevice(screen, browser, os);
return { userAgent, browser, os, ip, country, device }; return { userAgent, browser, os, ip, country, device, region, city };
} }

View File

@ -23,7 +23,10 @@ export async function getSession(req) {
throw new Error(`Invalid website: ${website_uuid}`); throw new Error(`Invalid website: ${website_uuid}`);
} }
const { userAgent, browser, os, ip, country, device } = await getClientInfo(req, payload); const { userAgent, browser, os, ip, country, device, region, city } = await getClientInfo(
req,
payload,
);
const website = await getWebsiteByUuid(website_uuid); const website = await getWebsiteByUuid(website_uuid);
@ -46,6 +49,8 @@ export async function getSession(req) {
language, language,
country, country,
device, device,
region,
city,
}); });
} }

View File

@ -18,7 +18,6 @@
"build-tracker": "rollup -c rollup.tracker.config.js", "build-tracker": "rollup -c rollup.tracker.config.js",
"build-db": "npm-run-all copy-db-schema build-db-client", "build-db": "npm-run-all copy-db-schema build-db-client",
"build-lang": "npm-run-all format-lang compile-lang", "build-lang": "npm-run-all format-lang compile-lang",
"build-geo": "node scripts/build-geo.js",
"build-db-schema": "dotenv prisma introspect", "build-db-schema": "dotenv prisma introspect",
"build-db-client": "dotenv prisma generate", "build-db-client": "dotenv prisma generate",
"build-mysql-schema": "dotenv prisma introspect -- --schema=./prisma/schema.mysql.prisma", "build-mysql-schema": "dotenv prisma introspect -- --schema=./prisma/schema.mysql.prisma",
@ -72,6 +71,7 @@
"date-fns-tz": "^1.1.4", "date-fns-tz": "^1.1.4",
"detect-browser": "^5.2.0", "detect-browser": "^5.2.0",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"fast-geoip": "^1.1.40",
"formik": "^2.2.9", "formik": "^2.2.9",
"immer": "^9.0.6", "immer": "^9.0.6",
"ipaddr.js": "^2.0.1", "ipaddr.js": "^2.0.1",

View File

@ -2,7 +2,7 @@ import { getPageviewMetrics, getSessionMetrics, getWebsiteById } from 'lib/queri
import { ok, methodNotAllowed, unauthorized, badRequest } from 'lib/response'; import { ok, methodNotAllowed, unauthorized, badRequest } from 'lib/response';
import { allowQuery } from 'lib/auth'; import { allowQuery } from 'lib/auth';
const sessionColumns = ['browser', 'os', 'device', 'country']; const sessionColumns = ['browser', 'os', 'device', 'country', 'region', 'city'];
const pageviewColumns = ['url', 'referrer']; const pageviewColumns = ['url', 'referrer'];
function getTable(type) { function getTable(type) {

View File

@ -62,6 +62,8 @@ model session {
screen String? @db.VarChar(11) screen String? @db.VarChar(11)
language String? @db.VarChar(35) language String? @db.VarChar(35)
country String? @db.Char(2) country String? @db.Char(2)
region String? @db.VarChar(35)
city String? @db.VarChar(100)
website website @relation(fields: [website_id], references: [website_id]) website website @relation(fields: [website_id], references: [website_id])
event event[] event event[]
pageview pageview[] pageview pageview[]

View File

@ -6,7 +6,7 @@ const zlib = require('zlib');
const tar = require('tar'); const tar = require('tar');
let url = let url =
'https://raw.githubusercontent.com/GitSquared/node-geolite2-redist/master/redist/GeoLite2-Country.tar.gz'; 'https://raw.githubusercontent.com/GitSquared/node-geolite2-redist/master/redist/GeoLite2-City.tar.gz';
if (process.env.MAXMIND_LICENSE_KEY) { if (process.env.MAXMIND_LICENSE_KEY) {
url = url =