diff --git a/docs/client/concepts.html b/docs/client/concepts.html
index 864a4025ac..c38aba29c7 100644
--- a/docs/client/concepts.html
+++ b/docs/client/concepts.html
@@ -84,72 +84,120 @@ for images, `favicon.ico`, `robots.txt`, and anything else.
{{#better_markdown}}
-Data
+Data and security
Meteor makes writing distributed client code as simple as talking to a
-local database. It's a clean and simple approach, much easier than
-building individual RPC endpoints, slow roundtrips to the server, and
-orchestrating invalidation messages.
+local database. It's a clean, simple, and secure approach that obviates
+the need to implement individual RPC endpoints, manually cache data on
+the client to avoid slow roundtrips to the server, and carefully
+orchestrate invalidation messages to every client as data changes.
-Every Meteor client includes an in-memory database cache. Each client's
-cache holds valid copies of some set of documents that are stored in a
-server's master database. When a matching document in that database
-changes, Meteor automatically synchronizes that change to every
-subscribed client.
+In Meteor, the client and server share the same database API. The same
+exact application code -- like validators and computed properties -- can
+often run in both places. But while code running on the server has
+direct access to the database, code running on the client does *not*.
+This distinction is the basis for Meteor's data security model.
-To manage the client caches, your server code *publishes* sets of
-documents, and your client code *subscribes* to those sets. For
-example, if you are building a chat system, the server might publish two
-sets: the set of all rooms, and the set of all messages in a given room.
-Each client would subscribe to the master set of available rooms and the
-set of messages in the currently-selected room. Once subscribed, the
-client uses its cache as a fast local database, dramatically simplifying
-your client model code.
+{{#note}}
+By default, a new Meteor app includes the `autopublish` and `insecure`
+packages, which together mimic the effect of each client having full
+read/write access to the server's database. These are useful
+prototyping tools, but typically not appropriate for production
+applications. When you're ready, just remove the packages.
+{{/note}}
-Meteor's protocol for distributing document updates is database
-agnostic. By default, Meteor applications use the
-familiar [MongoDB API](http://www.mongodb.org/display/DOCS/Manual):
-servers store documents in MongoDB collections, and clients cache those
-documents in a client-side cache that implements the same Mongo API for
-queries and updates.
+Every Meteor client includes an in-memory database cache. To manage the
+client cache, the server *publishes* sets of JSON documents, and the
+client *subscribes* to those sets. As documents in a set change, the
+server patches each client's cache.
- // server: publish all room documents, and per-room messages
- Meteor.publish("chatrooms");
+Each document set is defined by a publish function on the server. The
+publish function runs each time a new client subscribes to a document
+set. The data in a document set can come from anywhere, but the common
+case is to publish a database query.
+
+ // server: publish all room documents
+ Meteor.publish("all-rooms", function () {
+ return Rooms.find(); // everything
+ );
+
+ // server: publish all messages for a given room
Meteor.publish("messages", function (roomId) {
return Messages.find({room: roomId});
});
- // client: subscribe to all rooms, and messages in the first room
- Meteor.subscribe("chatrooms");
- Meteor.subscribe("messages", Chatrooms.find()[0]._id);
+ // server: publish the set of parties the logged-in user can see.
+ Meteor.publish("parties", function () {
+ return Parties.find({$or: [{"public": true},
+ {invited: this.userId},
+ {owner: this.userId}]});
+ });
-Document modifications also propagate automatically. Modification
-instructions like `insert`, `remove`, and `update` are executed
-immediately on the client's cached data. *At the same time*, the
-client sends that instruction up to the server, which executes the same
-change against the master database. Usually the client and server
-agree, but should they differ (permissions checking or overlapping with
-another client, for example), the server's result will publish back down
-to the client. And of course, all other clients with a matching
-subscription automatically receive an updated document.
+Publish functions can provide different results to each client. In the
+last example, a logged in user can only see `Party` documents that
+are public, that the user owns, or that the user has been invited to.
- // create new message, executes on both client and server.
- Messages.insert({room: 2413, text: "hello!"});
+Once subscribed, the client uses its cache as a fast local database,
+dramatically simplifying client code. Reads never require a costly
+round trip to the server. And they're limited to the contents of the
+cache: a query for every document in a collection on a client will only
+return documents the server is publishing to that client.
-Putting it all together, these techniques accomplish *latency
-compensation*. Clients hold a fresh copy of the data they need, and
-never need to wait for a roundtrip to the server. And when clients
+ // client: start a parties subscription
+ Meteor.subscribe("parties");
+
+ // client: return array of Parties this client can read
+ return Parties.find().fetch(); // synchronous!
+
+Sophisticated clients can turn subscriptions on and off to control how
+much data is kept in the cache and manage network traffic. When a
+subscription is turned off, all its documents are removed from the cache
+unless the same document is also provided by another active
+subscription.
+
+When the client *changes* one or more documents, it sends a message to
+the server requesting the change. The server checks the proposed change
+against a set of allow/deny rules you write as JavaScript functions.
+The server only accepts the change if all the rules pass.
+
+ // server: don't allow client to insert a party
+ Parties.allow({
+ insert: function (userId, party) {
+ return false;
+ }
+ });
+
+ // client: this will fail
+ var party = { ... };
+ Parties.insert(party);
+
+If the server accepts the change, it applies the change to the database
+and automatically propagates the change to other clients subscribed to
+the affected documents. If not, the update fails, the server's database
+remains untouched, and no other client sees the update.
+
+Meteor has a cute trick, though. When a client issues a write to the
+server, it also updates its local cache immediately, without waiting for
+the server's response. This means the screen will redraw right away.
+If the server accepted the update -- what ought to happen most of the
+time in a properly behaving client -- then the client got a jump on the
+change and didn't have to wait for the round trip to update its own
+screen. If the server rejects the change, Meteor patches up the
+client's cache with the server's result.
+
+Putting it all together, these techniques accomplish latency
+compensation. Clients hold a fresh copy of the data they need, and
+never need to wait for a roundtrip to the server. And when clients
modify data, those modifications can run locally without waiting for the
confirmation from the server, while still giving the server final say
over the requested change.
-You can substitute another database for MongoDB by providing a
-server-side database driver and/or a client-side cache that implements
-an alternative API. The `mongo-livedata` is a good starting point for
-such a project.
-
-XXX should we mention security/auth at all here, or just expect folks to keep
-reading until the accounts section?
+{{#note}}
+The current release of Meteor supports MongoDB, the popular document
+database, and the examples in this section use the
+ [MongoDB API](http://www.mongodb.org/display/DOCS/Manual). Future
+releases will include support for other databases.
+{{/note}}
{{/better_markdown}}
@@ -441,7 +489,7 @@ discussion.
{{#better_markdown}}
- Smart Packages
+ Smart packages
Meteor has an unusually powerful package system. All of the
functionality you've read about so far is implemented as standard
diff --git a/docs/client/docs.js b/docs/client/docs.js
index 5190ee9ad1..3e4c63dbde 100644
--- a/docs/client/docs.js
+++ b/docs/client/docs.js
@@ -81,11 +81,11 @@ var toc = [
],
"Concepts", [
"Structuring your app",
- "Data",
+ "Data and security",
"Reactivity",
"Live HTML",
"Templates",
- "Smart Packages",
+ "Smart packages",
"Accounts",
"Deploying"
],