Răsfoiți Sursa

fix: condition code not working on some website

Ahmad Kholid 2 ani în urmă
părinte
comite
5e30ad5d03

+ 41 - 7
src/workflowEngine/blocksHandler/handlerConditions.js

@@ -3,9 +3,10 @@ import browser from 'webextension-polyfill';
 import compareBlockValue from '@/utils/compareBlockValue';
 import testConditions from '@/utils/testConditions';
 import renderString from '../templating/renderString';
-import { automaRefDataStr, messageSandbox } from '../helper';
+import { automaRefDataStr, messageSandbox, checkCSPAndInject } from '../helper';
 
 const nanoid = customAlphabet('1234567890abcdef', 5);
+const isMV2 = browser.runtime.getManifest().manifest_version === 2;
 
 function checkConditions(data, conditionOptions) {
   return new Promise((resolve, reject) => {
@@ -46,7 +47,7 @@ function checkConditions(data, conditionOptions) {
   });
 }
 async function checkCodeCondition(activeTab, payload) {
-  const variableId = nanoid();
+  const variableId = `automa${nanoid()}`;
 
   if (
     !payload.data.context ||
@@ -55,16 +56,45 @@ async function checkCodeCondition(activeTab, payload) {
   ) {
     if (!activeTab.id) throw new Error('no-tab');
 
+    const refDataScriptStr = automaRefDataStr(variableId);
+
+    if (!isMV2) {
+      const result = await checkCSPAndInject(
+        {
+          target: { tabId: activeTab.id },
+          debugMode: payload.debugMode,
+        },
+        () => {
+          return `
+          (async () => {
+            const ${variableId} = ${JSON.stringify(payload.refData)};
+            ${refDataScriptStr}
+            try {
+              ${payload.data.code}
+            } catch (error) {
+              return {
+                $isError: true,
+                message: error.message,
+              }
+            }
+          })();
+        `;
+        }
+      );
+
+      if (result.isBlocked) return result.value;
+    }
+
     const [{ result }] = await browser.scripting.executeScript({
       world: 'MAIN',
-      args: [payload, variableId, automaRefDataStr(variableId)],
+      args: [payload, variableId, refDataScriptStr],
       target: {
         tabId: activeTab.id,
         frameIds: [activeTab.frameId || 0],
       },
       func: ({ data, refData }, varId, refDataScript) => {
         return new Promise((resolve, reject) => {
-          const varName = `automa${varId}`;
+          const varName = varId;
 
           const scriptEl = document.createElement('script');
           scriptEl.textContent = `
@@ -132,13 +162,17 @@ async function conditions({ data, id }, { prevBlockData, refData }) {
     ? prevBlockData[0]
     : prevBlockData;
 
+  const { debugMode } = this.engine.workflow?.settings || {};
+
   if (condition && condition.conditions) {
     const conditionPayload = {
+      isMV2,
       refData,
-      isMV2: this.engine.isMV2,
       isPopup: this.engine.isPopup,
-      checkCodeCondition: (payload) =>
-        checkCodeCondition(this.activeTab, payload),
+      checkCodeCondition: (payload) => {
+        payload.debugMode = debugMode;
+        return checkCodeCondition(this.activeTab, payload);
+      },
       sendMessage: (payload) =>
         this._sendMessageToTab({ ...payload.data, label: 'conditions', id }),
     };

+ 7 - 59
src/workflowEngine/blocksHandler/handlerJavascriptCode.js

@@ -7,10 +7,10 @@ import {
   jsContentHandlerEval,
 } from '../utils/javascriptBlockUtil';
 import {
+  waitTabLoaded,
   messageSandbox,
   automaRefDataStr,
-  waitTabLoaded,
-  sendDebugCommand,
+  checkCSPAndInject,
 } from '../helper';
 
 const nanoid = customAlphabet('1234567890abcdef', 5);
@@ -70,39 +70,8 @@ async function executeInWebpage(args, target, worker) {
     return result;
   }
 
-  const [isBlockedByCSP] = await browser.scripting.executeScript({
-    target,
-    func: () => {
-      return new Promise((resolve) => {
-        const eventListener = ({ srcElement }) => {
-          if (!srcElement || srcElement.id !== 'automa-csp') return;
-          srcElement.remove();
-          resolve(true);
-        };
-        document.addEventListener('securitypolicyviolation', eventListener);
-        const script = document.createElement('script');
-        script.id = 'automa-csp';
-        script.innerText = 'console.log("...")';
-
-        setTimeout(() => {
-          document.removeEventListener(
-            'securitypolicyviolation',
-            eventListener
-          );
-          script.remove();
-          resolve(false);
-        }, 500);
-
-        document.body.appendChild(script);
-      });
-    },
-    world: 'MAIN',
-  });
-
-  if (isBlockedByCSP.result) {
-    await new Promise((resolve) => {
-      chrome.debugger.attach({ tabId: target.tabId }, '1.3', resolve);
-    });
+  const { debugMode } = worker.engine.workflow.settings;
+  const cspResult = await checkCSPAndInject({ target, debugMode }, () => {
     const { 0: blockData, 1: preloadScripts, 3: varName } = args;
     const automaScript = getAutomaScript(
       varName,
@@ -116,30 +85,9 @@ async function executeInWebpage(args, target, worker) {
       preloadScripts,
     });
 
-    const execResult = await sendDebugCommand(
-      target.tabId,
-      'Runtime.evaluate',
-      {
-        expression: jsCode,
-        userGesture: true,
-        awaitPromise: true,
-        returnByValue: true,
-      }
-    );
-
-    const { debugMode } = worker.engine.workflow.settings;
-    if (!debugMode) await chrome.debugger.detach({ tabId: target.tabId });
-
-    if (!execResult || !execResult.result) {
-      throw new Error('Unable execute code');
-    }
-
-    if (execResult.result.subtype === 'error') {
-      throw new Error(execResult.description);
-    }
-
-    return execResult.result.value || null;
-  }
+    return jsCode;
+  });
+  if (cspResult.isBlocked) return cspResult.value;
 
   const [{ result }] = await browser.scripting.executeScript({
     args,

+ 66 - 0
src/workflowEngine/helper.js

@@ -213,3 +213,69 @@ export function injectPreloadScript({ target, scripts, frameSelector }) {
     },
   });
 }
+
+export async function checkCSPAndInject({ target, debugMode }, callback) {
+  const [isBlockedByCSP] = await browser.scripting.executeScript({
+    target,
+    func: () => {
+      return new Promise((resolve) => {
+        const eventListener = ({ srcElement }) => {
+          if (!srcElement || srcElement.id !== 'automa-csp') return;
+          srcElement.remove();
+          resolve(true);
+        };
+        document.addEventListener('securitypolicyviolation', eventListener);
+        const script = document.createElement('script');
+        script.id = 'automa-csp';
+        script.innerText = 'console.log("...")';
+
+        setTimeout(() => {
+          document.removeEventListener(
+            'securitypolicyviolation',
+            eventListener
+          );
+          script.remove();
+          resolve(false);
+        }, 500);
+
+        document.body.appendChild(script);
+      });
+    },
+    world: 'MAIN',
+  });
+
+  if (isBlockedByCSP.result) {
+    await new Promise((resolve) => {
+      chrome.debugger.attach({ tabId: target.tabId }, '1.3', resolve);
+    });
+
+    const jsCode = await callback();
+    const execResult = await sendDebugCommand(
+      target.tabId,
+      'Runtime.evaluate',
+      {
+        expression: jsCode,
+        userGesture: true,
+        awaitPromise: true,
+        returnByValue: true,
+      }
+    );
+
+    if (!debugMode) await chrome.debugger.detach({ tabId: target.tabId });
+
+    if (!execResult || !execResult.result) {
+      throw new Error('Unable execute code');
+    }
+
+    if (execResult.result.subtype === 'error') {
+      throw new Error(execResult.result.description);
+    }
+
+    return {
+      isBlocked: true,
+      value: execResult.result.value || null,
+    };
+  }
+
+  return { isBlocked: false, value: null };
+}