Activity Enrichment
kantle opened this issue · 4 comments
I've noticed that when I register a collection with Stream (using Stream.registerActivity) and access this activities through the synthetic collection (e.g. Stream.feeds.users) I get access to an instance of the object, rather than the objectId. This enrichment is certainly helpful when including the activity into the app (such as in an activity feed UI). However I noticed that when I add an activity using the Feedmanager, I only get the id of the object, not the enriched object. A sample of how I am doing this in FeedManager is:
var userFeed = Stream.feedManager.getUserFeed(userId);
var activity = {
actor: userId,
verb: 'invite',
object: doc.projectId,
target: doc.userId,
to: ['project:' + doc.projectId]
};
userFeed.addActivity(activity);
Sometimes it makes sense to use the collection integration (such as when I 'create' a new project), but sometimes I would prefer to use the FeedManager. An example would be if a created a post, but it remains in draft form until it is published - I don't actually want to create the activity record until the post is published (which may happen after the post document was created).
What is the best way to handle enrichment when I use FeedManager? Should I just check if the object is type string or type Object and create my own publications can subscribe to them based on the id?
Appreciate any thoughts!
Actually I just noticed one potential issue for the collection integration feature. When I register a collection, the package automatically publishes the full document. So if the actor is a user, the package publishes the full user document an an object within the activities document, including emails and password hashes. This presents a bit of a security challenge, including for other collections where I don't want to publish all the fields to the client. Is there anyway to limit the fields that are published as part of activity enrichment?
@kantle yes this is a known issue. We should come up with a way to allow the selection of specific fields to enrich on models. My suggestion is to enrich all fields by default except if you supply an object of fields to enrich, in that case we only enrich those fields on that model. A PR on this is welcome.
Well I would imagine it wouldn't be that hard to whitelist the desired fields (I think we just need to modify the find call on lines 13 and 84 of publish.js). The question is where would you store the list of whitelisted fields. I wouldn't want to make the request client side, since it would be too easy to spoof (a user could just open console and subscribe with the desired fields). I think you'd need to either pass the name of a server side object that holds the whitelisted fields or else just define in a server side object and not let the client have any say in the matter. I suppose you could also define the name of the object in Meteor.settings to allow someone to have some flexibility.
Ok - I made a PR #9 with a potential fix. Seems to work for my use case of preventing the whole document of going down ddp. It requires the user to create on object on the server called Stream.publishFields where you list the fields limitations by collection. Example use case:
Stream.publishFields = {
users: {
profile: 1,
}
}