Skip to content

Release 4.14.0#3289

Closed
jeanfbrito wants to merge 46 commits intomasterfrom
dev
Closed

Release 4.14.0#3289
jeanfbrito wants to merge 46 commits intomasterfrom
dev

Conversation

@jeanfbrito
Copy link
Copy Markdown
Member

@jeanfbrito jeanfbrito commented Apr 6, 2026

Summary

Release 4.14.0 brings screen sharing, a markdown file viewer, OS CA certificate loading, MSI auto-update controls, and several stability fixes.

Features

Fixes

Maintenance

Summary by CodeRabbit

  • New Features

    • Markdown viewer with syntax highlighting and improved PDF viewer
    • Windows MSI installer output
    • Video-call credential sharing (Pexip) and provider-awareness
    • Log viewer: server badges, server filtering, tail-reading and clear confirmation
    • Screen-sharing: improved picker, permission checks, and request tracking
  • Improvements

    • Outlook calendar: configurable sync interval, detailed-events logging, and optional insecure fallback
    • Corporate certificate configuration for restricted environments
    • Debug & detailed-events logging toggles and log deduplication
    • Upgraded Node/Electron runtime
  • Localization

    • Document viewer translations added across many locales

jeanfbrito and others added 30 commits February 4, 2026 23:48
…3190)

* fix: disable Bugsnag auto session tracking to prevent unwanted network connections

Adds autoTrackSessions: false to Bugsnag.start() configuration to prevent
the SDK from automatically connecting to sessions.bugsnag.com on initialization.
This fixes issues in air-gapped networks where the connection attempt triggers
certificate error dialogs even when telemetry is disabled.

Also upgrades @bugsnag/js from v7.22.3 to v8.8.1.

* test: add integration tests for Bugsnag network behavior

- Use nock to intercept real HTTP requests from Bugsnag SDK
- Verify no network calls when reporting is disabled
- Verify sessions are sent when reporting is enabled
- Use Object.defineProperty for env var mocking
- Skip tests on Windows due to Jest module mocking issues
…ook calendar

Add `allowInsecureOutlookConnections` setting for air-gapped environments
where Exchange servers use self-signed or internal CA certificates.

Configurable via overridden-settings.json:
{ "allowInsecureOutlookConnections": true }

Changes:
- Add new reducer for the setting (defaults to false)
- Apply setting to both Exchange (XhrApi) and Rocket.Chat (axios) connections
- Reuse single HTTPS agent per sync for better performance
- Fix missing await on createEventOnRocketChatServer call
The setting was being persisted to config.json, which meant once set to
true it would stay true even after removing from overridden-settings.json.

Changes:
- Remove from PersistableValues type and migrations
- Remove from selectPersistableValues selector
- Explicitly read from override files on each app start
- Accept case-insensitive "true" values for robustness
- Always defaults to false when key is missing

This ensures admins have full control over the setting in air-gapped
environments where remote debugging is not possible.
…ook calendar (#3191)

* feat: add admin setting to bypass SSL certificate validation for Outlook calendar

Add `allowInsecureOutlookConnections` setting for air-gapped environments
where Exchange servers use self-signed or internal CA certificates.

Configurable via overridden-settings.json:
{ "allowInsecureOutlookConnections": true }

Changes:
- Add new reducer for the setting (defaults to false)
- Apply setting to both Exchange (XhrApi) and Rocket.Chat (axios) connections
- Reuse single HTTPS agent per sync for better performance
- Fix missing await on createEventOnRocketChatServer call

* Version 4.12.1-alpha.2

* chore: patch @ewsjs/xhr to stop overwriting request errors

* lock file

* fix: make allowInsecureOutlookConnections override-only setting

The setting was being persisted to config.json, which meant once set to
true it would stay true even after removing from overridden-settings.json.

Changes:
- Remove from PersistableValues type and migrations
- Remove from selectPersistableValues selector
- Explicitly read from override files on each app start
- Accept case-insensitive "true" values for robustness
- Always defaults to false when key is missing

This ensures admins have full control over the setting in air-gapped
environments where remote debugging is not possible.

---------

Co-authored-by: Pierre Lehnen <pierre.lehnen@rocket.chat>
* feat: add configurable Outlook calendar sync interval (1-60 min)

Adds a user-editable sync interval setting to Settings > General,
with admin override support via overridden-settings.json. Uses a
nullable override pattern (number | null) to cleanly separate admin
overrides from persisted user preferences, preventing contamination.
Includes debounced runtime restart of the sync task on changes.

* chore: bump version to 4.12.1-alpha.3, improve sync interval change handling

Increases debounce to 10s, triggers an immediate sync before
rescheduling, and adds a log message when the interval changes.

* fix: clean up sync state when credentials are cleared or app shuts down

Prevents stale credentials from being used by the debounced interval
restart callback. Clears timers, nulls module-level state, and
unsubscribes the interval watcher on credential clear and shutdown.
* feat: Add Exchange/EWS debugging patches and error classification (#3187)

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

* Language update from Lingohub 🤖 (#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  (#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 (#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 (#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (#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 (#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 #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>

* feat: Add scoped logging infrastructure and log viewer window (#3186)

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

* Language update from Lingohub 🤖 (#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  (#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 (#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 (#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (#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 (#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>

* fix: call stopOutlookCalendarSync on app quit

Ensures all sync timers and debounce timers are properly cleaned up
when the application shuts down, preventing sync operations during
shutdown.

* fix: improve logging system security and log viewer context filtering

- Protect active log files from cleanup deletion
- Add IPC rate limiting to prevent renderer process flooding
- Restrict log file permissions to owner-only access
- Add context sanitization to error classification (passwords/tokens only)
- Remove ANSI color codes from OutlookCalendar logger prefixes
- Fix log viewer context filter to use structured tag matching instead of substring search

* feat: add detailed events logging toggle for Outlook calendar sync

Add a new toggle in Settings > Developer to log full event data exchanged
between Exchange and Rocket.Chat during calendar sync. When enabled, logs
raw Exchange appointments, CRUD payloads/responses, event comparisons,
and sync summaries for diagnosing sync issues.

* fix: address PR review feedback

- Fix regex precedence in error classification so 'timeout' doesn't match too broadly
- Add lang="en" to log viewer HTML for accessibility
- Add circular reference guard to redactObject to prevent stack overflow
- Update AGENTS.md with missing outlookDebug/outlookEventDetail imports

* fix: address second round of PR review feedback

- Narrow SSL/TLS regex to match specific error codes instead of broad substrings
- Make sanitizeContext recursive to redact nested sensitive keys
- Align multi-line JSON context with box-drawing prefix in error logs
- Preserve original case in custom path segments in buildEwsPathname

---------

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>
…on (#3203)

- Handle CRLF line endings from Windows log files (split on \r?\n)
- Fix regex to allow variable whitespace between bracket groups
- Change outlookLog/outlookDebug/outlookEventDetail to console.info
  so they reach the file transport in production (info threshold)
  instead of being silently dropped as debug level
- Fix Outlook preload console.log calls to console.info (same issue)
- Fix app startup completion log to console.info
)

Remove server version gate (>= 7.5.0) that conditionally included endTime and busy fields when syncing Outlook calendar events to Rocket.Chat server. The gate was failing for some customers because server.version was not populated in the Redux store, causing these fields to be silently dropped from create/update payloads regardless of actual server version.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
* feat: Add Exchange/EWS debugging patches and error classification (#3187)

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

* Language update from Lingohub 🤖 (#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  (#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 (#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 (#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (#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 (#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 #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>

* feat: Add scoped logging infrastructure and log viewer window (#3186)

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

* Language update from Lingohub 🤖 (#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  (#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 (#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 (#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (#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 (#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>

* fix: Add safe guards to prevent The application GUI just crashed (#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.

* fix: Screen picker not loading again after closing by clicking outside it (#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.

* chore: remove outdated Electron 10 comment (#3202)

* Language update from Lingohub 🤖 (#3196)

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: Update hu.i18n.json (#3193)

* chore: Remove package-lock.json in favor of yarn.lock (#3214)

* 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

* fix: address code review feedback

- privacy.ts: don't spread message in catch block to avoid leaking
  sensitive fields; return only safe metadata (level, date). Add one-time
  stderr warning when redaction fails for observability.
- store/index.ts: warn when watch() is called before store is initialized
  so callers aren't silently left in uninitialized state.
- hu.i18n.json: fix 'bolt' (shop) -> 'tároló' (storage) for software
  store references. Add missing trailing period for consistency.

---------

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>
Co-authored-by: Santam Roy Choudhury <52635773+SantamRC@users.noreply.github.com>
Co-authored-by: Balázs Úr <balazs@urbalazs.hu>
…nd log viewer enhancements (#3230)

* feat: logging system improvements with dedup, debug toggle, and async writes

- Add Debug Logging toggle in Developer Settings (runtime log level switch)
- Add log deduplication: skip consecutive identical non-error messages at
  file transport and IPC boundary, keeping logs clean and lightweight
- Enable async file writes (electron-log batching) to avoid blocking main thread
- Buffer errors.jsonl writes with periodic flush instead of per-error appendFile
- Fix privacy hook ordering: redact data before writing to errors.jsonl
- Fix IPC rate limit memory leak: clean up on webContents destroy
- Add incremental log reading (byte offset tailing) for efficient auto-refresh
- Add clear logs confirmation dialog
- Add scoped logger process context
- Add log viewer i18n locale detection
- Remove dead code (unused log wrappers, constants, background color fn)
- Change search filter to session-only state for privacy
- Clear authorized log paths on window close
- Add missing IPC log levels (verbose, silly, default)

* feat: add server identification to webview logs and log viewer UI

Add server-N tags to webview log entries so logs from different
workspaces can be distinguished. The preload script queries the main
process for the server index via a synchronous IPC handler that matches
window.location.origin against the Redux server list.

Log viewer UI gains a "Show Server" toggle, server filter dropdown,
and server name resolution (server-N mapped to workspace title/URL
via a new get-server-mapping IPC handler).

* fix: apply entry limit after filtering in log viewer

Load all entries from disk and apply the entry limit as a display cap
on filtered results. Previously "Last 100 entries" loaded 100 from disk
then filtered, showing fewer matches. Now it shows the last 100 entries
matching the current filters.

* feat: improve privacy hook with industry-standard redaction patterns

- Add JWT detection and partial masking (eyJh...xK9s)
- Add URL credential detection (https://user:pass@host)
- Add credit card detection with Luhn checksum validation
- Add long hex token detection (32+ char API keys/hashes)
- Add IP address partial masking (preserve localhost/private ranges)
- Add webhook URL and client secret patterns
- Require 8+ char values on credential patterns to reduce false positives
- Fix email regex to exclude package scopes and file extensions
- Use partial masking instead of full [REDACTED] for better debugging
- Add safe-key allowlist (token_type, password_policy, etc.)
- Add max depth protection against stack overflow on nested objects
- Update verbose logging toggle description for clarity

* style: fix lint formatting issues

* fix: address PR review findings

- Use event.sender.id for IPC rate limiting instead of renderer-supplied
  webContentsId to prevent spoofing
- Use senderWebContents.getURL() for server attribution instead of
  renderer-supplied serverUrl
- Separate IPC and file transport dedup keys to prevent interference
- Add try/catch in dedup makeKey to handle circular objects
- Use synchronous writes in flushErrorJsonl during shutdown to prevent
  data loss
- Fix IP address exemption: only 172.16-31.x.x are private (RFC 1918),
  not all 172.x.x.x
- Validate fromByte parameter in read-logs-tail IPC handler

* fix: address second round of PR review findings

- Dedup file hook: serialize structured objects with JSON.stringify
  instead of String() to produce meaningful dedup keys
- Privacy: guard redactObject spread against non-object return value
  when processing nested Redux state

* fix: redact username in URL credentials, enforce depth limit at 10

- Redact both username and password in URLs with embedded credentials
- Change depth check from > 10 to >= 10 to enforce max depth of 10
* feat: pass auth credentials to Pexip video call webview and skip JitsiBridge for non-Jitsi providers

Auto-grab Meteor auth token and userId from localStorage when opening a Pexip
video call, pipe them through IPC to the main process, and proactively
postMessage credentials to Rocket.Chat iframes detected inside the Pexip
webview via MutationObserver. Credentials are memory-only, provider-gated,
and cleared on window close.

Additionally, JitsiBridge now checks the provider name via synchronous IPC
before initializing, skipping entirely for non-Jitsi providers like Pexip.
This prevents false Jitsi URL detection, failed external_api.js loads, and
CORS errors that were occurring on Pexip calls.

* refactor: remove proactive iframe credential injection from video call preload

Pexip handles its own iframe — it just needs credentials available via the
API. Removed MutationObserver, postMessage injection, and all iframe detection
logic. Credentials are now only exposed through window.videoCallWindow.getAuthCredentials().

* docs: add technical documentation for Pexip auth credentials flow

* docs: simplify Pexip auth credentials doc for external sharing

Remove internal implementation details (Jitsi, IPC, Electron architecture)
and focus on the API surface that the Pexip team needs to integrate.

* docs: remove usage examples from Pexip auth credentials doc

Keep only the API reference — Pexip team can refer to RC server
docs for iframe authentication methods.

* fix: harden Pexip credential handler with try/catch and caller check

- Wrap URL parsing of _wc.getURL() in try/catch to prevent unhandled throw
- Scope get-credentials IPC handler to only respond to the video call
  window's webview, rejecting requests from other renderers
- Add language tag to docs fenced code block

* style: apply prettier formatting to get-credentials handler
- Escape regex dots in SSL error classification patterns
- Add array-of-objects handling to sanitizeContext
- Fix "Last N" log viewer filter returning oldest instead of newest
- Normalize trailing slashes in server URL matching
- Log warning when insecure SSL mode is enabled
- Fix Authorization header regex to capture scheme-based values (Basic, NTLM)
- Preserve Error message/stack in privacy redactObject()
- Check CRUD helper success before incrementing sync counters
- Fix coalescing queue resolving callers before sync completes
- Move token persistence after user validation check
- Centralize credential cleanup in cleanupVideoCallWindow
- Add origin check for Pexip credential reads
- Add authorization substring matching in context sanitizer
- Add circular reference protection in sanitizeContext
- Only strip trailing EWS path segments, preserve mid-path
- Keep totalEntriesInFile in sync during log streaming
- Remove origin verification for credential reads (Pexip origin !=
  RC server origin, check always fails — WebContents check is sufficient)
- Reset persisted server filter when stored value no longer exists
  in available options, preventing empty log list with hidden control
CI workflows and the desktop-release-action workspace were still
pinned to Node 22.17.1 while package.json engines, devEngines, and
volta all reference 24.11.1.
…OS (#3270)

* Version 4.13.0 (#3233)

* fix: Bugsnag network connections even with errors reporting disabled (#3190)

* fix: disable Bugsnag auto session tracking to prevent unwanted network connections

Adds autoTrackSessions: false to Bugsnag.start() configuration to prevent
the SDK from automatically connecting to sessions.bugsnag.com on initialization.
This fixes issues in air-gapped networks where the connection attempt triggers
certificate error dialogs even when telemetry is disabled.

Also upgrades @bugsnag/js from v7.22.3 to v8.8.1.

* test: add integration tests for Bugsnag network behavior

- Use nock to intercept real HTTP requests from Bugsnag SDK
- Verify no network calls when reporting is disabled
- Verify sessions are sent when reporting is enabled
- Use Object.defineProperty for env var mocking
- Skip tests on Windows due to Jest module mocking issues

* Version 4.12.1-alpha.1

* feat: add admin setting to bypass SSL certificate validation for Outlook calendar

Add `allowInsecureOutlookConnections` setting for air-gapped environments
where Exchange servers use self-signed or internal CA certificates.

Configurable via overridden-settings.json:
{ "allowInsecureOutlookConnections": true }

Changes:
- Add new reducer for the setting (defaults to false)
- Apply setting to both Exchange (XhrApi) and Rocket.Chat (axios) connections
- Reuse single HTTPS agent per sync for better performance
- Fix missing await on createEventOnRocketChatServer call

* Version 4.12.1-alpha.2

* chore: patch @ewsjs/xhr to stop overwriting request errors

* lock file

* fix: make allowInsecureOutlookConnections override-only setting

The setting was being persisted to config.json, which meant once set to
true it would stay true even after removing from overridden-settings.json.

Changes:
- Remove from PersistableValues type and migrations
- Remove from selectPersistableValues selector
- Explicitly read from override files on each app start
- Accept case-insensitive "true" values for robustness
- Always defaults to false when key is missing

This ensures admins have full control over the setting in air-gapped
environments where remote debugging is not possible.

* feat: add admin setting to bypass SSL certificate validation for Outlook calendar (#3191)

* feat: add admin setting to bypass SSL certificate validation for Outlook calendar

Add `allowInsecureOutlookConnections` setting for air-gapped environments
where Exchange servers use self-signed or internal CA certificates.

Configurable via overridden-settings.json:
{ "allowInsecureOutlookConnections": true }

Changes:
- Add new reducer for the setting (defaults to false)
- Apply setting to both Exchange (XhrApi) and Rocket.Chat (axios) connections
- Reuse single HTTPS agent per sync for better performance
- Fix missing await on createEventOnRocketChatServer call

* Version 4.12.1-alpha.2

* chore: patch @ewsjs/xhr to stop overwriting request errors

* lock file

* fix: make allowInsecureOutlookConnections override-only setting

The setting was being persisted to config.json, which meant once set to
true it would stay true even after removing from overridden-settings.json.

Changes:
- Remove from PersistableValues type and migrations
- Remove from selectPersistableValues selector
- Explicitly read from override files on each app start
- Accept case-insensitive "true" values for robustness
- Always defaults to false when key is missing

This ensures admins have full control over the setting in air-gapped
environments where remote debugging is not possible.

---------

Co-authored-by: Pierre Lehnen <pierre.lehnen@rocket.chat>

* Add configurable Outlook calendar sync interval (#3198)

* feat: add configurable Outlook calendar sync interval (1-60 min)

Adds a user-editable sync interval setting to Settings > General,
with admin override support via overridden-settings.json. Uses a
nullable override pattern (number | null) to cleanly separate admin
overrides from persisted user preferences, preventing contamination.
Includes debounced runtime restart of the sync task on changes.

* chore: bump version to 4.12.1-alpha.3, improve sync interval change handling

Increases debounce to 10s, triggers an immediate sync before
rescheduling, and adds a log message when the interval changes.

* fix: clean up sync state when credentials are cleared or app shuts down

Prevents stale credentials from being used by the debounced interval
restart callback. Clears timers, nulls module-level state, and
unsubscribes the interval watcher on credential clear and shutdown.

* feat: Add outlook detailed logs toggle (#3199)

* feat: Add Exchange/EWS debugging patches and error classification (#3187)

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

* Language update from Lingohub 🤖 (#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  (#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 (#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 (#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (#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 (#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 #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>

* feat: Add scoped logging infrastructure and log viewer window (#3186)

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

* Language update from Lingohub 🤖 (#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  (#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 (#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 (#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (#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 (#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>

* fix: call stopOutlookCalendarSync on app quit

Ensures all sync timers and debounce timers are properly cleaned up
when the application shuts down, preventing sync operations during
shutdown.

* fix: improve logging system security and log viewer context filtering

- Protect active log files from cleanup deletion
- Add IPC rate limiting to prevent renderer process flooding
- Restrict log file permissions to owner-only access
- Add context sanitization to error classification (passwords/tokens only)
- Remove ANSI color codes from OutlookCalendar logger prefixes
- Fix log viewer context filter to use structured tag matching instead of substring search

* feat: add detailed events logging toggle for Outlook calendar sync

Add a new toggle in Settings > Developer to log full event data exchanged
between Exchange and Rocket.Chat during calendar sync. When enabled, logs
raw Exchange appointments, CRUD payloads/responses, event comparisons,
and sync summaries for diagnosing sync issues.

* fix: address PR review feedback

- Fix regex precedence in error classification so 'timeout' doesn't match too broadly
- Add lang="en" to log viewer HTML for accessibility
- Add circular reference guard to redactObject to prevent stack overflow
- Update AGENTS.md with missing outlookDebug/outlookEventDetail imports

* fix: address second round of PR review feedback

- Narrow SSL/TLS regex to match specific error codes instead of broad substrings
- Make sanitizeContext recursive to redact nested sensitive keys
- Align multi-line JSON context with box-drawing prefix in error logs
- Preserve original case in custom path segments in buildEwsPathname

---------

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>

* Version 4.12.1-alpha.4

* fix: log viewer Windows compatibility and Outlook logging in production (#3203)

- Handle CRLF line endings from Windows log files (split on \r?\n)
- Fix regex to allow variable whitespace between bracket groups
- Change outlookLog/outlookDebug/outlookEventDetail to console.info
  so they reach the file transport in production (info threshold)
  instead of being silently dropped as debug level
- Fix Outlook preload console.log calls to console.info (same issue)
- Fix app startup completion log to console.info

* Version 4.12.1-alpha.5

* fix: always send endTime and busy fields in calendar sync payload (#3204)

Remove server version gate (>= 7.5.0) that conditionally included endTime and busy fields when syncing Outlook calendar events to Rocket.Chat server. The gate was failing for some customers because server.version was not populated in the Redux store, causing these fields to be silently dropped from create/update payloads regardless of actual server version.

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

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

* Version 4.12.1-alpha.6

* Merge master into dev — bring bug fixes to dev branch (#3215)

* feat: Add Exchange/EWS debugging patches and error classification (#3187)

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

* Language update from Lingohub 🤖 (#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  (#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 (#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 (#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (#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 (#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 #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>

* feat: Add scoped logging infrastructure and log viewer window (#3186)

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

* Language update from Lingohub 🤖 (#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  (#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 (#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 (#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (#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 (#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>

* fix: Add safe guards to prevent The application GUI just crashed (#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 contextBrid…
jeanfbrito and others added 13 commits March 23, 2026 13:36
Fix DocumentViewer layout so the toolbar with the Back button is always
visible regardless of sidebar state. The wrapper now properly fills its
parent with absolute positioning, and the viewer uses a column flex
layout to stack the toolbar above the PDF content.
* fix: add context menu to root window for deep link launch flow

The right-click context menu was only attached to server webview
webContents, not to the root window's own webContents. This meant
the "Enter your server URL" screen (rendered in the root window)
had no context menu, preventing users from pasting via right-click
when the app was launched through a deep link.

* fix: allow skipped updates to appear on manual check for updates

The update-available handler unconditionally honored skippedUpdateVersion,
silently suppressing skipped versions even when the user manually triggered
Check for Updates from the About dialog. This left no recovery path for
users who skipped a version and later changed their mind.

Add an isUserInitiatedCheck flag so the skip preference only applies to
automatic startup checks, not user-initiated ones.
The update-available handler unconditionally honored skippedUpdateVersion,
silently suppressing skipped versions even when the user manually triggered
Check for Updates from the About dialog. This left no recovery path for
users who skipped a version and later changed their mind.

Add an isUserInitiatedCheck flag so the skip preference only applies to
automatic startup checks, not user-initiated ones.
* Version 4.13.0 (#3233)

* fix: Bugsnag network connections even with errors reporting disabled (#3190)

* fix: disable Bugsnag auto session tracking to prevent unwanted network connections

Adds autoTrackSessions: false to Bugsnag.start() configuration to prevent
the SDK from automatically connecting to sessions.bugsnag.com on initialization.
This fixes issues in air-gapped networks where the connection attempt triggers
certificate error dialogs even when telemetry is disabled.

Also upgrades @bugsnag/js from v7.22.3 to v8.8.1.

* test: add integration tests for Bugsnag network behavior

- Use nock to intercept real HTTP requests from Bugsnag SDK
- Verify no network calls when reporting is disabled
- Verify sessions are sent when reporting is enabled
- Use Object.defineProperty for env var mocking
- Skip tests on Windows due to Jest module mocking issues

* Version 4.12.1-alpha.1

* feat: add admin setting to bypass SSL certificate validation for Outlook calendar

Add `allowInsecureOutlookConnections` setting for air-gapped environments
where Exchange servers use self-signed or internal CA certificates.

Configurable via overridden-settings.json:
{ "allowInsecureOutlookConnections": true }

Changes:
- Add new reducer for the setting (defaults to false)
- Apply setting to both Exchange (XhrApi) and Rocket.Chat (axios) connections
- Reuse single HTTPS agent per sync for better performance
- Fix missing await on createEventOnRocketChatServer call

* Version 4.12.1-alpha.2

* chore: patch @ewsjs/xhr to stop overwriting request errors

* lock file

* fix: make allowInsecureOutlookConnections override-only setting

The setting was being persisted to config.json, which meant once set to
true it would stay true even after removing from overridden-settings.json.

Changes:
- Remove from PersistableValues type and migrations
- Remove from selectPersistableValues selector
- Explicitly read from override files on each app start
- Accept case-insensitive "true" values for robustness
- Always defaults to false when key is missing

This ensures admins have full control over the setting in air-gapped
environments where remote debugging is not possible.

* feat: add admin setting to bypass SSL certificate validation for Outlook calendar (#3191)

* feat: add admin setting to bypass SSL certificate validation for Outlook calendar

Add `allowInsecureOutlookConnections` setting for air-gapped environments
where Exchange servers use self-signed or internal CA certificates.

Configurable via overridden-settings.json:
{ "allowInsecureOutlookConnections": true }

Changes:
- Add new reducer for the setting (defaults to false)
- Apply setting to both Exchange (XhrApi) and Rocket.Chat (axios) connections
- Reuse single HTTPS agent per sync for better performance
- Fix missing await on createEventOnRocketChatServer call

* Version 4.12.1-alpha.2

* chore: patch @ewsjs/xhr to stop overwriting request errors

* lock file

* fix: make allowInsecureOutlookConnections override-only setting

The setting was being persisted to config.json, which meant once set to
true it would stay true even after removing from overridden-settings.json.

Changes:
- Remove from PersistableValues type and migrations
- Remove from selectPersistableValues selector
- Explicitly read from override files on each app start
- Accept case-insensitive "true" values for robustness
- Always defaults to false when key is missing

This ensures admins have full control over the setting in air-gapped
environments where remote debugging is not possible.

---------

Co-authored-by: Pierre Lehnen <pierre.lehnen@rocket.chat>

* Add configurable Outlook calendar sync interval (#3198)

* feat: add configurable Outlook calendar sync interval (1-60 min)

Adds a user-editable sync interval setting to Settings > General,
with admin override support via overridden-settings.json. Uses a
nullable override pattern (number | null) to cleanly separate admin
overrides from persisted user preferences, preventing contamination.
Includes debounced runtime restart of the sync task on changes.

* chore: bump version to 4.12.1-alpha.3, improve sync interval change handling

Increases debounce to 10s, triggers an immediate sync before
rescheduling, and adds a log message when the interval changes.

* fix: clean up sync state when credentials are cleared or app shuts down

Prevents stale credentials from being used by the debounced interval
restart callback. Clears timers, nulls module-level state, and
unsubscribes the interval watcher on credential clear and shutdown.

* feat: Add outlook detailed logs toggle (#3199)

* feat: Add Exchange/EWS debugging patches and error classification (#3187)

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

* Language update from Lingohub 🤖 (#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  (#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 (#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 (#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (#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 (#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 #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>

* feat: Add scoped logging infrastructure and log viewer window (#3186)

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

* Language update from Lingohub 🤖 (#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  (#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 (#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 (#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (#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 (#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>

* fix: call stopOutlookCalendarSync on app quit

Ensures all sync timers and debounce timers are properly cleaned up
when the application shuts down, preventing sync operations during
shutdown.

* fix: improve logging system security and log viewer context filtering

- Protect active log files from cleanup deletion
- Add IPC rate limiting to prevent renderer process flooding
- Restrict log file permissions to owner-only access
- Add context sanitization to error classification (passwords/tokens only)
- Remove ANSI color codes from OutlookCalendar logger prefixes
- Fix log viewer context filter to use structured tag matching instead of substring search

* feat: add detailed events logging toggle for Outlook calendar sync

Add a new toggle in Settings > Developer to log full event data exchanged
between Exchange and Rocket.Chat during calendar sync. When enabled, logs
raw Exchange appointments, CRUD payloads/responses, event comparisons,
and sync summaries for diagnosing sync issues.

* fix: address PR review feedback

- Fix regex precedence in error classification so 'timeout' doesn't match too broadly
- Add lang="en" to log viewer HTML for accessibility
- Add circular reference guard to redactObject to prevent stack overflow
- Update AGENTS.md with missing outlookDebug/outlookEventDetail imports

* fix: address second round of PR review feedback

- Narrow SSL/TLS regex to match specific error codes instead of broad substrings
- Make sanitizeContext recursive to redact nested sensitive keys
- Align multi-line JSON context with box-drawing prefix in error logs
- Preserve original case in custom path segments in buildEwsPathname

---------

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>

* Version 4.12.1-alpha.4

* fix: log viewer Windows compatibility and Outlook logging in production (#3203)

- Handle CRLF line endings from Windows log files (split on \r?\n)
- Fix regex to allow variable whitespace between bracket groups
- Change outlookLog/outlookDebug/outlookEventDetail to console.info
  so they reach the file transport in production (info threshold)
  instead of being silently dropped as debug level
- Fix Outlook preload console.log calls to console.info (same issue)
- Fix app startup completion log to console.info

* Version 4.12.1-alpha.5

* fix: always send endTime and busy fields in calendar sync payload (#3204)

Remove server version gate (>= 7.5.0) that conditionally included endTime and busy fields when syncing Outlook calendar events to Rocket.Chat server. The gate was failing for some customers because server.version was not populated in the Redux store, causing these fields to be silently dropped from create/update payloads regardless of actual server version.

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

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

* Version 4.12.1-alpha.6

* Merge master into dev — bring bug fixes to dev branch (#3215)

* feat: Add Exchange/EWS debugging patches and error classification (#3187)

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

* Language update from Lingohub 🤖 (#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  (#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 (#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 (#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (#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 (#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 #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>

* feat: Add scoped logging infrastructure and log viewer window (#3186)

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

* Language update from Lingohub 🤖 (#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  (#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 (#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 (#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (#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 (#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>

* fix: Add safe guards to prevent The application GUI just crashed (#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,…
* feat: add DISABLE_AUTO_UPDATES property to MSI installer

Allow enterprise admins to disable auto-updates during MSI deployment:
msiexec /i rocketchat.msi DISABLE_AUTO_UPDATES=1 /qn

Uses electron-builder's msiProjectCreated hook to inject a WiX custom
action that writes resources/update.json with canUpdate and autoUpdate
set to false, matching the existing NSIS /disableAutoUpdates behavior.

* Harden VBScript custom action and add build-time validation

- Add error handling to VBScript: check resources/ exists, validate
  file creation, and raise descriptive errors on failure
- Guard custom action with NOT REMOVE~="ALL" to skip during uninstall
- Add build-time validation that throws if XML injection failed
- Document implementation assumptions in JSDoc header

* chore: bump version to 4.14.0-alpha.1

* ci: include MSI artifacts in PR builds

Add MSI target to the Windows electron-builder command and include
.msi files in Wasabi uploads and PR comment artifact links.
* feat: add markdown file viewer with GitHub-flavored rendering

Extend the document viewer to support markdown files alongside PDFs.
When a .md file is clicked in a server, it is intercepted at the
download level and rendered in an overlay using marked with GFM support,
syntax highlighting via highlight.js, and DOMPurify for XSS sanitization.

- Add MarkdownContent component with GitHub-style CSS and theme support
- Extract PdfContent into its own component for cleaner separation
- Thread documentViewerFormat through Redux state and IPC
- Intercept .md downloads via session will-download handler
- Fetch markdown content via main process IPC using server session auth
- Open links in external browser, contain scroll within viewer
- Add document viewer translation keys

* i18n: add document viewer translations for all languages

Add documentViewer.title.pdf and documentViewer.title.markdown
translation keys to all 21 non-English locale files.

* fix: address code review — security, accessibility, and link handling

- Validate URL protocol and origin in fetch-content IPC handler
- Use getAttribute('href') for links, resolve relative URLs against
  document base, and enforce protocol allowlist (http, https, mailto)
- Skip in-page anchor links (#) instead of opening externally
- Add aria-label to back button for screen readers
- Replace raw <h2> with Fuselage Box fontScale for theme consistency
- Add documentViewer.back translation key to all 22 languages

* fix: preserve in-page anchor scrolling in markdown viewer

Move preventDefault() after the hash-link check so that #anchor
links retain their default scrolling behavior.
…3283)

* docs: add admin guide for allowInsecureOutlookConnections setting

Document the overridden-settings.json configuration for bypassing
SSL certificate validation in Outlook calendar sync, covering
file paths per platform, default behavior, and usage scenarios.

* feat: load OS CA certificates at startup for corporate environments

Use Node.js 24's native tls.setDefaultCACertificates() to combine
system-trusted and bundled Mozilla CAs at boot time. This allows
all Node.js HTTPS connections (Outlook sync, version checks, etc.)
to trust certificates from the OS trust store without disabling
TLS verification.

Enabled by default, configurable via useSystemCertificates in
overridden-settings.json. The existing allowInsecureOutlookConnections
remains as a last-resort fallback.

* docs: consolidate certificate docs into single admin guide

Merge the separate outlook-calendar-insecure-connections.md and
system-ca-certificates.md into a unified corporate-certificate-configuration.md
covering both approaches (system CAs and insecure bypass) in one place.

* fix: address CodeRabbit review feedback

- Align settings precedence: read both override files and let appAsar
  win, matching the merge order in data.ts
- Use getCACertificates() (no arg) to preserve NODE_EXTRA_CA_CERTS
  alongside system and bundled CAs
- Clarify doc wording for app ASAR override location
Addresses CVE-2026-25639 (prototype pollution DoS in mergeConfig) and
MAL-2026-2306. Adds a resolutions entry to force axios 1.13.6 across
all transitive consumers (e.g. @ewsjs/xhr), eliminating the duplicate
1.13.4 copy from the lockfile.
Picks up Chromium 144.0.7559.236 and Node.js 24.14.0 with numerous
bug fixes including clipboard crash, Windows notification icons,
macOS safeStorage keychain migration, and desktopCapturer CoreAudio
Tap API support. No breaking changes within the 40.x series.
* fix: use hostname-based server tags in logging and log viewer filter

The log viewer server filter showed no results because the server-N IDs
in log entries (assigned from a webContents pool) didn't match the IDs
in the filter dropdown (derived from Redux array index).

Replace the anonymous pool-based server-N system with hostname-based
tags. Log entries now use the server hostname directly (e.g.,
[open.rocket.chat] instead of [server-2]), and the filter dropdown
uses the same hostname as key. This makes the mapping deterministic
and stable across app reloads.

* fix: use URL.host instead of hostname to avoid port collisions

Servers on the same hostname but different ports (e.g., :3000 vs :4000)
would collide when using hostname alone. URL.host includes the port
when non-default, making each server key unique.

* fix: dismiss path-based server matching review comment

Rocket.Chat servers are always identified by host, not subpaths.
Revert to origin-based matching and keep getHost for the server tag.

* fix: address code review feedback

- Rename webContentsToHostname → webContentsToHost to match URL.host usage
- Use token-based removal in LogEntry to avoid partial substring matches

* fix: use hostname-based server tags and fallback matching in log viewer

Three issues with the server filter:
- get-server-tag IPC returned index-based tags (server-1) instead of
  hostnames, causing a mismatch with the filter dropdown which uses
  hostnames from getHost()
- registerWebContentsServer was not called during dom-ready, so logs
  from webContents whose console injection failed had no server tag
- Filter only checked context tags, missing logs that mention the
  server URL in the message body

Now uses getHost() for server tags, registers server context early in
dom-ready, and falls back to matching against the full raw log line.
Merge all project-specific guidelines from AGENTS.md into CLAUDE.md,
keeping universally-useful rules (build, patches, signing, testing,
git safety, code style) accessible to all contributors. Remove
AGENTS.md to avoid split documentation. Add temp/cache directories
to .gitignore.
…GitHub-style CSS

Add heading ID generation for TOC anchor links, allow task list
checkboxes and details/summary elements through DOMPurify, and
inject GitHub-flavored styles for tables, blockquotes, code blocks,
task lists, and other common markdown elements.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 6, 2026

Important

Review skipped

Too many files!

This PR contains 163 files, which is 13 over the limit of 150.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d8a57086-b902-4cf0-9eab-8a27f3c5998c

📥 Commits

Reviewing files that changed from the base of the PR and between 6d8a1a1 and bb1af2b.

⛔ Files ignored due to path filters (9)
  • .3eaadeff7ffc7fd4-00000000.dylib is excluded by !**/*.dylib
  • .3eaadeffaf3877dc-00000000.dylib is excluded by !**/*.dylib
  • .3eaadfa76e3c37dc-00000000.dylib is excluded by !**/*.dylib
  • .3eaadfa7afffcff4-00000000.dylib is excluded by !**/*.dylib
  • .3eaadfa7be79fffc-00000000.dylib is excluded by !**/*.dylib
  • .3eaadfaf7fb957fc-00000000.dylib is excluded by !**/*.dylib
  • .3eaadfb7af3fdff4-00000000.dylib is excluded by !**/*.dylib
  • .3eaadfe7fef84ff4-00000000.dylib is excluded by !**/*.dylib
  • .3eaadff7ee7c6fdc-00000000.dylib is excluded by !**/*.dylib
📒 Files selected for processing (163)
  • .brv/config.json
  • .brv/context-tree/.snapshot.json
  • .brv/context-tree/_index.md
  • .brv/context-tree/_manifest.json
  • .brv/context-tree/ci_cd/_index.md
  • .brv/context-tree/ci_cd/context.md
  • .brv/context-tree/ci_cd/desktop_release_action/_index.md
  • .brv/context-tree/ci_cd/desktop_release_action/context.md
  • .brv/context-tree/ci_cd/desktop_release_action/desktop_release_action_workflow.md
  • .brv/context-tree/ci_cd/desktop_release_action/release_asset_upload_patterns.md
  • .brv/context-tree/ci_cd/github_release_management/_index.md
  • .brv/context-tree/ci_cd/github_release_management/context.md
  • .brv/context-tree/ci_cd/github_release_management/github_release_management_system.md
  • .brv/context-tree/ci_cd/linux_build_and_snapcraft_publishing/_index.md
  • .brv/context-tree/ci_cd/linux_build_and_snapcraft_publishing/linux_build_and_snapcraft_publishing.md
  • .brv/context-tree/ci_cd/macos_build_signing/_index.md
  • .brv/context-tree/ci_cd/macos_build_signing/context.md
  • .brv/context-tree/ci_cd/macos_build_signing/macos_build_and_code_signing.md
  • .brv/context-tree/ci_cd/shell_utilities/_index.md
  • .brv/context-tree/ci_cd/shell_utilities/shell_execution_utilities.md
  • .brv/context-tree/ci_cd/windows_signing/_index.md
  • .brv/context-tree/ci_cd/windows_signing/context.md
  • .brv/context-tree/ci_cd/windows_signing/windows_signing_pipeline_implementation.md
  • .brv/context-tree/ci_cd/windows_signing/yaml_checksum_update_post_signing.md
  • .brv/context-tree/ci_cd/windows_signing_and_kms/_index.md
  • .brv/context-tree/ci_cd/windows_signing_and_kms/windows_certificate_and_kms_provider_setup.md
  • .brv/context-tree/electron_apps/_index.md
  • .brv/context-tree/electron_apps/context.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/_index.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/architecture/_index.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/architecture/three_layer_architecture_overview.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/build_pipeline.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/build_system/_index.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/build_system/asset_generation_pipeline.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/build_system/build_and_bundling.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/build_system/build_assets_pipeline.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/build_system/image_assets_organization.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/build_system/svg_to_format_conversion_process.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/configuration.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/configuration/_index.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/configuration/auto_update_system.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/configuration/configuration_files.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/context.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/desktop_release_action.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/development_setup.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/installation.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/_index.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/certificate_and_protocol_security.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/cross_system_architecture_patterns.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/data_flow_server_selection_and_badge_updates.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/deep_links_protocol_handling.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/desktop_capturer_source_caching.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/document_viewer_ipc_system.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/downloads_system_architecture.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/downloads_system_ipc_handlers_and_s3_expiration.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/i18n_system_language_detection_and_initialization.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/ipc_channel_definitions.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/ipc_communication_system.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/ipc_main_process_implementation.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/ipc_renderer_process_implementation.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/ipc_retry_options_interface.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/jitsi_screen_capture_integration.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/log_viewer_window.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/logging_system_architecture.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/notifications_system_architecture.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/outlook_calendar_integration.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/preload_api_bridge.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/root_window_icon_and_server_info_management.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/screen_picker_provider_abstraction.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/screen_recording_permission_handling.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/screen_sharing_ipc_channels.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/screen_sharing_request_lifecycle.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/screen_sharing_system_architecture.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/sidebar_style_polling_system.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/spell_checking_system.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/spell_checking_system_language_management.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/system_certificates_integration.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/updates_system_configuration_and_flow.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/user_presence_system.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/video_call_window_configuration_and_webpreferences.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/video_call_window_display_media_and_screen_sharing.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/video_call_window_html_template_structure.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/video_call_window_ipc_channels.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/video_call_window_ipc_system.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/video_call_window_lifecycle_and_state_management.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/integrations/video_call_window_navigation_and_protocol_security.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/internationalization/_index.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/internationalization/i18n_system_architecture.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/main_process_lifecycle.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/notification_system_architecture.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/platform_support.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/platform_support/_index.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/platform_support/platform_support_and_installation.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/project_overview.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/renderer_entry_points.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/rocket_chat_electron_documentation.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/rocket_chat_electron_overview.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/server_management/_index.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/server_management/server_loading_and_persistence.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/server_management/server_url_resolution_system.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/shell_root_component.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/tech_stack.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/ui_components/_index.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/ui_components/addserverview_component.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/ui_components/global_css_stylesheet_and_theme_variables.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/ui_components/public_assets_structure.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/ui_components/root_window_html_template_and_initialization.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/ui_components/serversview_and_serverpane_components.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/ui_components/shell_root_component_and_layout.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/ui_components/sidebar_component.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/ui_components/useservers_hook.md
  • .brv/context-tree/electron_apps/rocketchat_desktop/ui_components/video_call_window_overlay_stylesheets.md
  • .brv/context-tree/structure/_index.md
  • .brv/context-tree/structure/app_module/_index.md
  • .brv/context-tree/structure/app_module/app_actions_and_state_selectors.md
  • .brv/context-tree/structure/app_module/app_module_bootstrap.md
  • .brv/context-tree/structure/app_module/context.md
  • .brv/context-tree/structure/ci_cd/_index.md
  • .brv/context-tree/structure/ci_cd/build_release_workflow.md
  • .brv/context-tree/structure/ci_cd/context.md
  • .brv/context-tree/structure/ci_cd/desktop_release_action_file_upload_strategy.md
  • .brv/context-tree/structure/ci_cd/desktop_release_action_routing_logic.md
  • .brv/context-tree/structure/ci_cd/github_release_asset_cleanup_and_limit_management.md
  • .brv/context-tree/structure/ci_cd/github_release_asset_upload_patterns_by_platform.md
  • .brv/context-tree/structure/ci_cd/linux_build_and_snapcraft_publishing.md
  • .brv/context-tree/structure/ci_cd/powershell_linting_workflow.md
  • .brv/context-tree/structure/ci_cd/pull_request_build_workflow.md
  • .brv/context-tree/structure/ci_cd/pull_request_validation_workflow.md
  • .brv/context-tree/structure/ci_cd/windows_signing_pipeline.md
  • .brv/context-tree/structure/configuration/_index.md
  • .brv/context-tree/structure/configuration/context.md
  • .brv/context-tree/structure/configuration/url_constants_module.md
  • .brv/context-tree/structure/error_handling/_index.md
  • .brv/context-tree/structure/error_handling/context.md
  • .brv/context-tree/structure/error_handling/global_error_handling_system.md
  • .brv/context-tree/structure/navigation/_index.md
  • .brv/context-tree/structure/navigation/certificate_trust_and_protocol_handling.md
  • .brv/context-tree/structure/navigation/context.md
  • .brv/context-tree/structure/redux_store/_index.md
  • .brv/context-tree/structure/redux_store/badge_selector_implementation.md
  • .brv/context-tree/structure/redux_store/download_state_management.md
  • .brv/context-tree/structure/redux_store/flux_standard_action_validation.md
  • .brv/context-tree/structure/redux_store/fsa_type_system_and_validation.md
  • .brv/context-tree/structure/redux_store/ipc_middleware_synchronization.md
  • .brv/context-tree/structure/redux_store/preload_dispatch_pattern.md
  • .brv/context-tree/structure/redux_store/public_api_methods.md
  • .brv/context-tree/structure/redux_store/reducer_slices_organization.md
  • .brv/context-tree/structure/redux_store/redux_store_architecture.md
  • .brv/context-tree/structure/redux_store/request_response_utility.md
  • .brv/context-tree/structure/redux_store/root_reducer_configuration.md
  • .brv/context-tree/structure/redux_store/service_base_class.md
  • .brv/context-tree/structure/redux_store/ui_action_type_mappings.md
  • .brv/context-tree/structure/redux_store/ui_actions_and_selectors.md
  • .brv/context-tree/structure/server_management/_index.md
  • .brv/context-tree/structure/server_management/server_lifecycle_and_loading.md
  • .brv/context-tree/structure/server_management/server_state_and_types.md
  • .brv/context-tree/structure/server_management/server_state_reducer.md
  • .brv/context-tree/structure/server_management/server_url_resolution.md
  • .claude/settings.json
  • AGENTS.md
  • src/i18n/hu.i18n.json
  • src/i18n/no.i18n.json
  • src/videoCallWindow/ipc.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

Introduces document viewer (PDF/Markdown), corporate system CA loading, logging and log-viewer enhancements, shared screen-sharing plumbing with capturer cache and request tracker, Outlook sync controls and insecure option, MSI build hook, Node.js runtime bump, many i18n strings, tests, and CI/docs updates.

Changes

Cohort / File(s) Summary
CI / Release
/.github/workflows/build-release.yml, /.github/workflows/pull-request-build.yml, /.github/workflows/validate-pr.yml, workspaces/desktop-release-action/package.json
Bump Node.js from 22.17.124.11.1 in workflows and workspace; PR workflow emits/uploads Windows MSI alongside NSIS.
MSI hooks & builder config
build/msiProjectCreated.js, electron-builder.json
Add msiProjectCreated hook injecting DISABLE_AUTO_UPDATES and deferred VBScript actions into WiX; register hook and bump mac bundleVersion.
Document viewer (PDF + Markdown)
src/documentViewer/ipc.ts, src/ui/components/ServersView/DocumentViewer.tsx, src/ui/components/ServersView/MarkdownContent.tsx, src/ui/components/ServersView/PdfContent.tsx, src/servers/actions.ts, src/servers/common.ts, src/servers/reducers.ts, src/ui/components/ServersView/*
Split viewer into MarkdownContent (marked + highlight.js + DOMPurify) and PdfContent; add document-viewer/fetch-content IPC with origin validation; thread documentFormat through actions/state; layout/style adjustments.
Screen sharing / desktop capturer
src/screenSharing/desktopCapturerCache.ts, src/screenSharing/ScreenSharingRequestTracker.ts, src/screenSharing/serverViewScreenSharing.ts, src/screenSharing/screenSharePicker.tsx, src/screenSharing/screenPicker/*, src/screenSharing/screenRecordingPermission.ts, src/ui/components/RootScreenSharePicker.tsx, src/ui/main/serverView/index.ts, src/videoCallWindow/*, src/ipc/channels.ts
Centralized capturer cache with TTL and in-flight dedupe; ScreenSharingRequestTracker for request lifecycle/timeouts; server-view displayMedia setup and provider selection; permission abstraction and parameterizable IPC channels; root-level picker wiring; integrate shared modules into video-call window.
Logging overhaul & privacy
src/logging/*, src/logViewerWindow/*, src/logging/dedup.ts, src/logging/privacy.ts, src/logging/context.ts, src/logging/index.ts, src/logging/preload.ts
Hostname-based context mapping; LogDeduplicator for IPC/file suppression; advanced redaction (tokens, PII, key policies); buffered NDJSON error logging with compaction; IPC rate-limiting and dedup; protected filenames; log-viewer tail reads and server filtering.
Outlook calendar sync & logging
src/outlookCalendar/*, src/outlookCalendar/reducers/*
Add allowInsecure option, pass httpsAgent through requests, detailed-events logging, dynamic interval (store-driven with override + watch), improved error sanitization, and stopOutlookCalendarSync export; new reducers/actions for interval/override and insecure setting.
Persisted settings, UI toggles & reducers
src/app/PersistableValues.ts, src/app/actions.ts, src/app/selectors.ts, src/ui/actions.ts, src/ui/reducers/*, src/store/rootReducer.ts, src/ui/components/SettingsView/features/*
Add outlookCalendarSyncInterval, isDetailedEventsLoggingEnabled, isDebugLoggingEnabled; new OverrideOnlySettings; migrations; new reducers and UI components for Outlook interval, detailed-events logging, and debug logging; clamp/override logic.
System certificates support
src/systemCertificates.ts, src/app/main/data.ts, docs/corporate-certificate-configuration.md
New module to load OS trust store CAs via overridden-settings.json, merge into Node default CAs, expose status; integrated into startup merge and documented configuration.
Video-call credentials & Pexip support
src/videoCallWindow/preload/index.ts, src/videoCallWindow/preload/jitsiBridge.ts, src/servers/preload/internalVideoChatWindow.ts, docs/pexip-auth-credentials.md
Expose videoCallWindow.getAuthCredentials() to webview; video-call-window/open-window accepts provider/credentials; conditional jitsiBridge init; internal video chat window enriches Pexip calls with persisted credentials; docs added.
Rollup / deps / package metadata
rollup.config.mjs, package.json, src/public/main.css
Mark new externals (marked, marked-highlight, highlight.js, dompurify); bump package version and electron; add dompurify, marked, highlight.js, github-markdown-css and types; import GitHub Markdown CSS.
i18n & interpolation
src/i18n/common.ts, src/i18n/*.i18n.json
Set i18next interpolation.escapeValue = false; add documentViewer titles/back and new logging/settings strings across locales; add log-viewer filter keys.
Log viewer UI & IPC
src/logViewerWindow/*, src/ui/components/*
Add read-logs-tail IPC, confirm-clear-logs, get-server-mapping; incremental tail streaming, server/workspace filtering UI, locale detection in log-viewer window, and server tag display in entries.
Tests, misc, docs & CI ignore
src/errors/main.spec.ts, src/main.spec.ts, .gitignore, AGENTS.md (removed), CLAUDE.md, other docs
New Bugsnag network tests; test mocks; added .gitignore patterns; AGENTS.md removal and expanded CLAUDE.md; docs for corporate certs and Pexip credentials; minor CI/test adjustments.
Other main lifecycle changes
src/main.ts, src/updates/main.ts, src/store/index.ts, src/public/log-viewer-window.html
Apply system certificates early in startup; register debug logging watcher; stop Outlook sync on before-quit; track user-initiated update checks; watch() warns if called before store init; set log-viewer HTML lang.

Sequence Diagram(s)

sequenceDiagram
  participant Guest as Guest WebContents
  participant Main as Main Process
  participant Provider as Root UI Provider
  participant Picker as Screen Picker (Renderer)
  participant Capturer as DesktopCapturer

  Guest->>Main: displayMedia request (guest)
  Main->>Main: create tracked request (ScreenSharingRequestTracker)
  Main->>Provider: send `screen-picker/open` IPC
  Provider->>Picker: show picker UI
  Picker->>Main: response (selected sourceId or null)
  Main->>Capturer: desktopCapturer.getSources() to validate sourceId
  Capturer-->>Main: sources metadata
  Main->>Guest: resolve displayMedia with selected source / reject on failure
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Comment thread src/ui/components/ServersView/MarkdownContent.tsx Fixed
Replace regex-based HTML stripping with document.createElement +
textContent for safe text extraction. Fixes CodeQL incomplete
multi-character sanitization warning.
Copy link
Copy Markdown
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: 12

Caution

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

⚠️ Outside diff range comments (3)
package.json (1)

156-163: ⚠️ Potential issue | 🟠 Major

Reconcile Node version specifications across engines, devEngines, and Volta.

The three version declarations diverge: engines.node requires >=24.11.1, but devEngines.runtime.version allows >=22.0.0 and Volta pins 22.22.1. This means developers using Volta will install a version engines.node explicitly marks as unsupported, creating a mismatch between local and CI environments.

Suggested alignment to `24.11.1`
   "devEngines": {
     "runtime": {
       "name": "node",
-      "version": ">=22.0.0"
+      "version": ">=24.11.1"
     }
   },
@@
   "volta": {
-    "node": "22.22.1",
+    "node": "24.11.1",
     "yarn": "4.6.0"
   },

Also applies to: 178-180

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

In `@package.json` around lines 156 - 163, Update the Node version declarations to
be consistent by aligning engines.node, devEngines.runtime.version, and the
Volta pin to the same minimum version (use "24.11.1"); specifically change the
engines.node value to ">=24.11.1" (if not already), set
devEngines.runtime.version to ">=24.11.1", and update the Volta pin (the "volta"
runtime/version entry) to "24.11.1" so local (Volta), dev, and CI requirements
match exactly.
.github/workflows/pull-request-build.yml (1)

520-524: ⚠️ Potential issue | 🟠 Major

Keep MSI out of the signed build phase.

The new msi target is being added to the same Windows build invocation that still runs with signing material in the environment. That reintroduces the exact KMS/CNG conflict this repo's packaging flow is supposed to avoid, so the new installer is likely to be flaky or fail outright in CI. Build the MSI unsigned here and sign the generated .msi afterward in the separate jsign phase.

Based on learnings: 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.

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

In @.github/workflows/pull-request-build.yml around lines 520 - 524, Remove the
MSI target from the signed Windows build invocation (the `yarn electron-builder
--publish never --x64 --ia32 --arm64 --win nsis msi` command) so the initial
electron-builder run produces unsigned MSI artifacts; clear or omit signing
environment variables (WIN_KMS_KEY_RESOURCE, WIN_CERT_FILE,
GOOGLE_APPLICATION_CREDENTIALS) during that build, then sign the generated .msi
in the separate `jsign` phase using the existing jsign job and Google Cloud KMS
credentials (i.e., move MSI signing out of the build step and into the jsign
step).
src/outlookCalendar/preload.ts (1)

8-21: ⚠️ Potential issue | 🟠 Major

Don't promote these preload success traces into the normal log stream.

These calls moved from console.log to console.info, so the success path now emits full event responses plus url/userId data at info level from a preload that cannot honor the verbose toggle. That adds a lot of noise and undermines the privacy/redaction work in this release. Please keep preload success logging off, or reduce it to a single redacted breadcrumb.

Based on learnings: Keep preload.ts logging minimal since it cannot access the verbose logging toggle from Redux Store and all logs always appear.

Also applies to: 34-42, 56-65, 78-85, 98-106

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

In `@src/outlookCalendar/preload.ts` around lines 8 - 21, The preload module emits
verbose success traces via console.info (e.g., the console.info calls around the
ipcRenderer.invoke('outlook-calendar/get-events', date) response handling and
the similar blocks at lines referenced), which bypass the app's verbose toggle
and leaks user/url data; replace those detailed console.info calls in preload.ts
(the success branches that log the full response, including the blocks after
ipcRenderer.invoke for get-events and the other similar response handlers at the
noted ranges) with a single minimal, redacted breadcrumb log (e.g., a one-line
note like "OutlookCalendar preload: events fetched" without
userIds/URLs/details) or remove them entirely so preload does not emit full
event/identity data. Ensure the change touches every success-path console.info
in this file (the blocks that log response objects) so only non-identifying,
minimal breadcrumbs remain.
🧹 Nitpick comments (15)
src/servers/common.ts (1)

31-32: Narrow documentViewerFormat to the supported literals.

Using string here removes the compiler backstop for the reducer/IPC/UI chain and lets typos survive until runtime. Please lift the supported values into a shared union/enum and reference that type here instead. As per coding guidelines, "Use TypeScript strict mode enabled in TypeScript configuration".

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

In `@src/servers/common.ts` around lines 31 - 32, Replace the loose string type
for documentViewerFormat with a shared literal union or enum (e.g.,
DocumentViewerFormat) that enumerates the exact supported values, export that
type and use it for documentViewerFormat in the interface so the reducer/IPC/UI
chain (and any uses of documentViewerFormat) get compile-time checking; update
any places referencing the old string (reducers, IPC messages, and UI props) to
import and use DocumentViewerFormat to prevent typos and enable TypeScript
strict validation.
.github/workflows/validate-pr.yml (1)

30-33: Include Node version in cache key after the runtime bump.

This avoids reusing stale node_modules caches built with older Node versions.

♻️ Suggested update
-          key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
+          key: ${{ runner.os }}-node-24.11.1-modules-${{ hashFiles('**/yarn.lock') }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/validate-pr.yml around lines 30 - 33, The cache key for
node_modules must include the Node runtime so caches from older Node versions
aren't reused; update the workflow's cache step that runs alongside the "Setup
Node 24.11.1" (actions/setup-node@v4) step to incorporate the node-version
(e.g., append or interpolate the node-version value like 24.11.1 or ${{
matrix.node-version }} / ${{ steps.setup-node.outputs.node-version }}) into the
cache key string (and restore-keys if used) so the cache key is unique per Node
runtime.
src/ui/main/serverView/index.ts (1)

175-189: Consider case-insensitive extension check for markdown files.

The current check item.getFilename().endsWith('.md') is case-sensitive. Markdown files could have extensions like .MD or .Md which would be missed.

Proposed fix
-    if (item.getFilename().endsWith('.md')) {
+    if (item.getFilename().toLowerCase().endsWith('.md')) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/ui/main/serverView/index.ts` around lines 175 - 189, The filename
extension check in the will-download handler is case-sensitive
(item.getFilename().endsWith('.md')) so files like ".MD" or ".Md" are missed;
update the check in the webviewSession.on('will-download', ...) handler to
compare a normalized filename (e.g., call item.getFilename() and convert to
lower case or use a case-insensitive regex) before calling item.cancel() and
dispatching SERVER_DOCUMENT_VIEWER_OPEN_URL so all markdown extensions are
detected; keep the rest of the logic (cancel and dispatch) unchanged.
src/videoCallWindow/preload/jitsiBridge.ts (1)

541-562: Consider adding debug logging for IPC fallback.

The empty catch block at line 548 silently swallows errors. While the fallback behavior is correct for backward compatibility, logging a debug message could help diagnose issues in development.

Proposed enhancement
 try {
   providerName = ipcRenderer.sendSync('video-call-window/get-provider-sync') as
     | string
     | null;
 } catch {
   // Fallback: if sync IPC fails, assume Jitsi for backward compatibility
+  console.debug('JitsiBridge: Sync IPC failed, defaulting to Jitsi initialization');
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/videoCallWindow/preload/jitsiBridge.ts` around lines 541 - 562, The empty
catch around ipcRenderer.sendSync('video-call-window/get-provider-sync')
swallows errors — update the catch to log a debug message including the caught
error and context (e.g., "IPC sync failed, falling back to Jitsi/unknown
provider") so failures are visible in development; keep the current fallback
behavior (leave providerName null and still create JitsiBridgeImpl), and
reference ipcRenderer.sendSync, providerName, JitsiBridgeImpl and
window.jitsiBridge when making the change.
src/documentViewer/ipc.ts (1)

38-61: Good security validations; consider adding a fetch timeout.

The origin validation and protocol checks provide good SSRF protection. However, ses.fetch(url) has no timeout, which could cause the handler to hang indefinitely on slow or unresponsive servers.

Proposed enhancement with AbortController timeout
       const partition = `persist:${serverUrl}`;
       const ses = session.fromPartition(partition);
-      const response = await ses.fetch(url);
+      const controller = new AbortController();
+      const timeoutId = setTimeout(() => controller.abort(), 30000);
+      try {
+        const response = await ses.fetch(url, { signal: controller.signal });
+        clearTimeout(timeoutId);
         if (!response.ok) {
           throw new Error(`Failed to fetch: ${response.status}`);
         }
         return response.text();
+      } catch (error) {
+        clearTimeout(timeoutId);
+        throw error;
+      }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/documentViewer/ipc.ts` around lines 38 - 61, The fetch handler for
'document-viewer/fetch-content' currently calls
session.fromPartition(...).fetch(url) with no timeout; add an AbortController
around ses.fetch to avoid hanging: create an AbortController, start a timeout
(e.g., 10s) that calls controller.abort(), pass controller.signal to ses.fetch,
clear the timeout on success, and catch an aborted/error state to throw a clear
timeout error; update the handler block where
handle('document-viewer/fetch-content', ...) and the ses.fetch call are located
to incorporate this logic.
src/ui/components/SettingsView/features/OutlookCalendarSyncInterval.tsx (2)

29-40: Input value may desync from displayed value after clamping.

When the user enters a value outside [1, 60], the clamped value is dispatched to Redux, but the InputBox continues showing the raw typed value until re-render. Since intervalMinutes from Redux is bound to value, this should eventually sync, but there could be a brief visual inconsistency or the input may retain focus with the invalid value.

Consider dispatching unconditionally or clearing/resetting the input if validation fails, to ensure the displayed value always matches the persisted state.

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

In `@src/ui/components/SettingsView/features/OutlookCalendarSyncInterval.tsx`
around lines 29 - 40, The input can show a raw out-of-range or non-numeric value
while the reducer gets a clamped number; update handleChange so it always
dispatches a normalized value to keep the displayed value in sync: in
handleChange (the callback that currently parses event.currentTarget.value)
parse the value, compute a clamped value within [1,60] (treat NaN as a fallback
like 1 or the previous valid value), and unconditionally dispatch
SETTINGS_SET_OUTLOOK_CALENDAR_SYNC_INTERVAL_CHANGED with that clamped number so
the InputBox value bound to intervalMinutes immediately reflects the validated
state.

62-71: Consider using Fuselage spacing tokens instead of inline styles.

The inline style={{ paddingTop: '4px' }} could be replaced with Fuselage's pt (padding-top) prop for consistency with the design system.

Suggested change
-        <Box display='flex' alignItems='center' style={{ paddingTop: '4px' }}>
+        <Box display='flex' alignItems='center' pt='x4'>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/ui/components/SettingsView/features/OutlookCalendarSyncInterval.tsx`
around lines 62 - 71, The Box wrapper for the InputBox uses an inline style
paddingTop (style={{ paddingTop: '4px' }}); replace this inline style with
Fuselage spacing tokens by removing the style prop and adding the pt prop on the
Box (use the appropriate token, e.g. pt='x2', to match the 4px spacing) so the
component (Box wrapping InputBox with id fieldId, value intervalMinutes and
onChange handleChange) follows the design system spacing conventions.
src/logViewerWindow/ipc.ts (1)

487-503: Consider using the Server type instead of any.

The forEach callback uses any for the server parameter. Since Server is already defined elsewhere in the codebase, using it would improve type safety.

💡 Import and use Server type
+import type { Server } from '../servers/common';
 import { getRootWindow } from '../ui/main/rootWindow';
-      servers.forEach((server: any) => {
+      servers.forEach((server: Server) => {
         if (!server.url) return;
         const host = getHost(server.url);
         mapping[host] = server.title || server.url;
       });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/logViewerWindow/ipc.ts` around lines 487 - 503, The forEach callback in
the IPC handler for 'log-viewer-window/get-server-mapping' uses an untyped
server parameter (any); import the existing Server type and change the callback
signature to use Server (e.g., servers.forEach((server: Server) => { ... })) and
adjust any related local typings (the select call returning RootState should
already give servers: Server[]); this ensures type safety for server.url and
server.title while keeping the rest of the logic (getHost, mapping) unchanged.
build/msiProjectCreated.js (1)

42-73: Consider whether On Error Resume Next could mask unexpected errors.

The VBScript uses On Error Resume Next and then explicitly checks Err.Number at specific points. While explicit error checks are present for file creation and writing, any errors between those checks (e.g., in CreateObject or Session.Property) would be silently ignored. This is a common VBScript pattern, but worth noting.

The explicit Err.Raise calls ensure critical failures are reported, so the current implementation should be sufficient for the intended use case.

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

In `@build/msiProjectCreated.js` around lines 42 - 73, The script currently uses a
global "On Error Resume Next" which can hide failures before the explicit
Err.Number checks; narrow error suppression or add immediate error checks:
remove the broad "On Error Resume Next" and instead use it only around specific
risky calls (e.g., CreateObject("Scripting.FileSystemObject") and reading
Session.Property("CustomActionData")), then immediately check Err.Number and
call Err.Raise with context (using the "WriteUpdateJson" source) if set; after
those checks use "On Error Goto 0" to restore normal error handling so
subsequent unexpected errors aren't silently ignored; keep the existing
Err.Raise locations for file/folder checks as-is.
src/systemCertificates.ts (1)

27-42: Last file wins in settings precedence — verify this is intentional.

The loop iterates over [userData, appPath] and doesn't break on first match, so if both files contain useSystemCertificates, the appPath (system-wide) location takes precedence. This seems like reasonable admin-override behavior, but confirm this is the intended priority order.

💡 Consider adding a comment clarifying precedence
 const readUseSystemCertificatesSetting = (): boolean => {
+  // Settings are read in order: user data first, then app path.
+  // Later values override earlier ones, so app path (system-wide) takes precedence.
   const locations = [
     path.join(app.getPath('userData'), 'overridden-settings.json'),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/systemCertificates.ts` around lines 27 - 42, The loop over locations
currently lets later files override earlier ones (the variable enabled is
reassigned for each matching useSystemCertificates entry), so appPath wins over
userData; either confirm that last-file-wins is intended and add a clear comment
above the for (const filePath of locations) loop explaining the precedence
(appPath overrides userData), or change the logic to stop on the first match
(add a break after setting enabled) if you want first-match precedence; update
any related tests for isSystemCertificatesEnabled (or the function/name
containing this logic) accordingly.
src/outlookCalendar/logger.ts (1)

58-70: Consider making outlookWarn always visible like outlookError.

The outlookError function correctly ensures the message is always logged (line 68), with details only shown when verbose mode is enabled. However, outlookWarn (lines 58-62) is entirely gated by verbose logging, which may hide important warnings from users.

Consider whether warnings should follow the same pattern as errors - always showing the message while gating verbose details:

♻️ Suggested pattern for consistent warning visibility
 export const outlookWarn = (...args: unknown[]): void => {
   if (global.isVerboseOutlookLoggingEnabled) {
     console.warn(prefix, ...args);
+  } else {
+    console.warn(prefix, args[0]);
   }
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/outlookCalendar/logger.ts` around lines 58 - 70, outlookWarn currently
only logs when global.isVerboseOutlookLoggingEnabled is true which can hide
important warnings; change outlookWarn to always call console.warn(prefix,
message) and only include extra details when
global.isVerboseOutlookLoggingEnabled is true (mirror the pattern used by
outlookError), referencing the outlookWarn function, the prefix variable, and
global.isVerboseOutlookLoggingEnabled to locate and adjust the logic so the
warning message is always emitted and verbose details are conditional.
src/ui/components/ServersView/MarkdownContent.tsx (1)

102-110: Incomplete HTML tag stripping in slug generation - mitigated by DOMPurify.

The regex /<[^>]*>/g at line 105 only removes complete HTML tags. Malformed inputs like <script (without closing >) could survive, as flagged by CodeQL. However, the generated HTML is sanitized by DOMPurify at lines 179-183 before rendering, which provides effective XSS protection.

For defense-in-depth, consider a more robust approach that also handles partial tags:

🛡️ Suggested improvement
     heading({ text, depth }: { text: string; depth: number }) {
       const slug = text
         .toLowerCase()
-        .replace(/<[^>]*>/g, '')
+        .replace(/<[^>]*>?/g, '')
         .replace(/[^\w\s-]/g, '')
         .replace(/\s+/g, '-')
         .replace(/-+/g, '-')
         .trim();
       return `<h${depth} id="${slug}">${text}</h${depth}>`;
     },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/ui/components/ServersView/MarkdownContent.tsx` around lines 102 - 110,
The slug generation in the heading(...) function currently uses
.replace(/<[^>]*>/g, '') which only strips complete tags and can leave partial
tag fragments (e.g., '<script')—update the slug creation for defense-in-depth by
more aggressively removing any stray '<' or '>' characters and any partial
tag-like sequences before applying the non-word/whitespace and hyphen
normalizations; modify the slug variable in heading to first strip or neutralize
'<' and '>' (and sequences that start with '<' up to whitespace or string end),
then continue the existing lowercasing, punctuation removal,
whitespace-to-hyphen collapse, and trimming, while keeping DOMPurify usage at
the render path (lines ~179-183) for runtime sanitization.
src/logViewerWindow/logViewerWindow.tsx (1)

257-326: Client-side entry limit after fetching all logs may cause performance issues.

The loadLogs function now always requests limit: 'all' from IPC (line 263), then applies entryLimit only client-side in filteredLogs. For very large log files, this means:

  1. Reading the entire file into memory on every load
  2. Parsing all log entries regardless of the display limit
  3. Transferring large strings over IPC

This could cause UI freezes or memory pressure with multi-MB log files.

♻️ Consider applying the limit server-side for initial load
       const response = (await ipcRenderer.invoke(
         'log-viewer-window/read-logs',
         {
-          limit: 'all',
+          limit: entryLimit === 'all' ? 'all' : parseInt(entryLimit) * 2, // Fetch extra for filtering headroom
           filePath: currentLogFile.isDefaultLog
             ? undefined
             : currentLogFile.filePath,
         }
       )) as ReadLogsResponse;

Alternatively, if fetching all logs is intentional for accurate filtering, consider adding a loading indicator or virtualized parsing for large files.

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

In `@src/logViewerWindow/logViewerWindow.tsx` around lines 257 - 326, The loadLogs
function currently always requests 'limit: "all"' from
ipcRenderer.invoke('log-viewer-window/read-logs') causing full-file reads;
change the RPC payload to pass a server-side limit (use the UI's entryLimit or a
sensible default) so the backend returns only needed lines, and update the call
site in loadLogs and any related logic in parseLogLines/filteredLogs to handle
partial results (e.g., totalEntries metadata still used for pagination),
ensuring lastKnownSizeRef and setFileInfo are updated from the response; if full
fetch is still needed for specific filters, gate that behavior behind an
explicit "fetchAll" flag instead of unconditional 'all'.
src/logging/index.ts (1)

288-293: Rate limiting prevents flooding but silently drops messages.

The rate limit of 100 messages per second per sender is reasonable for preventing compromised webviews from flooding logs. However, dropped messages are silently ignored, which could hide important information during high-activity periods.

💡 Consider logging periodic drop counts
+    const droppedCounts = new Map<number, number>();
+    const DROPPED_LOG_INTERVAL_MS = 60_000;
+
+    setInterval(() => {
+      for (const [senderId, count] of droppedCounts) {
+        if (count > 0) {
+          log.warn(`[logging] Dropped ${count} messages from webContents ${senderId} due to rate limiting`);
+          droppedCounts.set(senderId, 0);
+        }
+      }
+    }, DROPPED_LOG_INTERVAL_MS);

         rateState.count++;
         if (rateState.count > MAX_IPC_MESSAGES_PER_SECOND) {
+          droppedCounts.set(senderId, (droppedCounts.get(senderId) || 0) + 1);
           return;
         }

Also applies to: 418-427

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

In `@src/logging/index.ts` around lines 288 - 293, The rate limiter (ipcRateLimit
and MAX_IPC_MESSAGES_PER_SECOND) currently drops excess messages silently;
modify the per-sender map value to also track a droppedCount and timestamp of
lastReport, increment droppedCount whenever a message is dropped, and ensure the
code emits a periodic summary log (e.g., every N seconds or when resetTime
elapses) using the existing logger (e.g., logger.warn/processLogger.warn) that
reports the sender id, droppedCount and resetTime, then reset droppedCount after
reporting; apply the same change to the analogous rate-limit block around lines
418-427 so dropped counts are aggregated and surfaced instead of being ignored.
src/outlookCalendar/ipc.ts (1)

1287-1310: Potential unhandled promise rejection in watch callback.

The async maybeSyncEvents call inside setTimeout (line 1302) catches errors, but the startRecurringSyncTask call (line 1306) happens unconditionally after, even if the sync failed. This is likely intentional (restart regardless of sync outcome), but the error logging could be improved.

Also, the for...of loop iterates over serverSyncStates while potentially modifying it (via startRecurringSyncTask which calls getServerState). While getServerState only adds entries (not removes), this is safe but worth noting.

💡 Consider capturing server references before iteration
     (curr, prev) => {
       if (prev === undefined || curr === prev) return;
       outlookLog(
         `Outlook sync interval changed to ${curr} minutes, rescheduling sync jobs`
       );
-      for (const [, state] of serverSyncStates) {
+      const activeServers = [...serverSyncStates.values()]
+        .filter((state) => state.serverRef && state.userAPIToken)
+        .map((state) => ({ server: state.serverRef!, state }));
+
+      for (const { server, state } of activeServers) {
-        if (!state.serverRef || !state.userAPIToken) continue;
         clearTimeout(state.restartDebounceTimer);
-        const server = state.serverRef;
         state.restartDebounceTimer = setTimeout(async () => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/outlookCalendar/ipc.ts` around lines 1287 - 1310, The watch callback
risks unobserved/reordered behavior and iterating a mutating Map; fix by
snapshotting server refs before the loop (e.g.,
Array.from(serverSyncStates.values()) or mapping to servers) and for each
snapshot entry call clearTimeout/setTimeout, then inside the timeout use try {
await maybeSyncEvents(server); } catch (e) { outlookError(`Error syncing after
interval change for ${server.id ?? '<unknown>'}:`, e); } finally {
startRecurringSyncTask(server); } so startRecurringSyncTask runs
deterministically after the sync attempt and errors are logged with server
context; update references to watch, serverSyncStates, maybeSyncEvents,
startRecurringSyncTask, outlookError and outlookLog accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/errors/main.spec.ts`:
- Around line 106-119: The test helper unsetEnvVar currently leaves keys present
by redefining process.env[key] to undefined, and restoreEnvVars does not remove
keys that originally did not exist; update unsetEnvVar and restoreEnvVars to
record previous descriptor/existence in envMocks (already done) and on restore,
if envMocks.get(key).existed is false then delete process.env[key] (or use
Reflect.deleteProperty) instead of redefining to undefined, otherwise restore
the original descriptor/value using Object.defineProperty with the saved
descriptor; ensure this logic is applied for all keys managed by envMocks in the
restoreEnvVars function.

In `@src/i18n/common.ts`:
- Around line 105-107: The shared i18n config currently sets escapeValue: false
on the exported interpolation object (InitOptions['interpolation']), which
disables HTML escaping for all {{ }} interpolations; change this to enable
escaping by default (set escapeValue: true or remove the false override) so
regular {{ }} tokens are HTML-escaped, and rely on i18next's existing unescaped
syntax (e.g., {{- }}) or per-call options when you intentionally need raw HTML;
update the interpolation object and keep the format function as-is.

In `@src/logging/dedup.ts`:
- Around line 45-52: The dedup logic in shouldLog allows errors but doesn't
clear the stored non-error key, so a later identical non-error message gets
wrongly suppressed; update shouldLog (and the analogous method covering lines
66-85) to reset this.lastIpcKey when level === 'error' (after returning true) so
the previous key is cleared; locate uses of makeKey and lastIpcKey in shouldLog
and the other dedup function and ensure an error fast-path both returns true and
clears lastIpcKey so subsequent non-error messages are not deduplicated against
the pre-error key.

In `@src/logging/privacy.ts`:
- Around line 37-85: CREDENTIAL_KV_PATTERNS currently only redacts values of 8+
chars, allowing short secrets like "password=secret" or "token=abc12345" to
leak; update the CREDENTIAL_KV_PATTERNS array so that known secret keys (e.g.,
entries for 'password', 'passwd', 'secret', 'api_key', 'auth_token',
'access_token', 'refresh_token', 'authorization', 'client_secret',
'private_key', 'webhook_url', etc.) do not impose the {8,} length requirement
and will match and redact any non-empty value, and add a generic token matcher
(e.g., a `/\btoken["'\s:=]+["']?([^"'\s,}\]]+)/gi` style entry) to catch
free-form "token" pairs; locate and modify the CREDENTIAL_KV_PATTERNS constant
to remove the length quantifier for known keys and append the generic token
pattern so short secrets are also redacted.

In `@src/main.ts`:
- Around line 65-68: The call to applySystemCertificates() in start() invokes
Electron APIs (via readUseSystemCertificatesSetting()) before the app is ready;
move the applySystemCertificates() invocation to occur after awaiting
app.whenReady() (i.e., call await app.whenReady() then call
applySystemCertificates()), leaving setUserDataDirectory() where it is if it
does not depend on app readiness, and ensure any code that relies on system
certificate setup runs after the moved call.

In `@src/outlookCalendar/errorClassification.ts`:
- Around line 232-247: The SENSITIVE_CONTEXT_KEYS set and isSensitiveKey
function miss cookie headers so session cookies can leak; update
SENSITIVE_CONTEXT_KEYS (used in isSensitiveKey) to include 'cookie' and
'set-cookie' and extend the isSensitiveKey checks to treat any key containing
'cookie' as sensitive (in addition to the existing
token/password/secret/authorization checks) so header keys like 'cookie' and
'set-cookie' are redacted during Outlook logging.
- Around line 69-70: The TLS error regex in the pattern (in
errorClassification.ts) uses literal dots and misses space-separated messages;
update the regex to match natural language forms by replacing "self\.signed" and
"certificate\.has\.expired" with "self\s+signed" and
"certificate\s+has\s+expired" and include the space-separated variant of "UNABLE
TO VERIFY" (e.g., add "UNABLE TO VERIFY" or a pattern like
"UNABLE[_\s]TO[_\s]VERIFY") so the pattern (used by the pattern entry) will
catch strings like "self signed certificate", "certificate has expired", and
"unable to verify the first certificate".

In `@src/ui/components/ServersView/MarkdownContent.tsx`:
- Around line 16-26: The inserted link elements lightLink and darkLink use
hardcoded ../node_modules paths that will break in production; change the
implementation to resolve the stylesheet paths dynamically (like Shell does) by
using the app path variable (e.g., appPath or an equivalent bundled asset
resolver) or import the CSS assets so bundler/Electron serves them correctly,
then set lightLink.href and darkLink.href to those resolved URLs before
appending to document.head; ensure the symbols lightLink and darkLink and their
.href assignments are updated to use the resolved path variable or imported
asset reference.

In `@src/ui/components/ServersView/PdfContent.tsx`:
- Around line 41-45: The click handler added via document.addEventListener
currently only checks event.target.tagName === 'A' and href.endsWith('.pdf'),
which misses clicks on nested elements, querystrings/fragments, and different
case extensions; update the handler used in PdfContent.tsx to find the nearest
anchor with event.target.closest('a') (or equivalent), obtain its href, create a
URL against document.baseURI, and test the pathname case-insensitively for a
trailing ".pdf" (e.g. pathname.toLowerCase().endsWith('.pdf')); if it matches,
call event.preventDefault() as before. Ensure you reference the existing
listener registration (document.addEventListener) and the inline click callback
so the change replaces the current checks only.
- Around line 19-26: The effect is rescheduling duplicate navigations because
documentUrl is in the dependency array; change the useEffect to depend only on
url, not documentUrl, so it runs only when url changes, and when you call
setDocumentUrl('about:blank') schedule the delayed setDocumentUrl(url) with
setTimeout but store the timer id and clear it in the effect cleanup to avoid
multiple queued navigations; update the useEffect signature and add a cleanup
that calls clearTimeout on the saved timer id and resets/ignores it after firing
so rapid url changes don't enqueue duplicate navigations (refer to useEffect,
url, documentUrl, setDocumentUrl).

In `@src/ui/main/rootWindow.ts`:
- Around line 528-579: The current createRootWindowContextMenu builds a menu
only from editFlags (canUndo/canRedo/canCut/etc.), losing link/image/spellcheck
actions; update createRootWindowContextMenu (and the contextmenu handler that
currently always replaces the default) to follow the popupMenu.ts pattern:
detect ContextMenuParams.linkURL, mediaType, and isEditable and merge templates
(link actions, media/image actions, spellcheck suggestions, plus the edit
template) so link/image actions appear when present, or alternatively only
override the default menu when isEditable is true; reference the
createRootWindowContextMenu function and ContextMenuParams type and reuse the
conditional template builders from popupMenu.ts to compose the final
Menu.buildFromTemplate result.

In `@src/updates/main.ts`:
- Around line 165-166: The shared boolean isUserInitiatedCheck is racy across
concurrent checks; change the logic so the origin is tracked per-request (e.g.,
pass a userInitiated flag into checkForUpdates() or return a request token)
instead of a single module-level variable, and ensure you clear/reset that
request-scoped flag in all terminal event handlers ('update-available',
'update-not-available', 'error') or when the request completes/aborts so one
request cannot affect another; update references to isUserInitiatedCheck (and
the checkForUpdates() caller) accordingly to use the per-request flag or token.

---

Outside diff comments:
In @.github/workflows/pull-request-build.yml:
- Around line 520-524: Remove the MSI target from the signed Windows build
invocation (the `yarn electron-builder --publish never --x64 --ia32 --arm64
--win nsis msi` command) so the initial electron-builder run produces unsigned
MSI artifacts; clear or omit signing environment variables
(WIN_KMS_KEY_RESOURCE, WIN_CERT_FILE, GOOGLE_APPLICATION_CREDENTIALS) during
that build, then sign the generated .msi in the separate `jsign` phase using the
existing jsign job and Google Cloud KMS credentials (i.e., move MSI signing out
of the build step and into the jsign step).

In `@package.json`:
- Around line 156-163: Update the Node version declarations to be consistent by
aligning engines.node, devEngines.runtime.version, and the Volta pin to the same
minimum version (use "24.11.1"); specifically change the engines.node value to
">=24.11.1" (if not already), set devEngines.runtime.version to ">=24.11.1", and
update the Volta pin (the "volta" runtime/version entry) to "24.11.1" so local
(Volta), dev, and CI requirements match exactly.

In `@src/outlookCalendar/preload.ts`:
- Around line 8-21: The preload module emits verbose success traces via
console.info (e.g., the console.info calls around the
ipcRenderer.invoke('outlook-calendar/get-events', date) response handling and
the similar blocks at lines referenced), which bypass the app's verbose toggle
and leaks user/url data; replace those detailed console.info calls in preload.ts
(the success branches that log the full response, including the blocks after
ipcRenderer.invoke for get-events and the other similar response handlers at the
noted ranges) with a single minimal, redacted breadcrumb log (e.g., a one-line
note like "OutlookCalendar preload: events fetched" without
userIds/URLs/details) or remove them entirely so preload does not emit full
event/identity data. Ensure the change touches every success-path console.info
in this file (the blocks that log response objects) so only non-identifying,
minimal breadcrumbs remain.

---

Nitpick comments:
In @.github/workflows/validate-pr.yml:
- Around line 30-33: The cache key for node_modules must include the Node
runtime so caches from older Node versions aren't reused; update the workflow's
cache step that runs alongside the "Setup Node 24.11.1" (actions/setup-node@v4)
step to incorporate the node-version (e.g., append or interpolate the
node-version value like 24.11.1 or ${{ matrix.node-version }} / ${{
steps.setup-node.outputs.node-version }}) into the cache key string (and
restore-keys if used) so the cache key is unique per Node runtime.

In `@build/msiProjectCreated.js`:
- Around line 42-73: The script currently uses a global "On Error Resume Next"
which can hide failures before the explicit Err.Number checks; narrow error
suppression or add immediate error checks: remove the broad "On Error Resume
Next" and instead use it only around specific risky calls (e.g.,
CreateObject("Scripting.FileSystemObject") and reading
Session.Property("CustomActionData")), then immediately check Err.Number and
call Err.Raise with context (using the "WriteUpdateJson" source) if set; after
those checks use "On Error Goto 0" to restore normal error handling so
subsequent unexpected errors aren't silently ignored; keep the existing
Err.Raise locations for file/folder checks as-is.

In `@src/documentViewer/ipc.ts`:
- Around line 38-61: The fetch handler for 'document-viewer/fetch-content'
currently calls session.fromPartition(...).fetch(url) with no timeout; add an
AbortController around ses.fetch to avoid hanging: create an AbortController,
start a timeout (e.g., 10s) that calls controller.abort(), pass
controller.signal to ses.fetch, clear the timeout on success, and catch an
aborted/error state to throw a clear timeout error; update the handler block
where handle('document-viewer/fetch-content', ...) and the ses.fetch call are
located to incorporate this logic.

In `@src/logging/index.ts`:
- Around line 288-293: The rate limiter (ipcRateLimit and
MAX_IPC_MESSAGES_PER_SECOND) currently drops excess messages silently; modify
the per-sender map value to also track a droppedCount and timestamp of
lastReport, increment droppedCount whenever a message is dropped, and ensure the
code emits a periodic summary log (e.g., every N seconds or when resetTime
elapses) using the existing logger (e.g., logger.warn/processLogger.warn) that
reports the sender id, droppedCount and resetTime, then reset droppedCount after
reporting; apply the same change to the analogous rate-limit block around lines
418-427 so dropped counts are aggregated and surfaced instead of being ignored.

In `@src/logViewerWindow/ipc.ts`:
- Around line 487-503: The forEach callback in the IPC handler for
'log-viewer-window/get-server-mapping' uses an untyped server parameter (any);
import the existing Server type and change the callback signature to use Server
(e.g., servers.forEach((server: Server) => { ... })) and adjust any related
local typings (the select call returning RootState should already give servers:
Server[]); this ensures type safety for server.url and server.title while
keeping the rest of the logic (getHost, mapping) unchanged.

In `@src/logViewerWindow/logViewerWindow.tsx`:
- Around line 257-326: The loadLogs function currently always requests 'limit:
"all"' from ipcRenderer.invoke('log-viewer-window/read-logs') causing full-file
reads; change the RPC payload to pass a server-side limit (use the UI's
entryLimit or a sensible default) so the backend returns only needed lines, and
update the call site in loadLogs and any related logic in
parseLogLines/filteredLogs to handle partial results (e.g., totalEntries
metadata still used for pagination), ensuring lastKnownSizeRef and setFileInfo
are updated from the response; if full fetch is still needed for specific
filters, gate that behavior behind an explicit "fetchAll" flag instead of
unconditional 'all'.

In `@src/outlookCalendar/ipc.ts`:
- Around line 1287-1310: The watch callback risks unobserved/reordered behavior
and iterating a mutating Map; fix by snapshotting server refs before the loop
(e.g., Array.from(serverSyncStates.values()) or mapping to servers) and for each
snapshot entry call clearTimeout/setTimeout, then inside the timeout use try {
await maybeSyncEvents(server); } catch (e) { outlookError(`Error syncing after
interval change for ${server.id ?? '<unknown>'}:`, e); } finally {
startRecurringSyncTask(server); } so startRecurringSyncTask runs
deterministically after the sync attempt and errors are logged with server
context; update references to watch, serverSyncStates, maybeSyncEvents,
startRecurringSyncTask, outlookError and outlookLog accordingly.

In `@src/outlookCalendar/logger.ts`:
- Around line 58-70: outlookWarn currently only logs when
global.isVerboseOutlookLoggingEnabled is true which can hide important warnings;
change outlookWarn to always call console.warn(prefix, message) and only include
extra details when global.isVerboseOutlookLoggingEnabled is true (mirror the
pattern used by outlookError), referencing the outlookWarn function, the prefix
variable, and global.isVerboseOutlookLoggingEnabled to locate and adjust the
logic so the warning message is always emitted and verbose details are
conditional.

In `@src/servers/common.ts`:
- Around line 31-32: Replace the loose string type for documentViewerFormat with
a shared literal union or enum (e.g., DocumentViewerFormat) that enumerates the
exact supported values, export that type and use it for documentViewerFormat in
the interface so the reducer/IPC/UI chain (and any uses of documentViewerFormat)
get compile-time checking; update any places referencing the old string
(reducers, IPC messages, and UI props) to import and use DocumentViewerFormat to
prevent typos and enable TypeScript strict validation.

In `@src/systemCertificates.ts`:
- Around line 27-42: The loop over locations currently lets later files override
earlier ones (the variable enabled is reassigned for each matching
useSystemCertificates entry), so appPath wins over userData; either confirm that
last-file-wins is intended and add a clear comment above the for (const filePath
of locations) loop explaining the precedence (appPath overrides userData), or
change the logic to stop on the first match (add a break after setting enabled)
if you want first-match precedence; update any related tests for
isSystemCertificatesEnabled (or the function/name containing this logic)
accordingly.

In `@src/ui/components/ServersView/MarkdownContent.tsx`:
- Around line 102-110: The slug generation in the heading(...) function
currently uses .replace(/<[^>]*>/g, '') which only strips complete tags and can
leave partial tag fragments (e.g., '<script')—update the slug creation for
defense-in-depth by more aggressively removing any stray '<' or '>' characters
and any partial tag-like sequences before applying the non-word/whitespace and
hyphen normalizations; modify the slug variable in heading to first strip or
neutralize '<' and '>' (and sequences that start with '<' up to whitespace or
string end), then continue the existing lowercasing, punctuation removal,
whitespace-to-hyphen collapse, and trimming, while keeping DOMPurify usage at
the render path (lines ~179-183) for runtime sanitization.

In `@src/ui/components/SettingsView/features/OutlookCalendarSyncInterval.tsx`:
- Around line 29-40: The input can show a raw out-of-range or non-numeric value
while the reducer gets a clamped number; update handleChange so it always
dispatches a normalized value to keep the displayed value in sync: in
handleChange (the callback that currently parses event.currentTarget.value)
parse the value, compute a clamped value within [1,60] (treat NaN as a fallback
like 1 or the previous valid value), and unconditionally dispatch
SETTINGS_SET_OUTLOOK_CALENDAR_SYNC_INTERVAL_CHANGED with that clamped number so
the InputBox value bound to intervalMinutes immediately reflects the validated
state.
- Around line 62-71: The Box wrapper for the InputBox uses an inline style
paddingTop (style={{ paddingTop: '4px' }}); replace this inline style with
Fuselage spacing tokens by removing the style prop and adding the pt prop on the
Box (use the appropriate token, e.g. pt='x2', to match the 4px spacing) so the
component (Box wrapping InputBox with id fieldId, value intervalMinutes and
onChange handleChange) follows the design system spacing conventions.

In `@src/ui/main/serverView/index.ts`:
- Around line 175-189: The filename extension check in the will-download handler
is case-sensitive (item.getFilename().endsWith('.md')) so files like ".MD" or
".Md" are missed; update the check in the webviewSession.on('will-download',
...) handler to compare a normalized filename (e.g., call item.getFilename() and
convert to lower case or use a case-insensitive regex) before calling
item.cancel() and dispatching SERVER_DOCUMENT_VIEWER_OPEN_URL so all markdown
extensions are detected; keep the rest of the logic (cancel and dispatch)
unchanged.

In `@src/videoCallWindow/preload/jitsiBridge.ts`:
- Around line 541-562: The empty catch around
ipcRenderer.sendSync('video-call-window/get-provider-sync') swallows errors —
update the catch to log a debug message including the caught error and context
(e.g., "IPC sync failed, falling back to Jitsi/unknown provider") so failures
are visible in development; keep the current fallback behavior (leave
providerName null and still create JitsiBridgeImpl), and reference
ipcRenderer.sendSync, providerName, JitsiBridgeImpl and window.jitsiBridge when
making the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bd194af7-d274-4e47-a93b-97e9d183b811

📥 Commits

Reviewing files that changed from the base of the PR and between 729605b and af40a4a.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (112)
  • .github/workflows/build-release.yml
  • .github/workflows/pull-request-build.yml
  • .github/workflows/validate-pr.yml
  • .gitignore
  • AGENTS.md
  • CLAUDE.md
  • build/msiProjectCreated.js
  • docs/corporate-certificate-configuration.md
  • docs/pexip-auth-credentials.md
  • electron-builder.json
  • package.json
  • rollup.config.mjs
  • src/app/PersistableValues.ts
  • src/app/actions.ts
  • src/app/main/data.ts
  • src/app/selectors.ts
  • src/documentViewer/ipc.ts
  • src/errors.ts
  • src/errors/main.spec.ts
  • src/i18n/ar.i18n.json
  • src/i18n/common.ts
  • 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/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/ipc/channels.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/dedup.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/outlookCalendar/AGENTS.md
  • src/outlookCalendar/errorClassification.ts
  • src/outlookCalendar/getOutlookEvents.ts
  • src/outlookCalendar/ipc.ts
  • src/outlookCalendar/logger.ts
  • src/outlookCalendar/preload.ts
  • src/outlookCalendar/reducers/allowInsecureOutlookConnections.ts
  • src/outlookCalendar/reducers/outlookCalendarSyncInterval.ts
  • src/outlookCalendar/reducers/outlookCalendarSyncIntervalOverride.ts
  • src/public/log-viewer-window.html
  • src/public/main.css
  • src/screenSharing/ScreenSharingRequestTracker.ts
  • src/screenSharing/desktopCapturerCache.ts
  • src/screenSharing/screenPicker/createScreenPicker.ts
  • src/screenSharing/screenPicker/index.ts
  • src/screenSharing/screenPicker/providers/InternalPickerProvider.ts
  • src/screenSharing/screenPicker/providers/PortalPickerProvider.ts
  • src/screenSharing/screenPicker/types.ts
  • src/screenSharing/screenRecordingPermission.ts
  • src/screenSharing/screenSharePicker.tsx
  • src/screenSharing/serverViewScreenSharing.ts
  • src/servers/actions.ts
  • src/servers/common.ts
  • src/servers/preload/internalVideoChatWindow.ts
  • src/servers/reducers.ts
  • src/store/index.ts
  • src/store/rootReducer.ts
  • src/systemCertificates.ts
  • src/ui/actions.ts
  • src/ui/components/RootScreenSharePicker.tsx
  • src/ui/components/ServersView/DocumentViewer.tsx
  • src/ui/components/ServersView/MarkdownContent.tsx
  • src/ui/components/ServersView/PdfContent.tsx
  • src/ui/components/ServersView/ServerPane.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/features/DebugLogging.tsx
  • src/ui/components/SettingsView/features/DetailedEventsLogging.tsx
  • src/ui/components/SettingsView/features/OutlookCalendarSyncInterval.tsx
  • src/ui/components/Shell/index.tsx
  • src/ui/main/rootWindow.ts
  • src/ui/main/serverView/index.ts
  • src/ui/reducers/isDebugLoggingEnabled.ts
  • src/ui/reducers/isDetailedEventsLoggingEnabled.ts
  • src/updates/main.ts
  • src/videoCallWindow/ipc.ts
  • src/videoCallWindow/preload/index.ts
  • src/videoCallWindow/preload/jitsiBridge.ts
  • src/videoCallWindow/screenSharePickerMount.tsx
  • src/videoCallWindow/video-call-window.ts
  • workspaces/desktop-release-action/package.json
💤 Files with no reviewable changes (3)
  • src/logViewerWindow/constants.ts
  • src/logging/utils.ts
  • AGENTS.md

Comment thread src/errors/main.spec.ts
Comment on lines +106 to +119
const unsetEnvVar = (key: string): void => {
if (!envMocks.has(key)) {
envMocks.set(key, {
descriptor: Object.getOwnPropertyDescriptor(process.env, key),
existed: key in process.env,
});
}
Object.defineProperty(process.env, key, {
value: undefined,
writable: true,
enumerable: false,
configurable: true,
});
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

restoreEnvVars does not fully restore “unset” state.

Line 126 currently redefines missing keys as undefined instead of removing them. That leaves keys present in process.env and can leak state between tests.

Proposed fix
 const unsetEnvVar = (key: string): void => {
   if (!envMocks.has(key)) {
     envMocks.set(key, {
       descriptor: Object.getOwnPropertyDescriptor(process.env, key),
       existed: key in process.env,
     });
   }
-  Object.defineProperty(process.env, key, {
-    value: undefined,
-    writable: true,
-    enumerable: false,
-    configurable: true,
-  });
+  Reflect.deleteProperty(process.env, key);
 };
 
 const restoreEnvVars = (): void => {
   envMocks.forEach(({ descriptor, existed }, key) => {
     if (existed && descriptor) {
       Object.defineProperty(process.env, key, descriptor);
     } else {
-      Object.defineProperty(process.env, key, {
-        value: undefined,
-        writable: true,
-        enumerable: false,
-        configurable: true,
-      });
+      Reflect.deleteProperty(process.env, key);
     }
   });
   envMocks.clear();
 };

Also applies to: 121-133

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

In `@src/errors/main.spec.ts` around lines 106 - 119, The test helper unsetEnvVar
currently leaves keys present by redefining process.env[key] to undefined, and
restoreEnvVars does not remove keys that originally did not exist; update
unsetEnvVar and restoreEnvVars to record previous descriptor/existence in
envMocks (already done) and on restore, if envMocks.get(key).existed is false
then delete process.env[key] (or use Reflect.deleteProperty) instead of
redefining to undefined, otherwise restore the original descriptor/value using
Object.defineProperty with the saved descriptor; ensure this logic is applied
for all keys managed by envMocks in the restoreEnvVars function.

Comment thread src/i18n/common.ts
Comment on lines 105 to 107
export const interpolation: InitOptions['interpolation'] = {
escapeValue: false,
format: (value, format, lng) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's read the file to see the context around lines 105-107
cat -n src/i18n/common.ts | head -120 | tail -30

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 989


🏁 Script executed:

# Let's also search for locale files to understand the structure
fd -e json -e yml -e yaml src/i18n | head -20

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 412


🏁 Script executed:

# Check what other interpolation configurations exist and search for {{- patterns in locale files
rg "{{-" --type=json --type=yaml -A 2 -B 2 | head -50

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 153


🏁 Script executed:

# Find files in src/i18n directory
fd . src/i18n

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 681


🏁 Script executed:

# Search for {{- pattern (need to escape for regex)
rg '\{\{-' -A 2 -B 2 | head -80

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 4814


🏁 Script executed:

# Also check the git history to understand if escapeValue: false was added in this PR
git log --oneline -20 -- src/i18n/common.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 168


🏁 Script executed:

# Check what i18next version is being used
cat package.json | grep -A 2 -B 2 "i18next"

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 397


🏁 Script executed:

# Search for regular {{ }} interpolations (not {{- }})
rg '\{\{[^-]' src/i18n/*.json | head -40

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 3117


🏁 Script executed:

# Check git diff to see if escapeValue: false is newly added
git diff -- src/i18n/common.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 57


🏁 Script executed:

# Also check git status to confirm the file was modified
git status src/i18n/common.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 140


Reconsider disabling i18next escaping in the shared config.

The locale files contain both regular {{ }} interpolations (like {{copyright}}, {{source}}, {{date}}) that require HTML escaping for security, and {{- }} interpolations that intentionally bypass escaping. Setting escapeValue: false globally disables HTML escaping for all interpolations, including the regular ones that should be protected. This expands the XSS attack surface unnecessarily.

Suggested change
 export const interpolation: InitOptions['interpolation'] = {
-  escapeValue: false,
   format: (value, format, lng) => {
📝 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 interpolation: InitOptions['interpolation'] = {
escapeValue: false,
format: (value, format, lng) => {
export const interpolation: InitOptions['interpolation'] = {
format: (value, format, lng) => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/i18n/common.ts` around lines 105 - 107, The shared i18n config currently
sets escapeValue: false on the exported interpolation object
(InitOptions['interpolation']), which disables HTML escaping for all {{ }}
interpolations; change this to enable escaping by default (set escapeValue: true
or remove the false override) so regular {{ }} tokens are HTML-escaped, and rely
on i18next's existing unescaped syntax (e.g., {{- }}) or per-call options when
you intentionally need raw HTML; update the interpolation object and keep the
format function as-is.

Comment thread src/logging/dedup.ts
Comment thread src/logging/privacy.ts
Comment on lines +37 to +85
/**
* Key-value credential patterns.
* Requires the value portion to be 8+ chars to avoid matching
* short debug strings like "token expired" or "secret: no".
*/
const CREDENTIAL_KV_PATTERNS: { pattern: RegExp; label: string }[] = [
{
pattern: /password["'\s:=]+["']?([^"'\s,}\]]{8,})/gi,
label: 'password',
},
{ pattern: /passwd["'\s:=]+["']?([^"'\s,}\]]{8,})/gi, label: 'passwd' },
{ pattern: /secret["'\s:=]+["']?([^"'\s,}\]]{8,})/gi, label: 'secret' },
{
pattern: /api[_-]?key["'\s:=]+["']?([^"'\s,}\]]{8,})/gi,
label: 'api_key',
},
{
pattern: /auth[_-]?token["'\s:=]+["']?([^"'\s,}\]]{8,})/gi,
label: 'auth_token',
},
{
pattern: /access[_-]?token["'\s:=]+["']?([^"'\s,}\]]{8,})/gi,
label: 'access_token',
},
{
pattern: /refresh[_-]?token["'\s:=]+["']?([^"'\s,}\]]{8,})/gi,
label: 'refresh_token',
},
{
pattern: /x-auth-token["'\s:=]+["']?([^"'\s,}\]]{8,})/gi,
label: 'x-auth-token',
},
{
pattern: /authorization["'\s:=]+["']?((?:\w+\s+)?[^"',}\]]{8,})/gi,
label: 'authorization',
},
{
pattern: /client[_-]?secret["'\s:=]+["']?([^"'\s,}\]]{8,})/gi,
label: 'client_secret',
},
{
pattern: /private[_-]?key["'\s:=]+["']?([^"'\s,}\]]{8,})/gi,
label: 'private_key',
},
{
pattern: /webhook[_-]?url["'\s:=]+["']?([^"'\s,}\]]{8,})/gi,
label: 'webhook_url',
},
];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

The string pass still leaks common secret key/value pairs.

This table only redacts 8+ character values and it has no generic token matcher, so free-form messages like password=secret or token=abc12345 will still reach disk verbatim. For known secret keys, redaction should not depend on length.

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

In `@src/logging/privacy.ts` around lines 37 - 85, CREDENTIAL_KV_PATTERNS
currently only redacts values of 8+ chars, allowing short secrets like
"password=secret" or "token=abc12345" to leak; update the CREDENTIAL_KV_PATTERNS
array so that known secret keys (e.g., entries for 'password', 'passwd',
'secret', 'api_key', 'auth_token', 'access_token', 'refresh_token',
'authorization', 'client_secret', 'private_key', 'webhook_url', etc.) do not
impose the {8,} length requirement and will match and redact any non-empty
value, and add a generic token matcher (e.g., a
`/\btoken["'\s:=]+["']?([^"'\s,}\]]+)/gi` style entry) to catch free-form
"token" pairs; locate and modify the CREDENTIAL_KV_PATTERNS constant to remove
the length quantifier for known keys and append the generic token pattern so
short secrets are also redacted.

Comment thread src/main.ts
Comment on lines 65 to 68
const start = async (): Promise<void> => {
setUserDataDirectory();
applySystemCertificates();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the implementation of applySystemCertificates to verify it doesn't use app-ready-dependent APIs
ast-grep --pattern 'export const applySystemCertificates = $_'
cat src/systemCertificates.ts 2>/dev/null || fd -t f 'systemCertificates' --exec cat {}

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 4284


applySystemCertificates() calls Electron app APIs before app.whenReady() — must be deferred.

The implementation calls readUseSystemCertificatesSetting(), which in turn calls app.getPath('userData') and app.getAppPath(). These Electron APIs are not safe to use before the app is ready and can cause crashes or undefined behavior. Move the applySystemCertificates() call to after app.whenReady() resolves.

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

In `@src/main.ts` around lines 65 - 68, The call to applySystemCertificates() in
start() invokes Electron APIs (via readUseSystemCertificatesSetting()) before
the app is ready; move the applySystemCertificates() invocation to occur after
awaiting app.whenReady() (i.e., call await app.whenReady() then call
applySystemCertificates()), leaving setUserDataDirectory() where it is if it
does not depend on app readiness, and ensure any code that relies on system
certificate setup runs after the moved call.

Comment on lines +16 to +26
const lightLink = document.createElement('link');
lightLink.rel = 'stylesheet';
lightLink.href = '../node_modules/highlight.js/styles/github.css';
lightLink.media = '(prefers-color-scheme: light)';
document.head.appendChild(lightLink);

const darkLink = document.createElement('link');
darkLink.rel = 'stylesheet';
darkLink.href = '../node_modules/highlight.js/styles/github-dark.css';
darkLink.media = '(prefers-color-scheme: dark)';
document.head.appendChild(darkLink);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if highlight.js styles are bundled or served from node_modules
rg -n "highlight\.js.*styles" --type=ts --type=tsx --type=css --type=html -C2
# Check webpack/build config for asset handling
fd -e js -e ts -e json "webpack|vite|rollup|esbuild" --exec grep -l "highlight" {} \;

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 102


🏁 Script executed:

#!/bin/bash
# Search for highlight.js references with correct file types
echo "=== Searching for highlight.js references ==="
rg -n "highlight\.js|github\.css|github-dark\.css" --type=ts --type=js --type=json -C2

echo ""
echo "=== Checking project structure ==="
ls -la | head -20

echo ""
echo "=== Looking for build/bundling config files ==="
find . -maxdepth 2 -type f \( -name "webpack*" -o -name "vite*" -o -name "esbuild*" -o -name "rollup*" -o -name "package.json" \) | head -10

echo ""
echo "=== Checking if styles are in node_modules ==="
find . -path "*/node_modules/highlight.js/styles/*" 2>/dev/null | head -5 || echo "Path check (may not exist in sandbox)"

echo ""
echo "=== Looking for import/require patterns with stylesheets ==="
rg -n "import.*\.css|require.*\.css" --type=ts --type=js -C1 | head -30

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 3750


🏁 Script executed:

#!/bin/bash
echo "=== Reading rollup.config.mjs ==="
cat rollup.config.mjs | head -100

echo ""
echo "=== Checking package.json build scripts ==="
rg -A 5 '"scripts"' package.json

echo ""
echo "=== Looking for other stylesheet/CSS handling patterns ==="
rg -n "document\.createElement.*link|document\.head\.appendChild" --type=ts --type=js -C2

echo ""
echo "=== Checking for github-markdown-css import ==="
rg -n "github-markdown-css" --type=ts --type=js

echo ""
echo "=== Full MarkdownContent.tsx file to understand context ==="
head -50 src/ui/components/ServersView/MarkdownContent.tsx

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 7572


Use proper path resolution for highlight.js stylesheets to ensure they load correctly in production builds.

The hardcoded relative paths ../node_modules/highlight.js/styles/github.css and ../node_modules/highlight.js/styles/github-dark.css will not reliably resolve in a bundled Electron application. The Shell component demonstrates the correct pattern by using a dynamic path variable. Consider using a similar approach with appPath or importing the CSS directly to ensure consistent stylesheet loading across development and production environments.

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

In `@src/ui/components/ServersView/MarkdownContent.tsx` around lines 16 - 26, The
inserted link elements lightLink and darkLink use hardcoded ../node_modules
paths that will break in production; change the implementation to resolve the
stylesheet paths dynamically (like Shell does) by using the app path variable
(e.g., appPath or an equivalent bundled asset resolver) or import the CSS assets
so bundler/Electron serves them correctly, then set lightLink.href and
darkLink.href to those resolved URLs before appending to document.head; ensure
the symbols lightLink and darkLink and their .href assignments are updated to
use the resolved path variable or imported asset reference.

Comment thread src/ui/components/ServersView/PdfContent.tsx Outdated
Comment thread src/ui/components/ServersView/PdfContent.tsx
Comment thread src/ui/main/rootWindow.ts
Comment on lines +528 to +579
const createRootWindowContextMenu = ({
editFlags: {
canUndo = false,
canRedo = false,
canCut = false,
canCopy = false,
canPaste = false,
canSelectAll = false,
},
}: ContextMenuParams): Menu => {
const t = i18next.t.bind(i18next);
return Menu.buildFromTemplate([
{
label: t('contextMenu.undo'),
role: 'undo',
accelerator: 'CommandOrControl+Z',
enabled: canUndo,
},
{
label: t('contextMenu.redo'),
role: 'redo',
accelerator:
process.platform === 'win32' ? 'Control+Y' : 'CommandOrControl+Shift+Z',
enabled: canRedo,
},
{ type: 'separator' },
{
label: t('contextMenu.cut'),
role: 'cut',
accelerator: 'CommandOrControl+X',
enabled: canCut,
},
{
label: t('contextMenu.copy'),
role: 'copy',
accelerator: 'CommandOrControl+C',
enabled: canCopy,
},
{
label: t('contextMenu.paste'),
role: 'paste',
accelerator: 'CommandOrControl+V',
enabled: canPaste,
},
{
label: t('contextMenu.selectAll'),
role: 'selectAll',
accelerator: 'CommandOrControl+A',
enabled: canSelectAll,
},
]);
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's check the file size and read the relevant sections
wc -l src/ui/main/rootWindow.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 104


🏁 Script executed:

# Read lines 520-600 to see the full context including lines 528-579 and 584-588
sed -n '520,600p' src/ui/main/rootWindow.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 2077


🏁 Script executed:

# Search for context-menu event handler usage and where createRootWindowContextMenu is called
rg -n "context-menu|createRootWindowContextMenu" src/ui/main/rootWindow.ts -A 5 -B 2

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 612


🏁 Script executed:

# Check what ContextMenuParams type includes - search for its definition
rg -n "type ContextMenuParams|interface ContextMenuParams" --type ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 57


🏁 Script executed:

# Search for ContextMenuParams import or definition
rg -n "ContextMenuParams" src/ui/main/rootWindow.ts -B 5

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 297


🏁 Script executed:

# Check if there's a types file or electron types with ContextMenuParams
find . -name "*.d.ts" -type f | head -20

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 1197


🏁 Script executed:

# Search more broadly for ContextMenuParams usage
rg -n "ContextMenuParams" --type ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 767


🏁 Script executed:

# Check the import line for ContextMenuParams in rootWindow.ts
sed -n '1,10p' src/ui/main/rootWindow.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 216


🏁 Script executed:

# Read popupMenu.ts to see how it handles different context types
cat -n src/ui/main/serverView/popupMenu.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 8328


Replace edit-only context menu with the full context-aware menu pattern already used in the server view.

The handler at line 584–588 unconditionally suppresses the default context menu and replaces it with a menu built only from editFlags. This loses user-visible actions for links, images, and spellcheck that are available in ContextMenuParams but ignored. Users right-clicking a link in the login or add-server flow lose the ability to open links, copy link addresses, or access image save options.

The popupMenu.ts file already demonstrates the correct pattern: separate template builders that check linkURL, mediaType, and isEditable to conditionally include relevant actions. Apply that same approach here by combining spell-check, image, link, and default edit menu templates—or restrict the override to editable text contexts only.

🤖 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 528 - 579, The current
createRootWindowContextMenu builds a menu only from editFlags
(canUndo/canRedo/canCut/etc.), losing link/image/spellcheck actions; update
createRootWindowContextMenu (and the contextmenu handler that currently always
replaces the default) to follow the popupMenu.ts pattern: detect
ContextMenuParams.linkURL, mediaType, and isEditable and merge templates (link
actions, media/image actions, spellcheck suggestions, plus the edit template) so
link/image actions appear when present, or alternatively only override the
default menu when isEditable is true; reference the createRootWindowContextMenu
function and ContextMenuParams type and reuse the conditional template builders
from popupMenu.ts to compose the final Menu.buildFromTemplate result.

Comment thread src/updates/main.ts
Comment on lines +165 to +166
let isUserInitiatedCheck = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, check the file size and get context around the flagged lines
wc -l src/updates/main.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 98


🏁 Script executed:

# Get the code around lines 165-166 (flag declaration)
sed -n '160,170p' src/updates/main.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 382


🏁 Script executed:

# Get the code around lines 245-250 (first usage mentioned)
sed -n '240,255p' src/updates/main.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 649


🏁 Script executed:

# Get the code around lines 334-352 (second usage mentioned)
sed -n '330,360p' src/updates/main.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 824


🏁 Script executed:

# Look for all references to isUserInitiatedCheck in the file
rg -n 'isUserInitiatedCheck' src/updates/main.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 264


🏁 Script executed:

# Check if the flag is cleared anywhere in the file
rg -n 'isUserInitiatedCheck\s*=' src/updates/main.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 191


🏁 Script executed:

# Get more context on the event listeners to see if flag is reset in any of them
sed -n '230,280p' src/updates/main.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 1634


🏁 Script executed:

# Check for all event listeners attached to autoUpdater
rg -n "autoUpdater\.addListener|autoUpdater\.on" src/updates/main.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 383


🏁 Script executed:

# Get context around each event listener to see full implementation
sed -n '230,310p' src/updates/main.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 2568


🏁 Script executed:

# Get the error listener implementation
sed -n '321,330p' src/updates/main.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 297


🏁 Script executed:

# Get complete context around the manual check trigger (lines 348-360)
sed -n '348,365p' src/updates/main.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 520


🏁 Script executed:

# Search if flag is reset anywhere else in the file we might have missed
rg -C 3 "isUserInitiatedCheck\s*=" src/updates/main.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 614


isUserInitiatedCheck is racy across concurrent update checks.

This flag is shared by all updater callbacks and is set to true before the manual checkForUpdates() call. If the startup check is still awaiting a network response when a user triggers a manual check, the startup check's update-available event will fire with the flag incorrectly set to true, causing skipped versions to resurface. Additionally, the flag is never cleared after a manual check completes, so subsequent checks in the same session will inherit the wrong state.

Scope the origin to the actual request you initiate, or reset the flag in all terminal event handlers (update-available, update-not-available, error).

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

In `@src/updates/main.ts` around lines 165 - 166, The shared boolean
isUserInitiatedCheck is racy across concurrent checks; change the logic so the
origin is tracked per-request (e.g., pass a userInitiated flag into
checkForUpdates() or return a request token) instead of a single module-level
variable, and ensure you clear/reset that request-scoped flag in all terminal
event handlers ('update-available', 'update-not-available', 'error') or when the
request completes/aborts so one request cannot affect another; update references
to isUserInitiatedCheck (and the checkForUpdates() caller) accordingly to use
the per-request flag or token.

jeanfbrito added a commit that referenced this pull request Apr 6, 2026
- Reset dedup state on error so subsequent non-error messages aren't
  wrongly suppressed (logging/dedup.ts)
- Fix SSL cert regex to match "self signed certificate" with spaces
  and hyphens (outlookCalendar/errorClassification.ts)
- Redact cookie/set-cookie headers in sensitive context sanitizer
  (outlookCalendar/errorClassification.ts)
- Fix PdfContent useEffect to depend only on url, clear timeout on
  cleanup to prevent duplicate navigations (PdfContent.tsx)
- Use closest('a') and case-insensitive .pdf check for PDF link
  guard (PdfContent.tsx)
- Reset dedup state on error so subsequent non-error messages aren't
  wrongly suppressed (logging/dedup.ts)
- Fix SSL cert regex to match "self signed certificate" with spaces
  and hyphens (outlookCalendar/errorClassification.ts)
- Redact cookie/set-cookie headers in sensitive context sanitizer
  (outlookCalendar/errorClassification.ts)
- Fix PdfContent useEffect to depend only on url, clear timeout on
  cleanup to prevent duplicate navigations (PdfContent.tsx)
- Use closest('a') and case-insensitive .pdf check for PDF link
  guard (PdfContent.tsx)
Copy link
Copy Markdown
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: 2

♻️ Duplicate comments (1)
src/ui/components/ServersView/MarkdownContent.tsx (1)

16-26: ⚠️ Potential issue | 🟠 Major

Resolve highlight theme URLs through bundled assets.

These ../node_modules/... hrefs are source-tree dependent and won't resolve reliably once the Electron app is packaged, so syntax highlighting loses its theme outside dev. Please resolve them through the app's packaged asset path instead of pointing at node_modules directly.

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

In `@src/ui/components/ServersView/MarkdownContent.tsx` around lines 16 - 26, The
two link elements (lightLink and darkLink) in MarkdownContent.tsx currently
point at ../node_modules/... which breaks after packaging; instead resolve and
use bundled asset URLs at runtime (e.g., import or require the CSS so the
bundler includes them, or build the href via a packaged-assets path such as new
URL('./assets/highlight/github.css', import.meta.url) or an Electron-provided
app asset path) and set lightLink.href and darkLink.href to those resolved URLs;
ensure the highlight CSS files are copied into your app's static/assets during
build so MarkdownContent's lightLink and darkLink reference valid packaged files
rather than node_modules.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/ui/components/ServersView/MarkdownContent.tsx`:
- Around line 102-111: The heading(...) renderer currently strips non-ASCII
chars and doesn't dedupe IDs; change it to generate Unicode-friendly slugs (use
text.normalize('NFKD') with diacritic removal only, then localeLowerCase() and
replace only control/punctuation that would break an id, collapse whitespace to
'-') and add uniqueness by tracking produced slugs (e.g., a slugCounts Map in
the MarkdownContent component) so duplicates get suffixes like `-2`, `-3`; also
handle empty slugs by falling back to a default base like "section" and applying
the same dedupe logic. Ensure these changes are implemented in the heading
function and that the slugCounts state is reset/maintained appropriately for
each rendered document.
- Around line 172-185: marked.parse() leaves relative resource URLs unchanged so
embedded images/links resolve incorrectly in the Electron document; after
parsing the markdown (the string returned by marked.parse(text)) but before
DOMPurify.sanitize and setHtmlContent, parse the generated HTML into a DOM
(e.g., via DOMParser), locate elements with src, srcset and href attributes
(img, source, video, audio, a, link, etc.), and for each relative URL use new
URL(relativeOrCandidate, url || serverUrl) to resolve to an absolute,
authenticated-aware URL (handle srcset by splitting descriptors and resolving
each URL), replace the attributes with the resolved absolute URLs, serialize the
DOM back to HTML and then pass that HTML into DOMPurify.sanitize and
setHtmlContent; reference the existing variables and functions:
marked.parse(text), url, serverUrl, DOMPurify.sanitize, and setHtmlContent to
find where to insert this normalization step.

---

Duplicate comments:
In `@src/ui/components/ServersView/MarkdownContent.tsx`:
- Around line 16-26: The two link elements (lightLink and darkLink) in
MarkdownContent.tsx currently point at ../node_modules/... which breaks after
packaging; instead resolve and use bundled asset URLs at runtime (e.g., import
or require the CSS so the bundler includes them, or build the href via a
packaged-assets path such as new URL('./assets/highlight/github.css',
import.meta.url) or an Electron-provided app asset path) and set lightLink.href
and darkLink.href to those resolved URLs; ensure the highlight CSS files are
copied into your app's static/assets during build so MarkdownContent's lightLink
and darkLink reference valid packaged files rather than node_modules.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ccbaa5b5-cb0c-41e0-8138-dbe361c023dd

📥 Commits

Reviewing files that changed from the base of the PR and between af40a4a and 41e65be.

📒 Files selected for processing (1)
  • src/ui/components/ServersView/MarkdownContent.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build (windows-latest)
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: build (macos-latest)
🧰 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/components/ServersView/MarkdownContent.tsx
🧠 Learnings (4)
📓 Common learnings
Learnt from: Ram-sah19
Repo: RocketChat/Rocket.Chat.Electron PR: 3254
File: .github/workflows/build-release.yml:80-94
Timestamp: 2026-03-11T06:38:40.426Z
Learning: In the RocketChat/Rocket.Chat.Electron repository, the issues flagged in `.github/workflows/build-release.yml` (e.g., `node12` runtime in the release action and missing `snapcraft_token` input), i18n files, and `electron-builder.json` are pre-existing in the `develop` branch and are pulled in during merge conflict resolution. Do not flag these as new issues introduced by PRs that only modify `src/injected.ts` and `src/ui/main/rootWindow.ts`.
📚 Learning: 2026-03-11T06:38:40.426Z
Learnt from: Ram-sah19
Repo: RocketChat/Rocket.Chat.Electron PR: 3254
File: .github/workflows/build-release.yml:80-94
Timestamp: 2026-03-11T06:38:40.426Z
Learning: In the RocketChat/Rocket.Chat.Electron repository, the issues flagged in `.github/workflows/build-release.yml` (e.g., `node12` runtime in the release action and missing `snapcraft_token` input), i18n files, and `electron-builder.json` are pre-existing in the `develop` branch and are pulled in during merge conflict resolution. Do not flag these as new issues introduced by PRs that only modify `src/injected.ts` and `src/ui/main/rootWindow.ts`.

Applied to files:

  • src/ui/components/ServersView/MarkdownContent.tsx
📚 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/ui/components/ServersView/MarkdownContent.tsx
📚 Learning: 2026-04-01T15:41:58.866Z
Learnt from: jeanfbrito
Repo: RocketChat/Rocket.Chat.Electron PR: 3284
File: src/logging/index.ts:423-445
Timestamp: 2026-04-01T15:41:58.866Z
Learning: In the RocketChat/Rocket.Chat.Electron repository, Rocket.Chat server instances are always deployed at distinct origins (unique hostname or port combinations). Multiple servers sharing the same hostname but differing only by path (e.g., `https://host/team-a` vs `https://host/team-b`) is not a real-world deployment scenario. Therefore, comparing `new URL(s.url).origin` alone is sufficient for matching a webContents URL to its configured server in `src/logging/index.ts`, and path-based collision concerns do not apply.

Applied to files:

  • src/ui/components/ServersView/MarkdownContent.tsx
🪛 ast-grep (0.42.1)
src/ui/components/ServersView/MarkdownContent.tsx

[warning] 237-237: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

Comment on lines +102 to +111
heading({ text, depth }: { text: string; depth: number }) {
const temp = document.createElement('div');
temp.innerHTML = text;
const slug = (temp.textContent || '')
.toLowerCase()
.replace(/[^\w\s-]/g, '')
.replace(/\s+/g, '-')
.replace(/-+/g, '-')
.trim();
return `<h${depth} id="${slug}">${text}</h${depth}>`;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Make heading IDs work for localized and repeated headings.

The ASCII-only cleanup here strips non-English headings down to bad or empty IDs, and duplicate headings still collide because there is no dedupe step. That breaks the anchor navigation this viewer is adding.

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

In `@src/ui/components/ServersView/MarkdownContent.tsx` around lines 102 - 111,
The heading(...) renderer currently strips non-ASCII chars and doesn't dedupe
IDs; change it to generate Unicode-friendly slugs (use text.normalize('NFKD')
with diacritic removal only, then localeLowerCase() and replace only
control/punctuation that would break an id, collapse whitespace to '-') and add
uniqueness by tracking produced slugs (e.g., a slugCounts Map in the
MarkdownContent component) so duplicates get suffixes like `-2`, `-3`; also
handle empty slugs by falling back to a default base like "section" and applying
the same dedupe logic. Ensure these changes are implemented in the heading
function and that the slugCounts state is reset/maintained appropriately for
each rendered document.

Comment on lines +172 to +185
ipcRenderer
.invoke('document-viewer/fetch-content', url, serverUrl)
.then((text: string) => {
if (cancelled) return;
return marked.parse(text);
})
.then((html) => {
if (cancelled) return;
const sanitized = DOMPurify.sanitize(html as string, {
USE_PROFILES: { html: true },
ADD_TAGS: ['details', 'summary', 'input'],
ADD_ATTR: ['id', 'type', 'checked', 'disabled'],
});
setHtmlContent(sanitized);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Normalize embedded resource URLs before storing the rendered HTML.

marked.parse() leaves relative src/srcset URLs untouched. Once this HTML is injected into the Electron shell document, assets like ./image.png resolve against the app page instead of the markdown file URL, and they also miss the partition-scoped fetch path used in src/documentViewer/ipc.ts:38-61. Relative or authenticated images in markdown will therefore render broken.

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

In `@src/ui/components/ServersView/MarkdownContent.tsx` around lines 172 - 185,
marked.parse() leaves relative resource URLs unchanged so embedded images/links
resolve incorrectly in the Electron document; after parsing the markdown (the
string returned by marked.parse(text)) but before DOMPurify.sanitize and
setHtmlContent, parse the generated HTML into a DOM (e.g., via DOMParser),
locate elements with src, srcset and href attributes (img, source, video, audio,
a, link, etc.), and for each relative URL use new URL(relativeOrCandidate, url
|| serverUrl) to resolve to an absolute, authenticated-aware URL (handle srcset
by splitting descriptors and resolving each URL), replace the attributes with
the resolved absolute URLs, serialize the DOM back to HTML and then pass that
HTML into DOMPurify.sanitize and setHtmlContent; reference the existing
variables and functions: marked.parse(text), url, serverUrl, DOMPurify.sanitize,
and setHtmlContent to find where to insert this normalization step.

Copy link
Copy Markdown
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: 1

🧹 Nitpick comments (1)
src/logging/dedup.ts (1)

76-87: Consider extracting the shared key-generation logic.

The key-building pattern (serialize → join → normalize numbers) is duplicated between makeKey() and this inline block. While both implementations are correct, consolidating them would reduce maintenance burden.

♻️ Possible refactor to reuse makeKey
   createFileHook() {
     return (
       message: any,
       _transport: any,
       transportName?: string
     ): any | null => {
       if (transportName !== 'file') return message;
       if (!message) return message;
       if (message.level === 'error') {
         this.lastFileKey = '';
         return message;
       }

-      const text =
-        message.data
-          ?.map((item: any) => {
-            if (typeof item === 'string') return item;
-            try {
-              return JSON.stringify(item);
-            } catch {
-              return String(item);
-            }
-          })
-          .join(' ') || '';
-      const key = `${message.level}|${text.replace(/\b\d{4,}\b/g, '#').replace(/\b\d+\.\d+\b/g, '#')}`;
+      const key = this.makeKey(message.level, message.data || []);

       if (key === this.lastFileKey) return null; // suppress duplicate

       this.lastFileKey = key;
       return message;
     };
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/logging/dedup.ts` around lines 76 - 87, Extract the duplicated
key-generation logic (serialize message.data items, join with spaces, normalize
long integers and floats) into a single helper and reuse makeKey(); specifically
replace the inline serialization and normalization that builds text and key in
this block with a call to the shared helper (or makeKey) so both this file and
the existing makeKey() implementation share the same logic, updating any
references to message, text, and key to use the helper's return value to avoid
duplication.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/ui/components/ServersView/PdfContent.tsx`:
- Around line 39-67: Move the 'did-finish-load' listener registration out of
handleDidAttach so it is not re-registered on every attach (register it once for
webviewElement after creation), and ensure you remove that 'did-finish-load'
listener in the cleanup along with removing 'did-attach'; also deduplicate the
WEBVIEW_PDF_VIEWER_ATTACHED dispatch inside handleDidAttach (e.g. only dispatch
if the stored/previous WebContentsId differs or use a boolean flag) so the ipc
handler in src/documentViewer/ipc.ts that registers 'will-navigate' is not
invoked multiple times for the same webContents, and update cleanup to undo any
state used for deduplication.

---

Nitpick comments:
In `@src/logging/dedup.ts`:
- Around line 76-87: Extract the duplicated key-generation logic (serialize
message.data items, join with spaces, normalize long integers and floats) into a
single helper and reuse makeKey(); specifically replace the inline serialization
and normalization that builds text and key in this block with a call to the
shared helper (or makeKey) so both this file and the existing makeKey()
implementation share the same logic, updating any references to message, text,
and key to use the helper's return value to avoid duplication.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e82066e5-7d6a-4f9d-80d7-5a398d677972

📥 Commits

Reviewing files that changed from the base of the PR and between 41e65be and 6d8a1a1.

📒 Files selected for processing (3)
  • src/logging/dedup.ts
  • src/outlookCalendar/errorClassification.ts
  • src/ui/components/ServersView/PdfContent.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/outlookCalendar/errorClassification.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build (macos-latest)
  • GitHub Check: build (windows-latest)
  • GitHub Check: build (ubuntu-latest)
🧰 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/components/ServersView/PdfContent.tsx
  • src/logging/dedup.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: Ram-sah19
Repo: RocketChat/Rocket.Chat.Electron PR: 3254
File: .github/workflows/build-release.yml:80-94
Timestamp: 2026-03-11T06:38:40.426Z
Learning: In the RocketChat/Rocket.Chat.Electron repository, the issues flagged in `.github/workflows/build-release.yml` (e.g., `node12` runtime in the release action and missing `snapcraft_token` input), i18n files, and `electron-builder.json` are pre-existing in the `develop` branch and are pulled in during merge conflict resolution. Do not flag these as new issues introduced by PRs that only modify `src/injected.ts` and `src/ui/main/rootWindow.ts`.
🔇 Additional comments (4)
src/logging/dedup.ts (3)

1-18: LGTM!

Clear documentation of the two integration points and well-designed state separation between IPC and file transport deduplication.


24-38: LGTM!

The key generation logic correctly normalizes dynamic values (timestamps, IDs, decimals) while gracefully handling serialization errors for complex objects.


45-56: LGTM!

The error handling correctly resets lastIpcKey to prevent suppressing subsequent non-error messages after an error passes through. This properly addresses the deduplication state reset concern.

src/ui/components/ServersView/PdfContent.tsx (1)

19-33: Good fix on the URL reset effect.

Line 19–33 now avoids duplicate timeout scheduling and correctly clears the pending timer on cleanup.

Comment on lines +39 to +67
const handleDidAttach: () => void = () => {
const webContentsId = webviewElement.getWebContentsId();
dispatch({
type: WEBVIEW_PDF_VIEWER_ATTACHED,
payload: { WebContentsId: webContentsId },
});

webviewElement.addEventListener('did-finish-load', () => {
webviewElement.executeJavaScript(`
document.addEventListener('click', (event) => {
const anchor = event.target instanceof Element ? event.target.closest('a') : null;
if (anchor && anchor.href) {
try {
const url = new URL(anchor.href, document.baseURI);
if (url.pathname.toLowerCase().endsWith('.pdf')) {
event.preventDefault();
}
} catch {}
}
}, true);
`);
});
};

webviewElement.addEventListener('did-attach', handleDidAttach);

return () => {
webviewElement.removeEventListener('did-attach', handleDidAttach);
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Confirm PdfContent listener lifecycle (add/remove parity + attach dispatch pattern)
rg -n -C3 "did-attach|did-finish-load|WEBVIEW_PDF_VIEWER_ATTACHED|removeEventListener" src/ui/components/ServersView/PdfContent.tsx

# 2) Confirm downstream main-process registration behavior for the attached action
rg -n -C4 "listen\\(WEBVIEW_PDF_VIEWER_ATTACHED|will-navigate|openExternal|webContents\\.fromId" src/documentViewer/ipc.ts

Repository: RocketChat/Rocket.Chat.Electron

Length of output: 2260


Remove stacked event listeners and dedup attach dispatch.

Lines 46 and 63–67 create an event-listener leak: did-finish-load is registered inside did-attach (line 46) but never cleaned up (only did-attach removal at line 66). Each re-attach adds another handler without removing the previous one. Additionally, every did-attach dispatch triggers WEBVIEW_PDF_VIEWER_ATTACHED (line 42), which registers a new will-navigate listener in src/documentViewer/ipc.ts:69 with no cleanup, causing multiple handlers to fire on the same navigation event.

Fix: Extract did-finish-load registration outside handleDidAttach, add deduplication to prevent duplicate dispatches, and remove both listeners on cleanup.

♻️ Proposed fix
 const PdfContent = ({ url, partition }: { url: string; partition: string }) => {
   const [documentUrl, setDocumentUrl] = useState('');
   const webviewRef = useRef<HTMLWebViewElement>(null);
+  const lastAttachedWebContentsId = useRef<number | null>(null);

   useEffect(() => {
     const webviewElement = webviewRef.current;

-    if (webviewElement) {
-      const handleDidAttach: () => void = () => {
-        const webContentsId = webviewElement.getWebContentsId();
-        dispatch({
-          type: WEBVIEW_PDF_VIEWER_ATTACHED,
-          payload: { WebContentsId: webContentsId },
-        });
-
-        webviewElement.addEventListener('did-finish-load', () => {
-          webviewElement.executeJavaScript(`
+    if (!webviewElement) {
+      return;
+    }
+
+    const handleDidFinishLoad = () => {
+      void webviewElement.executeJavaScript(`
             document.addEventListener('click', (event) => {
               const anchor = event.target instanceof Element ? event.target.closest('a') : null;
               if (anchor && anchor.href) {
                 try {
                   const url = new URL(anchor.href, document.baseURI);
                   if (url.pathname.toLowerCase().endsWith('.pdf')) {
                     event.preventDefault();
                   }
                 } catch {}
               }
             }, true);
-          `);
-        });
-      };
+          `).catch(() => undefined);
+    };
+
+    const handleDidAttach = () => {
+      const webContentsId = webviewElement.getWebContentsId();
+      if (lastAttachedWebContentsId.current === webContentsId) {
+        return;
+      }
+      lastAttachedWebContentsId.current = webContentsId;
+      dispatch({
+        type: WEBVIEW_PDF_VIEWER_ATTACHED,
+        payload: { WebContentsId: webContentsId },
+      });
+    };

-      webviewElement.addEventListener('did-attach', handleDidAttach);
+    webviewElement.addEventListener('did-attach', handleDidAttach);
+    webviewElement.addEventListener('did-finish-load', handleDidFinishLoad);

-      return () => {
-        webviewElement.removeEventListener('did-attach', handleDidAttach);
-      };
-    }
-    return () => {};
+    return () => {
+      webviewElement.removeEventListener('did-attach', handleDidAttach);
+      webviewElement.removeEventListener('did-finish-load', handleDidFinishLoad);
+    };
   }, []);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/ui/components/ServersView/PdfContent.tsx` around lines 39 - 67, Move the
'did-finish-load' listener registration out of handleDidAttach so it is not
re-registered on every attach (register it once for webviewElement after
creation), and ensure you remove that 'did-finish-load' listener in the cleanup
along with removing 'did-attach'; also deduplicate the
WEBVIEW_PDF_VIEWER_ATTACHED dispatch inside handleDidAttach (e.g. only dispatch
if the stored/previous WebContentsId differs or use a boolean flag) so the ipc
handler in src/documentViewer/ipc.ts that registers 'will-navigate' is not
invoked multiple times for the same webContents, and update cleanup to undo any
state used for deduplication.

* Version 4.13.0 (#3233)

* fix: Bugsnag network connections even with errors reporting disabled (#3190)

* fix: disable Bugsnag auto session tracking to prevent unwanted network connections

Adds autoTrackSessions: false to Bugsnag.start() configuration to prevent
the SDK from automatically connecting to sessions.bugsnag.com on initialization.
This fixes issues in air-gapped networks where the connection attempt triggers
certificate error dialogs even when telemetry is disabled.

Also upgrades @bugsnag/js from v7.22.3 to v8.8.1.

* test: add integration tests for Bugsnag network behavior

- Use nock to intercept real HTTP requests from Bugsnag SDK
- Verify no network calls when reporting is disabled
- Verify sessions are sent when reporting is enabled
- Use Object.defineProperty for env var mocking
- Skip tests on Windows due to Jest module mocking issues

* Version 4.12.1-alpha.1

* feat: add admin setting to bypass SSL certificate validation for Outlook calendar

Add `allowInsecureOutlookConnections` setting for air-gapped environments
where Exchange servers use self-signed or internal CA certificates.

Configurable via overridden-settings.json:
{ "allowInsecureOutlookConnections": true }

Changes:
- Add new reducer for the setting (defaults to false)
- Apply setting to both Exchange (XhrApi) and Rocket.Chat (axios) connections
- Reuse single HTTPS agent per sync for better performance
- Fix missing await on createEventOnRocketChatServer call

* Version 4.12.1-alpha.2

* chore: patch @ewsjs/xhr to stop overwriting request errors

* lock file

* fix: make allowInsecureOutlookConnections override-only setting

The setting was being persisted to config.json, which meant once set to
true it would stay true even after removing from overridden-settings.json.

Changes:
- Remove from PersistableValues type and migrations
- Remove from selectPersistableValues selector
- Explicitly read from override files on each app start
- Accept case-insensitive "true" values for robustness
- Always defaults to false when key is missing

This ensures admins have full control over the setting in air-gapped
environments where remote debugging is not possible.

* feat: add admin setting to bypass SSL certificate validation for Outlook calendar (#3191)

* feat: add admin setting to bypass SSL certificate validation for Outlook calendar

Add `allowInsecureOutlookConnections` setting for air-gapped environments
where Exchange servers use self-signed or internal CA certificates.

Configurable via overridden-settings.json:
{ "allowInsecureOutlookConnections": true }

Changes:
- Add new reducer for the setting (defaults to false)
- Apply setting to both Exchange (XhrApi) and Rocket.Chat (axios) connections
- Reuse single HTTPS agent per sync for better performance
- Fix missing await on createEventOnRocketChatServer call

* Version 4.12.1-alpha.2

* chore: patch @ewsjs/xhr to stop overwriting request errors

* lock file

* fix: make allowInsecureOutlookConnections override-only setting

The setting was being persisted to config.json, which meant once set to
true it would stay true even after removing from overridden-settings.json.

Changes:
- Remove from PersistableValues type and migrations
- Remove from selectPersistableValues selector
- Explicitly read from override files on each app start
- Accept case-insensitive "true" values for robustness
- Always defaults to false when key is missing

This ensures admins have full control over the setting in air-gapped
environments where remote debugging is not possible.

---------

Co-authored-by: Pierre Lehnen <pierre.lehnen@rocket.chat>

* Add configurable Outlook calendar sync interval (#3198)

* feat: add configurable Outlook calendar sync interval (1-60 min)

Adds a user-editable sync interval setting to Settings > General,
with admin override support via overridden-settings.json. Uses a
nullable override pattern (number | null) to cleanly separate admin
overrides from persisted user preferences, preventing contamination.
Includes debounced runtime restart of the sync task on changes.

* chore: bump version to 4.12.1-alpha.3, improve sync interval change handling

Increases debounce to 10s, triggers an immediate sync before
rescheduling, and adds a log message when the interval changes.

* fix: clean up sync state when credentials are cleared or app shuts down

Prevents stale credentials from being used by the debounced interval
restart callback. Clears timers, nulls module-level state, and
unsubscribes the interval watcher on credential clear and shutdown.

* feat: Add outlook detailed logs toggle (#3199)

* feat: Add Exchange/EWS debugging patches and error classification (#3187)

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

* Language update from Lingohub 🤖 (#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  (#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 (#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 (#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (#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 (#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 #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>

* feat: Add scoped logging infrastructure and log viewer window (#3186)

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

* Language update from Lingohub 🤖 (#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  (#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 (#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 (#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (#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 (#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>

* fix: call stopOutlookCalendarSync on app quit

Ensures all sync timers and debounce timers are properly cleaned up
when the application shuts down, preventing sync operations during
shutdown.

* fix: improve logging system security and log viewer context filtering

- Protect active log files from cleanup deletion
- Add IPC rate limiting to prevent renderer process flooding
- Restrict log file permissions to owner-only access
- Add context sanitization to error classification (passwords/tokens only)
- Remove ANSI color codes from OutlookCalendar logger prefixes
- Fix log viewer context filter to use structured tag matching instead of substring search

* feat: add detailed events logging toggle for Outlook calendar sync

Add a new toggle in Settings > Developer to log full event data exchanged
between Exchange and Rocket.Chat during calendar sync. When enabled, logs
raw Exchange appointments, CRUD payloads/responses, event comparisons,
and sync summaries for diagnosing sync issues.

* fix: address PR review feedback

- Fix regex precedence in error classification so 'timeout' doesn't match too broadly
- Add lang="en" to log viewer HTML for accessibility
- Add circular reference guard to redactObject to prevent stack overflow
- Update AGENTS.md with missing outlookDebug/outlookEventDetail imports

* fix: address second round of PR review feedback

- Narrow SSL/TLS regex to match specific error codes instead of broad substrings
- Make sanitizeContext recursive to redact nested sensitive keys
- Align multi-line JSON context with box-drawing prefix in error logs
- Preserve original case in custom path segments in buildEwsPathname

---------

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>

* Version 4.12.1-alpha.4

* fix: log viewer Windows compatibility and Outlook logging in production (#3203)

- Handle CRLF line endings from Windows log files (split on \r?\n)
- Fix regex to allow variable whitespace between bracket groups
- Change outlookLog/outlookDebug/outlookEventDetail to console.info
  so they reach the file transport in production (info threshold)
  instead of being silently dropped as debug level
- Fix Outlook preload console.log calls to console.info (same issue)
- Fix app startup completion log to console.info

* Version 4.12.1-alpha.5

* fix: always send endTime and busy fields in calendar sync payload (#3204)

Remove server version gate (>= 7.5.0) that conditionally included endTime and busy fields when syncing Outlook calendar events to Rocket.Chat server. The gate was failing for some customers because server.version was not populated in the Redux store, causing these fields to be silently dropped from create/update payloads regardless of actual server version.

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

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

* Version 4.12.1-alpha.6

* Merge master into dev — bring bug fixes to dev branch (#3215)

* feat: Add Exchange/EWS debugging patches and error classification (#3187)

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

* Language update from Lingohub 🤖 (#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  (#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 (#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 (#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (#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 (#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 #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>

* feat: Add scoped logging infrastructure and log viewer window (#3186)

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

* Language update from Lingohub 🤖 (#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  (#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 (#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 (#3155)

* chore: Upgrade Electron and Node.js versions, update README and packa… (#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 (#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>

* fix: Add safe guards to prevent The application GUI just crashed (#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…
@jeanfbrito jeanfbrito closed this Apr 6, 2026
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.

3 participants