Commit graph

5542 commits

Author SHA1 Message Date
Arthur Sepiol
34db34759f feat: implement automatic session linking and identity stitching (#3820)
Links anonymous browser sessions to authenticated user identities, enabling unified
user journey tracking across login boundaries. This solves the "logged-out anonymous
session → logged-in session" tracking gap, providing complete funnel visibility and
accurate visitor deduplication.

## Changes

- Client-side: Persistent visitor ID in localStorage (data-identity-stitching attribute)
- Server-side: identity_link table linking visitors to distinct IDs (authenticated users)
- Query updates: getWebsiteStats now deduplicates by resolved identity
- Graceful degradation: Works in Safari private browsing and when localStorage unavailable

## Implementation Details

Uses hybrid approach combining client-side persistence with server-side linking:
- Visitor ID generated once per browser, persists across sessions
- When user logs in, identify() creates identity link
- stats queries join through identity_link to deduplicate cross-device sessions

Both PostgreSQL and ClickHouse supported with appropriate query patterns:
- PostgreSQL: normalized schema, joins through session table
- ClickHouse: denormalized with ReplacingMergeTree for deduplication

## Edge Cases Handled

- Safari private browsing: localStorage throws, visitorId undefined, no link created
- localStorage cleared: new visitorId generated, creates new link
- Multiple tabs: same visitorId shared via localStorage
- Multiple devices: one visitor can link to multiple distinct_ids
- Multiple accounts: one distinct_id can link to multiple visitors

## Test Plan

- [ ] Enable feature on test website (default enabled)
- [ ] Anonymous pageview - confirm visitor_id in events table
- [ ] Call umami.identify('user1') - confirm identity_link created
- [ ] Stats show 1 visitor (deduplicated)
- [ ] Log out, browse anonymously, stats still show 1 visitor
- [ ] Test with data-identity-stitching="false" - no visitor_id collected
- [ ] Test in Safari private browsing - no errors, gracefully skips
- [ ] Test ClickHouse: verify identity_link table populated and FINAL keyword works
- [ ] Verify retroactive: historical anonymous session attributed correctly
2025-12-03 16:54:56 +03:00
Arthur Sepiol
a902a87c08 feat: implement identity stitching for session linking (#3820)
Adds automatic session linking/identity stitching to link anonymous
browsing sessions with authenticated user sessions.

## Changes

### Database Schema
- Add `identity_link` table (PostgreSQL + ClickHouse) to store mappings
  between visitor IDs and authenticated user IDs
- Add `visitor_id` field to `Session` model
- Add `visitor_id` column to ClickHouse `website_event` table

### Client Tracker
- Generate and persist `visitor_id` in localStorage
- Include `vid` in all tracking payloads
- Support opt-out via `data-identity-stitching="false"` attribute

### API
- Accept `vid` parameter in `/api/send` endpoint
- Auto-create identity links when `identify()` is called with both
  visitor_id and distinct_id
- Store visitor_id in sessions and events

### Query Updates
- Update `getWebsiteStats` to deduplicate visitors by resolved identity
- Visitors who browse anonymously then log in are now counted as one user

## Usage

When a user logs in, call `umami.identify(userId)`. If identity stitching
is enabled (default), the tracker automatically links the anonymous
visitor_id to the authenticated userId. Stats queries then resolve
linked identities to accurately count unique visitors.

Resolves #3820
2025-12-03 16:06:54 +03:00
Mike Cao
9a269ab811
Merge pull request #3805 from prince0xdev/feat/mobile-navigation-improvement
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
Improve mobile navigation: clickable “online” badge & page title
2025-12-03 00:16:16 -08:00
Prince EKPINSE
beb2bc0a06 feat: improve mobile navigation with clickable page elements (#3770) 2025-11-29 13:53:32 +01:00
Prince EKPINSE
776e404c6f fix: [#3778] update 'Edit' word to support translation 2025-11-29 12:40:22 +01:00
Mike Cao
a19b92a5cb
Merge pull request #3756 from Abrar74774/master
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
docs: remove underlines between badges in README.md
2025-11-25 21:31:35 -08:00
Mike Cao
aaa1f9dc58 Merge branch 'dev'
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-11-18 10:27:02 -08:00
Mike Cao
abc1b50ad0 Reordered IP headers.
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-11-18 10:25:08 -08:00
Mike Cao
24b017cad8
Merge pull request #3765 from umami-software/dev
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
v3.0.1
2025-11-17 22:39:48 -08:00
Mike Cao
ef3f7274e3 Remember last team.
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-17 19:12:25 -08:00
Abrar74774
d34ad1d07f docs: remove underlines between bandges in README.md 2025-11-15 23:34:26 +03:00
Mike Cao
1852acc333 Merge remote-tracking branch 'origin/dev' into dev
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-11-14 15:46:59 -08:00
Mike Cao
cb63e49a9b Fixed triggered event lookup. Closes #3742. 2025-11-14 15:42:23 -08:00
Mike Cao
d382ad2975
Merge pull request #3682 from rkoh-rq/patch-1
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
fix: quote "event" reserved keyword in journey queries
2025-11-14 11:44:31 -08:00
Mike Cao
b1dc690e2f
Merge branch 'dev' into patch-1 2025-11-14 11:44:20 -08:00
Francis Cao
cc8254985b Increase resetWebsite timeout. fix retention bug returning decimal day_number in CH.
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
Closes #3698
2025-11-14 09:11:26 -08:00
Francis Cao
a3f32b036d revert getDateStringSQL for CH 2025-11-14 08:10:13 -08:00
Mike Cao
5ded9abbfe Added data-fetch-credentials attribute. Closes #3644
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-13 19:42:04 -08:00
Francis Cao
6751bf88bb fix chart and timezone issues, pass consistent dates to DB.
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
Closes #3700
2025-11-13 15:52:24 -08:00
Mike Cao
81bedec6d5
Merge pull request #3749 from Maxime-J/os-formatting
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
Restore OS formatting in tables
2025-11-13 13:06:39 -08:00
Maxime-J
4531538ad3 Restore OS formatting in tables 2025-11-13 15:46:05 +01:00
Mike Cao
9fbcec46af
Merge pull request #3737 from prince0xdev/fix/login-autocomplete-username
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
fix: correct autocomplete attributes to enable password manager autofill
2025-11-12 21:38:12 -08:00
Mike Cao
d98cc35208
Merge pull request #3743 from Mintimate/master
feat(geo): add redirect support for direct .mmdb downloads
2025-11-12 21:33:19 -08:00
Mike Cao
97ebdc1bab Merge remote-tracking branch 'origin/dev' into dev
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-12 16:40:50 -08:00
Mike Cao
8a66603d32 Responsive fixes. 2025-11-12 16:39:58 -08:00
Mintimate
e13362bfec feat(geo): add redirect support for direct .mmdb downloads 2025-11-12 19:18:44 +08:00
Mintimate
371ff47325 feat(geo): add support for direct .mmdb URL and custom GEO_DATABASE_URL
- Support GEO_DATABASE_URL environment variable for custom database URL

- Auto-detect .mmdb files and skip decompression

- Maintain backward compatibility with tar.gz archives
2025-11-12 17:51:19 +08:00
Francis Cao
3aa09572f5 Merge branch 'master' of https://github.com/umami-software/umami into dev
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-11 21:40:28 -08:00
Prince EKPINSE
a56746ce6d fix: enable password manager autofill on login form (#3735) 2025-11-12 00:15:05 +01:00
Prince EKPINSE
678a2ccdf3 fix: correct autocomplete attributes to enable password manager autofill 2025-11-12 00:08:36 +01:00
Francis Cao
bf498d9239 add RealtimeData to types
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-11-11 13:45:41 -08:00
Francis Cao
30781430c5 remove timezone from realtime. Closes #3700 2025-11-11 13:13:25 -08:00
Francis Cao
14f5babea7
Merge pull request #3731 from Maxime-J/unique-constraint
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
Prevent duplicate key db errors on session creation
2025-11-11 11:13:14 -08:00
Maxime-J
14f3db550b Use raw query with on conflict in createSession 2025-11-11 10:32:31 +01:00
Mike Cao
3d8402d2f1 Merge branch 'master' into dev 2025-11-10 22:44:36 -08:00
Mike Cao
7ac5913c86
Merge pull request #3704 from prince0xdev/fix/disable-download-when-no-data
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
Fix: Disable download button when no data available
2025-11-10 22:43:42 -08:00
Mike Cao
a6e130ab2e
Fix DownloadButton to avoid duplicate downloadCsv call
Removed redundant downloadCsv call from handleClick.
2025-11-10 22:43:22 -08:00
Mike Cao
4fe4bb99b7
Apply suggestion from @greptile-apps[bot]
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-11-10 22:42:20 -08:00
Mike Cao
592f7c0ae7 Added check for REDIS_URL. Closes #3677.
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-10 21:08:55 -08:00
Francis Cao
8787764e0e Merge branch 'analytics' of https://github.com/umami-software/umami into dev
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-10 17:32:18 -08:00
Francis Cao
839bf3898f add canonicalizeTimezone conversions
Co-authored-by: Om Mishra <contact@om-mishra.com>
2025-11-10 17:27:45 -08:00
Francis Cao
13ab84d50e Revert "add canonicalizeTimezone conversions"
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
This reverts commit a1d6204373.
2025-11-10 17:26:06 -08:00
Francis Cao
a1d6204373 add canonicalizeTimezone conversions
Co-authored-by: Om Mishra <contact@om-mishra.com>
2025-11-10 17:24:51 -08:00
Francis Cao
49e1582c28 implement generateTimeSeries for eventsChart 2025-11-10 15:36:43 -08:00
Francis Cao
64a6379c3c fix realtime logs for mobile
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-10 01:07:11 -08:00
Francis Cao
f3e246c64b fix hasdata queries, add hasData to website events, fix sessionactivity truncation, 2025-11-09 23:58:20 -08:00
Francis Cao
9230f3cb7b manually include basePath 2025-11-09 22:03:06 -08:00
Francis Cao
f30724629c Fix null and string return types from getWebsiteStats 2025-11-09 21:37:35 -08:00
Francis Cao
c44f6f8c9c Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-11-09 21:19:46 -08:00
Francis Cao
bf548c5aca Fix revenue bigInt but and case insensitive currency 2025-11-09 21:19:38 -08:00