Browse Source

feat: workflow permissions modal when adding hosted workflow

Ahmad Kholid 2 years ago
parent
commit
671780123f
4 changed files with 74 additions and 62 deletions
  1. 2 0
      src/newtab/App.vue
  2. 52 17
      src/newtab/pages/Workflows.vue
  3. 3 42
      src/stores/hostedWorkflow.js
  4. 17 3
      src/utils/workflowData.js

+ 2 - 0
src/newtab/App.vue

@@ -190,6 +190,8 @@ async function syncHostedWorkflows() {
     hostIds.push({ hostId, updatedAt: hostedWorkflows[hostId].updatedAt });
   });
 
+  if (hostIds.length === 0) return;
+
   await hostedWorkflowStore.fetchWorkflows(hostIds);
 }
 

+ 52 - 17
src/newtab/pages/Workflows.vue

@@ -321,11 +321,13 @@ import { useToast } from 'vue-toastification';
 import { useDialog } from '@/composable/dialog';
 import { useShortcut } from '@/composable/shortcut';
 import { useGroupTooltip } from '@/composable/groupTooltip';
-import { isWhitespace } from '@/utils/helper';
+import { fetchApi } from '@/utils/api';
 import { useUserStore } from '@/stores/user';
 import { useWorkflowStore } from '@/stores/workflow';
 import { useTeamWorkflowStore } from '@/stores/teamWorkflow';
 import { useHostedWorkflowStore } from '@/stores/hostedWorkflow';
+import { registerWorkflowTrigger } from '@/utils/workflowTrigger';
+import { isWhitespace, findTriggerBlock } from '@/utils/helper';
 import { importWorkflow, getWorkflowPermissions } from '@/utils/workflowData';
 import recordWorkflow from '@/newtab/utils/startRecordWorkflow';
 import WorkflowsLocal from '@/components/newtab/workflows/WorkflowsLocal.vue';
@@ -408,6 +410,22 @@ function addWorkflow() {
   });
   clearAddWorkflowModal();
 }
+async function checkWorkflowPermissions(workflows) {
+  let requiredPermissions = [];
+
+  for (const workflow of workflows) {
+    if (workflow.drawflow) {
+      const permissions = await getWorkflowPermissions(workflow.drawflow);
+      requiredPermissions.push(...permissions);
+    }
+  }
+
+  requiredPermissions = Array.from(new Set(requiredPermissions));
+  if (requiredPermissions.length === 0) return;
+
+  permissionState.items = requiredPermissions;
+  permissionState.showModal = true;
+}
 function addHostedWorkflow() {
   dialog.prompt({
     async: true,
@@ -421,10 +439,41 @@ function addHostedWorkflow() {
       const hostId = value.replace(/\s/g, '');
 
       try {
-        await hostedWorkflowStore.addHostedWorkflow(hostId);
+        if (!userStore.user && hostedWorkflowStore.toArray.length >= 3)
+          throw new Error('rate-exceeded');
+
+        const isTheUserHost = userStore.getHostedWorkflows.some(
+          (host) => hostId === host.hostId
+        );
+        if (isTheUserHost) throw new Error('exist');
+
+        const response = await fetchApi('/workflows/hosted', {
+          method: 'POST',
+          body: JSON.stringify({ hostId }),
+        });
+        const result = await response.json();
+
+        if (!response.ok) {
+          const error = new Error(result.message);
+          error.data = result.data;
+
+          throw error;
+        }
+
+        if (result === null) throw new Error('not-found');
+
+        result.hostId = `${hostId}`;
+        result.createdAt = Date.now();
+
+        await checkWorkflowPermissions([result]);
+        await hostedWorkflowStore.insert(result, hostId);
+
+        const triggerBlock = findTriggerBlock(result.drawflow);
+        await registerWorkflowTrigger(hostId, triggerBlock);
 
         return true;
       } catch (error) {
+        console.error(error);
         const messages = {
           exists: t('workflow.host.messages.hostExist'),
           'rate-exceeded': t('message.rateExceeded'),
@@ -442,21 +491,7 @@ function addHostedWorkflow() {
 async function openImportDialog() {
   try {
     const workflows = await importWorkflow({ multiple: true });
-    const insertedWorkflows = Object.values(workflows);
-    let requiredPermissions = [];
-
-    for (const workflow of insertedWorkflows) {
-      if (workflow.drawflow) {
-        const permissions = await getWorkflowPermissions(workflow.drawflow);
-        requiredPermissions.push(...permissions);
-      }
-    }
-
-    requiredPermissions = Array.from(new Set(requiredPermissions));
-    if (requiredPermissions.length === 0) return;
-
-    permissionState.items = requiredPermissions;
-    permissionState.showModal = true;
+    await checkWorkflowPermissions(Object.values(workflows));
   } catch (error) {
     console.error(error);
   }

+ 3 - 42
src/stores/hostedWorkflow.js

@@ -1,12 +1,11 @@
 import { defineStore } from 'pinia';
 import browser from 'webextension-polyfill';
 import { fetchApi } from '@/utils/api';
-import { findTriggerBlock } from '@/utils/helper';
 import {
   registerWorkflowTrigger,
   cleanWorkflowTriggers,
 } from '@/utils/workflowTrigger';
-import { useUserStore } from './user';
+import { findTriggerBlock } from '@/utils/helper';
 
 export const useHostedWorkflowStore = defineStore('hosted-workflows', {
   storageMap: {
@@ -31,10 +30,10 @@ export const useHostedWorkflowStore = defineStore('hosted-workflows', {
     async insert(data, idKey = 'hostId') {
       if (Array.isArray(data)) {
         data.forEach((item) => {
-          this.workflows[item[idKey]] = item;
+          this.workflows[idKey] = item;
         });
       } else {
-        this.workflows[data[idKey]] = data;
+        this.workflows[idKey] = data;
       }
 
       await this.saveToStorage('workflows');
@@ -57,44 +56,6 @@ export const useHostedWorkflowStore = defineStore('hosted-workflows', {
 
       return this.workflows[id];
     },
-    async addHostedWorkflow(hostId) {
-      if (this.workflows[hostId]) throw new Error('exist');
-
-      const userStore = useUserStore();
-      if (!userStore.user && this.toArray.length >= 3)
-        throw new Error('rate-exceeded');
-
-      const isTheUserHost = userStore.getHostedWorkflows.some(
-        (host) => hostId === host.hostId
-      );
-      if (isTheUserHost) throw new Error('exist');
-
-      const response = await fetchApi('/workflows/hosted', {
-        method: 'POST',
-        body: JSON.stringify({ hostId }),
-      });
-      const result = await response.json();
-
-      if (!response.ok) {
-        const error = new Error(result.message);
-        error.data = result.data;
-
-        throw error;
-      }
-
-      if (result === null) throw new Error('not-found');
-
-      result.hostId = hostId;
-      result.createdAt = Date.now();
-
-      const triggerBlock = findTriggerBlock(result.drawflow);
-      await registerWorkflowTrigger(hostId, triggerBlock);
-
-      this.workflows[hostId] = result;
-      await this.saveToStorage('workflows');
-
-      return result;
-    },
     async fetchWorkflows(ids) {
       if (!ids || ids.length === 0) return null;
 

+ 17 - 3
src/utils/workflowData.js

@@ -16,15 +16,29 @@ const requiredPermissions = {
   trigger: {
     name: contextMenuPermission,
     hasPermission({ data }) {
-      if (data.type !== 'context-menu') return true;
+      const permissions = [];
 
-      return checkPermission([contextMenuPermission]);
+      if (data.triggers) {
+        data.triggers.forEach((trigger) => {
+          if (trigger.type !== 'context-menu') return;
+
+          permissions.push(contextMenuPermission);
+        });
+      } else if (data.type === 'context-menu') {
+        permissions.push(contextMenuPermission);
+      }
+
+      return checkPermission(permissions);
     },
   },
   clipboard: {
     name: 'clipboardRead',
     hasPermission() {
-      return checkPermission(['clipboardRead']);
+      const clipboardPermissions = ['clipboardRead'];
+      if (BROWSER_TYPE === 'firefox')
+        clipboardPermissions.push('clipboardWrite');
+
+      return checkPermission(clipboardPermissions);
     },
   },
   notification: {