npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@casl/ability

v6.7.2

Published

CASL is an isomorphic authorization JavaScript library which restricts what resources a given user is allowed to access

Downloads

2,700,409

Readme

CASL Ability @casl/ability NPM version CASL Documentation CASL Join the chat

This package is the core of CASL. It includes logic responsible for checking and defining permissions.

Installation

npm install @casl/ability
# or
pnpm install @casl/ability
# or
yarn add @casl/ability

Documentation

This README file contains only basic information about the package. If you need an in depth introduction, please visit CASL's documentation.

Getting Started

Note: the best way to get started is to read the Guide in the official documentation. In this README file, you will find just basic information.

Note: all the examples below are written in ES6 using ES modules but CASL also has a sophisticated support for TypeScript, read CASL TypeScript support for details.

1. Define Abilities

Lets define Ability for a blog website where visitors:

  • can read blog posts
  • can manage (i.e., do anything) own posts
  • cannot delete a post if it was created more than a day ago
import { AbilityBuilder, createMongoAbility } from '@casl/ability';
import { User } from '../models'; // application specific interfaces

/**
 * @param user contains details about logged in user: its id, name, email, etc
 */
function defineAbilitiesFor(user) {
  const { can, cannot, build } = new AbilityBuilder(createMongoAbility);

  // can read blog posts
  can('read', 'BlogPost');
  // can manage (i.e., do anything) own posts
  can('manage', 'BlogPost', { author: user.id });
  // cannot delete a post if it was created more than a day ago
  cannot('delete', 'BlogPost', {
    createdAt: { $lt: Date.now() - 24 * 60 * 60 * 1000 }
  });

  return build();
});

Do you see how easily business requirements were translated into CASL's rules?

And yes, Ability class allow you to use some MongoDB operators to define conditions. Don't worry if you don't know MongoDB, it's not required and explained in details in Defining Abilities

2. Check Abilities

Later on you can check abilities by using can and cannot methods of Ability instance.

import { BlogPost, ForbiddenError } from '../models';

const user = getLoggedInUser(); // app specific function
const ability = defineAbilitiesFor(user)

// true if ability allows to read at least one Post
ability.can('read', 'BlogPost');

// true if there is no ability to read this particular blog post
const post = new BlogPost({ title: 'What is CASL?' });
ability.cannot('read', post);

// you can even throw an error if there is a missed ability
ForbiddenError.from(ability).throwUnlessCan('read', post);

Of course, you are not restricted to use only class instances in order to check permissions on objects. See Introduction for the detailed explanation.

3. Database integration

CASL has a complementary package [@casl/mongoose] which provides easy integration with MongoDB and [mongoose].

import { accessibleRecordsPlugin } from '@casl/mongoose';
import mongoose from 'mongoose';

mongoose.plugin(accessibleRecordsPlugin);

const user = getUserLoggedInUser(); // app specific function

const ability = defineAbilitiesFor(user);
const BlogPost = mongoose.model('BlogPost', mongoose.Schema({
  title: String,
  author: mongoose.Types.ObjectId,
  content: String,
  createdAt: Date,
  hidden: { type: Boolean, default: false }
}))

// returns mongoose Query, so you can chain it with other conditions
const posts = await Post.accessibleBy(ability).where({ hidden: false });

// you can also call it on existing query to enforce permissions
const hiddenPosts = await Post.find({ hidden: true }).accessibleBy(ability);

// you can even pass the action as a 2nd parameter. By default action is "read"
const updatablePosts = await Post.accessibleBy(ability, 'update');

See Database integration for details.

4. Advanced usage

CASL is incrementally adoptable, that means you can start your project with simple claim (or action) based authorization and evolve it later, when your app functionality evolves.

CASL is composable, that means you can implement alternative conditions matching (e.g., based on joi, ajv or pure functions) and field matching (e.g., to support alternative syntax in fields like addresses.*.street or addresses[0].street) logic.

See Advanced usage for details.

5. Performance and computational complexity

CASL checks are quite fast, thanks to underlying rule index structure. The estimated complexity of different operations can be found below:

| Operation | Complexity | Notes | |----------------------------------|------------|---------------| | Ability creation time | O(n) | n - amount of rules | | Check by action and subject type (e.g., ability.can('read', 'Todo')) | O(1) | | | Check by action and subject object (e.g., ability.can('read', todo)) | O(m + k) + O(p) | m - amount of rules for the same pair of action and subject; k - amount of operators in conditions; O(p) - complexity of used operators (e.g., $in implementation is more complex than $lt) |

Want to help?

Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on guidelines for contributing

License

MIT License