Skip to content

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

License

Notifications You must be signed in to change notification settings

falcondev-oss/caps

Repository files navigation

@falcondev-oss/caps

NPM version

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

Installation

npm add @falcondev-oss/caps

Example

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

const useActor = createActor<User>().build((cap) => ({
  social: {
    posts: cap.subject<Post>().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

About

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

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •