mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Merge branch 'auth-docs' into devel
This commit is contained in:
@@ -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`
|
||||
— 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
|
||||
|
||||
@@ -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 — 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",
|
||||
|
||||
@@ -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}}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -16,6 +16,7 @@ and removed with:
|
||||
|
||||
$ meteor remove <package_name>
|
||||
|
||||
{{> pkg_accounts_ui}}
|
||||
{{> pkg_amplify}}
|
||||
{{> pkg_backbone}}
|
||||
{{> pkg_bootstrap}}
|
||||
|
||||
11
docs/client/packages/accounts-ui.html
Normal file
11
docs/client/packages/accounts-ui.html
Normal 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>
|
||||
Reference in New Issue
Block a user