fix: prevent microphone indicator on startup by adding setPermissionCheckHandler#3278
Conversation
WalkthroughAdded a permission check handler for Electron's session that selectively allows only 'media' permissions while denying others on guest webview sessions when they become ready, preventing unnecessary system resource access on startup. Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Suggested labels
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/ui/main/serverView/index.ts (2)
431-434: Consider adding a comment explaining the purpose of the permission check handler.This handler is specifically added to fix issue
#3112(preventing the Windows microphone indicator on startup). Adding a brief comment would help future maintainers understand why this handler exists and why it differs in scope fromsetPermissionRequestHandler.+ // Intercept synchronous permission checks (e.g., navigator.permissions.query()) + // to prevent OS-level API calls that trigger the Windows microphone indicator on startup. + // See: https://github.com/RocketChat/Rocket.Chat.Electron/issues/3112 guestWebContents.session.setPermissionCheckHandler(handlePermissionCheck);🤖 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 431 - 434, Add a brief comment above the guestWebContents.session.setPermissionCheckHandler(...) call explaining that handlePermissionCheck is registered specifically to work around issue `#3112` (prevent the Windows microphone indicator appearing on startup) and that this check is intentionally broader/different in scope from guestWebContents.session.setPermissionRequestHandler(handlePermissionRequest) (which handles per-request permission prompts), so future maintainers understand why both handlers exist and how they differ.
373-376: Simplify the conditional return.The if/return pattern can be simplified for readability.
✨ Suggested simplification
const handlePermissionCheck: Parameters< Session['setPermissionCheckHandler'] >[0] = (_webContents, permission) => { - if (permission === 'media') { - return true; - } - return false; + return permission === 'media'; };🤖 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 373 - 376, Replace the redundant if/return pattern that checks the permission variable with a single boolean return; locate the snippet using the permission variable in serverView/index.ts (inside the function/method that currently contains "if (permission === 'media') { return true; } return false;") and change it to directly return the expression permission === 'media' to simplify and improve readability.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/ui/main/serverView/index.ts`:
- Around line 431-434: Add a brief comment above the
guestWebContents.session.setPermissionCheckHandler(...) call explaining that
handlePermissionCheck is registered specifically to work around issue `#3112`
(prevent the Windows microphone indicator appearing on startup) and that this
check is intentionally broader/different in scope from
guestWebContents.session.setPermissionRequestHandler(handlePermissionRequest)
(which handles per-request permission prompts), so future maintainers understand
why both handlers exist and how they differ.
- Around line 373-376: Replace the redundant if/return pattern that checks the
permission variable with a single boolean return; locate the snippet using the
permission variable in serverView/index.ts (inside the function/method that
currently contains "if (permission === 'media') { return true; } return false;")
and change it to directly return the expression permission === 'media' to
simplify and improve readability.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 14a0cc5e-9347-4aed-a24a-df676f1df31f
📒 Files selected for processing (1)
src/ui/main/serverView/index.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use TypeScript strict mode enabled in TypeScript configuration
Use React functional components with hooks instead of class components
Follow FSA (Flux Standard Action) pattern for Redux actions
Use camelCase for file names and PascalCase for component file names
All code must pass ESLint and TypeScript checks
Write self-documenting code with clear naming; avoid unnecessary comments except for complex business logic or non-obvious decisions
Use Fuselage components from@rocket.chat/fuselagefor all UI work and only create custom components when Fuselage doesn't provide what's needed
CheckTheme.d.tsfor valid color tokens when using Fuselage components
Use defensive coding with optional chaining and fallbacks for Linux-only APIs (process.getuid(), process.getgid(), process.geteuid(), process.getegid()) to ensure cross-platform compatibility across Windows, macOS, and Linux
Files:
src/ui/main/serverView/index.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 (1)
src/ui/main/serverView/index.ts (1)
370-377: ThehandlePermissionCheckhandler is intentionally narrow in scope and serves a different purpose thanhandlePermissionRequest. ThesetPermissionCheckHandlerresponds only tonavigator.permissions.query()calls, whilesetPermissionRequestHandlerhandles actual permission requests. Sincepermissions.query()is not used in the codebase, and screen sharing uses Jitsi's legacy chromeMediaSource constraints rather than the standarddisplay-capturepermission, the current implementation correctly addresses its targeted purpose: preventing the microphone indicator from appearing on startup. Aligning these handlers is unnecessary and could broaden the scope beyond the intended fix.> Likely an incorrect or invalid review comment.
|
Thanks for the PR! The approach is correct — However, the handler should mirror the permissions already granted by This could cause inconsistencies — for example, if the webapp calls The fix would be: const ALLOWED_PERMISSIONS = [
'media',
'geolocation',
'notifications',
'midiSysex',
'pointerLock',
'fullscreen',
] as const;
const handlePermissionCheck: Parameters<
Session['setPermissionCheckHandler']
>[0] = (_webContents, permission) => {
return ALLOWED_PERMISSIONS.includes(permission as any);
};Also, this PR was based on an older version of the codebase and will likely have merge conflicts with the current |
Fixes #3112
Problem
On Windows, the app triggers the microphone-in-use taskbar indicator
on startup because the webapp's routine
navigator.permissions.query()calls escalated into OS-level
getMediaAccessStatus('microphone')calls.Fix
Added
setPermissionCheckHandlerinserverView/index.tsthat returnstruefor'media'permission checks. This intercepts the webapp'sstartup permission queries before they escalate to OS API calls that
trigger the mic indicator.
Summary by CodeRabbit