feat: 1.13.0 visitor identity, Supabase cookie bridge, token build-binding#9
Merged
DorianOuvrard merged 3 commits intoJun 25, 2026
Merged
Conversation
Generate a stable anonymous visitor id and send it on every replay chunk so the backend can group a returning visitor's sessions and attach their earlier anonymous sessions once they identify. The id is a UUID persisted in localStorage (bworlds-visitor-id), scoped to the exact origin so it never leaks between builder apps that share a parent domain. Sent only on the replay payload as an additive field (the errors schema rejects unknown fields). Fail-open: an unreadable localStorage yields a per-page-load id and never throws, and a read that throws does not overwrite an existing id. Extract generateUuid into a shared module used by both the session id and the visitor id. Co-Authored-By: Claude Opus 4.8 <[email protected]>
The zero-config identity auto-bridge only read the session from localStorage, which misses Next.js / @supabase/ssr apps that keep the session in a cookie so the server can read it. Those apps stayed anonymous in replay despite a JS-readable session. The auto reader now also scans document.cookie for sb-*-auth-token, reassembles chunked .0/.1 cookies in index order, decodes the base64- base64url payload (UTF-8), and feeds the existing identity path. The cookie is read first so a stale localStorage token cannot shadow the live cookie session; localStorage apps have no auth cookie and fall through unchanged. The 2s poll catches cookie logins (cookies emit no change event) and caches the last cookie string to skip redundant decodes. httpOnly auth cookies are a no-op (not in document.cookie). Co-Authored-By: Claude Opus 4.8 <[email protected]>
The replay payload trusted any bworlds_token cookie on the domain: it decoded the JWT email claim and forwarded the token without checking the token belonged to this build. A token issued for another build can share the cookie jar (separate localhost ports in dev, or a parent-scoped cookie), so that build's user email could be stamped onto this app's sessions. The payload now reads the cookie only when the JWT's buildSlug claim equals the current build, mirroring the origin-scoping already applied to the visitor id. The JWT payload is decoded as UTF-8 so a non-ASCII email claim is not mangled. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
1.13.0
Three changes bundled into one release.
Cross-session anonymous visitor identity
The SDK generates a stable anonymous visitor id (UUID in
localStorage, origin-scoped) and sends it on every replay chunk, so the backend can group a returning visitor's sessions and attach their earlier anonymous sessions once they identify. Backend distiller wiring is tracked as vulk-corp/bworlds#913.Supabase identity from cookies (Next.js /
@supabase/ssr)The zero-config auto-bridge now reads the Supabase session from
document.cookie(sb-*-auth-token, chunked + base64url), so default Next.js +@supabase/ssrapps (session in a cookie, notlocalStorage) get their signed-in user attached automatically. The cookie is read first; localStorage apps are unchanged.bworlds_tokenbuild-binding (privacy)The replay payload trusts a
bworlds_tokencookie (email fallback + forwarded token) only when its JWTbuildSlugclaim matches the current build, so a foreign token sharing the cookie jar cannot leak another build's user. The JWT payload is decoded as UTF-8.Verification
264 vitest tests, type-check, and build green. Key behaviors (rotation reset, anti-stacking, chunk reassembly, build-binding, UTF-8 decode) proven by mutation testing.
🤖 Generated with Claude Code