Skip to content

feat: 1.13.0 visitor identity, Supabase cookie bridge, token build-binding#9

Merged
DorianOuvrard merged 3 commits into
mainfrom
feat/1.13.0-visitor-id-and-supabase-cookie-bridge
Jun 25, 2026
Merged

feat: 1.13.0 visitor identity, Supabase cookie bridge, token build-binding#9
DorianOuvrard merged 3 commits into
mainfrom
feat/1.13.0-visitor-id-and-supabase-cookie-bridge

Conversation

@DorianOuvrard

Copy link
Copy Markdown
Contributor

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/ssr apps (session in a cookie, not localStorage) get their signed-in user attached automatically. The cookie is read first; localStorage apps are unchanged.

bworlds_token build-binding (privacy)

The replay payload trusts a bworlds_token cookie (email fallback + forwarded token) only when its JWT buildSlug claim 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

DorianOuvrard and others added 3 commits June 25, 2026 11:48
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]>
@DorianOuvrard DorianOuvrard merged commit acff90f into main Jun 25, 2026
1 check passed
@DorianOuvrard DorianOuvrard deleted the feat/1.13.0-visitor-id-and-supabase-cookie-bridge branch June 25, 2026 19:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant