Skip to content

Add anonymous session mode with redacted user data#13

Open
CS-5 wants to merge 1 commit into
stagingfrom
claude/add-anonymous-mode-bR0Z9
Open

Add anonymous session mode with redacted user data#13
CS-5 wants to merge 1 commit into
stagingfrom
claude/add-anonymous-mode-bR0Z9

Conversation

@CS-5
Copy link
Copy Markdown
Member

@CS-5 CS-5 commented May 14, 2026

Summary

Adds support for anonymous browsing mode, allowing users to access statistics without providing a password. Anonymous sessions display redacted user information (hidden names and avatars) while maintaining full access to emoji reaction data.

Key Changes

Backend (Worker)

  • Added createAnonymousSessionToken() and verifyAnonymousSessionToken() functions with distinct token prefix (catalyst-anon-v1) to distinguish from password-authenticated sessions
  • Introduced verifyAnySessionToken() that checks both token types and returns the session mode ("full" or "anonymous")
  • New /api/auth/anonymous endpoint that creates anonymous sessions after Turnstile verification (no password required)
  • Extracted Turnstile verification into reusable verifyTurnstile() helper function
  • Added AppEnv type with sessionMode variable to track authentication type across requests
  • Updated all analytics/emoji/user/ranking routes to redact user names and avatars when in anonymous mode via isAnonymous() helper
  • Dynamic cache key generation based on session mode to prevent cache poisoning between authenticated and anonymous views

Frontend (Web)

  • New AnonymousAvatar component: generates deterministic, colorful identicons from user IDs using FNV-1a hashing
  • New AnonymousName component: displays variable-length redaction bars (4-9 characters) based on user ID hash
  • New UserName component: unified display that shows real names for authenticated users or redacted names for anonymous users
  • Updated Avatar component to support anonymous mode with identicon fallback
  • Added "Continue anonymously" button in AccessGate with visual separator
  • New AnonymousBanner component: fixed bottom-right banner showing anonymous mode status with sign-in option
  • Added SESSION_ANON_KEY localStorage flag and isAnonymousMode() helper to track anonymous sessions
  • Updated all user-facing components (leaderboards, trends, detail views) to use UserName and AnonymousAvatar for consistent redaction
  • Anonymous mode persists across page navigation via localStorage

Utilities

  • New packages/web/src/lib/anonymous.ts: FNV-1a hash function, redaction length calculation, and identicon seed generation
  • New packages/worker/src/lib/types.ts: AppEnv type definition and isAnonymous() helper

Implementation Details

  • Turnstile verification is required for both authenticated and anonymous sessions, preventing abuse
  • Anonymous tokens use the same TTL mechanism as password tokens for consistency
  • Both token types are verified in constant time to prevent timing attacks
  • Identicons are fully deterministic: same user ID always generates the same avatar and redaction length
  • Cache layer respects session mode to prevent authenticated users from seeing anonymized data and vice versa
  • Anonymous sessions can be revoked independently via distinct token prefix without affecting password-authenticated sessions

https://claude.ai/code/session_01Dw3UaAP1QDLQU47ZJhMNvX

A "Continue anonymously" button on the AccessGate issues a Turnstile-gated
anonymous session token. The worker tracks session mode in the bearer auth
middleware and redacts displayName + avatarUrl in stats responses for
anonymous sessions, so PII never reaches the client.

In the web UI, names render as a pixelated redaction pill of deterministic
hash-based width, and avatars render as a 5x5 symmetric identicon derived
from the userId. A small bottom-right banner lets anonymous visitors exit
back to the password gate.

The analytics route's cache namespace varies by session mode so authed and
anonymous responses can't share entries.

https://claude.ai/code/session_01Dw3UaAP1QDLQU47ZJhMNvX
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.

2 participants