Skip to content

feat(auth): anonymous sessions#851

Open
ital0 wants to merge 50 commits into
mainfrom
italomenezes/thu-383-add-anonymous-session-support-with-turnstile-bot-protection
Open

feat(auth): anonymous sessions#851
ital0 wants to merge 50 commits into
mainfrom
italomenezes/thu-383-add-anonymous-session-support-with-turnstile-bot-protection

Conversation

@ital0
Copy link
Copy Markdown
Collaborator

@ital0 ital0 commented May 9, 2026

Note

High Risk
Touches authentication/session handling and PowerSync authorization, plus a DB schema migration, so mistakes could affect login state, session security, or data sync behavior.

Overview
Introduces anonymous user support end-to-end: adds user.is_anonymous to the auth schema/migrations and upgrades Better Auth (plus enables the anonymous plugin) with a session-fixation guard that blocks /sign-in/anonymous when already authenticated.

Adds a PowerSync guard that rejects token issuance and /powersync/upload for anonymous users (both session and bearer-token paths), and updates DAL typing (getUserById) accordingly with new backend tests covering these cases.

On the client, adds an AnonymousSessionGuard that auto-creates an anonymous session when none exists, treats anonymous sessions as logged-out for sync/UI surfaces (sidebar footer, sync status, preferences sync toggle), adds cross-tab auth-token change handling, and adds PostHog alias/event tracking to link anonymous IDs to promoted accounts across OTP and SSO flows.

Reviewed by Cursor Bugbot for commit 6b34ee4. Bugbot is set up for automated code reviews on this repo. Configure here.

ital0 added 30 commits May 8, 2026 17:24
The 20-LOC information_schema columns query at the top of createAuth
forced the function async, cascading awaits through 11 files (elysia
plugin, index.ts, swagger.test.ts, and 8 auth/api test files).

The schema-drift test in CI plus Postgres' "column does not exist"
error on first anonymous sign-in already cover the deployment hazard
the health check was guarding against (M3 spec external-4). Removing
it lets createAuth stay sync, drops 11 mechanical await/Awaited<>
edits, and lets swagger.test.ts go back to being DB-less.
…load

Better Auth's M3 registration adds isAnonymous to additionalFields,
so the session.user object already carries it. The Path 1 + PUT /upload
re-fetches via getUserById were left over from when M4 ran in parallel
against an M3 that hadn't yet exposed the field.

Read user.isAnonymous directly off the session — eliminates two
redundant DB round-trips per token refresh / upload. Path 2
(Bearer-only refresh, no session derive) still needs getUserById.
- Convert anonymous sign-in promise chain to async/await for readability
- Remove unused anonymous_session_started PostHog event type
Comment thread src/waitlist/use-waitlist-state.ts
- PowerSyncStatus returns null for anonymous sessions since the backend
  rejects them and the affordance would be misleading
- SidebarFooter treats anonymous sessions as logged-out so the Sign In
  surface is shown instead of a synthetic email
Comment thread src/components/auth-gate/use-anonymous-session-guard.ts
- Replace per-file mock.module of @/contexts with createMockAuthClient
  + createTestProvider so tests exercise real provider wiring.
- Mock only single-export leaf modals (SignInModal, SyncSetupModal) and
  useIsMobile, per docs/development/testing.md.
- Add isAnonymous to MockAuthClientOptions session shape.
- remove mock.module() calls for app hooks, contexts, and modals
- rely on real implementations via createTestProvider + providers
- aligns with docs/development/testing.md (no mocking shared modules)
- Collapse phase state machine into a single hasAttempted flag
- Compute loading directly from observable state to avoid a render gap
  between mount and the post-commit effect firing
- Add effect cleanup to ignore stale completions on unmount
Comment thread backend/src/dal/anonymous.ts Outdated
Comment thread src/components/powersync-status.tsx Outdated
Comment thread src/hooks/use-powersync-credentials-invalid-listener.ts Outdated
Comment thread src/settings/preferences.tsx
Copy link
Copy Markdown
Collaborator

@raivieiraadriano92 raivieiraadriano92 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left a few question to confirm the correct behavior

…Account

- Drop the anonymous DAL (migration, row-cap, transient-error retry)
- Reduce onLinkAccount to a single delete of the anonymous user row
- Trim the auth integration test to cover the delete + fixation guard
ital0 added 3 commits May 12, 2026 13:50
Anonymous sessions have no real account to delete, so showing the
Delete My Account action is misleading and the underlying flow would
fail. Gate the section on !isAnonymous alongside isAuthenticated.
…tatus

- replace hide-entirely branch with reusing the logged-out popover path
- anonymous users now see the same sync affordance and Sign-In CTA as
  fully logged-out users, keeping the two states visually consistent
- relocate storage-event handler from use-powersync-credentials-invalid-
  listener.ts to AuthProvider so auth-token concerns live next to the
  rest of the auth lifecycle
- add coverage for both branches (token rotated → reload; token cleared
  → dispatch powersync_credentials_invalid)
- use the shared powersyncCredentialsInvalid event-name constant instead
  of repeating the string literal
Comment thread src/contexts/auth-context.test.ts Dismissed
Comment thread src/settings/preferences.tsx Outdated
- Sign In button already surfaces this affordance elsewhere
- update tests to assert on the button instead of hint text
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6b34ee4. Configure here.

Comment thread src/waitlist/use-waitlist-state.ts
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