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');
Related
I've basically followed this medium article to set up cognito in Node.JS. I used express for the UI: https://medium.com/#prasadjay/amazon-cognito-user-pools-in-nodejs-as-fast-as-possible-22d586c5c8ec
However, only one user can be logged in for the whole application. And that user becomes logged in on every browser and IP address. So the code isn't treating everyone as a separate user.
I tried putting the userPool in every function as shown below, as before it was a constant at the top of the JS file. However that did not do anything.
Here are the main functions:
app.get('/', (req, res) => {
let userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
let cognitoUser = userPool.getCurrentUser();
if(cognitoUser === null) {
res.render('index')
}
else {
res.redirect('/dashboard')
}
});
app.get('/dashboard', (req, res) => {
let userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
let cognitoUser = userPool.getCurrentUser();
if (cognitoUser != null) {
cognitoUser.getSession(function (err, session) {
if (err) {
req.flash('error_msg', err.message)
res.redirect('/');
}
if (session.isValid()) {
cognitoUser.getUserAttributes(function (err, result) {
if (err) {
req.flash('error_msg', err.message)
res.redirect('/');
}
let token = session['idToken']['jwtToken'];
ValidateToken(token);
res.render('dashboard', {name: result[2].getValue(), email: result[3].getValue()})
});
}
});
}
else {
req.flash('error_msg', 'You are not logged in...')
res.redirect('/');
}
})
app.post('/login', (req, res) => {
let userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
let username = req.body.email;
let password = req.body.password;
let authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails({
Username : username,
Password : password,
});
let userData = {
Username : username,
Pool : userPool
};
let cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
// console.log('access token + ' + result.getAccessToken().getJwtToken());
// console.log('id token + ' + result.getIdToken().getJwtToken());
// console.log('refresh token + ' + result.getRefreshToken().getToken());
req.flash('success_msg', 'Logged in');
res.redirect('/dashboard');
},
onFailure: function(err) {
req.flash('success_msg', err.message);
res.redirect('/dashboard');
console.log(err);
},
});
})
app.get('/register', (req, res) => {
let userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
let cognitoUser = userPool.getCurrentUser();
if(cognitoUser === null) {
res.render('register')
}
else {
res.redirect('/dashboard')
}
})
app.post('/register', (req, res) => {
let userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
let username = req.body.email;
let password = req.body.password;
let personalname = req.body.name;
let attributeList = [];
let dataEmail = {
Name : 'email',
Value : username, //get from form field
};
let dataPersonalName = {
Name : 'name',
Value : personalname, //get from form field
};
let attributeEmail = new AmazonCognitoIdentity.CognitoUserAttribute(dataEmail);
let attributePersonalName = new AmazonCognitoIdentity.CognitoUserAttribute(dataPersonalName);
attributeList.push(attributeEmail);
attributeList.push(attributePersonalName);
userPool.signUp(username, password, attributeList, null, function(err, result){
if (err) {
req.flash('error_msg', err.message);
res.redirect('/register');
return;
}
res.render('verify', {user: result.user.getUsername()})
});
})
app.post('/activation-code', (req, res) => {
let userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
let email = req.body.username;
let activation_code = req.body.activation_code;
let userData = {
Username: email,
Pool: userPool
};
let cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
// signing up
cognitoUser.confirmRegistration(activation_code, false, (error, result) => {
if (error) {
console.log(error)
req.flash('error_msg', error.message)
res.render('verify', {user: email})
}
else {
req.flash('success_msg', 'You have successfully verified your email. You can now log in.')
res.redirect('/')
}
});
})
I expect it to treat one browser session as one user, like a regular sign up. Thanks for any help.
I am working on a model here:
// user.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var bcrypt = require('bcrypt');
// Define collection and schema for Users
let User = new Schema(
{
firstName: String,
lastName: String,
emailaddress: String,
password: String,
},
{
collection: 'users'
}
);
// authenticate input against database documents
User.statics.authenticate = ((emailaddress, password, callback) => {
User.findOne({ emailaddress: emailaddress })
.exec(function(error, user){
if(error){
return callback(error)
} else if (!user){
console.log('User not found!');
}
bycrypt.compare(password, user.password, function(err, result){
if(result === true){
return callback(null, user);
} else {
return callback();
}
})
})
});
module.exports = mongoose.model('User', User);
As you can see on my model I put the User.statics.authenticate on my codes to do some authentication. And then on my login.js route file:
const path = require('path');
const express = require('express');
const router = express.Router();
const db = require('../../database/index');
const axios = require('axios');
const User = require('../../database/models/user');
router.get('/', (req, res) => {
console.log('hi there this is working login get');
});
router.post('/', (req, res) => {
var emailaddress = req.body.emailaddress;
var password = req.body.password;
if( emailaddress && password ){
User.authenticate(emailaddress, password, function(err, user){
if(err || !user){
console.log('Wrong email or password!');
} else {
req.session.userId = user._id;
return res.redirect('/');
}
});
} else {
console.log('both fields are required...');
}
});
module.exports = router;
I called the function and then User.authenticate function and also I created the route for root w/c is the sample that I want to protect and redirect the user after login:
router.get('/', (req, res) => {
if(! req.session.userId ){
console.log('You are not authorized to view this page!');
}
User.findById(req.session.userId)
.exect((err, user) => {
if(err){
console.log(err)
} else {
res.redirect('/');
}
})
});
Upon clicking submit on my react form it returns this error:
TypeError: User.findOne is not a function
at Function.User.statics.authenticate (/Users/mac/Documents/monkeys/database/models/user.js:35:8)
I checked the Mongoose documentation and it seems I am using the right syntax.Any idea what am I doing wrong here? Please help! Sorry super beginner here!
PS. I've already installed and set up the basic express session too.
UPDATES:
I remove the arrow function from my call and use this.model.findOne but still get the typerror findOne is not a function
// authenticate input against database documents
User.statics.authenticate = function(emailaddress, password, callback){
this.model.findOne({ emailaddress: emailaddress })
.exec(function(error, user){
if(error){
return callback(error)
} else if (!user){
console.log('User not found!');
}
bycrypt.compare(password, user.password, function(err, result){
if(result === true){
return callback(null, user);
} else {
return callback();
}
})
})
};
findOne is a method on your User model, not your user model instance. It provides its async results to the caller via callback:
User.findOne({field:'value'}, function(err, doc) { ... });
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 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;