Check for existing user doesn't go along - mongodb

As the Waterline's unique attribute is ignored for MongoDB, I take up the decision to make a check for existing model entry in my code:
var username = req.param('username');
var email = req.param('email');
var asd = "";
// Do check if user already exists
User.findOne({username: username}, function (err, user) {
asd = "invalid USERNAME";
console.log(asd);
if(err){
return res.serverError('error creating user' + err);
}
if(user){
asd = "invalid USERNAME";
console.log(asd);
return res.json({status: "INVALID_USERNAME"});
}
});
User.findOne({email: email}, function (err, user) {
asd = "invalid EMAIL";
console.log(asd);
if(err){
return res.serverError('error creating user' + err);
}
if(user){
asd = "invalid EMAIL";
console.log(asd);
res.json({status: "INVALID_EMAIL"});
}
});
// Create the user
User.create({.....});
Nevertheless, I never get in the findOne methods, even though the user with the provided credentials does exist in the database. I tried debugging, and I don't get in the statement. I even put this asd variable, just to check if smth happens, but unsuccessfully. And the user keeps being created again and again, with the same credentials.
Any thoughts on what am I missing?

You need to put the create inside the callback
User.findOne(...).exec(
function(err,user){
if(!user) User.create(...)
});
But as others have commented there might not be a need for this workaround. In the issue you linked, they explain the it only happens with
migrate: safe
set either config/models.js or chosen in the command line interface.
So just set it to something else. It is enough to set it once, run sails lift, and change it back to safe if you prefer

Related

Mongoose save method seems to not be working

I am trying to create a REST API. I am pretty new to the back end and am just practicing on my own for the time being. For my code, I know it's bad practice to store the plain text password but again, this is completely for practice and will never go live. I will also add encryption at a later point for practice.
My issue is I am not sure why my API does not work. I see where it fails, it fails in the catch block when I try to save a user but I do not get any error to tell me what is wrong exactly, besides the once I force. I have another part on this website that follows almost the exact same logic and it works perfectly but for this one it does not. I have no idea how to solve my issue but after googling I still cannot figure it out. It looks perfectly fine too me, but as mentioned I am pretty new to the backend.
This is my controller function:
const signup = async (req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return next(new HttpError('Invalid inputs passed, please check your data', 422));
}
const { name, email, password, places } = req.body;
let existingUser;
try {
existingUser = await User.findOne({email: email}) // finds one document matching our criteria we set
} catch(err) {
const error = new HttpError('Signing up failed, please try again later', 500);
return next(error);
}
if (existingUser) {
const error = new HttpError('User exists already, please login instead', 422);
return next(error);
}
const createdUser = new User({
name,
email,
image: 'https://images.pexels.com/photos/220453/pexels-photo-220453.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260',
password,
places
});
try {
await createdUser.save();
} catch(err) {
const error = new HttpError(
'Signing up failed', 500
);
return next(error);
}
res.status(201).json({user: createdUser.toObject({ getters:true })});
};
I use Postman to send the request to my API endpoint with all of the correct information. Based on what I recieve back it is failing in the try catch block of await createdUser.save()
For anyone who finds this from google this was my solution:
First I suggest you add this into your save method to try and diagnose the problem
await createdUser.save(function(err){
if(err){
console.log(err);
return;
}
});
This help me greatly as it gave me more information on how to solve it.It turns out my problem was because I misspelled a field in my Schema. So extremely simple solution!

How to stop the user from entering the duplicate record on default save

I have a custom module where there is an email field. Now i want to stop the user if the email is already in the database.
I want to stop the user on save button and show the error. Like when a required field goes empty.
I tried to get some help but was not able to understand it.
Note: I realized after posting this that you are using suitecrm which this answer will not be applicable toward but I will leave it in case anyone using Sugar has this question.
There are a couple of ways to accomplish this so I'll do my best to walk through them in the order I would recommend. This would apply if you are using a version of Sugar post 7.0.0.
1) The first route is to manually create an email address relationship. This approach would use the out of box features which will ensure your system only keeps track of a single email address. If that would work for your needs, you can review this cookbook article and let me know if you have any questions:
https://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_9.2/Cookbook/Adding_the_Email_Field_to_a_Bean/
2) The second approach, where you are using a custom field, is to use field validation. Documentation on field validation can be found here:
https://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_9.2/Cookbook/Adding_Field_Validation_to_the_Record_View/index.html
The code example I would focus on is:
https://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_9.2/Cookbook/Adding_Field_Validation_to_the_Record_View/#Method_1_Extending_the_RecordView_and_CreateView_Controllers
For your example, I would imagine you would do something like this:
Create a language key for your error message:
./custom/Extension/application/Ext/Language/en_us.error_email_exists_message.php
<?php
$app_strings['ERROR_EMAIL_EXISTS_MESSAGE'] = 'This email already exists.';
Create a custom controller for the record creation (you may also want to do this in your record.js):
./custom/modules//clients/base/views/create/create.js
({
extendsFrom: 'RecordView',
initialize: function (options) {
this._super('initialize', [options]);
//reference your language key here
app.error.errorName2Keys['email_exists'] = 'ERROR_EMAIL_EXISTS_MESSAGE';
//add validation tasks
this.model.addValidationTask('check_email', _.bind(this._doValidateEmail, this));
},
_doValidateEmail: function(fields, errors, callback) {
var emailAddress = this.model.get('your_email_field');
//this may take some time so lets give the user an alert message
app.alert.show('email-check', {
level: 'process',
title: 'Checking for existing email address...'
});
//make an api call to a custom (or stock) endpoint of your choosing to see if the email exists
app.api.call('read', app.api.buildURL("your_custom_endpoint/"+emailAddress), {}, {
success: _.bind(function (response) {
//dismiss the alert
app.alert.dismiss('email-check');
//analyze your response here
if (response == '<email exists>') {
errors['your_email_field'] = errors['your_email_field'] || {};
errors['your_email_field'].email_exists = true;
}
callback(null, fields, errors);
}, this),
error: _.bind(function (response) {
//dismiss the alert
app.alert.dismiss('email-check');
//throw an error alert
app.alert.show('email-check-error', {
level: 'error',
messages: "There was an error!",
autoClose: false
});
callback(null, fields, errors);
})
});
},
})
Obviously, this isn't a fully working example but it should get you most of the way there. Hope this helps!

How do I remove a user in mongoDB from the terminal by username?

My question is this: How can I remove a user from the users db by username, or at all even?
I have a meteor application with a custom registration, and when an account is created you can login and manage your account and what have you.. My problem is that, on the local host for testing, I created a few extra user accounts that I want to delete individually (not a complete reset). I am on OS X so I went to terminal, typed in 'show dbs' but users came up empty and when I typed 'show users' nothing came up. If I type 'db.users.findOne()' information appears and I can get a username and _id. I know there is users and this command shows that there is at least one but the rest of the commands indicate that I can't manage them.
Below is some code for the registration page, specifically the Accounts.createUser I'm not sure it will mater for the response but I wanted to be thorough.
Template.SignUp.events({
'submit form': function(event, template){
event.preventDefault();
var UsernameVar = template.find('#username').value;
var emailVar = template.find('#Email').value;
var passwordVar = template.find('#password').value;
var ConfirmPasswordVar = template.find('#Cpassword').value;
if(ConfirmPasswordVar == passwordVar)
{
document.getElementById("NotValid").style.display = 'none';
Accounts.createUser({
username: UsernameVar,
email: emailVar,
password: passwordVar
}, function(err, result){
if(err)
{
document.getElementById("Unavailable").style.display = 'block';
}
else{
document.getElementById("Unavailable").style.display = 'none';
}
});
}
else{
document.getElementById("NotValid").style.display = 'block';
}
}
});
I've done a lot of searching on this issue and all I've found is how to grant users the right to remove profiles but I want to do it from terminal, even when the application launches I will be the only one to be using this feature so I don't want to start giving those rights to users.
If there is anything else I should provide please let me know.
meteor mongo
db.users.find({username: "someusername"}) // ensure that your query returns the correct user that you want to remove
db.users.remove({username: "someusername"})

Sails.js Can't set headers after they are sent

I am using sailsjs v0.10.5.
I am trying to redirect to login after verifying user email and update the database before redirect.
I am using redirection in my update callback. But it sending the error after updating the database
'Cant send headers after they are sent'.
The following is the code am using for redirection:
verifyEmail: function(req, res){
var userId = req.param('userId');
User.update({id: userId},{isVerified: true}).exec(function(err, user) {
if (!err) {
req.flash('error', 'Your email is verified please login');
res.redirect('/login'); }else { return res.send(user, 400); }
});
Update waterline function is asynchronous, are you sure there isnt some res method later in the scope that may be fired before?
Its recommended to use return res.* for so-called "terminal methods" see http://sailsjs.org/#/documentation/reference/res/res.forbidden.html?q=notes

Mongoose + Everyauth weird behavior

Using everyauth, when I login with a never autenticated before user on my website, the following code is launched. Checks if the user is already in my mongodb, if not it writes it. The issue right now is that works for the first authenticated user, then if a second user logins, my joiningUser._id parameters is properly initiated, but all the other parameters of my schema are from the first ever saved user, its like my parameters are never reinitialised... weird, my console.log shows the right new parameters, and not what is actually written in the database. My authentication is done via the everyauth module, I use the express framework.
exports.findOrCreateFacebookUser = function(fbUserData, promise){
User.findOne({_id:fbUserData.id}, function(err, user) {
if(err) {
console.log("Error in finding user for auth. Check Db");
promise.fail(err);
return;
}
else if(user){
console.log("User found ");
promise.fulfill(user);
}
else{
var joiningUser = new User();
joiningUser._id = fbUserData.id;
joiningUser.firstName = fbUserData.first_name;
joiningUser.lastName = fbUserData.last_name;
joiningUser.email = fbUserData.email;
//console.log(JSON.stringify(joiningUser));
joiningUser.save(function(err){
if(err){
console.log("Couldnt save new user: " + err);
promise.fail(err);
return;
}
else{
console.log("User wasnt existant, it is now created: " + JSON.stringify(joiningUser));
promise.fulfill(joiningUser);
}
});
}
});
};
Use mongoose-auth. It takes care of the combination of mongoose and everyauth for you.
There seems to be an issue with assigning _id with a forced value. So I created another id for the profile specific id (ex: facebookId).