Catching parameters in query string at NodeJs simple mock - javascript

I'm working on a simple mock server, and am using nothing but JavaScript and Yarn to build it.
In a simplistic manner, I have this that's working as intended:
function server() {
(...)
return {
users: generate(userGenerator, 150)
}
This is generating 150 random users, when the /users endpoint is reached, and it's working as intended. The issue I'm having is with catching id's passed on the query string. ie:
/users/{id}/attribute
How can I get this to work?
Many thanks in advance

try req.params.id
app.get('/users/:id/attribute', function(req, res) {
console.log('id : ' + req.params.id);
...
});

Related

Is this a secure enough method to recover data?

I'd love to know if this method I'm using is secure enough to use on a public project, since I can't really find any other way to retrieve my id from my currently logged in user, but it's a fairly straightforward method , I find. If this method is not secure would it be possible to have a way to proceed? Thanks in advance.
I have a button for example when I use the send of the html that there is inside my div userid on the server to then use this information to make SQL queries from my app.js server.
I use socket.io hbs express node js jwt mysql
From my pages.js file generated with the express library where the main roads of my website are located, I send my user ID.
router.get('/accueil', authController.isLoggedIn, (req, res) => {
if(req.user) {
res.render('./accueil', {
data: req.user.id
});
} else {
res.redirect('/');
}
});
With Handlebars I display this data in my index.hbs (display: none;).
<div id="iduser">{{data}}</div>
Then I get my iduser div on my client.js
let userid = document.getElementById('iduser').innerHTML;
// (My method to display this div)
socket.on('uid', (data) => {
pargent.innerHTML = JSON.stringify(data.data[0].argent);
})
//
So I want to use this userid variable to make SQL queries from my app.js.
(let userid = document.getElementById('iduser').innerHTML;)
I am using socket.io for communication between client and server to send my userid data
Example :
db.query('UPDATE users SET money = money + ? WHERE id = ?', [100, theUserId]);
No
Never trust user supplied data.
References:
https://www.oreilly.com/library/view/http-developers-handbook/0672324547/0672324547_ch22lev1sec1.html
https://flylib.com/books/en/1.290.1.90/1/
https://www.garybell.co.uk/never-trust-user-input/
https://medium.com/#berniedurfee/never-trust-a-client-not-even-your-own-2de342723674
https://www.invicti.com/blog/web-security/input-validation-errors-root-of-all-evil/
https://laravel-news.com/never-trust-your-users
https://www.wearenova.co.uk/nova-blog/when-it-comes-to-online-security-why-you-should-never-trust-a-client
It depends on your authController.isLoggedIn logic,
But I would like to suggest an alternative solution simple as that;
iron-session
Read their docs, it's matches your use case and easy to use; here is equivalent of the snippet you provided with iron session:
//initiate session middleware yourself
router.use(session)
// later here
router.get('/accueil', (req, res) => {
if(req.session.user) {
res.render('./accueil', {
data: req.user.id
});
} else {
res.redirect('/');
}
});

Snipcart - error: 'product-crawling-failed'

I'm trying to set up Snipcart for the first time. It seems pretty straightforward for the most part, but I'm running into some issues when I try to check out with the test payment card.
I'm working with just a vanilla front end, and Express on the back. I'm getting the same error every time:
A 'cart-confirmation' error occurred in Snipcart.
Reason: 'product-crawling-failed'
But the URL it's returning me in my console looks like it should be able to crawl for the product properly: https://myHerokuApp.herokuapp.com/shop/starry-night
<button class="snipcart-add-item"
data-item-id="starry-night"
data-item-price="79.99"
data-item-url="/shop/starry-night"
data-item-description="This is a sweet piece of art."
data-item-image="img/1.jpg"
data-item-name="The Starry Night">
Add to cart
</button>
I'm really confused at to what I'm doing wrong. Is there something I have to do with my express router? I've tried routing something like this just to see what would happen
router.get("/shop/:product", function (req, res, next) {
res.json({
"data-item-id": "starry-night",
"data-item-price": "79.99",
"data-item-url": "/shop/starry-night"
})
});
But that didn't make a difference.
I'm really hoping someone can spot what I'm doing wrong or point me in the right direction in the docs..
Thank you!
Attributes data-item-id and data-item-price are used with HTML crawler and are defined inside buy-button.
If you want to use JSON crawler, then you should return valid JSON with properties id and price. Also, price should be of type number. Change your backed like this:
router.get("/shop/:product", function (req, res, next) {
res.json({
"id": "starry-night",
"price": 79.99
})
});
Note: your server must be publicly available (not running in your localhost).

How to fix deleteOne() function of a mongoose model when it does not delete by req.params.id?

Firstly to be mentioned, I'm absolutely new to Node.Js and MongoDB.
I'm coding a back end API with Node.Js and MongoDB which will deal with GET, POST, DELETE requests from the front end, quite simple stuff.
I'm stuck while working with DELETE functionality.
Here is my posts.service.ts file contains this deletePost() function which sends the postId to the back end app.js file.
`
deletePost(postId: string) {
this.http.delete('http://localhost:3000/api/posts/' + postId)
.subscribe(() => {
console.log(postId);
console.log('Deleted');
});
}
`
I have added this console.log(postId) to check whether it is actually containing the actual postId and found that it does. I have also matched it with the real Id in MongoDB by checking through mongo shell.
Here is the delete() function in the back end app.js file that should do the actual task.
`
app.delete("/api/posts/:id", (req, res, next) => {
Post.deleteOne({ _id: req.params.id }).then(result => {
console.log(result);
res.status(200).json({message: "Post deleted"});
});
});
`
The console.log(result) line should print some result in the terminal, but it does not, so does not it delete the collection in the DB.
I`m running this on an Ubuntu 16.04 LTS pc.
Some clue would mean great help. Thank you very much for your kind effort.
deleteOne doesn't return the deleted document. It always deletes the first matching document and return the number of documents deleted with the boolean value.
From the mongodb docs deleteOne:
Returns:
A document containing: A boolean acknowledged as true if the operation ran with write concern or false if write concern was
disabled
deletedCount containing the number of deleted documents
From the mongoose docs
Deletes the first document that matches conditions from the
collection. Behaves like remove(), but deletes at most one document
regardless of the single option.
I was facing exactly the same, i solved returning the deleteOne promise object and then using the .then property of the promise.
Something like this:
Model.js
...
bicicleSchema.statics.deleteById= function(id, cb){
return this.deleteOne({code: id}, cb);
};
...
module.exports = mongoose.model('Bicicle', bicicleSchema);
Service.js
var Bicicle = require('../../../model/bicicle');
...
const id = req.params.id;
Bicicle.deleteById(id).then(()=>{
//your code
});
...

Error with get request for users

When using a get request for all the users in my database (see code below) i only get the "first" user in the database. If i instead try to use the "findOne"-method i get the same user as before no matter what i put in (the username doesn't even have to be in the db it still gives me the same user). I've been trying to understand why this isn't working but can't find any problems with the code. Could it be a problem with db settings or something similar? All help is appreciated!
In AuthController:
// Get all users
AuthController.allusers = function(req, res) {
User.find({}, function(err, users) {
}).then(function(users) {
res.json({users: users});
});
}
In routes:
// GET Routes.
router.get('/users', AuthController.allusers);
Since you are using Sequelizejs, you might want to do findAll.
AuthController.allusers = function(req, res) {
User.findAll().then(function (users) {
res.send({users: users});
}
}
According to the docs:
find - Search for one specific element in the database
findAll - Search for multiple elements in the database

'or' query with different data types in sails.js

Given routes
GET /user/42
GET /user/dude
where 42 is user id and dude is username.
So, I want to have method in my controller that return user for both cases. Here it is:
// api/controllers/UserController.js
findOne: function(req, res) {
User.findOne({
or: [
{id: req.params.id},
{username: req.params.id}
]
}).exec(function(err, user) {
if (err) {
return console.log(err);
}
res.json(user);
});
},
When I try to GET /user/42 everything is fine.
When I try to GET /user/dude I get error:
Error (E_UNKNOWN) :: Encountered an unexpected error
error: invalid input syntax for integer: "dude"
It seems like sails refuses to process {id: 'dude'} because of type mismatch.
I am using sails 0.10.5 with sails-postgresql 0.10.9. So what am I doing wrong?
UPD: I do know how to solve problem. Of course I can put if statement to my controller and check what type of parameter it got. Actually, I just created two routes with regexp parameters that point to single method.
My actual problem is why I can not do this with or. Does sails provide such way?
By default, sails get method only supports id numbers. You will need
to define custom routes and implement the relevant api method to
support a get request using a string instead of a number.
Technical Details:
To solve your exact problem, you need to define the following route in your routes.js
module.exports.routes = {
...
'/user/get/:param': 'UserController.findByIDorName',
...
}
This will pass anything after the /user/get/ as the parameter named 'param' to the findByIDorName controller method.
Next you need to check the type of the param and decide if you want to fetch the user info based on the id or the name, so add this function in your userController.js
findByIDorName : function (req, res) {
if (isNaN(req.param)){
//find the user by his username after any validation you need
}
else {
//find the user by his id and return
}
}

Categories