sailsjs: Avoid saving some form inputs in database - node.js

I am trying to make a signup page, following irl nathans guide. Now everything works, however sail.js seems to save everything from the form in the database. For an example, I have this form:
<form class="form-signup" name="signup-form" action="/user/create" method="POST">
<input type="text" name="username" placeholder="<%= __('username') %>"> %>">
<input type="text" name="email" placeholder="<%= __('email') %>">
<input type="password" name="password" placeholder="<%= __('password') %>">
<input type="password" name="confirmation" placeholder="<%= __('confirm-password') %>">
<input class="button" type="submit" value="<%= __('signup') %>"/>
<input type="hidden" name="_csrf" value="<%= _csrf %>"/>
</form>
In this example it saves both the password and the password-confirmation in the database, which it shouldn't.
In my User.js model I have the following attributes, but these are just saved alongside the two passwords. I also have an encryptedPassword, that encrypts the password if they match.
module.exports = {
attributes: {
username: {
type: 'string',
required: true,
unique: true
},
email: {
type: 'string',
required: true,
isEmail: true,
unique: true
},
encryptedPassword: {
type: 'string'
},
// more unimportant code here.
}
I would like to know whether and it is possible to prevent sails.js from saving the two unencrypted passwords in the database whenever the form is submitted. I know I can just remove it afterwards from the database, however, that seems kind of stupid.
The saved record in the database, when submitted:
{
"username": "testuser",
"password": "2",
"confirmation": "2",
"email": "myemail#email.com",
"createdAt": 1496268539155,
"updatedAt": 1496268539155,
"encryptedPassword": "$2a$10$BkwvQnu3TA4DQ1kDMZmi6O7Z/K5uX90fHi/6zkZF.nkKi8MU.zWTS",
"id": "592f3efbaa4d2563e159dc20"
}
Since I am encrypting the password, it shouldn't also save the unencrypted passwords, just because they were part of the submit form. How do I prevent it from doing so?

Where you setup your db connection (connections.js or in your /env/development.js) specify schema: true
For example:
someDbServer: {
adapter: 'sails-mongo',
host: 'localhost',
port: 27017,
user: 'username',
password: 'pwd',
database: 'db_name',
schema: true
}
Setting schema to true means only attributes in the model js file can be inserted.
For encrypting your password you want to do that in beforeCreate and beforeUpdate. Take a look at lifecycle callbacks -sailsjs lifecycle callbacks

Thank you for the answers, however, I managed to solve the problem by passing an object to the .create() function. This object contains all the parameters I want to save, instead of using req.params.all().
var userObj = {
username : req.param('username'),
firstname : req.param('firstname'),
encryptedPassword : password,
surname : req.param('surname'),
email : req.param('email')
}

Related

Assign a value to a [(ngModel)] input

new to MEAN stack here,
I'm trying to insert datas into MongoDB, but with the _id of the connected user, so I have a function which display it :
getSessionInfos(){
return sessionStorage.getItem('id');
}
db.collection('transactions').insertOne({
date : req.body.date,
titre: req.body.titre,
description : req.body.description,
montant : "-" + req.body.montant,
id: req.body.id, <-------------
type: "debit"
So I thought to myself, alright, I'm gonna create a hidden input with the ID as a value, it's gonna be easier :
<input type="text" [(ngModel)]="data.id" value="getSessionInfos()">
Except that NO, it seems that you can't change the value of a NGmodel input,
So how am I supposed to do that ?
Thanks a lot
<input [hidden]='true' type="text" [(ngModel)]="data?.id" >
data: any = {
date: "",
titre: "",
description: "",
montant: "",
id: sessionStorage.getItem('id'),
type: ""
}
<ng-container *ngfor="let dataa in data"><input [hidden]='true' type="text" [(ngModel)]="dataa.id" (change)="getSessionInfos()"></ng-container>

html form input name for mongoose

MongoDB
{
"_id" : ObjectId("5bfac9c5c44526e73f960e89"),
"brand" : "Under Armour",
"amazon" : {
"order" : "666-666-666",
"id" : "B072LNJPS1"
}
...
}
HTML
<form....>
<input class="form-control" type="text" name="brand">
<input class="form-control" type="text" name="amazon.id">
<input class="form-control" type="text" name="amazon.order">
...
</form>
NodeJs
const myPost = request.body
const query = { _id: request.body._id }
const options = { upsert: true, new: true }
await model.findOneAndUpdate(query, myPost, options);
I have this error message because of the '.' in the field name
errmsg: 'Updating the path 'amazon.id' would create a conflict at 'amazon''
You have tips for the field name to match the model structure
This may not be a complete answer, but you need to replace "amazon.id" with "amazon[id]" to match the nested structure.
Reference: Colt Steele's "The Web Developer Bootcamp"

How can I access an object from a Mongoose Schema through the form?

I have this mongoose schema:
var mongoose = require("mongoose"),
passportLocalMongoose = require("passport-local-mongoose");
let userSchema = new mongoose.Schema({
username:
{type: String,
unique: true
},
password: String,
privileges:
{
region: [Number],
read: [Boolean],
write: [Boolean],
edit: [Boolean],
delete: [Boolean]
}
});
userSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", userSchema);
and I'm using this with the following form:
<form action="/register" method="POST">
<input type="text" name="username"><br/>
<input type="password" name="password"><br/>
<input type="text" name="privileges.region"><br/>
<input type="text" name="privileges.read"><br/>
<input type="text" name="privileges.write"><br/>
<input type="text" name="privileges.edit"><br/>
<input type="text" name="privileges.delete"><br/>
<button>Submit</button>
</form>
I suppose the name is okay because privileges is an object, so every property should be accessed with the dot notation. If it's not, please let me know.
req.body looks like this:
When I try to console.log(req.body.privileges.region) or any other property, I get undefined. How should I access one of the privileges objects properties? Thanks.
The keys for the dictionary coming back on the request are actually the strings: 'privileges.region', 'privileges.delete', etc. So you must access them as
req.body['privileges.region']
People will generally write a helper function that handles this sort of notation to map it back their original model. Or they might do the mapping when the form is submitted in the browser in order to get the data in the shape you really want it:
{username
permissions:{region, ...}
...
}

Getting "Cannot POST" with registration page using Sequelize

I'm sure there's a sound reason as to why I can't get this to work but I've been staring at the code for a long time and I'm brutally stuck. I'm trying to build out a very basic registration form that should store the data in my PostgreSQL database. I'm using bcrypt to hash out the password, but even without still having issues.
My HTML has the following:
<form action="/register/new" method="post">
<label for="username">Username</label>
<input type="text" name="username">
<label for="password">Password</label>
<input type="password" name="password">
<label for="confirm">Confirm Password</label>
<input type="password" name="confirm">
<button type="submit">Submit</button>
</form>
Then for the code I have:
app.get("/register", function(req,res){
res.render("register");
})
app.post('register', function(req,res){
let newUser = {
username: req.body.username,
passwordHash: bcrypt.hashSynce(req.body.password, 8)
}
models.Users.create(newUser).then(function(){
res.redirect('/login');
})
});
The plan for the registration data to be stored and the user redirected to the login page, login stores them in session, and so on. I thought for a bit that the issue was the action on the form but regardless I'm getting Cannot POST /register/new. I've also played around with doing a findOrCreate and do a comparison but I wanted to start with actually just creating before I make it more complex. The same issue occurs with cannot post.
Any thoughts on what I need to change?
Probably would've worked better if I did a app.post("/register"...
Simple miss of an "/"
try this modified code...
app.post('/register', function(req,res) {
let newUser = {
username: req.body.username,
passwordHash: bcrypt.hashSync(req.body.password, 8)
}
// if it does not connect/save try using models.User instead of models.Users below.
models.Users.create(newUser).then(function(){
res.location('/login');
res.redirect('/login');
})
});

How search value inside an object in Redis?

I'm newbie to Redis and Nodejs, I've watched this tutorial and i'm trying to search users by name,
Here is the object, returned from redis when i pass the id:
{
first_name: '‪john',
last_name: 'doe',
email: 'john#gmail.com',
phone: '543313305',
id: 'user001'
}
Here is the function of the search :
app.post('/user/search',function (req,res,next) {
let id = req.body.id;
client.hgetall(id ,function(err,obj){
if(!obj){
res.render('searchusers',{
error:"user doesn't exist",
});
} else {
obj.id = id
console.log(obj);
res.render('details',{
user:obj, });
}
});
});
I've tried to replace the search by id to search by first_name by doing this:
First I've changed the field name to "first_name" instead of "id"
<h1>Search Users</h1>
{{#if error}} <span>{{error}}</span>{{/if}}
<form class="form-inline" method="POST" action="/user/search">
<div class="form-group">
<input type="text" name="first_name" placeholder="Search" class="form-
control">
</div>
<input type="submit" class="btn btn-primary" value="Search">
And than I've changed it in the app.js ;
app.post('/user/search',function (req,res,next) {
let first_name = req.body.first_name;
client.hgetall(first_name ,function(err,obj){
if(!obj){
res.render('searchusers',{
error:"user doesn't exist",
});
} else {
obj.first_name = first_name
console.log(obj);
res.render('details',{
user:obj, });
}
});
});
The hgetall method that you are using in the search function of the method looks up a hash by the key, which in this case is the user id and returns all of the fields of the hash from Redis.
There is no function to search over the fields of the hash. If you need to be able to map from a first name to a user, you will need to manually build a secondary index using a data structure such as sets, that allows you to go from first name to the users that have that first name.

Resources