Able to subscribe to publications even with autopublish package removed

Hi everyone,

As the title suggests, I’m puzzled on why I’m still able to subscribe to publications without authentication.

I made sure that autopublish is removed.

$ meteor remove autopublish
autopublish is not a direct dependency in this project.

I’m using simpleDDP, to connect to meteor app:

Here is an example of publication:

Meteor.publish('usersList', function () {
    return Meteor.users.find()
});

Here is an example of simpleDDP function:

    const server = new simpleDDP(opts);
    let usersList = server.subscribe("usersList");
    let reactiveUserCollection = server.collection('users').reactive();
    console.log('reactiveCollection', reactiveCollection.data())

In the browser console, I’m able to see an object with all users documents :roll_eyes:

Any ideas?

Hello,

Your publication is returning all the users so it’s normal you get them on the client-side. You have to define what you want to publish on the server-side, for example just the connected user info:

return Meteor.users.find({ _id : this.userId })

Or to use fields in order to limit what you are sending back to the client.

I invite you to read thoroughly this part of the documentation:

1 Like

You are able to subscribe without authenication because your publication function does not have any authentication

This is how you would add authentication:

Meteor.publish('usersList', function () {
  if (!this.userId) {
    return this.ready();
  }
  return Meteor.users.find()
});

If you also wanted Authorization, you would ensure that your queries only return data that the current user is allowed to see.
For example, you can limit publised documents to the owner or people the document has been shared with like so:

Meteor.publish('foo', function () {
  if (!this.userId) {
    return this.ready();
  }
  return FooCollection.find({ $or: [{ owner: this.userId }, { sharedWith: this.userId }] });
});

Also check the Meteor guide on data loading:

1 Like

Thanks guys, I was under the wrong impression that once you remove auto publish, only authenticated users are able to subscribe.

Now, is there is a package or middleware that I can add to do just that? instead of going over 15+ publications and 20+ methods and secure them all ?

You can use mixins with mdg:validated-method, so with that at least your methods could be covered. Why at the same time no ValidatedPublication was created, I can’t tell, but maybe it’s possible too based on that code, including mixins.

1 Like

That impression is incorrect. There are many reasons why you might want data to be visible publicly. And usually data that is restricted to logged in users is also further restricted according to business rules that can only be determined by the business or developer.

If you want to make your publications restricted for logged in users only you’ve got a couple of options:

The nice way is to make your own loggedInPublish function

export const loggedInPublish(name, callback) {
  Meteor.publish(name, function (...args) {
     if (!this.userId) {
       return this.ready();
     }
     return callback(...args);
  }
}

And replace your Meteor.publish calls with this function

The fastest but not nice way is to monkey-patch Meteor.publish:

const originalPublish = Meteor.publish;
Meteor.publish = function (name, callback) {
  return originalPublish.call(Meteor, name, function (...args) {
     if (!this.userId) {
       return this.ready();
     }
     return callback(...args);
  }
}

This is not nice because it will affect all publications created after the monkey patching. If any happen before, they won’t be affected. It adds unncessesary complexity because you have to worry about module loading and execution order.

1 Like

Thanks for getting back to me on this one! and really appreciate the code examples, I have tried the secure publish method and it works :+1:t2:

2 Likes