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

mongoose-context-protected-plugin

v0.1.1

Published

mongoose-context-protected-plugin =================================

Downloads

12

Readme

mongoose-context-protected-plugin

Circle CI Build Status

##Which applications would this apply to?

Often mongoose/express apps start with CRUD routes being a super thin wrapper around database operations. Then to add access control, you might do checks in your route handlers. This is all well and good until you have lots of routes all operating on the same models. Perhaps on top of that you allow different types of users access to different parts of the model? This is an attempt to push the access control all the way down onto the models, so when you operate on them, you just provide the context that you're doing it in (on behalf of "John" for instance), and let the model sort it out.

If you think that "fat model/skinny controller" is a load of rubbish, you're not going to be a fan of this plugin.

##What problem does this solve? Rather than calling save or toObject/toJSON on your model, two alternatives, contextProtectedRead/contextProtectedWrite are exposed that take into account the context (generally the user that is requesting the change). This is generally useful when performing an action on the model because of an api call made from a user.

##Usage

####schema attribute canRead/canWrite -> boolean/function that resolves/returns a boolean These functions are options that you set on your mongoose model attributes, that are passed a context, and are expected to return a boolean, depending on whether the action is allowed on the attribute. this can also be used, and is the document being edited.

var TestSchema = new Schema({
    implicit: {
        type: String
        // canRead defaults to true when not specified
        // canWrite defaults to false when not specified
    },
    truthy: {
        type: String,
        canRead: true, // regardless of context, contextProtectedRead will return this value
        canWrite: true // regardless of context, contextProtectedWrite will allow writes to this attribute
    },
    falsy: {
        type: String,
        canRead: false, // regardless of context, contextProtectedRead will NOT return this value
        canWrite: false // regardless of context, contextProtectedWrite will NOT allow writes to this attribute
    },
    func: {
        type: String,
        canRead: function (user) {
            // allow the test to dictate whether this should be allowed or not
            return user.name === 'Patrick';
        },
        canWrite: function (user) {
            // if `this` had a owner field, you could compare user with this.owner
            // if only the document owner could write to this field
            return Q.resolve(user.name === 'Daniel');
        }
    }
});

TestSchema.plugin(require('mongoose-context-protected-plugin'));

####doc.contextProtectedRead (context) -> Q promise

Resolves to a JSON object, similar to what you might expect from toObject/toJSON, but only returns the values that are appropriate, depending on which context is provided. Will return just the fields where canRead was either not specified, equal to true, or returned true.

// using an instance of TestSchema defined above
user.name = 'Patrick';
test.contextProtectedRead(user);
/** -> resolved promise
  {
    implicit: XXX,
    truthy: XXX,
    func: XXX
  }
**/

####doc.contextProtectedWrite (context, attrs) -> Q promise

Returns a promise, which resolves with the object if successful. If any attribute's canWrite is not specified, equals, or returns false, the promise will reject with an error describing why the write was not allowed.

Failure case

// using an instance of TestSchema defined above
user.name = 'Patrick';
test.contextProtectedWrite(user, {
    implicit: XXX, // will fail because canWrite was not specified
    falsy: XXX, // will fail because canWrite === false
    func: XXX // will fail because name wasn't 'Daniel'
}); // -> rejected promise
// using an instance of TestSchema defined above
user.name = 'Daniel';
test.contextProtectedWrite(user, {
    truthy: XXX, // will succeed because canWrite === true
    func: XXX // will succeed because user.name === 'Daniel'
}); // -> resolved promise