How to logout from another browser after reset the password - javascript

I want to logout from another browser after reset the password.
I use passport.js for user authentication.
So i need a such kind of functionality that if i change my password from one browser then it will automatically logout that user from another browser(When switch to another browser).
Any idea?

function validateToken(token) {
return require("mongoclient").then(function (DB) {
return DB.query({$collection: "pl.connections", $filter: {token: token}});
}).then(function (data) {
if (data && data.result && data.result.length > 0) {
return true;
} else {
return false;
}
})
}
not a complete implementation but a sample code to validate the token in node with mongo
Add A bit of functionality in your app. maintain a table of token in your db corresponding to users so after a change to password just expire the tokens that are in table for a specific user. Its not just a idea its a working strategy that is adopted by many apps.

You can easily archive this using session Id which is generated each time a user is authenticated and is unique to a user. But you have to keep track of the Id
In this solution am using express-session
After a successful authentication req.session.id is assigned to the user, it is an alpha-numeric Id(6QP2t2_ffzkLNPHWNIEuRSXEvNm4lzLb). You can save this user session Id on account login, Then you can retrieve the user's session from the memory store at any time and destroy it:
let session = require('express-session');
const id = req.session.id
sessionStore = express.session.MemoryStore();
sessionStore.get(id, function(err, sess) {
sess.destroy (function (err) {
console.log(err, 'if any')
});
});

For example you can add expireAfter flag to your users table. And when you need to logout somebody just change their expireAfter to current time.
If current timestamp is greater than expireAfter then you just clear cookies in browser when request comes.
And when login just set expireAfter to 1st January of 2030
// something like that
var app = express();
app.use(function(req, res, next) {
var user = { ... } // load user from db
if (user.expireAfter >= new Date().getTime()) {
res.clearCookie('user_id') // or whatever you have
var err = new Error('not authorized, please re-login');
err.status = 403;
return next(err);
}
next();
});
... code code code ...

You can create timer at your client side.
use setInterval function.
Send function that will go to server and check if you need logout.
(This Logic is used to check expire sessions, at some systems)
UPDATE:
following to the comment, I notice that I forgot wrotten critical detail:
Of course, server itself need prevent any action when your password is changed. I meant to client side - that you want to logout it.

Related

Creating a user session - NODE js

I am new to node js & javascript in general. I have the below piece of code that will handle a login. I have a MYSQL database with a customer table. When the customer enters their username and password, it checks does it exist in the database. This part is working.
I now want to enhance this feature so that it will take the username and create some sort of a session variable, which can be used across the application. I am new to JS so I am not yet sure which inbuilt facilities already exist, or best practice around sessions.
I want to be able to use this session variable across the application, and for subsequent logout facility.
Can someone advise me on this, or point me in the right direction? Thanks.
case "/login":
var body = '';
console.log("user Login ");
request.on('data', function (data) {
body += data;
});
request.on('end', function () {
var obj = JSON.parse(body);
console.log(JSON.stringify(obj, null, 2));
var query = "SELECT * FROM Customer where name='"+obj.name+"'";
response.writeHead(200, {
'Access-Control-Allow-Origin': '*'
});
db.query(
query,
[],
function(err, rows) {
if (err) {
response.end('{"error": "1"}');
throw err;
}
if (rows!=null && rows.length>0) {
console.log(" user in database" );
theuserid = rows[0].customerID;
var obj = {
id: theuserid
}
response.end(JSON.stringify(obj));
}
else{
response.end('{"error": "1"}');
console.log(" user not in database");
}
}
);
});
}
There can be multiple ways of implementing a user session.
One, you could use a browser cookie, it comes with many pros and cons and you should read about it a bit to see how its managed. This would also depend on the server you are using (express, hapi, etc).
Two, you can set a JWT token on the backend, and include it in the header of the response, then you can either use your application state or the local storage of the browser to save that token on the UI. Any such follow up requests requiring authentication should contain this auth token as a header for verification.
For more clarity, you can look into related libraries (such as passport), which make this task a lot easier.
PS: If you choose cookies, please make sure the business is going to allow it or not as the end-users do not like being tracked always. :)

Firebase Authenticatoin - onAuthStateChanged called multiple times

Whenever I render the home page or account page my session is sometimes lost. I have a function called isSignedIn() that checks if the uid exists. Sometimes, when I refresh the homepage, it returns false. When I hit my account endpoint it returns false too even though it's true on the previous page. Any ideas on why this is happening?
How my app works:
When a user logs in I take the uid from client side and hit an auth endpoint.
function createServerSession(user) {
// Get secret token from Firebase for current session
firebase.auth().currentUser.getToken(true)
.then(function(idToken) {
// Get session on my Node server for server user identification
if (idToken) {
fetch('/firebaseauth?idtoken=' + encodeURIComponent(idToken) + '&username=' + encodeURIComponent(user.email.split('#')[0]), {
credentials:'include'
}).then(function(data){
if (window.location.pathname === '/' && document.getElementById('login').innerHTML.trim() === 'Join') {
redirect('/');
}
if (window.location.href.includes('login')) {
redirect('/');
}
})
}
})
}
Then it hits my node.js code to store the session:
app.get('/firebaseauth', function (req, res) {
if (! req.session.idToken) {
firebase.auth().verifyIdToken(req.query.idtoken).then(function(decodedToken) {
req.session.username = req.query.username
req.session.idToken = decodedToken.uid;
req.session.save(function(){
res.json(true)
})
})
This approach works fine most of the time, but some instances it will send multiple requests. The highest amount being 7400 at one point. Any guidance is appreciated.
Since posting this issue, I've switched hosts from GAE to Heroku and that fixed it. I know the functionality with node.js is in beta so maybe that was it

Payment GateWay integration in nodejs and mongodb

Hi I am Integration Payment GateWay to my app but i am stuck. for cod(Cash On Delivery) mode of payment it is working fine.but while in integration online payment gateway it is giving bit pain like i am creating payment link using instamojo when link is created successful; i return that payment link to client and redirect user to that link
1 if user fills card details successfully and instamojo hits my provided webhook(post url) with payment details
2 what if user cancels tab or doesn't pays
question here is where shall in create order in database. if it is to be created on placeorder url of my app then i need to set order status incomplete and run a cron job for second condition (because order is already created and webhook is not hit by intamojo). is it right way to do or there is other better ways to handle all this
Promise.all([getUpdatedCart(userId), findUser(userId), getDiscount(userId,couponCode)])
.then(function(resultArray) {
var cart = resultArray[0];
var user = resultArray[1];
var discountAmount = resultArray[2];
var offerId=null;
if (!cart)
return sendResponse(response,400,"error","Cart Not Found");
if (discountAmount>0)
var offerId=getOfferId(couponCode);
var order = {
user: user._id,
cart: cart._id,
shippingAddress:shippingAddressId,
billingAddress:billingAddressId,
paymenMethod: paymentMethod,
offer:offerId,
deliveryNote:deliveryNote,
amount:cart.amount
};
var newOrder = Order(order);
if (paymentMethod==='cod')
newOrder.save(function(error,order){
if (!error)
if (order){
Cart.expireCart(cart._id);
return sendResponse(response,201,"success",order);
}
});
else if(paymentMethod==='intamojo'){
var purpose='Order Number-'+ newOrder.id;
Instamojo.setHeaders(InstaConfig.test.API_KEY, InstaConfig.test.API_AUTH_TOKEN);
var amountPayable = cart.amount - discountAmount;
var data = generatePayload(user, purpose, amountPayable);
Instamojo.createPaymentLink(data, function(error, resultResponse, body) {
if (resultResponse && body && resultResponse.statusCode===201)
return sendResponse(response,200,"success",body.longUrl+"?embed=form");
});
}
else if(paymentMethod==='payumoney'){
}
else
return sendResponse(response,400,"error","Invalid Mode of Payment");
})
.catch(function(error) {
return sendResponse(response,400,"error",error);
});
Can anyone Please help if i need to write cron job kindly suggest library for that
You need not create a cron job.
You can create Order in your database first, and then create a request passing the orderID in purpose parameter to uniquely Identify the Payment Request.
Provide redirect_url and webhook at the time of create a request.
After any Payment payment_request_id and payment_id is send to the redirect_url provided.
Use payment_request_id and payment_id to get the status of the payment, the response will have payment: { ... ,status, ... } use this to update the status in your database.
You can use webhook as a fallback if the user accidentally closes the browser window/tab before it reaches the redirect_url.
For more details, read the documentation

How to use localStorage to store and get back user login details?

I'm building a mobile app using the Ionic framework, I need to be able to cache my user's login so they don't have to login every time.
I read a solution that recommends using HTML5 localStorage. However I'm unsure at the moment on how to implement it.
This is what my user login variables look like:
credentials Object {username: "leon", password: "sushi"}
And what my console.logs print out below:
My loginController:
// The Modernizr Code
////////////////////////////////////////////////////////////////////////////
if (Modernizr.localstorage) {
// window.localStorage is available!
console.log('localStorage is available!');
console.log('creds',creds);
} else {
console.log('no native support for HTML5 storage :(');
// no native support for HTML5 storage :(
// maybe try dojox.storage or a third-party solution
}
// The Login function
////////////////////////////////////////////////////////////////////////////
function login(credentials) {
console.log('credentials',credentials);
creds = localStorage["credentials"];
console.log('creds',creds);
AuthService.login(credentials).then(function (user) {
$rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
if (user.password_reset) {
$location.path('/password');
}
else {
AuthService.saveUser(user);
$location.path('/main');
}
}).catch(function () {
vm.errorModalClosed = false;
vm.loginError = true;
PopupFactory.saveConfig("failure", "The username and password you entered don’t match.", true);
$rootScope.$emit('open.popup');
});
}
localStorage is global in the browser you can save data and then retrieve wherever you want, you add item like this localStorage.setItem('key', 'value') and getting localStorage.getItem('key');
Remember something, localStorage only save string, you have to use JSON.stringify() for save an object y JSON.parse for parsing to json again
in you specific example in the moment you save the user
AuthService.saveUser(user);
localStorage.setItem('user', JSON.stringify(user));
$location.path('/main');
and retrieve in other place
var user = JSON.parse(localStorage.getItem('user'));
you can do that too inside your AuthServer.saveUser(user) and add some method like AuthServer.getUser() to get the user

Parse.com security: can I save an object and claim it's another user's?

I'm looking at this example of modeling a blog system using javascript, code snippet copied as below:
var user = Parse.User.current();
// Make a new post
var Post = Parse.Object.extend("Post");
var post = new Post();
post.set("title", "My New Post");
post.set("body", "This is some great content.");
post.set("user", user);
post.save(null, {
success: function(post) {
// Find all posts by the current user
var query = new Parse.Query(Post);
query.equalTo("user", user);
query.find({
success: function(usersPosts) {
// userPosts contains all of the posts by the current user.
}
});
}
});
It basically creates a post object and sets the current user object to its user field. To show all blog posts by the current user, it queries all blog posts with the user field set to the current user.
But since the User table by default is read only to all users, wouldn't this be problematic that a malicious user (X) can create random posts and "claim" that they are create by another user (Y), by setting the user field of those posts to Y as he queries from the User table? So the consequence would be that when the system shows posts for user Y, he would see all his true posts in addition to the post that was "forged" by X.
Is the mitigation that the User table needs to be ACL'd somehow? But if it is the solution, then why is the default behavior that an arbitrary user can see the entire User table?
Cloud Code is your friend here.
In this case you want a beforeSave handler that locks the user field to the currently authenticated user on new objects, and rejects the save if they're updating a post and trying to change the user field (or just using ACLs to prevent everyone except the post owner from modifying Post rows).
Something like this:
Parse.Cloud.beforeSave('Post', function(request, response) {
var post = request.object;
var user = request.user;
if (post.isNew()) {
post.set('user', user);
response.success();
} else {
// any special handling you want for updates, e.g.:
if (post.dirty('user')) {
response.error('Cannot change the owner of a Post!');
} else {
response.success();
}
}
});
My recommended approach to handling updates for something like a "Post" would be to prevent all updates. In the "Set permissions" for the class in the Data Browser I would change the following:
Update : Disabled
Delete : Disabled
To disable something just untick the "Any user can perform this action". Optionally you might want to assign a Role like "Administrator" or "Moderator" to allow those people to directly update/delete items.
These functions would then only be possible from Cloud Code when useMasterKey() is used, e.g.:
Parse.Cloud.define('deletePost', function(request, response) {
var postID = request.params.postID;
var query = new Parse.Query('post');
query.get(postID).then(function (post) {
if (post) {
// post found
var postOwner = post.get('user');
if (postOwner.id == request.user.id) {
// we let the owner delete their own posts
// NOTE: need to use the master key to modify/delete posts
Parse.Cloud.useMasterKey();
post.destroy().then(function () {
// TODO: delete all replies too?
response.success();
}, function (error) {
response.error(error);
});
} else {
response.error('Only the owner of a post can delete it!');
}
} else {
// post not found, might as well respond with success
response.success();
}
}, function (error) {
response.error(error);
}
});
But since the User table by default is read only to all users,
wouldn't this be problematic that a malicious user can create random
posts and "claim" that they are create by another user, by setting the
user field to the other user?
You can play around with curl to explore this.
IMO - you are right about world read on the _User class. So what. That is read.
When it comes to POST action, you are going to need an authenticated session as the user in question. You cant just spuuf things by claiming that u are a user that you read on the table.
try curl posts without an established session as the user. You will get a 403 or some 'illegal access' response.

Categories