diff --git a/.github/ISSUE_TEMPLATE/1.bug_report.yml b/.github/ISSUE_TEMPLATE/1.bug_report.yml index 711468f25..2404918b8 100644 --- a/.github/ISSUE_TEMPLATE/1.bug_report.yml +++ b/.github/ISSUE_TEMPLATE/1.bug_report.yml @@ -25,7 +25,7 @@ body: - type: input attributes: 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 attributes: label: Which browser are you using? (if relevant) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 314c6944b..835407b41 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,8 @@ env: jobs: build: + # Only run the CI if it belongs to the original repository + if: github.repository == 'umami-software/umami' runs-on: ubuntu-latest strategy: diff --git a/db/clickhouse/schema.sql b/db/clickhouse/schema.sql index fef600e05..1080b4d11 100644 --- a/db/clickhouse/schema.sql +++ b/db/clickhouse/schema.sql @@ -122,7 +122,7 @@ CREATE TABLE umami.website_event_stats_hourly min_time SimpleAggregateFunction(min, DateTime('UTC')), max_time SimpleAggregateFunction(max, DateTime('UTC')), tag SimpleAggregateFunction(groupArrayArray, Array(String)), - distinct_id, + distinct_id String, created_at Datetime('UTC') ) ENGINE = AggregatingMergeTree @@ -213,7 +213,7 @@ FROM (SELECT min(created_at) min_time, max(created_at) max_time, arrayFilter(x -> x != '', groupArray(tag)) tag, - distinct_id String, + distinct_id, toStartOfHour(created_at) timestamp FROM umami.website_event GROUP BY website_id, diff --git a/next.config.mjs b/next.config.mjs index 792d21f18..69ce52bef 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -16,7 +16,7 @@ const disableLogin = process.env.DISABLE_LOGIN; const disableUI = process.env.DISABLE_UI; const faviconURL = process.env.FAVICON_URL; 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 trackerScriptName = process.env.TRACKER_SCRIPT_NAME; const trackerScriptURL = process.env.TRACKER_SCRIPT_URL; diff --git a/src/app/api/send/route.ts b/src/app/api/send/route.ts index 60d6f7af0..65c88a285 100644 --- a/src/app/api/send/route.ts +++ b/src/app/api/send/route.ts @@ -145,7 +145,7 @@ export async function POST(request: Request) { const base = hostname ? `https://${hostname}` : 'https://localhost'; 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 urlDomain = currentUrl.hostname.replace(/^www./, ''); @@ -169,7 +169,7 @@ export async function POST(request: Request) { const twclid = currentUrl.searchParams.get('twclid'); if (process.env.REMOVE_TRAILING_SLASH) { - urlPath = urlPath.replace(/(.+)\/$/, '$1'); + urlPath = urlPath.replace(/\/(?=(#.*)?$)/, ''); } if (referrer) { diff --git a/src/lib/detect.ts b/src/lib/detect.ts index a023d27d2..ae750469b 100644 --- a/src/lib/detect.ts +++ b/src/lib/detect.ts @@ -127,7 +127,9 @@ export async function getLocation(ip: string = '', headers: Headers, hasPayloadI 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) { const country = result.country?.iso_code ?? result?.registered_country?.iso_code; diff --git a/src/tracker/index.js b/src/tracker/index.js index 905ba4344..76d29a1dd 100644 --- a/src/tracker/index.js +++ b/src/tracker/index.js @@ -150,6 +150,7 @@ try { const res = await fetch(endpoint, { + keepalive: true, method: 'POST', body: JSON.stringify({ type, payload }), headers: {