Skip to content

fix(collab): publish presence for users without a display name - #631

Open
Mineorey wants to merge 1 commit into
CoreBunch:mainfrom
Mineorey:fix/presence-without-display-name
Open

Mineorey wants to merge 1 commit into
CoreBunch:mainfrom
Mineorey:fix/presence-without-display-name

Conversation

@Mineorey

Copy link
Copy Markdown

Summary

What. Adds userDisplayLabel(user) in src/core/users/displayName.ts. It returns the trimmed display name, or the email address when there is none. It is now used in these places:

  • the collab relay's session identity (server/collab/socket.ts)
  • the presence that CanvasRoot publishes
  • the account menu, the profile tab and the dashboard activity widget
  • the users table and audit labels
  • UserAvatar (alt text and initial)

displayUserName (users utils) and the inline displayName.trim() || email fallbacks are removed.

Why. "Your name" is optional at setup and in the profile. usePublishEditorPresence publishes nothing when the name is empty, and the relay built its session identity from the raw display name. As a result, a user without a display name had no presence at all: peers saw no cursor and no selection ring, and the "someone else is editing" guards never fired for that user. The relay only forwards presence whose identity matches the session, so client and server have to use the same label. Both now use userDisplayLabel.

Impact. Collaborators now see the email address of a user who has no display name, in presence and in the existing name displays. The anti-spoofing check is unchanged: it still compares the full identity. No schema or data changes.

Note: server/handlers/cms/dashboard/activity.ts has an unrelated module-local helper with the same name (nullable row columns). I left it alone; it could be folded in later if that's wanted.

Verification

Run in the project's Bun dev container on this branch:

  • bun run build: passes
  • bun test --timeout 60000: 7122 pass, 2 fail. Both failures are environment-related and also fail on main in the same container: the circular-dependency check hits its internal 15 s timeout, and the pixel-art-icons .gitignore freshness check needs git, which the container doesn't have.
  • bun run lint: clean
  • Tests:
    • collabSocket.test.ts (new case: a user without a display name gets their email as the presence name)
    • collabRelayIntegration.test.ts (expected identities now use userDisplayLabel)
    • new src/__tests__/users/displayName.test.ts
  • Docker/deployment check: not relevant

Checklist

  • Tests cover behavior changes.
  • Docs were updated (docs/features/site-shell.md: session identity, and that collaborators see the email).
  • No compatibility shim was added for old pre-release behavior.
  • No secrets, local databases, uploads, or generated artifacts are included.

For transparancy: Generated with Claude

"Your name" is optional at setup and in the profile, but the editor only
published presence when the user had a display name, and the relay derived
the session identity from the raw display name. A user without one
published no presence at all: peers saw no cursor or selection ring, and
the "someone else is editing" guards never fired for them.

userDisplayLabel (src/core/users/displayName.ts) returns the trimmed
display name, else the email address. The relay's session identity and the
editor's published presence both use it, so they keep matching the
anti-spoofing check; collaborators now see the email of a user without a
display name. The account menu, profile tab, activity widget, users table,
audit labels and UserAvatar use the same helper, replacing displayUserName
and the inline fallbacks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Mineorey
Mineorey marked this pull request as ready for review October 12, 2026 15:51

This branch has not been deployed

No deployments
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