My website has a register function that creates a new document with the user's credentials. Below is my implementation, where the input fields for username and password are stored in an object called data:
let users = db.collection('users');
let query = sanitize(data);
users.findOne({username: query.username}).then(res=>{
if (res){
socket.emit('usercreated', {
msg: `User: ${query.username} already exists.`
});
return;
}
const h = query.username + query.password;
bcrypt.hash(h, 13, (err, hash)=>{
users.insert({username: query.username, password: hash}, (err, user)=>{
if (err){
socket.emit('usercreated', {
msg: `DB is having issues. Please contact admin.`
});
return;
}
socket.emit('usercreated', {
msg: `User ${query.username} has been created.`
});
});
});
})
However, a problem arises when a user spams the submit button for username and password. The 'res' variable does not recognize that the user already exists due to the asynchronous nature of the bcrypt.hash function.
I have attempted another method to check 'res' after bcrypt completes its hashing, but this approach does not solve the issue:
let users = db.collection('users');
let query = sanitize(data);
users.findOne({username: query.username}).then(res=>{
const h = query.username + query.password;
bcrypt.hash(h, 13, (err, hash)=>{
if (res){
socket.emit('usercreated', {
msg: `User: ${query.username} already exists.`
});
return;
}
users.insert({username: query.username, password: hash}, (err, user)=>{
if (err){
socket.emit('usercreated', {
msg: `DB is having issues. Please contact admin.`
});
return;
}
socket.emit('usercreated', {
msg: `User ${query.username} has been created.`
});
});
});
})
What would be a more effective way to properly check if the user already exists before proceeding with the insertion?