68 lines
1.4 KiB
TypeScript
68 lines
1.4 KiB
TypeScript
import { usePage } from '@inertiajs/react';
|
|
|
|
type RoleOrPermission = { name: string } | string;
|
|
|
|
type User = {
|
|
id: number;
|
|
username?: string;
|
|
roles?: RoleOrPermission[];
|
|
permissions?: RoleOrPermission[];
|
|
[key: string]: unknown;
|
|
};
|
|
|
|
type PageProps = {
|
|
auth: {
|
|
user?: User;
|
|
};
|
|
};
|
|
|
|
function extractNames(items?: RoleOrPermission[]): string[] {
|
|
if (!items) {
|
|
return [];
|
|
}
|
|
|
|
return items.map((item) => (typeof item === 'string' ? item : item.name));
|
|
}
|
|
|
|
export function useCan() {
|
|
const { auth } = usePage().props as PageProps;
|
|
const user = auth.user;
|
|
|
|
const roleNames = extractNames(user?.roles);
|
|
const permissionNames = extractNames(user?.permissions);
|
|
|
|
function can(permission: string): boolean {
|
|
if (!user) {
|
|
return false;
|
|
}
|
|
|
|
return permissionNames.includes(permission);
|
|
}
|
|
|
|
function canAny(...permissions: string[]): boolean {
|
|
if (!user) {
|
|
return false;
|
|
}
|
|
|
|
return permissions.some((p) => permissionNames.includes(p));
|
|
}
|
|
|
|
function hasRole(role: string): boolean {
|
|
if (!user) {
|
|
return false;
|
|
}
|
|
|
|
return roleNames.includes(role);
|
|
}
|
|
|
|
function hasAnyRole(roles: string[]): boolean {
|
|
if (!user) {
|
|
return false;
|
|
}
|
|
|
|
return roles.some((role) => roleNames.includes(role));
|
|
}
|
|
|
|
return { can, canAny, hasRole, hasAnyRole };
|
|
}
|