mirror of
https://github.com/grafana/grafana.git
synced 2024-11-29 12:14:08 -06:00
FE Sandbox: Fix worker post message not handling proxy objects correctly (#86654)
* FE Sandbox: Fix worker post message not handling proxy objects correctly * use expect error instead of ignore * use assertion instead of ignore * Fix formatting
This commit is contained in:
parent
3d55602fde
commit
0ec9c3e01a
@ -6,7 +6,7 @@ import { CustomVariableSupport, DataSourceApi } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
|
||||
import { forbiddenElements } from './constants';
|
||||
import { isReactClassComponent, logWarning } from './utils';
|
||||
import { isReactClassComponent, logWarning, unboxNearMembraneProxies } from './utils';
|
||||
|
||||
// IMPORTANT: NEVER export this symbol from a public (e.g `@grafana/*`) package
|
||||
const SANDBOX_LIVE_VALUE = Symbol.for('@@SANDBOX_LIVE_VALUE');
|
||||
@ -194,9 +194,30 @@ export function patchWebAPIs() {
|
||||
if (!nativeAPIsPatched) {
|
||||
nativeAPIsPatched = true;
|
||||
patchHistoryReplaceState();
|
||||
patchWorkerPostMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Worker.postMessage uses internally structureClone which won't work with proxies.
|
||||
*
|
||||
* In case where the blue realm code is directly handling proxy objects that
|
||||
* should be send over a post message the blue realm will call postMessage and try to
|
||||
* send the proxy resulting in an error.
|
||||
*
|
||||
* This makes sure all proxies are unboxed before being sent over the post message
|
||||
*/
|
||||
function patchWorkerPostMessage() {
|
||||
const originalPostMessage = Worker.prototype.postMessage;
|
||||
Object.defineProperty(Worker.prototype, 'postMessage', {
|
||||
value: function (...args: Parameters<typeof Worker.prototype.postMessage>) {
|
||||
// eslint-disable-next-line
|
||||
return originalPostMessage.apply(this, unboxNearMembraneProxies(args) as typeof args);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* window.history.replaceState is a native API that won't work with proxies
|
||||
* so we need to patch it to unwrap any possible proxies you pass to it.
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { isNearMembraneProxy } from '@locker/near-membrane-shared';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import React from 'react';
|
||||
|
||||
import { PluginSignatureType, PluginType } from '@grafana/data';
|
||||
@ -112,3 +113,24 @@ export function unboxRegexesFromMembraneProxy(structure: unknown): unknown {
|
||||
}
|
||||
return structure;
|
||||
}
|
||||
|
||||
export function unboxNearMembraneProxies(structure: unknown): unknown {
|
||||
if (!structure) {
|
||||
return structure;
|
||||
}
|
||||
|
||||
if (isNearMembraneProxy(structure)) {
|
||||
return cloneDeep(structure);
|
||||
}
|
||||
|
||||
if (Array.isArray(structure)) {
|
||||
return structure.map(unboxNearMembraneProxies);
|
||||
}
|
||||
if (typeof structure === 'object') {
|
||||
return Object.keys(structure).reduce((acc, key) => {
|
||||
Reflect.set(acc, key, unboxNearMembraneProxies(Reflect.get(structure, key)));
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
return structure;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user