Browse Source

feat: add proxy block

Ahmad Kholid 3 years ago
parent
commit
a2e7bd1447

+ 3 - 0
src/assets/css/tailwind.css

@@ -58,4 +58,7 @@ select:focus,
   .bg-box-transparent {
     @apply bg-black bg-opacity-5 dark:bg-gray-200 dark:bg-opacity-5;
   }
+  .bg-box-transparent-2 {
+    @apply bg-black bg-opacity-10 dark:bg-gray-200 dark:bg-opacity-10;
+  }
 }

+ 0 - 2
src/background/workflow-engine/blocks-handler/handler-loop-data.js

@@ -47,8 +47,6 @@ function loopData(block) {
       };
       /* eslint-disable-next-line */
       this.loopData[data.loopId] = data.loopThrough === 'numbers' ? data.fromNumber : currLoopData[0];
-
-      console.log(this.loopList, this.loopData);
     }
 
     resolve({

+ 60 - 0
src/background/workflow-engine/blocks-handler/handler-proxy.js

@@ -0,0 +1,60 @@
+import { isWhitespace } from '@/utils/helper';
+import { getBlockConnection } from '../helper';
+
+function setProxy({ data, outputs }) {
+  const nextBlockId = getBlockConnection({ outputs });
+
+  return new Promise((resolve, reject) => {
+    if (data.clearProxy) {
+      chrome.proxy.settings.clear({});
+    }
+
+    const config = {
+      mode: 'fixed_servers',
+      rules: {
+        singleProxy: {
+          scheme: data.scheme,
+        },
+        bypassList: isWhitespace(data.bypassList)
+          ? []
+          : data.bypassList.split(','),
+      },
+    };
+
+    if (!isWhitespace(data.host)) {
+      config.rules.singleProxy.host = data.host;
+    } else {
+      if (data.clearProxy) {
+        this.isUsingProxy = false;
+
+        resolve({
+          data: '',
+          nextBlockId,
+        });
+
+        return;
+      }
+
+      const error = new Error('invalid-proxy-host');
+      error.nextBlockId = nextBlockId;
+
+      reject(error);
+      return;
+    }
+
+    if (data.port !== 0) {
+      config.rules.singleProxy.port = data.port;
+    }
+
+    chrome.proxy.settings.set({ value: config, scope: 'regular' }, () => {
+      this.isUsingProxy = true;
+
+      resolve({
+        data: data.host,
+        nextBlockId,
+      });
+    });
+  });
+}
+
+export default setProxy;

+ 3 - 1
src/background/workflow-engine/engine.js

@@ -93,6 +93,7 @@ class WorkflowEngine {
     this.eventListeners = {};
     this.isPaused = false;
     this.isDestroyed = false;
+    this.isUsingProxy = false;
     this.frameId = null;
     this.windowId = null;
     this.tabGroupId = null;
@@ -172,7 +173,6 @@ class WorkflowEngine {
   async stop(message) {
     try {
       if (this.childWorkflow) {
-        console.log('setop', this.childWorkflow);
         await this.childWorkflow.stop();
       }
 
@@ -190,6 +190,8 @@ class WorkflowEngine {
 
   async destroy(status, message) {
     try {
+      if (this.isUsingProxy) chrome.proxy.settings.clear({});
+
       await browser.tabs.onRemoved.removeListener(this.tabRemovedHandler);
       await browser.tabs.onUpdated.removeListener(this.tabUpdatedHandler);
 

+ 77 - 0
src/components/newtab/workflow/edit/EditProxy.vue

@@ -0,0 +1,77 @@
+<template>
+  <div>
+    <div class="flex items-center mb-1">
+      <ui-select
+        :model-value="data.scheme"
+        label="Scheme"
+        class="mr-2"
+        @change="updateData({ scheme: $event })"
+      >
+        <option v-for="scheme in schemes" :key="scheme" :value="scheme">
+          {{ scheme.toUpperCase() }}
+        </option>
+      </ui-select>
+      <ui-input
+        :model-value="data.port"
+        label="Port"
+        placeholder="443"
+        class="flex-1"
+        type="number"
+        @change="updateData({ port: +$event })"
+      />
+    </div>
+    <ui-input
+      :model-value="data.host"
+      label="Host"
+      placeholder="1.2.3.4"
+      class="w-full mb-2"
+      @change="updateData({ host: $event })"
+    />
+    <ui-input
+      :model-value="data.bypassList"
+      placeholder="example1.com, example2.org"
+      class="w-full"
+      @change="updateData({ bypassList: $event })"
+    >
+      <template #label>
+        {{ t('workflow.blocks.proxy.bypass.label') }}
+        <a
+          href="https://developer.chrome.com/docs/extensions/reference/proxy/#bypass-list"
+          target="_blank"
+          rel="noopener"
+        >
+          &#128712;
+        </a>
+      </template>
+    </ui-input>
+    <p class="text-gray-600 dark:text-gray-200 text-sm">
+      {{ t('workflow.blocks.proxy.bypass.note') }}
+    </p>
+    <ui-checkbox
+      :model-value="data.clearProxy"
+      class="mt-4"
+      @change="updateData({ clearProxy: $event })"
+    >
+      {{ t('workflow.blocks.proxy.clear') }}
+    </ui-checkbox>
+  </div>
+</template>
+<script setup>
+import { useI18n } from 'vue-i18n';
+
+const props = defineProps({
+  data: {
+    type: Object,
+    default: () => ({}),
+  },
+});
+const emit = defineEmits(['update:data']);
+
+const { t } = useI18n();
+
+const schemes = Object.values(chrome.proxy.Scheme);
+
+function updateData(value) {
+  emit('update:data', { ...props.data, ...value });
+}
+</script>

+ 2 - 2
src/content/blocks-handler/handler-forms.js

@@ -5,7 +5,7 @@ function forms(block) {
   return new Promise((resolve) => {
     const { data } = block;
     const elements = handleElement(block, true);
-    console.log(data);
+
     if (data.getValue) {
       let result = '';
 
@@ -14,7 +14,7 @@ function forms(block) {
       } else {
         result = elements.value || '';
       }
-      console.log(result);
+
       resolve(result);
       return;
     }

+ 2 - 0
src/lib/v-remixicon.js

@@ -3,6 +3,7 @@ import {
   riHome5Line,
   riHandHeartLine,
   riFileCopyLine,
+  riShieldKeyholeLine,
   riToggleLine,
   riFolderLine,
   riInformationLine,
@@ -78,6 +79,7 @@ export const icons = {
   riHome5Line,
   riHandHeartLine,
   riFileCopyLine,
+  riShieldKeyholeLine,
   riToggleLine,
   riFolderLine,
   riInformationLine,

+ 9 - 0
src/locales/en/blocks.json

@@ -67,6 +67,15 @@
         "name": "Active tab",
         "description": "Set current tab that you're in as an active tab"
       },
+      "proxy": {
+        "name": "Proxy",
+        "description": "Set the proxy of the browser",
+        "clear": "Clear all proxy",
+        "bypass": {
+          "label": "Bypass list",
+          "note": "Use commas (,) to separate URL"
+        }
+      },
       "new-window": {
         "name": "New window",
         "description": "Create a new window",

+ 1 - 0
src/locales/en/newtab.json

@@ -82,6 +82,7 @@
     "messages": {
       "workflow-disabled": "Workflow is disabled",
       "stop-timeout": "Workflow is stopped because of timeout",
+      "invalid-proxy-host": "Invalid proxy host",
       "no-iframe-id": "Can't find Frame ID for the iframe element with \"{selector}\" selector",
       "no-tab": "Can't connect to a tab, use \"New tab\" or \"Active tab\" block before using the \"{name}\" block.",
       "empty-workflow": "You must select a workflow first",

+ 1 - 0
src/manifest.json

@@ -28,6 +28,7 @@
   ],
   "permissions": [
     "tabs",
+    "proxy",
     "alarms",
     "storage",
     "unlimitedStorage",

+ 4 - 0
src/utils/helper.js

@@ -1,3 +1,7 @@
+export function isWhitespace(str) {
+  return !/\S/g.test(str);
+}
+
 export function parseJSON(data, def) {
   try {
     const result = JSON.parse(data);

+ 19 - 0
src/utils/shared.js

@@ -92,6 +92,25 @@ export const tasks = {
       windowState: 'normal',
     },
   },
+  proxy: {
+    name: 'Proxy',
+    description: 'Set the proxy of the browser',
+    icon: 'riShieldKeyholeLine',
+    component: 'BlockBasic',
+    category: 'browser',
+    editComponent: 'EditProxy',
+    inputs: 1,
+    outputs: 1,
+    maxConnection: 1,
+    allowedInputs: true,
+    data: {
+      scheme: 'https',
+      host: '',
+      port: 443,
+      bypassList: '',
+      clearProxy: false,
+    },
+  },
   'go-back': {
     name: 'Go back',
     description: 'Go back to the previous page',