mirror of https://github.com/nocodb/nocodb
Braks
2 years ago
committed by
GitHub
23 changed files with 168 additions and 191 deletions
@ -1,9 +0,0 @@ |
|||||||
// todo: implement useAttachment
|
|
||||||
export function useAttachment() { |
|
||||||
const localFilesState = reactive([]) |
|
||||||
const attachments = ref([]) |
|
||||||
|
|
||||||
const uploadFile = () => {} |
|
||||||
|
|
||||||
return { uploadFile, localFilesState, attachments } |
|
||||||
} |
|
@ -0,0 +1,65 @@ |
|||||||
|
import { isString } from '@vueuse/core' |
||||||
|
import { computed, createSharedComposable, ref, useApi, useGlobal } from '#imports' |
||||||
|
import type { ProjectRole, Role, Roles } from '~/lib' |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides the roles a user currently has |
||||||
|
* |
||||||
|
* * `userRoles` - the roles a user has outside of projects |
||||||
|
* * `projectRoles` - the roles a user has in the current project (if one was loaded) |
||||||
|
* * `allRoles` - all roles a user has (userRoles + projectRoles) |
||||||
|
* * `hasRole` - a function to check if a user has a specific role |
||||||
|
* * `loadProjectRoles` - a function to load the project roles for a specific project (by id) |
||||||
|
*/ |
||||||
|
export const useRoles = createSharedComposable(() => { |
||||||
|
const { user } = useGlobal() |
||||||
|
|
||||||
|
const { api } = useApi() |
||||||
|
|
||||||
|
const projectRoles = ref<Roles<ProjectRole>>({}) |
||||||
|
|
||||||
|
const userRoles = computed<Roles<Role>>(() => { |
||||||
|
let roles = user.value?.roles ?? {} |
||||||
|
|
||||||
|
// if string populate key-value paired object
|
||||||
|
if (isString(roles)) { |
||||||
|
roles = roles.split(',').reduce<Roles>((acc, role) => { |
||||||
|
acc[role] = true |
||||||
|
return acc |
||||||
|
}, {}) |
||||||
|
} |
||||||
|
|
||||||
|
return roles |
||||||
|
}) |
||||||
|
|
||||||
|
const allRoles = computed<Roles>(() => ({ |
||||||
|
...userRoles.value, |
||||||
|
...projectRoles.value, |
||||||
|
})) |
||||||
|
|
||||||
|
async function loadProjectRoles(projectId: string, isSharedBase?: boolean, sharedBaseId?: string) { |
||||||
|
projectRoles.value = {} |
||||||
|
|
||||||
|
if (isSharedBase) { |
||||||
|
const user = await api.auth.me( |
||||||
|
{}, |
||||||
|
{ |
||||||
|
headers: { |
||||||
|
'xc-shared-base-id': sharedBaseId, |
||||||
|
}, |
||||||
|
}, |
||||||
|
) |
||||||
|
|
||||||
|
projectRoles.value = user.roles |
||||||
|
} else if (projectId) { |
||||||
|
const user = await api.auth.me({ project_id: projectId }) |
||||||
|
projectRoles.value = user.roles |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function hasRole(role: Role | ProjectRole | string) { |
||||||
|
return allRoles.value[role] |
||||||
|
} |
||||||
|
|
||||||
|
return { allRoles, userRoles, projectRoles, loadProjectRoles, hasRole } |
||||||
|
}) |
@ -1,46 +1,34 @@ |
|||||||
import { isString } from '@vueuse/core' |
import { isString } from '@vueuse/core' |
||||||
import type { Permission } from './rolePermissions' |
import type { Permission } from './rolePermissions' |
||||||
import rolePermissions from './rolePermissions' |
import rolePermissions from './rolePermissions' |
||||||
import { USER_PROJECT_ROLES, computed, useGlobal, useState } from '#imports' |
import { createSharedComposable, useGlobal, useRoles } from '#imports' |
||||||
import type { Role, Roles } from '~/lib' |
import type { ProjectRole, Role } from '~/lib' |
||||||
|
|
||||||
export function useUIPermission() { |
const hasPermission = (role: Role | ProjectRole, hasRole: boolean, permission: Permission | string) => { |
||||||
const { user, previewAs } = useGlobal() |
const rolePermission = rolePermissions[role] |
||||||
|
|
||||||
const projectRoles = useState<Record<string, boolean>>(USER_PROJECT_ROLES, () => ({})) |
if (!hasRole || !rolePermission) return false |
||||||
|
|
||||||
const baseRoles = computed(() => { |
if (isString(rolePermission) && rolePermission === '*') return true |
||||||
let userRoles = isString(user.value?.roles) ? user.value?.roles : ({ ...(user.value?.roles || {}) } as Roles) |
|
||||||
|
|
||||||
// if string populate key-value paired object
|
return rolePermission[permission as keyof typeof rolePermission] |
||||||
if (typeof userRoles === 'string') { |
} |
||||||
userRoles = userRoles.split(',').reduce<Record<string, boolean>>((acc, role) => { |
|
||||||
acc[role] = true |
|
||||||
return acc |
|
||||||
}, {}) |
|
||||||
} |
|
||||||
|
|
||||||
// merge user role and project specific user roles
|
export const useUIPermission = createSharedComposable(() => { |
||||||
return { |
const { previewAs } = useGlobal() |
||||||
...userRoles, |
const { allRoles } = useRoles() |
||||||
...projectRoles.value, |
|
||||||
} |
|
||||||
}) |
|
||||||
|
|
||||||
const isUIAllowed = (permission: Permission | string, skipPreviewAs = false) => { |
const isUIAllowed = (permission: Permission | string, skipPreviewAs = false) => { |
||||||
let roles = baseRoles.value as Record<string, any> |
|
||||||
|
|
||||||
if (previewAs.value && !skipPreviewAs) { |
if (previewAs.value && !skipPreviewAs) { |
||||||
roles = { |
const hasPreviewPermission = hasPermission(previewAs.value, true, permission) |
||||||
[previewAs.value as Role]: true, |
|
||||||
} |
if (hasPreviewPermission) return true |
||||||
} |
} |
||||||
|
|
||||||
return Object.entries<boolean>(roles).some(([role, hasRole]) => { |
return Object.entries(allRoles.value).some(([role, hasRole]) => |
||||||
const rolePermission = rolePermissions[role as keyof typeof rolePermissions] as '*' | Record<Permission, true> |
hasPermission(role as Role | ProjectRole, hasRole, permission), |
||||||
return hasRole && (rolePermission === '*' || rolePermission?.[permission as Permission]) |
) |
||||||
}) |
|
||||||
} |
} |
||||||
|
|
||||||
return { isUIAllowed } |
return { isUIAllowed } |
||||||
} |
}) |
||||||
|
Loading…
Reference in new issue