Pre-populating HTML/Jade from Express/node.js web app - html

I have a web app that is built using Express for node.js. I'm using Jade template files for the HTML displays. In one of these displays I'd like to have the various fields pre-populated with data. The data is being stored in a mongodb session store, as well as in a separate collection in the db. I'd prefer to use the session data to pre-populate these fields in the HTML/Jade displays. How can I go about doing this (if it's possible)?

Add the defaults to res.locals and then set the input elements value attribute in jade.
//node.js
app.get('/', function(req, res){
// Sorry I am unfamiliar with Mongo, not sure the syntax...
mongo.get('defaults', function(err, body){
res.locals.dName = body.defaultName;
res.locals.dFoo = body.defaultFoo;
res.render('myTemplate');
});
});
//myTemplate.jade
!!!
html
body
form(action='/form', method='post')
input#formName(name='name', value=locals.dName)
input#formFoo(name='foo', value=locals.dFoo)

I figured it out by using res.render() from the Express API to do this. I will credit Plato with the answer though because his also seems to be correct and he's a nice man for answering my question.
exports.viewProfile = function(req, res) {
res.render('viewProfile', {username: req.session.user, firstname: req.session.firstname});
}

Related

Is it not proper to use the send method to return HTML? Express

I am playing with express, in the past I have used echo with PHP to render out lines of html. In node/express I can add html to a variable and use res.send to return html. That way I can run loops and other things right in the function returning that route. Is this method bad practice? Below I have an example that counts to four.
var router = express.Router();
let a = (req, res, next) => {
let send = `<html>`;
for (let i = 0; i < 5; i++) {
send += `${i}`;
}
send += `</html>`;
res.send(send);
//res.download(filepath)
}
router.get('/', [a]);
module.exports = router;
I think this is a way to go about express router but it's probably not the easiest and it would cause a lot of code on your router page. It all depends on how large and scalable you want your project to be. If you are looking at doing a smaller project then this would work but if you were doing something a little larger e.g. e-commerce site then I would say put your html files in a separate folder and create a views directory for express. I would also suggest using an open source JavaScript Framework such as ReactJS, Vue, or ejs to name a few. You would have to do more code to your express server by adding views as seen in this link
Adding views in express
So instead of sending the html you would do something like res.render('/home'); if that is what you called your home page in your views file.
If that didn't answer your question please let me know.

Unable to access cookie in nodeJS after redirected from HTML page

I'm trying to make a post call via an html page. On 2nd application, i'm trying to access a cookie named cookie_test (can be set manually or via code in browser).
Under Application tab(Storage --> cookies), i'm able to see the cookie, but somehow i'm getting undefined in console log when trying to access it from 2nd application (refer 2nd code).
browser cookie screenshot
Application One (test.html is the only file in it & i'm trying to make a post call)
<form action="http://localhost:3000/page-two" method="POST">
<input type="submit" value="Go to P2">
</form>
Application Two (NodeJS/Express:
index.js)
var express = require('express');
var router = express.Router();
router.post('/', function (req, res, next) {
console.log("COOKIE-TEST::::::", req.cookies.cookie_test)
res.render("page_two", { cookie_data: req.cookies.cookie_test });
});
module.exports = router;
Note: Within node application, cookies are accessible & works as expected. Issues seems to happen during redirection.
I was able to solve the issue by setting the cookie parameters as secure(true) & sameSite(none). Make sure to use latest version of express for sameSite property. This setting allowed my 2nd application to access it's cookies, irrespective of getting redirected from any source (in my case Application one).
A couple of things to check.
First, your nodejs app needs the cookie-parser middleware if it is to receive any cookies from users' browsers. It looks like this.
var cookieParser = require('cookie-parser')
...
var express = require('express')
express.use(cookieParser())
...
You didn't mention how you set the cookie from your post route. You would do that like this with a call to res.cookie():
router.post('/', function (req, res, next) {
console.log("COOKIE-TEST::::::", req.cookies.cookie_test)
const testCookieVal = req.cookies.cookie_test || 'some default value'
res.cookie('cookie_test', testCookieVal)
res.render("page_two", { cookie_data: someCookieVal })
});
It's not clear how you set the cookie you're trying to retrieve in your post route. You should understand that your Application One html file is served from the file:// origin, and Application Two is served from the https://localhost:3000 origin. Browsers never send cookies associated with web pages served from one origin in requests to other origins.

Csrf fix in node js at page level

I looked at csrf implementation in node js Git hub example and was wondering this is for a application level. What if I want to apply it on one or two pages in the application. I did not find any example on the web. I know that in asp.net you can do it but not sure how the same can be achieved in Node JS.
Any help in guiding to a solution is greatly appreciated.
Add the csruf middleware on the routes which you want to protect. Like the example in the Github link shows:
app.get('/route/to/protect', csrfProtection, function (req, res) {
// pass the csrfToken to the view
res.render('send', { csrfToken: req.csrfToken() })
})
This will allow csrf only for this route and not others. You can also use Regex to match routes as explained in the express docs.

Serving Dynamic Webpages with Node.js

I am having a hard time understanding how exactly node.js serves dynamic content.
So let's say we have the following code that renders a home page:
var express = require('express'),
app = express();
app.get('/', function(req,res){
res.render('home.html');
});
However, let's say this home page was supposed to be a user profile in which you are pulling user information from a database, which results in code:
var express = require('express'),
mongoose = require('mongoose'),
app = express();
mongoose.connect('mongodb://localhost/ExampleDB');
app.get('/:id', function(req,res){
User.findOne({_id: req.id}, function (err, user){
var name = user.name;
var profilePic_uri = user.profilePic_uri;
res.render('home.html');
});
So, ideally home.html is just a template page, in which you set maybe the user's profile picture, their name, etc in the route handler. Right, because the idea behind node, is that this app.js should be able to handle pulling the dynamic content from a database at run time. Where I am having trouble is understanding how exactly rendering dynamic pages work with node. The html page is a static page. You can't really render a php or a asp page because, well, that doesn't really make sense does it?
Which leaves me with the question, how is it done?
If you add...
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
...after app=express() has been done then it will now default to the Jade rendering engine if you don't use an extension. Then in your router:
app.get('/', function(req,res){
res.render('home', {
var1: 'val1',
var2: 'val2'
});
});
You'd need to add Jade to your project's package.json file in the dependencies:
"jade": "~1.9.1",
...and then "npm install" in your folder to bring that in.
Then you'd need a file named /views/home.jade with the contents:
doctype html
html
body
p Var1 is #{var1}
p Var2 is #{var2}
You should see--when you visit your home page--that the values have been passed to the Jade rendering engine and expanded in place in the template as 'val1' and 'val2', respectively.
In your case the page is static. Here comes in play template engines (view engines), with this you can render the content of the page dynamic.
Some of the template engines that I remember right now are vash (it's like razor syntax from MVC, I love it) and jade. There are more of them.
Note: You can find in the links I provided how to integrate them with express.
What you are actually asking is not, how it works in Node, but how Express renders templates. Once you understand that you're actually using a feature of the express module, you're probably more aware of what you need to search for to get the correct documentation.
In short: Express features a template rendering engine that does the job for you, very much similar to what ASP or PHP do.
To get to know Node, I'd advise to try to build something without all the libraries first, just to get to know the platform, and to understand why it's feasible to use such libraries or frameworks (such as express).

Keeping a user logged in with nodeJS

I have a login system with my NodeJS using mysql-node.
The problem i have how ever is how to keep the user logged in, if they refresh the page they have to login again, because i do not know how to store the session.
My login system is like this:
socket.on('login', function(data,callBack){
var username = sanitize(data['login']).escape(),
pass = sanitize(data['password']).escape();
var query = connection.query('SELECT uid FROM users WHERE name = ? AND pass = ?', [username,pass],
function(err,results){
if(err){
console.log('Oh No! '+err);
} else if(results.length == 1){
//some how set a session here
} else if(!results.length) {
console.log('No rows found!');
}
});
});
I'm having difficulty understanding how i set up a session for each client that connects. Is this possible with NodeJS ?
Reading that they assign express to var app but if i already have this : var app = http.createServer( ... how can i also assign express to it :S bit confusing
You need to understand the difference between a express' server and a native NodeJS' server, here my link comparaison nodejs server vs express server
So you can do:
var app = express();
var server = http.createServer(app);
This enable you to have still the low level functionnaly with NodeJS.
So, if you don't want to use existing modules or framework, you can build your own session manager:
using cookie
using IP/UA
using socket
The best way would be first to implement it with socket, for example:
server.on('connection', function (socket) {
socket.id = id;
});
or
server.on('request', function (req, res) {
req.connection.id = id; // The socket can also be accessed at request.connection.
});
So, you just need to implement a middleware who check the id.
If you want to prevent from session prediction, session sidejacking, etc. you need to combine cookies, ip, socket, and your ideas to make it more secure for your app.
Once you've done your session manager, you can choose where to store the sessions, in a simple object, in redis, in mongodb, in mysql ... (express use MemoryStore by default, but maybe not now)
I don't have an idea if nodejs has core feature of saving sessions. you need to use a database along with it. using Express will help you to utilized a database to persist user sessions. You better study and use it
http://expressjs.com/
http://blog.modulus.io/nodejs-and-express-sessions
I don't think there is any session mechanism within Nodejs' core. However, they are plenty of libraries that would allow you to do it. The first that comes to mind is Connect's session, which is a middleware for Nodejs. Have a look at this question for more details on how to use it.
Have a look at this tutorial from dailyjs which tries to include Express's session into a notepad webapp. The source code is available here. (Note that Express' session is based on Connect's, and is practically the same).
EDIT: Here is a more complete example for Node authentication, using mongoose. They do however show their schemas, so I assume you can easily do the transition to MySQL.