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

v-access

v2.1.1

Published

An authorization plugin for Vue.js v2.x.

Downloads

23

Readme

An authentication solution based on Vue.js v2.x, including elements-based control and route-based control.

| Dependencies | Required | | :----------------------------------------------------: | :------: | | vue | ✔️ | | vue-router | ✔️ |

Features

  • Minimal design: Only one ability/privilege list and give you all element-based and route-based authentications.

  • Smooth changes: Support any dynamic private routes addition and deletion without page reloading.

Installation

# using npm
npm i v-access

# using yarn
yarn add v-access

Prerequisites

  • Ability type

    type Ability = string

    Ability should be a global unique identifier and string type.

  • Routes type

    interface RouteWithAbility extends RouteConfig {
      readonly children?: RouteWithAbility[]
      readonly meta?: {
        strict?: Ability[]
        weak?: Ability[]
        ability?: Ability
        [key: string]: any
      }
    }

    More details could be found from here.

Best practice

NOTICE: This section is only the best practice recommendation, not required.

The entire authorization system is based on an ability/privilege list provided by any back-end services. Every element in the list represents an ability that is used to access the corresponding database. A user role consists of multiple abilities, represents an ability set. One actual user could have multiple user roles.

There is a best practice that uses syntax like [scope].[module].[ability] (eg. IAM) to represents one ability. In this case, [scope] is optional if you have no other external systems (scope).

The advantage of this design is that the role of multiple users or the ability of multiple roles can be intersected. Multiple abilities can be arbitrarily combined to form a flexible abilities set.

The following chart represents an actual user's ability set:

                      +--> github.repo.read
      +-> user role 1 |
      |               +--> npm.org.import
      |
      |               +--> github.pull.read
user -+-> user role 2 |
      |               +--> npm.downloads.read
      |
      |               +--> github.action.read
      +-> user role 3 |
                      +--> npm.packages.publish

No matter what your ability name is, you should always call init function with a full ability list first.

Initialization

import Vue from 'vue'
import VAccess from 'v-access'

Vue.use(VAccess)

This package should be installed before the root Vue instance creation. This process will inject a global component named VAccess and a prototype property named $$auth.

import { init } from 'v-access'

export default {
  name: 'AnyComponent',

  // ... omit all unrelated properties

  created() {
    // a vuex action or http request
    fetchAbilities(payload)
      .then(list => list.map(abilityInfo => ability.name)) // ability serialization
      .then(abilities =>
        init({
          vm: this, // or this.$router
          abilities,
          redirect: '/forbidden',
          routes: [
            /* routes which need to add to vue-router would be filtered by abilities first */
          ]
        })
      )
      .catch(console.error)
  }
}

No matter the original abilities structure is, you should always pass an Ability identity list (a string[] type) to init function for initializing global authentication functionality.

interface InitOptions {
  vm: Vue | VueRouter
  abilities: Ability[]
  redirect: string
  routes?: RouteWithAbility[]
}

export declare function init({
  vm,
  abilities,
  redirect,
  routes
}: InitOptions): void

NOTE: redirect only support a fullPath string, not object type.

As you may have noticed, you can pass a global preset private routes collection to init function for dynamic routes addition. All valid private routes generation could be handled by this package and will be filtered by abilities set.

Scenario

This case would be useful when you want to create private routes that need to be filtered by the current user abilities.

How to authenticate ability

  1. Using element-based authentication

    The results of the following two authentication ways are reactive.

    1. VAccess component

      <v-access :ability="['github.repo.read', 'github.repo.pull']">
        <!-- any child components or HTML nodes -->
      </v-access>
      
      <!-- or -->
      <v-access strict :ability="['github.repo.read', 'github.repo.pull']">
        <!-- any child components or HTML nodes -->
      </v-access>
      
      <!-- or -->
      <v-access :ability="github.repo.read">
        <!-- any child components or HTML nodes -->
      </v-access>

      | Props | Type | Description | | :-----: | :----------------------: | :--------------------------------------------------------: | | ability | Ability or Ability[] | An ability or ability set that needs to be authenticated | | strict | boolean | Whether we should authenticate every abilities in the list |

    2. $$auth object

      The following table describes several $$auth authentication functions.

      | Function | Type | Description | | :--------: | :---------------------------------: | :-------------------------------------------------------------: | | has | (ability: Ability) => boolean | An ability that needs to be authenticated | | verifyAll | (abilities: Ability[]) => boolean | Whether we should authenticate every ability in the list | | verifySome | (abilities: Ability[]) => boolean | Whether we should authenticate at least one ability in the list |

  2. Using route-based authentication

    const routes = [
      // This route always pass authentication
      {
        name: 'PublicRoutes',
        path: '/public',
        component: () =>
          import(/* webpackChunkName: 'page-public' */ './views/Public.vue')
      },
      {
        name: 'PrivateRoutes',
        path: '/private',
        component: () =>
          import(/* webpackChunkName: 'page-private' */ './views/Private.vue'),
        meta: {
          strict: ['github.repo.read', 'github.repo.pull']
          // or
          // weak: ['github.repo.read', 'github.repo.pull'],
          // or
          // ability: 'github.repo.read'
        }
      }
    ]

    | Meta prop | Objective | | :-------: | :-------------------------------------------------------------: | | strict | Whether we should authenticate every ability in the list | | weak | Whether we should authenticate at least one ability in the list | | ability | A single ability that needs to be authenticated |

Reset

export declare function reset(router: VueRouter): void

You should always use reset(theCurrentRouterInstance) to delete all private routes added by init function without any page reloading.

import { reset } from 'v-access'

reset(this.$router)

With other hooks

Separation of concerns is a design principle for separating distinct parts, and implement the high cohesion and low coupling between multiple independent parts. Vue router navigation guard accepts multiple hooks to implement a navigation pipeline via this principle. This is the theoretical basis for v-access implementation. v-access has provided an authorizer as a beforeEach guard.

If you aren't familiar with how multiple global beforeEach hooks work, I strongly recommend you to read the documentation about router.beforeEach.

Changelog

All notable changes to this package will be documented in CHANGELOG file.

License

MIT © Bowen Liu