### Quick Start with AbilityProvider, Can, and useAbility
Source: https://github.com/stalniy/casl/blob/master/packages/casl-react/README.md
Demonstrates basic setup using AbilityProvider to wrap the app, Can for declarative rendering, and useAbility for imperative checks.
```tsx
import { createMongoAbility } from '@casl/ability';
import { AbilityProvider, Can, useAbility } from '@casl/react';
const ability = createMongoAbility([
{ action: 'read', subject: 'Post' },
{ action: 'create', subject: 'Post' },
]);
export function App() {
return (
List of posts
);
}
function CreatePostButton() {
const ability = useAbility();
return ability.can('create', 'Post') && (
);
}
```
--------------------------------
### Setup Development Environment
Source: https://github.com/stalniy/casl/blob/master/CONTRIBUTING.md
Commands to clone the repository, install dependencies using pnpm, and build the project packages.
```sh
# replace ${YOUR_GITHUB_USER_NAME} with your github username
git clone git@github.com:${YOUR_GITHUB_USER_NAME}/casl.git
# install pnpm, other ways at https://pnpm.js.org/en/installation
npx pnpm add -g pnpm
cd casl
pnpm i -r
pnpm run -r build # build all packages so local deps can be linked
```
--------------------------------
### Install @casl/ability with npm
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/guide/install/en.md
Use npm to install the core CASL ability package. This is the recommended method for most projects.
```sh
npm install @casl/ability
```
--------------------------------
### Install CASL Prisma and Ability
Source: https://github.com/stalniy/casl/blob/master/packages/casl-prisma/README.md
Install the necessary CASL packages for Prisma integration and core ability management.
```sh
npm install @casl/prisma @casl/ability
# or
yarn add @casl/prisma @casl/ability
# or
pnpm add @casl/prisma @casl/ability
```
--------------------------------
### Install CASL Vue
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/package/casl-vue/en.md
Install the CASL Vue package using npm or yarn.
```bash
npm install @casl/vue
```
```bash
yarn add @casl/vue
```
--------------------------------
### Install CASL Vue and Ability
Source: https://github.com/stalniy/casl/blob/master/packages/casl-vue/README.md
Install the necessary packages for CASL Vue integration using npm, yarn, or pnpm.
```sh
npm install @casl/vue @casl/ability
# or
yarn add @casl/vue @casl/ability
# or
pnpm add @casl/vue @casl/ability
```
--------------------------------
### Field Pattern Examples Table
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/guide/restricting-fields/en.md
This table illustrates the behavior of various field patterns, including '*', '**', and combinations thereof, with examples of how they match nested field names.
```plaintext
Pattern | Example | Result |
| --------------- | -------------| --------- |
| address.* |
| | `ability.can('read', 'User', 'address')` | `true` |
| | `ability.can('read', 'User', 'address.city')` | `true` |
| | `ability.can('read', 'User', 'address.city.name')` | `false` |
ad dress.** |
| | `ability.can('read', 'User', 'address')` | `true` |
| | `ability.can('read', 'User', 'address.city')` | `true` |
| | `ability.can('read', 'User', 'address.city.name')` | `true` |
| | `ability.can('read', 'User', 'address.city.location.lat')` | `true` |
| address.*.name |
| | `ability.can('read', 'User', 'address.*.name')` | `true` |
| | `ability.can('read', 'User', 'address.city.name')` | `true` |
| | `ability.can('read', 'User', 'address.city.location.name')` | `false` |
| address.**.name |
| | `ability.can('read', 'User', 'address.*.name')` | `true` |
| | `ability.can('read', 'User', 'address.city.name')` | `true` |
| | `ability.can('read', 'User', 'address.city.location.name')` | `true` |
| *.name |
| | `ability.can('read', 'User', '*.name')` | `true` |
| | `ability.can('read', 'User', 'city.name')` | `true` |
| | `ability.can('read', 'User', 'address.city.name')` | `false` |
| | `ability.can('read', 'User', 'address.city.location.name')` | `false` |
| **.name |
| | `ability.can('read', 'User', '*.name')` | `true` |
| | `ability.can('read', 'User', 'city.name')` | `true` |
| | `ability.can('read', 'User', 'address.city.name')` | `true` |
| | `ability.can('read', 'User', 'address.city.location.name')` | `true` |
| | `ability.can('read', 'User', 'address.city.code')` | `false` |
```
--------------------------------
### Install CASL Mongoose
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/package/casl-mongoose/en.md
Install the package via npm.
```bash
npm install @casl/mongoose
```
--------------------------------
### Install @casl/ability with yarn
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/guide/install/en.md
Use yarn to install the core CASL ability package. This is an alternative to npm.
```sh
yarn add @casl/ability
```
--------------------------------
### Install CASL React and Ability
Source: https://github.com/stalniy/casl/blob/master/packages/casl-react/README.md
Install the necessary CASL packages for React integration and ability management.
```sh
npm install @casl/react @casl/ability
# or
yarn add @casl/react @casl/ability
# or
pnpm add @casl/react @casl/ability
```
--------------------------------
### Install @casl/angular and @casl/ability
Source: https://github.com/stalniy/casl/blob/master/packages/casl-angular/README.md
Install the necessary CASL packages for Angular integration using npm, yarn, or pnpm.
```sh
npm install @casl/angular @casl/ability
# or
yarn add @casl/angular @casl/ability
# or
pnpm add @casl/angular @casl/ability
```
--------------------------------
### Install CASL Vue 1.x for Vue 2.x
Source: https://github.com/stalniy/casl/blob/master/packages/casl-vue/README.md
Install version 1.x of @casl/vue for compatibility with Vue 2.x applications.
```sh
npm install @casl/vue@1.x @casl/ability
# or
yarn add @casl/vue@1.x @casl/ability
# or
pnpm add @casl/vue@1.x @casl/ability
```
--------------------------------
### Check User Permissions
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/guide/intro/en.md
Check user permissions against defined abilities. This example demonstrates checking read, update, and delete permissions for 'Post' and 'User' subjects.
```javascript
import ability from './defineAbility.js';
ability.can('read', 'Post') // true
ability.can('read', 'User') // true
ability.can('update', 'User') // true
ability.can('delete', 'User') // false
ability.cannot('delete', 'User') // true
```
--------------------------------
### Initial Database Migration (SQLite)
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/cookbook/roles-with-persisted-permissions/en.md
Defines the schema for users, articles, and roles tables, including foreign key constraints. This script is used with Knex.js for database setup.
```js
exports.up = function(knex) {
return knex.schema
.createTable('users', (table) => {
table.increments('id');
table.string('email', 255).notNullable();
table.string('password', 50).notNullable();
table.integer('roleId').unsigned().notNullable();
table.foreign('roleId').references('id').inTable('roles');
})
.createTable('articles', (table) => {
table.increments('id');
table.string('title', 255).notNullable();
table.string('description').notNullable();
table.integer('authorId').unsigned().notNullable();
table.foreign('authorId').references('id').inTable('users');
})
.createTable('roles', (table) => {
table.increments('id');
table.string('name', 255).notNullable();
table.json('permissions').notNullable();
});
};
exports.down = function(knex) {
return knex.schema
.dropTable('users')
.dropTable('articles')
.dropTable('roles');
};
```
--------------------------------
### Install CASL Mongoose and Ability
Source: https://github.com/stalniy/casl/blob/master/packages/casl-mongoose/README.md
Install the necessary CASL packages for Mongoose integration and ability definition.
```sh
npm install @casl/mongoose @casl/ability
# or
yarn add @casl/mongoose @casl/ability
# or
pnpm add @casl/mongoose @casl/ability
```
--------------------------------
### Install @casl/ability with pnpm
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/guide/install/en.md
Use pnpm to install the core CASL ability package. This is another alternative package manager.
```sh
pnpm add @casl/ability
```
--------------------------------
### Install CASL Angular package
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/package/casl-angular/en.md
Use npm to install the package in your Angular project.
```bash
npm install @casl/angular @casl/ability
```
--------------------------------
### Define User Abilities
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/guide/intro/en.md
Define user abilities using `can` and `cannot` functions. This example permits all actions on all subjects but forbids deleting users.
```javascript
import { defineAbility } from '@casl/ability';
export default defineAbility((can, cannot) => {
can('manage', 'all');
cannot('delete', 'User');
});
```
--------------------------------
### Build CASL from Source
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/guide/install/en.md
Use this command to clone the CASL repository, install dependencies, and build the CASL package from the latest source code. This is necessary if you need to use CASL directly from GitHub.
```sh
git clone git@github.com:stalniy/casl.git
cd casl
pnpm i -r
cd packages/casl-ability
npm run build
```
--------------------------------
### Fetch Accessible Records for a Different Action
Source: https://github.com/stalniy/casl/blob/master/packages/casl-mongoose/README.md
Fetches records accessible for an action other than the default 'read'. This example retrieves posts that the user can 'update'.
```javascript
const Post = require('./Post');
const ability = require('./ability');
async function main() {
const postsThatCanBeUpdated = await Post.accessibleBy(ability, 'update');
console.log(postsThatCanBeUpdated);
}
```
--------------------------------
### Manual Claim Check
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/cookbook/claim-authorization/en.md
A basic JavaScript example demonstrating how to check for permissions by manually including claims in a user object. This approach requires explicit testing and maintenance for each permission check.
```typescript
const ACTIONS = ['review', 'publish', 'read'];
function publishArticle(article, user) {
if (!user.permissions.includes('publish')) {
throw new Error('You cannot publish articles');
}
// logic to publish article
}
```
--------------------------------
### Infer Subject Types from Interfaces
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/advanced/typescript/en.md
Define actions and subjects using TypeScript interfaces. This example demonstrates how to create an ability instance and includes examples of correct and incorrect usage that would result in build-time errors.
```typescript
import { createMongoAbility } from '@casl/ability';
interface Article {
id: number
title: string
content: string
authorId: number
}
interface User {
id: number
name: string
}
interface Comment {
id: number
content: string
authorId: number
}
type Action = 'create' | 'read' | 'update' | 'delete';
type Subject = Article | Comment | User | 'Article' | 'User' | 'Comment';
const ability = createMongoAbility<[Action, Subject]>();
ability.can('read', 'Article');
ability.can('write', 'Article'); // error because non-existing action name
ability.can('update', 'Coment') // error because of typo
```
--------------------------------
### Fetch Accessible Articles using Static Method
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/advanced/ability-to-database-query/en.md
This example demonstrates how to use the `accessibleBy` static method on the `Article` model to fetch records that the current user has permission to read. It initializes Sequelize, defines the Article model, creates an ability, and then calls `Article.accessibleBy`.
```javascript
const { Sequelize } = require('sequelize');
const { defineAbility } = require('@casl/ability');
const defineArticle = require('./Article');
const sequelize = new Sequelize('sqlite::memory');
const Article = defineArticle(sequelize);
async function main() {
const ability = defineAbility(can => can('read', Article, { published: true }));
const articles = await Article.accessibleBy(ability);
console.log(articles);
}
main().catch(console.error);
```
--------------------------------
### Define Basic Rules with defineAbility
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/guide/define-rules/en.md
Use the `defineAbility` function for simple rule definitions, suitable for unit tests, examples, and prototypes. It accepts `can` and `cannot` functions to declare permissions.
```javascript
import { defineAbility } from '@casl/ability';
export default defineAbility((can, cannot) => {
can('read', 'Post');
cannot('delete', 'Post', { published: true });
});
```
--------------------------------
### Check Article Permissions
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/guide/intro/en.md
Check permissions for various scenarios using a CASL ability instance. This example demonstrates checking read and update permissions on specific fields and articles.
```javascript
import defineAbilityFor from './defineAbility';
import { Article } from './entities';
const moderator = { id: 2, isModerator: true };
const ownArticle = new Article({ authorId: moderator.id });
const foreignArticle = new Article({ authorId: 10 });
const ability = defineAbilityFor(moderator);
ability.can('read', 'Article') // true
ability.can('update', 'Article', 'published') // true
ability.can('update', ownArticle, 'published') // true
ability.can('update', foreignArticle, 'title') // false
```
--------------------------------
### Casl Ability Setup with TypeScript
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/cookbook/roles-with-persisted-permissions/en.md
Defines available actions and subjects for Casl abilities and provides a typed factory function for creating ability instances. Uses TypeScript for enhanced type safety.
```ts
import { createMongoAbility, MongoAbility, RawRuleOf, ForcedSubject } from '@casl/ability';
export const actions = ['manage', 'create', 'read', 'update', 'delete'] as const;
export const subjects = ['Article', 'all'] as const;
export type Abilities = [
typeof actions[number],
typeof subjects[number] | ForcedSubject>
];
export type AppAbility = MongoAbility;
export const createAbility = (rules: RawRuleOf[]) => createMongoAbility(rules);
```
--------------------------------
### Updating Ability Instance on User Login
Source: https://github.com/stalniy/casl/blob/master/packages/casl-react/README.md
This example demonstrates how to update the CASL `Ability` instance when a user logs in, based on their role. It uses `fetch` to log in and then calls `updateAbility` to apply new rules.
```typescript
import { AbilityBuilder, Ability } from '@casl/ability';
import React, { useState } from 'react';
import { useAbility } from '@casl/react';
function updateAbility(ability, user) {
const { can, rules } = new AbilityBuilder(Ability);
if (user.role === 'admin') {
can('manage', 'all');
} else {
can('read', 'all');
}
ability.update(rules);
}
export default () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const ability = useAbility();
const login = () => {
const params = {
method: 'POST',
body: JSON.stringify({ username, password })
};
return fetch('path/to/api/login', params)
.then(response => response.json())
.then(({ user }) => updateAbility(ability, user));
};
return (
);
};
```
--------------------------------
### Define Ability with Inverted Rule
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/guide/define-rules/en.md
This example demonstrates how to define an ability that uses an inverted rule to explicitly forbid an action based on a condition, such as a user not having a paid subscription.
```javascript
import { AbilityBuilder, createMongoAbility } from '@casl/ability';
async function defineAbility(user) {
const hasPaidSubscription = await user.hasPaidSubscription();
const { can, cannot, build } = new AbilityBuilder(createMongoAbility);
if (hasPaidSubscription) {
can('create', 'BlogPost');
} else {
cannot('create', 'BlogPost').because('You have not paid for monthly subscription');
}
return build()
}
```
--------------------------------
### Infer Subject Types from Classes
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/advanced/typescript/en.md
Define actions and subjects using TypeScript classes. This example shows how to create an ability instance and use it with class instances and class references.
```typescript
import { createMongoAbility } from '@casl/ability';
class Article {
id: number
title: string
content: string
authorId: number
}
type Action = 'create' | 'read' | 'update' | 'delete';
type Subject = typeof Article | Article;
const ability = createMongoAbility<[Action, Subject]>();
ability.can('read', Article);
ability.can('update', new Article());
```
--------------------------------
### Test Rule Distribution Logic (Incorrect Approach)
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/advanced/debugging-testing/en.md
This example demonstrates an incorrect way to test CASL permissions by directly checking the generated rules. This approach is brittle and prone to breaking when rules are refactored.
```javascript
import { defineRulesFor } from './defineAbility';
describe('Permissions', () => {
let user;
describe('when user is an admin', () => {
beforeEach(() => {
user = { isAdmin: true };
});
it('can do anything', () => {
expect(defineRulesFor(user)).to.deep.equal([
{ action: 'manage', subject: 'all' }
]);
});
});
describe('when user is a regular user', () => {
beforeEach(() => {
user = { isRegular: true };
});
it('can read non private article', () => {
expect(defineRulesFor(user)).to.deep.contain([
{ action: 'read', subject: 'Article' },
{ action: 'read', subject: 'Article', conditions: { private: true }, inverted: true }
]);
});
});
});
```
--------------------------------
### Common MongoDB Query Operator Examples
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/guide/conditions-in-depth/en.md
Provides a collection of various query patterns including equality, existence checks, range filtering, array matching, and regex patterns for property validation.
```javascript
const queries = [
{ private: true },
{ private: false, hidden: false },
{ private: { $exists: true } },
{ status: { $in: ['review', 'inProgress'] } },
{ price: { $gte: 10, $lte: 50 } },
{ tags: { $all: ['permission', 'casl'] } },
{ email: { $regex: /@gmail.com$/i } },
{ 'cities.address': { $elemMatch: { postalCode: { $regex: /^AB/ } } } }
]
```
--------------------------------
### Safer Permissions Inference with Dependencies
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/advanced/typescript/en.md
Define explicit dependencies between actions and subjects for enhanced type safety. This example demonstrates how to restrict actions on certain subjects, leading to build-time errors for disallowed operations.
```typescript
import { createMongoAbility } from '@casl/ability';
type CRUD = 'create' | 'read' | 'update' | 'delete';
type Abilities = ['read', 'User'] | [CRUD, 'Article'];
const ability = createMongoAbility();
ability.can('read', 'User');
ability.can('create', 'User'); // build time error! because it's not allowed to create users
```
--------------------------------
### Allow Access to Fields Matching a Prefix with '*'
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/guide/restricting-fields/en.md
Use a pattern like 'street*' to grant access to fields that start with a specific prefix. This is helpful when a resource has multiple fields with similar naming conventions, such as 'street1', 'street2', etc.
```javascript
import { defineAbility } from '@casl/ability';
const ability = defineAbility((can) => {
can('read', 'User', ['street*']);
});
ability.can('read', 'User', 'street'); // true
ability.can('read', 'User', 'street1'); // true
ability.can('read', 'User', 'street2'); // true
```
--------------------------------
### Initial Database Migration Script
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/cookbook/roles-with-static-permissions/en.md
Sets up the 'users' and 'roles' tables for the application. The 'users' table includes foreign key constraint to the 'roles' table.
```javascript
exports.up = function(knex) {
return knex.schema
.createTable('users', (table) => {
table.increments('id');
table.string('email', 255).notNullable();
table.string('password', 50).notNullable();
table.integer('roleId').unsigned().notNullable();
table.foreign('roleId').references('id').inTable('roles');
})
.createTable('roles', (table) => {
table.increments('id');
table.string('name', 255).notNullable();
});
};
exports.down = function(knex) {
return knex.schema
.dropTable('users')
.dropTable('roles');
};
```
--------------------------------
### Instantiate Ability with Rules
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/api/casl-ability/en.md
Create a new Ability instance and initialize it with a set of permission rules. This is useful for setting up initial permissions.
```typescript
const ability = new Ability<['read' | 'update', 'Article']>([
{ action: 'read', subject: 'Article' },
{ action: 'update', subject: 'Article' },
]);
```
--------------------------------
### Check Permissions in Application Logic
Source: https://github.com/stalniy/casl/blob/master/packages/casl-ability/README.md
Shows how to verify user permissions against specific actions or objects using the ability instance, and how to enforce them by throwing errors.
```javascript
import { BlogPost, ForbiddenError } from '../models';
const user = getLoggedInUser();
const ability = defineAbilitiesFor(user);
ability.can('read', 'BlogPost');
const post = new BlogPost({ title: 'What is CASL?' });
ability.cannot('read', post);
ForbiddenError.from(ability).throwUnlessCan('read', post);
```
--------------------------------
### Initial Database Seed Script
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/cookbook/roles-with-static-permissions/en.md
Populates the 'roles' table with 'admin' and 'member' roles and seeds the 'users' table with initial admin and member user records.
```javascript
exports.seed = async (knex) => {
await Promise.all([
knex('users').del(),
knex('roles').del()
]);
await knex('roles').insert([
{ id: 1, name: 'admin' },
{ id: 2, name: 'member' }
]);
await knex('users').insert([
{ id: 1, email: 'admin@casl.io', password: '123456', roleId: 1 },
{ id: 2, email: 'member@casl.io', password: '123456', roleId: 2 },
]);
};
```
--------------------------------
### Initial Database Seed
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/cookbook/roles-with-persisted-permissions/en.md
Populates the database with initial roles (admin, member) and users. Permissions are stored as JSON strings, with dynamic conditions for member articles.
```js
exports.seed = async (knex) => {
await Promise.all([
knex('users').del(),
knex('roles').del()
]);
await knex('roles').insert([
{
id: 1,
name: 'admin',
permissions: JSON.stringify([
{ action: 'manage', subject: 'all' }
])
},
{
id: 2,
name: 'member',
permissions: JSON.stringify([
{ action: 'read', subject: 'Article' },
{ action: 'manage', subject: 'Article', conditions: { authorId: '${user.id}' } },
])
}
]);
await knex('users').insert([
{ id: 1, email: 'admin@casl.io', password: '123456', roleId: 1 },
{ id: 2, email: 'member@casl.io', password: '123456', roleId: 2 },
]);
};
```
--------------------------------
### Fetch Users and Create Abilities
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/cookbook/roles-with-persisted-permissions/en.md
Fetches admin and author users and creates CASL Ability instances for each based on their permissions. Ensure user fetching and ability creation services are correctly implemented.
```typescript
import { findBy } from './services/users';
import { createAbility } from './services/appAbility';
export default async function main() {
const [admin, author] = await Promise.all([
findBy({ email: 'admin@casl.io' }),
findBy({ email: 'member@casl.io' }),
]);
const adminAbility = createAbility(admin!.permissions);
const authorAbility = createAbility(author!.permissions);
// the rest of the code
}
```
--------------------------------
### Ability Constructor
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/api/casl-ability/en.md
Initializes a new instance of the Ability class. It accepts an array of rules and an options object for customizing behavior like subject type detection, condition matching, field matching, and action alias resolution.
```APIDOC
## Ability Constructor
### Description
Initializes a new instance of the Ability class. It accepts an array of rules and an options object for customizing behavior like subject type detection, condition matching, field matching, and action alias resolution.
### Parameters
* `rules`: `RawRuleFrom[]` - An array of raw rules to initialize the ability with. Defaults to an empty array.
* `options`: `AbilityOptions` - An optional object for configuration:
* `detectSubjectType`: `(subject?: Subject) => string` - A function to detect the subject type.
* `conditionsMatcher`: `ConditionsMatcher` - A function to customize condition matching logic.
* `fieldMatcher`: `FieldMatcher` - A function to customize field matching logic.
* `resolveAction`: `ResolveAction[0]>` - A function to resolve action aliases.
### Usage
```ts
import { Ability } from '@casl/ability';
const ability = new Ability<['read' | 'update', 'Article']>([
{ action: 'read', subject: 'Article' },
{ action: 'update', subject: 'Article' },
]);
```
### See also
* [Define rules](../../guide/define-rules)
```
--------------------------------
### Can Component with Field Check
Source: https://github.com/stalniy/casl/blob/master/packages/casl-react/README.md
Example of using the Can component to check permissions for a specific field within a subject.
```jsx
export default ({ post }) =>
Yes, you can do this! ;)
```
--------------------------------
### Find User by Conditions and Prepare Permissions
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/cookbook/roles-with-persisted-permissions/en.md
Fetches a user from the database based on provided conditions and interpolates their permissions. This function prepares user permissions for direct use with `createAbility`.
```typescript
import db from '../db';
import { User } from '../models/User';
import interpolate from '../helpers/interpolate';
export async function findBy(where: Partial>) {
const { permissions, ...user } = await db('users')
.innerJoin('roles', 'users.roleId', 'roles.id')
.select('users.id', 'users.email', 'roles.permissions', { role: 'roles.name' })
.where(where)
.first();
user.permissions = interpolate(permissions, { user });
return user;
}
```
--------------------------------
### Can Component with React Element Children
Source: https://github.com/stalniy/casl/blob/master/packages/casl-react/README.md
Example of using standard React elements as children for the Can component for simple conditional rendering.
```jsx
export default () =>
```
--------------------------------
### Define Ability Instance
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/package/casl-vue/en.md
Create an instance of the `Ability` class and define rules for authorization.
```javascript
import { AbilityBuilder } from '@casl/ability';
function defineAbilitiesFor(user) {
const { can, build } = new AbilityBuilder(Ability);
if (user.isAdmin) {
can('manage', 'all');
} else {
can('read', 'all');
}
return build();
}
export default defineAbilitiesFor;
```
--------------------------------
### Define User Abilities with CASL
Source: https://github.com/stalniy/casl/blob/master/packages/casl-ability/README.md
Demonstrates how to use AbilityBuilder to define granular permissions, including conditional rules based on user ownership and time-based constraints.
```javascript
import { AbilityBuilder, createMongoAbility } from '@casl/ability';
import { User } from '../models';
function defineAbilitiesFor(user) {
const { can, cannot, build } = new AbilityBuilder(createMongoAbility);
can('read', 'BlogPost');
can('manage', 'BlogPost', { author: user.id });
cannot('delete', 'BlogPost', {
createdAt: { $lt: Date.now() - 24 * 60 * 60 * 1000 }
});
return build();
}
```
--------------------------------
### Express Session Configuration with Redis
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/cookbook/cache-rules/en.md
Configures express-session with a Redis store for session management. This setup is necessary when using session storage for CASL rules.
```typescript
import { provideAbility } from './provideAbility';
import express from 'express';
import session from 'express-session';
import redis from 'redis';
import createRedisStore from 'connect-redis';
const app = express();
const RedisStore = createRedisStore(session);
app.use(session({
store: new RedisStore({ client: redis.createClient() }),
secret: 'my app session secret',
}));
// app configuration and other middlewares
app.use(provideAbility);
```
--------------------------------
### Provide Ability Instance with AbilityProvider
Source: https://github.com/stalniy/casl/blob/master/packages/casl-react/README.md
Wraps the application or a part of it with AbilityProvider to make the ability instance available via context.
```jsx
import { AbilityProvider } from '@casl/react';
import ability from './ability';
export default function App() {
return (
)
}
```
--------------------------------
### Alias Directionality Example
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/guide/define-aliases/en.md
Demonstrates that aliases are one-directional. Defining 'modify' as an alias for 'update' and 'delete' does not mean 'update' or 'delete' can be checked using the 'modify' alias.
```typescript
import { defineAbility, createAliasResolver } from '@casl/ability'
const resolveAction = createAliasResolver({
modify: ['update', 'delete']
});
const ability = defineAbility((can) => {
can(['update', 'delete'], 'Post');
}, { resolveAction });
ability.can('modify', 'Post'); // false <---
ability.can('update', 'Post'); // true
ability.can('delete', 'Post'); // true
```
--------------------------------
### Get Versioned Base Path
Source: https://github.com/stalniy/casl/blob/master/docs-src/public/web-root/404.html
Extracts the versioned base path (e.g., '/v7') from a URL pathname. If no version is found, it returns a default fallback version.
```javascript
function getVersionBasePath(pathname, fallbackVersion) {
var versionMatch = pathname.match(/^\/v\d+(?=\/|$)/);
return versionMatch ? versionMatch[0] : fallbackVersion;
}
```
--------------------------------
### Get Relevant Rule for an Action
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/advanced/debugging-testing/en.md
Use `relevantRuleFor` to retrieve the specific rule that allows or forbids an action on a subject. This method returns `null` if no rule matches.
```javascript
import { defineAbility } from '@casl/ability';
const ability = defineAbility((can) => {
can('read', 'Article');
});
const rule = ability.relevantRuleFor('read', 'Article'); // instance of internal `Rule` class
```
```javascript
const rule = ability.relevantRuleFor('update', 'Article'); // null
```
--------------------------------
### Basic Usage of accessibleFieldsBy with Mongoose Models
Source: https://github.com/stalniy/casl/blob/master/packages/casl-mongoose/README.md
A concise example showing the direct usage of `accessibleFieldsBy` with a Mongoose `Post` model and a document instance, without relying on the `accessibleRecordsPlugin`.
```typescript
import { accessibleFieldsBy } from '@casl/mongoose';
accessibleFieldsBy(ability).ofType(Post);
const post = new Post();
accessibleFieldsBy(ability).of(post);
```
--------------------------------
### Update Ability Rules
Source: https://github.com/stalniy/casl/blob/master/docs-src/src/content/pages/api/casl-ability/en.md
Completely replace the existing rules of an Ability instance with a new set of rules. Use this to dynamically change permissions, for example, after login or logout.
```typescript
import { Ability } from '@casl/ability';
const ability = new Ability([{ action: 'manage', subject: 'all' }]);
ability.update([]); // took back all permissions
```
--------------------------------
### Configure Prisma Client Output Path
Source: https://github.com/stalniy/casl/blob/master/packages/casl-prisma/README.md
Specify a custom directory for the Prisma client generator in your schema.prisma file. This is necessary for Prisma 7 and later when `@prisma/client` does not re-export project types.
```prisma
generator client {
provider = "prisma-client"
output = "../src/generated/client"
}
```
--------------------------------
### Check Permissions in Templates using AbilityService
Source: https://github.com/stalniy/casl/blob/master/packages/casl-angular/README.md
Use the AbilityService to get an observable of the current Ability instance and check permissions within Angular templates using the async pipe.
```typescript
@Component({
selector: 'my-home',
template: `
@if (ability$ | async as ability) {