I want to remove all malicious data input from my express api requests?
how I sensitize data
"use strict";
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const bodyParser = require("body-parser");
const mongoose = require('mongoose');
require('dotenv').config();
var util= require('util');
var cors = require('cors');
I am using this all package in above code
You can use lodash to do that sanitize process, in the following way.
const _ = require('lodash');
function sanitize(body, values) {
return _.pick(req.body, values);
}
console.log(sanitize(req.body, ['name', 'email', 'password']));
If you are using express you can the following middleware as follow:
const validatorFunc = (values) => {
return (req,res,next) => {
const data = _.pick(req.body, values);
req.body = data;
next();
}
}
please refer to sanitize npm package for your request object
Link: https://www.npmjs.com/package/sanitize
I've got an Express/Mongoose app that keeps throwing "cyclic dependency detected" errors at me. I've localized the problem to one of these files.
app.js
var express = require('express');
var mongoose = require('mongoose');
mongoose.connect('mongodb+srv://username:MY.PASSWORD#cluster0-6vlss.mongodb.net/test?retryWrites=true');
require('./models/Users');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
routes/users.js
var mongoose = require('mongoose');
var express = require('express');
var router = express.Router();
var User = mongoose.model('User');
router.route('/user/:id')
.get((req, res, next) => {
User.findById(req.params.id, (err, user) => {
if (err) return next(err);
res.json(user);
});
});
models/Users.js
var mongoose = require('mongoose');
var UserSchema = mongoose.Schema({
_id: String,
username: {type: String, unique: true},
hash: String,
salt: String,
chats: Array
});
var User = mongoose.model('User', UserSchema);
module.exports = User;
Hopefully I condensed my code well enough. Could somebody point to my screw-up?
Got it. In app.js, dbconfig is an object that stores the database URI string. I called "dbconfig" directly instead of "dbconfig.url". Everything's good now.
app.js :
var index = require('./routes/index2');
var users = require('./routes/users');
app.use('/', index);
app.use('/users', users);
index2.js :
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
when I go to localhost:3000/ I don't see the text in send function
I guess your browser is you waiting for a response?
If you change index2.js to be a function and return the router, you'll be adding it as a middleware with app.use('url', middleware). I hope this helps
app.js
var index = require('./routes/index2');
var users = require('./routes/users');
app.use('/', index()); //Invoke the object to get the router back
app.use('/users', users);
index2.js
var express = require('express');
var router = express.Router();
module.exports = function() {
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
return router;
};
Returning the router from index2 to be used as a middleware
I have defined my route in a separate route.js file as below (details removed for brevity)
var express = require('express');
var router = express.Router();
router.route('')put(function(req, res){
console.log(req.params.id); //prints undefined
});
and in server.js I map this route as below
var route = require('./routes/route.js');
app.use('/api/use/:id/role', route);
My route function is correctly invoked but the id parameter is not available in the router handler. Am I doing anything wrong?
Use the mergeParams option:
var router = express.Router({ mergeParams : true });
Full standalone example:
var express = require('express');
var app = express();
var server = app.listen(3000);
var router = express.Router({ mergeParams : true });
router.route('').get(function(req, res) {
console.log('id', req.params.id);
return res.sendStatus(200);
});
app.use('/api/use/:id/role', router);
I'm trying to create a really simple node API using express.js 4 but I need a few 'realtime' events for which I added socket.io. I'm fairly new to both so I'm likely missing something basic but I can't find good docs/tuts on this.
In the express app (created with the express generator) I have something like this based on simple examples and project docs that I read. This works OK and from client apps, I can send/receive the socket events:
var express = require('express');
var path = require('path');
var logger = require('morgan');
var api = require('./routes/api');
var app = express();
var io = require('socket.io').listen(app.listen(3000));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/api', api);
io.sockets.on('connection', function (socket) {
console.log('client connect');
socket.on('echo', function (data) {
io.sockets.emit('message', data);
});
});
// error handlers omitted
module.exports = app;
but I want to use the sockets from my API routes (in the ./routes/api.js file that I 'require' above). For example, someone might use the API to PUT/POST a resource and I want that broadcast to connected socket.io clients.
I cannot see how to use the 'io' variable or organise the code currently in the io.sockets.on('connection' ... function inside express routes. Here's the ./routes/api.js file:
var express = require('express');
var router = express.Router();
var io = ???;
router.put('/foo', function(req, res) {
/*
do stuff to update the foo resource
...
*/
// now broadcast the updated foo..
io.sockets.emit('update', foo); // how?
});
module.exports = router;
One option is to pass it in to req object.
app.js:
var express = require('express');
var path = require('path');
var logger = require('morgan');
var api = require('./routes/api');
var app = express();
var io = require('socket.io').listen(app.listen(3000));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
io.sockets.on('connection', function (socket) {
console.log('client connect');
socket.on('echo', function (data) {
io.sockets.emit('message', data);
});
});
// Make io accessible to our router
app.use(function(req,res,next){
req.io = io;
next();
});
app.use('/api', api);
// error handlers omitted
module.exports = app;
./routes/api.js:
var express = require('express');
var router = express.Router();
router.put('/foo', function(req, res) {
/*
do stuff to update the foo resource
...
*/
// now broadcast the updated foo..
req.io.sockets.emit('update', foo);
});
module.exports = router;
I've modified your files a little bit, may you check if it works?
You can pass the io you've defined to your routes like below;
require('./routes/api')(app,io);
I didn't test the Socket.IO parts but there is no syntax error and routes also working.
server.js file:
var express = require('express');
var app = express();
var path = require('path');
var logger = require('morgan');
var io = require('socket.io').listen(app.listen(3000));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
io.sockets.on('connection', function (socket) {
console.log('client connect');
socket.on('echo', function (data) {
io.sockets.emit('message', data);
});
});
require('./routes/api')(app,io);
console.log("Server listening at port 3000");
api.js:
module.exports = function(app,io) {
app.put('/foo', function(req, res) {
/*
do stuff to update the foo resource
...
*/
// now broadcast the updated foo..
console.log("PUT OK!");
io.sockets.emit('update'); // how?
res.json({result: "update sent over IO"});
});
}
Supposing you want to access the SocketIO from anywhere in your application, not just in the router, you could create a singleton for it. This is what works for me:
//socket-singletion.js
var socket = require('socket.io');
var SocketSingleton = (function() {
this.io = null;
this.configure = function(server) {
this.io = socket(server);
}
return this;
})();
module.exports = SocketSingleton;
Then, you need to configure it using your server:
//server config file
var SocketSingleton = require('./socket-singleton');
var http = require('http');
var server = http.createServer(app);
SocketSingleton.configure(server); // <--here
server.listen('3000');
Finally, use it wherever you want:
//router/index.js
var express = require('express');
var router = express.Router();
var SocketSingleton = require('../socket-singleton');
/* GET home page. */
router.get('/', function(req, res, next) {
setTimeout(function(){
SocketSingleton.io.emit('news', {msg: 'success!'});
}, 3000);
res.render('index', { title: 'Express' });
});
module.exports = router;
One more option is to use req.app.
app.js
const express = require('express');
const path = require('path');
const logger = require('morgan');
const api = require('./routes/api');
const app = express();
const io = require('socket.io').listen(app.listen(3000));
// Keep the io instance
app.io = io;
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
// ...
app.use('/api', api);
module.exports = app;
routes/api.js
const express = require('express');
const router = express.Router();
router.put('/foo', function(req, res) {
/*
* API
*/
// Broadcast the updated foo..
req.app.io.sockets.emit('update', foo);
});
module.exports = router;
Refactored Edudjr's answer.
Change the singleton to create a new instance of socket.io server
const { Server } = require('socket.io');
const singleton = (() => {
this.configure = (server) => this.io = new Server(server)
return this
})();
module.exports = singleton
Initialise your express app, the server and the singleton.
// initialise app
const app = express();
const server = require('http').createServer(app);
// configure socket.io
socket.configure(server)
Then in your router
const socket = require('/utils/socket-singleton');
socket.io.emit('event', {message: 'your message here'})
I think best way is to set io as a property of req, like below:
app.use(function(req,res,next){
req.io = io;
next();
});
app.use('/your-sub-link', your-router);