From 660d3b8fcf92508fcebd69b77bfc3bc056adbee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Tue, 31 Jan 2023 14:43:00 +0100 Subject: [PATCH] fix(aot) validate frame name --- alwaysontop/main/index.js | 40 ++++++++++++++++++++++++++++++------- alwaysontop/main/utils.js | 13 +----------- alwaysontop/render/index.js | 11 +++++----- 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/alwaysontop/main/index.js b/alwaysontop/main/index.js index fa21f390..e7ebfe55 100644 --- a/alwaysontop/main/index.js +++ b/alwaysontop/main/index.js @@ -1,6 +1,7 @@ +const crypto = require('crypto'); const electron = require('electron'); const os = require('os'); -const { ipcMain } = electron; +const { BrowserWindow, ipcMain } = electron; const { windowsEnableScreenProtection } = require('../../helpers/functions'); const { EVENTS, STATES, AOT_WINDOW_NAME, EVENTS_CHANNEL } = require('../constants'); @@ -13,11 +14,15 @@ const { savePosition, setAspectRatioToResizeableWindow, setLogger, - windowExists, - getAotWindow + windowExists } = require('./utils'); const aotConfig = require('./config'); +/** + * Token for matching window open requests. + */ +let aotMagic; + /** * The main window instance */ @@ -34,14 +39,23 @@ let isIntersecting; */ let _existingWindowOpenHandler; +/** + * The aot window instance + */ +const getAotWindow = () => BrowserWindow.getAllWindows().find(win => { + if (!win || win.isDestroyed() || win.webContents.isCrashed()) return false; + const frameName = win.webContents.mainFrame.name || ''; + return frameName === `${AOT_WINDOW_NAME}-${aotMagic}`; +}); + /** * Sends an update state event to renderer process * @param {string} value the updated aot window state */ -const sendStateUpdate = state => { +const sendStateUpdate = (state, data = {}) => { logInfo(`sending ${state} state update to renderer process`); - mainWindow.webContents.send(EVENTS_CHANNEL, { name: EVENTS.UPDATE_STATE, state }); + mainWindow.webContents.send(EVENTS_CHANNEL, { name: EVENTS.UPDATE_STATE, state, data }); }; /** @@ -87,9 +101,17 @@ const handleWindowCreated = window => { const windowOpenHandler = args => { const { frameName } = args; - if (frameName === AOT_WINDOW_NAME) { + if (frameName.startsWith(AOT_WINDOW_NAME)) { logInfo('handling new aot window event'); + const magic = frameName.split('-')[1]; + + if (magic !== aotMagic) { + logInfo('bad AoT window magic'); + + return { action: 'deny' }; + } + return { action: 'allow', overrideBrowserWindowOptions: { @@ -114,6 +136,8 @@ const showAot = () => { logInfo('show aot handler'); let state; + let data = {}; + const aotWindow = getAotWindow(); if (windowExists(aotWindow)) { @@ -121,9 +145,11 @@ const showAot = () => { aotWindow.showInactive(); } else { state = STATES.OPEN; + aotMagic = crypto.randomUUID().replaceAll('-', ''); + data.aotMagic = aotMagic; } - sendStateUpdate(state); + sendStateUpdate(state, data); }; /** diff --git a/alwaysontop/main/utils.js b/alwaysontop/main/utils.js index ea54f800..52e393dd 100644 --- a/alwaysontop/main/utils.js +++ b/alwaysontop/main/utils.js @@ -2,8 +2,7 @@ const Store = require('electron-store'); const electron = require('electron'); const os = require('os'); const log = require('@jitsi/logger'); -const { SIZE, ASPECT_RATIO, STORAGE, AOT_WINDOW_NAME } = require('../constants'); -const { BrowserWindow } = electron; +const { SIZE, ASPECT_RATIO, STORAGE } = require('../constants'); /** * Stores the current size of the AOT during the conference @@ -27,15 +26,6 @@ let logger; const store = new Store(); -/** - * The aot window instance - */ - const getAotWindow = () => BrowserWindow.getAllWindows().find(win => { - if (!win || win.isDestroyed() || win.webContents.isCrashed()) return false; - const frameName = win.webContents.mainFrame.name || ''; - return frameName === AOT_WINDOW_NAME; -}); - /** * Changes the window resize functionality to respect the passed aspect ratio. * @@ -244,7 +234,6 @@ const windowExists = browserWindow => { }; module.exports = { - getAotWindow, getPosition, getSize, logError, diff --git a/alwaysontop/render/index.js b/alwaysontop/render/index.js index 6468d436..385d303e 100644 --- a/alwaysontop/render/index.js +++ b/alwaysontop/render/index.js @@ -172,13 +172,13 @@ class AlwaysOnTop extends EventEmitter { /** * Opens a new window */ - _openNewWindow() { + _openNewWindow(magic) { logInfo('new window'); this._api.on('largeVideoChanged', this._updateLargeVideoSrc); this._api.on('prejoinVideoChanged', this._updateLargeVideoSrc); this._api.on('videoMuteStatusChanged', this._updateLargeVideoSrc); - this._aotWindow = window.open('', AOT_WINDOW_NAME); + this._aotWindow = window.open('', `${AOT_WINDOW_NAME}-${magic}`); this._aotWindow.alwaysOnTop = { api: this._api, dismiss: this._dismiss, @@ -291,7 +291,7 @@ class AlwaysOnTop extends EventEmitter { _onAotEvent (event, { name, ...rest }) { switch (name) { case EVENTS.UPDATE_STATE: - this._handleStateChange(rest.state); + this._handleStateChange(rest.state, rest.data); break; } } @@ -300,8 +300,9 @@ class AlwaysOnTop extends EventEmitter { * Handler for state updates * * @param {string} state updated state + * @param {Object} data ancillary data to the event */ - _handleStateChange (state) { + _handleStateChange (state, data) { logInfo(`handling ${state} state update from main process`); switch (state) { @@ -309,7 +310,7 @@ class AlwaysOnTop extends EventEmitter { this._hideWindow(); break; case STATES.OPEN: - this._openNewWindow(); + this._openNewWindow(data.aotMagic); break; case STATES.SHOW: this._showWindow();