mongoose-hidden
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)
npm install --save mongoose-hidden
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 } });
[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.
[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.
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.
-
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.
-
Implement turning on and off on a single invocation (if possible). Something like this:
var jsonUser = user.toJSON({ hide: false });