Astronomy package as a Model Layer for Meteor: Questions, Pros & Cons

Astronomy is a very promising package, but I have some (potentially dumb) questions :slight_smile:
Please help me fill up the gaps in my understanding.
(sorry for the markdowned question numbers)

  1. What could be some potential security implications of Astronomy’s set / get methods availability to the Client? i.e. can this cause some data or security leaks?

In the following example we get all the fields of the class instance.

// Returns object with all fields: '_id', 'title' and 'commentsCount'.
post.get();

Also, if a malicious user can override (shadow) some Class properties from the Client, for ex., set a post.set = cleverBadFunction, how dangerous this could be?

// You can also set values directly but assigned values won't be converted to the proper type of the fields.

post.title = 'New title';
post.title = 123;  // Value won't be converted to String.
alert(post.title);  // 123, not '123'
  1. If methods property is available to the Client, what would be some good ways to hide the body (source) of functions defined in methods property?

  2. If methods property can be overwritten at runtime, how bad could that be?

  3. If a user can add methods from the Client, what should we look out for?

We also have here two ways of adding methods to an already defined schema: addMethod and addMethods …

  1. Since the Astronomy event hooks for the save() and remove() of a Class “…will not be called on direct manipulations of the underlying collections (i.e. Posts.remove(id)).”, then, how do we handle security and tracking of unauthorized/unexpected modifications to collections?

Hi, to resolve your doubts :smile:

  1. set and get methods on the client does not cause any security issue. It is always the developer duty to make sure that user will not corrupt data. It’s how Meteor works. You have to provide security layer by server checks or by allow and deny rules. Astronomy does not change anything in this matter.
    Moreover, you don’t have to hide methods’ body. However you can define different set of methods for client and server by using Class.addMethod function only on the server.

  2. As answered in previous point, there is no risk as far if you provide security layer on the server or in allow and deny rules.

  3. i think that I don’t understand this question. However maybe my answer will be correct. Ability to add methods to already defined class allows for defining different set of methods for the client and server. There are many situations when you don’t want to expose your server code to the world. So, add some methods only on the server would be good choice.

  4. It just means that if you are using save and remove functions, then events will be called. When you call Collection.insert (direct operation on collection) then no events will be called. When you want to invoke some direct operation on collection then you have to be sure what are you doing.

If you have any other question feel free to ask.

2 Likes

Thanks @Jagi! And special thanks to all contributors for the great docs!

Now, let me clarify some of my concerns:

What if someone (an admin user or some process) somehow modifies the DB from the server-side (for ex., via mongo shell), so, how do we track such modifications with Astronomy?

Yes, Meteor will be tracking the DB changes, but how do we make sure that certain changes will trigger some specific logic of our application (e.g. logs, alerts etc.)?

I guess we could use some other packages which handle events/modifications at the collection-level (vs. Astronomy’s doc-level), but then we might lose the benefit of consistency provided by Astronomy, and perhaps duplicate some of the logic and bloat an application.

So, basically, what would be your thoughts and recommendations on firing & handling events upon direct actions (via a console or a method bypassing Astronomy) on a DB/collection?

Yet, Allow/Deny rules can get really messy :slight_smile:

And some more,

  1. What are some particular advantages of using behaviors:{} property vs. defining some fields like createdAt and updatedAt in the fields:{} property, by default?

  2. How to customize the behavior of Astronomy’s xyz.save() and xyz.remove()?
    (for ex., when we want to keep the document, but mark it as “Trashed”)

  3. Are there other ways to make some fields optional besides setting a default value on that field?
    And how to make a field optional, but apply validations when the field is set (for ex. later update)? Just omit Validators.required()?

  4. What happens if we define a model XYZ with some validators in its schema, but we don’t call xyz.validate() before calling xyz.save()? Does it always fail to save (throwing an error by default) or are there some exceptional cases?

Answering your first question:
Yes you should use some package for collection events. However there was a proposal for creating such module for Astronomy to make it, as you said, consistent. I think it’s a good idea. Could you add issue on the GitHub so I will be able to track it?

  1. Using behaviors just makes things easier. You don’t have to do things by hand. Of course there can be situation when it’s not enough and you will need some custom logic. But just take a look at the slug or timestamp behaviors’ code. It’s not so simple and instead rewriting them for every project, you can just use behavior.

  2. You have for this the softremove behavior.

  3. You can use conjunction of validators:

Validators.or([
  Validators.null(),
  Validators.and([
    Validators.string(),
    Validators.minlength(5)
  ])
])
  1. Validation will not take place and a doc will be saved without checking anything.
1 Like

Thanks, @jagi! I created the issue for the requested feature.

For optional fields, your suggested way is robust, but perhaps there should be a simpler way (like setting optional: true for ex.) instead of:

And also it would be good to clearly indicate this in docs:

Again, thanks for you amazing work and keep up!

Hey @jagi! It’s not directly related to the author’s question but it definitely fits under the title of this thread.

I am wondering if there’s a canonical way to implement server-side time-stamping using astronomy. I am aware of the timestamp behavior but the problem with it is that it only runs wherever I call model.save(), right? So when client is editing the model, the timestamp will be taken from user’s browser.

It’s not something Astronomy specific by Meteor specific. You always have to run code on the server to make sure that a data you are saving is not corrupt. Knowing that you have to create Meteor method that will run on both client and server. On the client it will perform simulation but on the server the CORRECT timestamp generation will take place and the document will be saved. After that it will be synchronized with the client. If the server side version differs from the client side version then the client side version will be overridden by the server side version. That’s it. You don’t have to do anything else, just make sure that you call given method in both environments.

Damn, a lot of people still dont really understand how meteor security/latency compensation work.

To make this clear:

It does not matter how the user may change their database input, the only real change made to the actual database is only made on the server, and as soon as the meteor app detects the differences between the server and client version it re-syncs.

So as long as someone has not broken into your mongo server shell/meteor server shell, The data should never be corrupted unless you have the package “insecure” installed (which is by default)

Hi, @jagi - your package looks fantastic! However, at the risk of repeating some of the questions above in a different way, I’d really like to make sure of some things.

  1. Is there a way to ensure validation logic on the server if the client does a direct operation on the collection (for example through the console).

  2. I’m currently using the ‘collection hooks’ package. If hooks in astronomy won’t run if the collection is accessed directly on the client, I can’t ensure the hooks will run on the server, right?

Thanks again.

  1. You should use methods to perform server side validation of data.

  2. Yes, “hooks” won’t be executed. Using methods is preferred way of working with data in Astronomy. It will change in Astronomy 2.0

Ok thanks. I deleted my previous answers as I have to admit I didn’t know how methods worked client side. That makes all much more sense. Will try astronomy asap :smile: