How to fix "trim" not working in mongoose schemas - javascript

I'm learning mongoose and tried setting "trim" to true inside a mongoose schema. However it is not working as expected.
I've tried setting other things like "lowercase" to true and it does work, so I don't know why "trim" isn't working.
var userSchema = {
name: {type: String, required: true, trim: true, lowercase: true},
email: {
type: String,
required: true,
validate: function(value){
if(!(validator.isEmail(value))){
throw new Error("Not a valid email address");
}
},
trim: true,
},
age: {
type: Number,
validate: function(value){
if(value < 0){
throw new Error("Age must be a positive number");
}
},
default: 0
},
password: {
type: String,
required: true,
minlength: 7,
validate: function(value){
if(value.toLowerCase().includes("password")){
throw new Error(" Passwords should not contain the word
'password ' ");
}
},
trim: true
}
}
var User = mongoose.model('User', userSchema);
var someuser = new User({
name: "some user",
age: 25,
email: "user#something.com",
password: "verysecurepassword"
})
I expected an the name of the new user to be 'someuser', but instead it turned out to be 'some user'.

Name "some user" has space in the middle of the string.
What you are trying to do will not work as trim will remove whitespaces from start and end of string only.

Please check trim() definition in the docs, it seems like you're trying to remove unwanted characters in the middle of the string, but trim() removes them only at the start and at the end of the string MongoDocs
I would suggest you to define a custom settermiddleware or preSavemiddleware docs hook for this and transform string using regex (if you want to remove only spaces): str.replace( /\s\s+/g, ' ' )

Related

mongoose Schema max property has no effect

const mongoose = require("mongoose");
const PostSchema = new mongoose.Schema(
{
user_id: {
type: String,
required: true,
},
content: {
type: String,
max: 150,
required: true,
},
},
{
timestamps: true,
}
);
As defined above, I can nevertheless push content that has more than 150 characters. What is wrong with how the Query is defined?
Type string does not have “max”, instead use “maxLength”:
maxLength: 150,
Documentation about validation that mentions this.
Hopefully that helps!

Node, Mongoose - $or operator not functioning as expected

Within my express app, I have a mongoose schema like so:
User model schema:
const userSchema = new mongoose.Schema({
username: {
type: String,
required: true,
unique: true,
minlength: 4,
maxlength: 50
},
email: {
type: String,
required: true,
minlength: 3,
maxlength: 255,
unique: true
},
password: {
type: String,
required: true,
minlength: 6,
},
})
Here is an operation I do in one of my endpoints. I expect a user to be returned if req.body.usernameOrEmail matches a username or email of a User. Here is the operation:
let user = await User.find({ $or: [ { username: req.body.usernameOrEmail }, { email: req.body.usernameOrEmail } ] })
if (!user) return res.send('No user found')
What happens is that if I put anything req.body.usernameOrEmail, the 'No user found' message is not printed as expected. Anybody know whats going wrong with the operation performed above? Thanks.
awaited .find() method returns an empty array which is truthy in JavaScript, try:
console.log(![])
You can use .findOne() instead and in that case null will be returned when there's no match and your condition will work

Is secure return salt data of user model?

In a MEAN app i define my user model and encrypt the password using the fields hash and salt like these:
var mongoose = require('mongoose');
var crypto = require('crypto');
var jwt = require('jsonwebtoken');
var UsersSchema = new mongoose.Schema({
personalId: {
type: String,
unique: "Personal Id already exists",
required: true
},
name: {
type: String,
required: true
},
surname:{
type: String,
required: true
},
username: {
type: String,
unique: "Username already exists",
required: "Please fill in a username",
lowercase: true
},
hash: String,
salt: String,
email:{
type: String,
unique: true,
lowercase: true,
trim: true
},
contract:{
type: String
},
role:{
type: String,
required: true
},
dateUpdated: {
type: Date
},
dateCreated: {
type: Date,
default: Date.now
}
});
UsersSchema.methods.setPassword = function (password) {
this.salt = crypto.randomBytes(16).toString('hex');
this.hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha512').toString('hex');
};
UsersSchema.methods.validPassword = function (password) {
var hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha512').toString('hex');
return this.hash === hash;
};
UsersSchema.methods.generateJwt = function () {
var expiry = new Date();
expiry.setDate(expiry.getDate() + 7);
return jwt.sign({
_id: this._id,
username: this.username,
exp: parseInt(expiry.getTime() / 1000),
}, "MY_SECRET"); // DO NOT KEEP YOUR SECRET IN THE CODE!
};
mongoose.model('Users', UsersSchema);
When i create a new user, return the object user complete (all values),
when i get list of users too return all values for each user.
My question is: Is correct return salt and hash values when i ask for users objects ?
Correct or not, just make sure you're not leaking the user object in app logs. You may want to have another table though just to link users and passwords instead of having it all in the users object.

My schema for Meteor.users fails validation every time

I'm using the collection2 package as seen here: https://github.com/aldeed/meteor-collection2
I've set up a simple schema wherein only email is a non-optional value, but despite this simpleness the validation fails every time claiming that "Email is required".
My schema:
Schema.UserProfile = new SimpleSchema({
firstName: {
type: String,
regEx: /^[a-zA-Z-]{2,25}$/,
optional: true
},
lastName: {
type: String,
regEx: /^[a-zA-Z]{2,25}$/,
optional: true
},
birthday: {
type: Date,
optional: true
},
likes: {
type: [String],
optional: true
}
})
Schema.User = new SimpleSchema({
username: {
type: String,
regEx: /^[a-z0-9A-Z_]{3,15}$/,
optional: true
},
email: {
type: String,
regEx: SimpleSchema.RegEx.Email
},
verified: {
type: Boolean,
optional: true
},
createdAt: {
type: Date,
optional: true
},
profile: {
type: Schema.UserProfile,
optional: true
},
services: {
type: Object,
optional: true,
blackbox: true
}
})
I set it like so:
Meteor.users.attachSchema(Schema.User)
And just to check it I hardcode a value to add a user with a perfectly fine email address:
Accounts.createUser({email: "fdfs#fdsfs.com"})
But when I run this a big exception is returned, saying, among other things:
Exception while invoking method 'registerUser` Error: Email is required
at getErrorObject <packages/aldeed:collection2/collection2.js:369:1>
Sanitized and reported to the client as: Email is required [400]
What am I missing?
As you can see in the docs, user.emails is an an array of objects with the properties verified and address.
So try something like this instead:
emails: {
type: [Object],
optional: true
},
'emails.$.address': {
type: String,
regEx: SimpleSchema.RegEx.Email
},
'emails.$.verified': {
type: Boolean
},

Unique index not working on Mongoose schema

I have a schema setup like this:
var UserSchema = new Schema({
id: {type: String, required: true, unique: true, index: true, default: mongoose.Types.ObjectId},
name: { type: String, required: true },
email: { type: String, required: true, unique: true, index: true },
mobile: { type: String, unique: true, sparse: true },
password: { type: String, required: true }
});
Seems to work great except the email field is letting in duplicates, despite have unique:true set. I do the following:
User.create({
name: req.body.name,
email: req.body.email,
mobile: req.body.mobile,
password: password
}, function(err, user) {
if (err) return res.send({ invalid : true });
});
If req.body.email is a value that's already in the database, the query above should return err. But it doesn't, it creates the new user perfectly fine, resulting in duplicate emails in the database.
Why is this happening?
mongo and hence mongoose will assign an automatic id fields to your document. usually that is "_id".
Try removing the "id" from your schema to fix your issue.

Categories

Resources