Sandbox: Fix history.replace calls inside the sandbox (#76049)
* Sandbox: Fix `history.replace` calls inside the sandbox * Improve signature verification and comments * Add clarifying comment
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { ProxyTarget } from '@locker/near-membrane-shared';
|
||||
import { cloneDeep, isFunction } from 'lodash';
|
||||
|
||||
import { PluginMeta } from '@grafana/data';
|
||||
@@ -520,13 +521,31 @@ async function distortPostMessage(distortions: DistortionMap) {
|
||||
}
|
||||
|
||||
/**
|
||||
* We define "live" APIs as APIs that can only be distorted in runtime on-the-fly and not at initialization
|
||||
* time like other distortions do.
|
||||
*
|
||||
* This could be because the objects we want to patch only become available after specific states are reached
|
||||
* or because the libraries we want to patch are lazy-loaded and we don't have access to their definitions
|
||||
*
|
||||
* "Live" APIs are APIs that can only be distorted at runtime.
|
||||
* This could be because the objects we want to patch only become available after specific states are reached,
|
||||
* or because the libraries we want to patch are lazy-loaded and we don't have access to their definitions.
|
||||
* We put here only distortions that can't be static because they are dynamicly loaded
|
||||
*/
|
||||
export async function distortLiveApis() {
|
||||
export function distortLiveApis(originalValue: ProxyTarget): ProxyTarget | undefined {
|
||||
distortMonacoEditor(generalDistortionMap);
|
||||
|
||||
// This distorts the `history.replace` function in react-router-dom.
|
||||
// constructed for each browser history and is only accessible within the react context.
|
||||
// Note that this distortion does not affect `String.prototype.replace` calls.
|
||||
// because they don't go through distortions
|
||||
if (
|
||||
originalValue instanceof Function &&
|
||||
originalValue.name === 'replace' &&
|
||||
originalValue.prototype.constructor.length === 2
|
||||
) {
|
||||
return function replace(this: unknown, ...args: unknown[]) {
|
||||
// validate history.replace signature further
|
||||
if (args && args[0] && typeof args[0] === 'string' && args[1] && !(args[1] instanceof Function)) {
|
||||
const newArgs = cloneDeep(args);
|
||||
return Reflect.apply(originalValue, this, newArgs);
|
||||
}
|
||||
return Reflect.apply(originalValue, this, args);
|
||||
};
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -63,10 +63,17 @@ async function doImportPluginModuleInSandbox(meta: PluginMeta): Promise<System.M
|
||||
} else {
|
||||
patchObjectAsLiveTarget(originalValue);
|
||||
}
|
||||
distortLiveApis();
|
||||
const distortion = generalDistortionMap.get(originalValue);
|
||||
if (distortion) {
|
||||
return distortion(originalValue, meta, sandboxEnvironment) as ProxyTarget;
|
||||
|
||||
// static distortions are faster distortions with direct object descriptors checks
|
||||
const staticDistortion = generalDistortionMap.get(originalValue);
|
||||
if (staticDistortion) {
|
||||
return staticDistortion(originalValue, meta, sandboxEnvironment) as ProxyTarget;
|
||||
}
|
||||
|
||||
// live distortions are slower and have to do runtime checks
|
||||
const liveDistortion = distortLiveApis(originalValue);
|
||||
if (liveDistortion) {
|
||||
return liveDistortion;
|
||||
}
|
||||
return originalValue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user