Search code examples
node.jsexpressmongooseserver-side-renderingexpress-handlebars

Express Handlebars Won't Render Data


I am working with NodeJS and Express using Express-Handlebars template engine.

Handlebars is throwing the following error when trying to render a template:

Handlebars: Access has been denied to resolve the property "username" because it is not an "own property" of its parent. You can add a runtime option to disable the check or this warning: See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details

According to the above link:

From version 4.6.0 on, Handlebars forbids accessing prototype properties and methods of the context object by default. The reason are various security issues that arise from this possibility.

My app.js contains the following:

const exphbs = require('express-handlebars');
const express = require('express');
// Init Express
const app = express();
// VIEW ENGINE
app.engine('handlebars', exphbs({
  defaultLayout: 'main'
}));
app.set('view engine', 'handlebars');

My route file fetches from MongoDB via Mongoose:

//@GET - View
router.get('/', authMiddleware, (req, res, next) => {
  // Mongoose
  Model.find({ user: req.user._id })
    .sort({ date: -1 })
    .then(model => {
      res.render('/overview', { model: model })
    })
    .catch(err => {
      if (err) throw err;
      req.flash('error_msg', 'No Model Found');
    })

})

model is an array of objects

This issue only started happening after I began to mess around with adding handlebar helpers. I have removed the helpers and reverted to my original configuration settings (above) to no avail. I've tried deleting node_modules folder and reinstalling npm.

What's being sent is an array of objects, and I am trying to loop over the properties of the objects using the {{#each model}} helper and reference the individual properties via {{prop1}} within the each.

According to Handlebars, this disabling of proto properties is false by default, and this change shouldn't break anything.

My question:

  1. Am I sending data to handlebars incorrectly? If so, what is the correct method (not exposing my server to security holes) to send data to the express-handlebars template for rendering?

Thank you in advance.


Solution

  • Correct! I used to work with Sequelize and toJSON() did the trick.

    If you tried it already and it didn't work, I think the same result in Mongoose could be achieved by using lean – mas 2 hours ago

    I added .lean between .sort() and .then(), This worked!