Should I validate get parameter with mongoose - javascript

In my routing I have get request:
router.get('/getOne', auth(), mapController.getOne);
I'm passing id parameter in url and doing mongo query with mongoose in mapController like this:
exports.getOne = async(req, res, next) => {
try {
const mapData = await Map.findById(req.query.id);
res.json(mapData);
} catch (e) {
return next(e);
}
};
previously I was working with PHP where we were escaping parameters to avoid sql injection. Here I'm not doing anything similiar I just pass req.query.id straight to findById method. Is everything okey with above code when it comes to security?

In this case Mongoose would detect that you are passing a string and internally would try to convert it to mongodb ObjectId. If that fails it would not run the query. The error you would get is:
UnhandledPromiseRejectionWarning: CastError: Cast to ObjectId failed
for value "VALUE HERE" at path "_id" for model "Map"
So as you see you either pass an actual mongoDb ObjectId or a valid string which can be casted to one. Anything else would produce a CastError by Mongoose.

Related

Type 'number' has no properties in common with type 'FindOneOptions<Client>'

While creating a findOne request using typeorm i get this error, HELP!
According to the TypeORM docs you need to call findOne like this (assuming clientId is also the name of the column in the Client table).
const client = await Client.findOne({
where: {
clientId: clientId
}
});
The error message is telling you that it is expecting a FindOneOptions<Client> but you are giving it a number instead.

Return (send) int with express js

If I do this with Express it fails:
res.send(13245)
It says:
express deprecated res.send(status): Use res.sendStatus(status) instead src/x.js:38:9
(node:25549) UnhandledPromiseRejectionWarning: RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: 13245
It's because it consider 13245 might be a status code.
I want to return 13245 anyway, is there a way do do this?
You have to return a String (see http://expressjs.com/en/api.html#res.send):
res.send('13245')
If you check documentation http://expressjs.com/en/api.html#res.send, the value just can be a Buffer object, a String, an object, or an Array. What if you send
res.send({ value: 13245 })
and then in the other side you just need to grab the value (e.g. body.value).
You can try res.send('13245'); or you can try res.send(""+13245).
You are getting that error because Express assumes you are trying to send a status code. So you can send it as a string and Express will accept it or join it to a string and Express should think you are sending back just some plain number and yes always check the docs when you run into trouble:
http://expressjs.com/en/api.html#res.send
let say you are doing a calculation and you wanna send the result.
app.post("/transaction", (req, res) => {
const a = req.body.amount;
const b = req.body.price;
const total = a*b;
res.send(total.toString());
});

Create a new field inside a JSON

I'm using the combo Express (Node.js) and Mongoose to make a REST API. I'm trying to make the login using a JWT token but I've got a problem. When I execute the following code
const mongoose = require('mongoose');
const User = mongoose.model('User');
// other code
_api.post('/login', function (req, res) {
const data = req.body;
// some data control
User.findOne({ username: data.username}, function(err, doc) {
if (hash(password) == doc.password) { // password check
myToken = generateToken(); // generating the token
doc.jwtToken = myToken; // including the generated token to the response
res.status(200).json(doc); // return the final JSON to client
}
}
}
the final JSON returned by the API doesn't have the field "jwtToken":"mygeneratedtoken" and this is strange. I included other times new fields inside a JSON with the same syntax and it worked. I tried to use a tmp variable to which I assigned the doc content (that is a javascript object) and then I added the jwtToken filed and return the tmp variable. But nothing.
Can someone explain me if there is something wrong with my code or if there is something that I need to know?
Documents returned by mongoose are immutable, and thus assignment to doc.jwtToken does not modify the object. You can either use the lean method to modify the query, or toObject to convert the document to a regular javascript object. Try:
var docObject = doc.toObject();
docObject.jwtToken = myToken;
res.status(200).json(docObject);

MongoDB Error: Cannot create property '_id' on string

I'm using Node.js and Express on Heroku, with the MongoDB addon.
My database connection works fine and I can successfully push some data in, but not other.
Here is the database connection:
mongodb.MongoClient.connect(mongoURI, function (err, database) {
if (err) {
console.log(err);
process.exit(1);
}
// Save database object from the callback for reuse.
db = database;
console.log("Database connection ready");
// Initialize the app.
var server = app.listen(process.env.PORT || dbport, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
});
I can successfully push my Twitter API response into the database like this:
db.collection(TWEETS_COLLECTION).insert(data);
('data' is just a JSON variable)
But when I try to push another JSON variable into the database in the same method, I get an error. Code:
var jsonHash = '{"hashtag":"","popularity":1}';
var objHash = JSON.parse(jsonHash);
objHash.hashtag = req.body.hashtag;
JSON.stringify(objHash);
collection(HASHTAG_COLLECTION).insert(jsonHash);
And the error:
TypeError: Cannot create property '_id' on string '{"hashtag":"myhash","popularity":1}'
at Collection.insertMany...
...
Any ideas what I'm doing wrong?
I don't know where you are getting the jsonHash variable from but I think you are doing unecessary JSON-handling here. You are also inserting the wrong variable, you want to insert objHash which is a valid object to insert, now you are inserting jsonHash which is just a string. JSON.stringify(objHash); is not doing anything as you are not saving the JSON returned from the function. I think you want something like this?
var objHash = {
hashtag: "",
popularity:1
};
objHash.hashtag = req.body.hashtag;
collection(HASHTAG_COLLECTION).insert(objHash);
jsonHash is still a string. May be you want to save objHash instead without JSON.stringify ?

Updating document within find

I'm having issues updating a document from within a find using Mongoose. The issue is only when I attempt to overwrite the document with an object (e.g doc = req.body). I am however able to directly set properties of the original document to a specific string (e.g. doc.name = 'jason borne';).
I've verified that res.body is an object, so I don't see why I'm unable to set it this way.
Client.findById(req.params.client_id, function (err, client) {
if (err)
return next(new restify.InternalError(err));
// client.name = 'jason borne';
client = req.body;
client.save(function(err) {
if (err)
return next(new restify.InternalError(err));
res.send(client);
});
});
When attempting to set the doc to an object, I receive the error:
TypeError: Object # has no method 'save'
I'm aware that I can do an update with a simple Client.update(...) command, however this method does not allow my schema middleware or validation to run (which is notated in the Mongoose documentation).
Any thoughts? I'm new to Node, and Mongoose.
You need to use something like underscore's extend method to copy the properties of req.body into the client object instead of just re-pointing client to req.body as you are now.
var _ = require('underscore');
Client.findById(req.params.client_id, function (err, client) {
if (err)
return next(new restify.InternalError(err));
_.extend(client, req.body);
client.save(function(err) {
if (err)
return next(new restify.InternalError(err));
res.send(client);
});
});
The symptoms you're now getting are caused by the fact that you're replacing a mogoose model object (with methods like save, find, etc), by a simple json object parsed from your body, which is missing save.
Try doing an update instead of find/save.
Client.update({_id: req.params.client_id}, {$set : req.body}, function(err) {...});
Or try to merge your req.body to the client object.

Categories

Resources