Skip to content

fix: knowledge workflow permission - #7758

Merged
peslyn merged 1 commit into
v3from
pr@v3@fix_knowledge_workflow_permission
Nov 9, 2026
Merged

peslyn merged 1 commit into
v3from
pr@v3@fix_knowledge_workflow_permission

Conversation

@shaohuzhang1

Copy link
Copy Markdown
Contributor

fix: knowledge workflow permission

@peslyn
peslyn merged commit 092b13f into v3 Nov 9, 2026
3 of 4 checks passed
@peslyn
peslyn deleted the pr@v3@fix_knowledge_workflow_permission branch November 9, 2026 08:13
<MkDropdownItem v-if="knowledgeWorkflowPermission('workflowEdit')" @click.stop>
<template #icon><MkIcon name="icon_save_outlined" /></template>
<span>自动保存</span>
<el-switch v-model="autoSaveEnabled" class="ml-auto" size="small" @click.stop @change="handleAutoSaveChange" />

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the shown diff, the change is generally reasonable, but there are several important issues to address before merging.

Critical issues

1. UI hiding is not authorization

Using v-if="knowledgeWorkflowPermission(...)" only hides controls. The handlers are still callable via keyboard shortcuts, programmatic calls, or other UI paths:

  • handleSave
  • handleOpenPublish
  • handleExportWorkflow
  • handleAutoSaveChange

Add permission checks inside the handlers as well. Server-side authorization must also enforce these rules.

function handleSave() {
  if (!knowledgeWorkflowPermission('workflowEdit')) return
  // ...
}

function handleOpenPublish() {
  if (!knowledgeWorkflowPermission('publish')) return
  // ...
}

function handleExportWorkflow() {
  if (!knowledgeWorkflowPermission('workflowExport')) return
  // ...
}

2. Auto-save may continue running after permission is lost

You hide the auto-save switch, but if autoSaveEnabled was already true, the auto-save logic may continue saving. This is especially risky for shared/read-only resources.

You should stop auto-save when edit permission becomes unavailable:

watch(
  () => knowledgeWorkflowPermission('workflowEdit'),
  (canEdit) => {
    if (!canEdit) {
      autoSaveEnabled.value = false
      stopAutoSave()
    }
  },
  { immediate: true }
)

Also guard handleAutoSaveChange and the auto-save execution path.

3. Verify knowledgeId is not a ref/computed

The helper uses:

perm.knowledge.workspace[method](knowledgeId)

If knowledgeId is a ref or computed, this passes a Ref object instead of the actual ID. In that case, use:

perm.knowledge.workspace[method](knowledgeId.value)

The same applies if isSystemResource, isSystemSharedResource, or isWorkspaceSharedResource are computed values rather than functions.

Potential behavioral issue

4. Workspace-shared resources always return false

This line:

if (isWorkspaceSharedResource()) return false // 工作空间侧共享知识库只读

blocks all three permissions, including workflowExport. If export is intended to be allowed for read-only shared resources, this is too restrictive. Confirm whether workflowExport should really be blocked here.

Minor improvements

5. Avoid repeated permission calls in the template

knowledgeWorkflowPermission(...) is called multiple times per render. Prefer computed properties:

const canEditWorkflow = computed(() => knowledgeWorkflowPermission('workflowEdit'))
const canPublish = computed(() => knowledgeWorkflowPermission('publish'))
const canExportWorkflow = computed(() => knowledgeWorkflowPermission('workflowExport'))

Then use:

<MkTooltip v-if="canEditWorkflow" ...>

This improves readability, avoids repeated permission logic, and makes watchers/guards easier.

6. Prefer extensionless import

This:

import perm from '@/permission/index.ts'

may work in Vite, but extensionless imports are more conventional and avoid TypeScript/bundler configuration issues:

import perm from '@/permission'

7. Consider a guard for missing permission methods

If perm is not fully typed or can change between versions, a missing method will throw:

perm.knowledge.workspace[method](knowledgeId)

You could defensively check:

const check = perm.knowledge.workspace[method]
return typeof check === 'function' ? Boolean(check(knowledgeId)) : false

Only do this if perm is not strongly typed.

Suggested refactor

import perm from '@/permission'

type KnowledgeWorkflowPermissionMethod =
  | 'workflowEdit'
  | 'publish'
  | 'workflowExport'

function knowledgeWorkflowPermission(
  method: KnowledgeWorkflowPermissionMethod
): boolean {
  if (isSystemResource()) {
    return Boolean(perm.knowledge.system[method]())
  }

  if (isSystemSharedResource()) {
    return Boolean(perm.knowledge.share[method]())
  }

  if (isWorkspaceSharedResource()) {
    return false
  }

  // Use knowledgeId.value if knowledgeId is a ref/computed
  return Boolean(perm.knowledge.workspace[method](knowledgeId))
}

const canEditWorkflow = computed(() => knowledgeWorkflowPermission('workflowEdit'))
const canPublish = computed(() => knowledgeWorkflowPermission('publish'))
const canExportWorkflow = computed(() => knowledgeWorkflowPermission('workflowExport'))

Overall: the diff is syntactically plausible, but the main missing piece is enforcing the same permission checks in the action handlers and auto-save lifecycle, not only in the template.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants