mirror of
https://github.com/umami-software/umami.git
synced 2026-02-21 04:55:36 +01:00
Merge branch 'dev' into feat/um-185-event-data-redirect
This commit is contained in:
commit
53a6a8924d
23 changed files with 3791 additions and 98 deletions
|
|
@ -74,9 +74,13 @@ function getFilterQuery(filters = {}, params = {}) {
|
|||
|
||||
switch (key) {
|
||||
case 'url':
|
||||
case 'pageTitle':
|
||||
case 'os':
|
||||
case 'browser':
|
||||
case 'device':
|
||||
case 'subdivision1':
|
||||
case 'subdivision2':
|
||||
case 'city':
|
||||
case 'country':
|
||||
arr.push(`and ${key} = {${key}:String}`);
|
||||
params[key] = filter;
|
||||
|
|
@ -109,11 +113,25 @@ function getFilterQuery(filters = {}, params = {}) {
|
|||
}
|
||||
|
||||
function parseFilters(filters: any = {}, params: any = {}) {
|
||||
const { domain, url, eventUrl, referrer, os, browser, device, country, eventName, query } =
|
||||
filters;
|
||||
const {
|
||||
domain,
|
||||
url,
|
||||
eventUrl,
|
||||
referrer,
|
||||
pageTitle,
|
||||
os,
|
||||
browser,
|
||||
device,
|
||||
country,
|
||||
subdivision1,
|
||||
subdivision2,
|
||||
city,
|
||||
eventName,
|
||||
query,
|
||||
} = filters;
|
||||
|
||||
const pageviewFilters = { domain, url, referrer, query };
|
||||
const sessionFilters = { os, browser, device, country };
|
||||
const pageviewFilters = { domain, url, referrer, query, pageTitle };
|
||||
const sessionFilters = { os, browser, device, country, subdivision1, subdivision2, city };
|
||||
const eventFilters = { url: eventUrl, eventName };
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export function getIpAddress(req) {
|
|||
return requestIp.getClientIp(req);
|
||||
}
|
||||
|
||||
export function getDevice(screen, browser, os) {
|
||||
export function getDevice(screen, os) {
|
||||
if (!screen) return;
|
||||
|
||||
const [width] = screen.split('x');
|
||||
|
|
@ -55,12 +55,7 @@ export function getDevice(screen, browser, os) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function getCountry(req, ip) {
|
||||
// Cloudflare
|
||||
if (req.headers['cf-ipcountry']) {
|
||||
return req.headers['cf-ipcountry'];
|
||||
}
|
||||
|
||||
export async function getLocation(ip) {
|
||||
// Ignore local ips
|
||||
if (await isLocalhost(ip)) {
|
||||
return;
|
||||
|
|
@ -68,23 +63,31 @@ export async function getCountry(req, ip) {
|
|||
|
||||
// Database lookup
|
||||
if (!lookup) {
|
||||
lookup = await maxmind.open(path.resolve('node_modules/.geo/GeoLite2-Country.mmdb'));
|
||||
lookup = await maxmind.open(path.resolve('node_modules/.geo/GeoLite2-City.mmdb'));
|
||||
}
|
||||
|
||||
const result = lookup.get(ip);
|
||||
const country = result?.country?.iso_code ?? result?.registered_country?.iso_code;
|
||||
const subdivision1 = result?.subdivisions[0]?.iso_code;
|
||||
const subdivision2 = result?.subdivisions[1]?.names?.en;
|
||||
const city = result?.city?.names?.en;
|
||||
|
||||
return result?.country?.iso_code;
|
||||
return { country, subdivision1, subdivision2, city };
|
||||
}
|
||||
|
||||
export async function getClientInfo(req, { screen }) {
|
||||
const userAgent = req.headers['user-agent'];
|
||||
const ip = getIpAddress(req);
|
||||
const country = await getCountry(req, ip);
|
||||
const location = await getLocation(ip);
|
||||
const country = location.country;
|
||||
const subdivision1 = location.subdivision1;
|
||||
const subdivision2 = location.subdivision2;
|
||||
const city = location.city;
|
||||
const browser = browserName(userAgent);
|
||||
const os = detectOS(userAgent);
|
||||
const device = getDevice(screen, browser, os);
|
||||
|
||||
return { userAgent, browser, os, ip, country, device };
|
||||
return { userAgent, browser, os, ip, country, subdivision1, subdivision2, city, device };
|
||||
}
|
||||
|
||||
export function getJsonBody(req) {
|
||||
|
|
|
|||
|
|
@ -75,8 +75,12 @@ function getFilterQuery(filters = {}, params = []): string {
|
|||
switch (key) {
|
||||
case 'url':
|
||||
case 'os':
|
||||
case 'pageTitle':
|
||||
case 'browser':
|
||||
case 'device':
|
||||
case 'subdivision1':
|
||||
case 'subdivision2':
|
||||
case 'city':
|
||||
case 'country':
|
||||
arr.push(`and ${key}=$${params.length + 1}`);
|
||||
params.push(decodeURIComponent(filter));
|
||||
|
|
@ -113,11 +117,25 @@ function parseFilters(
|
|||
params = [],
|
||||
sessionKey = 'session_id',
|
||||
) {
|
||||
const { domain, url, eventUrl, referrer, os, browser, device, country, eventName, query } =
|
||||
filters;
|
||||
const {
|
||||
domain,
|
||||
url,
|
||||
eventUrl,
|
||||
referrer,
|
||||
pageTitle,
|
||||
os,
|
||||
browser,
|
||||
device,
|
||||
country,
|
||||
subdivision1,
|
||||
subdivision2,
|
||||
city,
|
||||
eventName,
|
||||
query,
|
||||
} = filters;
|
||||
|
||||
const pageviewFilters = { domain, url, referrer, query };
|
||||
const sessionFilters = { os, browser, device, country };
|
||||
const pageviewFilters = { domain, url, referrer, query, pageTitle };
|
||||
const sessionFilters = { os, browser, device, country, subdivision1, subdivision2, city };
|
||||
const eventFilters = { url: eventUrl, eventName };
|
||||
|
||||
return {
|
||||
|
|
@ -126,7 +144,7 @@ function parseFilters(
|
|||
eventFilters,
|
||||
event: { eventName },
|
||||
joinSession:
|
||||
os || browser || device || country
|
||||
os || browser || device || country || subdivision1 || subdivision2 || city
|
||||
? `inner join session on website_event.${sessionKey} = session.${sessionKey}`
|
||||
: '',
|
||||
filterQuery: getFilterQuery(filters, params),
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@ export async function findSession(req) {
|
|||
throw new Error(`Website not found: ${websiteId}`);
|
||||
}
|
||||
|
||||
const { userAgent, browser, os, ip, country, device } = await getClientInfo(req, payload);
|
||||
const { userAgent, browser, os, ip, country, subdivision1, subdivision2, city, device } =
|
||||
await getClientInfo(req, payload);
|
||||
const sessionId = uuid(websiteId, hostname, ip, userAgent);
|
||||
|
||||
// Clickhouse does not require session lookup
|
||||
|
|
@ -59,6 +60,9 @@ export async function findSession(req) {
|
|||
screen,
|
||||
language,
|
||||
country,
|
||||
subdivision1,
|
||||
subdivision2,
|
||||
city,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -84,6 +88,9 @@ export async function findSession(req) {
|
|||
screen,
|
||||
language,
|
||||
country,
|
||||
subdivision1,
|
||||
subdivision2,
|
||||
city,
|
||||
});
|
||||
} catch (e) {
|
||||
if (!e.message.toLowerCase().includes('unique constraint')) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue