[MM-54742] Force secure keyboard entry off when window loses focus and when servers switch (#2869)
* [MM-54742] Force secure keyboard entry off when window loses focus and when servers switch * Fix for when window is not focused, added tests
This commit is contained in:
@@ -16,6 +16,7 @@ import {
|
||||
SHOW_NEW_SERVER_MODAL,
|
||||
SHOW_REMOVE_SERVER_MODAL,
|
||||
SWITCH_SERVER,
|
||||
TOGGLE_SECURE_INPUT,
|
||||
UPDATE_SERVER_ORDER,
|
||||
UPDATE_SHORTCUT_MENU,
|
||||
UPDATE_TAB_ORDER,
|
||||
@@ -87,6 +88,7 @@ export class ServerViewState {
|
||||
ServerManager.getServerLog(serverId, 'WindowManager').error('Cannot find server in config');
|
||||
return;
|
||||
}
|
||||
ipcMain.emit(TOGGLE_SECURE_INPUT, null, false);
|
||||
this.currentServerId = serverId;
|
||||
const nextView = ServerManager.getLastActiveTabForServer(serverId);
|
||||
if (waitForViewToExist) {
|
||||
|
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {app} from 'electron';
|
||||
|
||||
import {getLocalURLString, getLocalPreload} from 'main/utils';
|
||||
import ServerManager from 'common/servers/serverManager';
|
||||
import MainWindow from 'main/windows/mainWindow';
|
||||
@@ -9,8 +11,15 @@ import ModalManager from 'main/views/modalManager';
|
||||
import {
|
||||
handleWelcomeScreenModal,
|
||||
handleMainWindowIsShown,
|
||||
handleToggleSecureInput,
|
||||
} from './intercom';
|
||||
|
||||
jest.mock('electron', () => ({
|
||||
app: {
|
||||
setSecureKeyboardEntryEnabled: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('app/serverViewState', () => ({}));
|
||||
jest.mock('common/config', () => ({
|
||||
setServers: jest.fn(),
|
||||
@@ -73,4 +82,38 @@ describe('main/app/intercom', () => {
|
||||
expect(ModalManager.addModal).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('handleToggleSecureInput', () => {
|
||||
beforeEach(() => {
|
||||
MainWindow.get.mockReturnValue({
|
||||
isFocused: () => true,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it('should not fire for OSes that are not macOS', () => {
|
||||
const originalPlatform = process.platform;
|
||||
Object.defineProperty(process, 'platform', {
|
||||
value: 'linux',
|
||||
});
|
||||
|
||||
handleToggleSecureInput({}, true);
|
||||
|
||||
Object.defineProperty(process, 'platform', {
|
||||
value: originalPlatform,
|
||||
});
|
||||
|
||||
expect(app.setSecureKeyboardEntryEnabled).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not fire if window is not focused', () => {
|
||||
MainWindow.get.mockReturnValue({isFocused: () => false});
|
||||
handleToggleSecureInput({}, true);
|
||||
|
||||
expect(app.setSecureKeyboardEntryEnabled).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -153,6 +153,11 @@ export function handleToggleSecureInput(event: IpcMainEvent, secureInput: boolea
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't allow this to turn on if the main window isn't focused
|
||||
if (secureInput && !MainWindow.get()?.isFocused()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Enforce macOS to restrict processes from reading the keyboard input when in a password field
|
||||
log.debug('handleToggleSecureInput', secureInput);
|
||||
app.setSecureKeyboardEntryEnabled(secureInput);
|
||||
|
@@ -376,14 +376,21 @@ window.addEventListener('resize', () => {
|
||||
});
|
||||
|
||||
let isPasswordBox = false;
|
||||
|
||||
window.addEventListener('focusin', (event) => {
|
||||
const targetIsPasswordBox = event.target.tagName === 'INPUT' && event.target.type === 'password';
|
||||
if (targetIsPasswordBox && !isPasswordBox) {
|
||||
const shouldSecureInput = (element, force = false) => {
|
||||
const targetIsPasswordBox = (element && element.tagName === 'INPUT' && element.type === 'password');
|
||||
if (targetIsPasswordBox && (!isPasswordBox || force)) {
|
||||
ipcRenderer.send(TOGGLE_SECURE_INPUT, true);
|
||||
} else if (!targetIsPasswordBox && isPasswordBox) {
|
||||
} else if (!targetIsPasswordBox && (isPasswordBox || force)) {
|
||||
ipcRenderer.send(TOGGLE_SECURE_INPUT, false);
|
||||
}
|
||||
|
||||
isPasswordBox = targetIsPasswordBox;
|
||||
};
|
||||
|
||||
window.addEventListener('focusin', (event) => {
|
||||
shouldSecureInput(event.target);
|
||||
});
|
||||
|
||||
window.addEventListener('focus', () => {
|
||||
shouldSecureInput(document.activeElement, true);
|
||||
});
|
||||
|
@@ -27,6 +27,7 @@ import {
|
||||
MAIN_WINDOW_RESIZED,
|
||||
MAIN_WINDOW_FOCUSED,
|
||||
VIEW_FINISHED_RESIZING,
|
||||
TOGGLE_SECURE_INPUT,
|
||||
} from 'common/communication';
|
||||
import Config from 'common/config';
|
||||
import {Logger} from 'common/log';
|
||||
@@ -314,6 +315,7 @@ export class MainWindow extends EventEmitter {
|
||||
globalShortcut.unregisterAll();
|
||||
|
||||
this.emit(MAIN_WINDOW_RESIZED, this.getBounds());
|
||||
ipcMain.emit(TOGGLE_SECURE_INPUT, null, false);
|
||||
|
||||
// App should save bounds when a window is closed.
|
||||
// However, 'close' is not fired in some situations(shutdown, ctrl+c)
|
||||
|
Reference in New Issue
Block a user