Merge branch 'auth-docs' into devel

This commit is contained in:
Nick Martin
2012-10-11 15:04:32 -07:00
7 changed files with 831 additions and 58 deletions

View File

@@ -120,6 +120,11 @@ is the place to stop the observes.
{{> api_box subscription_stop}}
{{> api_box subscription_userId}}
This is constant. However, if the logged-in user changes, the publish
function is rerun with the new value.
{{> api_box subscribe}}
When you subscribe to a record set, it tells the server to send records
@@ -201,6 +206,8 @@ object, which provides the following:
* `isSimulation`: a boolean value, true if this invocation is a stub.
* `unblock`: when called, allows the next method from this client to
begin running.
* `userId`: a function that returns the id of the current user.
* `setUserId`: a function that associates the current client with a user.
Calling `methods` on the client defines *stub* functions associated with
server methods of the same name. You don't have to define a stub for
@@ -215,6 +222,29 @@ intended to *simulate* the result of what the server's method will do,
but without waiting for the round trip delay. If a stub throws an
exception it will be logged to the console.
{{> api_box method_invocation_userId}}
The user id is an arbitrary string — typically the id of the user
record in the database. You can set it with the `setUserId` function. If
you're using the Meteor accounts system then this is handled for you.
{{> api_box method_invocation_setUserId}}
Call this function to change the currently logged in user on the
connection that made this method call. This simply sets the value of
`userId` for future method calls received on this connection. Pass
`null` to log out the connection.
If you are using the built-in Meteor accounts system then this should correspond to
the `_id` field of a document in the
<a href="#meteor_users">`Meteor.users`</a> collection.
`setUserId` is not retroactive. It affects the current method call and
any future method calls on the connection. Any previous method calls on
this connection will still see the value of `userId` that was in effect
when they started.
{{> api_box method_invocation_isSimulation}}
{{> api_box method_invocation_unblock}}
@@ -623,6 +653,153 @@ Example:
Logs.remove({});
{{> api_box allow}}
When a client calls `insert`, `update`, or `remove` on a collection, the
collection's `allow` and <a href='#deny'>`deny`</a> callbacks are called
on the server to determine if the write should be allowed. If at least
one `allow` callback allows the write, and no `deny` callbacks deny the
write, then the write is allowed to proceed.
These checks are run only when a client tries to write to the database
directly, for example by calling `update` from inside an event
handler. Server code is trusted and isn't subject to `allow` and `deny`
restrictions. That includes methods that are called with `Meteor.call`
&mdash; they are expected to do their own access checking rather than
relying on `allow` and `deny`.
You can call `allow` as many times as you like, and each call can
include any combination of `insert`, `update`, and `remove`
functions. The functions should return `true` if they think the
operation should be allowed. Otherwise they should return `false`, or
nothing at all (`undefined`). In that case Meteor will continue
searching through any other `allow` rules on the collection.
The available callbacks are:
<dl class="callbacks">
{{#dtdd "insert(userId, doc)"}}
The user `userId` wants to insert the document `doc` into the
collection. Return `true` if this should be allowed.
{{/dtdd}}
{{#dtdd "update(userId, docs, fields, modifier)"}}
The user `userId` wants to update some documents. Meteor has fetched the
documents from the database and they are available in `docs` as an
array. Return `true` if the user should be allowed to change these
documents.
Additional details about the proposed modification are in `fields` and
`modifier`. `fields` is the top-level fields in the document that the
client wishes to modify, for example `['name', 'score']`. `modifier` is
the raw Mongo modifier that the client wants to execute, for example
`{$set: {'name.first': "Alice"}, $inc: {score: 1}}`.
Only Mongo modifiers are supported (operations like `$set` and `$push`.)
If the user tries to replace the entire document rather than use
$-modifiers, the request will be denied without checking the `allow`
functions.
{{/dtdd}}
{{#dtdd "remove(userId, docs)"}}
The user `userId` wants to remove some documents. Meteor has fetched the
documents from the database and they are available in `docs` as an
array. Return `true` if the user should be allowed to remove these
documents.
{{/dtdd}}
</dl>
By default, when Meteor fetches the documents from the database for the
`docs` array, it will retrieve all of the fields in the documents. For
efficiency you may instead want to retrieve just the fields that are
actually needed by your functions. This is enabled by the `fetch`
option. Set `fetch` to an array of the field names that should be
retrieved.
Example: XXX test me!
// Create a collection where users can only modify documents that
// they own. Ownership is tracked by an 'owner' field on each
// document. All documents must be owned by the user that created
// them and ownership can't be changed. Only a document's owner
// is allowed to delete it, and the 'locked' attribute can be
// set on a document to prevent its accidental deletion.
Posts = new Meteor.Collection("posts");
Posts.allow({
insert: function (userId, doc) {
// the user must be logged in, and the document must be owned by the user
return (userId && doc.owner === userId);
},
update: function (userId, docs, fields, modifier) {
// can only change your own documents
return _.all(docs, function(doc) {
return doc.owner === userId;
});
},
remove: function (userId, docs) {
// can only remove your own documents
return _.all(docs, function(doc) {
return doc.owner === userId;
});
},
fetch: ['owner']
});
Posts.deny({
update: function (userId, docs, fields, modifier) {
// can't change owners
return _.contains(fields, 'owner');
},
remove: function (userId, docs) {
// can't remove locked documents
return _.any(docs, function (doc) {
return doc.locked;
});
},
fetch: ['locked'] // no need to fetch 'owner'
});
If you never set up any `allow` rules on a collection then all client
writes to the collection will be denied, and it will only be possible to
write to the collection from server-side code. In this case you will
have to create a method for each possible write that clients are allowed
to do. You'll then call these methods with `Meteor.call` rather than
having the clients call `insert`, `update`, and `remove` directly on the
collection.
Meteor also has a special "insecure mode" for quickly prototyping new
applications. In insecure mode, if you haven't set up any `allow` or
`deny` rules on a collection, then all users have full write access to
the collection. This is the only effect of insecure mode. If you call
`allow` or `deny` at all, even `allow({})`, then access is checked just
like normal. __New Meteor projects start in insecure mode by default.__ To
turn it off just type `meteor remove insecure`.
{{#note}}
For `update` and `remove`, documents will be affected only if they match
the selector both at the time the documents are fetched to run the
`allow` and `deny` rules, __and__ at the time that the operation is
actually executed. This is accomplished by rewriting the selector to
`{$and: [(original selector), {$in: {_id: [(ids of documents fetched
and checked by allow and deny)]}}]}`.
{{/note}}
{{> api_box deny}}
This works just like <a href='#allow'>`allow`</a>, except it lets you
make sure that certain writes are definitely denied, even if there is an
`allow` rule that says that they should be permitted.
When a client tries to write to a collection, the Meteor server first
checks the collection's `deny` rules. If none of them return true then
it checks the collection's `allow` rules. Meteor allows the write only
if no `deny` rules return `true` and at least one `allow` rule returns
`true`.
<h2 id="meteor_collection_cursor"><span>Cursors</span></h2>
To create a cursor, use [`find`](#find). To access the documents in a
@@ -1460,6 +1637,84 @@ sub-template.
<h2 id="accounts_api"><span>Accounts</span></h2>
XXX intro text
{{> api_box user}}
- {_id: foo} if not userLoaded.
- schema / common fields
{{> api_box userId}}
{{> api_box users}}
- on the client, current user. on the server all users.
- examples of usage?
- schema
- default publish and allow for profile
{{> api_box userLoaded}}
- more text
{{#note}}
We realize this is inconvenient. It is a temporary solution. In the
future we will either make it unnecessary or fold it into a more
general mechanism.
{{/note}}
{{> api_box logout}}
{{> api_box loginWithPassword}}
{{> api_box loginWithOAuth}}
- example scopes
{{> api_box accounts_createUser}}
- logs you in on the client
- diff between client and server
- username and/or email. which are optional.
- default user hook adds profile, override w/ onCreateUser
- not for oauth
{{> api_box accounts_changePassword}}
{{> api_box accounts_forgotPassword}}
- triggers sendResetPasswordEmail
- document where the token goes in Accounts._whatever?
- youre responsibility to get it into resetPassword
{{> api_box accounts_resetPassword}}
- don't need to call if you have accounts-ui
{{> api_box accounts_setPassword}}
{{> api_box accounts_verifyEmail}}
- pass token from sendVerificationEmail
- what changes in the schema
{{> api_box accounts_sendResetPasswordEmail}}
{{> api_box accounts_sendEnrollmentEmail}}
{{> api_box accounts_sendVerificationEmail}}
{{> api_box accounts_emailTemplates}}
{{> api_box accounts_config}}
{{> api_box accounts_ui_config}}
{{> api_box accounts_validateNewUser}}
{{> api_box accounts_onCreateUser}}
- takes `options`, `user`
<h2 id="timers"><span>Timers</span></h2>
Meteor uses global environment variables

View File

@@ -145,6 +145,14 @@ Template.api.subscription_onStop = {
]
};
Template.api.subscription_userId = {
id: "publish_userId",
name: "<i>this</i>.userId",
locus: "Server",
descr: ["The id of logged-in user, or `null` if no user is logged in."]
};
Template.api.subscribe = {
id: "meteor_subscribe",
name: "Meteor.subscribe(name [, arg1, arg2, ... ] [, onComplete])",
@@ -187,6 +195,25 @@ Template.api.methods = {
]
};
Template.api.method_invocation_userId = {
id: "method_userId",
name: "<i>this</i>.userId",
locus: "Anywhere",
descr: ["The id of the user that made this method call, or `null` if no user was logged in."]
};
Template.api.method_invocation_setUserId = {
id: "method_setUserId",
name: "<i>this</i>.setUserId(userId)",
locus: "Server",
descr: ["Set the logged in user."],
args: [
{name: "userId",
type: "String or null",
descr: "The value that should be returned by `userId` on this connection."}
]
};
Template.api.method_invocation_unblock = {
id: "method_unblock",
name: "<i>this</i>.unblock()",
@@ -371,6 +398,93 @@ Template.api.findone = {
]
};
Template.api.insert = {
id: "insert",
name: "<em>collection</em>.insert(doc, [callback])",
locus: "Anywhere",
descr: ["Insert a document in the collection. Returns its unique _id."],
args: [
{name: "doc",
type: "Object",
descr: "The document to insert. Should not yet have an _id attribute."},
{name: "callback",
type: "Function",
descr: "Optional. If present, called with an error object as the first argument and, if no error, the _id as the second."}
]
};
Template.api.update = {
id: "update",
name: "<em>collection</em>.update(selector, modifier, [options], [callback])",
locus: "Anywhere",
descr: ["Modify one or more documents in the collection"],
args: [
{name: "selector",
type: "Object: Mongo selector, or String",
type_link: "selectors",
descr: "Specifies which documents to modify"},
{name: "modifier",
type: "Object: Mongo modifier",
type_link: "modifiers",
descr: "Specifies how to modify the documents"},
{name: "callback",
type: "Function",
descr: "Optional. If present, called with an error object as its argument."}
],
options: [
{name: "multi",
type: "Boolean",
descr: "True to modify all matching documents; false to only modify one of the matching documents (the default)."}
]
};
Template.api.remove = {
id: "remove",
name: "<em>collection</em>.remove(selector, [callback])",
locus: "Anywhere",
descr: ["Remove documents from the collection"],
args: [
{name: "selector",
type: "Object: Mongo selector, or String",
type_link: "selectors",
descr: "Specifies which documents to remove"},
{name: "callback",
type: "Function",
descr: "Optional. If present, called with an error object as its argument."}
]
};
Template.api.allow = {
id: "allow",
name: "<em>collection</em>.allow(options)",
locus: "Server",
descr: ["Allow users to write directly to this collection from client code, subject to limitations you define."],
options: [
{name: "insert, update, remove",
type: "Function",
descr: "Functions that look at a proposed modification to the database and return true if it should be allowed."},
{name: "fetch",
type: "Array of String",
descr: "Optional performance enhancement. Limits the fields that will be fetched from the database for inspection by your `update` and `remove` functions."}
]
};
Template.api.deny = {
id: "deny",
name: "<em>collection</em>.deny(options)",
locus: "Server",
descr: ["Override `allow` rules."],
options: [
{name: "insert, update, remove",
type: "Function",
descr: "Functions that look at a proposed modification to the database and return true if it should be denied, even if an `allow` rule says otherwise."},
{name: "fetch",
type: "Array of Strings",
descr: "Optional performance enhancement. Limits the fields that will be fetched from the database for inspection by your `update` and `remove` functions."}
]
};
Template.api.cursor_count = {
id: "count",
name: "<em>cursor</em>.count()",
@@ -429,62 +543,6 @@ Template.api.cursor_observe = {
]
};
Template.api.insert = {
id: "insert",
name: "<em>collection</em>.insert(doc, [callback])",
locus: "Anywhere",
descr: ["Insert a document in the collection. Returns its unique _id."],
args: [
{name: "doc",
type: "Object",
descr: "The document to insert. Should not yet have an _id attribute."},
{name: "callback",
type: "Function",
descr: "Optional. If present, called with an error object as the first argument and, if no error, the _id as the second."}
]
};
Template.api.update = {
id: "update",
name: "<em>collection</em>.update(selector, modifier, [options], [callback])",
locus: "Anywhere",
descr: ["Modify one or more documents in the collection"],
args: [
{name: "selector",
type: "Object: Mongo selector, or String",
type_link: "selectors",
descr: "Specifies which documents to modify"},
{name: "modifier",
type: "Object: Mongo modifier",
type_link: "modifiers",
descr: "Specifies how to modify the documents"},
{name: "callback",
type: "Function",
descr: "Optional. If present, called with an error object as its argument."}
],
options: [
{name: "multi",
type: "Boolean",
descr: "True to modify all matching documents; false to only modify one of the matching documents (the default)."}
]
};
Template.api.remove = {
id: "remove",
name: "<em>collection</em>.remove(selector, [callback])",
locus: "Anywhere",
descr: ["Remove documents from the collection"],
args: [
{name: "selector",
type: "Object: Mongo selector, or String",
type_link: "selectors",
descr: "Specifies which documents to remove"},
{name: "callback",
type: "Function",
descr: "Optional. If present, called with an error object as its argument."}
]
};
Template.api.selectors = {
id: "selectors",
name: "Mongo-style Selectors"
@@ -610,6 +668,380 @@ Template.api.isolate = {
Template.api.user = {
id: "meteor_user",
name: "Meteor.user()",
locus: "Anywhere but publish functions",
descr: ["Get the current user record, or `null` if no user is logged in. A reactive data source."]
};
Template.api.userId = {
id: "meteor_userid",
name: "Meteor.userId()",
locus: "Anywhere but publish functions",
descr: ["Get the current user id, or `null` if no user is logged in. A reactive data source."]
};
Template.api.users = {
id: "meteor_users",
name: "Meteor.users",
locus: "Anywhere",
descr: ["A <a href='#collections'>Meteor.Collection</a> containing user documents."]
};
Template.api.userLoaded = {
id: "meteor_userloaded",
name: "Meteor.userLoaded()",
locus: "Client",
descr: ["Determine if the current user document is fully loaded in <a href='#meteor_users'>Meteor.users</a>. A reactive data source."]
};
Template.api.logout = {
id: "meteor_logout",
name: "Meteor.logout([callback])",
locus: "Client",
descr: ["Log the user out."],
args: [
{
name: "callback",
type: "Function",
descr: "Optional callback. Called with no arguments on success, or with a single `Error` argument on failure."
}
]
};
Template.api.loginWithPassword = {
id: "meteor_loginwithpassword",
name: "Meteor.loginWithPassword(user, password, [callback])",
locus: "Client",
descr: ["Log the user in with a password."],
args: [
{
name: "user",
type: "Object or String",
descr: "Either a string interpreted as a username or an email; or an object with a single key: `email`, `username` or `id`."
},
{
name: "password",
type: "String",
descr: "The user's password. This is __not__ sent in plain text over the wire &mdash; it is secured with <a href='http://en.wikipedia.org/wiki/Secure_Remote_Password_protocol' target='_blank'>SRP</a>."
},
{
name: "callback",
type: "Function",
descr: "Optional callback. Called with no arguments on success, or with a single `Error` argument on failure."
}
]
};
Template.api.loginWithOAuth = {
id: "meteor_loginwithoauth",
name: "Meteor.loginWith<i>OAuthProvider</i>([options], [callback])",
locus: "Client",
descr: ["Log the user in using an external OAuth service."],
args: [
{
name: "callback",
type: "Function",
descr: "Optional callback. Called with no arguments on success, or with a single `Error` argument on failure."
}
],
options: [
{
name: "requestPermissions",
type: "Array of Strings",
descr: "A list of permissions to request from the user."
}
]
};
Template.api.accounts_createUser = {
id: "accounts_createuser",
name: "Accounts.createUser(options, [callback])",
locus: "Anywhere",
descr: ["Create a new user."],
args: [
{
name: "callback",
type: "Function",
descr: "Client only, optional callback. Called with no arguments on success, or with a single `Error` argument on failure."
}
],
options: [
{
name: "username",
type: "String",
descr: "A unique name for this user."
},
{
name: "email",
type: "String",
descr: "The user's email address."
},
{
name: "password",
type: "String",
descr: "The user's password. This is __not__ sent in plain text over the wire."
},
{
name: "profile",
type: "Object",
descr: "The user's profile, typically including the `name` field."
}
]
};
Template.api.accounts_changePassword = {
id: "accounts_changepassword",
name: "Accounts.changePassword(oldPassword, newPassword, [callback])",
locus: "Client",
descr: ["Change the current user's password. Must be logged in."],
args: [
{
name: "oldPassword",
type: "String",
descr: "The user's current password. This is __not__ sent in plain text over the wire."
},
{
name: "newPassword",
type: "String",
descr: "A new password for the user. This is __not__ sent in plain text over the wire."
},
{
name: "callback",
type: "Function",
descr: "Optional callback. Called with no arguments on success, or with a single `Error` argument on failure."
}
]
};
Template.api.accounts_forgotPassword = {
id: "accounts_forgotpassword",
name: "Accounts.forgotPassword(options, [callback])",
locus: "Client",
descr: ["Request a forgot password email."],
args: [
{
name: "callback",
type: "Function",
descr: "Optional callback. Called with no arguments on success, or with a single `Error` argument on failure."
}
],
options: [
{
name: "email",
type: "String",
descr: "The email address to send a password reset link."
}
]
};
Template.api.accounts_resetPassword = {
id: "accounts_resetpassword",
name: "Accounts.resetPassword(token, newPassword, [callback])",
locus: "Client",
descr: ["Reset the password for a user using a token received in email. Logs the user in afterwards."],
args: [
{
name: "token",
type: "String",
descr: "The token retrieved from the reset password URL."
},
{
name: "newPassword",
type: "String",
descr: "A new password for the user. This is __not__ sent in plain text over the wire."
},
{
name: "callback",
type: "Function",
descr: "Optional callback. Called with no arguments on success, or with a single `Error` argument on failure."
}
],
};
Template.api.accounts_setPassword = {
id: "accounts_setpassword",
name: "Accounts.setPassword(userId, newPassword)",
locus: "Server",
descr: ["Forcibly change the password for a user."],
args: [
{
name: "userId",
type: "String",
descr: "The id of the user to update."
},
{
name: "newPassword",
type: "String",
descr: "A new password for the user."
}
]
};
Template.api.accounts_verifyEmail = {
id: "accounts_verifyemail",
name: "Accounts.verifyEmail(token, [callback])",
locus: "Client",
descr: ["Marks the user's email address as verified. Logs the user in afterwards."],
args: [
{
name: "token",
type: "String",
descr: "The token retrieved from the verification URL."
},
{
name: "callback",
type: "Function",
descr: "Optional callback. Called with no arguments on success, or with a single `Error` argument on failure."
}
]
};
Template.api.accounts_sendResetPasswordEmail = {
id: "accounts_sendresetpasswordemail",
name: "Accounts.sendResetPasswordEmail(userId, [email])",
locus: "Server",
descr: ["Send an email with a link the user can use to reset their password."],
args: [
{
name: "userId",
type: "String",
descr: "The id of the user to send email to."
},
{
name: "email",
type: "String",
descr: "Optional. Which address of the user's to send the email to. This address must be in the user's `emails` list. Defaults to the first email in the list."
}
]
};
Template.api.accounts_sendEnrollmentEmail = {
id: "accounts_sendenrollmentemail",
name: "Accounts.sendEnrollmentEmail(userId, [email])",
locus: "Server",
descr: ["Send an email with a link the user can use to set their initial password."],
args: [
{
name: "userId",
type: "String",
descr: "The id of the user to send email to."
},
{
name: "email",
type: "String",
descr: "Optional. Which address of the user's to send the email to. This address must be in the user's `emails` list. Defaults to the first email in the list."
}
]
};
Template.api.accounts_sendVerificationEmail = {
id: "accounts_sendverificationemail",
name: "Accounts.sendVerificationEmail(userId, [email])",
locus: "Server",
descr: ["Send an email with a link the user can use verify their email address."],
args: [
{
name: "userId",
type: "String",
descr: "The id of the user to send email to."
},
{
name: "email",
type: "String",
descr: "Optional. Which address of the user's to send the email to. This address must be in the user's `emails` list. Defaults to the first unverified email in the list."
}
]
};
Template.api.accounts_emailTemplates = {
id: "accounts_emailtemplates",
name: "Accounts.emailTemplates",
locus: "Anywhere",
descr: ["XXX"]
};
Template.api.accounts_config = {
id: "accounts_config",
name: "Accounts.config(options)",
locus: "Anywhere",
descr: ["Set global accounts options."],
options: [
{
name: "sendVerificationEmail",
type: "Boolean",
descr: "New users with an email address will receive an address verification email."
},
{
name: "forbidClientAccountCreation",
type: "Boolean",
descr: "<a href='#accounts_createuser'>`createUser`</a> requests from the client will be rejected."
}
]
};
Template.api.accounts_ui_config = {
id: "accounts_ui_config",
name: "Accounts.ui.config(options)",
locus: "Client",
descr: ["Set Accounts UI options for the `loginButtons` template."],
options: [
{
name: "requestPermissions",
type: "Object",
descr: "Which permissions to request from the user for each OAuth service. For example: `{facebook: ['user_likes'], github: ['user', 'repo']}`"
},
{
name: "passwordSignupFields",
type: "String",
descr: "Which fields to display in the user creation form. One of '`USERNAME_AND_EMAIL`', '`USERNAME_AND_OPTIONAL_EMAIL`', '`USERNAME_ONLY`', or '`EMAIL_ONLY`' (default)."
}
]
};
Template.api.accounts_validateNewUser = {
id: "accounts_validatenewuser",
name: "Accounts.validateNewUser(func)",
locus: "Server",
descr: ["Set restrictions on new user creation."],
args: [
{
name: "func",
type: "Function",
descr: "Called whenever a new user is created. Takes the new user object, and returns true to allow the creation or false to abort."
}
]
};
Template.api.accounts_onCreateUser = {
id: "accounts_oncreateuser",
name: "Accounts.onCreateUser(func)",
locus: "Server",
descr: ["Customize new user creation."],
args: [
{
name: "func",
type: "Function",
descr: "Called whenever a new user is created. Return the new user ojbject, or throw an `Error` to abort the creation."
}
]
};
Template.api.setTimeout = {
id: "meteor_settimeout",
name: "Meteor.setTimeout",

View File

@@ -13,6 +13,7 @@ when writing those apps.
{{> livehtml }}
{{> templates }}
{{> packages_concept }}
{{> accounts }}
{{> deploying }}
</template>
@@ -207,6 +208,9 @@ And the reactive data sources that can trigger changes are:
* <a href="#session">Session</a> variables
* Database queries on <a href="#find">Collections</a>
* <a href="#meteor_status">`Meteor.status`</a>
* <a href="#meteor_user">`Meteor.user`</a>
* <a href="#meteor_userid">`Meteor.userId`</a>
* <a href="#meteor_userloaded">`Meteor.userLoaded`</a>
Meteor's <a href="https://github.com/meteor/meteor/blob/master/packages/deps/deps.js" target="_blank">implementation</a>
of reactivity is short and sweet, about 50 lines of code. You can
@@ -489,6 +493,30 @@ make your own packages just yet. Coming soon.
{{/better_markdown}}
</template>
<template name="accounts">
{{#better_markdown}}
<h2 id="accounts">Accounts</h2>
Meteor has an Accounts system.
- simplest integration
- add accounts-ui accounts-password
- and XXX loginButtons}} to app
- which packages
- can build own accounts-ui
- link to api section
{{/better_markdown}}
</template>
<template name="deploying">
{{#better_markdown}}

View File

@@ -265,6 +265,10 @@ dl.callbacks dt .name, dl.methods dt .name {
font-size: 1.1em;
}
dl.callbacks {
margin-left: 1.5em;
}
#main dd p {
margin-top: 0.5em;
}

View File

@@ -75,6 +75,7 @@ var toc = [
"Live HTML",
"Templates",
"Smart Packages",
"Accounts",
"Deploying"
],
@@ -93,7 +94,8 @@ var toc = [
{instance: "this", name: "complete", id: "publish_complete"},
{instance: "this", name: "flush", id: "publish_flush"},
{instance: "this", name: "onStop", id: "publish_onstop"},
{instance: "this", name: "stop", id: "publish_stop"}
{instance: "this", name: "stop", id: "publish_stop"},
{instance: "this", name: "userId", id: "publish_userId"}
],
"Meteor.subscribe",
"Meteor.autosubscribe"
@@ -101,6 +103,8 @@ var toc = [
{name: "Methods", id: "methods_header"}, [
"Meteor.methods", [
{instance: "this", name: "userId", id: "method_userId"},
{instance: "this", name: "setUserId", id: "method_setUserId"},
{instance: "this", name: "isSimulation", id: "method_issimulation"},
{instance: "this", name: "unblock", id: "method_unblock"}
],
@@ -121,7 +125,9 @@ var toc = [
{instance: "collection", name: "findOne"},
{instance: "collection", name: "insert"},
{instance: "collection", name: "update"},
{instance: "collection", name: "remove"}
{instance: "collection", name: "remove"},
{instance: "collection", name: "allow"},
{instance: "collection", name: "deny"}
],
"Meteor.Collection.Cursor", [
@@ -168,6 +174,41 @@ var toc = [
{name: "Reactivity isolation", style: "noncode", id: "isolate"}
],
{name: "Accounts", id: "accounts_api"}, [
"Meteor.user",
"Meteor.userId",
"Meteor.users",
"Meteor.userLoaded",
"Meteor.logout",
"Meteor.loginWithPassword",
{name: "Meteor.loginWithFacebook", id: "meteor_loginwithoauth"},
{name: "Meteor.loginWithGithub", id: "meteor_loginwithoauth"},
{name: "Meteor.loginWithGoogle", id: "meteor_loginwithoauth"},
{name: "Meteor.loginWithTwitter", id: "meteor_loginwithoauth"},
{name: "Meteor.loginWithWeibo", id: "meteor_loginwithoauth"},
{type: "spacer"},
"Accounts.createUser",
"Accounts.changePassword",
"Accounts.forgotPassword",
"Accounts.resetPassword",
"Accounts.setPassword",
"Accounts.verifyEmail",
{type: "spacer"},
"Accounts.sendResetPasswordEmail",
"Accounts.sendEnrollmentEmail",
"Accounts.sendVerificationEmail",
"Accounts.emailTemplates",
{type: "spacer"},
"Accounts.config",
"Accounts.ui.config",
"Accounts.validateNewUser",
"Accounts.onCreateUser"
],
"Timers", [
"Meteor.setTimeout",
"Meteor.setInterval",
@@ -206,6 +247,7 @@ var toc = [
],
"Packages", [ [
"accounts-ui",
"amplify",
"backbone",
"bootstrap",

View File

@@ -16,6 +16,7 @@ and removed with:
$ meteor remove <package_name>
{{> pkg_accounts_ui}}
{{> pkg_amplify}}
{{> pkg_backbone}}
{{> pkg_bootstrap}}

View File

@@ -0,0 +1,11 @@
<template name="pkg_accounts_ui">
{{#better_markdown}}
## `accounts-ui`
A full featured login interface.
`XXX loginButtons` and `XXX loginButtonsRight`.
{{/better_markdown}}
</template>