How to pass two parameters to model.fetch() in backbone? - javascript

I'm making a very simple user authentication system. I'm trying to pass a combination of username and password as params to the back-end nodejs server. So this combination will be used in my db query to fetch user details.
This is what I tried on the front-end:
var user = new UserModel({id:['username', 'password']});
user.fetch();
I have defined a urlRoot property in my model that goes like this: /api/users
The back-end will handle the following url: /api/users/:id
Here since I have passed id as an array, I tried to access the 'username' by doing this req.params.id[0]. Instead it returns the first letter of the 'username'. But I want to take the entire string of username. Of course I could use the split() function to separate them but I believe there is a better way to do this.
Please tell me if my approach is wrong somewhere.

That's because Backbone serializes your array to string and then encodes it as URI component.
So effectively you're sending a String 'username%2Cpassword' instead of an array.
I had the same problem and decided that sign in process doesn't really represent any "physical" resource, and most likely shouldn't be handled by user model. One doesn't CRUD users when signing in.
What i did was to create a separate model for SignIn:
SignInModel = Backbone.Model.extend({
urlRoot: 'api/sign_in',
defaults: {
'username' : '',
'password': ''
}
});
which statically maps to api/sign_in (no id's here), and then query the database by username and password passed in the request body to the api/sign_in handler.
UserModel can then be left to handle CRUD of users.

Related

JavaScript (Discord) Is there a way for my bot to store values and then repeat?

I have my current Discord Bot project using JavaScript however i cannot find a way to store the value itself when done through a command such as !setname ___ hoping for a response of that being repeated back when I use !myname.
I know how to do it by storing it temporarily through:
bot.on('message', function (user, userID, channelID, message, evt) {
if(message == "!myname") {
bot.sendMessage({
to: channelID,
message: 'Your name is ' + user.username;
});
}
}
However i cant figure out how to do it through the ability to call for it whenever you want rather than getting an immediate response. For example setting my name now but being able to have it output when i use the command instead of having command that sets the value then outputs it in an immediate string
Would recommend a simple key-value dictionary style in the current instance.
(Though you could store it to a text-file or database later if you prefer the data to be persistent across different sessions.)
Instance based:
Based on this post on stackoverflow...
You can create a global dictionary at the top var usernameChangeDict = {};
Whenever the user invokes !setname, just do:
usernameChangeDict[user.id] = Their_new_name_here
Fetch it back using usernameChangeDict[user.id], should return null or empty if they did not set their name before.
Persistent data:
Could either store it in a text file on your local computer, or do a database as Zooly mentioned.(Though personally, a database would be an overkill if your bot is not going to be used by a wide range of people.)
Text file
Read from this post, it contains details on how to write onto a text file.
This post talks about reading from a text file.
I would recommend storing it in a JSON format to make your life easier, since JSON.parse exists.
Most likely you would end up storing in a format like this:
{ "23125167744": "someone", "USER_ID": "username" }
Access it by parsedJson["USER_ID"].
SQLite
This tutorial would probably explain how to set your SQLite for javascript better than I do.
Once its all setup, just store the userID and username, you can just do:
SELECT username FROM yourTable WHERE userID = ?;
and
INSERT INTO yourTable (username, userID) VALUES (?, ?);
For inserting and selecting into database respectively.

Meteor.js - Fetch/Get Enrollment token (from Accounts.sendEnrollmentEmail)

I can't figure out how to get the enrollment token from the Accounts.sendEnrollmentEmail function.
I know this function sends a direct mail towards the user which in the end looks something like this:
http://localhost:3000/#/enroll-account/FCXzBbqHInZgBlLaOpu8Iv11jP9DJEG-e1auAHDsh6S
However, I would need to somehow get only to the token part FCXzBbqHInZgBlLaOpu8Iv11jP9DJEG-e1auAHDsh6S as I want to send enrollment mail trough a different service (e.g Postmark)
How to do this?
The Accounts.sendEnrollmentEmail(userId, email) function generates a random token and saves it in the user's services.password.reset.token field.
The code that generates the token is:
var token = Random.secret();
var when = new Date();
var tokenRecord = {
token: token,
email: email,
when: when
};
Meteor.users.update(userId, {$set: {
"services.password.reset": tokenRecord
}});
(You can view the function's source code here).
It then sends an email to the user using the Email package. If you want to use a different service to send the email, you basically have 2 options:
Use the same convention yourself (i.e, create the same record and use your own email service in your own function).
Use the existing function, allow the mail delivery to fail silently and then query the user's document for the token and send the email yourself.
Neither is a particularly good option, but both will work for the time being. I wish they had refactored this part into its own function.
Note that the accounts packages are expected to undergo some changes towards the release of the next Meteor versions.
BTW, this function is very similar to Accounts.sendResetPasswordEmail, which you may also wish to override or create your own version.

Do I need to validate, sanitise or escape data when using the build method in sequelize.js

I have a node / express / sequelize app. I am using the build method in sequelize to create an instances of my foo model.
Foo Controller
exports.create = function(req, res) {
var foo = db.Foo.build(req.body);
foo.save().then(function(){
// do stuff
});
}
Foo Model
module.exports = function(sequelize, DataTypes) {
var Foo = sequelize.define('Foo',
{
bar: DataTypes.STRING,
baz: DataTypes.STRING
}
Does the build method check that the data I am saving is clean or do I need to take some extra precautions here?
I prefer to make secondary validation in routes, because:
1) Storing data in a database is one of many things you can do with this data. If you only validate in database then in other places you get not validated data. For example you may need some computation or concatenation before saving it in a database.
2) or when you use one sequelize model in many routes (e.g. User model in customer route and partner route) and you want to make different validation rules.
I always set validation in sequelize models, but this is validation with 'maximum allowable conditions' (e.g. username field never be larger then 200 chars and it is string). I make also routes validation. It is more specific and concrete (e.g. in customer route username max large is 100 but in partner route username may have 150 chars and also check content of this string).
And finally, the strict answer for your question: sequelize validation is mostly for validating format. And this is not enough. Look at my answer NodeJS/express - security for public API endpoint
if you save data without correct validation and then serve this data then you are exposed to XSS attack.

In Meteor Js how do I add a referral code from query string to user profile?

I'm using the accounts-entry package in a Meteor application. I want to be able to give partners to our application the ability to refer users to us with a link, eg: ourawesomeapp.com?partnerId=1234. When a user comes from a partner I want to be able to store that in the users collection under a partnerId field to pay commissions when users spend money with us. I'm currently trying to use this: (note this Accounts.onCreateUser() method runs on the server only)
Accounts.onCreateUser(function(options, user){
user.partnerId = partnerId from the query string here...;
return user;
});
The spot I'm getting stuck at is getting the partnerId from the query string to the server to be able to use it there.
If you use the recommended routing package for Meteor, iron-router, you can access the query string like this:
// given the url: "/?partnerId=1234"
Router.route('/', function () {
var partnerId = this.params.query.partnerId;
});
If the query string isn't available on the server, an option is to make the partnerId a URL path instead of query string:
Router.route('/partner/:_id', function () {
var partnerId = this.params._id;
}, {where: 'server'});
More in the iron-router guide.

Search criteria form and collections

In my application, I would like to create a search form in order to retrieve some users. This form contains many criteria (lastname, firstname, birthdate, etc.). But I do not understand how I can post my form in order to filter my collection. I can not use fetch method because if I use GET method, my search criteria will be displayed in the URL. In fact I would like to submit a POST request (which contains the search criteria serialize in JSON) to the server and retrieve a user list.
I have read the backbone documentation but I do not found anything that allow me to do that. This functionality is not supported by backbone ? There is some workarround to implement this requirements ?
Thanks in advance
In short, I don't think backbone is a good fit for what you are describing. Read on for a longer version...
Based on your question, I think backbone would be well suited to display your collection of users, but not so good at the submission of your filter criteria.
You could create a criteria model and set the attributes of the model to Username, Birthday, etc and then you could post it to the server using backbone. However when you save it using backbone, it is assumed that you saved the criteria. Any result that comes back from the server from that POST is assumed to be updated properties of the criteria, and not a list of users.
Tim is correct that this isn't exactly what Backbone is meant for. That being said I think I would still at least use a Backbone model to track the state of the search criteria. On this model I would add a custom method for activating search that would serialize the model's state and POST it to the server itself. On the success of this method, I would use the results to reset the current user collection.
Here is my idea in code:
var SearchModel = Backbone.Model.extend({
defaults: {
firstName: "*",
lastName: "Smith"
},
search: function() {
$.ajax({
dataType: "json",
type: "POST",
data: this.toJSON(),
success: function(data) {
this.options.peopleCollection.reset(data);
}
})
}
});
var myPeopleCollection = new PeopleCollection();
var mySearch = new SearchModel({ peopleCollection: myPeopleCollection });
mySearch.set({ firstName: "Steve"});
mySearch.set({ lastName: "Smith" });
mySearch.search();

Categories