
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
react-permissions-dynamic
Advanced tools
Lightweight package that resolves permissions in your app
Wrap your App in PermissionsProvider
const Main = () => {
return <PermissionsProvider>{/* your app code */}</PermissionsProvider>;
};
Provide initialPermissions?: CheckResult and/or onCheckPermissions?: OnCheckPermissionsType
If you have all permissions somewhere, and you don't need dynamic checks - use only initialPermissions
If permissions are controled by you - use permissions prop
export type PermissionsProps<T extends string = string> = {
children: React.ReactNode;
permissions?: CheckResult<T>;
initialPermissions?: CheckResult<T>;
onCheckPermissions?: OnCheckPermissionsType<T>;
isAllowed?: (action: T, allowed: T[]) => boolean;
};
type CheckResult = {
action: string,
allowed?: boolean,
}[];
type OnCheckPermissionsType = (
actions: string[]
) => Promise<CheckResult> | CheckResult;
const exampleInitialPermissions = [
{ action: 'can_view_transactions', allowed: true },
{ action: 'can_edit_people', allowed: false },
];
const exampleCheckPermissions = (actions: string[]) => {
return [
{ action: 'this_is_allowed', allowed: true },
{ action: 'denied_this_is', allowed: false },
{ action: 'undefined_is_allowed' },
];
};
return (
<PermissionsProvider
onCheckPermissions={exampleCheckPermissions}
initialPermissions={exampleInitialPermissions}
isAllowed={action => isUserSuperAdmin(action)}
>
// children
</PermissionsProvider>
);
If you have "allow all" check - add it via isAllowed function
const isUserSuperAdmin = _action => true;
return (
<PermissionsProvider isAllowed={action => isUserSuperAdmin(action)}>
// children
</PermissionsProvider>
);
It's recommended to specify union-type for your components/utilities You can do it like this
import {
PermissionCheck as LibPermissionCheck,
PermissionsProvider as LibPermissionsProvider,
} from 'react-permissions-dynamic';
import type {
PermissionCheckProps as LibPermissionCheckProps,
PermissionsProviderProps as LibPermissionsProviderProps,
} from 'react-permissions-dynamic';
type MyPermission = 'can_view_files' | 'can_edit_files';
type PermissionCheckProps = LibPermissionCheckProps<MyPermission>;
type PermissionsProviderProps = LibPermissionsProviderProps<MyPermission>;
const PermissionCheck = LibPermissionCheck as React.FC<PermissionCheckProps>;
const PermissionsProvider =
LibPermissionsProvider as React.FC<PermissionsProviderProps>;
export { PermissionCheck, PermissionsProvider };
In the code itself use PermissionCheck component
// Base usage:
return (
<PermissionCheck action="can_view_files">
<FileViewer />
</PermissionCheck>
);
// Two or more permissions at the same time:
return (
<PermissionCheck action={['can_view_files', 'is_system_admin']}>
<SystemFileViewer />
</PermissionCheck>
);
// Provide Fallback for denied access:
return (
<PermissionCheck fallback="It's not for you, sorry" action="can_view_files">
<SystemFileViewer />
</PermissionCheck>
);
// Provide Loading if checks are dynamic:
return (
<PermissionCheck loading={<Spin />} action="can_view_files">
<SystemFileViewer />
</PermissionCheck>
);
// Provide onDeny if you want to do something on permission deny
return (
<PermissionCheck
action="can_view_files"
onDeny={action => {
logger.info(`Action [${action}] got denied`);
redirectUser('/');
}}
>
<SystemFileViewer />
</PermissionCheck>
);
// Provide custom logic for permissions
return (
<PermissionCheck
action={['can_view_files', 'can_view_system_files', 'has_full_access']}
isAllowed={(allowed = [], denied = []) => {
if (
allowed.includes('can_view_files') &&
allowed.includes('can_view_system_files')
) {
return true;
}
return !denied.includes('has_full_access');
}}
>
<FileViewer />
</PermissionCheck>
);
This component allows you to hide content based on permissions
type PermissionCheckProps = {
// this action/actions will be checked upon
// if it's allowed - we will show content
action: string | string[],
// content that must be shown if action is allowed
children: React.ReactNode,
// content that must be shown if action is not allowed
// default = null
fallback?: React.ReactNode,
// content that must be shown while we check if action is allowed
// default = null
loading?: React.ReactNode,
// event when action is denied
// fire alerts, write logs or redirects - do anything
onDenied?: (action: string) => void,
// if you need to implement custom check
// by default we need to have all actions allowed
isAllowed?: (allowedActions: string[], deniedActions: string[]) => boolean,
};
return <PermissionCheck>Secure Content</PermissionCheck>;
type ActionStatusType<T extends string> = {
// return action just in case you need it
action: T;
// if action is checked and allowed - returns true
allowed: boolean;
// if action is checked - returns true. if check is in progress - returns false
checked: boolean;
};
type UseCheckPermissionType = <T extends string>(
action: T
) => ActionStatusType<T>;
// Example:
const Component = () => {
const { allowed, checked } = useCheckPermission('can_view_files');
return allowed ? <FileViewer /> : null;
};
type UseCheckPermissionsType = <T extends string>(
actions: T[],
onCheck?: (status: ActionStatusType<T>) => void
) => ActionStatusType<T>[];
// Same as useCheckPermission, but you get array of results
// Also has onCheck callback, for single permission check
// Example:
const Component = () => {
const handleOnCheck = status => {
// actions here are always "checked", so no need to have `status.checked === true` condition
if (status.action === 'is_admin' && !status.allowed) {
return redirect('/404');
}
};
const results = useCheckPermissions(
['can_upload_files', 'is_admin'],
handleOnCheck
);
return results.some(s => s.action === 'can_upload_files' && s.allowed) ? (
<FileUploader />
) : null;
};
const allowed: string[] = useAllowed(['one', 'two', 'three']);
FAQs
This is a package with react-permissions
We found that react-permissions-dynamic demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.