fix(web): stop boot from consuming the /share route's claim params - #452
Merged
Conversation
added 2 commits
July 10, 2026 12:02
The boot resolver treated ?hub= as a hub-pin request and scrubbed stray payload/handle params — but it runs before the router mounts, and share links carry link+hub (+#s= secret) as the /share route's claim INPUT. Boot stripped them first, so every web-fallback claim died with 'Missing link, handle, or payload in share link' (and the issuing hub got persisted as the user's pinned hub). Present since the flow landed; masked until now because the Electron deep link usually won the race. - boot: leave the /share route's URL untouched (path- and hash-routed); keep the ?hub= pin and payload/handle scrub on all other routes - share route sanitizer: drop a bare #s= fragment instead of keeping it — it retained the secret in the address bar on path-routed deployments while discarding the search params - extract resolveHubSessionFromLocation into boot/hub-session.ts so it's unit-testable without the SQLite worker import graph Verified in-browser against hub.xnet.fyi: interstitial-shaped URL now claims and lands on the shared doc. Signed-off-by: xNet Test <test@xnet.dev>
Signed-off-by: xNet Test <test@xnet.dev>
Contributor
|
Preview removed for PR #452. |
Contributor
🖼️ UI changes in this PRWarning 1 changed UI file(s) map to no capture target. Unmapped files
|
crs48
added a commit
that referenced
this pull request
Jul 10, 2026
Extends URL share-links to two more node kinds, reusing the exact pipeline pages/databases already use (and that #448/#452 hardened this week). ## Channels - Hub accepts `docType: 'channel'` (`SHARE_DOC_TYPES`). - Share entry points: a **Share button in the channel header** (`ChannelView`) and a **Share action in the ChatsPanel** channel context-menu/kebab. - A claimed channel routes to `/channel/$channelId` (both `docRouteFor` and the `/share` web-fallback map). - **Authorization:** `ChatMessage@` is added to the comment-schema allowlist, so a **comment-role** channel share means "can post messages, can't edit the channel" — `write` still required to edit the channel node itself. `Channel@` is deliberately *not* in the allowlist. ## Workspaces - Per-row **Share button in the workspace (bench) switcher**, alongside the pre-existing `Workspace: Share…` command. Preset workspaces aren't shareable (guarded by `isPresetWorkspaceId`). - `EditorHeader` maps `channel` tabs to the `channel` docType too, so a focused channel shows Share in the editor chrome. ## Verification - **Channel flow verified end-to-end in a real browser** against a live hub: created a channel → **Share → New link** minted a hub link → a second identity claimed it via the API (200, `docType: channel`, role granted) → the in-browser `/share` claim routed to `/channel/$channelId`. - Hub tests assert **all eight** `ShareDocType`s round-trip create→claim, and that a comment grantee may post `ChatMessage` but not `Channel`/arbitrary schemas. - Web unit tests cover `docRouteFor('channel')`; typecheck + lint clean across hub and web. - The workspace-switcher Share button reuses the identical `ShareDialog`/`setShareFor` path the existing `workspace.share` command already ships (typecheck-verified). Also fixes a stale source-guard test that still pointed at `use-boot-sequence.ts` after #452 moved the URL-stripping logic to `boot/hub-session.ts`. No publishable package changed (hub + apps/web are private) → no changeset; changelog fragment included. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Opening a share link in the web app died with 'Missing link, handle, or payload in share link': the boot resolver (
resolveHubSessionFromLocation) consumed?hub=as a hub-pin request and scrubbedpayload/handle— before the router ever mounted. Share links carrylink+hub+#s=as the /share route's claim input, so the route parsed an already-stripped URL. Worse, the issuing hub got persisted as the user's pinned hub. Present since the cross-surface claim flow landed (masked when the Electron deep link won the race); surfaced while validating the hub.xnet.fyi recovery today.?hub=pin and stray payload/handle scrub still apply on all other routes.#s=secret fragment on path-routed deployments while discarding the search — now it drops it (that's the one thing it exists to remove).resolveHubSessionFromLocationextracted toboot/hub-session.ts(unit-testable without the SQLite worker graph) + tests for all four cases.Verified in a real browser against the production hub: an interstitial-shaped URL now claims and navigates to the shared doc; address bar ends clean at
/share.🤖 Generated with Claude Code