Skip to content

Fix: Prevent GUI crash on second launch in Desktop App#3242

Open
Ram-sah19 wants to merge 116 commits intoRocketChat:developfrom
Ram-sah19:fix-desktop-gui-crash
Open

Fix: Prevent GUI crash on second launch in Desktop App#3242
Ram-sah19 wants to merge 116 commits intoRocketChat:developfrom
Ram-sah19:fix-desktop-gui-crash

Conversation

@Ram-sah19
Copy link

@Ram-sah19 Ram-sah19 commented Mar 9, 2026

Description

This PR fixes an issue where the Rocket.Chat Desktop application crashes on the second launch with the error:

"Application Error - The application GUI just crashed"

The application works correctly on the first launch, but crashes when started again. Reloading the app using Ctrl + Shift + R temporarily resolves the problem.

Root Cause

The renderer process fails during initialization on subsequent launches due to improper handling of the window startup state in the desktop client.

Solution

Updated the window initialization logic in rootWindow.ts to ensure the renderer loads correctly and prevents the GUI crash on startup.

Testing

Tested on:

  • OS: Fedora 43
  • Rocket.Chat Desktop App Version: 4.12.0

Steps to verify:

  1. Launch the Rocket.Chat Desktop application
  2. Close the application
  3. Launch the application again

Result:

  • The application loads successfully without any GUI crash.

Additional testing:

  • Repeated launch test (10 times)
  • Manual reload using Ctrl + Shift + R

All tests passed successfully.

Related Issue

Fixes #ISSUE_NUMBER Fixes #3589

Summary by CodeRabbit

  • New Features

    • Open external links in the default browser; automatic renderer crash recovery.
  • Bug Fixes

    • Fixed YAML/key formatting and a missing CSS semicolon.
  • Documentation

    • Updated release, Linux display, video call, window management docs and templates (issues/PRs/contributing).
  • Localization

    • Updated Norwegian and Polish translations, removed Swedish file, and applied minor i18n fixes.
  • Chores

    • Repository-wide formatting, whitespace and config cleanups.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 9, 2026

Important

Review skipped

Too many files!

This PR contains 218 files, which is 68 over the limit of 150.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5c5da2ae-7cae-4938-9fce-6dafebcfc604

📥 Commits

Reviewing files that changed from the base of the PR and between 3af92de and c17e03b.

⛔ Files ignored due to path filters (3)
  • .yarn/patches/@ewsjs-xhr-npm-2.0.2-77506b0a6c.patch is excluded by !**/.yarn/**
  • workspaces/desktop-release-action/dist/index.js is excluded by !**/dist/**
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (218)
  • .cursor/worktrees.json
  • .eslintignore
  • .eslintrc.json
  • .github/workflows/build-release.yml
  • .github/workflows/powershell-lint.yml
  • .github/workflows/pull-request-build.yml
  • .github/workflows/validate-pr.yml
  • .gitignore
  • AGENTS.md
  • CLAUDE.md
  • LICENSE
  • README.md
  • alpha-app-update.yml
  • beta-app-update.yml
  • build/afterPack.js
  • build/entitlements.mac.plist
  • build/entitlements.mas.inherit.plist
  • build/entitlements.mas.plist
  • build/install-kms-cng-provider.ps1
  • build/installers/.gitkeep
  • build/linux/wrapper.sh
  • build/notarize.js
  • build/winSignKms.js
  • docs/alpha-release-process.md
  • docs/linux-display-server.md
  • docs/linux-wayland-bug-postmortem.md
  • docs/pre-release-process.md
  • docs/qa-alpha-update-testing.md
  • docs/supported-versions-flow.md
  • docs/video-call-screen-sharing.md
  • docs/video-call-window-flow.md
  • docs/video-call-window-management.md
  • docs/video-call-window-wgc-limitations.md
  • electron-builder.json
  • package.json
  • rollup.config.mjs
  • scripts/README.md
  • scripts/install-volta.sh
  • scripts/linux-test-appimage.sh
  • scripts/linux-test-deb.sh
  • scripts/release-tag.ts
  • src/app/PersistableValues.ts
  • src/app/actions.ts
  • src/app/main/app.main.spec.ts
  • src/app/main/app.ts
  • src/app/main/data.spec.ts
  • src/app/main/data.ts
  • src/app/reducers/screenCaptureFallbackForced.ts
  • src/app/selectors.ts
  • src/documentViewer/ipc.ts
  • src/downloads/actions.spec.ts
  • src/downloads/actions.ts
  • src/downloads/integration.spec.ts
  • src/downloads/main.spec.ts
  • src/downloads/main.ts
  • src/downloads/main/download-persistence.spec.ts
  • src/downloads/main/setup.ts
  • src/downloads/notifications.spec.ts
  • src/downloads/reducers/downloads.spec.ts
  • src/downloads/reducers/downloads.ts
  • src/errors.ts
  • src/i18n/ar.i18n.json
  • src/i18n/de-DE.i18n.json
  • src/i18n/en.i18n.json
  • src/i18n/es.i18n.json
  • src/i18n/fi.i18n.json
  • src/i18n/fr.i18n.json
  • src/i18n/hu.i18n.json
  • src/i18n/it-IT.i18n.json
  • src/i18n/ja.i18n.json
  • src/i18n/nb-NO.i18n.json
  • src/i18n/nn.i18n.json
  • src/i18n/no.i18n.json
  • src/i18n/pl.i18n.json
  • src/i18n/pt-BR.i18n.json
  • src/i18n/resources.ts
  • src/i18n/ru.i18n.json
  • src/i18n/se.i18n.json
  • src/i18n/sv.i18n.json
  • src/i18n/tr-TR.i18n.json
  • src/i18n/uk-UA.i18n.json
  • src/i18n/zh-CN.i18n.json
  • src/i18n/zh-TW.i18n.json
  • src/i18n/zh.i18n.json
  • src/injected.ts
  • src/ipc/channels.ts
  • src/ipc/renderer.ts
  • src/jitsi/ipc.ts
  • src/logViewerWindow/LogEntry.tsx
  • src/logViewerWindow/constants.ts
  • src/logViewerWindow/ipc.ts
  • src/logViewerWindow/log-viewer-window.tsx
  • src/logViewerWindow/logViewerWindow.tsx
  • src/logViewerWindow/types.ts
  • src/logging/cleanup.ts
  • src/logging/context.ts
  • src/logging/fallback.ts
  • src/logging/index.ts
  • src/logging/preload.ts
  • src/logging/privacy.ts
  • src/logging/scopes.ts
  • src/logging/utils.ts
  • src/main.spec.ts
  • src/main.ts
  • src/navigation/main.ts
  • src/notifications/actions.ts
  • src/notifications/attentionDrawing.ts
  • src/notifications/common.ts
  • src/notifications/main.ts
  • src/notifications/preload.ts
  • src/outlookCalendar/AGENTS.md
  • src/outlookCalendar/errorClassification.ts
  • src/outlookCalendar/getOutlookEvents.spec.ts
  • src/outlookCalendar/getOutlookEvents.ts
  • src/outlookCalendar/ipc.ts
  • src/outlookCalendar/logger.ts
  • src/outlookCalendar/preload.ts
  • src/outlookCalendar/type.ts
  • src/preload.ts
  • src/public/error.css
  • src/public/index.html
  • src/public/loading.css
  • src/public/log-viewer-window.html
  • src/public/video-call-window.html
  • src/rootWindow.ts
  • src/servers/common.ts
  • src/servers/preload/api.ts
  • src/servers/preload/gitCommitHash.ts
  • src/servers/preload/internalVideoChatWindow.ts
  • src/servers/preload/reloadServer.ts
  • src/servers/preload/themeAppearance.ts
  • src/servers/reducers.ts
  • src/servers/supportedVersions/main.main.spec.ts
  • src/servers/supportedVersions/main.ts
  • src/store/index.ts
  • src/store/rootReducer.ts
  • src/ui/actions.ts
  • src/ui/components/AboutDialog/index.tsx
  • src/ui/components/Dialog/hooks.ts
  • src/ui/components/OutlookCredentialsDialog/index.tsx
  • src/ui/components/ServerInfoContent.tsx
  • src/ui/components/ServerInfoModal/index.tsx
  • src/ui/components/ServersView/DocumentViewer.tsx
  • src/ui/components/ServersView/ServerPane.tsx
  • src/ui/components/ServersView/UnsupportedServer.tsx
  • src/ui/components/ServersView/index.tsx
  • src/ui/components/ServersView/styles.tsx
  • src/ui/components/SettingsView/DeveloperTab.tsx
  • src/ui/components/SettingsView/GeneralTab.tsx
  • src/ui/components/SettingsView/SettingsView.tsx
  • src/ui/components/SettingsView/features/AvailableBrowsers.tsx
  • src/ui/components/SettingsView/features/MenuBar.tsx
  • src/ui/components/SettingsView/features/ScreenCaptureFallback.tsx
  • src/ui/components/SettingsView/features/SideBar.tsx
  • src/ui/components/SettingsView/features/ThemeAppearance.tsx
  • src/ui/components/SettingsView/features/TransparentWindow.tsx
  • src/ui/components/SettingsView/features/VerboseOutlookLogging.tsx
  • src/ui/components/Shell/index.tsx
  • src/ui/components/Shell/styles.tsx
  • src/ui/components/SideBar/ServerButton.tsx
  • src/ui/components/SideBar/ServerInfoDropdown.tsx
  • src/ui/components/SideBar/index.tsx
  • src/ui/components/SupportedVersionDialog/index.tsx
  • src/ui/components/TopBar/index.tsx
  • src/ui/main/dialogs.ts
  • src/ui/main/dock.ts
  • src/ui/main/mediaPermissions.ts
  • src/ui/main/menuBar.ts
  • src/ui/main/rootWindow.spec.ts
  • src/ui/main/rootWindow.ts
  • src/ui/main/serverView/index.ts
  • src/ui/reducers/dialogs.ts
  • src/ui/reducers/isDeveloperModeEnabled.ts
  • src/ui/reducers/isMenuBarEnabled.spec.ts
  • src/ui/reducers/isSideBarEnabled.spec.ts
  • src/ui/reducers/isTransparentWindowEnabled.ts
  • src/ui/reducers/isVerboseOutlookLoggingEnabled.ts
  • src/ui/reducers/isVideoCallDevtoolsAutoOpenEnabled.ts
  • src/ui/reducers/isVideoCallScreenCaptureFallbackEnabled.ts
  • src/ui/reducers/userThemePreference.ts
  • src/ui/selectors.ts
  • src/ui/utils/platform.ts
  • src/updates/actions.ts
  • src/updates/common.ts
  • src/updates/main.spec.ts
  • src/updates/main.ts
  • src/updates/reducers.ts
  • src/urls.ts
  • src/videoCallWindow/ipc.ts
  • src/videoCallWindow/main/ipc.spec.ts
  • src/videoCallWindow/preload/jitsiBridge.ts
  • src/videoCallWindow/screenPicker/createScreenPicker.ts
  • src/videoCallWindow/screenPicker/index.ts
  • src/videoCallWindow/screenPicker/providers/InternalPickerProvider.ts
  • src/videoCallWindow/screenPicker/providers/PortalPickerProvider.ts
  • src/videoCallWindow/screenPicker/types.ts
  • src/videoCallWindow/screenSharePicker.tsx
  • src/videoCallWindow/screenSharePickerMount.tsx
  • src/videoCallWindow/video-call-window.ts
  • src/videoCallWindow/video-call-window.tsx
  • src/videoCallWindow/videoCallWindow.tsx
  • tsconfig.json
  • workspaces/desktop-release-action/action.yml
  • workspaces/desktop-release-action/package.json
  • workspaces/desktop-release-action/src/github.ts
  • workspaces/desktop-release-action/src/index.ts
  • workspaces/desktop-release-action/src/shell.ts
  • workspaces/desktop-release-action/src/types/js-yaml.d.ts
  • workspaces/desktop-release-action/src/windows.ts
  • workspaces/desktop-release-action/src/windows/certificates.ts
  • workspaces/desktop-release-action/src/windows/google-cloud.ts
  • workspaces/desktop-release-action/src/windows/index.ts
  • workspaces/desktop-release-action/src/windows/kms-provider.ts
  • workspaces/desktop-release-action/src/windows/msi-service-fix.ts
  • workspaces/desktop-release-action/src/windows/sign-packages.ts
  • workspaces/desktop-release-action/src/windows/signing-tools.ts
  • workspaces/desktop-release-action/src/windows/update-yaml-checksums.ts
  • workspaces/desktop-release-action/src/windows/verify-signature.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This pull request standardizes formatting across configs, docs, and i18n files, adjusts several translations, and adds an external link-opening feature via a new IPC channel exposed to renderer/preload and handled in the main process.

Changes

Cohort / File(s) Summary
Configuration Files
\.cursor/worktrees.json, \.eslintrc.json, \.prettierrc.mjs, tsconfig.json, workspaces/desktop-release-action/\.prettierrc.mjs, workspaces/desktop-release-action/tsconfig.json
Formatting and style normalization: array/object formatting, quote/trailing-comma changes, and EOF newline adjustments.
GitHub Templates & Workflows
.github/CONTRIBUTING.md, .github/ISSUE_TEMPLATE.md, .github/ISSUE_TEMPLATE/feature_request.md, .github/PULL_REQUEST_TEMPLATE.md, .github/workflows/powershell-lint.yml
Whitespace and minor formatting edits in templates and workflow files; no logic changes.
App Update YAML
alpha-app-update.yml, beta-app-update.yml
Fixed YAML key formatting (removed leading dash from channel entries).
Documentation - Release & Process
docs/alpha-release-process.md, docs/supported-versions-flow.md
Docs updates and wording changes; supportedVersionsValidatedAt field added to per-server state and blocking logic for fetchState=error refined.
Documentation - Video/Display
docs/linux-display-server.md, docs/video-call-screen-sharing.md, docs/video-call-window-flow.md, docs/video-call-window-management.md, docs/video-call-window-wgc-limitations.md
Extensive doc refinements: flow descriptions, lazy-loading/persistence semantics for screen picker, cache/SWR details, diagrams and formatting changes.
Documentation - QA & Misc
docs/qa-alpha-update-testing.md, CHANGELOG.md, CODE_OF_CONDUCT.md, scripts/README.md
Formatting, table alignment, and content clarifications; CHANGELOG reflowed.
Internationalization — EOF normalization
src/i18n/ar.i18n.json, src/i18n/de-DE.i18n.json, src/i18n/es.i18n.json, src/i18n/fi.i18n.json, src/i18n/fr.i18n.json, src/i18n/it-IT.i18n.json, src/i18n/ja.i18n.json, src/i18n/nb-NO.i18n.json, src/i18n/nn.i18n.json, src/i18n/pt-BR.i18n.json, src/i18n/ru.i18n.json, src/i18n/tr-TR.i18n.json, src/i18n/uk-UA.i18n.json, src/i18n/zh-CN.i18n.json, src/i18n/zh-TW.i18n.json, src/i18n/zh.i18n.json
Added/normalized trailing newlines; no content changes.
Internationalization — Content Changes
src/i18n/no.i18n.json, src/i18n/pl.i18n.json, src/i18n/sv.i18n.json
Translation text adjustments, new/updated keys (Norwegian adds some keys; Polish/Swedish wording tweaks).
Internationalization — Removed
src/i18n/se.i18n.json
Swedish se translation file deleted.
External Link Opening (IPC)
src/injected.ts, src/ipc/channels.ts, src/main.ts, src/servers/preload/api.ts, src/servers/preload/openExternal.ts
Added click handler that routes external http/https links to a new open-external IPC channel; channel defined, main handler wired to openExternal launcher, and preload exposes RocketChatDesktop.openExternal.
Renderer / Window Handling
src/ui/main/rootWindow.ts, src/injected.ts
Added renderer crash recovery (clear storage/cache and reload) and injected click handling (note: click handler is registered twice in src/injected.ts).
Public HTML & CSS
src/public/index.html, src/public/video-call-window.html, src/public/error.css, src/public/loading.css, src/public/main.css
HTML reformatting, minor CSS fixes (missing semicolon), and EOF adjustments.
Outlook & Misc Source
src/outlookCalendar/AGENTS.md, src/servers/preload/openExternal.ts, src/servers/preload/api.ts, src/public/*
Import formatting and new preload helper to invoke open-external.
Release Action Workspace
workspaces/desktop-release-action/...
Mostly formatting and signature reflows; notable logic: added main installer checksum update in update-yaml-checksums.ts and explicit JAVA_HOME/PATH handling in signing-tools.ts.

Sequence Diagram(s)

sequenceDiagram
    participant Renderer as Renderer Process
    participant Injected as Click Handler\n(src/injected.ts)
    participant Preload as Preload API\n(src/servers/preload/openExternal.ts)
    participant IPC as IPC Main\n(src/ipc/channels.ts)
    participant Main as Main Process\n(src/main.ts)
    participant Launcher as Browser Launcher\n(utils/browserLauncher)

    Renderer->>Injected: user clicks anchor
    Injected->>Injected: determine same-origin?
    alt external http/https
        Injected->>Preload: call RocketChatDesktop.openExternal(url)
        Preload->>IPC: invoke('open-external', url)
        IPC->>Main: handle 'open-external'
        Main->>Launcher: openExternal(url)
        Launcher-->>Main: result
        Main-->>IPC: resolve
        IPC-->>Preload: resolved
        Preload-->>Injected: promise resolves
        Injected->>Renderer: preventDefault()
    else internal / same-origin
        Injected->>Renderer: allow navigation
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main fix: preventing a GUI crash on the second launch of the Desktop App, which aligns with the primary objective of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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 and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
docs/supported-versions-flow.md (1)

7-7: 🛠️ Refactor suggestion | 🟠 Major

Update key principle statement for consistency.

Line 7 states: "Allow access during data loading and when using fallback sources." However, the more detailed explanation at line 585 clarifies that when using fallback sources (error state), the app should "block if fallback data (cache or builtin) confirms unsupported version."

The statement at line 7 could be misinterpreted to mean the app always allows access when using fallback sources, which contradicts the actual behavior. Consider updating line 7 to align with the more precise explanation at line 585.

✏️ Suggested update for line 7
-**Key principle**: Block users only when we have **definitive proof** that their server version is unsupported. Allow access during data loading and when using fallback sources.
+**Key principle**: Block users only when we have **definitive proof** that their server version is unsupported. Allow access during data loading. When using fallback sources (cache or builtin), allow access only if data is uncertain or confirms support; block if fallback confirms unsupported.

Or more concisely:

-**Key principle**: Block users only when we have **definitive proof** that their server version is unsupported. Allow access during data loading and when using fallback sources.
+**Key principle**: Block users only when we have **definitive proof** that their server version is unsupported (from fresh or fallback data). Always allow access during data loading.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/supported-versions-flow.md` at line 7, Update the "Key principle"
sentence that currently reads "Allow access during data loading and when using
fallback sources." to match the detailed behavior later in the doc: state that
access is allowed during data loading, but when using fallback sources the app
should only allow access if the fallback does not confirm an unsupported version
— otherwise block; replace the ambiguous phrase with a clarified line such as
"Allow access during data loading; when using fallback sources, block only if
the fallback (cache or builtin) confirms the version is unsupported."
workspaces/desktop-release-action/src/windows/sign-packages.ts (1)

68-89: ⚠️ Potential issue | 🟠 Major

Escape the installer path properly before embedding it in the inline script.

Line 72 uses file.replace(/\\/g, '\\\\') to escape backslashes only. This leaves single quotes unescaped, so a path like C:\Users\O'Neill\setup.exe produces invalid JavaScript in the generated node -e command and causes the signing step to fail.

Suggested fix
       const config = {
-        path: '${file.replace(/\\/g, '\\\\')}',
+        path: ${JSON.stringify(file)},
         name: 'Rocket.Chat',
         site: 'https://rocket.chat'
       };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@workspaces/desktop-release-action/src/windows/sign-packages.ts` around lines
68 - 89, The inline script embeds the installer path into scriptContent using
file.replace(/\\/g, '\\\\') but doesn't escape single quotes, breaking the
generated node -e command for paths like C:\Users\O'Neill\setup.exe; update the
embedding to properly serialize/escape the path (e.g., use JSON.stringify(file)
when inserting into scriptContent or at minimum chain .replace(/'/g, "\\'")
after escaping backslashes) so the path value in the generated script is always
valid JavaScript; adjust the code that builds scriptContent (and the execAsync
call that executes it) to use this safe serialization for the path passed to
sign(config).
docs/video-call-screen-sharing.md (1)

229-237: ⚠️ Potential issue | 🟡 Minor

Add fence languages to the new plain-text examples.

These newly added fenced blocks are unlabeled, which trips markdownlint MD040. Use text for the timing/pseudocode examples so docs lint stays green.

📝 Minimal fix
-```
+```text
 T=0s: User opens picker → Cache returns instantly (2s old)
 T=0s: Background refresh starts (async)
 T=1s: Background refresh completes, cache updated
 T=5s: User opens picker again → Gets fresh data instantly

```diff
-```
+```text
 Cache hit within 3s → Return cached data
 Cache expired → Fetch new data (blocking)
 Window close → Schedule 60s cleanup timer

```diff
-```
+```text
 Cache exists → Return immediately (always instant)
 Cache stale → Background refresh (non-blocking)
 Window close → Keep cache (no cleanup timer)
</details>


Also applies to: 291-312

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @docs/video-call-screen-sharing.md around lines 229 - 237, The unlabeled
fenced code blocks in docs/video-call-screen-sharing.md (e.g., the pseudocode
timing block shown at T=0s...T=5s) should be marked with a fence language to
satisfy markdownlint MD040; update each of those triple-backtick blocks (the
timing/pseudocode examples around the T=0s..T=5s block and the other two
examples noted) to use text instead of so they become fenced as plain
text — apply the same change for the other occurrences referenced (around lines
291-312).


</details>

</blockquote></details>

</blockquote></details>
🧹 Nitpick comments (2)
docs/supported-versions-flow.md (2)

119-119: Consider clarifying the phrasing for wait time calculation.

The calculation is mathematically correct (4 seconds total), but the phrase "2 waits × 2s delays" is slightly awkward. Consider rephrasing to improve readability.

📝 Suggested rephasing options

Option 1:

-**Total wait per source**: Up to 4 seconds (3 attempts with 2 waits × 2s delays)
+**Total wait per source**: Up to 4 seconds (2 delays of 2s each between 3 attempts)

Option 2:

-**Total wait per source**: Up to 4 seconds (3 attempts with 2 waits × 2s delays)
+**Total wait per source**: Up to 4 seconds (3 attempts with 2-second delays between them)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/supported-versions-flow.md` at line 119, The phrasing "2 waits × 2s
delays" under the "Total wait per source" line is awkward; update that sentence
to a clearer wording such as "Total wait per source: Up to 4 seconds (three
attempts with two 2-second waits)" or "Total wait per source: Up to 4 seconds
(three attempts, two waits of 2s each)" so the math and units read naturally;
edit the string that currently reads "**Total wait per source**: Up to 4 seconds
(3 attempts with 2 waits × 2s delays)" to one of these clearer options.

335-346: Verify timing consistency between retry delay and total scenario time.

At line 119, the documentation states each source takes "Up to 4 seconds (3 attempts with 2 waits × 2s delays)," which accounts for only the delay times between attempts. However, this offline scenario timeline shows each source (Server and Cloud) taking approximately 6 seconds (0-6s for Server, 6-12s for Cloud).

The 6-second duration per source likely includes both the attempt times (network timeouts/failures) and the 2-second delays. For clarity, consider either:

  1. Updating line 119 to clarify that "4 seconds" refers only to delays, not total time, or
  2. Adding a note explaining that the total time per source includes both attempt duration and delays
💡 Suggested clarification

At line 119, you could clarify:

-**Total wait per source**: Up to 4 seconds (3 attempts with 2 waits × 2s delays)
+**Total delay time per source**: Up to 4 seconds (2 waits of 2s each)
+**Total time per source**: Up to 6 seconds (including attempt timeouts and delays)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/supported-versions-flow.md` around lines 335 - 346, The sentence stating
"Up to 4 seconds (3 attempts with 2 waits × 2s delays)" is ambiguous because the
timeline shows ~6s per source — update that sentence to clarify whether "4
seconds" refers only to cumulative delay between retries (the 2s waits) or
change it to state the total per-source duration includes both per-attempt
timeout durations plus the 2s inter-attempt waits; alternatively add a short
parenthetical note after the existing phrase (or a sentence immediately after)
explaining that the total ~6s observed in the timeline includes the
attempt/timeout durations in addition to the 4s of delays so readers understand
the difference.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CHANGELOG.md`:
- Around line 125-130: The changelog contains a duplicated release block for the
header "#
[3.3.0](https://github.com/RocketChat/Rocket.Chat.Electron/compare/3.2.2...3.3.0)
(2021-06-17)" — remove the redundant block (the second occurrence that repeats
the two "i18n" bug fix lines) so only the original 3.3.0 entry remains; search
for the "[3.3.0]" header and delete the duplicated header and its following list
items to keep a single canonical release entry.

In `@docs/supported-versions-flow.md`:
- Line 136: The comment in UnsupportedServer.tsx (near the UnsupportedServer
component) is inaccurate: the current logic blocks whenever isSupported ===
false and fetchState !== 'loading' (i.e., on both 'success' and 'error'), not
only on a definitive 'success' proof; either update the comment to state that
behavior explicitly, or change the logic to match the docs by adding the
conditional fallback check (e.g., only treat error as blocking if a fallback
confirms unsupported) — adjust the check around isSupported and fetchState (and
any fallback check variable used) accordingly so code and comment/doc are
consistent.

In `@src/i18n/pl.i18n.json`:
- Line 213: Typo in the video-call error message: change the "announcement" JSON
value from "Hjuston, mamy problem" to the correct phrase (e.g., "Houston, mamy
problem" or preferred translation) in the src/i18n/pl.i18n.json file; locate the
"announcement" key in that file and update its string so the failure UI shows
the corrected message.

In `@src/injected.ts`:
- Around line 204-215: The origin check is unsafe because
startsWith(window.location.origin) treats "chat.example.com.evil.tld" as
internal; replace the naive startsWith logic by parsing the link.href with the
URL constructor and compare its origin strictly to window.location.origin (e.g.,
new URL(url, window.location.href).origin === currentOrigin), handling relative
URLs and wrapping parsing in try/catch to fall back to treating unknown/invalid
URLs as external before calling window.RocketChatDesktop?.openExternal(url).
Ensure you reference the variables url, currentOrigin, link.href and the call to
window.RocketChatDesktop.openExternal when making the change.
- Around line 194-219: The click handler added with
document.addEventListener(...) is registered in the capture phase (third
argument true) so it runs before the page's handlers and can override their
preventDefault; change this to register in the bubble phase (remove or set the
third argument to false) and also guard early by checking event.defaultPrevented
before processing; locate the listener in injected.ts (the
document.addEventListener click handler that computes target/closest('a'),
link.href, url and does url.startsWith checks) and update registration and add a
check like if (event.defaultPrevented) return to avoid intercepting clicks
already handled by the page.

In `@src/ipc/channels.ts`:
- Line 134: The 'open-external' IPC handler and the openExternal() utility
currently forward arbitrary URLs to shell.openExternal(), which allows untrusted
URI schemes; update the IPC handler for 'open-external' and/or the
openExternal() function to parse the incoming URL (using new URL(url)) and
validate its protocol against an allowlist (at minimum 'http:' and 'https:'),
throwing an error for unsupported protocols and only calling
shell.openExternal() with the validated URL string; reference the
'open-external' handler name and the openExternal() utility/shell.openExternal()
call to locate where to add the check.

In `@src/main.ts`:
- Around line 148-150: The IPC handler registered as handle('open-external',
...) currently forwards the renderer-provided url directly to openExternal;
change it to first validate the URL scheme with the existing
isProtocolAllowed(url) from src/navigation/main.ts and only call openExternal
when isProtocolAllowed returns true, otherwise reject/return an error (and
optionally log the blocked attempt via your logger). Ensure you import
isProtocolAllowed, perform the check inside the same handler for
'open-external', and avoid calling openExternal or shell.openExternal for
disallowed schemes.

In `@src/ui/main/rootWindow.ts`:
- Around line 519-531: The render-process-gone handler registered via
browserWindow.webContents.on('render-process-gone') in showRootWindow() must be
made safe: register it only once per window (use webContents.once or check
webContents.listenerCount / a browserWindow property) and add a
recovery-in-progress guard (e.g., a boolean on the BrowserWindow or closure) to
prevent re-entry/infinite reload loops; check details.reason and bail out early
for clean exits or non-recoverable reasons before attempting recovery; when
clearing state, clear both the default session and any persisted partitions used
by your webviews (iterate known server URLs and call
session.fromPartition(`persist:${serverUrl}`) then clearCache/clearStorageData
on each) and ensure you handle and log errors for each session separately.

In `@workspaces/desktop-release-action/src/windows/certificates.ts`:
- Around line 53-69: In verifyCertificateInStore, validate and normalize
certSha1 before building verifyCertCmd/hasPrivateKeyCmd: ensure certSha1 matches
a 40-character hex SHA-1 (e.g. /^[A-Fa-f0-9]{40}$/), convert to a consistent
case (upper or lower) and throw a clear error if invalid, then use the validated
value when constructing the PowerShell commands (this prevents injection or
malformed thumbprints being interpolated into verifyCertCmd and
hasPrivateKeyCmd).

---

Outside diff comments:
In `@docs/supported-versions-flow.md`:
- Line 7: Update the "Key principle" sentence that currently reads "Allow access
during data loading and when using fallback sources." to match the detailed
behavior later in the doc: state that access is allowed during data loading, but
when using fallback sources the app should only allow access if the fallback
does not confirm an unsupported version — otherwise block; replace the ambiguous
phrase with a clarified line such as "Allow access during data loading; when
using fallback sources, block only if the fallback (cache or builtin) confirms
the version is unsupported."

In `@docs/video-call-screen-sharing.md`:
- Around line 229-237: The unlabeled fenced code blocks in
docs/video-call-screen-sharing.md (e.g., the pseudocode timing block shown at
T=0s...T=5s) should be marked with a fence language to satisfy markdownlint
MD040; update each of those triple-backtick blocks (the timing/pseudocode
examples around the T=0s..T=5s block and the other two examples noted) to use
```text instead of ``` so they become fenced as plain text — apply the same
change for the other occurrences referenced (around lines 291-312).

In `@workspaces/desktop-release-action/src/windows/sign-packages.ts`:
- Around line 68-89: The inline script embeds the installer path into
scriptContent using file.replace(/\\/g, '\\\\') but doesn't escape single
quotes, breaking the generated node -e command for paths like
C:\Users\O'Neill\setup.exe; update the embedding to properly serialize/escape
the path (e.g., use JSON.stringify(file) when inserting into scriptContent or at
minimum chain .replace(/'/g, "\\'") after escaping backslashes) so the path
value in the generated script is always valid JavaScript; adjust the code that
builds scriptContent (and the execAsync call that executes it) to use this safe
serialization for the path passed to sign(config).

---

Nitpick comments:
In `@docs/supported-versions-flow.md`:
- Line 119: The phrasing "2 waits × 2s delays" under the "Total wait per source"
line is awkward; update that sentence to a clearer wording such as "Total wait
per source: Up to 4 seconds (three attempts with two 2-second waits)" or "Total
wait per source: Up to 4 seconds (three attempts, two waits of 2s each)" so the
math and units read naturally; edit the string that currently reads "**Total
wait per source**: Up to 4 seconds (3 attempts with 2 waits × 2s delays)" to one
of these clearer options.
- Around line 335-346: The sentence stating "Up to 4 seconds (3 attempts with 2
waits × 2s delays)" is ambiguous because the timeline shows ~6s per source —
update that sentence to clarify whether "4 seconds" refers only to cumulative
delay between retries (the 2s waits) or change it to state the total per-source
duration includes both per-attempt timeout durations plus the 2s inter-attempt
waits; alternatively add a short parenthetical note after the existing phrase
(or a sentence immediately after) explaining that the total ~6s observed in the
timeline includes the attempt/timeout durations in addition to the 4s of delays
so readers understand the difference.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 477a04bb-cc39-4ea4-9be4-a5a6c74dd97c

📥 Commits

Reviewing files that changed from the base of the PR and between 49261f5 and 92471b9.

⛔ Files ignored due to path filters (1)
  • workspaces/desktop-release-action/dist/index.js is excluded by !**/dist/**
📒 Files selected for processing (67)
  • .cursor/worktrees.json
  • .eslintrc.json
  • .github/CONTRIBUTING.md
  • .github/ISSUE_TEMPLATE.md
  • .github/ISSUE_TEMPLATE/feature_request.md
  • .github/PULL_REQUEST_TEMPLATE.md
  • .github/workflows/powershell-lint.yml
  • .prettierrc.mjs
  • CHANGELOG.md
  • CODE_OF_CONDUCT.md
  • alpha-app-update.yml
  • beta-app-update.yml
  • docs/alpha-release-process.md
  • docs/linux-display-server.md
  • docs/qa-alpha-update-testing.md
  • docs/supported-versions-flow.md
  • docs/video-call-screen-sharing.md
  • docs/video-call-window-flow.md
  • docs/video-call-window-management.md
  • docs/video-call-window-wgc-limitations.md
  • scripts/README.md
  • src/i18n/ar.i18n.json
  • src/i18n/de-DE.i18n.json
  • src/i18n/es.i18n.json
  • src/i18n/fi.i18n.json
  • src/i18n/fr.i18n.json
  • src/i18n/it-IT.i18n.json
  • src/i18n/ja.i18n.json
  • src/i18n/nb-NO.i18n.json
  • src/i18n/nn.i18n.json
  • src/i18n/no.i18n.json
  • src/i18n/pl.i18n.json
  • src/i18n/pt-BR.i18n.json
  • src/i18n/ru.i18n.json
  • src/i18n/se.i18n.json
  • src/i18n/sv.i18n.json
  • src/i18n/tr-TR.i18n.json
  • src/i18n/uk-UA.i18n.json
  • src/i18n/zh-CN.i18n.json
  • src/i18n/zh-TW.i18n.json
  • src/i18n/zh.i18n.json
  • src/injected.ts
  • src/ipc/channels.ts
  • src/main.ts
  • src/outlookCalendar/AGENTS.md
  • src/public/error.css
  • src/public/index.html
  • src/public/loading.css
  • src/public/main.css
  • src/public/video-call-window.html
  • src/servers/preload/api.ts
  • src/servers/preload/openExternal.ts
  • src/ui/main/rootWindow.ts
  • tsconfig.json
  • workspaces/desktop-release-action/.prettierrc.mjs
  • workspaces/desktop-release-action/action.yml
  • workspaces/desktop-release-action/src/github.ts
  • workspaces/desktop-release-action/src/index.ts
  • workspaces/desktop-release-action/src/types/js-yaml.d.ts
  • workspaces/desktop-release-action/src/windows/certificates.ts
  • workspaces/desktop-release-action/src/windows/google-cloud.ts
  • workspaces/desktop-release-action/src/windows/kms-provider.ts
  • workspaces/desktop-release-action/src/windows/msi-service-fix.ts
  • workspaces/desktop-release-action/src/windows/sign-packages.ts
  • workspaces/desktop-release-action/src/windows/signing-tools.ts
  • workspaces/desktop-release-action/src/windows/update-yaml-checksums.ts
  • workspaces/desktop-release-action/tsconfig.json
💤 Files with no reviewable changes (3)
  • .github/ISSUE_TEMPLATE/feature_request.md
  • src/i18n/se.i18n.json
  • src/public/error.css
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript strict mode enabled in TypeScript configuration
Use React functional components with hooks instead of class components
Follow FSA (Flux Standard Action) pattern for Redux actions
Use camelCase for file names and PascalCase for component file names
All code must pass ESLint and TypeScript checks
Write self-documenting code with clear naming; avoid unnecessary comments except for complex business logic or non-obvious decisions
Use Fuselage components from @rocket.chat/fuselage for all UI work and only create custom components when Fuselage doesn't provide what's needed
Check Theme.d.ts for valid color tokens when using Fuselage components
Use defensive coding with optional chaining and fallbacks for Linux-only APIs (process.getuid(), process.getgid(), process.geteuid(), process.getegid()) to ensure cross-platform compatibility across Windows, macOS, and Linux

Files:

  • workspaces/desktop-release-action/src/types/js-yaml.d.ts
  • workspaces/desktop-release-action/src/windows/msi-service-fix.ts
  • src/servers/preload/api.ts
  • workspaces/desktop-release-action/src/windows/signing-tools.ts
  • src/injected.ts
  • src/main.ts
  • workspaces/desktop-release-action/src/windows/update-yaml-checksums.ts
  • workspaces/desktop-release-action/src/windows/certificates.ts
  • src/ipc/channels.ts
  • workspaces/desktop-release-action/src/windows/sign-packages.ts
  • workspaces/desktop-release-action/src/github.ts
  • src/ui/main/rootWindow.ts
  • workspaces/desktop-release-action/src/windows/kms-provider.ts
  • src/servers/preload/openExternal.ts
  • workspaces/desktop-release-action/src/windows/google-cloud.ts
  • workspaces/desktop-release-action/src/index.ts
🧠 Learnings (20)
📚 Learning: 2026-03-06T19:31:11.433Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: src/outlookCalendar/AGENTS.md:0-0
Timestamp: 2026-03-06T19:31:11.433Z
Learning: Applies to src/outlookCalendar/**/*(!preload).ts?(x) : Always use the centralized logger from `logger.ts` (outlookLog, outlookDebug, outlookError, outlookWarn, outlookEventDetail) instead of console.log() for Outlook Calendar module logging

Applied to files:

  • src/outlookCalendar/AGENTS.md
📚 Learning: 2026-03-06T19:31:11.433Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: src/outlookCalendar/AGENTS.md:0-0
Timestamp: 2026-03-06T19:31:11.433Z
Learning: Applies to src/outlookCalendar/**/preload.ts : Keep preload.ts logging minimal since it cannot access the verbose logging toggle from Redux Store and all logs always appear

Applied to files:

  • src/outlookCalendar/AGENTS.md
📚 Learning: 2026-03-06T19:31:11.433Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: src/outlookCalendar/AGENTS.md:0-0
Timestamp: 2026-03-06T19:31:11.433Z
Learning: Applies to src/outlookCalendar/**/*.{ts,tsx} : Always use outlookError() for errors as it logs regardless of verbose mode settings, ensuring errors are always visible to users

Applied to files:

  • src/outlookCalendar/AGENTS.md
📚 Learning: 2026-03-06T19:31:11.433Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: src/outlookCalendar/AGENTS.md:0-0
Timestamp: 2026-03-06T19:31:11.433Z
Learning: Applies to src/outlookCalendar/**/*.{ts,tsx} : Use `createClassifiedError()` from `errorClassification.ts` for user-facing errors to provide error categorization, user-friendly messages, and structured error context

Applied to files:

  • src/outlookCalendar/AGENTS.md
📚 Learning: 2026-03-06T19:31:11.433Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: src/outlookCalendar/AGENTS.md:0-0
Timestamp: 2026-03-06T19:31:11.433Z
Learning: Verbose logging (outlookLog, outlookWarn, outlookDebug) should only output when the verbose logging toggle is enabled in Settings > Developer > Verbose Outlook Logging

Applied to files:

  • src/outlookCalendar/AGENTS.md
📚 Learning: 2026-02-04T19:29:54.650Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Use root package.json commands for workspace builds with `yarn workspaces:build` instead of running `yarn build` directly in workspace directories

Applied to files:

  • .cursor/worktrees.json
📚 Learning: 2026-02-23T17:21:22.132Z
Learnt from: SantamRC
Repo: RocketChat/Rocket.Chat.Electron PR: 3213
File: tsconfig.json:22-22
Timestamp: 2026-02-23T17:21:22.132Z
Learning: In the RocketChat/Rocket.Chat.Electron project, configuration files like `tsconfig.json` should maintain strict JSON compliance (no trailing commas) to ensure compatibility with various tooling and parsers in the development ecosystem, even though TypeScript itself accepts JSONC format.

Applied to files:

  • beta-app-update.yml
  • workspaces/desktop-release-action/.prettierrc.mjs
  • CHANGELOG.md
  • alpha-app-update.yml
  • .prettierrc.mjs
📚 Learning: 2026-02-04T19:29:54.650Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript strict mode enabled in TypeScript configuration

Applied to files:

  • workspaces/desktop-release-action/.prettierrc.mjs
  • tsconfig.json
  • .eslintrc.json
  • workspaces/desktop-release-action/tsconfig.json
  • .prettierrc.mjs
📚 Learning: 2026-02-04T19:29:54.650Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Use two-phase Windows code signing: build packages without signing first (empty environment variables), then sign built packages using jsign with Google Cloud KMS to prevent MSI build failures from KMS CNG provider conflicts

Applied to files:

  • workspaces/desktop-release-action/src/windows/signing-tools.ts
  • workspaces/desktop-release-action/src/windows/sign-packages.ts
📚 Learning: 2026-02-04T19:29:54.650Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Include all Windows build architectures (x64, ia32, arm64) when building with electron-builder using `yarn electron-builder --x64 --ia32 --arm64 --win nsis`

Applied to files:

  • workspaces/desktop-release-action/src/windows/signing-tools.ts
📚 Learning: 2026-02-23T17:21:16.480Z
Learnt from: SantamRC
Repo: RocketChat/Rocket.Chat.Electron PR: 3213
File: tsconfig.json:22-22
Timestamp: 2026-02-23T17:21:16.480Z
Learning: In RocketChat/Rocket.Chat.Electron, ensure tsconfig.json files use strict JSON syntax with no trailing commas. Although TypeScript parses JSONC, many tools and parsers expect valid JSON, so configurations should avoid trailing commas to maintain compatibility across tooling.

Applied to files:

  • tsconfig.json
  • workspaces/desktop-release-action/tsconfig.json
📚 Learning: 2026-02-04T19:29:54.650Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Applies to **/*.{ts,tsx} : Use Fuselage components from `rocket.chat/fuselage` for all UI work and only create custom components when Fuselage doesn't provide what's needed

Applied to files:

  • src/public/main.css
📚 Learning: 2026-02-04T19:29:54.650Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Applies to **/*.{ts,tsx} : Check `Theme.d.ts` for valid color tokens when using Fuselage components

Applied to files:

  • src/public/main.css
📚 Learning: 2026-02-04T19:29:54.650Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Always verify library and framework usage by checking official documentation and TypeScript type definitions before using; for TypeScript check `.d.ts` files in `node_modules/package-name/dist/`

Applied to files:

  • workspaces/desktop-release-action/src/windows/sign-packages.ts
📚 Learning: 2026-02-04T19:29:54.650Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Applies to **/*.{ts,tsx} : All code must pass ESLint and TypeScript checks

Applied to files:

  • .eslintrc.json
📚 Learning: 2026-02-04T19:29:54.650Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Applies to **/*.{ts,tsx} : Use camelCase for file names and PascalCase for component file names

Applied to files:

  • .eslintrc.json
📚 Learning: 2026-02-04T19:29:54.650Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Applies to **/*.{spec,main.spec}.ts : Use `*.spec.ts` file naming for renderer process tests and `*.main.spec.ts` for main process tests

Applied to files:

  • .eslintrc.json
📚 Learning: 2026-02-04T19:29:54.650Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Applies to **/*.{ts,tsx} : Follow FSA (Flux Standard Action) pattern for Redux actions

Applied to files:

  • .eslintrc.json
📚 Learning: 2026-02-04T19:29:54.650Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Remove nested dist folder created by ncc bundler after building desktop-release-action with command `rm -rf workspaces/desktop-release-action/dist/dist`

Applied to files:

  • workspaces/desktop-release-action/action.yml
  • workspaces/desktop-release-action/src/index.ts
📚 Learning: 2026-02-04T19:29:54.650Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Applies to **/*.{ts,tsx} : Use defensive coding with optional chaining and fallbacks for Linux-only APIs (process.getuid(), process.getgid(), process.geteuid(), process.getegid()) to ensure cross-platform compatibility across Windows, macOS, and Linux

Applied to files:

  • workspaces/desktop-release-action/src/index.ts
🪛 ESLint
src/ui/main/rootWindow.ts

[error] 520-520: Replace 'render-process-gone', with ⏎····'render-process-gone',⏎···

(prettier/prettier)


[error] 521-521: Insert ··

(prettier/prettier)


[error] 522-522: Insert ··

(prettier/prettier)


[error] 523-523: Insert ··

(prettier/prettier)


[error] 523-523: Use object destructuring.

(prefer-destructuring)


[error] 524-524: Insert ··

(prettier/prettier)


[error] 525-525: Insert ··

(prettier/prettier)


[error] 526-526: Insert ··

(prettier/prettier)


[error] 527-527: Replace ······ with ········

(prettier/prettier)


[error] 528-528: Insert ··

(prettier/prettier)


[error] 529-529: Replace ······ with ········

(prettier/prettier)


[error] 530-530: Insert ··

(prettier/prettier)


[error] 531-531: Replace ··} with ····}⏎··

(prettier/prettier)

🪛 LanguageTool
CHANGELOG.md

[uncategorized] ~25-~25: Did you mean Apple’s computer “Mac” (= trademark, capitalized)?
Context: ...5d53219e018)) - Missing entitlements on mac app ([#2191](https://github.com/RocketC...

(APPLE_PRODUCTS)


[grammar] ~49-~49: Ensure spelling is correct
Context: .....3.5.6) (2021-09-23) ### Bug Fixes - Jitisi opening on browser ([#2180](https://git...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[uncategorized] ~53-~53: Did you mean the proper noun “Apple Silicon”?
Context: ...42d02a8890308f136f6f)) ### Features - apple silicon universal support ([#2170](https://gith...

(APPLE_PRODUCTS)


[grammar] ~89-~89: Ensure spelling is correct
Context: ... (2021-09-08) ### Bug Fixes - Prevent Webcontent to navigate (outside) ([abd7a08](https:...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~279-~279: Use a hyphen to join words.
Context: ...cbc4a5857dcbd4e6e79b9)) - Embedded spell checking dictionaries ([#1523](https://g...

(QB_NEW_EN_HYPHEN)


[uncategorized] ~314-~314: The operating system from Apple is written “macOS”.
Context: ...8) (2020-03-01) ### Bug Fixes - Allow MacOS users to browse for spell checking dict...

(MAC_OS)


[grammar] ~314-~314: Use a hyphen to join words.
Context: ... - Allow MacOS users to browse for spell checking dictionaries ([3c75bfe](https:/...

(QB_NEW_EN_HYPHEN)


[uncategorized] ~334-~334: The operating system from Apple is written “macOS”.
Context: ...e91)) - Ignore Hunspell dictionaries on MacOS ([cccca77](https://github.com/RocketCha...

(MAC_OS)


[uncategorized] ~556-~556: The operating system from Apple is written “macOS”.
Context: ...- Main window destroyed when closing on MacOS ## 2.14.6 (2018...

(MAC_OS)


[uncategorized] ~564-~564: The operating system from Apple is written “macOS”.
Context: ...ying why some permissions are needed in MacOS - Fix servers.json path resolution <a ...

(MAC_OS)


[uncategorized] ~689-~689: The operating system from Apple is written “macOS”.
Context: ...n/pull/880) Tray icon toggle crashes in MacOS - [#869](https://github.com/RocketChat/...

(MAC_OS)


[uncategorized] ~702-~702: The operating system from Apple is written “macOS”.
Context: ...visioning profiles and entitlements for MacOS builds ## 2.13....

(MAC_OS)


[uncategorized] ~708-~708: The operating system from Apple is written “macOS”.
Context: ... ## 2.13.1 (2018-08-30) Fixes for MacOS and Windows builds. <...

(MAC_OS)


[uncategorized] ~819-~819: The operating system from Apple is written “macOS”.
Context: ...Chat/Rocket.Chat.Electron/pull/597) Fix MacOS dmg build # 2.1...

(MAC_OS)


[uncategorized] ~882-~882: Did you mean Apple’s computer “Mac” (= trademark, capitalized)?
Context: ...ectron/pull/425) Make sure app quits on mac on update - [#426](https://github.com/R...

(APPLE_PRODUCTS)

docs/video-call-window-management.md

[grammar] ~313-~313: Ensure spelling is correct
Context: ...05, -106): 1500ms delay - Other errors: 800ms delay - Prevents premature error displa...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

CODE_OF_CONDUCT.md

[style] ~27-~27: Try using a synonym here to strengthen your wording.
Context: ...vances - Trolling, insulting/derogatory comments, and personal or political attacks - Pu...

(COMMENT_REMARK)

docs/supported-versions-flow.md

[grammar] ~232-~232: Ensure spelling is correct
Context: ... (fetchState === 'error') - ✅ Generic builtin fallback (fetchState === 'error') **...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~585-~585: Ensure spelling is correct
Context: ...state, block if fallback data (cache or builtin) confirms unsupported version. 2. **Va...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🪛 markdownlint-cli2 (0.21.0)
CODE_OF_CONDUCT.md

[warning] 22-22: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

docs/video-call-screen-sharing.md

[warning] 95-95: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 192-192: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (20)
beta-app-update.yml (1)

5-5: Valid updater channel mapping.

This restores a proper YAML key/value entry for the release channel and looks correct.

alpha-app-update.yml (1)

5-5: Valid updater channel mapping.

This fixes the channel entry into a proper YAML mapping and looks good.

src/outlookCalendar/AGENTS.md (1)

8-14: Formatting-only update looks good.

This keeps the centralized logger example intact while matching the repo’s multiline import style. Based on learnings: Always use the centralized logger from logger.ts (outlookLog, outlookDebug, outlookError, outlookWarn, outlookEventDetail) instead of console.log() for Outlook Calendar module logging.

docs/linux-display-server.md (1)

19-33: Clear, useful docs update.

The added detection/package tables and the Wayland troubleshooting notes are consistent with the wrapper-based startup behavior described in the rest of the document, and they make the Linux setup/debug path much easier to follow.

Also applies to: 48-60, 107-142

workspaces/desktop-release-action/src/github.ts (2)

156-175: LGTM!

The formatting changes to multi-line parameter declarations improve readability. The function logic correctly identifies and deletes stale assets not in the expected list.


177-212: LGTM!

The formatting improvements enhance readability. The function logic correctly:

  1. Returns early when cleanup isn't needed
  2. Sorts assets by creation date (newest first)
  3. Deletes only the oldest assets exceeding the keepLatest threshold
workspaces/desktop-release-action/src/windows/signing-tools.ts (2)

7-32: LGTM!

The formatting changes to findSigntool improve readability by adding visual separation between logical blocks. No functional changes.


34-68: LGTM!

The formatting changes in installJsign improve readability:

  • The multi-line condition (lines 45-48) makes the compound check more readable
  • Added whitespace provides clearer separation between installation steps

The existing logic correctly handles environment propagation by manually setting process.env.PATH and process.env.JAVA_HOME after each installation step, which is necessary since refreshenv runs in a subprocess and won't propagate changes back to the Node.js process. Based on learnings, this aligns with the two-phase Windows code signing approach using jsign with Google Cloud KMS.

docs/supported-versions-flow.md (1)

215-215: LGTM: Formatting improvements enhance readability.

The addition of blank lines before list sections follows markdown best practices and improves document rendering. These changes enhance readability without affecting the technical content.

Also applies to: 222-222, 228-228, 234-234, 275-275, 481-481, 496-496, 503-503, 509-509

src/i18n/es.i18n.json (1)

465-465: LGTM - Standard EOF newline formatting.

The addition of a trailing newline at end-of-file follows standard formatting conventions. This applies to all i18n JSON files in this review (es.i18n.json, tr-TR.i18n.json, de-DE.i18n.json, ru.i18n.json, zh.i18n.json, fi.i18n.json, pt-BR.i18n.json). No semantic changes to translations or structure.

src/public/main.css (1)

4-5: LGTM - CSS syntax correction.

The addition of the semicolon after the CSS custom property value corrects a syntax error. CSS property declarations require a semicolon terminator. The fix properly closes the :root rule block.

.github/PULL_REQUEST_TEMPLATE.md (1)

10-11: LGTM!

Minor formatting improvement adding visual separation before the issue reference line.

workspaces/desktop-release-action/src/types/js-yaml.d.ts (1)

1-1: LGTM!

EOF newline addition follows standard formatting conventions.

src/i18n/zh-TW.i18n.json (1)

236-236: LGTM!

EOF newline normalization for the zh-TW locale file.

src/i18n/it-IT.i18n.json (1)

43-43: LGTM!

EOF newline normalization for the it-IT locale file.

src/i18n/ja.i18n.json (1)

259-259: LGTM!

EOF newline normalization for the ja locale file.

src/i18n/nn.i18n.json (1)

43-43: LGTM!

EOF newline normalization for the nn locale file.

tsconfig.json (1)

22-22: LGTM!

The tsconfig.json maintains valid JSON syntax with no trailing commas, compliant with project standards. Based on learnings: "ensure tsconfig.json files use strict JSON syntax with no trailing commas."

src/i18n/fr.i18n.json (1)

434-434: LGTM!

EOF newline normalization for the fr locale file.

workspaces/desktop-release-action/tsconfig.json (1)

19-19: Good JSON cleanup.

Removing the trailing comma keeps this config consumable by tooling that expects strict JSON instead of JSONC.

Based on learnings, tsconfig.json files should use strict JSON syntax with no trailing commas.

CHANGELOG.md Outdated
Comment on lines +125 to +130
# [3.3.0](https://github.com/RocketChat/Rocket.Chat.Electron/compare/3.2.2...3.3.0) (2021-06-17)


### Bug Fixes

* **i18n:** Language update from LingoHub 🤖 ([#2042](https://github.com/RocketChat/Rocket.Chat.Electron/issues/2042)) ([cb07526](https://github.com/RocketChat/Rocket.Chat.Electron/commit/cb07526ed5f4831fd05458208561be8e81f5d218))
* **i18n:** Language update from LingoHub 🤖 ([#2047](https://github.com/RocketChat/Rocket.Chat.Electron/issues/2047)) ([891b7b7](https://github.com/RocketChat/Rocket.Chat.Electron/commit/891b7b70d9fb6382ca2070c1644669b3f38b17ef))


- **i18n:** Language update from LingoHub 🤖 ([#2042](https://github.com/RocketChat/Rocket.Chat.Electron/issues/2042)) ([cb07526](https://github.com/RocketChat/Rocket.Chat.Electron/commit/cb07526ed5f4831fd05458208561be8e81f5d218))
- **i18n:** Language update from LingoHub 🤖 ([#2047](https://github.com/RocketChat/Rocket.Chat.Electron/issues/2047)) ([891b7b7](https://github.com/RocketChat/Rocket.Chat.Electron/commit/891b7b70d9fb6382ca2070c1644669b3f38b17ef))
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove the duplicated 3.3.0 block.

Line 125 repeats the same 3.3.0 release already listed at Lines 112-117, so the changelog now contains two identical entries for the same version.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CHANGELOG.md` around lines 125 - 130, The changelog contains a duplicated
release block for the header "#
[3.3.0](https://github.com/RocketChat/Rocket.Chat.Electron/compare/3.2.2...3.3.0)
(2021-06-17)" — remove the redundant block (the second occurrence that repeats
the two "i18n" bug fix lines) so only the original 3.3.0 entry remains; search
for the "[3.3.0]" header and delete the duplicated header and its following list
items to keep a single canonical release entry.

CheckState -->|loading| Allow2["✅ ALLOW<br/>Still fetching, not proven"]
CheckState -->|success| Block["❌ BLOCK<br/>Fresh data confirms unsupported"]
CheckState -->|error| Block2["❌ BLOCK<br/>Even fallback confirms unsupported"]
CheckState -->|error| Block2["❌ BLOCK<br/>Block if fallback confirms unsupported; otherwise allow (uncertain data)"]
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Review the blocking condition implementation and related comments

# Check the blocking logic in UnsupportedServer component
rg -n -A 5 -B 5 'shouldBlock.*fetchState' --type=tsx --type=ts

# Look for related comments about blocking logic
rg -n -C 3 'definitive proof|Only block if' --type=tsx --type=ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 130


🏁 Script executed:

#!/bin/bash
# Find the UnsupportedServer component file
fd -type f -name '*UnsupportedServer*'

# Search for shouldBlock logic in the codebase
rg -n -A 5 -B 5 'shouldBlock'

# Search for the comment about blocking logic
rg -n -C 3 'definitive proof|Only block if'

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 2690


🏁 Script executed:

#!/bin/bash
# Read the documentation file around line 136 to see the full context
sed -n '130,145p' docs/supported-versions-flow.md

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 574


Update code comment in UnsupportedServer.tsx to accurately reflect blocking behavior.

The code comment at line 35 states "Only block if we have definitive proof (success state) that server is unsupported," but the code logic fetchState !== 'loading' actually blocks on both success and error states, not just success.

Additionally, the updated documentation at line 136 indicates conditional blocking on error ("Block if fallback confirms unsupported; otherwise allow"), but the current code unconditionally blocks whenever isSupported === false and fetchState !== 'loading'. Clarify whether the blocking logic should implement the conditional fallback check described in the documentation, or update the documentation to reflect the unconditional blocking behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/supported-versions-flow.md` at line 136, The comment in
UnsupportedServer.tsx (near the UnsupportedServer component) is inaccurate: the
current logic blocks whenever isSupported === false and fetchState !== 'loading'
(i.e., on both 'success' and 'error'), not only on a definitive 'success' proof;
either update the comment to state that behavior explicitly, or change the logic
to match the docs by adding the conditional fallback check (e.g., only treat
error as blocking if a fallback confirms unsupported) — adjust the check around
isSupported and fetchState (and any fallback check variable used) accordingly so
code and comment/doc are consistent.

"error": {
"title": "Nie udało się załadować połączenia wideo",
"announcement": "Houston, mamy problem",
"announcement": "Hjuston, mamy problem",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix the typo in the video-call error message.

Hjuston, mamy problem looks unintentional and will show up directly in the failure UI.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/i18n/pl.i18n.json` at line 213, Typo in the video-call error message:
change the "announcement" JSON value from "Hjuston, mamy problem" to the correct
phrase (e.g., "Houston, mamy problem" or preferred translation) in the
src/i18n/pl.i18n.json file; locate the "announcement" key in that file and
update its string so the failure UI shows the corrected message.

Comment on lines +194 to +219
document.addEventListener(
'click',
(event) => {
const target = event.target as HTMLElement | null;
const link = target?.closest('a') as HTMLAnchorElement | null;

if (!link?.href) {
return;
}

const url = link.href;
const currentOrigin = window.location.origin;

// If it is an internal Rocket.Chat link, allow normal navigation
if (url.startsWith(currentOrigin)) {
return;
}

// External link
if (url.startsWith('http://') || url.startsWith('https://')) {
event.preventDefault();
window.RocketChatDesktop?.openExternal(url);
}
},
true
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Don't register the link interceptor in capture phase.

With true here, this handler runs before the page's own click handlers and can force external opening even when the app intended to preventDefault() and handle the click itself.

Suggested fix
-  document.addEventListener(
-    'click',
-    (event) => {
+  document.addEventListener('click', (event) => {
+      if (
+        event.defaultPrevented ||
+        event.button !== 0 ||
+        event.metaKey ||
+        event.ctrlKey ||
+        event.shiftKey ||
+        event.altKey
+      ) {
+        return;
+      }
+
       const target = event.target as HTMLElement | null;
       const link = target?.closest('a') as HTMLAnchorElement | null;
@@
-    },
-    true
-  );
+  });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/injected.ts` around lines 194 - 219, The click handler added with
document.addEventListener(...) is registered in the capture phase (third
argument true) so it runs before the page's handlers and can override their
preventDefault; change this to register in the bubble phase (remove or set the
third argument to false) and also guard early by checking event.defaultPrevented
before processing; locate the listener in injected.ts (the
document.addEventListener click handler that computes target/closest('a'),
link.href, url and does url.startsWith checks) and update registration and add a
check like if (event.defaultPrevented) return to avoid intercepting clicks
already handled by the page.

Comment on lines +204 to +215
const url = link.href;
const currentOrigin = window.location.origin;

// If it is an internal Rocket.Chat link, allow normal navigation
if (url.startsWith(currentOrigin)) {
return;
}

// External link
if (url.startsWith('http://') || url.startsWith('https://')) {
event.preventDefault();
window.RocketChatDesktop?.openExternal(url);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Use a real origin comparison here.

A URL like https://chat.example.com.evil.tld/... still passes startsWith(window.location.origin) and will be treated as internal.

Suggested fix
-      const url = link.href;
-      const currentOrigin = window.location.origin;
+      const url = new URL(link.href, window.location.href);
+      const currentOrigin = window.location.origin;
 
       // If it is an internal Rocket.Chat link, allow normal navigation
-      if (url.startsWith(currentOrigin)) {
+      if (url.origin === currentOrigin) {
         return;
       }
 
       // External link
-      if (url.startsWith('http://') || url.startsWith('https://')) {
+      if (url.protocol === 'http:' || url.protocol === 'https:') {
         event.preventDefault();
-        window.RocketChatDesktop?.openExternal(url);
+        void window.RocketChatDesktop?.openExternal?.(url.toString());
       }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const url = link.href;
const currentOrigin = window.location.origin;
// If it is an internal Rocket.Chat link, allow normal navigation
if (url.startsWith(currentOrigin)) {
return;
}
// External link
if (url.startsWith('http://') || url.startsWith('https://')) {
event.preventDefault();
window.RocketChatDesktop?.openExternal(url);
const url = new URL(link.href, window.location.href);
const currentOrigin = window.location.origin;
// If it is an internal Rocket.Chat link, allow normal navigation
if (url.origin === currentOrigin) {
return;
}
// External link
if (url.protocol === 'http:' || url.protocol === 'https:') {
event.preventDefault();
void window.RocketChatDesktop?.openExternal?.(url.toString());
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/injected.ts` around lines 204 - 215, The origin check is unsafe because
startsWith(window.location.origin) treats "chat.example.com.evil.tld" as
internal; replace the naive startsWith logic by parsing the link.href with the
URL constructor and compare its origin strictly to window.location.origin (e.g.,
new URL(url, window.location.href).origin === currentOrigin), handling relative
URLs and wrapping parsing in try/catch to fall back to treating unknown/invalid
URLs as external before calling window.RocketChatDesktop?.openExternal(url).
Ensure you reference the variables url, currentOrigin, link.href and the call to
window.RocketChatDesktop.openExternal when making the change.

success: boolean;
mapping: Record<string, string>;
};
'open-external': (url: string) => void;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -C4 "open-external|openExternal|shell\.openExternal|new URL\(|protocol" src

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 50387


Add protocol validation to the open-external IPC handler.

The main-process handler at src/main.ts:148-150 forwards the URL directly to openExternal() without any validation:

handle('open-external', async (_webContents, url) => {
  await openExternal(url);
});

The openExternal() utility (src/utils/browserLauncher.ts:58) also lacks validation and passes the URL straight to shell.openExternal(). This allows renderer code to request OS handling for arbitrary URI schemes. Add a protocol allowlist check:

handle('open-external', async (_webContents, url) => {
  const parsed = new URL(url);
  if (!['http:', 'https:'].includes(parsed.protocol)) {
    throw new Error(`Unsupported external URL protocol: ${parsed.protocol}`);
  }
  await openExternal(parsed.toString());
});

This pattern is already used elsewhere in the codebase (e.g., src/videoCallWindow/ipc.ts:610-626, src/navigation/main.ts:213-237).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/ipc/channels.ts` at line 134, The 'open-external' IPC handler and the
openExternal() utility currently forward arbitrary URLs to shell.openExternal(),
which allows untrusted URI schemes; update the IPC handler for 'open-external'
and/or the openExternal() function to parse the incoming URL (using new
URL(url)) and validate its protocol against an allowlist (at minimum 'http:' and
'https:'), throwing an error for unsupported protocols and only calling
shell.openExternal() with the validated URL string; reference the
'open-external' handler name and the openExternal() utility/shell.openExternal()
call to locate where to add the check.

src/main.ts Outdated
Comment on lines +148 to +150
handle('open-external', async (_webContents, url) => {
await openExternal(url);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

cd /tmp && find . -name "main.ts" -type f 2>/dev/null | head -5

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 57


🏁 Script executed:

cd /tmp && git ls-files | grep -E "(main\.ts|browserLauncher\.ts|channels\.ts|preload.*api)" | head -20

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 143


🏁 Script executed:

cd /tmp && git ls-files | grep -E "src/.*\.ts$" | head -20

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 143


🏁 Script executed:

find . -type f -name "main.ts" 2>/dev/null

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 461


🏁 Script executed:

find . -type f -name "*.ts" | grep -E "(main|browserLauncher|channels|preload)" | head -20

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 631


🏁 Script executed:

wc -l src/main.ts src/ipc/channels.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 127


🏁 Script executed:

cat -n src/main.ts | sed -n '140,160p'

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 725


🏁 Script executed:

find . -type f -name "browserLauncher.ts"

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 105


🏁 Script executed:

find . -type f -path "*/servers/preload/api.ts"

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 103


🏁 Script executed:

cat -n src/utils/browserLauncher.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 4081


🏁 Script executed:

cat -n src/servers/preload/api.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 3419


🏁 Script executed:

cat -n src/ipc/channels.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 6201


🏁 Script executed:

rg -n "RocketChatDesktop" --type ts --type tsx | head -20

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 102


🏁 Script executed:

find . -type f -name "*.ts" -o -name "*.tsx" | xargs grep -l "servers/preload/api" | head -10

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 91


🏁 Script executed:

find . -type f -name "*.ts" | xargs grep -l "preload.ts" | grep -E "servers|main" | head -10

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 57


🏁 Script executed:

cat -n src/preload.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 3521


🏁 Script executed:

rg "open-external" --type ts -B 2 -A 2

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 656


🏁 Script executed:

cat -n src/servers/preload/openExternal.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 240


🏁 Script executed:

rg "window.location\|navigate\|loadURL\|webContents.loadURL" --type ts -B 2 -A 2 | head -40

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 57


🏁 Script executed:

rg "createWindow\|new BrowserWindow" --type ts -B 2 -A 8 | head -60

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 57


🏁 Script executed:

find . -type f -name "*.ts" | xargs grep -l "server-view\|webview" | head -10

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 372


🏁 Script executed:

cat -n src/ui/main/serverView/index.ts | head -80

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 2912


🏁 Script executed:

wc -l src/ui/main/serverView/index.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 110


🏁 Script executed:

cat -n src/ui/main/serverView/index.ts | grep -A 10 -B 5 "loadURL\|server.url\|Server\['url" | head -80

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 2865


🏁 Script executed:

cat -n src/ui/main/serverView/index.ts | sed -n '200,300p'

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 3703


🏁 Script executed:

cat -n src/ui/main/serverView/index.ts | sed -n '298,400p'

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 3803


🏁 Script executed:

rg "isProtocolAllowed\|OpenExternalPermissionRequest" --type ts -B 3 -A 5

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 57


🏁 Script executed:

cat -n src/ui/main/serverView/index.ts | sed -n '394,420p'

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 919


🏁 Script executed:

find . -type f -name "*.ts" | xargs grep -l "isProtocolAllowed" | head -5

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 200


🏁 Script executed:

rg "export.*isProtocolAllowed" --type ts -B 2 -A 15

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 1071


🏁 Script executed:

cat -n src/navigation/main.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 8205


Use isProtocolAllowed() to validate the URL scheme before delegating to the browser launcher.

This IPC handler forwards a renderer-controlled string directly to shell.openExternal() without any protocol filtering. The codebase already has an isProtocolAllowed() validation function in src/navigation/main.ts that enforces an allowlist (http:, https:, mailto:, plus user-persisted protocols), but this new handler bypasses it entirely. A compromised or malicious renderer (via XSS on a remote Rocket.Chat server) can use window.RocketChatDesktop.openExternal() to trigger arbitrary protocol handlers without user confirmation.

🔒 Suggested fix

Import and use the existing validation:

  import { openExternal } from './utils/browserLauncher';
+ import { isProtocolAllowed } from './navigation/main';
  
  handle('open-external', async (_webContents, url) => {
+   if (!(await isProtocolAllowed(url))) {
+     throw new Error(`Protocol not allowed for URL: ${url}`);
+   }
    await openExternal(url);
  });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
handle('open-external', async (_webContents, url) => {
await openExternal(url);
});
handle('open-external', async (_webContents, url) => {
if (!(await isProtocolAllowed(url))) {
throw new Error(`Protocol not allowed for URL: ${url}`);
}
await openExternal(url);
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main.ts` around lines 148 - 150, The IPC handler registered as
handle('open-external', ...) currently forwards the renderer-provided url
directly to openExternal; change it to first validate the URL scheme with the
existing isProtocolAllowed(url) from src/navigation/main.ts and only call
openExternal when isProtocolAllowed returns true, otherwise reject/return an
error (and optionally log the blocked attempt via your logger). Ensure you
import isProtocolAllowed, perform the check inside the same handler for
'open-external', and avoid calling openExternal or shell.openExternal for
disallowed schemes.

Comment on lines +519 to +531
// Handle renderer process crashes
browserWindow.webContents.on('render-process-gone', async (event, details) => {
console.error('Renderer process crashed:', details.reason);
try {
const session = browserWindow.webContents.session;
await session.clearCache();
await session.clearStorageData();
console.log('Cache cleared. Reloading window...');
browserWindow.reload();
} catch (error) {
console.error('Failed to recover from crash:', error);
}
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\nshowRootWindow call sites:\n'
rg -n -C2 --type=ts '\bshowRootWindow\s*\('

printf '\nrender-process-gone handlers:\n'
rg -n -C2 --type=ts 'render-process-gone'

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 734


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check ESLint/Prettier output for the specific lines
printf '\nChecking file rootWindow.ts for linting status:\n'
cd src/ui/main && wc -l rootWindow.ts

# Get the full showRootWindow function context
printf '\nshowRootWindow function:\n'
rg -A 50 'export const showRootWindow' src/ui/main/rootWindow.ts

# Check getRootWindow implementation
printf '\ngetRootWindow function:\n'
rg -B 5 -A 15 'const getRootWindow\|function getRootWindow' src/ui/main/rootWindow.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 250


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check if there's an ESLint config and run it on the specific lines
printf '\nLinting information for rootWindow.ts:\n'
if [ -f .eslintrc.json ] || [ -f .eslintrc.js ] || [ -f eslint.config.js ]; then
  echo "ESLint config found - detailed analysis needed"
  cat .eslintrc.json 2>/dev/null || cat .eslintrc.js 2>/dev/null || echo "Using eslint.config.js"
fi

# Check the exact code around lines 519-531
printf '\nExact code at lines 515-535:\n'
sed -n '515,535p' src/ui/main/rootWindow.ts | cat -n

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 2582


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Get getRootWindow implementation with more context
printf '\ngetRootWindow implementation:\n'
rg -B 2 -A 20 'const getRootWindow|function getRootWindow' src/ui/main/rootWindow.ts | head -60

# Check if browserWindow is cached/singleton
printf '\nBrowserWindow reference pattern:\n'
rg -n 'let.*browserWindow|var.*browserWindow|const.*browserWindow' src/ui/main/rootWindow.ts | head -20

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 1132


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check if the repository has a lint script or npm commands
printf '\nChecking package.json for lint commands:\n'
grep -A 5 '"scripts"' package.json | grep -i lint

# Try to find/run ESLint directly if available
printf '\nChecking if node_modules has eslint:\n'
if [ -d node_modules ]; then
  ls node_modules/.bin/ | grep -i lint
fi

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 116


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Get full context of showRootWindow function
printf '\nFull showRootWindow function:\n'
rg -A 50 'export const showRootWindow' src/ui/main/rootWindow.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 1555


Guard crash recovery against infinite loops and ensure all relevant session state is cleared.

The handler registered on lines 520-531 lacks safeguards: it triggers recovery (cache/storage wipe and reload) for any render-process-gone event without checking the reason or guarding against re-entry. This can cause infinite reload loops if the crash is persistent. Additionally, clearing only browserWindow.webContents.session misses the per-server persist:${serverUrl} partitions used by main webviews, so persisted state that may have triggered the crash remains intact.

The handler is also registered unconditionally inside showRootWindow() with .on(), which means future refactoring that calls showRootWindow() again would stack multiple handlers. Consider registering the handler only once per window and adding conditions to exit early on clean exits or when recovery is already in progress.

🧰 Tools
🪛 ESLint

[error] 520-520: Replace 'render-process-gone', with ⏎····'render-process-gone',⏎···

(prettier/prettier)


[error] 521-521: Insert ··

(prettier/prettier)


[error] 522-522: Insert ··

(prettier/prettier)


[error] 523-523: Insert ··

(prettier/prettier)


[error] 523-523: Use object destructuring.

(prefer-destructuring)


[error] 524-524: Insert ··

(prettier/prettier)


[error] 525-525: Insert ··

(prettier/prettier)


[error] 526-526: Insert ··

(prettier/prettier)


[error] 527-527: Replace ······ with ········

(prettier/prettier)


[error] 528-528: Insert ··

(prettier/prettier)


[error] 529-529: Replace ······ with ········

(prettier/prettier)


[error] 530-530: Insert ··

(prettier/prettier)


[error] 531-531: Replace ··} with ····}⏎··

(prettier/prettier)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/ui/main/rootWindow.ts` around lines 519 - 531, The render-process-gone
handler registered via browserWindow.webContents.on('render-process-gone') in
showRootWindow() must be made safe: register it only once per window (use
webContents.once or check webContents.listenerCount / a browserWindow property)
and add a recovery-in-progress guard (e.g., a boolean on the BrowserWindow or
closure) to prevent re-entry/infinite reload loops; check details.reason and
bail out early for clean exits or non-recoverable reasons before attempting
recovery; when clearing state, clear both the default session and any persisted
partitions used by your webviews (iterate known server URLs and call
session.fromPartition(`persist:${serverUrl}`) then clearCache/clearStorageData
on each) and ensure you handle and log errors for each session separately.

Comment on lines 53 to 69
export const verifyCertificateInStore = async (
certSha1: string
): Promise<void> => {
core.info('Verifying certificate installation...');
const verifyCertCmd = `powershell -Command "Get-ChildItem -Path 'Cert:\\CurrentUser\\My' | Where-Object { $_.Thumbprint -eq '${certSha1}' } | Select-Object -First 1"`;
const certCheck = await runAndBuffer(verifyCertCmd);

if (!certCheck || certCheck.trim() === '') {
throw new Error(`Certificate with thumbprint ${certSha1} not found in CurrentUser\\My store!`);
throw new Error(
`Certificate with thumbprint ${certSha1} not found in CurrentUser\\My store!`
);
}

core.info(`✅ Certificate found in store with thumbprint: ${certSha1}`);

// Check if certificate has private key (it shouldn't for KMS)
const hasPrivateKeyCmd = `powershell -Command "(Get-ChildItem -Path 'Cert:\\CurrentUser\\My' | Where-Object { $_.Thumbprint -eq '${certSha1}' }).HasPrivateKey"`;
Copy link
Contributor

@coderabbitai coderabbitai bot Mar 9, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Action input definitions for win_kms_cert_sha1:"
fd '^action\.ya?ml$' . -x sed -n '/win_kms_cert_sha1/,+12p' {}

echo
echo "Thumbprint handling in the release action:"
rg -nC2 '\bwin_kms_cert_sha1\b|verifyCertificateInStore|computeThumbprint' workspaces/desktop-release-action

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 6284


🏁 Script executed:

sed -n '21,51p' workspaces/desktop-release-action/src/windows/certificates.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 1021


🏁 Script executed:

# Check for any validation or sanitization before calling verifyCertificateInStore
rg -nB5 -A5 'verifyCertificateInStore\(certSha1\)' workspaces/desktop-release-action/src/windows

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 902


🏁 Script executed:

# Check if there are any workflow files that validate inputs
fd -e yml -e yaml . workspaces/desktop-release-action | xargs grep -l 'win_kms_cert_sha1' | head -5

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 119


Validate the thumbprint before embedding it in PowerShell.

Line 57 and Line 69 interpolate certSha1 directly into powershell -Command. The input comes from either core.getInput('win_kms_cert_sha1') (user-provided, unconstrained) or computeThumbprint() (extracted from cert file). A malformed value—including quotes or special characters—can break command parsing. Since a SHA-1 thumbprint must always be 40 hex characters, local validation is a simple and effective defensive measure.

🛡️ Proposed fix
 export const verifyCertificateInStore = async (
   certSha1: string
 ): Promise<void> => {
+  if (!/^[A-Fa-f0-9]{40}$/.test(certSha1)) {
+    throw new Error(`Invalid certificate thumbprint: ${certSha1}`);
+  }
+
   core.info('Verifying certificate installation...');
   const verifyCertCmd = `powershell -Command "Get-ChildItem -Path 'Cert:\\CurrentUser\\My' | Where-Object { $_.Thumbprint -eq '${certSha1}' } | Select-Object -First 1"`;
   const certCheck = await runAndBuffer(verifyCertCmd);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const verifyCertificateInStore = async (
certSha1: string
): Promise<void> => {
core.info('Verifying certificate installation...');
const verifyCertCmd = `powershell -Command "Get-ChildItem -Path 'Cert:\\CurrentUser\\My' | Where-Object { $_.Thumbprint -eq '${certSha1}' } | Select-Object -First 1"`;
const certCheck = await runAndBuffer(verifyCertCmd);
if (!certCheck || certCheck.trim() === '') {
throw new Error(`Certificate with thumbprint ${certSha1} not found in CurrentUser\\My store!`);
throw new Error(
`Certificate with thumbprint ${certSha1} not found in CurrentUser\\My store!`
);
}
core.info(`✅ Certificate found in store with thumbprint: ${certSha1}`);
// Check if certificate has private key (it shouldn't for KMS)
const hasPrivateKeyCmd = `powershell -Command "(Get-ChildItem -Path 'Cert:\\CurrentUser\\My' | Where-Object { $_.Thumbprint -eq '${certSha1}' }).HasPrivateKey"`;
export const verifyCertificateInStore = async (
certSha1: string
): Promise<void> => {
if (!/^[A-Fa-f0-9]{40}$/.test(certSha1)) {
throw new Error(`Invalid certificate thumbprint: ${certSha1}`);
}
core.info('Verifying certificate installation...');
const verifyCertCmd = `powershell -Command "Get-ChildItem -Path 'Cert:\\CurrentUser\\My' | Where-Object { $_.Thumbprint -eq '${certSha1}' } | Select-Object -First 1"`;
const certCheck = await runAndBuffer(verifyCertCmd);
if (!certCheck || certCheck.trim() === '') {
throw new Error(
`Certificate with thumbprint ${certSha1} not found in CurrentUser\\My store!`
);
}
core.info(`✅ Certificate found in store with thumbprint: ${certSha1}`);
// Check if certificate has private key (it shouldn't for KMS)
const hasPrivateKeyCmd = `powershell -Command "(Get-ChildItem -Path 'Cert:\\CurrentUser\\My' | Where-Object { $_.Thumbprint -eq '${certSha1}' }).HasPrivateKey"`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@workspaces/desktop-release-action/src/windows/certificates.ts` around lines
53 - 69, In verifyCertificateInStore, validate and normalize certSha1 before
building verifyCertCmd/hasPrivateKeyCmd: ensure certSha1 matches a 40-character
hex SHA-1 (e.g. /^[A-Fa-f0-9]{40}$/), convert to a consistent case (upper or
lower) and throw a clear error if invalid, then use the validated value when
constructing the PowerShell commands (this prevents injection or malformed
thumbprints being interpolated into verifyCertCmd and hasPrivateKeyCmd).

Copy link
Author

Choose a reason for hiding this comment

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

Applied eslint/prettier formatting fixes to resolve lint errors.

Copy link
Contributor

Choose a reason for hiding this comment

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

@Ram-sah19, thanks for the update! Just to clarify — the ESLint/Prettier formatting changes in the diff are separate from my suggestion. My comment was specifically about a security concern: certSha1 is interpolated directly into PowerShell command strings (Lines 57 and 69) without any validation. If it contains unexpected characters, it could break command parsing.

The suggested fix was to add a thumbprint format check at the top of verifyCertificateInStore:

export const verifyCertificateInStore = async (
  certSha1: string
): Promise<void> => {
  if (!/^[A-Fa-f0-9]{40}$/.test(certSha1)) {
    throw new Error(`Invalid certificate thumbprint: ${certSha1}`);
  }

  core.info('Verifying certificate installation...');
  // ... rest of function

This validation ensures certSha1 is always a well-formed 40-character hex string before it's embedded into the PowerShell commands. Would you like to apply this change?


🧠 Learnings used
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Applies to **/*.{ts,tsx} : All code must pass ESLint and TypeScript checks

Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Applies to **/*.{ts,tsx} : Write self-documenting code with clear naming; avoid unnecessary comments except for complex business logic or non-obvious decisions

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for the suggestion! Since this change is unrelated to the scope of this PR, I suggest addressing it in a separate PR focused on improving certificate validation.

Copy link
Contributor

Choose a reason for hiding this comment

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

@Ram-sah19, that's completely reasonable — keeping PRs focused is good practice. Would you like me to open a follow-up GitHub issue to track the thumbprint validation improvement so it doesn't get lost?

(¬、¬)


🧠 Learnings used
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Applies to **/*.{ts,tsx} : Write self-documenting code with clear naming; avoid unnecessary comments except for complex business logic or non-obvious decisions

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
src/ui/main/rootWindow.ts (1)

519-534: ⚠️ Potential issue | 🟠 Major

Make renderer crash recovery single-shot and reason-aware.

Line 520 registers this with .on() inside showRootWindow(), so any later call can stack another recovery handler on the same webContents. Combined with unconditional clearStorageData() + reload(), a persistent renderer failure—or even a non-recoverable/clean exit reason—can turn into repeated destructive reload attempts. Register the handler once per window and bail out when recovery is already running or the reason should not be recovered from.

🔧 Suggested fix
-  // Handle renderer process crashes
-  browserWindow.webContents.on(
-    'render-process-gone',
-    async (event, details) => {
-      console.error('Renderer process crashed:', details.reason);
-      try {
-        const session = browserWindow.webContents.session;
-        await session.clearCache();
-        await session.clearStorageData();
-        console.log('Cache cleared. Reloading window...');
-        browserWindow.reload();
-      } catch (error) {
-        console.error('Failed to recover from crash:', error);
-      }
-    }
-  );
+  if (!browserWindow.webContents.listenerCount('render-process-gone')) {
+    let recoveryInProgress = false;
+
+    browserWindow.webContents.on(
+      'render-process-gone',
+      async (_event, { reason }) => {
+        if (recoveryInProgress || reason === 'clean-exit') {
+          return;
+        }
+
+        recoveryInProgress = true;
+        console.error('Renderer process crashed:', reason);
+
+        try {
+          const { session } = browserWindow.webContents;
+          await session.clearCache();
+          await session.clearStorageData();
+          browserWindow.reload();
+        } catch (error) {
+          console.error('Failed to recover from crash:', error);
+        } finally {
+          recoveryInProgress = false;
+        }
+      }
+    );
+  }
#!/bin/bash
set -euo pipefail

printf '\nshowRootWindow call sites:\n'
rg -n -C2 --type=ts '\bshowRootWindow\s*\('

printf '\nCurrent render-process-gone registration in src/ui/main/rootWindow.ts:\n'
sed -n '516,540p' src/ui/main/rootWindow.ts
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/ui/main/rootWindow.ts` around lines 519 - 534, The render-process-gone
handler registered inside showRootWindow uses .on() and unconditionally clears
storage and reloads, which can cause repeated destructive recoveries; change the
registration to be single-shot and reason-aware by using
webContents.once('render-process-gone', ...) or by setting a per-window
"isRecovering" flag on the BrowserWindow to prevent re-entry, inspect the
details.reason (e.g., ignore 'clean-exit' or other non-recoverable reasons) and
only attempt recovery for recoverable reasons, and avoid always calling
session.clearStorageData() (limit to clearCache() or a scoped storage clear)
before calling browserWindow.reload(); ensure the handler removes or disables
itself after running so subsequent showRootWindow calls won't stack recovery
handlers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/ui/main/rootWindow.ts`:
- Around line 519-534: The render-process-gone handler registered inside
showRootWindow uses .on() and unconditionally clears storage and reloads, which
can cause repeated destructive recoveries; change the registration to be
single-shot and reason-aware by using webContents.once('render-process-gone',
...) or by setting a per-window "isRecovering" flag on the BrowserWindow to
prevent re-entry, inspect the details.reason (e.g., ignore 'clean-exit' or other
non-recoverable reasons) and only attempt recovery for recoverable reasons, and
avoid always calling session.clearStorageData() (limit to clearCache() or a
scoped storage clear) before calling browserWindow.reload(); ensure the handler
removes or disables itself after running so subsequent showRootWindow calls
won't stack recovery handlers.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 564baeb5-6eed-42fa-a81c-01a410fb949e

📥 Commits

Reviewing files that changed from the base of the PR and between 92471b9 and 3af92de.

⛔ Files ignored due to path filters (1)
  • workspaces/desktop-release-action/dist/index.js is excluded by !**/dist/**
📒 Files selected for processing (1)
  • src/ui/main/rootWindow.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript strict mode enabled in TypeScript configuration
Use React functional components with hooks instead of class components
Follow FSA (Flux Standard Action) pattern for Redux actions
Use camelCase for file names and PascalCase for component file names
All code must pass ESLint and TypeScript checks
Write self-documenting code with clear naming; avoid unnecessary comments except for complex business logic or non-obvious decisions
Use Fuselage components from @rocket.chat/fuselage for all UI work and only create custom components when Fuselage doesn't provide what's needed
Check Theme.d.ts for valid color tokens when using Fuselage components
Use defensive coding with optional chaining and fallbacks for Linux-only APIs (process.getuid(), process.getgid(), process.geteuid(), process.getegid()) to ensure cross-platform compatibility across Windows, macOS, and Linux

Files:

  • src/ui/main/rootWindow.ts
🪛 ESLint
src/ui/main/rootWindow.ts

[error] 525-525: Use object destructuring.

(prefer-destructuring)

@Ram-sah19 Ram-sah19 changed the base branch from master to develop March 10, 2026 18:47
dougfabris and others added 25 commits March 11, 2026 00:48
…hat#3028)

* perf: Optimize server loading by deferring inactive webviews

* bump version

* remove duplicated code
)

* feat: Close video call window when Jitsi call is closed

* bump version

* only closes on fixed close html jitsi pages
Project Name: Rocket.Chat.Electron
Project Link: https://app.lingohub.com/project/pr_1Ag2Vlx6MWNt-16038/branches/prb_16rm9BiWK53b-4144
User: Robot Lingohub

Easy language translations with Lingohub 🚀

Co-authored-by: lingohub[bot] <69908207+lingohub[bot]@users.noreply.github.com>
* create update channel selection

* fix select

* order channels name

* add translations

* fix lint
* updated electron-builder v26.0.3

* add flipFuses
…#3041)

* feat: support mapping users to exchange servers by domain

* fix: lint error

* chore: simplify and add version gate

* fix: update variable names

* fix version checking on develop versions

* make remember my credentials default true

* improve code

* bump version

* show outlook exchange url on server info panel

---------

Co-authored-by: Jean Brito <jeanfbrito@gmail.com>
Project Name: Rocket.Chat.Electron
Project Link: https://app.lingohub.com/project/pr_1Ag2Vlx6MWNt-16038/branches/prb_16rm9BiWK53b-4144
User: Robot Lingohub

Easy language translations with Lingohub 🚀

Co-authored-by: lingohub[bot] <69908207+lingohub[bot]@users.noreply.github.com>
jeanfbrito and others added 29 commits March 11, 2026 00:48
- Added support for auto-opening developer tools based on state settings in the video call window.
- Updated the video call window to load HTML files with query parameters for URL and auto-open devtools.
- Refactored ScreenSharePicker component to improve UI consistency by changing background color and adjusting color logic for selected sources.
- Improved state management in VideoCallWindow to initialize URL and auto-open devtools settings from query parameters, enhancing user experience.
- Adjusted loading and visibility logic for better handling of error and loading states in the video call interface.
* testing

* macOS: keep Sidebar transparent only; restore normal backgrounds for Shell, content, and webviews. Make body/shell transparent on macOS and paint main content instead; Sidebar uses transparent bg on darwin. Revert global transparent CSS injection.

* transparent topbar

* feat: Add transparent window feature with settings and internationalization support

- Introduced a new feature to enable a transparent window effect, enhancing the visual experience on macOS.
- Updated the state management to include `isTransparentWindowEnabled`.
- Added a new settings component for toggling the transparent window effect.
- Implemented internationalization for the new feature in multiple languages (en, de, es, fr, hu, no, pt-BR, ru, sv).
- Updated the root window creation logic to respect the transparent window setting.

* feat: Enhance transparent window feature with state management and styling updates

- Added support for `isTransparentWindowEnabled` state in the Shell component to manage the transparent window effect.
- Updated GlobalStyles to conditionally set the background color based on the transparency setting and platform.
- Refactored the Wrapper component to apply the transparent background style when enabled.
- Improved the reducer for `isTransparentWindowEnabled` to handle invalid payload types gracefully.
- Introduced platform detection utility to streamline platform-specific logic across components.

* feat(i18n): Add transparent window effect localization for multiple languages

- Introduced translations for the new transparent window effect feature in Arabic, Finnish, Italian, Japanese, Norwegian, Polish, Swedish, Turkish, Ukrainian, and Chinese (Simplified and Traditional).
- Updated the settings structure in each language file to include titles and descriptions for the transparent window option, enhancing user experience across different locales.

* feat(i18n): Add transparent window effect localization in Turkish

- Added Turkish translations for the transparent window effect feature, including title and description.
- Removed the previous settings structure for the transparent window from the settings section, streamlining the localization file.

* fix: Resolve lint errors from master merge

Fixed formatting issues in videoCallWindow files that were introduced in recent master commits.
* feat: Implement Windows executable signing in afterPack hook

- Added functionality to sign Windows executables using jsign and Google Cloud KMS during the afterPack process.
- Introduced environment variable validation for signing credentials and tools.
- Enhanced the build process to ensure executables are signed post-build, improving security and compliance.
- Updated the Windows packaging workflow to include signing steps, ensuring all built packages are properly signed before distribution.

* fix: Update key alias extraction logic in afterPack.js

- Refactored the `extractKeyAlias` function to trim whitespace and adjust the index for extracting the key alias from the KMS resource, ensuring correct parsing of the resource string.
- Improved readability of the code by consolidating the environment variable handling in the signing process for Windows executables.

* refactor: Update afterPack.js to improve Windows executable signing process

- Changed comments for clarity regarding the application path determination for builds.
- Moved Windows executable signing logic to occur before applying security fuses, ensuring proper signing of executables.
- Enhanced error handling during the signing process to prevent build failures if signing fails, improving build resilience.
- Updated logging to provide clearer information about the signing and fusing processes.

* refactor: Revise Windows signing and fusing process in afterPack and notarize scripts

- Consolidated Windows executable signing logic to occur before applying security fuses, ensuring proper signing order.
- Introduced a new function to apply fuses after signing, enhancing clarity in the build process.
- Updated comments and logging for better understanding of the signing and fusing workflow.
- Adjusted environment variable handling to align with the new signing process, improving overall build resilience.
…tChat#3143)

* feat(video-call): Enhance Windows Graphics Capture handling in RDP sessions

- Implemented comprehensive disabling of Windows Graphics Capture (WGC) features to ensure fallback to the Desktop Duplication API during RDP sessions.
- Updated smart restart behavior to provide clearer user guidance when toggling settings in RDP environments.
- Enhanced UI to reflect the current state of WGC settings, including disabling the toggle when in RDP sessions.
- Added technical details on the implementation of disabled Chrome features and their impact on screen capture reliability.

This update improves the user experience and ensures consistent behavior across different session types.

* fix(rollup): Update output directory for preload files

- Changed the output directory for preload files from 'app' to 'app/preload' in the Rollup configuration. This adjustment improves project structure and organization for better clarity in file management.

* fix(i18n): Update Russian translation for video call screen capture fallback

- Revised the forced description for the video call screen capture fallback to enhance clarity and user understanding regarding its behavior in RDP sessions. The new translation provides a more accurate explanation of the feature's functionality and its impact on local launches.

* refactor(videoCall): Clean up code formatting and improve readability

- Reformatted the `loadFile` method call in `ipc.ts` for better readability.
- Removed unnecessary blank line in `video-call-window.tsx`.
- Adjusted visibility logic in `videoCallWindow.tsx` for improved clarity.

* refactor(videoCall): Migrate video call window to TypeScript and enhance error/loading UI

- Renamed `video-call-window.tsx` to `video-call-window.ts` and refactored the component to TypeScript for better type safety.
- Introduced new loading and error overlay components with corresponding CSS for improved user experience during loading and error states.
- Updated the Rollup configuration to reflect the new input file name.
- Adjusted documentation to match the new file naming conventions.

* refactor(videoCall): Simplify ScreenSharePicker component and improve IPC handling

- Removed the onUnmount prop from ScreenSharePicker to keep the component mounted for reuse, enhancing performance.
- Updated IPC event handling to ensure proper visibility management without unmounting the component.
- Cleaned up code formatting for better readability in screenSharePickerMount and video-call-window files.

* refactor(videoCall): Update preload script path in video call window

- Changed the preload script path from using `path.join` to a relative path for improved compatibility and simplicity in the video call window component.

* refactor(videoCall): Enhance ScreenSharePicker and improve preload script handling

- Updated ScreenSharePicker to accept an onMounted prop for better visibility management.
- Improved IPC event handling in screenSharePickerMount to ensure proper visibility state when the component is mounted.
- Refactored video-call-window to construct an absolute path for the preload script, enhancing compatibility with Electron's webview requirements.

* feat(videoCall): Add prewarm capturer cache functionality and enhance video call handling

- Introduced a new IPC event 'video-call-window/prewarm-capturer-cache' to prewarm the desktop capturer cache for improved performance during video calls.
- Updated the video call window to invoke the prewarm cache function on setup, ensuring a smoother user experience.
- Enhanced the ScreenSharePicker and related components for better visibility management and optimized preload script handling.

* feat(videoCall): Enhance video call window and screen sharing flow

- Implemented a vanilla JavaScript bootstrap architecture for the video call window, improving performance and reducing initial load times.
- Introduced a stale-while-revalidate caching mechanism for the desktop capturer, ensuring instant access to cached data while refreshing in the background.
- Enhanced the ScreenSharePicker component with deferred loading, allowing for faster user interactions during screen sharing.
- Updated documentation to reflect architectural changes and improved user experience features, including cache pre-warming and error handling strategies.

* refactor(videoCall): Improve video call webview detection and preload handling

- Enhanced the logic for identifying video call webviews using strict URL parsing and partition checks.
- Implemented a function to resolve and validate preload file paths, ensuring fallback options are available if the primary preload file is missing.
- Updated the ScreenSharePicker component to optimize the useEffect hook for better performance.
- Revised documentation to reflect changes in caching architecture and performance characteristics.

* feat(videoCall): Update screen picker IPC handling and improve URL retrieval logic

- Modified the IPC event for opening the screen picker to return a success status, enhancing error handling.
- Improved URL retrieval logic in the video call window to request the URL via IPC if not provided in query parameters, ensuring a smoother user experience.
- Added comments for clarity and better understanding of the code flow in the video call window and screen share picker components.

* fix(videoCall): Reset screen picker promise on error to prevent stale state

- Added a line to set `screenPickerModulePromise` to null in the error handling block of the screen picker opening function, ensuring that the promise state is reset if an error occurs while attempting to open the screen picker.

* fix(videoCall): Add missing type import for screenPickerModulePromise

- Included a type import for `screenPickerModulePromise` to ensure proper type checking and consistency in the video call window component.

* fix(videoCall): Ensure visibility state is reset on screen share picker mount

- Moved the reset of `shouldShowOnMount` to the callback function to maintain proper visibility management when the screen share picker is shown.

* Fix markdownlint MD040: Add language identifiers to code blocks

* feat(videoCall): Enhance video call webview handling and URL validation

- Added support for both `persist:jitsi-session` and `persist:pexip-session` partitions in video call webviews to ensure proper identification and preload script application.
- Introduced a URL validation function to enforce strict checks on video call URLs, allowing only specific protocols and known hosts, improving security and reliability.
- Updated the preload script path handling for consistency and clarity across components.
- Enhanced the ScreenSharePicker module with a new type definition for better type safety.

* feat(videoCall): Revise video call window documentation and enhance provider support

- Updated the video call window documentation to clarify support for any video conferencing provider, emphasizing the generic, provider-agnostic architecture.
- Enhanced URL validation to remove provider-specific patterns, allowing seamless integration with various video call services.
- Improved the handling of webview partitions to use a generic partition name for all providers, ensuring consistent behavior across different video call implementations.
- Added detailed sections on provider-specific requirements for Jitsi and PEXIP, highlighting necessary components and integration steps.

* fix(videoCall): Simplify webview webpreferences attribute

- Removed the 'nativeWindowOpen=true' option from the webview's webpreferences attribute, streamlining the configuration for improved clarity and consistency.

* feat(notifications): Add category field to notifications for better classification

- Introduced a 'category' field in notification options, allowing notifications to be classified as 'DOWNLOADS' or 'SERVER'.
- Updated various notification creation points across the application to include the new category field, enhancing the organization and handling of notifications.
- Adjusted tests to verify the inclusion of the category in notification payloads, ensuring consistency in notification behavior.

* fix(videoCall): Update webview preferences and partition naming

- Added 'nativeWindowOpen=true' back to the webview's webpreferences attribute for improved popup handling.
- Changed the webview partition name from 'persist:video-call-session' to 'persist:jitsi-session' for better clarity and consistency in session management.

* feat(videoCall): Enhance screen sharing documentation and implement source validation caching

- Updated the screen sharing documentation to include illustrative timings in the example flow.
- Added a new source validation cache mechanism to improve performance by caching the validation of selected sources for 30 seconds.
- Modified the video call window HTML to provide a label for the reload button, enhancing user experience.
- Refactored the video call window logic to limit automatic reload attempts, improving error handling during video call initialization.

* fix(videoCall): Update video call webview handling by removing unused parameters

- Removed the unused `_params.src` parameter from the `isVideoCallWebview` function call to streamline the logic.
- Adjusted the function call to ensure it only uses necessary parameters, improving code clarity and maintainability.
* feat(winSignKms): Skip non-signable file types during Authenticode signing process

- Added logic to skip files with extensions `.appx` and `.zip` in both `signWindowsOnLinux` and `signWindowsOnWindows` functions, improving the efficiency of the signing process by avoiding unnecessary operations on unsupported file types.
- Included console logging to inform users when a file is skipped, enhancing transparency in the signing workflow.

* refactor(winSignKms): Improve console logging for skipped file types

- Enhanced the console logging in both `signWindowsOnLinux` and `signWindowsOnWindows` functions to improve readability by formatting the log messages across multiple lines. This change maintains clarity when informing users about skipped file types during the Authenticode signing process.
RocketChat#3153)

- Upgraded Electron dependency from version 39.2.3 to 39.2.5 to incorporate the latest bug fixes and improvements.
- Updated corresponding entries in yarn.lock to reflect the new Electron version.
* fix: Add Linux ozone platform switch for improved compatibility

- Introduced a command line switch for Linux to set the ozone platform to 'x11', enhancing compatibility with specific environments during Electron startup.

* chore: Bump version to 4.10.1 in package.json

* fix: Add executable arguments for Linux ozone platform compatibility

- Included the `--ozone-platform=x11` argument in the Electron builder configuration to enhance compatibility with specific Linux environments during application startup.
…etChat#3162)

* feat: Enhance Linux support for screen sharing and dependencies

- Added `xdg-desktop-portal` and `xdg-desktop-portal-gtk` as recommended dependencies in the Electron builder configuration for improved screen sharing functionality on Linux.
- Removed the ozone platform switch for `x11` in the Electron startup process and enabled PipeWire screen capture support for Wayland environments.
- Updated the display media request handler to utilize system picker for better user experience during screen sharing.

* chore: Bump version to 4.10.2 in package.json

* feat(videoCall): Implement screen sharing request handling and cleanup logic

- Added a timeout mechanism for screen sharing requests to prevent orphaned listeners.
- Introduced cleanup functions for screen sharing listeners and request states to enhance resource management.
- Improved IPC handling for screen sharing source responses, ensuring proper request tracking and error handling.
- Enhanced user experience by preventing concurrent screen sharing requests and managing listener cleanup effectively.

* fix(videoCall): Improve screen sharing timeout handling and listener cleanup

- Added validation to ensure the screen sharing timeout is only processed for the current request, preventing double-invocation.
- Enhanced cleanup logic to clear timeout references and invoke callbacks appropriately, improving resource management and user experience during screen sharing sessions.

* fix(videoCall): Refactor screen sharing listener cleanup and request completion handling

- Introduced `removeScreenSharingListenerOnly` to streamline listener removal and timeout clearing without altering the pending request state.
- Added `markScreenSharingComplete` to reset request states, allowing new screen sharing requests after completion.
- Enhanced existing cleanup logic to improve resource management and prevent concurrent screen sharing requests.

* feat(gpuFallback): Implement GPU crash detection and fallback mode for Linux

- Added a GPU crash handler to automatically switch to X11 mode if the GPU process crashes during startup.
- Introduced a persistent fallback mode setting to remember the user's choice across sessions.
- Enhanced the settings UI to allow users to control the display server mode, including options for auto-detect, force X11, or disable GPU.
- Updated the application to handle GPU fallback mode changes dynamically, improving user experience and stability on Linux systems.

* fix(app): Adjust crash count condition and preserve command-line arguments on relaunch

- Updated the crash detection logic to trigger fallback mode after exceeding the maximum crash count.
- Enhanced the relaunch functionality to preserve command-line arguments, ensuring user inputs are retained during application restarts.

* feat: Enhance Linux display server support and crash handling

- Added Wayland support to the Electron builder configuration, allowing for improved compatibility with modern Linux environments.
- Updated documentation to reflect auto-detection of display servers for Snap packages, enhancing user clarity.
- Refactored crash detection logic to use a more descriptive variable name and improved logging for better debugging during GPU fallback scenarios.

* refactor(app): Streamline GPU crash handling and fallback logic

- Simplified the GPU crash detection process by consolidating logic for tracking crash counts and managing fallback mode.
- Improved logging for better visibility during relaunch scenarios.
- Ensured that the application preserves command-line arguments when relaunching after a GPU crash.

* docs: Update Linux display server documentation and improve GPU crash recovery details

- Clarified the automatic GPU crash detection and recovery process in the documentation.
- Removed version-specific language for GPU crash recovery to streamline information.
- Enhanced the logging section with standard Chromium flags for better debugging.

* feat(scripts): Add installation and testing scripts for Linux

- Introduced `install-volta.sh` to automate the installation of Volta, ensuring node.js and npm are available for building the project.
- Added `linux-test-deb.sh` for building, installing, and running the Rocket.Chat Desktop .deb package, with options to skip build, install, or run steps.
- Created a README.md to document the usage and functionality of the new scripts, enhancing developer experience and automation for testing on Linux.

* refactor(scripts): Improve error handling in installation and dependency management

- Updated `install-volta.sh` to handle installation errors more gracefully by checking the success of the Volta installation command.
- Enhanced `linux-test-deb.sh` to streamline dependency installation checks and provide clearer error messages if installation fails.
- Refactored the package installation logic to handle dependency issues more effectively, ensuring smoother installation processes.

* feat(linux): Enhance Wayland and X11 support for GPU handling

- Implemented auto-detection of Wayland sessions and added logic to relaunch the app with X11 fallback for stability.
- Updated GPU fallback mode to include 'wayland' as a valid option, allowing users to specify their preferred display server.
- Improved logging for GPU crash handling and display server mode selection, enhancing debugging and user experience on Linux.
- Adjusted screen sharing request handling to utilize XDG portal on Wayland sessions, improving compatibility with modern desktop environments.

* feat(videoCall): Introduce screen picker functionality for enhanced screen sharing

- Implemented a new screen picker system to handle display media requests, improving user experience during screen sharing.
- Created internal and portal picker providers to support different environments, including Linux Wayland and X11.
- Enhanced IPC handling for screen sharing requests, ensuring proper state management and preventing concurrent requests.
- Added initialization and cleanup logic for the screen picker, streamlining resource management and improving performance.

* refactor(videoCall): Improve screen sharing request handling and listener management

- Refactored the internal picker handler to enhance state management during screen sharing requests, preventing concurrent requests and ensuring proper cleanup.
- Improved error handling for screen sharing source validation, including better logging for unavailable sources and request timeouts.
- Streamlined the listener setup and removal process, enhancing resource management and overall performance during screen sharing operations.

* refactor(videoCall): Enhance webview handler setup and error management

- Refactored the setup of webview handlers to use lazy loading for the screen picker module, improving performance and preventing blocking during webview initialization.
- Improved error handling in the display media request handler, ensuring that errors are logged without disrupting the webview loading process.
- Updated the internal picker provider to streamline the handling of display media requests, particularly for Linux environments.

* refactor(gpuFallback): Extend valid fallback modes and improve type safety

- Updated the GPU fallback mode validation to include 'wayland' as a valid option, enhancing compatibility with modern Linux environments.
- Improved type safety in the reducer by refining the type checks for fallback modes, ensuring better error handling and maintainability.

* refactor(gpuFallback): Improve fallback mode handling in reducer

- Updated the GPU fallback mode reducer to return the current state if the provided fallback mode is invalid, enhancing stability and preventing unintended state changes.
- This change ensures that only valid fallback modes are accepted, improving overall type safety and error handling.

* refactor(videoCall): Update display media request handling for improved platform compatibility

- Enhanced comments in the IPC and PortalPickerProvider files to clarify the behavior of the display media request handler across different platforms, particularly focusing on macOS and Linux/Wayland.
- Adjusted the handling of the XDG portal picker to ensure it returns a valid source or an empty array, improving robustness in source selection during screen sharing.

* refactor(config): Clean up whitespace and improve logging consistency

- Removed unnecessary whitespace in rollup configuration and video call window files for better readability.
- Consolidated console log statements in the app setup to enhance clarity and maintain consistency in logging format.
- Improved import organization in screen picker files to follow a more structured format.

* fix(build): Update electron-builder command to include appimage target

- Modified the build command in the pull request workflow to include 'appimage' as a target alongside 'snap' and 'deb', enhancing the packaging options for Linux distributions.

* feat(build): Add AppImage support to pull request workflow

- Updated the pull request build workflow to include the AppImage target in the S3 upload command, expanding the packaging options for Linux distributions.

* fix(build): Correct AppImage file extension in pull request workflow

- Updated the file extension for AppImage in the S3 upload command from '.AppImage' to '.appimage' to ensure proper handling of the file format during the build process.

* fix(build): Add AppImage pattern to pull request workflow file matching

- Updated the file matching patterns in the pull request build workflow to include the AppImage file extension, ensuring proper identification and handling of AppImage artifacts during the build process.

* feat(scripts): Add Linux AppImage testing script

- Introduced a new script for testing the Rocket.Chat Linux AppImage, which includes steps for building, making the AppImage executable, and running it.
- The script provides options to skip build, installation, and execution, along with informative logging for each step.
- Enhanced the relaunch functionality in the app to support AppImage, ensuring reliable relaunch behavior.

* refactor(gpuFallback): Simplify GPU fallback handling and improve logging

- Removed unnecessary session type checks for Wayland, streamlining the logic for determining X11 fallback needs.
- Updated logging messages for clarity when relaunching the app with X11.
- Adjusted the order of GPU crash handler setup to catch early failures more effectively.

* refactor(gpuFallback): Enhance Wayland handling and logging for X11 fallback

- Introduced a check for Wayland sessions in handleLinuxDisplayServer to default to XWayland for stability, addressing potential GPU issues on virtual machines.
- Updated logging messages to clarify the use of XWayland when a Wayland session is detected, improving user guidance on display server settings.
- Removed redundant Wayland session checks from performElectronStartup, streamlining the GPU fallback logic.

* feat(wayland): Enable native Wayland support by default

Use native Wayland when available instead of forcing X11 fallback.
The GPU crash handler will automatically switch to X11 if issues occur.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Address PR review comments

- Remove X11 forcing on Wayland in linux-test-deb.sh (use native Wayland)
- Fix console.log formatting with JSON.stringify in src/main.ts
- Fix misleading success message in test scripts when app exits early
- Remove unnecessary `as any` type assertion in InternalPickerProvider.ts

* fix(linux): Enforce X11 mode on Wayland sessions

Always use X11 (XWayland) on Wayland sessions for stability.
The app automatically relaunches with --ozone-platform=x11
when a Wayland session is detected.

* feat(wayland): Enable native Wayland support by default

Use native Wayland when available instead of forcing X11 fallback.
The GPU crash handler will automatically switch to X11 if issues occur.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(linux): Add proactive GPU detection with X11 fallback

- Remove sentinel file system (crash counting, timing windows)
- Add gpu-info-update listener to detect GPU issues early
- Check gpu_compositing and webgl status for disabled/unavailable states
- Relaunch with --disable-gpu --ozone-platform=x11 when GPU is broken
- Simplify crash handler to immediately trigger fallback on GPU crash

* fix(ci): Fix AppImage upload and PR comment updates

- Fix case sensitivity: rocketchat-*.appimage → rocketchat-*.AppImage
  (AWS CLI on Linux is case-sensitive, file wasn't being uploaded)
- Fix sticky comment header to use simple identifier instead of markdown
- Remove redundant recreate/append flags (defaults work correctly)

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Project Name: Rocket.Chat.Electron
Project Link: https://app.lingohub.com/project/pr_1Ag2Vlx6MWNt-16038/branches/prb_16rm9BiWK53b-4144
User: Lingohub Robot

Easy language translations with Lingohub 🚀

Co-authored-by: lingohub[bot] <69908207+lingohub[bot]@users.noreply.github.com>
- Updated the bundle version in electron-builder.json from 25110 to 26010.
- Incremented the application version in package.json from 4.10.2 to 4.11.0.
- Updated copyright year in LICENSE and package.json from 2025 to 2026.
* feat: Enhance Linux display server detection and fallback logic

- Updated the Linux display server configuration to automatically detect Wayland sessions and fallback to X11 if necessary, preventing crashes during initialization.
- Improved documentation to clarify the automatic detection process and added troubleshooting information for Ubuntu 22.04 LTS users experiencing segfaults.
- Introduced unit tests for the platform detection logic to ensure correct behavior across various session types and manual overrides.

* test: Update logging tests for platform detection

- Refactored logging tests in `app.main.spec.ts` to validate JSON structure of log messages for Wayland and X11 sessions.
- Removed outdated tests for session type handling and improved assertions for log data properties.
- Enhanced clarity in test descriptions to reflect the updated logging behavior during Electron startup.

* refactor(tests): Remove redundant JSON parsing checks in platform detection tests

- Eliminated unnecessary assertions for JSON parsing in the logging tests for Wayland and X11 sessions in `app.main.spec.ts`.
- Streamlined test cases to focus on validating the structure of log data without redundant error handling, enhancing clarity and maintainability.

* fix(linux): add wrapper script to prevent Wayland/X11 crashes (RocketChat#3154)

The app.commandLine.appendSwitch() approach doesn't work because Chromium
initializes before Electron JavaScript runs.

Fix by package type:
- deb/rpm/tar.gz: Wrapper script runs BEFORE binary, detects display server
- Snap: Set allowNativeWayland=false to force X11 via electron-builder
- Flatpak/AppImage: Use electron-builder launcher with X11 fallback

Wrapper script detection logic:
- If XDG_SESSION_TYPE != wayland: force X11
- If WAYLAND_DISPLAY is empty: force X11
- If Wayland socket doesn't exist: force X11
- Otherwise: use native Wayland

Validated on:
- Fedora 42 physical (GTX 1660 Ti) - Wayland native
- Ubuntu 22.04 physical (GTX 1660 Ti) - X11 session
- Fedora 42 VM (no GPU)
- Ubuntu 22.04 VM (no GPU)

All 5 test scenarios pass with fix vs SEGFAULT without.

Closes RocketChat#3154

* docs: add Fedora 42 test results to postmortem

* fix: add Wayland socket existence check and address review feedback

- Add fs.statSync check to verify Wayland socket actually exists
- Add 'socket-not-found' reason when socket is missing
- Remove placeholder dates from timeline in postmortem
- Add tests for socket existence checking

* fix: address review feedback

- Add tests for ELECTRON_OZONE_PLATFORM_HINT env var override
- Fix Snap docs: Auto-detect → Force X11 (allowNativeWayland: false)
- Fix date: January 2025 → January 2026
- Add 'The Solution That Actually Worked' section to postmortem

* chore: bump version to 4.11.1 in package.json

* chore: update Snap configuration to use core22 base

* fix: use defensive coding for Linux-only APIs (VSCode pattern)

Use optional chaining with fallback for process.getuid() instead of
mocking in tests. This is the pattern used by VSCode for cross-platform
compatibility.

Changes:
- app.ts: process.getuid() → process.getuid?.() ?? 1000
- Remove process.getuid mocking from tests (no longer needed)
- Update CLAUDE.md with VSCode pattern and source attribution

* fix: address CodeRabbit review comments

- Fix timeline dates in post-mortem from 2025 to 2026
- Remove incorrect mock of ../actions with electronBuilderJsonInformation
  (electronBuilderJsonInformation is exported from app.ts, not ../actions)

* fix: correct post-mortem completion date from 2025 to 2026
…e validity (RocketChat#3175)

* fix: apply Electron fuses before signing to preserve Windows signature validity

Fixes RocketChat#3174

The Windows executable was showing 'signed but invalid' because fuses were
being applied after signing, which modifies the binary and invalidates
the signature.

Changes:
- Move fuse application from afterSign to afterPack (before signing)
- Add signature verification after each signing step
- Build fails if any signature is invalid

Per Electron docs: fuses must be flipped 'at package time before you
code sign your app' so the OS can verify signature integrity.

* fix: address code review feedback and enable release workflow for PR testing

- Fix backslash escaping in PowerShell command (CodeQL)
- Fix clearTimeout -> clearInterval for setInterval timer
- Use fs.existsSync instead of glob.sync for exact paths
- Temporarily enable build-release workflow for PR testing

* fix: use electron-builder's proven PowerShell signature verification approach

Based on electron-builder's windowsExecutableCodeSignatureVerifier.ts:
- Use -LiteralPath instead of -FilePath (handles paths literally)
- Only escape single quotes (double them)
- Use chcp 65001 for UTF-8 encoding
- Use -NonInteractive -InputFormat None flags
- Check Status === 0 (JSON serialized enum) or 'Valid' for compatibility

Reference: electron-builder/packages/electron-updater/src/windowsExecutableCodeSignatureVerifier.ts

* chore: remove temporary PR trigger from build-release workflow
* feat: Enable alpha release channel support

- Add semver check to prevent showing "downgrades" as updates
- Mark prerelease versions (alpha/beta) as prerelease on GitHub
- Change development branch from 'develop' to 'dev' in workflows
- Add release-tag.ts script for creating release tags
- Add alpha release process documentation

* fix: correct git push command for tags in release-tag script

Use refs/tags/ prefix instead of invalid 'git push origin tag --' syntax.

* chore: Bump version numbers for release

- Updated the bundle version in electron-builder.json from 26010 to 26011.
- Incremented the application version in package.json from 4.11.1 to 4.12.0-alpha.1.
* chore(theme): transparency mode not removing background of server view (RocketChat#3156)

* Language update from Lingohub 🤖 (RocketChat#3165)

Project Name: Rocket.Chat.Electron
Project Link: https://app.lingohub.com/project/pr_1Ag2Vlx6MWNt-16038/branches/prb_16rm9BiWK53b-4144
User: Lingohub Robot

Easy language translations with Lingohub 🚀

Co-authored-by: lingohub[bot] <69908207+lingohub[bot]@users.noreply.github.com>

* feat: Implement user theme preference settings  (RocketChat#3160)

* feat: Implement user theme preference settings and remove legacy theme appearance handling

- Introduced a new `ThemeAppearance` component to manage user theme preferences, allowing selection between 'auto', 'light', and 'dark' themes.
- Updated state management to include `userThemePreference`, replacing the previous `themeAppearance` handling.
- Removed deprecated theme appearance logic from various components and files, streamlining the codebase.
- Added internationalization support for theme appearance settings across multiple languages.
- Enhanced the UI to reflect user-selected theme preferences dynamically.

* fix(i18n): Correct Norwegian translation for theme appearance description

* fix(theme): Validate theme preference values before dispatching

- Updated the `handleChangeTheme` function to include validation for theme preference values, ensuring only 'auto', 'light', or 'dark' are accepted. This change prevents invalid values from being dispatched, enhancing the robustness of the theme management logic.

* refactor(DocumentViewer): Update theme management to utilize Redux state for user preferences

- Replaced the use of `useDarkMode` with Redux selectors to determine the theme based on user preferences and machine theme.
- Enhanced theme logic to support 'auto', 'light', and 'dark' settings, improving the flexibility and responsiveness of the theme management in the DocumentViewer component.

* refactor(DocumentViewer): Simplify theme management by removing Redux dependencies

- Eliminated the use of Redux selectors for theme management in the DocumentViewer component, replacing it with a static 'tint' background and default color settings.
- Streamlined the component's code by removing unnecessary theme logic, enhancing readability and maintainability.

* chore: Clean up code by removing unnecessary blank lines in ThemeAppearance, TransparentWindow, and userThemePreference files

* fix: Address PR review comments and restore API compatibility

- Remove trailing blank lines from ThemeAppearance.tsx, TransparentWindow.tsx, and userThemePreference.ts
- Restore setUserThemeAppearance as no-op function for backwards compatibility with @rocket.chat/desktop-api interface

* fix: resolve 91 security vulnerabilities in dependencies (RocketChat#3173)

* fix: resolve 91 security vulnerabilities in dependencies

- Update axios 1.6.4 -> 1.13.2 (SSRF, DoS, credential leakage)
- Update electron-updater 5.3.0 -> 6.3.9 (code signing bypass)
- Update rollup 4.9.6 -> 4.32.0 (DOM clobbering XSS)
- Update glob 11.0.3 -> 11.1.0 in workspace (command injection)
- Add resolutions for transitive dependencies:
  - cross-spawn, braces, ws, follow-redirects
  - form-data, tar-fs, undici
- Add comprehensive security remediation documentation

* docs: fix markdown lint - add language specifier to code block

* chore: Remove security documentation from repository

Security vulnerability remediation documentation kept locally for reference.

* fix: Issues in German translation (RocketChat#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (RocketChat#3179)

* chore: Upgrade Electron and Node.js versions, update README and package configurations

- Updated Electron dependency from version 39.2.5 to 40.0.0 in package.json and yarn.lock.
- Bumped Node.js version requirements in package.json and devEngines to >=24.11.1.
- Revised README.md to reflect new supported platforms and minimum version requirements.
- Removed deprecated tests related to ELECTRON_OZONE_PLATFORM_HINT in app.main.spec.ts.
- Enhanced documentation for development prerequisites and troubleshooting sections.

* chore: Bump version numbers in configuration files

- Updated the bundle version in electron-builder.json from 26010 to 26011.
- Incremented the application version in package.json from 4.11.1 to 4.12.0.

* docs: Update README to reflect new platform support and installation formats

- Revised the supported platforms section to include additional architectures and installation formats for Windows, macOS, and Linux.
- Updated download links for Microsoft Store and Mac App Store, ensuring accurate access to application sources.

* docs: Revise README layout for download links

- Updated the formatting of download links for Microsoft Store, Mac App Store, and Snap Store to improve visual presentation and accessibility.
- Changed from a div-based layout to a paragraph-based layout with adjusted image sizes for better responsiveness.

* chore: Update @types/node version in package.json and yarn.lock

- Upgraded @types/node from version 16.18.69 to 25.0.10 in both package.json and yarn.lock to ensure compatibility with the latest TypeScript features and improvements.

* chore: Enable alpha releases (RocketChat#3180)

* chore: Upgrade Electron and Node.js versions, update README and package configurations

- Updated Electron dependency from version 39.2.5 to 40.0.0 in package.json and yarn.lock.
- Bumped Node.js version requirements in package.json and devEngines to >=24.11.1.
- Revised README.md to reflect new supported platforms and minimum version requirements.
- Removed deprecated tests related to ELECTRON_OZONE_PLATFORM_HINT in app.main.spec.ts.
- Enhanced documentation for development prerequisites and troubleshooting sections.

* chore: Bump version numbers in configuration files

- Updated the bundle version in electron-builder.json from 26010 to 26011.
- Incremented the application version in package.json from 4.11.1 to 4.12.0.

* docs: Update README to reflect new platform support and installation formats

- Revised the supported platforms section to include additional architectures and installation formats for Windows, macOS, and Linux.
- Updated download links for Microsoft Store and Mac App Store, ensuring accurate access to application sources.

* docs: Revise README layout for download links

- Updated the formatting of download links for Microsoft Store, Mac App Store, and Snap Store to improve visual presentation and accessibility.
- Changed from a div-based layout to a paragraph-based layout with adjusted image sizes for better responsiveness.

* docs: Add alpha release process documentation

- Introduced a new document detailing the alpha release process for the Rocket.Chat Desktop app, including channel definitions, versioning guidelines, and steps for creating and publishing alpha releases.
- Included instructions for users to opt into the alpha channel and troubleshooting tips for common issues.

* chore: Update architecture support and Node.js version requirements

- Added 'arm64' architecture support to the build targets in electron-builder.json for NSIS, MSI, and ZIP formats.
- Lowered the minimum Node.js version requirement in package.json from >=24.11.1 to >=20.0.0 for better compatibility.

* chore: Change develop branch to dev for release workflow

Update build-release workflow and desktop-release-action to use 'dev'
branch instead of 'develop' for development releases.

* chore: Update versioning and add release tag script

- Bumped version in package.json to 4.12.0.alpha.1.
- Added scripts/release-tag.ts for automated release tagging.
- Updated .eslintignore to exclude the new scripts directory.

* chore: Correct version format in package.json

- Updated version format in package.json from "4.12.0.alpha.1" to "4.12.0-alpha.1" for consistency.

* chore: Update all workflows to use dev branch instead of develop

- validate-pr.yml: Add dev to PR target branches
- powershell-lint.yml: Change develop to dev
- pull-request-build.yml: Change develop to dev

* fix: Normalize tags for consistent comparison in release-tag script

Strip leading 'v' prefix when comparing tags to handle both v-prefixed
and non-prefixed tag formats consistently.

* chore: Increment bundle version in electron-builder.json to 26012

* chore: Address nitpick comments in release-tag script

- Add comment explaining why /scripts is excluded from eslint
- Return null on exec error to distinguish from empty output
- Add warning when git tag list fails
- Use -- separator in git commands for safety

* fix: Add jsign to GITHUB_PATH in Windows CI setup

The jsign tool was being installed but not added to PATH for subsequent
steps. This caused the "Verify tools" step to fail with "jsign not found".

* chore: Bump version to 4.12.0-alpha.2

- Updated version in package.json to 4.12.0-alpha.2
- Incremented bundleVersion in electron-builder.json to 26013

* docs: Add QA testing guide for alpha channel updates

* docs: Rename alpha docs to pre-release and fix workflow concurrency

- Rename alpha-release-process.md to pre-release-process.md
- Add beta release documentation
- Add detailed channel switching instructions
- Fix concurrency group using github.ref instead of github.head_ref
  (github.head_ref is empty for push events, causing tag builds to cancel)

* fix: address code review feedback for 4.12.0 release

- Fix duplicate 'settings' key in ja.i18n.json breaking JSON parsing
- Fix extra space before comma in de-DE.i18n.json
- Add theme value validation in userThemePreference reducer
- Add Windows-safe release:tag:win script variant
- Update Volta yarn version to match packageManager (4.6.0)
- Add fallback jsign discovery in CI workflow
- Fix pre-release terminology consistency in docs
- Use execFileSync for shell safety in release-tag.ts
- Improve README sentence structure variety

* fix: address additional code review feedback

- Remove duplicate tag push in release-tag.ts (would fail on second attempt)
- Fix duplicate content and malformed code block in pre-release docs
- Add missing Windows architectures (ia32, arm64) to PR build workflow
- Add exit 1 after jsign Write-Error for fail-fast behavior

---------

Co-authored-by: Rodrigo Nascimento <rodrigoknascimento@gmail.com>
Co-authored-by: lingohub[bot] <69908207+lingohub[bot]@users.noreply.github.com>
Co-authored-by: Max Lee <max@themoep.de>
…cketChat#3187)

* chore(theme): transparency mode not removing background of server view (RocketChat#3156)

* Language update from Lingohub 🤖 (RocketChat#3165)

Project Name: Rocket.Chat.Electron
Project Link: https://app.lingohub.com/project/pr_1Ag2Vlx6MWNt-16038/branches/prb_16rm9BiWK53b-4144
User: Lingohub Robot

Easy language translations with Lingohub 🚀

Co-authored-by: lingohub[bot] <69908207+lingohub[bot]@users.noreply.github.com>

* feat: Implement user theme preference settings  (RocketChat#3160)

* feat: Implement user theme preference settings and remove legacy theme appearance handling

- Introduced a new `ThemeAppearance` component to manage user theme preferences, allowing selection between 'auto', 'light', and 'dark' themes.
- Updated state management to include `userThemePreference`, replacing the previous `themeAppearance` handling.
- Removed deprecated theme appearance logic from various components and files, streamlining the codebase.
- Added internationalization support for theme appearance settings across multiple languages.
- Enhanced the UI to reflect user-selected theme preferences dynamically.

* fix(i18n): Correct Norwegian translation for theme appearance description

* fix(theme): Validate theme preference values before dispatching

- Updated the `handleChangeTheme` function to include validation for theme preference values, ensuring only 'auto', 'light', or 'dark' are accepted. This change prevents invalid values from being dispatched, enhancing the robustness of the theme management logic.

* refactor(DocumentViewer): Update theme management to utilize Redux state for user preferences

- Replaced the use of `useDarkMode` with Redux selectors to determine the theme based on user preferences and machine theme.
- Enhanced theme logic to support 'auto', 'light', and 'dark' settings, improving the flexibility and responsiveness of the theme management in the DocumentViewer component.

* refactor(DocumentViewer): Simplify theme management by removing Redux dependencies

- Eliminated the use of Redux selectors for theme management in the DocumentViewer component, replacing it with a static 'tint' background and default color settings.
- Streamlined the component's code by removing unnecessary theme logic, enhancing readability and maintainability.

* chore: Clean up code by removing unnecessary blank lines in ThemeAppearance, TransparentWindow, and userThemePreference files

* fix: Address PR review comments and restore API compatibility

- Remove trailing blank lines from ThemeAppearance.tsx, TransparentWindow.tsx, and userThemePreference.ts
- Restore setUserThemeAppearance as no-op function for backwards compatibility with @rocket.chat/desktop-api interface

* fix: resolve 91 security vulnerabilities in dependencies (RocketChat#3173)

* fix: resolve 91 security vulnerabilities in dependencies

- Update axios 1.6.4 -> 1.13.2 (SSRF, DoS, credential leakage)
- Update electron-updater 5.3.0 -> 6.3.9 (code signing bypass)
- Update rollup 4.9.6 -> 4.32.0 (DOM clobbering XSS)
- Update glob 11.0.3 -> 11.1.0 in workspace (command injection)
- Add resolutions for transitive dependencies:
  - cross-spawn, braces, ws, follow-redirects
  - form-data, tar-fs, undici
- Add comprehensive security remediation documentation

* docs: fix markdown lint - add language specifier to code block

* chore: Remove security documentation from repository

Security vulnerability remediation documentation kept locally for reference.

* fix: Issues in German translation (RocketChat#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (RocketChat#3179)

* chore: Upgrade Electron and Node.js versions, update README and package configurations

- Updated Electron dependency from version 39.2.5 to 40.0.0 in package.json and yarn.lock.
- Bumped Node.js version requirements in package.json and devEngines to >=24.11.1.
- Revised README.md to reflect new supported platforms and minimum version requirements.
- Removed deprecated tests related to ELECTRON_OZONE_PLATFORM_HINT in app.main.spec.ts.
- Enhanced documentation for development prerequisites and troubleshooting sections.

* chore: Bump version numbers in configuration files

- Updated the bundle version in electron-builder.json from 26010 to 26011.
- Incremented the application version in package.json from 4.11.1 to 4.12.0.

* docs: Update README to reflect new platform support and installation formats

- Revised the supported platforms section to include additional architectures and installation formats for Windows, macOS, and Linux.
- Updated download links for Microsoft Store and Mac App Store, ensuring accurate access to application sources.

* docs: Revise README layout for download links

- Updated the formatting of download links for Microsoft Store, Mac App Store, and Snap Store to improve visual presentation and accessibility.
- Changed from a div-based layout to a paragraph-based layout with adjusted image sizes for better responsiveness.

* chore: Update @types/node version in package.json and yarn.lock

- Upgraded @types/node from version 16.18.69 to 25.0.10 in both package.json and yarn.lock to ensure compatibility with the latest TypeScript features and improvements.

* chore: Enable alpha releases (RocketChat#3180)

* chore: Upgrade Electron and Node.js versions, update README and package configurations

- Updated Electron dependency from version 39.2.5 to 40.0.0 in package.json and yarn.lock.
- Bumped Node.js version requirements in package.json and devEngines to >=24.11.1.
- Revised README.md to reflect new supported platforms and minimum version requirements.
- Removed deprecated tests related to ELECTRON_OZONE_PLATFORM_HINT in app.main.spec.ts.
- Enhanced documentation for development prerequisites and troubleshooting sections.

* chore: Bump version numbers in configuration files

- Updated the bundle version in electron-builder.json from 26010 to 26011.
- Incremented the application version in package.json from 4.11.1 to 4.12.0.

* docs: Update README to reflect new platform support and installation formats

- Revised the supported platforms section to include additional architectures and installation formats for Windows, macOS, and Linux.
- Updated download links for Microsoft Store and Mac App Store, ensuring accurate access to application sources.

* docs: Revise README layout for download links

- Updated the formatting of download links for Microsoft Store, Mac App Store, and Snap Store to improve visual presentation and accessibility.
- Changed from a div-based layout to a paragraph-based layout with adjusted image sizes for better responsiveness.

* docs: Add alpha release process documentation

- Introduced a new document detailing the alpha release process for the Rocket.Chat Desktop app, including channel definitions, versioning guidelines, and steps for creating and publishing alpha releases.
- Included instructions for users to opt into the alpha channel and troubleshooting tips for common issues.

* chore: Update architecture support and Node.js version requirements

- Added 'arm64' architecture support to the build targets in electron-builder.json for NSIS, MSI, and ZIP formats.
- Lowered the minimum Node.js version requirement in package.json from >=24.11.1 to >=20.0.0 for better compatibility.

* chore: Change develop branch to dev for release workflow

Update build-release workflow and desktop-release-action to use 'dev'
branch instead of 'develop' for development releases.

* chore: Update versioning and add release tag script

- Bumped version in package.json to 4.12.0.alpha.1.
- Added scripts/release-tag.ts for automated release tagging.
- Updated .eslintignore to exclude the new scripts directory.

* chore: Correct version format in package.json

- Updated version format in package.json from "4.12.0.alpha.1" to "4.12.0-alpha.1" for consistency.

* chore: Update all workflows to use dev branch instead of develop

- validate-pr.yml: Add dev to PR target branches
- powershell-lint.yml: Change develop to dev
- pull-request-build.yml: Change develop to dev

* fix: Normalize tags for consistent comparison in release-tag script

Strip leading 'v' prefix when comparing tags to handle both v-prefixed
and non-prefixed tag formats consistently.

* chore: Increment bundle version in electron-builder.json to 26012

* chore: Address nitpick comments in release-tag script

- Add comment explaining why /scripts is excluded from eslint
- Return null on exec error to distinguish from empty output
- Add warning when git tag list fails
- Use -- separator in git commands for safety

* fix: Add jsign to GITHUB_PATH in Windows CI setup

The jsign tool was being installed but not added to PATH for subsequent
steps. This caused the "Verify tools" step to fail with "jsign not found".

* chore: Bump version to 4.12.0-alpha.2

- Updated version in package.json to 4.12.0-alpha.2
- Incremented bundleVersion in electron-builder.json to 26013

* docs: Add QA testing guide for alpha channel updates

* docs: Rename alpha docs to pre-release and fix workflow concurrency

- Rename alpha-release-process.md to pre-release-process.md
- Add beta release documentation
- Add detailed channel switching instructions
- Fix concurrency group using github.ref instead of github.head_ref
  (github.head_ref is empty for push events, causing tag builds to cancel)

* feat(outlook): add @ewsjs/xhr debugging patches

Add comprehensive NTLM authentication debugging to @ewsjs/xhr library:

- patches-src/ directory structure for maintainable patches
- Enhanced ntlmProvider.ts with detailed NTLM handshake logging
- Enhanced xhrApi.ts with HTTP request/response debugging
- Yarn patch resolution for @ewsjs/xhr@2.0.2
- apply-patches.sh script for regenerating patches

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-Claude)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* feat(outlook): add type definitions for calendar sync

Add error-related type definitions to support error classification:

- ErrorSource: exchange, rocket_chat, desktop_app, network, authentication, configuration
- ErrorSeverity: low, medium, high, critical
- OutlookCalendarError: full error object with context
- ErrorClassification: pattern matching result type

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-Claude)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* feat(outlook): add error classification system

Add comprehensive error classification for Outlook calendar sync:

- Pattern-based error detection for Exchange, Rocket.Chat, and desktop errors
- Automatic severity and source classification
- User-friendly error messages with suggested actions
- Structured logging format for debugging
- Support for NTLM auth, network, SSL, and credential errors

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-Claude)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* feat(outlook): enhance calendar sync with debugging and mutex

* test(outlook): add tests for getOutlookEvents

* feat(outlook): add logging infrastructure for calendar debugging

* chore: fix linting issues for Outlook calendar debugging

- Exclude patches-src/ from eslint (not part of main build)
- Fix has-credentials handler return type to match expected signature

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-Claude)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: address CodeRabbit review issues for Outlook calendar

- Fix console transport recursion by using originalConsole in writeFn
- Fix infinite recursion in redactObject using destructuring
- Remove NTLM Type 3 message logging (contains credentials)
- Fix queued sync promises never resolving by tracking resolve/reject
- Fix unhandled async errors in preload using .then().catch()
- Accept HTTP 2xx status codes instead of only 200
- Fix URL validation to check pathname instead of full URL
- Update tests to match actual implementation behavior

* feat(settings): add Developer tab with verbose Outlook logging toggle

- Add Developer tab in Settings (only visible when developer mode enabled)
- Add verbose Outlook logging toggle to control [OutlookCalendar] console output
- Add colored console output for better visibility on dark themes
- Redirect to General tab when developer mode disabled while on Developer tab
- Create centralized logger (outlookLog, outlookError, etc.) in src/outlookCalendar/logger.ts
- Convert all direct console.log calls to use centralized logger
- Fix infinite recursion bug in patches (verboseLog calling itself)
- Add AGENTS.md documentation files for knowledge management
- Use theme-aware colors for Settings UI text

* fix(ci): remove conflicting patch-package patch for @ewsjs/xhr

The @ewsjs/xhr package is already patched via Yarn's patch protocol
(.yarn/patches/). The patch-package patch was accidentally added and
conflicts with the already-applied Yarn patch, causing CI failures.

* docs: add patching mechanism documentation to AGENTS.md

Clarify that @ewsjs/xhr uses Yarn patch protocol (.yarn/patches/)
while patch-package (patches/) is only for other packages.
This prevents accidental CI breakage from conflicting patches.

* fix: address CodeRabbit review comments

- logger.ts: Use shared prefix constants instead of duplicating strings
- getOutlookEvents.ts: Replace Promise.reject() with throw statements
- getOutlookEvents.ts: Route console.error through outlookError
- ipc.ts: Route all console.* through outlookLog/outlookWarn/outlookError
- ipc.ts: Replace Promise.reject(e) with throw e
- AGENTS.md: Fix markdown formatting and update versions

* fix(outlook): address CodeRabbit review issues

- Add JSDoc to syncEventsWithRocketChatServer documenting sync coalescing
- Remove isSyncInProgress check in initial sync (let queue handle it)
- Remove logging implementation details test (tested console.log colors)

* chore: remove unused patches-src directory

The debugging code in patches-src/ was never applied - only the minimal
bug fix in .yarn/patches/ is used. Removing dead code to avoid confusion.

* fix: address all code review issues from PR RocketChat#3187 review

CRITICAL fixes:
- Support multi-server sync state (Map instead of globals)
- Fix Promise<Promise<boolean>> return type
- Use JSON.stringify for safe string escaping in executeJavaScript

MAJOR fixes:
- Add RocketChat calendar event types for type safety
- CRUD operations now return {success, error?} instead of swallowing errors
- Replace sync fs.appendFileSync with async fs.promises.appendFile
- Add useId() and htmlFor for accessibility in ThemeAppearance
- Apply privacy redaction to all transports (not just file)

MINOR fixes:
- Extract magic numbers to named constants
- Extract duplicate buildEwsPathname helper function
- Remove unused _context parameter from classifyError
- Remove fire-and-forget connectivity test calls
- Add originalConsole fallback in preload logging
- Optimize getComponentContext to skip stack trace for log/info/debug
- Fix email regex typo: [A-Z|a-z] -> [A-Za-z]
- Fix double timestamp in createClassifiedError
- Replace inline style with Fuselage pt prop

* fix(outlook): fix race condition in sync queue processing

Changed 'if' to 'while' loop to ensure all queued syncs are processed.
Previously, syncs queued while lastSync.run() was executing would be lost
because the queue was cleared before processing started.

* fix: address additional code review issues

- Fix pool exhaustion bug in context.ts: add overflow counter fallback
  when availableServerIds is depleted, emit warning with diagnostics
- Fix PII leak in ipc.ts error logging: move sensitive fields (subject,
  responseData) to verbose-only outlookLog calls at 5 locations
- Fix silent failure in performSync: throw error instead of silent
  return when eventsOnRocketChatServer fetch fails

* fix(logging): add captureComponentStack parameter to getLogContext

Allows callers to opt into stack-based component detection by passing
captureComponentStack=true, while preserving default behavior.

---------

Co-authored-by: Rodrigo Nascimento <rodrigoknascimento@gmail.com>
Co-authored-by: lingohub[bot] <69908207+lingohub[bot]@users.noreply.github.com>
Co-authored-by: Max Lee <max@themoep.de>
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…Chat#3186)

* chore(theme): transparency mode not removing background of server view (RocketChat#3156)

* Language update from Lingohub 🤖 (RocketChat#3165)

Project Name: Rocket.Chat.Electron
Project Link: https://app.lingohub.com/project/pr_1Ag2Vlx6MWNt-16038/branches/prb_16rm9BiWK53b-4144
User: Lingohub Robot

Easy language translations with Lingohub 🚀

Co-authored-by: lingohub[bot] <69908207+lingohub[bot]@users.noreply.github.com>

* feat: Implement user theme preference settings  (RocketChat#3160)

* feat: Implement user theme preference settings and remove legacy theme appearance handling

- Introduced a new `ThemeAppearance` component to manage user theme preferences, allowing selection between 'auto', 'light', and 'dark' themes.
- Updated state management to include `userThemePreference`, replacing the previous `themeAppearance` handling.
- Removed deprecated theme appearance logic from various components and files, streamlining the codebase.
- Added internationalization support for theme appearance settings across multiple languages.
- Enhanced the UI to reflect user-selected theme preferences dynamically.

* fix(i18n): Correct Norwegian translation for theme appearance description

* fix(theme): Validate theme preference values before dispatching

- Updated the `handleChangeTheme` function to include validation for theme preference values, ensuring only 'auto', 'light', or 'dark' are accepted. This change prevents invalid values from being dispatched, enhancing the robustness of the theme management logic.

* refactor(DocumentViewer): Update theme management to utilize Redux state for user preferences

- Replaced the use of `useDarkMode` with Redux selectors to determine the theme based on user preferences and machine theme.
- Enhanced theme logic to support 'auto', 'light', and 'dark' settings, improving the flexibility and responsiveness of the theme management in the DocumentViewer component.

* refactor(DocumentViewer): Simplify theme management by removing Redux dependencies

- Eliminated the use of Redux selectors for theme management in the DocumentViewer component, replacing it with a static 'tint' background and default color settings.
- Streamlined the component's code by removing unnecessary theme logic, enhancing readability and maintainability.

* chore: Clean up code by removing unnecessary blank lines in ThemeAppearance, TransparentWindow, and userThemePreference files

* fix: Address PR review comments and restore API compatibility

- Remove trailing blank lines from ThemeAppearance.tsx, TransparentWindow.tsx, and userThemePreference.ts
- Restore setUserThemeAppearance as no-op function for backwards compatibility with @rocket.chat/desktop-api interface

* fix: resolve 91 security vulnerabilities in dependencies (RocketChat#3173)

* fix: resolve 91 security vulnerabilities in dependencies

- Update axios 1.6.4 -> 1.13.2 (SSRF, DoS, credential leakage)
- Update electron-updater 5.3.0 -> 6.3.9 (code signing bypass)
- Update rollup 4.9.6 -> 4.32.0 (DOM clobbering XSS)
- Update glob 11.0.3 -> 11.1.0 in workspace (command injection)
- Add resolutions for transitive dependencies:
  - cross-spawn, braces, ws, follow-redirects
  - form-data, tar-fs, undici
- Add comprehensive security remediation documentation

* docs: fix markdown lint - add language specifier to code block

* chore: Remove security documentation from repository

Security vulnerability remediation documentation kept locally for reference.

* fix: Issues in German translation (RocketChat#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (RocketChat#3179)

* chore: Upgrade Electron and Node.js versions, update README and package configurations

- Updated Electron dependency from version 39.2.5 to 40.0.0 in package.json and yarn.lock.
- Bumped Node.js version requirements in package.json and devEngines to >=24.11.1.
- Revised README.md to reflect new supported platforms and minimum version requirements.
- Removed deprecated tests related to ELECTRON_OZONE_PLATFORM_HINT in app.main.spec.ts.
- Enhanced documentation for development prerequisites and troubleshooting sections.

* chore: Bump version numbers in configuration files

- Updated the bundle version in electron-builder.json from 26010 to 26011.
- Incremented the application version in package.json from 4.11.1 to 4.12.0.

* docs: Update README to reflect new platform support and installation formats

- Revised the supported platforms section to include additional architectures and installation formats for Windows, macOS, and Linux.
- Updated download links for Microsoft Store and Mac App Store, ensuring accurate access to application sources.

* docs: Revise README layout for download links

- Updated the formatting of download links for Microsoft Store, Mac App Store, and Snap Store to improve visual presentation and accessibility.
- Changed from a div-based layout to a paragraph-based layout with adjusted image sizes for better responsiveness.

* chore: Update @types/node version in package.json and yarn.lock

- Upgraded @types/node from version 16.18.69 to 25.0.10 in both package.json and yarn.lock to ensure compatibility with the latest TypeScript features and improvements.

* chore: Enable alpha releases (RocketChat#3180)

* chore: Upgrade Electron and Node.js versions, update README and package configurations

- Updated Electron dependency from version 39.2.5 to 40.0.0 in package.json and yarn.lock.
- Bumped Node.js version requirements in package.json and devEngines to >=24.11.1.
- Revised README.md to reflect new supported platforms and minimum version requirements.
- Removed deprecated tests related to ELECTRON_OZONE_PLATFORM_HINT in app.main.spec.ts.
- Enhanced documentation for development prerequisites and troubleshooting sections.

* chore: Bump version numbers in configuration files

- Updated the bundle version in electron-builder.json from 26010 to 26011.
- Incremented the application version in package.json from 4.11.1 to 4.12.0.

* docs: Update README to reflect new platform support and installation formats

- Revised the supported platforms section to include additional architectures and installation formats for Windows, macOS, and Linux.
- Updated download links for Microsoft Store and Mac App Store, ensuring accurate access to application sources.

* docs: Revise README layout for download links

- Updated the formatting of download links for Microsoft Store, Mac App Store, and Snap Store to improve visual presentation and accessibility.
- Changed from a div-based layout to a paragraph-based layout with adjusted image sizes for better responsiveness.

* docs: Add alpha release process documentation

- Introduced a new document detailing the alpha release process for the Rocket.Chat Desktop app, including channel definitions, versioning guidelines, and steps for creating and publishing alpha releases.
- Included instructions for users to opt into the alpha channel and troubleshooting tips for common issues.

* chore: Update architecture support and Node.js version requirements

- Added 'arm64' architecture support to the build targets in electron-builder.json for NSIS, MSI, and ZIP formats.
- Lowered the minimum Node.js version requirement in package.json from >=24.11.1 to >=20.0.0 for better compatibility.

* chore: Change develop branch to dev for release workflow

Update build-release workflow and desktop-release-action to use 'dev'
branch instead of 'develop' for development releases.

* chore: Update versioning and add release tag script

- Bumped version in package.json to 4.12.0.alpha.1.
- Added scripts/release-tag.ts for automated release tagging.
- Updated .eslintignore to exclude the new scripts directory.

* chore: Correct version format in package.json

- Updated version format in package.json from "4.12.0.alpha.1" to "4.12.0-alpha.1" for consistency.

* chore: Update all workflows to use dev branch instead of develop

- validate-pr.yml: Add dev to PR target branches
- powershell-lint.yml: Change develop to dev
- pull-request-build.yml: Change develop to dev

* fix: Normalize tags for consistent comparison in release-tag script

Strip leading 'v' prefix when comparing tags to handle both v-prefixed
and non-prefixed tag formats consistently.

* chore: Increment bundle version in electron-builder.json to 26012

* chore: Address nitpick comments in release-tag script

- Add comment explaining why /scripts is excluded from eslint
- Return null on exec error to distinguish from empty output
- Add warning when git tag list fails
- Use -- separator in git commands for safety

* fix: Add jsign to GITHUB_PATH in Windows CI setup

The jsign tool was being installed but not added to PATH for subsequent
steps. This caused the "Verify tools" step to fail with "jsign not found".

* chore: Bump version to 4.12.0-alpha.2

- Updated version in package.json to 4.12.0-alpha.2
- Incremented bundleVersion in electron-builder.json to 26013

* docs: Add QA testing guide for alpha channel updates

* docs: Rename alpha docs to pre-release and fix workflow concurrency

- Rename alpha-release-process.md to pre-release-process.md
- Add beta release documentation
- Add detailed channel switching instructions
- Fix concurrency group using github.ref instead of github.head_ref
  (github.head_ref is empty for push events, causing tag builds to cancel)

* feat(logging): add scoped logging infrastructure

* feat(log-viewer): add log viewer window and components

* build: add log viewer window build configuration

* feat: integrate logging and log viewer into app lifecycle

* feat: add log viewer IPC channels and menu item

* feat: add i18n translations and fix UI color tokens

* chore: add logging dependencies and fix type error

* fix: address code review feedback

- Add 'silly' log level to LogLevel type for electron-log compatibility
- Fix duplicate server IDs by using overflow counter instead of MAX_SERVER_ID
- Reset startInProgress flag when retry count exceeded in preload
- Add statLog to log viewer preload API
- Use contextIsolation and preload script for log viewer window security
- Replace direct ipcRenderer usage with window.logViewerAPI in renderer

* revert: restore log viewer window settings and add architecture guidelines

- Revert nodeIntegration/contextIsolation changes that broke log viewer
- Add CLAUDE.md guidelines to prevent destructive architecture changes
- Document that existing code patterns exist for specific reasons

* fix: address code review feedback from CodeRabbit

This commit addresses three major review comments:

1. Remove unused preload script for log viewer window
   - The preload.ts was built but never wired to the BrowserWindow
   - Current implementation uses nodeIntegration: true and contextIsolation: false
   - Removed unused build entry from rollup.config.mjs
   - Deleted unused src/logViewerWindow/preload.ts file

2. Guard programmatic scrolls to prevent disabling auto-scroll
   - Added isAutoScrollingRef to track programmatic vs user-initiated scrolls
   - Set flag before calling scrollToIndex and reset after
   - handleScroll now returns early if scroll is programmatic
   - Prevents auto-scroll from being disabled when virtuosoRef.scrollToIndex triggers onScroll

3. Don't swallow startup failures - exit after logging
   - Changed start().catch(console.error) to properly log error and exit
   - Uses logger.error for structured logging
   - Calls app.exit(1) to prevent partial initialization
   - Prevents app running in broken state after critical failures

4. Add error handling to log viewer menu item
   - Wrapped openLogViewer click handler in try-catch
   - Matches pattern used by videoCallDevTools menu item
   - Logs errors to console for debugging

* fix(log-viewer): guard against non-positive limits in getLastNEntries

Return empty content when limit <= 0 to prevent undefined behavior
from negative slice indices.

---------

Co-authored-by: Rodrigo Nascimento <rodrigoknascimento@gmail.com>
Co-authored-by: lingohub[bot] <69908207+lingohub[bot]@users.noreply.github.com>
Co-authored-by: Max Lee <max@themoep.de>
…ketChat#3206)

* fix: guard store functions against pre-initialization calls on macOS Tahoe

On macOS 26.x (Tahoe), the IPC call to retrieve the server URL is slower
than on earlier macOS versions, causing the preload to retry with a 1-second
delay. During this window the RC webapp loads and calls
`window.RocketChatDesktop.setTitle()` and `setUserPresenceDetection()`, which
internally invoke `dispatch()` and `listen()` from the Redux store before
`createRendererReduxStore()` has completed. Since `reduxStore` is still
`undefined`, accessing `.dispatch` or `.subscribe` throws a TypeError that
propagates back through contextBridge into the React tree, crashing the app
with "The application GUI just crashed".

Fix: add null guards to `dispatch`, `dispatchSingle`, `dispatchLocal`,
`watch`, and `listen` so they silently no-op instead of throwing when the
store is not yet initialized. The webapp reactively re-fires these calls
once the app is fully ready, so no state is permanently lost.

Also guard `request()` to reject immediately with a clear error rather than
returning a hung Promise that never resolves, preventing potential memory
leaks if `createNotification()` is called before store init.

Simplify the `getInternalVideoChatWindowEnabled` selector as a drive-by.

* fix: add safeSelect for preload context and guard getInternalVideoChatWindowEnabled

select() has no null guard by design — it crashes loudly if called before
store initialization, which is correct for the main process where the store
is always ready before any select() call.

Add safeSelect() for preload contexts where the store may not yet be
initialized. Unlike select(), it returns T | undefined and TypeScript
enforces that callers handle the undefined case.

Use safeSelect in getInternalVideoChatWindowEnabled() with an explicit
?? false fallback, so early calls before store init return false (safe
default) instead of crashing or silently returning undefined-as-boolean.
…e it (RocketChat#3205)

* fix: improve screen share picker cancellation reliability

- Remove redundant dialog.close() call inside onclose handler in Dialog
  hooks (close event fires after dialog is already closed, making the
  call a no-op per WHATWG spec)
- Add safety-net IPC cancellation in ScreenSharePicker: track whether a
  response was sent per picker session; if visible transitions false
  without a response having been sent, send null cancellation as fallback.
  This covers all dismissal paths (click-outside, ESC, programmatic close)
  regardless of the Dialog close event chain

* fix: resolve screen share picker stuck after dismissal

Three compounding bugs caused the screen sharing button to become
permanently unresponsive after the user dismissed the picker by
clicking outside the dialog:

1. handleClose firing after handleShare — when handleShare called
   setVisible(false), the useDialog useEffect triggered dialog.close()
   which synchronously fired onclose → handleClose. Since handleClose
   had no guard, it sent a null cancellation immediately after the real
   sourceId, consuming the ipcMain.once listener with null and leaving
   Jitsi's getDisplayMedia callback unresolved on the next attempt.
   Fix: added responseSentRef.current guard at the top of handleClose.

2. isScreenSharingRequestPending cleared after cb() — Jitsi calls
   getDisplayMedia again synchronously inside the setDisplayMediaRequest-
   Handler callback, re-entering createInternalPickerHandler while
   isScreenSharingRequestPending was still true, permanently blocking
   subsequent requests. Fix: moved markScreenSharingComplete() before
   cb() in both the response listener and the timeout handler.

3. Dual ipcMain.once race in open-screen-picker handler — the jitsiBridge
   IPC path registered its own relay listener without clearing any active
   listener from createInternalPickerHandler first. Fix: call
   cleanupScreenSharingListener() before registering the relay.

Also adds "Open System Preferences" link to the screen recording
permission denied callout, consistent with the microphone permission UX.
Project Name: Rocket.Chat.Electron
Project Link: https://app.lingohub.com/project/pr_1Ag2Vlx6MWNt-16038/branches/prb_16rm9BiWK53b-4144
User: Lingohub Robot

Easy language translations with Lingohub 🚀

Co-authored-by: lingohub[bot] <69908207+lingohub[bot]@users.noreply.github.com>
* chore: remove package-lock.json in favor of yarn.lock

This project uses Yarn as its package manager. Having both
package-lock.json and yarn.lock tracked causes conflicts and
breaks npx/npm tooling due to devEngines format differences.

* chore: anchor package-lock.json ignore to repository root
i18n: correct Polish gender, Norwegian sentence case, and translation typo
@Ram-sah19 Ram-sah19 force-pushed the fix-desktop-gui-crash branch from 3af92de to c17e03b Compare March 10, 2026 19:29
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.