sails.js waterline: maxLength not set in DB - node.js

I have set the validation rule maxLength for one of my fields in one of my models and it is recognized by sails.js if my input is too long. My problem is that if I check my database it shows a field length of 255 for my mysql db. I would expect it to be the same as my maxLength value.
I've found this on StackOverflow:
SailsJS - How to specify string attribute length without getting error when creating record?
Since this has been opened Sails.js made a lot of progress and so I don't know if custom validation rules is still the way to go. I don't like this because it looks more like a temporary hack rather than a real solution.
Is this expected behavior or a bug?

I know you do not need the answer anymore, but maybe other people do.
You must use the size attribute for this purpose.
On the doc's says:
If supported in the adapter, can be used to define the size of the attribute. For example in MySQL, size can be specified as a number (n) to create a column with the SQL data type: varchar(n).
Just use it like this
attributes: {
name: {
type: 'string',
size: 24
}
}
https://sailsjs.com/documentation/concepts/models-and-orm/attributes#size

Related

Marklogic QueryByExample in collection NodeJS

TLDR
Is there a way to limit queryByExample to a collection in NodeJS?
Problem faced
I have a complex query with some optional fields (i.e. sometimes some search fields will be omitted). So I need to create a query dynamically, e.g. in JSON. QueryByExample seems to be the right tool to use here as it gives me that flexibility to pass a JSON. However my problem is that I would like to limit my search to only one collection or directory.
e.g. I was hoping for something like
searchJSON = {
title: { $word: "test" },
description: { $word: "desc" }
};
//query
db.documents.query(qb.where(
qb.collection("collectionName"),
qb.byExample(searchJSON)
)).result()...
In this case searchJSON could have been built dynamically, for example maybe sometimes title may be omitted from the search.
This doesn't work because the query builder only allows queryByExample to be the only query. But I'd instead like to built a dynamic search query which is limited to a collection or directory.
At present, I think you would have to express the query with QueryBuilder instead of Query By Example using
qb.and([
qb.collection('collectionName'),
qb.word('title', 'test'),
qb.word('description', 'desc')
])
See http://docs.marklogic.com/jsdoc/queryBuilder.html#word
That said, it should be possible for the Node.js API to relax that restriction based on the fixes in MarkLogic 9.0-2
Please file an issue on https://github.com/marklogic/node-client-api

How do I define Sequelize.STRING length?

I want to define a length of a datatype in sequelize.
There is my source code :
var Profile = sequelize.define('profile', {
public_id: Sequelize.STRING,
label: Sequelize.STRING
})
It create a table profiles with a public_id with a datatype varchar(255).
I would like to define a public_id with varchar(32).
I searched on the doc and the stack but couldn't find any answer...
How can I do that please ?
As it is mentioned in the documentation, use:
Sequelize.STRING(32)
First, I think you need to rethink your design just a little bit. The basic point is that length constraints should be meaningful, not just there to save space. PostgreSQL does not store 'A'::varchar(10) any differently than it does 'A'::text (both are stored as variable length text strings, only as long as the value stored, along with a length specifier and some other metadata), so you should use the longest size that can work for you, and use the lengths for substantive enforcement rather than to save space. When in doubt, don't constrain. When you need to make sure it fits on a mailing label, constrain appropriately.
Secondly Dankohn's answer above:
var Profile = sequelize.define('PublicID', {
public_id: {
validate: { len: [0,32] })
is how you would then add such enforcement to the front-end. Again, such enforcement should be based on what you know you need, not just what seems like a good idea at the time, and while it is generally easier to relax constraints than tighten them, for string length, it's really a no-brainer to do things the other way.
As for using such in other applications, you'd probably want to look up the constraint info in the system catalogs, which gets you into sort of advanced territory.

How dangerous is a mongo query which is fed directly from a URL query string?

I am playing around with node.js, express, and mongoose.
For the sake of getting something up and running right now I am passing the Express query string object directly to a mongoose find function. What I am curious about is how dangerous would this practice be in a live app. I know that a RDBMS would be extremely vulnerable to SQL injection. Aside from the good advice of "sanitize your inputs" how evil is this code:
app.get('/query', function (req, res) {
models.findDocs(req.query, function (err, docs) {
res.send(docs);
});
});
Meaning that a a get request to http://localhost:8080/query?name=ahsteele&status=a would just shove the following into the findDocs function:
{
name: 'ahsteele',
status: 'a'
}
This feels icky for a lot of reasons, but how unsafe is it? What's the best practice for passing query parameters to mongodb? Does express provide any out of the box sanitization?
As far as injection being problem, like with SQL, the risk is significantly lower... albeit theoretically possible via an unknown attack vector.
The data structures and protocol are binary and API driven rather than leveraging escaped values within a domain-specific-language. Basically, you can't just trick the parser into adding a ";db.dropCollection()" at the end.
If it's only used for queries, it's probably fine... but I'd still caution you to use a tiny bit of validation:
Ensure only alphanumeric characters (filter or invalidate nulls and anything else you wouldn't normally accept)
Enforce a max length (like 255 characters) per term
Enforce a max length of the entire query
Strip special parameter names starting with "$", like "$where" & such
Don't allow nested arrays/documents/hashes... only strings & ints
Also, keep in mind, an empty query returns everything. You might want a limit on that return value. :)
Operator injection is a serious problem here and I would recommend you at least encode/escape certain characters, more specifically the $ symbol: http://docs.mongodb.org/manual/faq/developers/#dollar-sign-operator-escaping
If the user is allowed to append a $ symbol to the beginning of strings or elements within your $_GET or $_POST or whatever they will quickly use that to: http://xkcd.com/327/ and you will be a gonner, to say the least.
As far as i know Express doesnt provide any out of box control for sanitization. Either you can write your own Middleware our do some basic checks in your own logic.And as you said the case you mention is a bit risky.
But for ease of use the required types built into Mongoose models at least give you the default sanitizations and some control over what gets into or not.
E.g something like this
var Person = new Schema({
title : { type: String, required: true }
, age : { type: Number, min: 5, max: 20 }
, meta : {
likes : [String]
, birth : { type: Date, default: Date.now }
}
});
Check this for more info also.
http://mongoosejs.com/docs/2.7.x/docs/model-definition.html

Node.js + Mongoose / Mongo & a shortened _id field

I'd like the unique _id field in one of my models to be relatively short: 8 letters/numbers, instead of the usual Mongo _id which is much longer. Having a short unique-index like this helps elsewhere in my code, for reasons I'll skip over here. I've successfully created a schema that does the trick (randomString is a function that generates a string of the given length):
new Schema('Activities', {
'_id': { type: String, unique: true, 'default': function(){ return randomString(8); } },
// ... other definitions
}
This works well so far, but I am concerned about duplicate IDs generated from the randomString function. There are 36^8 possible IDs, so right now it is not a problem... but as the set of possible IDs fills up, I am worried about insert commands failing due to a duplicate ID.
Obviously, I could do an extra query to check if the ID was taken before doing an insert... but that makes me cry inside.
I'm sure there's a better way to be doing this, but I'm not seeing it in the documentation.
This shortid lib https://github.com/dylang/shortid is being used by Doodle or Die, seems to be battle tested.
By creating a unique index on _id you'll get an error if you try to insert a document with a duplicate key. So wrap error handling around any inserts you do that looks for the error and then generates another ID and retries the insert in that case. You could add a method to your schema that implements this enhanced save to keep things clean and DRY.

mongodb schema data type for a list of numbers (or an array of numbers without a specific size)

what kind of schema data type should i use to define a list of numbers (or an array of numbers with changing size)
I tried :
{type : [Number]}
but i suspect it may cause problems as i try to insert a value to the array (with $addToSet) from nodejs nothing happens,although trying to do this from mongodb interactive shell works fine.. perhaps(most likely) it's a different problem but i would like to remove any doubts regarding the way i defined the schema.
Thank you.
Try this:
fieldName: [ { type: Number } ]

Resources