Why is my [Op.or] only partially working? - javascript

I am trying to write an endpoint for searching for a user with a username or id that matches the passed string. Below is the current code I have set up for an endpoint on localhost at .../api/users/:search.
//GET user by id or password
router.get('/:search', (req, res, next) => {
User.findOne({
where: {
[Op.or]: [
{
id : { [Op.eq]: req.params.search }
},
{
username : { [Op.eq] : req.params.search }
}
]
}
}).then(data => {
res.json(data)
}).catch(next)
});
I believe I've set everything up correctly, but I'm only able to get a response when I pass in an existing id. Example: I have a user with the id "1" and the username "hyena12". If I do a GET on .../api/users/1, it will return the user. But if I do a GET on .../api/users/hyena12, the response just says "error".
I am using Sequelize with Node and am using PostMan to try and test this. Postgres DB is being used on the backend.

Related

Retrieve Authenticate User's Orders

GET method
Use accessToken of an authenticated user.
Only non-admin account can proceed.
User should be able to retrieve his orders only.
Router
router.get("/my-orders", auth.verify, (req, res) => {
const user = auth.decode(req.headers.authorization);
if (!user.isAdmin) {
UserController.getMyOrders(req.body).then(getMine => res.send(getMine));
} else {
return res.status(403).send("Access denied.");
}
});```
Controller
module.exports.getMyOrders = (body) => {
return User.find({}, {
"isAdmin": 0,
"_id": 0,
"password": 0
});
}
I am getting everything. Can someone help me code how to filter the user where the token belongs and retrieve his orders and not able to get other users' orders?
By passing an empty object in your .find method, you are telling mongodb to look for everything. I'm assuming in body you have some data to find a specific user, if so you would use that. eg. if body contains a username, you would write...
module.exports.getMyOrders = (body) => {
return User.find({username: body.username});
}
Here is some more info on db.collection.find()
EDIT - Look up user by JWT:
router.get("/my-orders", auth.verify, (req, res) => {
//Here you have decoded your JWT and saved it as user
const user = auth.decode(req.headers.authorization);
if (!user.isAdmin) {
//here you are passing user instead of req.body
UserController.getMyOrders(user).then(getMine => res.send(getMine));
} else {
return res.status(403).send("Access denied.");
}
});
module.exports.getMyOrders = (user) => {
//now you are using 'username' from the decoded jwt to look up the user
return User.find({username: user.username});
}

Why am I getting, "Undefined binding(s) detected when compiling FIRST."?

I have an app with 3 routes: register, login, and dashboard; with dashboard being a protected route.
Within my dashboard route, I am creating a post request which will retrieve the users information.
In my service file:
//Return a user by ID
const getUserById = (id) =>
knex('users').select('user_name').where({ user_id: id }).first();
In my controller file:
async function create(req, res, next) {
try {
const user = await service.getUserById(req.user);
res.json(user);
} catch (err) {
console.error(err.message);
}
}
I get this error:
Undefined binding(s) detected when compiling FIRST. Undefined column(s): [user_id] query: select "user_name" from "users" where "user_id" = ? limit ?
My table users has 4 columns: user_id, user_name, user_email, and user_password.
What is wrong with my service file or controller file?
Looking from code the req.user must be undefined.
You are passing a user object to the function when it expects an id.
service.getUserById(req.user)
But the function signature is:
const getUserById = (id) => ...

'TypeError: Converting circular structure to JSON' with Express

I use NodeJS and Express for my project and set it when the user login to index will keep the session value.
req.session.user
{ adminID: 3, username: 'admin', password: 'admin' }
And I want to get data from MYSQL so I use Knex like this.
router.get('/profile/user/me', (req, res, next) => {
let user = req.session.user;
if(user) {
try {
let me = req.session.user.adminID;
let info = knex('admin_account').where('adminID', `%${me}%`)
res.json(info)
} catch (e) {
console.log(e);
}
res.sendFile(path.join(__dirname + '/../public/personal_information.html'));
return;
}else{
res.redirect('/');
}
});
In my opinion, I think that if we are finished logging in, we will have a req.session.user I will use it to get data together with Knex.
req.sessions.user and info may have the same value but arent the same type you should, first check the value of your variable info console.log(info), there is a chance that you might need to json.parse() it or json.stringify() it if you want to send it as a response.
You need to execute the query builder and wait for result before returning:
knex('admin_account').where('adminID', me)
.then(info => {
res.json(info)
})
.catch(err => {
console.log(e);
});
And you don't need % wildcards unless you are doing loose string comparison with like operator.
One more thing about the code is that you seem to try to return res.json and also res.sendFile(path.join(__dirname + '/../public/personal_information.html')) at the same time, which doesn't make sense.

How to get data with just inserted data with Sequelize in PostgreSql?

I want to get updated table values after I add user to my "WOD" table. For instance, I have 2 users in my WOD table and after I add third user , I want to return a response to client with I have just inserted data (third guy). But now , I can only return first 2 users because I can not take updated values. Of course I can make another query to get updated table values after I insert, but is there any better solution ? Here is my codes;
const addUser = async (req, res) => {
try {
const { userId, wodId } = req.body;
if (!userId || !wodId) {
res.status(400).send({ status: false, message: 'need userId and wodId' });
}
const wod = await Wod.findByPk(wodId, {
include: [
{
model: User,
as: 'Participants',
through: { attributes: [] }
}
]
});
//check capacity if full.
if (wod.Participants.length >= wod.capacity) {
res
.status(403)
.send({ status: false, message: 'Capacity of this class is full!' });
}
const result = await wod.addParticipants(userId);
res.status(201).json({ status: !!result, wod });
} catch (error) {
res.status(500).send({ status: result, message: error.message });
console.log(error.message);
}
};
As a result of many-to-many association sequelize.sync will generate some functions for us. You are used addParticipants function and this returns an array that added to the assocation(userwod) table.
In this array you will find some id fields(join table fields) because you just run like this INSERT INTO 'user_wods' ('user_id''wod_id') VALUES (2,1). If you want to return the added user's information then you should run a SELECT * FROM 'user' WHERE 'id'=2.
You must call reload function for fetch the third guy.
await wod.reload()

Expressjs authentication

I have some questions regarding login and sessions. I have this code:
The db query:
login: function(req,callback) {
var query = 'SELECT id FROM users WHERE email = "' + req.body.email_login + '" AND password = "' + hashlib.sha1(req.body.password_login) + '" LIMIT 1';
client.query(query, callback);
}
The route:
app.post('/login', function(req, res, next) {
users.login(req,function(err, results) {
if (err) {
res.render('index');
} else if (results[0]) {
req.session.userdata = results[0];
req.session.is_logged_in = true;
res.render('site/news');
}
}
}
Auth middleware:
var auth = function (req, res, next) {
if (req.session.userdata && req.session.is_logged_in === true) {
next();
} else {
res.redirect('/');
}
}
I use db store for the session.
Now my questions are:
1) Is this a safe way to do it? Or should I consider doing it some other way?
2) Say I have this URL /domain/users/1, where the last segment is the user id which is used to fetch user data.
And on that view I have a form for changing user data. Is it safe to check if the user id matches the session user id and then show the form?
In the view:
// e.g. get the session.id from dynamichelper
if (data.userid === session.userdata.id) {
// The form where user can change his data contained within here
}
The server is going to use SSL.
Thanks in advance
George
In the db query code, check for req.body.email_login and req.body.password_login to make sure they're not null and that they're strings. Someone could sent an empty response and that will generate an Internal Error on your side.
Also in the route, you might want to log the error and redirect the user to the /500.html page (internal error):
if (err) {
console.log(error);
res.redirect('500');
} else ...
You shouldn't do this in the view:
if(data.userid === session.userdata.id) { //The form where user can change his data contained within here }
Try instead to achieve this in the model (preferably), make a function for it and pass only one parameter to the view like so:
res.render('view', { loggedIn: true });
The function from the model:
function checkUser(id, session) {
return (userid === session.userdata.id);
}
...
module.exports.checkUser = checkUser;
You can call it from the route like so (for ex):
res.render('view', { loggedIn: model.checkUser(req.body.id, req.session); }
You might also want to look at http://passportjs.org/

Categories

Resources