Skip to content

feat(agents): send X-Base44-Anonymous-Id on unauthenticated clients#198

Open
cowchimp wants to merge 3 commits into
mainfrom
feat/anonymous-visitor-id-header
Open

feat(agents): send X-Base44-Anonymous-Id on unauthenticated clients#198
cowchimp wants to merge 3 commits into
mainfrom
feat/anonymous-visitor-id-header

Conversation

@cowchimp

Copy link
Copy Markdown
Collaborator

Summary

Unauthenticated clients now attach a stable, browser-persisted anonymous visitor id (X-Base44-Anonymous-Id) to every request, so the Base44 backend can support anonymous in-app agent access — grouping an anonymous visitor's agent conversations and enforcing ownership — without a signed-in user.

What changed

  • New getOrCreateAnonymousVisitorId() (src/utils/anon-visitor.ts): mints a UUID, persists it in localStorage, returns the same id across reloads. Browser-only — returns null on the server (SSR / createClientFromRequest), so no header is sent there.
  • createAxiosClient (src/utils/axios-client.ts): the shared request interceptor attaches X-Base44-Anonymous-Id only when the client has no token. Authenticated clients keep being identified by their Bearer token (no anon header). This covers every agent HTTP call (createConversation, addMessage, getConversation).

Why here

The published-app surface uses this public SDK (@base44/sdk), not the platform's internal SDK. Anonymous agent access can't work on published apps until the SDK sends this header — that's the gap this PR closes.

Pairs with

Platform-side anonymous in-app agent access (base44-dev/apper#11814). The backend reads X-Base44-Anonymous-Id only when there's no authenticated app user, so sending it is a no-op for authenticated traffic.

Testing

  • New tests/unit/anon-visitor.test.ts (5 tests): mint/persist/stability, fresh id after clear, returns null without a browser, and the interceptor attaches the header only when unauthenticated.
  • npm run build (tsc), eslint src, and the full unit suite (158 tests) all pass.

Unauthenticated clients now attach a stable, browser-persisted anonymous
visitor id (X-Base44-Anonymous-Id) to every request. This lets the Base44
backend support anonymous in-app agent access — grouping an anonymous
visitor's conversations and enforcing ownership — without a signed-in user.

- New getOrCreateAnonymousVisitorId() helper (localStorage-backed UUID,
  browser-only; returns null on the server so no header is sent there).
- Header is attached in the shared axios request interceptor only when the
  client has no token; authenticated clients are identified by their token.

Pairs with the platform-side anonymous in-app agent access work.
@claude

claude Bot commented Jun 16, 2026

Copy link
Copy Markdown

Claude encountered an error —— View job


I'll analyze this and get back to you.

@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown

🚀 Package Preview Available!


Install this PR's preview build with npm:

npm i @base44-preview/sdk@0.8.32-pr.198.5317b98

Prefer not to change any import paths? Install using npm alias so your code still imports @base44/sdk:

npm i "@base44/sdk@npm:@base44-preview/sdk@0.8.32-pr.198.5317b98"

Or add it to your package.json dependencies:

{
  "dependencies": {
    "@base44/sdk": "npm:@base44-preview/sdk@0.8.32-pr.198.5317b98"
  }
}

Preview published to npm registry — try new features instantly!

Reuse the existing persisted analytics session id (getAnalyticsSessionId,
localStorage `base44_analytics_session_id`) as the X-Base44-Anonymous-Id
value instead of minting a separate dedicated id. One identity per anonymous
visitor across analytics + agents (enables correlation), and a single source
of truth for the id.

Follow-up (deferred): harden the id generator to crypto-strength and/or
decouple agent identity from analytics — the current generateUuid is
Math.random-based, acceptable short-term but weak for a bearer-style
ownership credential.

- Drop src/utils/anon-visitor.ts; axios-client uses getAnalyticsSessionId.
- Rename test to anonymous-visitor-header.test.ts; assert the header equals
  the persisted analytics session id and is absent when authenticated.
@claude

claude Bot commented Jun 16, 2026

Copy link
Copy Markdown

Claude encountered an error —— View job


I'll analyze this and get back to you.

@claude

claude Bot commented Jun 21, 2026

Copy link
Copy Markdown

Claude encountered an error —— View job


I'll analyze this and get back to you.

1 similar comment
@claude

claude Bot commented Jun 21, 2026

Copy link
Copy Markdown

Claude encountered an error —— View job


I'll analyze this and get back to you.

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