🐛 [devext] support v7 session cookie and expose anonymous ID / account context - #4960
🐛 [devext] support v7 session cookie and expose anonymous ID / account context#4960mormubis wants to merge 7 commits into
Conversation
🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: 248ec33 | Docs | View more details | Give us feedback! |
5eb1c53 to
8af253c
Compare
Bundles Sizes Evolution
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8af253ce64
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| .find(([cookieName]) => cookieName === name) | ||
| ?.[1] |
There was a problem hiding this comment.
Match the active v7 cookie by its configuration marker
issue: When multiple _dd_s_v2 cookies are visible, such as after changing trackSessionAcrossSubdomains or partitioned-cookie settings, this returns the first value regardless of its c marker. The v7 SDK deliberately selects the cookie whose marker matches its current cookie options in sessionInCookie.ts, so the extension can display and link to a stale or unrelated session instead of the one the SDK is using.
Useful? React with 👍 / 👎.
The SDK version string cannot identify which cookie name is active: local dev builds always report 'dev' regardless of which major is checked out, so a v6 and a v7 dev build are indistinguishable. Read both names and keep whichever holds the more recently created valid session instead. Also apply c marker matching to _dd_s, not just _dd_s_v2, since v6 with betaEncodeCookieOptions could also write duplicates under that name.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 248ec3378f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const domain = config?.domain | ||
| const crossSite = config?.usePartitionedCrossSiteSessionCookie ? 1 : 0 | ||
| const domainCount = domain ? domain.split('.').length - 1 : 0 | ||
| const expectedC = ((domainCount << 1) | crossSite).toString(16) |
There was a problem hiding this comment.
Derive the marker from the actual cookie domain
issue: When trackSessionAcrossSubdomains is enabled, getInitConfiguration() exposes that boolean but no computed domain property; the SDK derives the domain internally with getCurrentSite(). Consequently domainCount remains zero here, the expected c marker does not match the active cross-subdomain cookie, and the fallback can display a stale duplicate. Fresh evidence in this revision is the new marker-matching implementation's direct read of the nonexistent config.domain value.
Useful? React with 👍 / 👎.
| const cookieRawValue = | ||
| v2Session && v6Session | ||
| ? (Number(v2Session.created) >= Number(v6Session.created) ? v2RawValue : v6RawValue) | ||
| : (v2RawValue ?? v6RawValue) |
There was a problem hiding this comment.
Select the cookie whose parsed session is valid
issue: When _dd_s_v2 contains an expiration tombstone such as isExpired=1 while a v6 SDK has an active _dd_s cookie, v2Session is correctly parsed as invalid but this fallback still selects v2RawValue merely because it is defined. The Infos tab then loses the active v6 session ID and links; choose between the validated sessions rather than the raw values.
Useful? React with 👍 / 👎.
| ` | ||
| document.cookie = '_dd_s=isExpired=1; expires=${expires}; path=/' | ||
| if (document.cookie.includes('_dd_s_v2=')) { | ||
| document.cookie = '_dd_s_v2=isExpired=1; expires=${expires}; path=/' |
There was a problem hiding this comment.
Preserve the anonymous ID when ending a v7 session
issue: On the default v7 configuration where anonymous-user tracking is enabled, replacing _dd_s_v2 with only isExpired=1 discards its aid. The SDK's own stopSession() path deliberately carries that value into the expired state so the anonymous identity persists across session renewal; clicking “End current session” instead assigns a new anonymous identity on the next interaction. Include the existing aid in the tombstone.
Useful? React with 👍 / 👎.
| const cookieRawValue = | ||
| v2Session && v6Session | ||
| ? (Number(v2Session.created) >= Number(v6Session.created) ? v2RawValue : v6RawValue) | ||
| : (v2RawValue ?? v6RawValue) |
There was a problem hiding this comment.
Determine freshness from session expiry instead of creation
issue: When both cookie names contain IDs—for example, a v6 session starts, the same origin briefly loads v7, and then returns to v6 within the original session—the abandoned v7 cookie always wins because its fixed created timestamp is newer. Active sessions update expire, not created, and this parser also accepts an elapsed expire, so the stale cookie can continue shadowing the session used by the currently running SDK long after it stopped being refreshed; use the SDK version when reliable or compare active expiry/freshness instead.
Useful? React with 👍 / 👎.
Motivation
SDK v7 renamed the session cookie from
_dd_sto_dd_s_v2, so the extension was showing empty session data for any v7 app. v7 also added anaid(anonymous ID) field in the cookie and agetAccount()API that the extension wasn't exposing. Jira: RUM-17172.Changes
In
useSdkInfos.ts, cookie reading no longer tries to detect which SDK major is running. The version string can't do that reliably: local dev builds always reportversion: "dev"regardless of which major is checked out, so a v6 dev build and a v7 dev build look identical. Instead, it reads both_dd_sand_dd_s_v2, and keeps whichever holds the more recently created valid session, since only an actively running SDK writes fresh data under its own cookie name.Both cookie names can also have duplicates under the same name (e.g. after changing
trackSessionAcrossSubdomainsorusePartitionedCrossSiteSessionCookie, or with v6'sbetaEncodeCookieOptions). The SDK picks the right one by matching acmarker encoded in the cookie value against its current config.findMatchingCookieValue()replicates that matching for both cookie names, so the extension doesn't just grab the first duplicate.The
aidcookie field is mapped toanonymousIdfor readability. AddedgetAccount()calls for both RUM and Logs.In
infosTab.tsx, anonymous ID shows under the cookie section, account under RUM and Logs.endSession()also expires_dd_s_v2, but only if it already exists — unconditionally writing it on a v6 page would create a phantom cookie that shadows the real v6 session on next load.Test instructions
yarn dev, openhttp://localhost:8080, open the Infos tab. Session data should show, including the anonymous ID.DD_RUM.setAccount({ id: 'test' })in the console. Account should appear under RUM._dd_s_v2should be expired in Application → Cookies, and reloading starts a new session._dd_s(e.g.document.cookie = '_dd_s=id=v6&created=' + Date.now() + '&expire=9999999999999; path=/') while a stale_dd_s_v2is still present. The Infos tab should now read from_dd_s, since it holds the more recently created session._dd_s_v2cookies with differentcvalues by hand (or reuse ones left over from changingtrackSessionAcrossSubdomainsbetween reloads) and confirm the extension shows the one matching the SDK's current config, not just the first one found.Checklist