I read a book where an example deploys a javascript object in Node.js , in order to save and edit a User.
Is it safe to save the hashed password to an object, even if it is back-end? I think is a good practice to hash it and save it, not keep it around in an object, because I guess it will maybe be accesible.
In a simpler project I used Apache and synchronous PHP, so I got the password, hash it and save it in the database. It feels risky to me to store it in an object. I am used to keeping the id of the user in a session, so I know who she is, and thats it.
So, is it safe to keep it in an object or am I overeacting here?
This is the book's code
function User(obj){
for (var key in obj)
{this[key]=obj[key;]}
}
User.prototype.save = function (fn){
var user = this;
user.hashPassword(function (err){
var id = user.id;
//save user on redis...
})
}
User.prototype.hashPassword = function (fn){
var user = this;
bcrypt.genSalt(12, function(err,salt){
user.salt = salt;
bcrypt.hash(user.pass, salt, function(){
user.pass = hash;
fn();
})
})
To test this I add
var tobi = new User({
name:'tobi',
pass:'im a ferret'
});
tobi.save(function (err){
if (err)throw error;
})
and then hit on the console node folder/filename.js
The book is "Node.js in Action",
Mike Cantelon, Marc Harter, T.J. Holowaychuk and Nathan Rajlich, Manning Publications, ©2014, pp. 233-236
Thanks!
Related
I'm trying to pull an array of data from a MongoDB database, and while the code is rusty (and I do want some corrections on it if it could be done better or is missing something or is wrong), it should be taking the array, finding the "user" and "description" objects, and then putting them into a discord.js message.
I've tried referencing the objects individually, making them strings, parsing the data, but I still cant find out how to do it. Heres the code I've been using.
module.exports.run = async (bot, message, args) => {
const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb+srv://something:something#something/test?retryWrites=true&w=majority';
const assert = require('assert');
try {
function remindersChecker() {
let mongoClientPromise = MongoClient.connect(url, function (err, client) {
const db = client.db("reminders");
let date = new Date().getTime();
let now = Math.floor(Date.now() / 1000);
db.collection("reminders").find().toArray(function (err, result) {
let data = JSON.toObject();
console.log(data);
let user = data.author
let description = data.description
console.log(user);
user.send("I have a reminder for you! " + description)
})
})
}
remindersChecker()
} catch(err) {
catchError()
}
}}
module.exports.help = {
name: "check"
}
(The command is temporary and will be used on a setTimeout later, hence the function rather than just plain old code.)
Thanks! And I hope I can get help soon.
probably some more information would be great to better understand the problem.
from what i can see here, you are receiving an object from your database and converting it into an array here:
db.collection("reminders").find().toArray(function (err, result) {...
now that array is actually that result obtained from the callback and you are not using it at all, you probably have to iterate on that.
plus i remember that I used to write
...find({})..
to search in the database as for SELECT*FROM in SQL. maybe that can help too.
hope this helps.
I have used many services from AWS, some were easy, while some were a bit difficult. After 2 days of searching everywhere, I can say documentation for this service is misleading.
I have simple task to do. I want to change a user attribute in the Cognito pool. And to make things easy, I just need to change an Email, and thats it. Application is an Backoffice (Express/Node), where admins can change user's email.
After reading and reading, I am getting more confused. Apparently, the aws-sdk library, the one I am familiar with, has some Cognito API's that I could use. Getting a working example on how to use them, turned out to be a nightmare.
Then I found out there is a library, but only to be used on the client side. After some tweaks I got it running in Node.js. The tweak was to expose a fetch library in global Node.js namespace.
I was able to add a new user. But for all my intentions, I can't change any of the attributes (like email). The library wants me to provide Username (real user) and a password.
I do have a Username (in this case an email), but I don't have the password.
All I need to do is to connect to the service, and send new attribute for the user and thats it.
This is what I have so far (mainly hacked code samples, from variety of places), and I cant get it to work:
var poolData = {
UserPoolId : 'euXXXXXXX',
ClientId : 'XXXXXXXXXXXX'
};
var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
Ok The above line makes a connection to the existing user pool.
Now if I were to do this:
var attributeList = [];
var dataEmail = {
Name : 'email',
Value : 'email#mydomain.com'
};
var dataPhoneNumber = {
Name : 'phone_number',
Value : '+15555555555'
};
var attributeEmail = new AmazonCognitoIdentity.CognitoUserAttribute(dataEmail);
var attributePhoneNumber = new AmazonCognitoIdentity.CognitoUserAttribute(dataPhoneNumber);
attributeList.push(attributeEmail);
attributeList.push(attributePhoneNumber);
userPool.signUp('username', 'password', attributeList, null, function(err, result){
if (err) {
alert(err.message || JSON.stringify(err));
return;
}
cognitoUser = result.user;
console.log('user name is ' + cognitoUser.getUsername());
});
I can see in AWS console that the user is being added. Great.
Now how to change the attributes of the existing user?
All of examples like this and this
Suggest the following:
Use case 8. Update user attributes for an authenticated user.
var attributeList = [];
var attribute = {
Name : 'nickname',
Value : 'joe'
};
var attribute = new AmazonCognitoIdentity.CognitoUserAttribute(attribute);
attributeList.push(attribute);
cognitoUser.updateAttributes(attributeList, function(err, result) {
if (err) {
alert(err.message || JSON.stringify(err));
return;
}
console.log('call result: ' + result);
});
The problem here is I cant authenticate the user. I can't know user's password, only his email. This is after all a simple Backoffice program, where I just need to change users email.
What can I do in this case?
To update the attributes of a Cognito User Pool-user as an admin, you should use adminUpdateUserAttributes function from the aws-sdk class CognitoIdentityServiceProvider.
let AWS = require('aws-sdk');
let cognitoISP = new AWS.CognitoIdentityServiceProvider({ region: 'your-region-here' });
function updateUserAttribute(name, value, username, userPoolId){
return new Promise((resolve, reject) => {
let params = {
UserAttributes: [
{
Name: name, // name of attribute
Value: value // the new attribute value
}
],
UserPoolId: userPoolId,
Username: username
};
cognitoISP.adminUpdateUserAttributes(params, (err, data) => err ? reject(err) : resolve(data));
});
}
I am trying to pass data to Mongodb using Websocket and total.js.
In my homepage.html I can get the user input and connect to the server via websocket after clicking the save button.
In default.js is my server side code. At this point the app hat got the user input and connected to the server correctly, but how can I save data to mongodb now?
This is my homepage.html
<br />
<div>
<input type="text" name="message" placeholder="Service" maxlength="200" style="width:500px" />
<button name="send" >Save</div>
</div>
<br />
<script type="text/javascript">
var socket = null;
$(document).ready(function() {
connect();
$('button').bind('click', function() {
if (this.name === 'send') {
console.log(send());
return;
}
});
});
function connect() {
if (socket !== null)
return;
socket = new WebSocket('ws://127.0.0.1:8000/');
socket.onopen = function() {
console.log('open');
};
socket.onmessage = function(e) {
var el = $('#output');
var m = JSON.parse(decodeURIComponent(e.data)).message;
el.val(m + '\n' + el.val());
};
socket.onclose = function(e) {
// e.reason ==> total.js client.close('reason message');
console.log('close');
};
}
function send() {
var el = $('input[name="message"]');
var msg = el.val();
if (socket !== null && msg.length > 0)
socket.send(encodeURIComponent(JSON.stringify({ message: msg })));
el.val('');
return msg;
}
This is my default.js
exports.install = function(framework) {
framework.route('/', view_homepage);
framework.route('/usage/', view_usage);
framework.websocket('/', socket_homepage, ['json']);
};
function view_usage() {
var self = this;
self.plain(self.framework.usage(true));
}
function view_homepage() {
var self = this;
self.view('homepage');
}
function socket_homepage() {
var controller = this;
controller.on('open', function(client) {
console.log('Connect');
});
controller.on('message', function(client, message) {
console.log(message);
/*
var self = this;
var message = MODEL('message').schema;
var model = self.body;
var message = new message({ message: model.message }).save(function(err) {
if (err)
self.throw500(err);
// Read all messages
message.find(self.callback());
});
*/
});
controller.on('error', function(error, client) {
framework.error(error, 'websocket', controller.uri);
});
}
Any help Please!!!
This is complete project
---Update---
In this function i use to save data to MongoDB
but it didn't give any error.also Didnt save the data to database.i not sure my code is write or wrong
controller.on('message', function(client, message) {
console.log(message);
/*
var self = this;
var message = MODEL('message').schema;
var model = self.body;
var message = new message({ message: model.message }).save(function(err) {
if (err)
self.throw500(err);
// Read all messages
message.find(self.callback());
});
*/
});
This my mongoose.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://totaldemo:123456#ds029979.mongolab.com:29979/totaldemo');
global.mongoose = mongoose;
This is my user.js
var userSchema = mongoose.Schema({ user: String})
exports.schema = mongoose.model('user', userSchema,'user');
exports.name = 'user';
I don't know totaljs framework at all, but i see some issues already with plain javascript.
First of all, i suggest You set up Your model like this:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
user: String
});
module.exports = mongoose.model('User', userSchema);
and then in controller, when You import:
var User = require('path/to/user/file')
You can use it like this straight away:
User.find()
Also - i totally dont get what are You doing later.
You defined user model and exported NOTHING MORE than a STRING. Only tthing it will do is, that when You import that user to variable User, the User.name will === to 'user' string. so in Your example it would be:
var User = require('path/to/user/model/file')
console.log(User.name) // prints 'user'
and nothing more! There are no models attached to that export. Maybe its how totaljs works, but i VERY doubt it.
Later on - You try to ... use message model. Where it comes from? You defined user model, not message model.
Another thing - as i stated - i dont know totaljs, but I doubt it ask YOu to define var model, and then never use variable model.
I strongly suggest using plain node with mongoose first, then try to integrate it with any fullstack.
For sure its not a solution, but maybe it points out some problems in Your code and will help.
EDIT:
I looked quickly in totaljs, and it looks that You really should export string (which is little weird and doing magic stuff:) ), but its NOT mongoose, and i guess will ONLY work with native totaljs model solution. You cant use mongoose and totaljs like that. I dont know how much not using native totaljs models system ruins framework other options, but its probably safer to use native one.
Honestly, i dont have time to look deeper into docs, but google says nothing about sql or even mongo inside of totaljs docs... so, You have to figure it out :)
EDIT2 i found https://github.com/totaljs/examples/tree/master/mongoose and it looks weird... check if that example works (looks like You seen it, Your code is similar :)). check if You're mongod is working, check if You can conenct from plain node...
Honestly sorry, i surrender. Totaljs has to much magic and abstraction for me to help You out with this :(. Hope You will find Your answer.
i made many times questions about connections on mongodb, i cant understand many things yet, but i try...
with this connection...
db.collection('usuarios').insert(campos,{safe:true}, function(err, result)
i get a safe connection.... but mongodb pull me this warning
========================================================================================
= Please ensure that you set the default safe variable to one of the =
= allowed values of [true | false | {j:true} | {w:n, wtimeout:n} | {fsync:true}] =
= the default value is false which means the driver receives does =
= return the information of the success/error of the insert/update/remove =
= =
= ex: new Db(new Server('localhost', 27017), {safe:true}) =
= =
= http://www.mongodb.org/display/DOCS/getLastError+Command =
= =
= The default of false will change to true in the near future =
= =
= This message will disappear when the default safe is set on the driver Db =
========================================================================================
so i try this way...
var db = mongo.db("root:toor#127.0.0.1:27017/cordoba",{safe:true});
db.collection('usuarios').insert(campos,{new:true}, function(err, result)
but im not sure if this is a safe:true connection so i put like this
var db = mongo.db("root:toor#127.0.0.1:27017/cordoba",{safe:true});
db.collection('usuarios').insert(campos,{safe:true},{new:true}, function(err, result)
may be that way is safe:true but when i put safe:true before new:true mongodb returns me the old var, so i put safe:true after new:true
var db = mongo.db("root:toor#127.0.0.1:27017/cordoba",{safe:true});
db.collection('usuarios').insert(campos,{new:true},{safe:true}, function(err, result)
and works right but im not sure if it is safe:true, so i try put safe:true in new:true object like this
var db = mongo.db("root:toor#127.0.0.1:27017/cordoba",{safe:true});
db.collection('usuarios').insert(campos,{new:true,safe:true},function(err, result)
i thought that mongdb freaks out! but nothing... no error no nothing .... so i dont know how can i know when mongodb is using safe:true or not safe:true...
how can i know that??
the api is no longer {safe: true} but {w: 1} http://mongodb.github.com/node-mongodb-native/api-generated/db.html
var db = mongo.db('mongodb://127.0.0.1:27017/test', {w: 1})
{safe: true} will still work, but it's deprecated. if you set it at the DB level, you don't need to set it at the collection.insert() level.
the api signature for insert is insert(docs[, options][, callback]), so you should only have one options object.
also, there is no {new: true} options for collection.insert.
so basically, you don't need to set any options (on insert).
I'd like to create a model to handle everything related to users, starting with a findOne() function.
app.js:
var u = new User(client);
u.findOne(function(error, user) {
console.log(error, user);
});
models/User.js:
var User = function (client) {
this.client = client
};
User.prototype.findOne = function (id, callback) {
client.connect();
client.get('testkey', function(error, result) {
var test = "hello#world.com";
callback(null, test);
client.close();
});
};
module.exports = User;
node.js complains findOne() would be undefined.
What's the correct way of creating such models and providing them with objects, like database pools etc.?
Your code contains various errors:
You do not use new when creating the instance
You mixed a function with the object literal syntax:
var User = function (client) {
client: client
};
You want this.client = client; instead. Right now the function body does nothing as it just defines a label called client does nothing with the variable client.
I would suggest you to search for an existing ORM for node.js instead of trying to write one on your own.