Meteor - How to use use server side validation on password - javascript

I'm performing server-side validation in the "Accounts.onCreateUser" function so that I can pass the options object as well. I wasn't able to figure out how to do this with the validate user function.
First, I'm totally open for correct if I'm going the wrong direction so please advise.
I can't figure out how to validate password length server-side. Is it because it's already converted prior to the creation? When testing, if I enter in a single character for password it doesn't throw an error.
Accounts.onCreateUser(function (options, user) {
if (options.profile) {
user.profile = options.profile;
user.profile.user_status = "new user";
}
// Error checking
var errors = "";
if (user.username.length === 0) {
errors = errors + '<li>Email is required</li>';
}
if (user.username.length !== 0 && user.username.length < 4) {
errors = errors + '<li>Email too short</li>';
}
if (user.profile.firstname.length === 0) {
errors = errors + '<li>First name is required</li>';
}
if (user.profile.firstname.length !== 0 && user.profile.firstname.length < 2) {
errors = errors + '<li>First name is too short</li>';
}
if (user.profile.lastname.length === 0) {
errors = errors + '<li>Last name is required</li>';
}
if (user.profile.lastname.length !== 0 && user.profile.lastname.length < 2) {
errors = errors + '<li>Last name is too short</li>';
}
if (user.services.password.length === 0) {
errors = errors + '<li>Please enter a password</li>';
}
if (user.services.password.length < 7) {
errors = errors + '<li>Password requires 7 or more characters</li>';
}
if (errors) {
throw new Meteor.Error(403, errors);
} else {
return user;
}
});
I'm not using Accounts-ui. Trying to roll out my own... Being completely new with Meteor it has been a bit of a battle trying to understand account creation and verification. If there's a way to do this with ValidateNewUser function should I be using that instead?
Thank you for all your help.

I've figured out the best manner to perform this. Hope this will help others.
I'm using a method on server side to validate and returning error if there is one. Then proceeding with the Account Creation.
Meteor.call('Validate_Registration', email, password, cpassword, firstname, lastname, terms, function(error) {
if (error) {
error = error.reason;
$('#Error-Block').fadeIn().children('ul').html(error);
console.log(error);
} else {
Accounts.createUser({
username: email,
email: email,
password: password,
profile: {
firstname: firstname,
lastname: lastname
}
}, function(error) {
if (error) {
error = error.reason;
$('#Error-Block').fadeIn().children('ul').html(error);
} else {
var uid = Accounts.connection.userId();
Meteor.call('Verify_Email', uid, email);
Router.go('/email-instructions');
}
});
}
});
The only thing I'm unsure of at this point is if it's correct to use:
var uid = Accounts.connection.userId();
This seems to be local to the current user only, and is stored in local storage to the user.

Accounts-password uses SRP, which is a bit complicated so I won't describe it fully here. The actual check of the hashed tokens happens around here Basically, the password does not arrive at the server as a plain text string therefore you will not be able to enforce password policy on the server, while using SRP.
Also notably around here there is a DDP only "plaintext" login option for those who (understandably) don't want to implement SRP on their own. As advertised, it should only be used if the user is connected w/ SSL. I would probably start there.
In the meantime, you can at least do some client side enforcing until you can roll your server-side login handler.
You may also want to check out this meteorhacks article for a custom login handler tutorial.

According to the documentation, the password "is not sent in plain text over the wire", so the password string you're looking at on the server side is not the same as what the user typed in.
EDIT: At least, that's what I think.
EDIT2: Found a comment in another question that confirms it.

Related

Firebase checking two different database refs despite a if check

I am trying to seperate two different logins for the different types of users that are in the account. One of the users is a regular consumer who is able to search through the app. The other is a business dashboard where businesses get to see what users are checkedin to their business.
The problem is that when I check my two different database references, it seems it checks both of them instead of validating the first check and proceeds to pull and error saying one of my nodes is null.
The case it apprently fails is the first if check but in my database the node userType is set properly:
The problem seems to be it auth().onStateChanged where it looks for the uid of in both database references. When I try to login with a business account it successfully enters that statement and redirects, when I log in with a consumer account it tries to check the business refs if and then pulls out the error userType is null cannot read
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// This prompts the user to allow for location access
// When logged in it would allow us to show the
// nearby businesses to the user
var uid = user.uid
if(window.navigator.geolocation) {
window.navigator.geolocation.getCurrentPosition(function(position){
})
}
var uid = user.uid
console.log(uid)
business.child(uid).on("value", snap => {
if(snap.val().userType == "business") {
alert("This is not a consumer account!")
firebase.auth().signOut()
window.location.href = "businesslogin.html"
} else {
consumer.child(uid).on("value", snap => {
if(snap.val().userType == "consumer") {
if(snap.val().isPhoneVerified == true) {
window.location.href = 'nearbyBusinesses.html'
} else {
window.location.href = 'loginVerification.html'
}
if(snap.val().isUserCheckedin == true){
window.location.href = "leave.html" + '#' + snap.val().checkedInBusinessId
} else {
window.location.href = "nearbyBusinesses.html"
}
}
})
}
})
}
})
The bug is in this line if(snap.val() == "business"). It needs to be if(snap.val().userType == "business"). Atleast that is what i can see imediately. Try that and see if it solves your problem

JSON file messing up

I am making a Twitch bot in node.js and I have ran into a few weird issues.
I have a JSON file system set up, which can be manipulated via commands in the chat. However, for some reason, the JSON file's formatting messes up terribly upon inputting wrong data (such as not defining the user or giving letters/characters instead of a number). A well formatted JSON file will turn into a one-line monster and will often totally mess up the file contents when inputting even more wrong stuff.
The weird part is, that I have set up a detection system for wrong input which should return an error message and ignore writing to the JSON file, however that does not work for some reason (Error message appears, JSON file still changes).
I am a pretty novice programmer so go easy If I may ask.
if (userName === "xyz1" || userName === "xyz2") { // censored for privacy
if (!args[0] || !args[1]) return client.say(channelName, 'You did not specify the user or the value)!');
const user = args[0].toLowerCase();
const giveRaw = args[1];
if (!giveRaw.match(/^[0-9]+$/)) return client.say(channelName, 'Your amount cannot contain letters/symbols/decimals!');
const giveInt = parseInt(giveRaw);
if (pointsjson.hasOwnProperty(user)) {
pointsjson[user] = {
points: pointsjson[user].points + giveInt
}
fs.writeFile('./system/points.json', JSON.stringify(pointsjson, null, 10), err => { // write to json
if (err) throw err;
});
client.say(channelName, `Added ${giveInt} coins to ${user}'s balance.`);
} else if (pointsjson.hasOwnProperty(user) === false) {
pointsjson[user] = {
points: giveInt
}
fs.writeFile("./system/points.json", JSON.stringify(pointsjson, null, 10), err => { // write to json
if (err) throw err;
});
client.say(channelName, `Added ${giveInt} coins to ${user}'s balance. (User has no record in database, added points anyways, did you input the name correctly?)`);
}
} else if (userName !== 'xyz1' && userName !== 'xyz2') return client.say(channelName, "Can't do that broski! (Developer only command.)");
Solved the problem. Apparently I messed up JSON.stringify() somewhere in my code, which got triggered every time a message was sent. I feel so dumb.

Azure - Server Validation

Okay, so I am attempting to validate on the server side. I am using Windows Azure Mobile Services for my Android application. The validation is done in Javascript / Node.js.
I have been doing my best to find solutions to my issue and stumbled upon [this link] (http://blogs.msdn.com/b/carlosfigueira/archive/2012/09/21/playing-with-the-query-object-in-read-operations-on-azure-mobile-services.aspx)!
I intend to use regexp to validate the object before persisting it to the DB.
I would understand how to do this 'pre-query' but as I need access to use regex, I must perform 'post-query' filtering.
Below is the code in which I have (so far) but I want to know how can I validate many fields and deliver appropriate error messages for each invalid fields. If all are valid, then persist to the DB.
Thanks in advance!
function insert(item, user, request) {
var userTable = tables.getTable('User');
userTable.where({email: item.email}).read({
success: emailExists
});
function emailExists(existingItems)
{
if (existingItems.length > 0)
{
request.respond(statusCodes.CONFLICT,
"An account is already registered with this email!.");
}
else
{
// Insert the item as normal.
request.execute({
success: function (results)
{
var regexEmail = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
var filtered = results.filter(function(item)
{
return regexEmail.test(item.email);
});
request.respond(statusCodes.OK, filtered);
}
});
}
}
}
If I understand what you want to do correctly, you first need to validate the input's e-mail against the items in the database (to maintain unicity), then validate other fields in the input before inserting that. If that's the case, then after the query validation (to prevent duplicate e-mails) you can validate the item fields individually, as shown in this document. The code below shows an example of such validation.
function insert(item, user, request) {
var userTable = tables.getTable('User');
userTable.where({email: item.email}).read({
success: emailExists
});
function emailExists(existingItems)
{
if (existingItems.length > 0)
{
request.respond(statusCodes.CONFLICT,
"An account is already registered with this email!.");
}
else
{
// Validate fields *before* inserting
var regexEmail = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (!regexEmail.test(item.email)) {
request.respond(statusCodes.BAD_REQUEST, { error: 'E-mail is invalid' });
return;
}
if (!item.name || item.name.length < 10) {
request.respond(statusCodes.BAD_REQUEST, { error: 'Item must have a name of at least 10 characters' });
return;
}
// If all validation succeeded, then insert the item
request.execute();
}
}
}

Geddy Save User

I am currently involved helping out on a project which involves using the Geddy js framework, which it is my first time using. I am currently trying to fix the create method inside a model for users. Here is the code below:
this.create = function (req, resp, params) {
var self = this
, user = geddy.model.User.create(params);
//need to ensure that the user agrees with the terms and conditions.
// Non-blocking uniqueness checks are hard
geddy.model.User.first({username: user.username}, function(err, data) {
if (data) {
params.errors = {
username: 'This username is already in use.'
};
//self.transfer('add');
}
else {
if (user.isValid()) {
user.password = cryptPass(user.password);
user.suburb = "";
user.state = "";
user.postcode = "";
}
user.save(function(err, data) {
if (err) {
params.errors = err;
self.transfer('add');
}
else {
// setup e-mail data with unicode symbols
var mailOptions = {
from: "App ✔ <hello#app.com>", // sender address
to: user.email, // list of receivers
subject: user.username + " Thank you for Signing Up ✔", // Subject line
text: "Please log in and start shopping! ✔", // plaintext body
html: "<b>Please log in and start shopping!✔</b>" // html body
}
smtpTransport.sendMail(mailOptions, function(error, response){
if(error){
console.log(error);
}else{
console.log("Message sent: " + response.message);
}
// if you don't want to use this transport object anymore, uncomment following line
smtpTransport.close(); // shut down the connection pool, no more messages
});
self.redirect({controller: self.name});
}
});
}
});
};
If you look in the code there is apparently a check to see if the so-called user is valid like so: if (user.isValid()) {
user.password = cryptPass(user.password);
user.suburb = "";
user.state = "";
user.postcode = "";
}
The proceeds on to 'save' regardless whether or not the user is valid. I'm thinking why is the code this way? It sounds nonsensical. I asked the original developer who was on the project about it and he said the model was apparently generated when he created the project.
So in bit of a confused state, if anyone can tell me why the save method is outside the if statement in the first place? Is it something the original creators of Geddy intended? or is really nonsensical and I should change it?
Thanks.
Geddy's save() call will error out if the data is invalid (unless force flag is set, which it isn't). It uses the same isValid() call actually. So, looks like what you have here is just someone's way to have a single error handler for all the error cases.
For user.password being set with crypted data only if the data looks valid, I'm guessing this is simply to make 'must be set' type of validation to work. Chances are that even with an empty password, the crypted string would be otherwise counted as set.

Get User Account Active Directory Group in Windows 8 app

I have been struggling with this problem all day.
I am developing a Windows 8 app using JavaScript and HTML5. I need to restrict some functionality on the app depending of the active directory group where an user account is assigned.
The question is: how I can check if a user account belongs to a Active Directory group?
I have tried using Windows.System.UserProfile.UserInformation and Windows.Security.Credentials.UI.CredentialPicker, but none of them returns either a way to test if a user account belongs to a group, or the group where the user account is assigned.
Thanks in advance for your help.
I found a solution to perform this, which was the one I implemented, and it works. You can create a web service that validates the credentials against Active Directory, where you pass the domain, username and password, then call it from the app using WinJS.xhr. To ask for the credentials, you can use the CredentialPicker control, which returns, the domain, username, and password entered by the user.
Here is the code:
Web Service Code:
ValidateUserResult vur = new ValidateUserResult();
try
{
using (PrincipalContext context =
new PrincipalContext(ContextType.Domain, domain))
{
vur.UserCredentialsAreValid = context
.ValidateCredentials(username, password);
if (vur.UserCredentialsAreValid)
{
vur.ProcessMessageText = "Ok";
vur.ProcessMessageCode = 0;
}
else
{
vur.ProcessMessageText =
"Credenciales invalidas";
vur.ProcessMessageCode = -1;
}
}
}
catch (Exception ex)
{
vur.UserCredentialsAreValid = false;
vur.ProcessMessageText = ex.Message;
vur.ProcessMessageCode = ex.HResult;
}
return vur;
Windows 8 App:
WinJS.xhr({
type: "get"
, url: {Web Service Url}
+ "/json/{Web Service Method Name}?domain="
+ domain + "&username=" + username
+ "&password=" + password
}).then(
function (result) {
if (result.status === 200) {
// Place code here.
}
},
function (error) {
// If an error occurs, manage here
});

Categories