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

payload-warding

v0.1.10

Published

A Collections / Globals Backed Payload RBAC Plugin

Downloads

8

Readme

A Collections / Globals Backed Payload RBAC Plugin

📖 Table of Contents

✨ Synopsis

  • This plugin collects information from collections, globals and user provided extra synopses to build a collection of unified features which looks like the following data structure:
{
  feature: string, // the slug of a collection or a global
  traits: string[], // a collection of field names or endpoint (which belongs to the collection or global) paths
  verbs: string[], // create, read, update, delete
}[] // a collection of this of all the collections, globals and user provided synopses
  • Then the data is used to bring to us this:

Warding example

⚙️ Usage

yarn add payload-warding
# or
npm i payload-warding
// ...
import warding, { convention } from "payload-warding";

//...
export default buildConfig({
  // ...
  plugins: [
    // ...
    warding(
      convention.opts({
        root: { email: process.env.YOUR_ROOT_EMAIL!, password: process.env.YOUR_ROOT_PASSWORD! },
      }),
    ),
    // ...
  ],
  // ...
});
// ...

The convention.opts will merge your options with predefined default options, see convention.ts for details.

🎨 Options

  • root
/**
 * The root user's email and password. If not provided, the root user will not
 * be created.
 */
root?: {
  email: string;
  password: string;
};

Please note that the user created in the create-first-user page will be automatically bound with a root role. So it's fine to skip the root user creation.

  • user
/**
 * The user {@link Options}.
 */
user?: Options;

type Options = {
  slug: string;
  fields?: Field[]; // payload's Field type
  title?: string;
  tag?: SpecLabels;
};

type SpecLabels = {
  plural?: Record<string, string> | string;
  singular?: Record<string, string> | string;
};
  • role
/**
 * The role {@link Options}.
 */
role?: Options;
  • label
/**
 * All the labels for plugin introduced collections, fields and select options.
 */
label?: Label;
  • ext
/**
 * Extended features in the form of {@link Synopsis}s.
 */
ext?: Synopsis[];

type Synopsis = {
  slug: string;
  traits: [string, Label | undefined][];
  label?: Label;
};

type Label = Record<string, string> | string;

This paired with the check function in convention.ts can be used to build custom access control upon the user + role system provided by this plugin.

  • mod
/**
 * Modifies the {@link Built} result after {@link Warding.build}.
 */
mod?: (w: Built) => Built;

type Built = {
  collections: { user: CollectionConfig; role: CollectionConfig };
  warden: Warden;
  populate: Populate;
  initialize: Initialize;
  initializationExtra?: { user: any; role: any };
};

See factory/spec.ts for details.

  • mute
/**
 * Disable this plugin without uninstalling it.
 */
mute?: boolean;

🔐 Authorization

📚 Collections

Authorizations of Collections are provided by adding access functions to all possible collections, fields...and so on. The said access functions will ask for a specific feature, traits, verbs combination to be present, or otherwise reject the operation it is assigned to.

For example, the expected feature, traits, verbs combination for which an access.create of a collection chad will ask looks like this:

{
  feature: "chad",
  trais: [],
  verbs: ["create"]
}

Any user who has a role with a feature chad and any trait (which, if is left empty in the role editing page, will have a default "_" trait assigned) of verb create can pass the check. As for the access.update of a field age of the collection chad, it looks like this:

{
  feature: "chad",
  trais: ["age"],
  verbs: ["update"]
}

🧭 Globals

Authorizations of Globals are provided the same way as Collections

🌠 Endpoints

Authorizations of Endpoints are provided by prepending check functions in the handler function arrays. The check functions basically do the same as those access functions mentioned above, in which case the verbs are determined by the endpoint's http method as such:

{
  post: "create",
  connect: "read",
  options: "read",
  head: "read",
  get: "read",
  put: "update",
  patch: "update",
  delete: "delete",
}

✏️ Note


Note You can also choose to skip the authorization for specific collections, globals or some of their fields or endpoints by assign the custom.warding.should to false or custom.warding.should.[verb] flags of corresponding verbs to false.


Alternatively, if an access function is customly assigned in collections, globals or fields, the authorization will always be skipped but a plugin generated authorization function req.context.warding will be attached to the access function argument. So that plugin users can decide how and when to call the plugin generated authorization function.


The custom.warding.should and custom.warding.should.[verb] flags assigned in fields or endpoints can override those assigned in their corresponding collections and globals.


The plugin generated authorization function req.context.warding will always be attached to the handler function's argument when endpoints have the custom.warding.should flag or custom.warding.should.[verb] flags assigned to false.