Skip to main content

Authentication Hooks

Hooks for role-based access control, permission management, login/logout UI, and security settings.

useActiveRoles

Fetches all active roles from the admin API. Returns role data with loading and error states.

useActiveRoles(): {
roles: RoleData[];
loading: boolean;
error: string | null;
getActiveRoles: (signal?: AbortSignal) => Promise<RoleData[]>;
clearError: () => void;
}

Return Values

PropertyTypeDescription
rolesRoleData[]Array of active role objects
loadingbooleanWhether roles are being fetched
errorstring | nullError message if the fetch failed
getActiveRoles(signal?) => Promise<RoleData[]>Trigger role fetch (supports AbortSignal)
clearError() => voidClear the current error state
import { useActiveRoles } from '@/hooks/use-active-roles';

function RoleSelector() {
const { roles, loading, getActiveRoles } = useActiveRoles();

useEffect(() => {
const controller = new AbortController();
getActiveRoles(controller.signal);
return () => controller.abort();
}, [getActiveRoles]);

if (loading) return <Spinner />;

return (
<select>
{roles.map((role) => (
<option key={role.id} value={role.id}>{role.name}</option>
))}
</select>
);
}

useIsDevOrAdmin

A simple boolean hook that returns true if the application is running in development mode or the current user is an admin. Useful for showing debug information, dev tools, or detailed error messages.

useIsDevOrAdmin(): boolean

Returns: boolean -- true when NODE_ENV === 'development' OR the current user has isAdmin === true.

import { useIsDevOrAdmin } from '@/hooks/use-is-dev-or-admin';

function ErrorDisplay({ error }) {
const showDetails = useIsDevOrAdmin();

return (
<div>
<p>Something went wrong</p>
{showDetails && <pre>{error.stack}</pre>}
</div>
);
}

useRolePermissions

Manages permissions for a specific role using React Query. Provides fetching, updating, and cache invalidation for role-permission associations.

useRolePermissions(roleId: string, enabled?: boolean): UseRolePermissionsReturn

Parameters

ParameterTypeDefaultDescription
roleIdstring--The role ID to fetch permissions for
enabledbooleantrueWhether to enable the query

Return Values

PropertyTypeDescription
permissionsPermission[]Array of permissions assigned to the role
roleobject | undefinedRole metadata (id, name, description)
isLoadingbooleanWhether permissions are being fetched
isUpdatingbooleanWhether a permission update is in progress
errorError | nullFetch error
updatePermissions(permissions: Permission[]) => Promise<boolean>Update role permissions; returns success status
refetch() => voidRe-fetch permissions from server
invalidateCache() => voidInvalidate the permissions cache

Query Configuration

SettingValue
Stale time5 minutes
GC time10 minutes
RetryUp to 3 times; skips 401/403 errors
Retry delayExponential backoff, max 30s
import { useRolePermissions } from '@/hooks/use-role-permissions';

function PermissionEditor({ roleId }) {
const { permissions, isLoading, updatePermissions, isUpdating } =
useRolePermissions(roleId);

const handleToggle = async (perm) => {
const updated = permissions.includes(perm)
? permissions.filter((p) => p !== perm)
: [...permissions, perm];
await updatePermissions(updated);
};

return (
<div>
{permissions.map((perm) => (
<Checkbox key={perm} checked onChange={() => handleToggle(perm)} />
))}
</div>
);
}

useLoginModal

A Zustand-based global store for controlling the login modal. Can be accessed from any component without prop drilling.

useLoginModal(): LoginModalStore

Store Shape

PropertyTypeDescription
isOpenbooleanWhether the login modal is visible
messagestring | undefinedOptional message displayed in the modal
callbackUrlstring | undefinedURL to redirect to after login
onOpen(message?, callbackUrl?) => voidOpen the modal with optional message and redirect
onClose() => voidClose the modal and clear message/callback
import { useLoginModal } from '@/hooks/use-login-modal';

function ProtectedAction() {
const { onOpen } = useLoginModal();

const handleClick = () => {
if (!isAuthenticated) {
onOpen('Please sign in to continue', '/dashboard');
return;
}
// proceed with action
};

return <button onClick={handleClick}>Submit</button>;
}

useLogoutOverlay

Creates an animated full-screen overlay during the sign-out process. Handles dark mode adaptation, focus management, and prevents concurrent logout flows.

useLogoutOverlay(): {
handleLogout: (texts?: { title?: string; description?: string }) => Promise<void>;
}

Parameters

ParameterTypeDescription
texts.titlestringCustom overlay title (default: "Signing Out")
texts.descriptionstringCustom overlay description

Behavior

  1. Creates a full-screen overlay with spinner, title, and description
  2. Calls signOut({ redirect: false }) from NextAuth
  3. Redirects to "/" on success
  4. Cleans up overlay and restores focus on completion or error
  5. Adapts colors when the theme changes mid-logout via MutationObserver
import { useLogoutOverlay } from '@/hooks/use-logout-overlay';

function LogoutButton() {
const { handleLogout } = useLogoutOverlay();

return (
<button onClick={() => handleLogout()}>
Sign Out
</button>
);
}

useSecuritySettings

Fetches the user's security settings (2FA status, sessions, password info) via React Query.

useSecuritySettings(): UseQueryResult<SecuritySettings>

SecuritySettings Shape

FieldTypeDescription
twoFactorEnabledbooleanWhether 2FA is active
lastPasswordChangestring | nullISO timestamp of last password change
activeSessionsCountnumberNumber of active sessions
loginAttemptsCountnumberRecent login attempts count
accountLockedbooleanWhether the account is locked
passwordExpiresAtstring | nullPassword expiration timestamp

useLoginActivity(page?, limit?) -- Fetches paginated login activity records.

useSecurityCache() -- Provides cache management functions:

FunctionDescription
invalidateSecuritySettings()Refresh security settings
invalidateLoginActivity()Refresh login activity
invalidateAllSecurity()Refresh all security data
prefetchSecuritySettings()Prefetch settings into cache
import { useSecuritySettings, useLoginActivity } from '@/hooks/use-security-settings';

function SecurityDashboard() {
const { data: settings, isLoading } = useSecuritySettings();
const { data: activity } = useLoginActivity(1, 10);

if (isLoading) return <Spinner />;

return (
<div>
<p>2FA: {settings?.twoFactorEnabled ? 'Enabled' : 'Disabled'}</p>
<p>Active sessions: {settings?.activeSessionsCount}</p>
</div>
);
}

Summary Table

HookPurposeSource File
useActiveRolesFetch active roles from admin APIuse-active-roles.ts
useIsDevOrAdminCheck dev mode or admin statususe-is-dev-or-admin.ts
useRolePermissionsCRUD role permissions with React Queryuse-role-permissions.ts
useLoginModalGlobal login modal state (Zustand)use-login-modal.ts
useLogoutOverlayAnimated logout overlay with sign-outuse-logout-overlay.ts
useSecuritySettingsFetch security settingsuse-security-settings.ts
useLoginActivityFetch paginated login activityuse-security-settings.ts
useSecurityCacheSecurity data cache managementuse-security-settings.ts