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

trivialperms

v2.0.0

Published

A simple RBAC implementation that is datasource agnostic.

Downloads

7

Readme

TrivialPermissions

A simple RBAC implementation that is datasource agnostic. I've designed it to be easy to integrate into existing projects, while being flexible and very simple to use. It may not be the most powerful permission system ever devised, but it is one of the easiest to get up and running with in very little time.

Installation

Node.js

Simply install with npm:

$ npm add trivialperms

or yarn:

$ yarn add trivialperms

Usage

TrivialPermissions is built on the concept of 'role based access control'. In essence, a user is a member of a group. That group has specific permissions. A user may also have specific permissions granted. A user is allowed access if either they, or one of their groups they have the permission being tested.

Permissions

In TrivialPermissions, a permission is any string (other than * or */*):

'PermissionDescriptor'

TrivialPermissions supports whatever roles you want to use. It supports any arbitrary string. Previous versions were built around a Object/Permission styles, and those still work, but in the spirit of simplification and flexibility, we've dropped the concept of 'object level' permissions, since those were never really implemented in a useful way.

Glob Matching

TrivialPermissions has special support for * and */*. These strings, when used as a permission name, are considered wildcards. All permission checks will pass if a user or group has * or */* as a permission.

Groups

Groups are small objects with a name and a list of permissions. TrivialPermissions requires you to define (or load) these groups before you attempt to use them. This is generally considered part of the initial setup for TrivialPermissions. While TrivialPermissions allows you to use your own objects for users, it requires you to preload your groups.

Defining a Group

  • defineGroup({ name: '...', permissions: [...] }) - Returns the created group object.

Defining an individual group is very simple:

import tp from 'trivialperms'

// Create an 'Admins' group
const admGroup = tp.defineGroup({ name: 'Admins', permissions: ['*/*'] });

Loading Groups

  • loadGroups(list) - Returns a list of all loaded groups.

More usefully, you will want to load multiple groups at once. TrivialPermissions supports loading a list of groups.

Note: Previous versions allowed for you to pass in a promise or a function, and it would resolve it, but in the world of async/await, there's no reason to support this anymore.

import tp from 'trivialperms';

// Load from a list
tp.loadGroups([
    {
        name: "Administrators",
        permissions: [
            "*/*"
        ]
    },
    {
        name: "Authors",
        permissions: [
            "canViewPosts",
            "canAddPosts",
            "canEditPosts"
        ]
    },
    {
        name: "Users",
        permissions: [
            "canViewPosts"
        ]
    }
]);

This should make it very easy to integrate with a database library, for example.

Users

You are expected to be providing your own user objects. Generally, this would come from either an authentication system, or a database of some kind. Because of this, we did not want to force you to preload all your users; rather, you provide TrivialPermissions with the object when you want to check permissions. TrivialPermissions requires an object that looks like this:

export interface TPUser {
    permissions ?: string[];
    groups ?: string[];
}

While both permissions and groups are optional, the user will have no permissions if one of the two isn't set.

Checking Permissions

  • hasPerm(user, perm) - Returns true if the user has that permission on that object, otherwise false.

This is the heart of the system: checking permissions. It's very simply; you pass the user object, and the permission descriptor (string). Here are a few examples:

import tp from 'trivialperms';

// Setup
tp.loadGroups([
    {
        name: "Administrators",
        permissions: [
            "*/*"
        ]
    },
    {
        name: "Authors",
        permissions: [
            "canViewPosts",
            "canAddPosts",
            "canEditPosts"
        ]
    },
    {
        name: "Users",
        permissions: [
            "canViewPosts"
        ]
    }
]);

// Define Users
const batman = {
    name: 'batman',
    groups: ['Administrators']
};

const stark = {
    name: 'tstark',
    permissions: ['*'],
    groups: ['Users']
};

const leo = {
    name: 'lblume',
    groups: ['Users']
};

// Batman can edit posts
console.log(tp.hasPerm(batman, 'canEditPosts'));			// true

// Tony Start can do anything
console.log(tp.hasPerm(stark, 'canEditPosts'));				// true
console.log(tp.hasPerm(stark, 'canGetAwayWithMurder'));		// true

// Leo can read posts
console.log(tp.hasPerm(leo, 'canViewPosts'));				// true

// Leo can not edit posts
console.log(tp.hasPerm(leo, 'canEditPosts'));				// false

Checking Group membership

  • hasGroup(user, groupName) - Returns true if the user is a member of the group and the group has been defined, otherwise false.

Checking for group membership is also a very simple thing to do in TrivialPermissions. However, we add one additional check about simply seeing if groupName is in the list of groups on the user: hasGroup() returns false for groups that have not been defined, regardless of is the user has that group name in their list of groups.

import tp from 'trivialperms';

// Setup
tp.loadGroups([
    {
        name: "Administrators",
        permissions: [
            "*/*"
        ]
    },
    {
        name: "Authors",
        permissions: [
            "canViewPosts",
            "canAddPosts",
            "canEditPosts"
        ]
    },
    {
        name: "Users",
        permissions: [
            "canViewPosts"
        ]
    }
]);

// Define Users
const batman = {
    name: 'batman',
    groups: ['Administrators']
};

const stark = {
    name: 'tstark',
    permissions: ['*'],
    groups: ['Users']
};

const leo = {
    name: 'lblume',
    groups: ['Users']
};

// Batman is an admin
console.log(tp.hasGroup(batman, 'Administrators'));				// true

// Tony Start is not an admin
console.log(tp.hasGroup(stark, 'Administrators'));				// false

// Leo is a user
console.log(tp.hasGroup(leo, 'Users'));							// true