Skip to content

fix: honor uniqueId-scoped support exceptions on server-signed path - #3404

Merged
jeanfbrito merged 1 commit into
masterfrom
fix/supported-versions-exception-uniqueid-scope
Jul 10, 2026
Merged

fix: honor uniqueId-scoped support exceptions on server-signed path#3404
jeanfbrito merged 1 commit into
masterfrom
fix/supported-versions-exception-uniqueid-scope

Conversation

@jeanfbrito

@jeanfbrito jeanfbrito commented Jul 9, 2026

Copy link
Copy Markdown
Member

What

Workspaces with a uniqueId-scoped support exception (issued via Rocket.Chat Cloud) were shown the "Unsupported" screen on desktop 4.15.0–4.15.2 even though the exception was valid and present in the server's signed supportedVersions payload. Reported through a customer support escalation (workspace running 7.13.9 with a valid exception; mobile unaffected).

Why

The exception scope check added in #3323 requires exceptions.uniqueId === server.uniqueID. That check did not cover the common deployment path:

  • server.uniqueID is only written by getUniqueId() inside updateSupportedVersionsData, but the server-signed validation path returns before that call — so the local uniqueID is never populated for servers whose /api/info succeeds.
  • The intended fallback, serverInfoResult.uniqueId, never applies: /api/info does not include a uniqueId field (verified against servers running 7.13 and 8.7). The existing test fixtures included it, which is why the suite stayed green.

With the local uniqueID undefined, every uniqueId-scoped exception was disqualified and the version fell through to the supported-versions list, which no longer contains the excepted version.

How

  • New withExceptionScopeUniqueId helper on the server-signed path: when the payload carries a uniqueId-scoped exceptions block and the local uniqueID is missing or different, resolve it from the server (settings.public?_id=uniqueID), dispatch WEBVIEW_SERVER_UNIQUE_ID_UPDATED so it persists for subsequent runs (including offline cache validation), and validate against the resolved identity.
  • Fail-secure: if the fetch fails or the fetched value does not match exceptions.uniqueId, the exception remains rejected. The cross-tenant scope check semantics from Fix "Unsupported Version" Block on Valid Servers After App Update #3323 are unchanged.
  • exceptions.domain is now compared case-insensitively (DNS names are case-insensitive per RFC 4343); URL.hostname is already lowercased.
  • No extra network request in steady state: the uniqueID fetch only runs when the payload is uniqueId-scoped and the persisted value does not already match.

Tests

  • 5 new specs in main.main.spec.ts: exception honored when /api/info omits uniqueId; stale persisted uniqueID re-resolved; mismatched uniqueID still rejected; no extra fetch when persisted value matches; domain case-insensitive matching.
  • yarn jest src/servers/supportedVersions/main.main.spec.ts: 82/82 pass. tsc --noEmit and yarn lint clean.

Summary by CodeRabbit

  • Bug Fixes
    • Improved server version checks to better handle exception rules tied to a unique server identity.
    • If the stored server identity is outdated, the app now refreshes it before deciding whether the server is supported.
    • Exception matching is now case-insensitive for server domains, reducing false negatives.

The exception scope check introduced in #3323 requires
exceptions.uniqueId to equal server.uniqueID, but the server-signed
validation path returns before getUniqueId() ever runs and /api/info
does not include a uniqueId field, so the local uniqueID is missing on
that path and uniqueId-scoped exceptions were always disqualified.

Resolve the workspace uniqueID from the server before validating when
the payload carries a uniqueId-scoped exceptions block, persist it via
WEBVIEW_SERVER_UNIQUE_ID_UPDATED so subsequent runs (including offline
cache validation) keep working, and keep rejecting when the fetched
value does not match. Also compare exceptions.domain case-insensitively
(DNS names are case-insensitive per RFC 4343).
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR fixes exception-scope validation for server supported-versions checks. It makes exceptions.domain matching case-insensitive and introduces a withExceptionScopeUniqueId helper that fetches and persists a fresh uniqueId before validating server-signed exceptions scoped to a tenant uniqueId. Tests cover both behaviors.

Changes

Exception scope validation fix

Layer / File(s) Summary
Case-insensitive exception domain matching
src/servers/supportedVersions/main.ts, src/servers/supportedVersions/main.main.spec.ts
isServerVersionSupported lowercases exceptions.domain before comparing to hostname; a new test confirms matching succeeds with differing letter case.
Exception-scoped uniqueId resolution and wiring
src/servers/supportedVersions/main.ts, src/servers/supportedVersions/main.main.spec.ts
New withExceptionScopeUniqueId helper fetches a fresh uniqueId and dispatches WEBVIEW_SERVER_UNIQUE_ID_UPDATED when it mismatches serverView.uniqueID; updateSupportedVersionsData uses the resolved server view for server-signed validation instead of the prior possibly-stale view; comments updated; four new test scenarios cover fetch-before-validate, re-fetch on stale value, rejection on scope mismatch, and skip-fetch when already matching.

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

Sequence Diagram(s)

sequenceDiagram
  participant Main as updateSupportedVersionsData
  participant Helper as withExceptionScopeUniqueId
  participant Server as Server API
  participant Store as Dispatch/Store
  participant Validator as isServerVersionSupported

  Main->>Helper: serverView, exceptions.uniqueId
  alt uniqueId mismatch
    Helper->>Server: fetch fresh uniqueId
    Server-->>Helper: uniqueId
    Helper->>Store: dispatch WEBVIEW_SERVER_UNIQUE_ID_UPDATED
    Helper-->>Main: serverView with fresh uniqueID
  else uniqueId matches
    Helper-->>Main: original serverView
  end
  Main->>Validator: validate serverForValidation
  Validator-->>Main: supported verdict
  Main->>Store: dispatch WEBVIEW_SERVER_IS_SUPPORTED_VERSION
Loading

Possibly related PRs

  • RocketChat/Rocket.Chat.Electron#3323: Directly builds on the same isServerVersionSupported/updateSupportedVersionsData exception identity and uniqueId logic introduced in that PR.

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 summarizes the main change: honoring uniqueId-scoped support exceptions on the server-signed path.

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.

@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.

🧹 Nitpick comments (1)
src/servers/supportedVersions/main.ts (1)

594-604: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Minor: possible duplicate getUniqueId fetch on the server-signed decode-error fallback.

When withExceptionScopeUniqueId triggers a fetch (uniqueId-scoped exception with a stale/missing local id) but the surrounding try later throws (e.g. a subsequent decode/validation error clears serverEncoded), control falls through to the general path at Line 631, which calls getUniqueId again for the same server. Not incorrect, just a redundant network round-trip on that edge path. Consider caching the resolved id to reuse downstream.

🤖 Prompt for 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.

In `@src/servers/supportedVersions/main.ts` around lines 594 - 604, Avoid the
redundant second unique-id lookup on the server-signed decode-error fallback
path. In the flow around withExceptionScopeUniqueId, serverForValidation, and
the later general retry/validation handling, cache the resolved uniqueId from
the first fetch and reuse it if the same server reaches the fallback path again.
Update the relevant server version validation logic so getUniqueId is only
called once per server in this edge case.
🤖 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.

Nitpick comments:
In `@src/servers/supportedVersions/main.ts`:
- Around line 594-604: Avoid the redundant second unique-id lookup on the
server-signed decode-error fallback path. In the flow around
withExceptionScopeUniqueId, serverForValidation, and the later general
retry/validation handling, cache the resolved uniqueId from the first fetch and
reuse it if the same server reaches the fallback path again. Update the relevant
server version validation logic so getUniqueId is only called once per server in
this edge case.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f6f50e92-93bd-48cb-bb3c-05d073033165

📥 Commits

Reviewing files that changed from the base of the PR and between 60d9a60 and 615d79d.

📒 Files selected for processing (2)
  • src/servers/supportedVersions/main.main.spec.ts
  • src/servers/supportedVersions/main.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (4)
  • GitHub Check: build (ubuntu-latest, linux)
  • GitHub Check: build (windows-latest, windows)
  • GitHub Check: check (ubuntu-latest)
  • GitHub Check: check (windows-latest)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript for all new code unless explicitly told otherwise.
Use Fuselage components for all UI work; only create custom components when Fuselage does not provide what is needed.
Import UI components from @rocket.chat/fuselage.
Check Theme.d.ts for valid color tokens before using Fuselage theme colors.
Use optional chaining with fallbacks for platform-specific APIs, especially Linux-only process APIs like process.getuid(), process.getgid(), process.geteuid(), and process.getegid().
Only mock platform-specific APIs when defensive coding is not possible.
Use TypeScript strict mode.
Use React functional components with hooks.
Redux actions must follow the Flux Standard Action (FSA) pattern.
Use camelCase for file names and PascalCase for components.

**/*.{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.

Files:

  • src/servers/supportedVersions/main.ts
  • src/servers/supportedVersions/main.main.spec.ts
**/*.spec.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use *.spec.ts for renderer process tests.

Files:

  • src/servers/supportedVersions/main.main.spec.ts
**/*.main.spec.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use *.main.spec.ts for main process tests.

Main-process specs use *.main.spec.ts.

Files:

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

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

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

📄 CodeRabbit inference engine (AGENTS.md)

Renderer specs must live in a Jest-matched nested path, such as src/<module>/<subdir>/*.spec.ts(x); flat src/<module>/*.spec.ts files are not discovered by the current testMatch.

Files:

  • src/servers/supportedVersions/main.main.spec.ts
🔇 Additional comments (4)
src/servers/supportedVersions/main.ts (2)

356-362: LGTM!


506-528: LGTM!

src/servers/supportedVersions/main.main.spec.ts (2)

374-539: LGTM!


1007-1041: LGTM!

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

macOS installer download

@jeanfbrito
jeanfbrito merged commit fcc126f into master Jul 10, 2026
11 checks passed
@jeanfbrito
jeanfbrito deleted the fix/supported-versions-exception-uniqueid-scope branch July 10, 2026 12:51
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