1 /* We create a proxy around the `chrome` or `browser` global object to hide them
2 * from the devtools of our extension. This is done to prevent developers from
3 * accidentally or intentionally modifying the extension's messaging system, which
4 * could cause unexpected behavior or security issues. By hiding these globals,
5 * we ensure that the extension's messaging system is only accessed through the
6 * provided APIs, and not directly through the devtools console or other means */
7 import browser, { type Browser } from 'webextension-polyfill';
9 import { logger } from '@proton/pass/utils/logger';
11 const self = globalThis as any;
16 browser: self.browser,
20 export const disableBrowserProxyTrap = () => (context.allowProxy = false);
22 /* To ensure that Sentry's internal checks involving the browser
23 * APIs don't interfere with the initialization of our apps, we
24 * wrap the proxy initialization in a setTimeout function, which
25 * delays the initialization until the next tick after our apps load.
26 * ⚠️ Make sure Sentry is always initialized on app boot. */
27 export default ((): Browser => {
28 if (BUILD_TARGET === 'safari') return self.browser;
30 const polyfill = browser;
35 Object.entries(context.globals)
36 .filter(([, value]) => value)
37 .forEach(([key, value]) => {
38 self[key] = new Proxy(value, {
39 get(target, prop, receiver) {
40 if (process.env.NODE_ENV !== 'development') {
41 /** Early return `undefined` for 'app' property to prevent
42 * Sentry's ChromeApp detection from generating errors */
43 if (prop === 'app') return undefined;
44 return logger.error(`[Extension::Error] extension API is protected`);
47 return Reflect.get(target, prop, receiver);
50 logger.error(`[Extension::Error] extension API is read-only`);
61 export const chromeAPI = context.globals.chrome as typeof chrome;