An open API service indexing awesome lists of open source software.

https://github.com/falcondev-oss/caps

Simple, fully type-safe library to handle permissions/access control by defining capabilities with generators.
https://github.com/falcondev-oss/caps

access-control capabilities generator permissions typescript

Last synced: 7 months ago
JSON representation

Simple, fully type-safe library to handle permissions/access control by defining capabilities with generators.

Awesome Lists containing this project

README

          

# @falcondev-oss/caps

NPM version

Simple, **fully type-safe** library to handle permissions/access control by defining capabilities with generators.

## Installation

```bash
npm add @falcondev-oss/caps
```

## Example

```typescript
type User = { userId: string; role: 'user' | 'moderator' | 'admin'; isBanned: boolean }
type Post = { author: User }

const useActor = createActor().build((cap) => ({
social: {
posts: cap.subject().define(
function* ({ actor, subject, args }) {
// banned users can't do anything
if (actor.isBanned || subject.author.isBanned) return []

// everyone can read posts
yield ['read']

// users can update & delete posts themselves
if (actor.userId === subject.author.userId) yield ['update', 'delete']

// admins can delete any post & ban users
if (actor.role === 'admin') {
yield ['delete', 'ban']
}

// moderators can only delete posts from users
if (actor.role === 'moderator' && subject.author.role === 'user') {
yield ['delete']

// moderators can also ban users temporarily
if (args.ban?.temporary) yield ['ban']
}

return []
},
{
ban: arg<{ temporary: boolean }>,
},
),
},
}))

const Users = {
user1: { userId: '1', role: 'user', isBanned: false },
user2: { userId: '2', role: 'user', isBanned: false },
moderator: { userId: '3', role: 'moderator', isBanned: false },
admin: { userId: '4', role: 'admin', isBanned: false },
} as const

const user = useActor(Users.user1)

user.social.posts.subject({ author: Users.user2 }).can('read').check() // => true
user.social.posts.subject({ author: Users.user1 }).can('update').check() // => true
user.social.posts.subject({ author: Users.user2 }).can('delete').check() // => false

const moderator = useActor(Users.moderator)

moderator.social.posts.subject({ author: Users.user1 }).can('delete').check() // => true
moderator.social.posts.subject({ author: Users.user1 }).can('update').check() // => false
moderator.social.posts.subject({ author: Users.user1 }).can('ban', { temporary: false }).check() // => false
moderator.social.posts.subject({ author: Users.user1 }).can('ban', { temporary: true }).check() // => true

const admin = useActor(Users.admin)

admin.social.posts.subject({ author: Users.user1 }).can('ban', { temporary: false }).check() // => true
```