On application start, the proxy must be configured to be aware of the involved collections and their events.
Assuming we have a collection of users, we should have the following:
var dbConfig = { port: 27017, host: "localhost", name: "db" } var collectionName = "users" var collectionSchema = { type: "object", required: true, properties: { firstName: { type: "string", required: true }, lastName: { type: "string", required: true }, password: { type: "string", required: true } } }
var dbproxy = require('mongodb-proxy') var db = dbproxy.create(dbConfig) db.configure(function (config) { config.register({ name: collectionName, schema: collectionSchema, events: { get: require('./events/get.js'), post: require('./events/post.js'), put: require('./events/put.js'), validate: require('./events/validate.js'), delete: require('./events/delete.js') } }) })
./events/get.js
Get events are triggered against the resolved data to provide opportunities to halt the retrieve process.
module.exports = function (sender, context, data) { // if the request is not coming from an internal proxy if (!context.internal) // check that the user has permissions on the current store and the current item if(!isUserAuthorised(currentUser, context.store.name, data.id, 'get')) // return Unauthorized return context.error(401, 'Access denied') // hide the password property from the resulted object context.hide('password') // trigger the async callback context.done() }
./events/post.js
Post events are triggered before validation as a last step for the data to be modified or the post process to be halted.
module.exports = function (sender, context, data) { // if the request is not coming from an internal proxy if (!context.internal) // check that the user has permissions on the current store and the current item's parent if(!isUserAuthorised(currentUser, context.store.name, data.parentId, 'post')) // return Unauthorized return context.error(401, 'Access denied') // set defaults data.createdOn = new Date().getTime() // trigger the async callback context.done() }
./events/put.js
Similarly, put events are also triggered before validation as a last step for the data to be modified or the put process to be halted.
module.exports = function (sender, context, data) { // if the request is not coming from an internal proxy if (!context.internal) // check that the user has permissions on the current store and the current item's parent if(!isUserAuthorised(currentUser, context.store.name, data.id, 'put')) // return Unauthorized return context.error(401, 'Access denied') // prevent from changing a field if(context.changed('password')) return context.error(400, 'Cannot change field') // set defaults data.modifiedOn = new Date().getTime() // trigger the async callback context.done() }
./events/validate.js
Validate events are triggered after local post and put actions and before actual post and put actions mostly for schema validation.
The schema registered with the collection, is already validated on a step before this one, so here we should check for extra more specific validations.
module.exports = function (sender, context, data) { // check password length if(data.password.length < 5) return context.error(400, 'Password should be at least 5 characters') // trigger the async callback context.done() }
./events/delete.js
Delete events are similarly triggered before delete actions.
module.exports = function (sender, context, data) { return context.error(401, 'Access denied') }