/mongoose-hidden

A Mongoose schema plugin for filtering properties you usually do not want to sent client-side like passwords and ids

Primary LanguageJavaScript

mongoose-hidden

build status Coverage Status NPM version Get help on Codementor Join the chat at https://gitter.im/mblarsen/mongoose-hidden

Beerpay Beerpay

A Mongoose schema plugin that hooks into toJSON() and toObject() to allow hiding of properties you usually do not want to sent client-side.

(Note: always check github for most up-to-date documentation)

Install

npm install --save mongoose-hidden

Usage

First setup a schema and attach the plugin:

var mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    mongooseHidden = require('mongoose-hidden')();

var UserSchema = new Schema(
    name: String,
    password: { type: String, hide: true },
    email: String
);

UserSchema.plugin(mongooseHidden);

Now let's create a model:

var User = mongoose.model('User', UserSchema);
var user = new User({ name: "Joe", email: "joe@example.com", password: "secret" });
user.save(function() {
    var jsonUser = user.toJSON();
    console.log(jsonUser);
});

Outputs to the console the user without password:

{ name: "Joe", email: "joe@example.com" }

In stead of hide: true you can specify the property to only be hidden for toJSON() or toObject() be writing: hideJSON: true or hideObject respectively.

Optionally you can use a function object for hide, hideJSON and hideObject. The function has the following signature and must return true if the property should be hidden:

function (doc, ret) {
    // return true to filter
}

The parameters doc and ret are passed in from the transform function. See toJSON() and toObject() in the Mongoose documentation.

Default Hidden

By default _id and __v properties are hidden automatically. You can override this behaviour, when you load the plugin:

var mongooseHidden = require("mongoose-hidden")({ defaultHidden: { password: true } });
UserSchema.plugin(mongooseHidden);

Now only password will be hidden. Note: You don't need to specify hide: true in the schema.

A more practical example is illustrated here passing the settings to your models:

// file: app.js
var modelConfig = { defaultHidden: { password: true } };
require ('./models/user')(modelConfig);

// file: models/user.js
module.exports = function (config) {
    var mongooseHidden = require('mongoose-hidden')(config);
    var schema = new Schema( ... schema stuff ... );
    schema.plugin(mongooseHidden);
    ... profit! ...
};

A different way to configure default hidden properties, is when applying the plugin to the schema:

UserSchema.plugin(mongooseHidden, { defaultHidden: { password: true } });

Doing it this way instead of adding it to the schema directly allows you to conditionally hide properties. E.g.

if (app === 'web') {
    UserSchema.plugin(mongooseHidden, { defaultHidden: { "_id": true, password: true } });
} else if (app == 'private-api') {
    UserSchema.plugin(mongooseHidden, { defaultHidden: { password: true } });
} else {
    UserSchema.plugin(mongooseHidden);
}

So depending on the app using the model, different properties would be hidden.

Note: you can change the default behaviour for this defaultHidden properties by using autoHideJSON and autoHideObject in the same way (but only when instantiating the module):

var mongooseHidden = require("mongoose-hidden")({ autoHideObject: false });

What this does, is that when you invoke toObject() the default hidden properties will no longer be exclude, but they will when invoking toJSON().

Hidden

[since 0.7.0]

The hidden option will add to the defaultHidden.

By default _id and __v properties are hidden automatically as seen above. The example shown (duplicated from above) sets password hidden, but now _id and __v are returned.

var mongooseHidden = require("mongoose-hidden")({ defaultHidden: { password: true } });
UserSchema.plugin(mongooseHidden);

Using hidden allows you to keep whatever is the default and modify that setting:

var mongooseHidden = require("mongoose-hidden")(); // _id, __v hidden
UserSchema.plugin(mongooseHidden, { hidden: { _id: false, password: true } }); // adds, password and unhides _id

or

var mongooseHidden = require("mongoose-hidden")({ hidden: { password: true } });
UserSchema.plugin(mongooseHidden, { hidden: { _id: false } });  // unhides _id, password is hidden

UnsecureUserSchema.plugin(mongooseHidden, { hidden: { password: false } });

Virtuals

[since 0.3.1]

Hiding of virtuals can be done as well.

// By default in Mongoose virtuals will not be included. Turn on before enabling plugin.
schema.set('toJSON', { virtuals: true });
schema.set('toObject', { virtuals: true });

// Enable plugin
schema.plugin(mongooseHidden, { virtuals: { fullname: 'hideJSON' }});

Be sure to include the plugin after you turn on virtuals.

The value of the virtuals key can be: hide, hideJSON and hideObject, but remember that if you don't turn on virtuals for toObject, fullname in the above example will NOT be hidden, even though it specifies that only JSON is hidden.

Transform

[since 0.6]

The plugin makes use of toJSON() and toObject()'s transform-functionality to hide values. You can set a transform function prior to applying the plugin. The plugin will then invoke that function before hiding properties.

var mongooseHidden = require("mongoose-hidden")({ defaultHidden: { password: true } });

// First define transform function
UserSchema.set('toJSON', { transform: function (doc, ret, opt) {
    ret["name"] = "Mr " + ret["name"];
    return ret;
}});

// Then apply plugin
UserSchema.plugin(mongooseHidden);

All names will now be prefixed with "Mr" and passwords will be hidden of course.

Changes

0.9.0

Another internal rewrite to make the hide-logic more readable.

0.8.0

Internal rewrite to make nested documents and non-schema-values work.

0.7.0

Add hidden option.

0.6.4

Limited dependency version range for should.

0.6.2

Removed lodash dependency.

0.6.1

Fixes Issue #3

0.6.0

New: If a transform has already been set before loading plugin that function will be applied before applying plugin tranforms.

Other: Reduced code size.

0.4.0

Changed: Default virtuals value set to { } meaning id will no longer be hidden by default.

0.3.2

Fixed: id virtual was included by mistake in 0.3.1.

0.3.1

New: Introduced hiding of virtuals.

0.3.0

Changed: require("mongoose-hidden") is now require("mongoose-hidden")(defaults) with optional defaults.

Limitations

  • Always set { getters: true, virtuals: true } before installing plugin:

    schema.set('toJSON', { getters: true, virtuals: true }); schema.plugin(require(mongooseHidden));

  • Recursive use of hide not supported, but nested documents/objects are supported.

TODO

  • Implement turning on and off on a single invocation (if possible). Something like this:

    var jsonUser = user.toJSON({ hide: false });