Skip to content

@casl/mongoose@4.0.0

Compare
Choose a tag to compare
@stalniy stalniy released this 12 Feb 08:45
· 400 commits to master since this release

4.0.0 (2021-02-12)

Code Refactoring

Features

  • angular: updates angular to v11 (#421) (ec16bf9)
  • mongoose: throws ForbiddenError instead of returning a hard-coded value when user has not permissions to do some action (917dd01), closes #404

BREAKING CHANGES

  • vue: refactor to use Vue 3 what introduces a bunch of breaking changes:

    • Ability instance is not a required plugin parameter. Previously, we could decide whether to pass ability as plugin parameter or as root component option. Now, the only way is to pass it in plugin:

      Before

      import { abilitiesPlugin } from '@casl/vue';
      import Vue from 'vue';
      import { ability } from './services/AppAbility';
      
      Vue.use(abilitiesPlugin);
      new Vue({
        ability
      }).$mount('#app')

      After

      import { abilitiesPlugin } from '@casl/vue';
      import { createApp } from 'vue';
      import { ability } from './services/AppAbility';
      
      createApp()
       .use(abilitiesPlugin, ability)
       .mount('#app');
    • abilitiesPlugin no more define global $ability and $can properties, instead a recommended way to get AppAbility instance is by injecting it through provide/inject API. To get previous behavior, pass useGlobalProperties: true option:

      Before

      import { abilitiesPlugin } from '@casl/vue';
      import Vue from 'vue';
      import { ability } from './services/AppAbility';
      
      Vue.use(abilitiesPlugin);
      const root = new Vue({
        ability
      }).$mount('#app')
      
      console.log(root.$ability)

      After

      Recommended way:

      import { abilitiesPlugin, ABILITY_TOKEN } from '@casl/vue';
      import { createApp } from 'vue';
      import { ability } from './services/AppAbility';
      
      const App = {
        name: 'App',
        inject: {
          $ability: { from: ABILITY_TOKEN }
        }
      };
      
      const root = createApp(App)
        .use(abilitiesPlugin, ability, {
          useGlobalProperties: true
        })
        .mount('#app');
      
      console.log(root.$ability)

      Backward compatible way:

      import { abilitiesPlugin } from '@casl/vue';
      import { createApp } from 'vue';
      import { ability } from './services/AppAbility';
      
      const root = createApp()
        .use(abilitiesPlugin, ability, {
          useGlobalProperties: true
        })
        .mount('#app');
      
      console.log(root.$ability)
    • AllCanProps<TAbility> type was renamed to CanProps<TAbility>

    • @casl/vue no more augment vue types, so if you decide to use global properties, you will need to augment types by yourself

      Before

      @casl/vue augments type of $ability to AnyAbility and $can to typeof $ability['can']

      After

      create a separate file src/ability-shim.d.ts with the next content:

      import { AppAbility } from './AppAbility'
      
      declare module 'vue' {
        interface ComponentCustomProperties {
          $ability: AppAbility;
          $can(this: this, ...args: Parameters<this['$ability']['can']>): boolean;
        }
      }
  • mongoose: accessibleBy eventually throws ForbiddenError instead of returning a hard-coded value

    Before:

    // ability doesn't allow to read Post
    const ability = defineAbility(can => can('manage', 'Comment'));
    
    try {
      const items = await Post.accessibleBy(ability, 'read');
      console.log(items); // []
    } catch (error) {
      console.error(error); // no error thrown
    }

    After:

    // ability doesn't allow to read Post
    const ability = defineAbility(can => can('manage', 'Comment'));
    
    try {
      const items = await Post.accessibleBy(ability, 'read');
      console.log(items); // not reached, because query fails with error
    } catch (error) {
      console.error(error); // ForbiddenError thrown
    }