Node.js Registration Form - javascript

I am trying to implement a registration form into my web app. Once I insert the 'name' and 'email' provided by the user into my database (Mysql). I need separate error messages to pop up on the registration form if the 'name' or 'email' are already in use, something like
"the 'name' is already in use"
or
"the 'email' is already in use"
The problem is I use the error I get from the Mysql to show the message
"the 'name' or 'email' is already in use"
My question is how can i use the Mysql error to distinguish whether it is the 'name' or the 'email' that is being duplicated.
app.post(myArgs[0]+"/register", function(req,res){
con.query('insert into users values(UUID(),\'' + req.body.user + '\',\''+req.body.pass+'\',\''+req.body.mail+'\',NULL)',function(err,res){
if(err){
console.error(err+" Ooops name or email already in use !"); //here is where I want to find out whether it is the name or the email that is already in use!
errorregister();
return;
} else {
passregister();
}
})
function errorregister(){
res.redirect(myArgs[0]+"/register");
console.log(_dict);
}
function passregister(){
res.redirect(myArgs[0]+"/login");
console.log(_dict);
}
});

After the DB give you a error on inserting, you know that either emailor name, or both, is duplicated.
You can then search the DB for name, then for email.
After that, customizing your error message is easy.
Checking before inserting could go wrong in case of race conditions (two users trying to register the same name/email at the same time). After inserting, you know for sure something is duplicated.

Check for error 1586 when inserting in MySQL(List of error codes)
You can check for which INSERT the error occurred.
Whenever a duplicate key is being inserted in a UNIQUE KEY column, this error is returned. Based on this error you can send a AJAX response to client, which would update DOM to show the required error.

Alright this is how i got it done
app.post(myArgs[0]+"/register", function(req,res){
con.query('insert into users values(UUID(),\'' + req.body.user + '\',\''+req.body.pass+'\',\''+req.body.mail+'\',NULL)',function(err,res){
if(err){
error(err);
return;
} else {
passregister();
}
})
function error(err){
if (err.toString().search("'PRIMARY'") != -1 ){
console.error(" Ooops!!! name duplicated");
res.redirect(myArgs[0]+"/register")
} else {
console.error(" Ooops!!! email duplicated");
res.redirect(myArgs[0]+"/register")
}
return;
}
function passregister(){
_dict[req.body.user]={};
res.redirect(myArgs[0]+"/login");
console.log(_dict);
}
});

Related

How can a user's displayName be added to a Firestore database collection entry?

I am setting up a simple webpage with Firebase Authentication and a Firestore database which takes user inputs from a form, adds the inputs as a collection document in Firestore, and then also outputs the whole collection. Each document in the collection has two fields, the Name and the Body of the document. The goal is to allow users to make posts on the website using the input form. Everything I described is working, but now I would like to display the user.displayName with the post, to show who exactly created the user input, and that's what I can't figure out how to do. Here's the relevant code, from the script.js of the website:
const createForm = document.querySelector('#create-form');
createForm.addEventListener('submit', (e) => {
e.preventDefault();
db.collection('forumposts').add({
Body: createForm['body'].value,
//the line below is what I cannot figure out how to set up
Name: string(user.displayName)
}).then(() => {
//reset the form
createForm.reset();
}).catch(err => {
console.log(err.message)
})
});
I'm still learning about JavaScript, so I apologize if I am missing something obvious. I know the user's displayName (which is collected upon sign up) is being collected properly, as I can log it to the console and it shows up correctly. I just cannot figure out how to then add it as a field in this database collection input. I have tried searching here on SO for related questions, but am only getting questions related to how the user can add a display name on sign-up. I already have the display name, I just need to input it into the database. Any help would be greatly appreciated!
Where is the "user" defined? That could be null if no user is logged in so it's better to check for the user.
const createForm = document.querySelector('#create-form');
createForm.addEventListener('submit', (e) => {
e.preventDefault();
const user = firebase.auth().currentUser
if (user) {
db.collection('forumposts').add({
Body: createForm['body'].value,
Name: user.displayName || "No username"
}).then(() => {
//reset the form
createForm.reset();
}).catch(err => {
console.log(err.message)
})
} else {
console.log("NO user logged in")
}
});
You don't need the String() constructor. If displayName is defined it'll be a string. You can use if (user.displayName) before adding the post to check if user has a display name.
It's String(), not string(). As long as displayName is a property of user, it will be added to the database.

Problem with two send responses: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

I try to make a small 'database' where I can put some data into an input field and also make queries. For instance when I write a name into the field and click on the request button it will show the information about that person.
It works pretty well and also it shows a message when nothing was found. But I always get the error mentioned in the title, I can't understand what's wrong.
server.post('/MyWebApp/mydatabase1', function(req, res){
database.forEach(element => {
if(element.email == req.body.email || element.nachname == req.body.nachname || element.vorname == req.body.vorname)
res.send(element);
});
res.send("No Entry found");
});
first I wanted to check if any element is matching, if yes it should res.send(element);
if not res.send("No Entry found");
it works though I get that error
'Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent
to the client'
Is it maybe because I made two send responses?
How can I fix it?
This happens because you're sending outside of the callback function - which will always happen (res.send is not like return - it does not terminate the function).
It also looks like you're attempting to send back multiple elements. You're either looking for one element, or you're sending back an array of matching elements - but you can't send them back one at a time (think of the client side aspects of this).
Your code would look a bit like this, if you intend to return all matches:
server.post('/MyWebApp/mydatabase1', function(req, res) {
let elements = database.filter(element => element.email == req.body.email || element.nachname == req.body.nachname || element.vorname == req.body.vorname);
if(elements.length) {
res.send(elements);
}
else {
res.send("No Entry found");
}
});
If you only intend to have a single match, you can always just return elements[0] (if it exists).

Insert document only if not already exists

I am creating documents with
Subscription.create({ email: req.body.email }, (err, subscription) => {
//
});
I have made the email field unique in my Mongoose schema, so it's not possible to create multiple docs with same email.
But I don't care whether a certain email already exists, so I don't want a duplicate error as I receive now. How can I insert only if the email doesn't exist already and not create if it does exist, but not tell the user?
I assume it's best practice not to tell the user if the email already exists in the database, since it can be used to test whether an email is associated with the site. It doesn't seem very problematic, but I still think it's better not to tell due to privacy concerns.
In mongoose you can use the pre function.
var schema = new Schema(..);
schema.pre('save', function(next) {
// Check if the mail exists. If it does, just throw an exception
// If not, just create the thing using next.
next();
});
You should be careful to catch the exception and when you call the save function. I believe this will do the work.

Invalid email when resetting password on Parse.com (JS SDK)

I am trying to reset password on my angularjs App. I am using Parse (js SDK) as a backend.
I am using Parse.User.requestPasswordReset as said in the doc, but I am always getting an error 125 invalid email address.
Here is my html form :
<input type="email" ng-model="resetData.email" required>
<button ng-click="resetPassword(resetData)">
Ok
</button>
Here is my controller :
app.controller('userCtrl', function($scope, loginService){
$scope.resetPassword = function(resetData){
loginService.resetPassword(resetData,$scope);
};
});
And finally here is my factory :
app.factory('loginService', function(){
return{
resetPassword:function(resetData,scope){
console.log(resetData.email);
Parse.User.requestPasswordReset(resetData.email,{
success:function(){
alert('You'll receive an email to reset your password');
},
error:function(error){
if (error.code === 205) {
scope.msg_erreur='User not found';
console.log("error "+error.code+" "+error.message);
}
else{
scope.msg_erreur='Oops ! Something wrong happened';
console.log("error "+error.code+" "+error.message);
};
}
})
}
}
});
Good to know :
the console.log(resetData.email) show the good email address.
the email address I used are really in the User Class (if not there is an "error 205 user not found")
I tried to put an email address directly in my code in the Parse.User.requestPasswordReset instead of resetData.email
I tried with several email address, all are real ones.
In every case I always have this error 125 invalid email address.
Does anyone have an idea ?
Thanks
I presume you are storing the email address in the username field, and letting users login that way. Put the email address in the email field as well and the reset email should go out as expected.
This seems to be an issue with the way Parse is dealing with resets, because this was not a problem before. This workaround is not elegant, but it will work until the issue is properly resolved from their end.

How do I validate input with MongoDB?

I have a simple little user registration form that looks like this:
// POST Register new user
exports.new = function(req, res) {
var db = require('mongojs').connect('localhost/busapp', ['users']);
db.users.ensureIndex({email:1}, {unique: true})
function User(email, username, password, dateCreated) {
this.email = email;
this.username = username;
this.password = password;
this.dateCreated = new Date();
this.admin = 0;
this.activated = 0
}
if (req.body.user.password !== req.body.user.passwordc) {
res.send('Passwords do not match');
} else {
var user = new User(req.body.user.email, req.body.user.username,
req.body.user.password);
// TODO: Remove this after we clarify that it works.
console.log(user.email + " " + user.username + " " +
user.password);
// Save user to database
db.users.save(user, function(err, savedUser) {
if (err) {
res.send(err);
} else {
console.log("User " + savedUser.email + " saved");
}
});
}
}
But I'm having trouble validating information submitted, like unique values, is empty, that sort of thing, so nobody can send post requests to the database to bypass the jQuery validation functions. I've read through the docs but I cannot seem to get it right. I tried setting a ensureIndex, but, that doesn't seem to work. Any information on how to validate the input on the database side would be great thanks!
One of the strengths/features of MongoDB is flexible schema. MongoDB does not impose any specific contraints on fields types. In general with web applications, you should try to do validation as early as possible .. so first at the client (JavaScript) level, then the application, and as a last resort in the database server.
MongoDB validation
MongoDB can do a limited amount of validation such as ensuring a unique index. Any data validation such as required fields or field types (string, integer, ..) should be done in your application code.
Clientside/application validation
You could use jQuery validation, but that would only be effective in the client (browser view). Any validation should also be done in your application code/model, otherwise disabling JavaScript in the browser would be a simple way to insert invalid data.
why cant you do stuff like password != "". as for unique values you should do use the find or findOne functions to see if that name exists in the db.
i would highly recommend installing mongoose. it is really useful as it allows you to create schemas. so if you are familiar with MVC, in your models, you would have user.js which contains the schema for the user. basically it gives guidelines on how the user object will be stored in the database. in your controllers, you would try to do what you are doing in the code you have above. you would do a user = require(user.js) and then you would do user.find() or user.findOne() to find that thing in the database. for example. if the username was already in the database, then its not unique. so dont add him.

Categories

Resources