Skip to content

fix: open conference deep links in the video call window - #3412

Merged
jeanfbrito merged 5 commits into
hotfix/4.15.4from
fix/conference-deeplink-call-window
Jul 14, 2026
Merged

fix: open conference deep links in the video call window#3412
jeanfbrito merged 5 commits into
hotfix/4.15.4from
fix/conference-deeplink-call-window

Conversation

@jeanfbrito

@jeanfbrito jeanfbrito commented Jul 13, 2026

Copy link
Copy Markdown
Member

What changed

Conference deep links (rocketchat://conference?...&path=conference/<id>?callUrl=...&callProvider=...) opened the call inside the server webview, replacing the workspace UI. performConference navigated the webview with loadURL, so the conference page loaded over the whole workspace.

They now open in the standalone video call window — the same window used when a conference is joined from inside the app.

How

  • performConference reads callUrl/callProvider from the deep link and sends conference/open-call-requested to the server webview instead of navigating it. Links without callUrl keep the previous loadURL fallback, so nothing regresses for older-style links.
  • A new preload listener (listenToConferenceCallRequests) forwards the request to the existing openInternalVideoChatWindow. It registers early and buffers a single request until the renderer store is ready (flushPendingConferenceCallRequest), so a deep link that cold-launches the app isn't dropped before the listener exists.
  • Pexip credential enrichment is applied only when the callUrl origin matches the workspace origin, so a crafted deep link can't cause the workspace session token to be handed to an unrelated URL loaded in the call window.

Testing

Requires the build-artifacts installer build.

1. Fix path — opens in call window (main case):
Use a real Pexip conference deep link from the QA workspace — one whose path carries a callUrl and callProvider=Pexip, i.e. of the shape:

https://go.rocket.chat/conference?host=<qa-workspace>&path=conference%2F<id>%3FcallUrl%3D<encoded-pexip-call-url>%26callProvider%3DPexip

Expected: the call opens in the separate video call window; the workspace stays visible behind it (not replaced).

2. Fallback path — no callUrl:

https://go.rocket.chat/conference?host=pr-40764.qa.rocket.chat&path=conference%2F80879108%3Fscheduled=true

Expected: previous behavior preserved (navigates the webview to the conference route).

3. Security check: a conference deep link whose callUrl points to a host different from the workspace origin must not carry Pexip credentials into the call window.

Automated checks

  • tsc --noEmit: 0 errors
  • yarn test (deepLinks/main.spec.ts + servers/preload/tests/internalVideoChatWindow.spec.ts): 42 passed
  • eslint: clean

Follow-up (webapp, out of scope here)

The web client's /conference/:id route ignores its :id param and trusts the deep-link callUrl outright. A server-trusted videoConference.joinCall(callId) endpoint already exists; wiring ConferencePage to resolve the URL from :id via that endpoint would retire deep-link callUrl trust entirely.

Summary by CodeRabbit

  • New Features
    • Enhanced rocketchat://conference routing to open calls directly when a callUrl is provided.
    • Added cold-start handling for conference call requests by buffering until the app is ready.
  • Bug Fixes
    • Deep links without callUrl no longer attempt in-view navigation; they use the standard call-opening flow instead.
    • Provider options are only enriched for same-origin call links.
  • Tests
    • Added Jest coverage for conference deep-link routing and buffered flush behavior.
  • Chores
    • Updated CI workflow triggers to include hotfix/** branches.
    • Bumped app version to 4.15.4.

Conference deep links (rocketchat://conference?...&path=conference/<id>?callUrl=...&callProvider=...)
opened the call inside the server webview because performConference navigated
the webview with loadURL, replacing the workspace UI underneath the call.

Route the request to the standalone video call window instead — the same path
used when a conference is joined from inside the app:

- performConference reads callUrl/callProvider from the deep link and sends
  'conference/open-call-requested' to the server webview (no navigation).
  Links without callUrl keep the previous loadURL fallback.
- A new preload listener (listenToConferenceCallRequests) forwards the request
  to the existing openInternalVideoChatWindow. The listener is registered early
  and buffers a single request until the renderer store is ready
  (flushPendingConferenceCallRequest), so a deep link that cold-launches the app
  is not dropped before the listener exists.
- Pexip credential enrichment is applied only when the callUrl origin matches the
  workspace origin, so a crafted deep link cannot cause the workspace session
  token to be handed to an unrelated URL loaded in the call window.
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Conference deep links now dispatch call requests through IPC when needed, with preload buffering during cold start and same-origin provider handling. Pull request workflows also include hotfix/** branches, and the package version increases to 4.15.4.

Changes

Conference call deep-link routing

Layer / File(s) Summary
Conference deep-link dispatch
src/deepLinks/main.ts, src/deepLinks/main.spec.ts
Conference links dispatch conference/open-call-requested when callUrl is absent and load URLs containing callUrl; both paths are tested.
Preload call request processing
src/servers/preload/internalVideoChatWindow.ts, src/servers/preload/__tests__/internalVideoChatWindow.spec.ts
Preload validates and buffers requests before readiness, processes them after flushing, and applies provider enrichment only for same-origin URLs.
Preload startup wiring
src/preload.ts
The conference-call listener registers during module load, and pending requests flush when the desktop API is ready.

Workflow and release metadata

Layer / File(s) Summary
Hotfix workflow filters
.github/workflows/pull-request-build.yml, .github/workflows/validate-pr.yml
Build and validation workflows trigger for pull requests targeting hotfix/** branches.
Package version update
package.json
The application version changes from 4.15.3 to 4.15.4.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant processDeepLink
  participant webContents
  participant preload
  participant openInternalVideoChatWindow
  User->>processDeepLink: open conference deep link
  processDeepLink->>webContents: send conference/open-call-requested with callUrl
  webContents->>preload: deliver callUrl and provider
  preload->>openInternalVideoChatWindow: process call URL and provider options
Loading

Suggested labels: type: bug

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: conference deep links now open in the video call window.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • PR-40764: Request failed with status code 401

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Replace a real customer lab hostname in the conference deep-link test
data with a generic example host.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/servers/preload/internalVideoChatWindow.ts`:
- Around line 38-59: Update processConferenceCallRequest so the catch block for
malformed callUrl returns immediately, preventing the invalid URL from reaching
openInternalVideoChatWindow; preserve the existing same-origin provider
enrichment for valid URLs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 23e30138-2bcb-4212-87c8-b5085c18119f

📥 Commits

Reviewing files that changed from the base of the PR and between 885ad12 and 0ddcdb3.

📒 Files selected for processing (5)
  • src/deepLinks/main.spec.ts
  • src/deepLinks/main.ts
  • src/preload.ts
  • src/servers/preload/__tests__/internalVideoChatWindow.spec.ts
  • src/servers/preload/internalVideoChatWindow.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript for new code unless explicitly told otherwise.
Use Fuselage components from @rocket.chat/fuselage for UI work unless the design requires something Fuselage does not provide.
Check Theme.d.ts for valid color tokens before using Fuselage colors.
Verify library props, APIs, and tokens against official docs or local .d.ts files instead of assuming.
Use React functional components with hooks.
Redux actions follow FSA shape.
Use camelCase for file names and PascalCase for components.
Prefer clear names over unnecessary comments.
Prefer editing existing files over creating new abstractions unless the new abstraction removes real complexity or matches an existing pattern.

**/*.{ts,tsx}: Use TypeScript for all new code unless explicitly told otherwise.
Use Fuselage components for all UI work; create custom components only when Fuselage lacks the required functionality.
Import Fuselage components from @rocket.chat/fuselage.
Use only valid color tokens documented by Theme.d.ts.
Use optional chaining with fallbacks for platform-specific APIs, especially Linux-only process APIs such as process.getuid(), getgid(), geteuid(), and getegid().
Use TypeScript strict mode.
Redux actions must follow the Flux Standard Action pattern.
Use camelCase for file names and PascalCase for component names.
Avoid unnecessary comments; prefer self-documenting code through clear naming.
Do not commit or push without explicit user permission.
Verify library APIs, props, tokens, and types against official documentation and .d.ts files instead of assuming they are valid.

Files:

  • src/servers/preload/__tests__/internalVideoChatWindow.spec.ts
  • src/deepLinks/main.ts
  • src/preload.ts
  • src/deepLinks/main.spec.ts
  • src/servers/preload/internalVideoChatWindow.ts
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Renderer specs use *.spec.ts / *.spec.tsx.

Files:

  • src/servers/preload/__tests__/internalVideoChatWindow.spec.ts
  • src/deepLinks/main.spec.ts
**/*.spec.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use *.spec.ts for renderer process tests.

Files:

  • src/servers/preload/__tests__/internalVideoChatWindow.spec.ts
  • src/deepLinks/main.spec.ts
src/**/*.{spec.ts,spec.tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Renderer test files should be placed in nested module paths such as src/<module>/<subdir>/*.spec.ts(x) so Jest discovers them.

Files:

  • src/servers/preload/__tests__/internalVideoChatWindow.spec.ts
  • src/deepLinks/main.spec.ts
🔇 Additional comments (5)
src/deepLinks/main.ts (1)

213-233: LGTM!

src/deepLinks/main.spec.ts (1)

651-726: LGTM!

src/servers/preload/internalVideoChatWindow.ts (1)

64-70: LGTM!

Also applies to: 72-108

src/servers/preload/__tests__/internalVideoChatWindow.spec.ts (1)

1-134: LGTM!

src/preload.ts (1)

9-12: LGTM!

Also applies to: 38-42, 80-80

Comment thread src/servers/preload/internalVideoChatWindow.ts
The PR build and validate workflows only triggered for PRs targeting
master or dev, so hotfix PRs got no CI or build artifacts. Add
hotfix/** to the pull_request branch filters so any hotfix line gets
the same CI and build-artifacts coverage.
@jeanfbrito
jeanfbrito force-pushed the fix/conference-deeplink-call-window branch from 3c0dc90 to 4759fde Compare July 13, 2026 21:45
@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown

macOS installer download

Conference deep links come in two shapes. Links carrying an explicit
callUrl already work: the workspace webview loads the conference page,
which forwards the callUrl to the desktop video call window. Those are
left untouched.

Links without a callUrl (conference/<id>) instead loaded the conference
page over the workspace webview, trapping the user on it with no way
back. Route those to the standalone video call window so closing it
returns the user to an untouched workspace.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/deepLinks/main.ts`:
- Around line 222-237: The conference deep-link routing contract is reversed. In
src/deepLinks/main.ts lines 222-237, dispatch conference/open-call-requested
when url.searchParams.has('callUrl'), and use webContents.loadURL as the
fallback when callUrl is absent. In src/deepLinks/main.spec.ts lines 679-719,
invert the test names and assertions to verify this routing behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e20c4645-84f1-439d-9966-1891e1e2e57c

📥 Commits

Reviewing files that changed from the base of the PR and between 4759fde and 66b94ef.

📒 Files selected for processing (3)
  • src/deepLinks/main.spec.ts
  • src/deepLinks/main.ts
  • src/servers/preload/__tests__/internalVideoChatWindow.spec.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/servers/preload/tests/internalVideoChatWindow.spec.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (6)
  • GitHub Check: check (windows-latest)
  • GitHub Check: check (ubuntu-latest)
  • GitHub Check: build (macos-latest, mac)
  • GitHub Check: check (macos-latest)
  • GitHub Check: build (ubuntu-latest, linux)
  • GitHub Check: build (windows-latest, windows)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript for new code unless explicitly told otherwise.
Use Fuselage components from @rocket.chat/fuselage for UI work unless the design requires something Fuselage does not provide.
Check Theme.d.ts for valid color tokens before using Fuselage colors.
Verify library props, APIs, and tokens against official docs or local .d.ts files instead of assuming.
Use React functional components with hooks.
Redux actions follow FSA shape.
Use camelCase for file names and PascalCase for components.
Prefer clear names over unnecessary comments.
Prefer editing existing files over creating new abstractions unless the new abstraction removes real complexity or matches an existing pattern.

**/*.{ts,tsx}: Use TypeScript for all new code unless explicitly told otherwise.
Use Fuselage components for all UI work; create custom components only when Fuselage lacks the required functionality.
Import Fuselage components from @rocket.chat/fuselage.
Use only valid color tokens documented by Theme.d.ts.
Use optional chaining with fallbacks for platform-specific APIs, especially Linux-only process APIs such as process.getuid(), getgid(), geteuid(), and getegid().
Use TypeScript strict mode.
Redux actions must follow the Flux Standard Action pattern.
Use camelCase for file names and PascalCase for component names.
Avoid unnecessary comments; prefer self-documenting code through clear naming.
Do not commit or push without explicit user permission.
Verify library APIs, props, tokens, and types against official documentation and .d.ts files instead of assuming they are valid.

Files:

  • src/deepLinks/main.spec.ts
  • src/deepLinks/main.ts
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Renderer specs use *.spec.ts / *.spec.tsx.

Files:

  • src/deepLinks/main.spec.ts
**/*.spec.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use *.spec.ts for renderer process tests.

Files:

  • src/deepLinks/main.spec.ts
src/**/*.{spec.ts,spec.tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Renderer test files should be placed in nested module paths such as src/<module>/<subdir>/*.spec.ts(x) so Jest discovers them.

Files:

  • src/deepLinks/main.spec.ts

Comment thread src/deepLinks/main.ts
@jeanfbrito
jeanfbrito changed the base branch from hotfix/4.15.3 to hotfix/4.15.4 July 14, 2026 01:07
@jeanfbrito
jeanfbrito merged commit 1c1d426 into hotfix/4.15.4 Jul 14, 2026
10 of 11 checks passed
@jeanfbrito
jeanfbrito deleted the fix/conference-deeplink-call-window branch July 14, 2026 01:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant