@inventi/acl
TypeScript icon, indicating that this package has built-in type declarations

1.1.0 • Public • Published

@inventi/acl 🇩🇪

@inventi/acl

Example

See tests in source code for more examples!

Permission definition and plain usage:

import Permission, { Permission, PermissionUser, ResourceNameArgument } from '@inventi/acl'

const acl = new Permission()
acl.addRole('guest')
acl.addRole('registered', 'guest') // 'registered' dědí od 'guest'
acl.addRole('admin', 'registered')  // a od něj dědí 'admin'

acl.addResource('article')
acl.addResource('comment')
acl.addResource('poll')

// guest může prohlížet články, komentáře i ankety
acl.allow('guest', ['article', 'comment', 'poll'], 'view')

// administrátor nemůže editovat ankety, to by bylo nedemokratické
acl.deny('admin', 'poll', 'edit')

// volitelný callback = dynamická aserce
acl.allow('guest', 'article', 'poll', (role: string, resource: ResourceNameArgument, operation: string, extraData?: any) => {
  if (typeof resource !== 'string' && resource?.resourceName === 'article' && extraData?.userInfo?.id === 1) return true
  return false
})

expect(acl.isAllowed('guest', 'article', 'view')).toBe(true)
expect(acl.isAllowed('guest', { resourceName: 'article', type: 'baz' }, 'poll', { userInfo: { id: 1 } })).toBe(true)
expect(acl.isAllowed('registered', 'article', 'view')).toBe(true)
expect(acl.isAllowed('admin', 'article', 'edit')).toBe(true)


let user = new PermissionUser(acl)
user.setRole('guest')
expect(user.isAllowed('article', 'view')).toBe(true)
expect(user.isAllowed('article', 'edit')).toBe(false)
expect(user.isAllowed('poll', 'vote')).toBe(true)
expect(user.isAllowed('comment', 'add')).toBe(false)
expect(user.isAllowed({ resourceName: 'article', type: 'baz' }, 'poll', { userInfo: { id: 1 } })).toBe(true)
expect(user.isAllowed({ resourceName: 'bar', type: 'foo' }, 'add', { userInfo: { id: 2 } })).toBe(false)

user = new PermissionUser(acl)
user.setRole('registered')
expect(user.isAllowed('article', 'view')).toBe(true)

Usage in React:

  1. Define permissions
import { Permission } from '@packages/acl'

const acl = new Permission()
acl.addRole('guest')
acl.addRole('admin')

acl.addResource('article')

acl.allow('guest', ['article', 'comment'], 'view')
acl.allow('admin', acl.ALL, ['view', 'edit', 'add'])

export default acl
  1. Add a provider to the root of your app
import { Provider as AclProvider } from '@packages/acl'

<AclProvider permission={acl} role="guest">
   ...
</AclProvider>
  1. Query (hooks or Can component) :)
import { Can, usePermission } from '@packages/acl'

const MyComponent = () => {
  // the hooks way
  const permision = usePermission()
  console.log('Are you allowed to view a comment?', permision.isAllowed('comment', 'view'))
  return (
  {/* the component way */}
  <Can I="launch" a="atomMissile">
    <h1>You can launch a atom missile!</h1>
  </Can>
  <Can not I="launch" a="atomMissile">
    <h1>You can NOT launch a atom missile!</h1>
  </Can>
  )
}

Disclaimer

This package is not intended for dynamic permissions changes (but it can be done with little effort ;)).

If you make changes like permission.permission.allow(), permission.permission.deny(), and so on, after Context Provider is created, context wont catch this changes!

Readme

Keywords

none

Package Sidebar

Install

npm i @inventi/acl

Weekly Downloads

35

Version

1.1.0

License

MIT

Unpacked Size

73.5 kB

Total Files

27

Last publish

Collaborators

  • adambisek