Quickblox: Change password of other user in Javascript - javascript

I'm doing a javascript app with Quickblox and I'm having one problem. I want to have a recover user password function and I have thought that an special user could change another one password. For that I'm using this:
var params = {password: newPassword, old_password: oldPassword };
QB.users.update(userId, params, function (error, response) {
//...
});
The function only works if I use the same userId of the user connected. I know that there is a forgot password function that is sending mails in Quickblox, however, I would like to not send any mail. What I can do? How can I use QB.users.update properly?
Lot of thanks in advance and best regards

You can't change a password of another users, only yours.
You can try to use admin account's credentials to change other user's password

Related

Approach to modify the database without logging the user?

I have a React frontend with a Node + MySQL backend, I'm sending an email to an user with two buttons to accept or decline a quote. What I'm trying to achieve is to make the buttons in the email modify the database securely without the user having to log into his account. My idea is to have two routes, one that sends the email containing the buttons which will have a url to my website with the jwt token on its parameters, and another for verifying said token and making the changes to the db. Here's some pseudo-code:
app.post("/email-quote", async function (req, res) {
const payload = {
uid: req.body.user.id,
quoteId: req.body.quote.id,
accepted: // true for the accept button, false for the decline button
}
const secret = ?
const token = jwt.sign(payload, secret);
// ...
// Generate and send email with buttons containing the url + the token
});
When the user clicks one of the buttons, I re-direct him to my website and there I can extract the token and verify its validity:
app.get("/verify-email-quote/:token", async function (req, res) {
const decodedJwt = jwt.decode(req.params.token);
const secret = ?
const verifiedJwt = jwt.verify(req.params.token, secret);
if (verifiedJwt) {
// Make the changes to the db
}
});
I wasn't able to find any examples trying to achieve something similar on the web, so I have these questions:
Would a jwt token be a good approach to achieve this?
If yes, what secret should I use to create the token?
If no, what other solutions could I look into?
Yes, you can do it this way.
The secret does not matter. As long as the secret is secret
It doesn't need to be a jwt token. It can just be a normal token. The incentive to using jwt is that you can embed a payload into the token. For your case, it looks like it is exclusively for verification purposes. It doesn't matter in the grand scheme of things, but if you don't have jwt already implemented, there's no need to go through all that extra work just for this use case.

MySql, NodeJS, ExpressJS and bcrypt: what is the best way to handle users' login?

My solution works, but I'm not sure this is safe and appropriate. On the front end I have a ReactJS app that send with axios a request with the login and password. On the back end I have NodeJS + ExpressJS handling the request as follows:
router.post('/', function(req, res, next) {
// get the records that match the login provided
const sql = "SELECT name, surname, login, password, blocked FROM users WHERE login=?";
query(sql, [req.body.login])
.then((result)=> {
// if there are 1 or more results, compare the passwords with bcrypt
if (result.length > 0) {
bcrypt.compare(req.body.password, result[0].password, function(err, success) {
if (success) {
// if the user is not blocked, send the status 200 with user's data
result[0].blocked ?
res.status(401).json({type: 'Warning', message: 'Your account has been blocked. Plase contact the admins.'})
:
res.status(200).json({name: result[0].name, surname: result[0].surname, email: result[0].email});
} else {
// send an error if the password is wrong
res.status(401).json({type: 'Error', message: 'Please check that your login and password are correct.'});
}
});
} else {
// send an error if the login was not found
res.status(401).json({type: 'Error', message: 'Please check that your login and password are correct.'});
}
});
});
Is it enough/safe to query the db for the provided login (it's unique) with if (result.length > 0)?
Is it ok to have the error message contained in the server response like this?
res.status(401).json({type: 'Warning', message: 'Your account has been blocked. Plase contact the admins.'})
I have the chance to let the user know if he typed the correct login but the wrong password; should I let him know that? I think it would give to malicious users the knowledge that the login actually exists, so for now I just send a generic login/pwd error. Is this ok?
Is ok to send the user's data from the server to the client if the login was successful?
Is it ok to have the error message contained in the server response like this?
I have the chance to let the user know if he typed the correct login but the wrong password; should I let him know that? I think it would give to malicious users the knowledge that the login actually exists, so for now I just send a generic login/pwd error. Is this ok?
Your implementation is good enough. It's also a good practice letting users know why they are unable to login without giving out too much information EVEN when it's a problem with their supplied credentials (something you are doing already).
Is it enough/safe to query the db for the provided login (it's unique) with if (result.length > 0)?
Yes, this is fine too. You may also want to add a LIMIT 1 to your query to give you a little performance boost since there is no point having your DB scan through all the records when you expect only one result.
It is also a good practice to only send the minimum amount of information and request for more on demand.
As a general observation of your code, you would benefit from the following:
Doing some error checking on your request object before querying the database at all (good practice too) as there is no guarantee that a valid or well formatted username/password would be sent with the request.
Moving the responses into another file to make your code cleaner and maintainable.

How can I impersonate another user with Passport.js in Node?

Using Passport.js in Node, is there a way for me to allow one user to impersonate another? eg. as an Administrator in the application, I want to be able to log in as another user, without knowing their password.
Most simply, I would be satisfied if I could change the serialized user data (user ID) so when deserializeUser is called it will just assume the identity of the alternate user. I've tried replacing the value at req._passport.session.user and the value at req.session.passport.user but the net effect is just that my session seems to become invalid and Passport logs me out.
Passport provides a req.logIn method in case you want to do the authentication manually. You can use it to login any user even regardless of authentication.
Here's how you can use it. Have the Admin login normally, who'll have an isAdmin flag set.
Then place a middleware before passport.authenticate in your login route. This will login the new user based only on their username, if the currently logged in user isAdmin.
app.post('/login',
function forceLogin(req, res, next) {
if (!req.user.isAdmin) return next(); // skip if not admin
User.findOne({
username: req.body.username // < entered username
}, function(err, user) {
// no checking for password
req.logIn(user);
res.redirect('/users/' + user.username);
});
},
passport.authenticate('local'),
function(req, res) {
res.redirect('/users/' + req.user.username);
}
);
I have another way to impersonate, because:
I didn't want to mess with internals of authentication/passport like
session storage / logIn / etc. You must understand them really well
and also they are prone to change so I'd say it's not an option for
me.
Also, I'd like to still be able to tell if action is made from
superuser (impersonated) or normal user (not impersonated).
What I do is:
Have a route for user with superadmin role to impersonate, like /superadmin/impersonate?username=normaluser1 which sets req.user.impersonated.userid = normaluser1.userid
Then I have a middleware, which checks if user is superadmin and is impersonated:
if (req.user.isAdmin && req.user.impersonated) {
req.user.userid = req.user.impersonated.userid;
}
Also, I have found this to be a good article about user impersonation. Similar to my approach, and good for inspiration for building something similar.
The answer to your question is basically: no. The reason is this: the sessions library that is being used 99% of the time is signing the cookies, so if you tamper with the data the web server will reject it.
The way around this is to write your own passport authentication strategy that obviously doesn't do this, but I'm assuming you're talking about working with the built-in strategies here.

NodeJS Sessions

Hy and thanks in advance, So im working on a project, where part of the requirements, is to have a field where the user can insert is e-email, and then receive a custom url on his e-mail account, from there he can access the site. This is like the example of a "password-reset", where a custom url is generated and sent to u with a time-stamp validation. Im very new to nodejs, and my question here is if anyone has some type of guidlines to start doing this. My idea was to generate a sessionID, then generate a custom url, send the email, and then the users goes to the webpage. Im using express, and the whole site is already assembled, its just this feature tha is killing me! :(
I'm not sure what you need, but here is what I'd suggest (spoke about this on Reddit earlier).
// If you want the user to **have** to be a custom URL
req.param('userId', function(req, res, next) {
db.getUser(userId, function(e, usr) {
if (e) throw new Error(e);
req.user = usr;
});
});
req.all("*", function(req, res, next) {
if (!req.user) return res.redirect('/login');
});
// Rest of routes
req.get()
req.post()
That being said, you normally shouldn't have user login this way. Normally you would set the user in the session and validate it that way. Here's a good article on setting up sessions in Express.
If you do it this way, you would do something like this:
req.all("*", function(req, res, next) {
var userId = req.session('userid');
if (!userId) res.redirect('/login');
db.getUser(userId, function(e, usr) {
if (e) throw new Error(e);
if (!usr) return res.redirect('/login');
// Now the user is accessbile through its session
req.session.user = usr;
});
});
// Rest of routes
req.get()
req.post()
Password resetting requires what's called a nonce. This will be a small object in your DB that has a created date. You email them a link to your site that uses that nonce.
Whenever the route is hit that uses the password reset nonce, you look it up in the DB, verify it's new enough (within X hours or days), then give them access to the route that resets their password.
Your project requirements are pretty vague, so I'm not exactly sure what you need.
As of my understanding you want how to implement password reset functionality using expressjs.
Here are steps
1.
for forgot password
create an API
app.post('/forgotpassword',function(req,res){
var email = req.body.email;
// validation
// your custom url creation logic here
// someurl/:resetpasswordtoken
// store this in user data
// for this I'll suggest to use any unique string creation logic*
}
to show reset password page
app.get('/someurl/:resetpasswordtoken, function(req,res) {
//check token exist
// render the page for reset like current passwor,new password
}
Action for reset password
app.post('/someurl/:resetpasswordtoken , function(req,res){
var currentPwd = //get current pwd
var newPwd = //get new pwd
//check token
//then reset password for user
}

how to store signup data into redis with node.js

i want to store signup data it contains name and email and password.
i will store this data in mongodb like this
db.save({"name":"xxxx","email":"xxxxx","password":'xxxxxxxx'},function(err,result){});
when user login ,they surely give their email id or username with password so i will find this user exist in db or not by using like this
db.find({'email:'xxxxxxx','password':'xxxxxxxxx'},function(err,result){});
i have tried to do same in redis,by like this
db.hmset('key' name xxxxx email xxxx pass xxxxxx,function(){});
it is stored but how can i check email id usename already exist becz user will give email and password only.if i know key then only i can find that data.even if i know key i can get only data i could not be found data already exist ot not like mongodb
how can i solve this?
You could store your users both in a Set and a Hash for details.
You can then check in the Set if a user exists with: http://redis.io/commands/sismember
I think you should break things down into chunks instead of trying to do everything with one query. So, for example, to add a new user, first check if the user exists:
(My example assumes a Mongoose User Model has been defined)
User.findOne({$or : [{'email': req.body.email}, {'username': req.body.username}],
function(err, result) {
if (err) {next(err);}
if (result) {
// you found an existing user
res.send(309, {'message':'Error: User exists'});
} else {
// no user found
var user = new User({
'email': req.body.email,
'username': req.body.username,
'password': req.body.password,
'and-so-on': req.body.moredata
});
user.save(function(err){
if (err) {next(err);}
res.send(200, {'message':'User Registered Successfully'});
});
}
Honestly though, I wouldn't recommend writing a user authentication system from scratch, because it is pretty limiting in todays world of auth methods. I personally use Passport, because it gives you the ability to use multiple auth systems with your app, including Facebook, Twitter, and so on and so forth.

Categories

Resources