fix: ensure that internal messages are sent from the main process (#26429)

This commit is contained in:
Milan Burda 2020-11-12 04:20:01 +01:00 committed by GitHub
parent 83d30c5c2a
commit 5ee9cc202b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 34 additions and 9 deletions

View file

@ -302,7 +302,7 @@ function metaToError (meta: { type: 'error', value: any, members: ObjectMember[]
} }
function handleMessage (channel: string, handler: Function) { function handleMessage (channel: string, handler: Function) {
ipcRendererInternal.on(channel, (event, passedContextId, id, ...args) => { ipcRendererInternal.onMessageFromMain(channel, (event, passedContextId, id, ...args) => {
if (passedContextId === contextId) { if (passedContextId === contextId) {
handler(id, ...args); handler(id, ...args);
} else { } else {

View file

@ -3,7 +3,7 @@ import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-in
type IPCHandler = (event: Electron.IpcRendererEvent, ...args: any[]) => any type IPCHandler = (event: Electron.IpcRendererEvent, ...args: any[]) => any
export const handle = function <T extends IPCHandler> (channel: string, handler: T) { export const handle = function <T extends IPCHandler> (channel: string, handler: T) {
ipcRendererInternal.on(channel, async (event, requestId, ...args) => { ipcRendererInternal.onMessageFromMain(channel, async (event, requestId, ...args) => {
const replyChannel = `${channel}_RESPONSE_${requestId}`; const replyChannel = `${channel}_RESPONSE_${requestId}`;
try { try {
event.sender.send(replyChannel, null, await handler(event, ...args)); event.sender.send(replyChannel, null, await handler(event, ...args));

View file

@ -29,4 +29,27 @@ ipcRendererInternal.invoke = async function<T> (channel: string, ...args: any[])
return result; return result;
}; };
ipcRendererInternal.onMessageFromMain = function (channel: string, listener: (event: Electron.IpcRendererEvent, ...args: any[]) => void) {
return ipcRendererInternal.on(channel, (event, ...args) => {
if (event.senderId !== 0) {
console.error(`Message ${channel} sent by unexpected WebContents (${event.senderId})`);
return;
}
listener(event, ...args);
});
};
ipcRendererInternal.onceMessageFromMain = function (channel: string, listener: (event: Electron.IpcRendererEvent, ...args: any[]) => void) {
return ipcRendererInternal.on(channel, function wrapper (event, ...args) {
if (event.senderId !== 0) {
console.error(`Message ${channel} sent by unexpected WebContents (${event.senderId})`);
return;
}
ipcRendererInternal.removeListener(channel, wrapper);
listener(event, ...args);
});
};
export { ipcRendererInternal }; export { ipcRendererInternal };

View file

@ -32,17 +32,17 @@ const dispatchEvent = function (
}; };
export function registerEvents (webView: WebViewImpl, viewInstanceId: number) { export function registerEvents (webView: WebViewImpl, viewInstanceId: number) {
ipcRendererInternal.on(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DESTROY_GUEST}-${viewInstanceId}`, function () { ipcRendererInternal.onMessageFromMain(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DESTROY_GUEST}-${viewInstanceId}`, function () {
webView.guestInstanceId = undefined; webView.guestInstanceId = undefined;
webView.reset(); webView.reset();
webView.dispatchEvent('destroyed'); webView.dispatchEvent('destroyed');
}); });
ipcRendererInternal.on(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DISPATCH_EVENT}-${viewInstanceId}`, function (event, eventName, ...args) { ipcRendererInternal.onMessageFromMain(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DISPATCH_EVENT}-${viewInstanceId}`, function (event, eventName, ...args) {
dispatchEvent(webView, eventName, eventName, ...args); dispatchEvent(webView, eventName, eventName, ...args);
}); });
ipcRendererInternal.on(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_IPC_MESSAGE}-${viewInstanceId}`, function (event, channel, ...args) { ipcRendererInternal.onMessageFromMain(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_IPC_MESSAGE}-${viewInstanceId}`, function (event, channel, ...args) {
webView.dispatchEvent('ipc-message', { channel, args }); webView.dispatchEvent('ipc-message', { channel, args });
}); });
} }

View file

@ -182,7 +182,7 @@ class BrowserWindowProxy {
this.guestId = guestId; this.guestId = guestId;
this._location = new LocationProxy(guestId); this._location = new LocationProxy(guestId);
ipcRendererInternal.once(`${IPC_MESSAGES.GUEST_WINDOW_MANAGER_WINDOW_CLOSED}_${guestId}`, () => { ipcRendererInternal.onceMessageFromMain(`${IPC_MESSAGES.GUEST_WINDOW_MANAGER_WINDOW_CLOSED}_${guestId}`, () => {
removeProxy(guestId); removeProxy(guestId);
this.closed = true; this.closed = true;
}); });
@ -282,7 +282,7 @@ export const windowSetup = (
if (contextIsolationEnabled) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['prompt'], window.prompt); if (contextIsolationEnabled) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['prompt'], window.prompt);
if (!usesNativeWindowOpen || openerId != null) { if (!usesNativeWindowOpen || openerId != null) {
ipcRendererInternal.on(IPC_MESSAGES.GUEST_WINDOW_POSTMESSAGE, function ( ipcRendererInternal.onMessageFromMain(IPC_MESSAGES.GUEST_WINDOW_POSTMESSAGE, function (
_event, sourceId: number, message: any, sourceOrigin: string _event, sourceId: number, message: any, sourceOrigin: string
) { ) {
// Manually dispatch event instead of using postMessage because we also need to // Manually dispatch event instead of using postMessage because we also need to
@ -337,7 +337,7 @@ export const windowSetup = (
let cachedVisibilityState = isHiddenPage ? 'hidden' : 'visible'; let cachedVisibilityState = isHiddenPage ? 'hidden' : 'visible';
// Subscribe to visibilityState changes. // Subscribe to visibilityState changes.
ipcRendererInternal.on(IPC_MESSAGES.GUEST_INSTANCE_VISIBILITY_CHANGE, function (_event, visibilityState: VisibilityState) { ipcRendererInternal.onMessageFromMain(IPC_MESSAGES.GUEST_INSTANCE_VISIBILITY_CHANGE, function (_event, visibilityState: VisibilityState) {
if (cachedVisibilityState !== visibilityState) { if (cachedVisibilityState !== visibilityState) {
cachedVisibilityState = visibilityState; cachedVisibilityState = visibilityState;
document.dispatchEvent(new Event('visibilitychange')); document.dispatchEvent(new Event('visibilitychange'));

View file

@ -232,7 +232,9 @@ declare namespace ElectronInternal {
interface IpcRendererInternal extends Electron.IpcRenderer { interface IpcRendererInternal extends Electron.IpcRenderer {
invoke<T>(channel: string, ...args: any[]): Promise<T>; invoke<T>(channel: string, ...args: any[]): Promise<T>;
sendToAll(webContentsId: number, channel: string, ...args: any[]): void sendToAll(webContentsId: number, channel: string, ...args: any[]): void;
onMessageFromMain(channel: string, listener: (event: Electron.IpcRendererEvent, ...args: any[]) => void): this;
onceMessageFromMain(channel: string, listener: (event: Electron.IpcRendererEvent, ...args: any[]) => void): this;
} }
// Internal IPC has _replyInternal and NO reply method // Internal IPC has _replyInternal and NO reply method