Merge branch 'analytics' of https://github.com/umami-software/umami into dev
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Has been cancelled
Node.js CI / build (push) Has been cancelled

This commit is contained in:
Francis Cao 2026-01-29 10:24:15 -08:00
commit 1229663814
2 changed files with 14 additions and 3 deletions

View file

@ -10,6 +10,16 @@ import { safeDecodeURIComponent } from '@/lib/url';
const MAXMIND = 'maxmind'; const MAXMIND = 'maxmind';
const PROVIDER_HEADERS = [ const PROVIDER_HEADERS = [
// Umami custom headers (cloud mode only)
...(process.env.CLOUD_MODE
? [
{
countryHeader: 'x-umami-client-country',
regionHeader: 'x-umami-client-region',
cityHeader: 'x-umami-client-city',
},
]
: []),
// Cloudflare headers // Cloudflare headers
{ {
countryHeader: 'cf-ipcountry', countryHeader: 'cf-ipcountry',
@ -66,13 +76,13 @@ function decodeHeader(s: string | undefined | null): string | undefined | null {
return Buffer.from(s, 'latin1').toString('utf-8'); return Buffer.from(s, 'latin1').toString('utf-8');
} }
export async function getLocation(ip: string = '', headers: Headers, hasPayloadIP: boolean) { export async function getLocation(ip: string = '', headers: Headers, skipHeaders: boolean) {
// Ignore local ips // Ignore local ips
if (!ip || (await isLocalhost(ip))) { if (!ip || (await isLocalhost(ip))) {
return null; return null;
} }
if (!hasPayloadIP && !process.env.SKIP_LOCATION_HEADERS) { if (!skipHeaders && !process.env.SKIP_LOCATION_HEADERS) {
for (const provider of PROVIDER_HEADERS) { for (const provider of PROVIDER_HEADERS) {
const countryHeader = headers.get(provider.countryHeader); const countryHeader = headers.get(provider.countryHeader);
if (countryHeader) { if (countryHeader) {

View file

@ -1,6 +1,7 @@
import ipaddr from 'ipaddr.js'; import ipaddr from 'ipaddr.js';
export const IP_ADDRESS_HEADERS = [ export const IP_ADDRESS_HEADERS = [
...(process.env.CLOUD_MODE ? ['x-umami-client-ip'] : []), // Umami custom header (cloud mode only)
'true-client-ip', // CDN 'true-client-ip', // CDN
'cf-connecting-ip', // Cloudflare 'cf-connecting-ip', // Cloudflare
'fastly-client-ip', // Fastly 'fastly-client-ip', // Fastly
@ -81,7 +82,7 @@ export function getIpAddress(headers: Headers) {
} }
if (header === 'forwarded') { if (header === 'forwarded') {
const match = ip.match(/for=(\[?[0-9a-fA-F:.]+\]?)/); const match = ip.match(/for=(\[?[0-9a-fA-F:.]+]?)/);
if (match) { if (match) {
return resolveIp(match[1]); return resolveIp(match[1]);