I have a form with username password fields that stores the username and passwords in node.js
How do I keep track of how many times an individual user is logged in. I want to output the number of sessions for a user beside each username in the list of logged in users
index.js:
var loggedInUsers = {};
var LoggedIn = 'TheUserIsLoggedIn';
function index(req, res) {
if (req.session.username) {
res.redirect("/users");
} else {
debugger;
res.render('index', { title: 'COMP 2406 Session Demo',
error: req.query.error });
}
}
function users(req, res) {
if (req.session.username) {
res.render("account.jade", {username:req.session.username,
title:"Account",
loggedInUsers: loggedInUsers});
} else {
res.redirect("/?error=Not Logged In");
}
};
function login(req, res) {
var username = req.body.username;
req.session.username = username;
loggedInUsers[username] = LoggedIn;
res.redirect("/users")
}
function logout(req, res) {
delete loggedInUsers[req.session.username];
req.session.destroy(function(err){
if(err){
console.log("Error: %s", err);
}
});
res.redirect("/");
}
exports.index = index;
exports.users = users;
exports.login = login;
exports.logout = logout;
Without any persistence layer, I would recommend:
if( loggedInUsers[username] ) {
loggedInUsers[username].timesLoggedIn++;
loggedInUsers[username].sessions.push( req.session );
}
else {
loggedInUsers[username] = {
timesLoggedIn : 0,
sessions : []
};
}
instead of:
loggedInUsers[username] = LoggedIn;
Related
It appears as though when I sign into my application, it is storing the credentials locally on the EC2 server. I've quadruple checked my code and I can't figure out what the deal is. If KEVIN signs in from any device, the next user to sign in, or if someone refreshes their page they end up signed in as KEVIN. I am including all code that could potentially be involved in the issue. Outside of this problem, all of my interaction with cognito works great; no errors & no problems. Any help would be greatly appreciated. I am using Node.js, Express, AWS, and Websockets on my EC2 Instance.
// Accessed from server for route authentication before page render or redirection
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
module.exports = {
ensureAuthenticated: function(req, res, next) {
let data = { UserPoolId : 'us-east-1_7xUGRJPKq',
ClientId : '6glign6b34c806osfhnik18cb3'
};
let userPool = new AmazonCognitoIdentity.CognitoUserPool(data);
let cognitoUser = userPool.getCurrentUser();
console.log(`ensuring authentication....`);
console.log(cognitoUser);
if (cognitoUser === null) {
req.flash('error_msg', 'Please log in');
res.redirect('/login');
} else {
cognitoUser.getSession((err, session) => {
if (err) {
console.log(err);
} else {
next();
}
});
}
},
};
// Routes where I am seeing the problem
const express = require('express');
const router = express.Router();
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
const { ensureAuthenticated } = require('../config/auth.js');
router.get('/', (req, res) => {
res.redirect('/dashboard');
});
router.get('/dashboard', ensureAuthenticated, (req, res) => {
res.render('dashboard', {
layout: './layouts/dashboard-layout.ejs'
});
});
// Login authentication
router.post('/login', (req, res) => {
const loginDetails = {
Username: req.body.email,
Password: req.body.password
}
const authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(loginDetails);
const userDetails = {
Username: req.body.email,
Pool: userPool
}
const cognitoUser = new AmazonCognitoIdentity.CognitoUser(userDetails);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: data => {
cognitoUser.getUserAttributes(function(err, result) {
if (err) {
console.log(err);
return;
} else {
console.log('LOGIN RESULTS')
console.log(result[0].Value.toString());
let userId = result[0].Value.toString();
let userCity = result[2].Value.toString();
console.log(userId);
console.log(userCity);
res.redirect(`/dashboard/${userCity}/${userId}/`)
};
});
},
onFailure: err => {
req.flash('error_msg', 'Invalid Credentials');
console.error(err);
res.redirect('/login');
}
})
});
Thank You!
UPDATE 10/21/19: Removed function that doesn't apply to the issue.
Also do not seem to have any JWT in local storage:
Click Here for image
I have a function that is inserting user credentials. I want to return value from a call back function...
var router = require('express').Router();
var User = require('../Models').users;
// function calling here
router.post('/signup', function (req, res)
{
var result = User.signUp(req.body);
res.send(result);
});
module.exports = router;
//implemetation of function
userSchema.statics.signUp = function signUp(obj) {
var user = new userModel(obj);
user.password = hash.generate(obj.password);
return user.save(function (err, newuser) {
if (err)
{
return 'Error occured during insertion..';
} else
{
return 'You have sign up successfully...';
}
});
}
I want to return the response as a string but it showing undefined. How should it be done?
var router = require('express').Router();
var User = require('../Models').users;
router.post('/signup', function (req, res)
{
var result = User.signUp(req.body, function(err, result){
if(err){
}
else{
res.send(result)
}
});
});
userSchema.statics.signUp = function signUp(obj, callabck) {
var user = new userModel(obj);
user.password = hash.generate(obj.password);
user.save(function (err, newuser) {
if (err)
{
callback( 'Error occured during insertion..');
} else
{
callback(null, newuser);
}
});
}
Use the callback i.e.
var router = require('express').Router();
var User = require('../Models').users;
// function calling here
router.post('/signup', function (req, res)
{
User.signUp(req.body,function(err,result){
res.send(result);
});
});
module.exports = router;
//implemetation of function
userSchema.statics.signUp = function signUp(obj,callback) {
var user = new userModel(obj);
user.password = hash.generate(obj.password);
return user.save(function (err, newuser) {
if (err)
{
callback('Error occured during insertion..',null);
} else
{
callback(null,'You have sign up successfully...');
}
});
}
Because of async nature .. Try this:
router.post('/signup', function (req, res)
{
var result = User.signUp(req.body, function(err, result){
if(err){}
else{res.send(result)}
});;
});
userSchema.statics.signUp = function signUp(obj, callabck) {
var user = new userModel(obj);
user.password = hash.generate(obj.password);
user.save(function (err, newuser) {
if (err)
{
callback( 'Error occured during insertion..',null);
} else
{
callback (null, 'You have sign up successfully...');
}
});
}
I am having trouble making the #PUT method for my application. So far, I managed to make the #GET, #POST and #DELETE. So after doing some research, it turns out that the #PUT is a mixture of my #GET and #POST.
My #GET (by cuid) method
export function getUser(req, res) {
// just get the user information
User.findOne({ cuid: req.params.cuid }).exec((err, user) => {
if (err) {
return res.status(500).send(err);
}
return res.json({ user });
});
}
My #POST method
export function addUser(req, res) {
// Check for empty fields
if (!req.body.user.firstName || !req.body.user.lastName ||
!req.body.user.email || !req.body.user.password ||
!req.body.user.studentId) {
return res.status(403).end();
}
const newUser = new User(req.body.user);
// Let's sanitize inputs
newUser.firstName = sanitizeHtml(newUser.firstName);
newUser.lastName = sanitizeHtml(newUser.lastName);
newUser.studentId = sanitizeHtml(newUser.studentId);
newUser.email = sanitizeHtml(newUser.email);
newUser.password = sha512(newUser.password).toString('hex');
newUser.cuid = cuid();
newUser.save((err, saved) => {
if (err) {
return res.status(500).send(err);
}
return res.json({ user: saved });
});
}
The req.body.user will be the same in the #PUT method as in the addUser function on the #POST. In other words, the req.body.user will be something like { firstname: 'assa', lastName: 'nen', email: 'ed#aid.com', password: 'ddee', student: 112 }
My question is how would you modify the specific user (by cuid) information and save it to the db? In other words, how would you write the #PUT method
Try findOneAndUpdate
export function updateUser(req, res) {
var userId = req.body.userId;
var conditions = {
_id : userId
}
var update = {
firstName = sanitizeHtml(req.body.firstName );
lastName = sanitizeHtml(req.body.lastName);
studentId = sanitizeHtml(req.body.studentId);
email = sanitizeHtml(req.body.email);
password = sha512(req.body.password).toString('hex');
}
model.findOneAndUpdate(conditions,update,function(error,result){
if(error){
// handle error
}else{
console.log(result);
}
});
}
I've created a file to hold some application wide configuration using app.locals. That config file looks like this:
config/vars.js
// App wide variables
module.exports = function (app) {
app.locals.accessLevels = [
{
"levelName" : "Basic",
"scrapes" : 3
},
{
"levelName" : "Pro",
"scrapes" : 10
},
{
"levelName" : "Ultimate",
"scrapes" : 99999
}
];
}
I want to access the app.locals.accessLevels array within my user's model which is here:
app/models/user.js
var userSchema = mongoose.Schema({
local : {
firstName : String,
lastName : String
// more stuff, simplified here for the question
}
});
userSchema.methods.remainingScrapes = function() {
// === >>> I need access to app.locals.accessLevels here
var today = new Date().yyyymmdd();
var scrapes = this.local.scrapes;
if (scrapes.length > 0) {
scrapes.forEach(function(item, i) {
if (today === item.date.yyyymmdd()) {
return item.count;
}
});
}
}
module.exports = mongoose.model('User', userSchema);
Then, there is also my existing code to consider where I'm accessing the User model (e.g. routes.js) because if I change something in the user model file, I don't want it to break my routes.js file...
** app/routes.js **
// I have simplified this file and removed excess code, but the function below
// is using the User model, so I have kept it in to demonstrate what code I have
var User = require('../app/models/user');
module.exports = function(app, passport) {
function isLoggedIn(req, res, next) {
// if user is authenticated in the session, carry on
if (req.isAuthenticated()) {
return next();
}
// automatically login admin
else if (app.locals.env == "development") {
User.findOne({ 'local.email' : 'anthony.hull#gmail.com' }, function (err, user) {
if (err) {
throw err;
} else {
console.log("login", "defaulting to admin user log in");
// assign user to req.user with passport's login method
req.login(user, function(err) {
if (err) {return next(err); }
return next(null, user);
});
}
});
}
else {
res.redirect('/login');
}
}
}
This is my model.
UserApiSchema.statics.createApi = function(user,fn){
var instance = new UserApi();
instance.user = user;
instance.apiKey = "asdasdacasdasasd";
console.log("username is " + user.username);
instance.save(function(err){
fn(err,instance);
});
};
UserSchema.statics.newUser = function (email, password,username, fn) {
var instance = new User();
var apiInstance = new UserApi();
instance.email = email;
instance.password =password;
instance.username = username;
instance.save(function (err) {
fn(err, instance);
});
};
This is my controller-users.js:
app.post(
'/signup/',
function(req, res) {
{console.log(req.body.username);
User.newUser(
req.body.email, req.body.password,req.body.username,
function (err, user) {
if ((user)&&(!err)) {
console.log(user.username)
UserApi.createApi(
user,function(err,userapi){
if((!err)){
res.send("APi created")
}
else{
if(err.errors.apiKey){
res.send(err)
}
}
});
req.session.regenerate(function(){
req.session.user = user._id;
res.send("Success here!");
});
} else {
if (err.errors.email) {
res.send(err)
console.log(req.body.password);
console.log(req.body.email);
console.log(req.body);
}
if (err.errors.username) {
res.send(err)
console.log(req.body.password);
console.log(req.body.email);
console.log(req.body);
}
}
});
}
});
The concept is once the user-name/password is accepted, an API key is stored along with the username. Though, the username payload is getting accepted, when I do the UserApiSchema call to generate the api, no such api is generated. No errors either.
Might be real basic ... but, did you create the objects needed?
UserApiSchema = {};
UserApiSchema.statics = {};
UserApiSchema.statics.createApi = function(user,fn){ ...}
If so ... are they in a module?
Did you export them from the module?
exports.userApiSchema = UserApiSchema;
Did you import them in controller-users.js?
var userApiSchema = require('./UserApiSchema.js');