Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | 159x 159x 159x 159x 164x 164x 123x 159x 145x 159x 159x 1x 1x 1x 242x 1x 159x | import { computed, watch } from 'vue'
import { useFlowsStore } from '@/stores/flows'
import { useAuthStore } from '@/stores/auth'
import { useRolesStore } from '@/stores/roles'
/**
* Provides permission checking for the current active flow.
* Mirrors the wildcard matching logic from the backend PermissionChecker.
* Automatically fetches roles for the current flow if not already loaded.
*/
export function usePermissions() {
const flowsStore = useFlowsStore()
const authStore = useAuthStore()
const rolesStore = useRolesStore()
// Ensure roles are loaded for the current flow so permission checks are accurate
watch(
() => authStore.currentFlow,
(flowId) => {
if (flowId && !rolesStore.roles.length && !rolesStore.loading) {
rolesStore.fetchRoles(flowId).catch(() => {
// Background fetch — silently ignore errors; permission checks will
// fall back to isOwner only until roles are eventually loaded.
})
}
},
{ immediate: true }
)
const currentMembership = computed(() =>
flowsStore.myFlows.find((f) => f.flowId === authStore.currentFlow)
)
const isOwner = computed(() => currentMembership.value?.isOwner ?? false)
const userPermissions = computed((): string[] => {
Iif (isOwner.value) return ['*:*']
const membership = currentMembership.value
Eif (!membership?.roleIds?.length) return []
const perms = new Set<string>()
for (const roleId of membership.roleIds) {
const role = rolesStore.roles.find((r) => r.roleId === roleId)
if (role?.permissions) {
role.permissions.forEach((p) => perms.add(p))
}
}
return Array.from(perms)
})
/**
* Checks whether a granted permission (which may contain wildcards) covers a required permission.
* Mirrors backend matchesPermission logic.
*/
function matchesPermission(granted: string, required: string): boolean {
if (!granted || !required) return false
if (granted === required) return true
const pattern = granted.replace(/[.+?^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*')
try {
return new RegExp(`^${pattern}$`).test(required)
} catch {
return false
}
}
/**
* Returns true if the current user has the required permission in the active flow.
* Flow owners always return true.
*/
function hasPermission(required: string): boolean {
if (isOwner.value) return true
return userPermissions.value.some((granted) => matchesPermission(granted, required))
}
return { hasPermission, isOwner, userPermissions }
}
|