Hooks
No hooks found in any category.
useRoleGuard
authInstallation
npx usehooks-cli@latest add use-role-guard
Description
A React hook for role-based access control that checks user permissions against required roles. Provides utilities for authorization, redirection, and session management.
Parameters
Name | Type | Default | Description |
---|---|---|---|
requiredRoles | string[] | - | Array of roles required to access the resource |
options? | UseRoleGuardOptions | - | Configuration options for the role guard |
Parameter Properties
options properties:
Name | Type | Description |
---|---|---|
user? | User | null | User object with id and roles array |
redirectTo? | string | URL to redirect to when unauthorized (default: '/unauthorized') |
onUnauthorized? | () => void | Callback function to execute when user is unauthorized |
sessionKey? | string | Session storage key for user data (default: 'user') |
Return Type
UseRoleGuardReturn
Property | Type | Description |
---|---|---|
hasAccess | boolean | Whether the user has access to the current resource |
hasAnyRole | (roles: string[]) => boolean | Function to check if user has any of the specified roles |
hasAllRoles | (roles: string[]) => boolean | Function to check if user has all of the specified roles |
isLoading | boolean | Whether the hook is currently loading user data |
user | User | null | Current user object with roles |
checkAccess | (requiredRoles: string[]) => boolean | Function to check access for specific roles |
redirect | () => void | Function to manually trigger redirect |
Examples
Role-based component protection
Protecting components based on user roles
1import { useRoleGuard } from '@usehooks.io/use-role-guard';
2
3function AdminPanel() {
4 const { hasAccess, isLoading, user, hasAnyRole } = useRoleGuard(
5 ['admin', 'moderator'],
6 {
7 redirectTo: '/login',
8 onUnauthorized: () => console.log('Access denied')
9 }
10 );
11
12 if (isLoading) {
13 return <div>Loading...</div>;
14 }
15
16 if (!hasAccess) {
17 return <div>Access denied</div>;
18 }
19
20 return (
21 <div>
22 <h1>Admin Panel</h1>
23 <p>Welcome, {user?.id}</p>
24 {hasAnyRole(['admin']) && (
25 <button>Admin Only Action</button>
26 )}
27 </div>
28 );
29}
Dependencies
react
Notes
- •Automatically redirects unauthorized users if redirectTo is provided
- •Loads user data from session storage if no user is provided
- •Uses hasAnyRole logic for access checking by default
- •Handles loading state while retrieving user data from session
Implementation
1'use client';
2
3import { useState, useEffect, useCallback } from "react";
4
5interface User {
6 id: string;
7 roles: string[];
8 [key: string]: any;
9}
10
11interface UseRoleGuardOptions {
12 user?: User | null;
13 redirectTo?: string;
14 fallbackComponent?: React.ComponentType;
15 onUnauthorized?: () => void;
16 sessionKey?: string;
17}
18
19interface UseRoleGuardReturn {
20 hasAccess: boolean;
21 hasAnyRole: (roles: string[]) => boolean;
22 hasAllRoles: (roles: string[]) => boolean;
23 isLoading: boolean;
24 user: User | null;
25 checkAccess: (requiredRoles: string[]) => boolean;
26 redirect: () => void;
27}
28
29export function useRoleGuard(
30 requiredRoles: string[],
31 options: UseRoleGuardOptions = {}
32): UseRoleGuardReturn {
33 const {
34 user: providedUser,
35 redirectTo = "/unauthorized",
36 onUnauthorized,
37 sessionKey = "user",
38 } = options;
39
40 const [user, setUser] = useState<User | null>(providedUser || null);
41 const [isLoading, setIsLoading] = useState(!providedUser);
42
43 // Get user from session storage if not provided
44 useEffect(() => {
45 if (!providedUser && typeof window !== "undefined") {
46 try {
47 const sessionUser = sessionStorage.getItem(sessionKey);
48 if (sessionUser) {
49 const parsedUser = JSON.parse(sessionUser);
50 setUser(parsedUser);
51 }
52 } catch (error) {
53 console.error("Error parsing user from session:", error);
54 } finally {
55 setIsLoading(false);
56 }
57 }
58 }, [providedUser, sessionKey]);
59
60 // Check if user has any of the required roles
61 const hasAnyRole = useCallback(
62 (roles: string[]): boolean => {
63 if (!user || !user.roles) return false;
64 return roles.some((role) => user.roles.includes(role));
65 },
66 [user]
67 );
68
69 // Check if user has all of the required roles
70 const hasAllRoles = useCallback(
71 (roles: string[]): boolean => {
72 if (!user || !user.roles) return false;
73 return roles.every((role) => user.roles.includes(role));
74 },
75 [user]
76 );
77
78 // Check access based on required roles
79 const checkAccess = useCallback(
80 (roles: string[]): boolean => {
81 return hasAnyRole(roles);
82 },
83 [hasAnyRole]
84 );
85
86 // Calculate if user has access to current resource
87 const hasAccess = checkAccess(requiredRoles);
88
89 // Redirect function
90 const redirect = useCallback(() => {
91 if (typeof window !== "undefined" && redirectTo) {
92 window.location.href = redirectTo;
93 }
94 }, [redirectTo]);
95
96 // Handle unauthorized access
97 useEffect(() => {
98 if (!isLoading && !hasAccess) {
99 if (onUnauthorized) {
100 onUnauthorized();
101 } else if (redirectTo && typeof window !== "undefined") {
102 redirect();
103 }
104 }
105 }, [hasAccess, isLoading, onUnauthorized, redirect, redirectTo]);
106
107 return {
108 hasAccess,
109 hasAnyRole,
110 hasAllRoles,
111 isLoading,
112 user,
113 checkAccess,
114 redirect,
115 };
116}
117