I am trying to build a user management based on cognito user pool.
I am using nodesjs + express for the backend, all the operation to cognito will be done from the nodejs.
my signup route is
app.post('/signup', (req, res) => {
let userName = req.body.userName;
let email = req.body.email;
let familyName = req.body.familyName;
let password = req.body.password;
let attributeList = [];
let dataEmail = {
Name: 'email',
Value: email
};
let name = {
Name: 'name',
Value: userName
};
let familyname = {
Name: 'family_name',
Value: familyName
};
let attributeEmail = new AmazonCognitoIdentity.CognitoUserAttribute(dataEmail);
let attributeName = new AmazonCognitoIdentity.CognitoUserAttribute(name);
let attributeFamilyName = new AmazonCognitoIdentity.CognitoUserAttribute(familyname);
attributeList.push(attributeEmail);
attributeList.push(attributeName);
attributeList.push(familyname);
let userPool = new CognitoUserPool(poolData);
userPool.signUp(email, password, attributeList, null, (err, result) => {
if (err) {
console.log(`got error during signup ${err}`);
res.sendStatus(500);
} else {
let cognitoUser = result.user;
console.log('user name is ' + cognitoUser.getUsername());
res.sendStatus(200);
}
});
});
however I am getting a failure and cannot find how to over come it
the error is missing parameter:
got error during signup MissingRequiredParameter: Missing required key 'Username' in params
A 'username' attribute is always required to register a user. So you'll need to add one to the attributes list.
If you're not asking the users for a username or don't need one for your use case, you can just use whatever value your using to uniquely identify the user. Thats a simple way to handle it.
So for example, on top of adding their email address to the email address attribute, submit it as the username attribute too.
Reference:
http://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html
Related
How to use node.js fetch data from mongodb and push retrieved data into an array ? I have user collection in mongodb and I can fetch the user and its USER_SECRET and PAS_SECRET information by email without problem to display them in a form, but I was failed to push USER_SECRET and PASS_SECRET of user into a users [] array . I Got error 500.
//-----login ui form-----
router.get("/user/login", function (req, res) {
res.render("users/login.ejs");
});
//------ Post ---
router.post("/user_secret", async (req, res) => {
const email = req.body.username;
console.log(email);
users = [];
try {
const user = await User.findOne({ USER_SECRET: email });
if (!user) {
return res.status(404).send("Inputs are Incorrect Information");
}
// res.render("users/addOrEdit", { user });// this works
res.users.push({
username: user.USER_SECRET,
password: user.PASS_SECRET,
});
} catch (e) {
res.status(500).send();
}
});
I could not find the reason of failure. Should I use map method ?
How to check if the users [] has data or not ? Please help.
I think res.users is undefined...so after getting the user, you can write:
res.status(200).send([{
username: user.USER_SECRET,
password: user.PASS_SECRET
}])
Instead of:
res.users.push({ ... })
What im trying to do is to create clients. From the front end, Im getting requests in an array of more than one client(fullName, phone).
To create them in MongoDB I iterate the req.body.
exports.createTrustees = asyncHandler(async (req, res, next) => {
req.body.forEach( async (user) => {
const {fullName, phone} = user;
users = await Users.create({
fullName,
phone,
});
})
res.status(200, `The user : ${phone} has been registerd!`).json({
success: true,
data: users,
});
});
This code it won't work, it shows this error: ReferenceError: phone is not defined
How can I solve this?
You don't say which instance of phone is not defined, but I am assuming the one in the res.status line.
You are defining the phone variable inside the req.body.forEach( async (user) code block - therefore it is only visible (or has scope) within that code block.
You will need to declare a variable phone at a higher level e.g.
let phone2;
req.body.forEach( async (user) => {
const {fullName, phone} = user;
phone2 = phone;
users = await Users.create({
fullName,
phone,
});
})
res.status(200, `The user : ${phone2} has been registerd!`).json({
success: true,
data: users,
});
I am having a problem with an npm package called 'mongoose-encryption'. Here is my code.
main().catch((err) => console.log(err));
async function main() {
await mongoose.connect('mongodb://localhost:27017/userEncryptedDB', { useNewUrlParser: true });
}
const userSchema = new mongoose.Schema({
email: String,
password: String
});
const secret = 'xxs4Ox4nSKSVnJzIxzy+es6ouOmoMcqcarAnEVRP26Q=';
userSchema.plugin(encrypt, {secret: secret, encryptedFields: ['password']});
const User = mongoose.model('User', userSchema);
Now, if I don't use the package, registration and logging in to the website works properly but if I use the plug in, it says "You are never registered!" even though I register for the email and password...
app.post('/login', (req, res) => {
const email = req.body.username;
const password = req.body.password;
User.findOne({email: email, password: password}, (err, user) => {
if(err) {
console.error(err);
} else {
if(user){
console.log('You are already registered!');
res.render('secrets');
} else {
console.error('You are never registered!');
}
}
});
});
What am I doing wrong here? I started computer stopped database, restarted it. Registration is successfully done but when I try to login page keeps rolling... If I dont use mongoose-encryption, login page works fine once I enter password.
I can clearly see that the new username gets added to the database like so:
{ "_id" : ObjectId("616a4aa45dfbf877d9f92468"), "email" : "aras#aras.com", "_ct" : BinData(0,"YbVYW9Pi6dz1yqRD7XgcEyEp48lLGVjp3J40ZgxGt/YuA8+eyiyebMaO9AGdygBj6A=="), "_ac" : BinData(0,"YQiV2QvS9AyrE1hjm81x5U8K6+0lT8h1ruxtCEZv/iwZWyJfaWQiLCJfY3QiXQ=="), "__v" : 0 }
But then when I try to login, it fails to retrieve password. Password I use here in this case is "1".
Try dropping the collection (first save it somewhere for later use) and try again. It will work!
I am building a Web API using Node JS. For database operation, I am using the Sequalize package. In my test when I run the same query that gets a record after updating the record again, it is giving me the old/previous result.
Here is my code:
let testUser = await User.findOne({
where: {
email: {
[Op.eq]: testHelper.testUser.email
}
}
})
let now = new Date();
//genrate the token in the database before making the request.
let verificationToken = await VerificationToken.create({
userId: testUser.id,
verificationToken: "testing",
expiresAt: date.addSeconds(now, 40000)
})
let requestBody = {
email: testUser.email,
password: "Newpassword123",
confirm_password: "Newpassword123",
token: "testing"
}
const res = await request(app).put("/api/auth/reset-password").send(requestBody);
expect(res.statusCode).toBe(200);
expect(res.body.error).toBe(false);
//refresh the user instance by fetching the new record from the database.
let user = await User.findOne({
where: {
email: {
[Op.eq]: testHelper.testUser.email
}
}
})
// here user.password and testUser.password are the same even the record is actually updated
As you can see in the comment, the password of user object is still the same as the password of testUser object even though the password is updated in the database. How can I fix it to get the latest record?
This is my code in backend (ExpressJs, multer)
Note: I used cors in server.js file and it working as I expected in previous route, but in this Register Admin route, the other error occurs
const multer = require('multer');
const upload = multer({ dest: './public/uploads/' });
const User = require('../models/user.model'); // User model
router.post('/admin/register', upload.single('avatar'),
async (req, res) => {
const avatar = req.file.path.slice(7);
const user = {
...JSON.parse(req.body.user),
avatar
};
// hapi/joi validate => 1
const { error } = Validation.adminRegisterValidation(user);
if (error) {
return res.json({ error: error.details[0].message });
}
// validate from database => 2
const emailExist = await User.findOne({ email: user.email });
if (emailExist) {
return res.json({ error: 'Email already exist!' });
}
// hash the password => 3
const hashedPassword = await bcrypt.hash(user.password, 10);
const newUser = new User({
...user,
admin: false,
password: hashedPassword,
sub_admin: true
});
try {
await newUser.save();
return res.json("Add user success!");
} catch (err) {
return res.json({ error: err });
}
}
);
If i turn 1,2,3 to comment, the user is added as I expected
This project in my Github Github
- Front-end in file: src -> components -> dashboard -> user-dashboard -> CreateUser.js
- Backend in file: backend -> routes -> user.route.js
THIS IS MY ERROR IMAGE
Well I found two errors that might be causing your issue, not really sure if it will totally fix your issue, but will definitely get you close.
1) Remove Max length property from user schema
Right now you have max length of 30 for password in your user Schema but once you hash the password, hashed password can go beyond 30 characters.
You can click here to see what I'm talking about.
2) You need to remove old password in order to store the new hashed password
In this line of code you are using Spread Syntax to include all the fields in NewUser object from user object, which already includes password that comes from your frontend
const newUser = new User({
...user,
admin: false,
password: hashedPassword,
sub_admin: true
});
This what causes newUser to have 2 password fields, to delete the old password after hashing do this
// hash the password => 3
const hashedPassword = await bcrypt.hash(user.password, 10);
delete user.password
const newUser = new User({
...user,
admin: false,
password: hashedPassword,
sub_admin: true
});
This way you can set password to new Hashed one.
AS your error is very Generic It's almost impossible to DEBUG it, these are the few things I found very odd.
As I said not really sure if it will fix your error but it might get you close