Skip to content

feat: a Room can put the browser and platform a participant joined with in their groups - #28

Merged
sunib merged 1 commit into
mainfrom
feat/browser-groups
Oct 6, 2026
Merged

sunib merged 1 commit into
mainfrom
feat/browser-groups

Conversation

@sunib

@sunib sunib commented Oct 6, 2026

Copy link
Copy Markdown
Owner

Stacked on #27. Merge that first; GitHub then retargets this PR to main.

A Room can add two groups to everyone who joins, named after the browser and platform they joined with. Nobody is asked anything.

spec:
  browserGroups:
    prefix: "demo:"     # demo:browser-safari, demo:platform-ios
Group Names
<prefix>browser-… safari, chrome, firefox, edge, samsung, opera, other
<prefix>platform-… ios, android, macos, windows, chromeos, linux, other

How

  • At enrollment, Room Pass reads the User-Agent header and picks a name from each fixed list. The order of the checks matters: almost every browser claims Safari, every Chromium browser claims Chrome, iOS says it is "like Mac OS X", and Android says Linux.
  • No part of the header ever becomes part of a group, so a forged User-Agent gains nothing but another name from the list.
  • The groups are stored in the Participant's spec.groups, next to the answer from feat: a Room can ask one question at the door, and the answer becomes a group #27, and sent to Dex the same way.
  • The join page says what will be shared before anyone presses Continue: "…and your browser, Safari on iOS."
  • The prefix must start with demo:. Group names that fail the pattern, such as those from a prefix that escaped the schema, are dropped.

Why not a claim or the phone brand

  • Not a claim: Dex's authproxy connector passes on only a user ID, name, email and groups, so a custom claim would need a different connector.
  • Not the brand: since Chrome froze the User-Agent, Android phones report model K. Recovering the brand would need Client Hints plus a table of model numbers. platform-ios is the closest there is to "Apple".
  • No library: User-Agent parsers like uap-go mostly exist to identify device models, which is the part the header no longer carries. A fixed list of names takes about 30 lines and can't be pushed outside it.

Why this is a feat:

A Room without browserGroups reads nothing from the User-Agent, and its page and groups stay byte-for-byte the same; a test checks this. The new field on the Room is optional.

Test plan

  • task lint, task test, task verify-generate, task integration, which refuses system: and comma prefixes
  • A unit table of 20 real and hostile User-Agents
  • task e2e-up && task browser: 9/9. Chromium sends an iPhone Safari User-Agent and reads demo:browser-safari and demo:platform-ios from the real Dex token.
  • task e2e
  • task test-network: not run locally; this change doesn't touch the network policy

🤖 Generated with Claude Code

@sunib
sunib added this pull request to stack #29 October 6, 2026 12:26
Base automatically changed from feat/room-question to main October 6, 2026 12:26
…th in their groups

spec.browserGroups is optional: a demo: prefix. Everyone who joins gets
<prefix>browser-<name> and <prefix>platform-<name>, such as
demo:browser-safari and demo:platform-ios, kept on the Participant beside the
answer to the Room's question and sent to Dex the same way.

The names come from fixed lists: safari, chrome, firefox, edge, samsung,
opera, other; ios, android, macos, windows, chromeos, linux, other. The
User-Agent only selects one, so a forged header gains nothing but another
name from the list. The join page says what will be shared before anyone
presses Continue.

There is no phone brand: Chrome on Android reports every phone as model "K"
since the User-Agent was frozen.

A Room without browserGroups reads nothing from the User-Agent, and its page
and groups are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sunib
sunib force-pushed the feat/browser-groups branch from 242a8d4 to 6cec7b2 Compare October 6, 2026 12:27
@sunib
sunib merged commit 622d87c into main Oct 6, 2026
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