Merge branch 'umami-software:master' into master

This commit is contained in:
arrow2nd 2025-07-08 14:32:06 +09:00 committed by GitHub
commit 8732bf6d84
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 12 additions and 7 deletions

View file

@ -25,7 +25,7 @@ body:
- type: input - type: input
attributes: attributes:
label: Which Umami version are you using? (if relevant) label: Which Umami version are you using? (if relevant)
description: 'For example: Chrome, Edge, Firefox, etc' description: 'For example: 2.18.0, 2.15.1, 1.39.0, etc'
- type: input - type: input
attributes: attributes:
label: Which browser are you using? (if relevant) label: Which browser are you using? (if relevant)

View file

@ -11,6 +11,8 @@ env:
jobs: jobs:
build: build:
# Only run the CI if it belongs to the original repository
if: github.repository == 'umami-software/umami'
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:

View file

@ -122,7 +122,7 @@ CREATE TABLE umami.website_event_stats_hourly
min_time SimpleAggregateFunction(min, DateTime('UTC')), min_time SimpleAggregateFunction(min, DateTime('UTC')),
max_time SimpleAggregateFunction(max, DateTime('UTC')), max_time SimpleAggregateFunction(max, DateTime('UTC')),
tag SimpleAggregateFunction(groupArrayArray, Array(String)), tag SimpleAggregateFunction(groupArrayArray, Array(String)),
distinct_id, distinct_id String,
created_at Datetime('UTC') created_at Datetime('UTC')
) )
ENGINE = AggregatingMergeTree ENGINE = AggregatingMergeTree
@ -213,7 +213,7 @@ FROM (SELECT
min(created_at) min_time, min(created_at) min_time,
max(created_at) max_time, max(created_at) max_time,
arrayFilter(x -> x != '', groupArray(tag)) tag, arrayFilter(x -> x != '', groupArray(tag)) tag,
distinct_id String, distinct_id,
toStartOfHour(created_at) timestamp toStartOfHour(created_at) timestamp
FROM umami.website_event FROM umami.website_event
GROUP BY website_id, GROUP BY website_id,

View file

@ -16,7 +16,7 @@ const disableLogin = process.env.DISABLE_LOGIN;
const disableUI = process.env.DISABLE_UI; const disableUI = process.env.DISABLE_UI;
const faviconURL = process.env.FAVICON_URL; const faviconURL = process.env.FAVICON_URL;
const forceSSL = process.env.FORCE_SSL; const forceSSL = process.env.FORCE_SSL;
const frameAncestors = process.env.ALLOWED_FRAME_URLS; const frameAncestors = process.env.ALLOWED_FRAME_URLS ?? '';
const privateMode = process.env.PRIVATE_MODE; const privateMode = process.env.PRIVATE_MODE;
const trackerScriptName = process.env.TRACKER_SCRIPT_NAME; const trackerScriptName = process.env.TRACKER_SCRIPT_NAME;
const trackerScriptURL = process.env.TRACKER_SCRIPT_URL; const trackerScriptURL = process.env.TRACKER_SCRIPT_URL;

View file

@ -145,7 +145,7 @@ export async function POST(request: Request) {
const base = hostname ? `https://${hostname}` : 'https://localhost'; const base = hostname ? `https://${hostname}` : 'https://localhost';
const currentUrl = new URL(url, base); const currentUrl = new URL(url, base);
let urlPath = currentUrl.pathname === '/undefined' ? '' : currentUrl.pathname; let urlPath = currentUrl.pathname === '/undefined' ? '' : currentUrl.pathname + currentUrl.hash;
const urlQuery = currentUrl.search.substring(1); const urlQuery = currentUrl.search.substring(1);
const urlDomain = currentUrl.hostname.replace(/^www./, ''); const urlDomain = currentUrl.hostname.replace(/^www./, '');
@ -169,7 +169,7 @@ export async function POST(request: Request) {
const twclid = currentUrl.searchParams.get('twclid'); const twclid = currentUrl.searchParams.get('twclid');
if (process.env.REMOVE_TRAILING_SLASH) { if (process.env.REMOVE_TRAILING_SLASH) {
urlPath = urlPath.replace(/(.+)\/$/, '$1'); urlPath = urlPath.replace(/\/(?=(#.*)?$)/, '');
} }
if (referrer) { if (referrer) {

View file

@ -127,7 +127,9 @@ export async function getLocation(ip: string = '', headers: Headers, hasPayloadI
global[MAXMIND] = await maxmind.open(path.resolve(dir, 'GeoLite2-City.mmdb')); global[MAXMIND] = await maxmind.open(path.resolve(dir, 'GeoLite2-City.mmdb'));
} }
const result = global[MAXMIND].get(ip); // When the client IP is extracted from headers, sometimes the value includes a port
const cleanIp = ip?.split(':')[0];
const result = global[MAXMIND].get(cleanIp);
if (result) { if (result) {
const country = result.country?.iso_code ?? result?.registered_country?.iso_code; const country = result.country?.iso_code ?? result?.registered_country?.iso_code;

View file

@ -150,6 +150,7 @@
try { try {
const res = await fetch(endpoint, { const res = await fetch(endpoint, {
keepalive: true,
method: 'POST', method: 'POST',
body: JSON.stringify({ type, payload }), body: JSON.stringify({ type, payload }),
headers: { headers: {