Repository navigation
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@r69shabh is attempting to deploy a commit to the Databuddy OSS Team on Vercel. A member of the Team first needs to authorize it. |
|
izadoesdev
left a comment
There was a problem hiding this comment.
Verified against the tracker rather than the description, since getting this wrong would make getSessionId() return null for every real visitor.
packages/tracker/src/index.ts:315-316 and packages/tracker/src/core/tracker.ts:286-287 write did_session and did_session_timestamp together on every session write, so the timestamp this reads is always present for a tracker-created session. The boundary matches exactly: the tracker rotates on sessionAge >= 30 * 60 * 1000 (index.ts:313) and keeps on sessionAge < 30 * 60 * 1000 (core/tracker.ts:276), so treating exactly 30 minutes as expired is correct, and the boundary test asserts the right side of it.
The did_session without a timestamp case is also safe to treat as expired: core/tracker.ts:271-282 removes both keys when the timestamp is missing or stale, so that pairing is not a state the tracker produces.
One non-blocking note: the 30-minute window is now a constant in both packages/tracker and packages/sdk with only a comment tying them together. That will drift. A shared constant, or a test that asserts the two agree, would be the durable version.
The three red checks are Vercel – dashboard, – databuddy-status and – documentation, which are the fork-preview authorization step rather than builds; staging has no required status checks.
izadoesdev
left a comment
There was a problem hiding this comment.
Requesting changes after a closer look at how the tracker maintains did_session_timestamp, which my earlier approval missed.
The tracker only writes that timestamp on page load (packages/tracker/src/core/tracker.ts, session init) and on back/forward cache restore (packages/tracker/src/index.ts, the pageshow handler). In-app navigation in a single-page app never refreshes it, yet the tracker keeps sending the same did_session for the life of the page. With this change, 30 minutes after an SPA loads, getSessionId() returns null while events still carry that session id, so anything that reads getTrackingIds() at that point (checkout metadata for revenue attribution, for example) loses the session.
Could you apply the expiry only when no tracker is running on the page? If isTrackerAvailable() is true, return the stored did_session as is. Please add a test for that case too: tracker present plus a 31-minute-old timestamp still returns the id.
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Make the boundary test deterministic by freezing Date.now().
Review effort: Lite
Findings: 1
What changed in this PR
Updates SDK session handling to reject missing or expired session IDs after 30 minutes.
Changes:
- Adds timestamp-based session expiry validation.
- Expands tests for fresh, missing, expired, and boundary timestamps.
- Adds an SDK patch changeset.
| File | Summary |
|---|---|
packages/sdk/tests/sdk-functions.spec.ts |
Adds session expiry coverage; the exact-boundary test should freeze Date.now() for deterministic equality. |
packages/sdk/src/core/tracker.ts |
Validates stored session age before returning the session ID. |
.changeset/sdk-session-id-expiry.md |
Documents the SDK patch release. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
7af87be to
9e77d78
Compare
|
Sorry for the late commit, was occupied over the week. Addressed both pieces of feedback: @izadoesdev's change request — the expiry check now only applies when no tracker is running on the page. While rebasing onto latest
New tests: tracker present + 31-minute-old timestamp returns the id, for both the modern delegation path and the legacy no- Copilot's boundary determinism — the exact-30-minute test now installs a fixed clock ( Verified: full One open thread from your earlier note: the 30-minute window is still a duplicated constant in |
9e77d78 to
6892eec
Compare

Fixes #694
What
getSessionId()readsdid_sessionfrom sessionStorage without checkingdid_session_timestamp. The tracker rotates sessions after 30 minutes of inactivity, so between expiry and the tracker's next visit the SDK hands back a session id that is no longer the current one.getTrackingIds()andgetTrackingParams()inherit the problem since they delegate to it.Why it matters
getTrackingParams()exists to carry the ids to another origin for cross-domain tracking. If the session has actually expired, propagating the stale id links events to a session the tracker has already closed — anyone keying server-side joins on these ids gets subtly wrong data.How
getSessionId()now reads the timestamp alongside the id and returnsnullif it's missing or older than 30 minutes — the same rule the tracker uses (sessionAge < 30 * 60 * 1000ingetOrCreateSessionId()). The window is a named constant with a comment pointing at the tracker logic. URL-param priority is untouched, andgetTrackingIds/getTrackingParamsare unchanged — they get the behavior for free.Tests: the existing
did_sessionsetups now write a fresh timestamp, plus new cases for no-timestamp → null, older than 30 minutes → null, and exactly at the boundary → expired (matching the tracker's strict<check).Tests
AI disclosure: I used Claude (via Qoder) for research and writing. I found the mismatch myself while comparing the tracker's expiry logic against the SDK helper, reproduced it in the e2e suite, and sketched the fix — Claude helped complete the implementation and fill in the test cases from that. I reviewed all the generated code and ran type-check and the full e2e suite locally; the pre-push hook ran the monorepo suite clean.
Summary by cubic
getSessionId()now respects the tracker's 30-minute session expiry when the tracker isn't running, returningnullfor missing or expired timestamps (with the same strict<boundary the tracker uses), and returning the stored id as-is while the tracker is on the page.getTrackingIds()andgetTrackingParams()inherit the fix; URL params still take priority.Written for commit 06c9536. Summary will update on new commits.