Repository navigation
feat!: remove userId cookie and use SSR user state (v6.0.0) - #15
Conversation
Deploying passkeys with
|
| Latest commit: |
a9ab63a
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://82fbf0da.passkeys-3nt.pages.dev |
| Branch Preview URL: | https://feat-remove-userid-cookie.passkeys-3nt.pages.dev |
There was a problem hiding this comment.
📋 Review Summary
This pull request removes the dedicated userId cookie across server session management, client utility functions, and web components, relying instead on session-backed user state and window.user. The package version is correctly bumped to 6.0.0 to reflect this breaking change. The overall refactoring is concise and improves session hygiene, but interpolating d.user into an inline script in functions/layout.js requires escaping to prevent potential Cross-Site Scripting (XSS).
🔍 General Feedback
- Eliminating the separate
userIdcookie simplifies state management and removes duplicate identity signals in favour of the authoritative session store. - Updating the major version to 6.0.0 correctly signals the breaking change for consumers who may have inspected the
userIdcookie directly. - Both
<sign-in>and<sign-in-button>components now consistently support receivinguseras a property or falling back to globalwindow.user.
📊 Token Usage & Cost Efficiency
| Metric | Value |
|---|---|
| Input Tokens (uncached) | 3,304 |
| Input Tokens (cached) | 28,791 (⚡ 88.5% cached) |
| PR Comments History Tokens | 434 |
| Thinking / Reasoning Tokens | 20,191 |
| Output Tokens | 482 |
| Total Session Tokens | 53,202 |
| Cost (uncached input) | $0.0028 |
| Cost (cached input) | $0.0022 |
| Cost (thinking / reasoning) | $0.0757 |
| Cost (response output) | $0.0018 |
| Estimated Total Cost | $0.0825 |
Gemini 3.8 Flash: introductory rate $0.75/$3.75 per 1M applied; reverts to $1.5/$7.5 after 2026-12-31.
Gemini 3.8 Flash: standard tier; batch and flex are half again, priority is higher.
Cache reads are priced here, but context-cache STORAGE, where the model charges for it separately per token-hour, is not included, so the figure can run slightly low.
There was a problem hiding this comment.
📋 Review Summary
This pull request refactors user session state management across the application by removing the standalone userId cookie in favour of server-verified user data (c.data.user) and client-side hydration via window.user. The client web components (sign-in and sign-in-button) have been updated to consume this state reactively, and the package version has been correctly incremented to 6.0.0 for this breaking change. Overall, this change improves security, simplifies cookie management, and enhances codebase maintainability.
✅ Resolved Items from Prior Reviews
- Escaped
<characters to\u003cduring JSON serialisation inlayout.jsto prevent inline<script>XSS breakout. (functions/layout.js:43)
🔍 General Feedback
- Eliminating the separate
userIdcookie simplifies cookie handling across the library and removes reliance on unauthenticated cookie values on the client. - Centralising user context through
c.data.userin the Cloudflare Pages middleware and hydrating client components via properties andwindow.userprovides a cleaner, more robust architecture. - Appropriate semver major version bump to 6.0.0 reflecting the breaking change in cookie behaviour.
📊 Token Usage & Cost Efficiency
| Metric | Value |
|---|---|
| Input Tokens (uncached) | 3,076 |
| Input Tokens (cached) | 28,926 (⚡ 88.9% cached) |
| PR Comments History Tokens | 549 |
| Thinking / Reasoning Tokens | 15,959 |
| Output Tokens | 310 |
| Total Session Tokens | 48,820 |
| Cost (uncached input) | $0.0027 |
| Cost (cached input) | $0.0022 |
| Cost (thinking / reasoning) | $0.0598 |
| Cost (response output) | $0.0012 |
| Estimated Total Cost | $0.0659 |
Gemini 3.8 Flash: introductory rate $0.75/$3.75 per 1M applied; reverts to $1.5/$7.5 after 2026-12-31.
Gemini 3.8 Flash: standard tier; batch and flex are half again, priority is higher.
Cache reads are priced here, but context-cache STORAGE, where the model charges for it separately per token-hour, is not included, so the figure can run slightly low.
There was a problem hiding this comment.
📋 Review Summary
This PR refactors session management by removing the explicit userId cookie in favour of passing the user object directly from request context to templates and frontend components via a shared state module. In addition, the package version is bumped to 6.0.0. Minor cleanups around attribute quoting and test coverage for the new component behaviour are recommended.
✅ Resolved Items from Prior Reviews
- Resolved XSS vulnerability in layout.js by removing the inline window.user script injection and passing user data into components with JSON entity escaping. (
functions/layout.js:43)
🔍 General Feedback
- Eliminating the separate
userIdcookie reduces redundant cookie footprint and simplifies sign-out and session lifecycle handling. - Using
c.data.useras the single source of truth across server-rendered templates (dashboard.js,index.js,signin.js, andlayout.js) creates a cleaner and more consistent data flow.
📊 Token Usage & Cost Efficiency
| Metric | Value |
|---|---|
| Input Tokens (uncached) | 30,023 |
| PR Comments History Tokens | 669 |
| Output Tokens | 758 |
| Total Session Tokens | 31,450 |
| Cost (uncached input) | $0.0230 |
| Cost (output) | $0.0028 |
| Estimated Total Cost | $0.0259 |
Gemini 3.8 Flash: introductory rate $0.75/$3.75 per 1M applied; reverts to $1.5/$7.5 after 2026-12-31.
Gemini 3.8 Flash: standard tier; batch and flex are half again, priority is higher.
There was a problem hiding this comment.
📋 Review Summary
This pull request completes the transition from client-accessible userId cookies to a secure session-driven user state model, bumping the package to major version 6.0.0. Client components (<sign-in> and <sign-in-button>) now ingest user state directly via attributes and share it via in-memory state. Prior review feedback regarding HTML attribute escaping and sign-out redirection has been comprehensively addressed.
✅ Resolved Items from Prior Reviews
- Removed unsafe JSON interpolation within an inline script tag in functions/layout.js, eliminating potential XSS risks. (
functions/layout.js:43) - Escaped HTML entities (&, <, >, ") when serialising the user object into the sign-in-button attribute in functions/layout.js. (
functions/layout.js:67) - Escaped HTML attribute characters when serialising user data for the sign-in web component in functions/signin.js. (
functions/signin.js:22) - Updated SignIn.signOut() in public/components/sign-in.js to redirect to '/' upon sign out, ensuring consistent behavior with SignInButton. (
public/components/sign-in.js:201)
🔍 General Feedback
- The removal of the client-readable
userIdcookie in favour of server session resolution and client state store is a substantial improvement to security and architectural clarity. - Documentation update recommendation: As
stateis now imported directly by the web components (import state from 'state'), the CDN importmap snippet inREADME.mdshould be updated in a follow-up commit to include"state": "https://cdn.jsdelivr.net/gh/treeder/state@3/state.js"and update the CDN version tag from@4to@6.
📊 Token Usage & Cost Efficiency
| Metric | Value |
|---|---|
| Input Tokens (uncached) | 30,421 |
| PR Comments History Tokens | 1,018 |
| Thinking / Reasoning Tokens | 9,829 |
| Output Tokens | 491 |
| Total Session Tokens | 41,759 |
| Cost (uncached input) | $0.0236 |
| Cost (thinking / reasoning) | $0.0369 |
| Cost (response output) | $0.0018 |
| Estimated Total Cost | $0.0623 |
Gemini 3.8 Flash: introductory rate $0.75/$3.75 per 1M applied; reverts to $1.5/$7.5 after 2026-12-31.
Gemini 3.8 Flash: standard tier; batch and flex are half again, priority is higher.
Summary
userIdcookie from session creation and deletion, keeping only thesessioncookie.window.uservia SSR and useuserproperty /window.userin client components (sign-in,sign-in-button).6.0.0.Key Changes
src/sessions.js: Stop serializinguserIdcookie inputSession.src/utils.js&public/js/signout.js: Only deletesessioncookie on sign-out.functions/layout.js,functions/index.js,functions/dashboard.js,functions/signin.js: Passc.data.userand setwindow.user.public/components/sign-in.js&public/components/sign-in-button.js: Checkthis.user || window.userinstead ofdocument.cookie.includes('userId=').Verification
node test/test_passkeys_multi.js, all unit tests pass.