diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fc3cdd..a2db0da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## Unreleased + +#### Changed +- Accept explicit `username` or `email` in default login endpoint ([#121][]) + + ## [v0.8.2] - 2015-08-05 #### Changed @@ -355,3 +361,4 @@ _Note: API-breaking changes are in **bold**_ [#81]: https://github.com/kahmali/meteor-restivus/issues/81 "Issue #81" [#91]: https://github.com/kahmali/meteor-restivus/issues/91 "Issue #91" [#118]: https://github.com/kahmali/meteor-restivus/issues/118 "Issue #118" +[#121]: https://github.com/kahmali/meteor-restivus/issues/121 "Issue #121" diff --git a/README.md b/README.md index 20b9853..3c7b94e 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,10 @@ and is built on top of [Simple JSON Routes][json-routes] to provide: - [Consuming a Restivus API](#consuming-a-restivus-api) - [Basic Usage](#basic-usage) - [Authenticating](#authenticating) - - [Authenticated Calls](#authenticated-calls) + - [Default Authentication](#default-authentication) + - [Logging In](#logging-in) + - [Logging Out](#logging-out) + - [Authenticated Calls](#authenticated-calls) - [Upgrading Restivus](#upgrading-restivus) - [Upgrading to 0.8.0](#upgrading-to-080) - [Upgrading to 0.7.0](#upgrading-to-070) @@ -1129,30 +1132,47 @@ curl -d "message=Some message details" http://localhost:3000/api/articles/3/comm **Warning: Make sure you're using HTTPS, otherwise this is insecure!** +### Default Authentication + _Note: To use the default authentication, you must first [create a user with the `accounts-password` package](http://docs.meteor.com/#/full/accounts_passwords). You can do this with Restivus if you [setup a POST collection endpoint for the `Meteor.users` collection](#users-collection-endpoints)._ +#### Logging In + If you have `useDefaultAuth` set to `true`, you now have a `POST /api/login` endpoint that returns a -`userId` and `authToken`. You must save these, and include them in subsequent requests. +`userId` and `authToken`. You must save these, and include them in subsequent requests. The login +endpoint accepts the following parameters (via the request body): +- `email`: An email address associated with your `Meteor.user` account +- `username`: The username associated with your `Meteor.user` account +- `user`: **Note: This is for legacy purposes only. It is recommended to use one of the options + above.** Accepts either of the options listed above. Restivus will (very naively) attempt to + determine if the value provided is an email, otherwise it will assume it to be the username. This + can sometimes lead to unexpected behavior. + +A login will look something like ```bash -curl http://localhost:3000/api/login/ -d "password=testpassword&user=test" +curl http://localhost:3000/api/login/ -d "username=test&password=password" ``` -The response will look like this, which you must save (for subsequent authenticated requests): +And the response will look like ```javascript { status: "success", data: {authToken: "f2KpRW7KeN9aPmjSZ", userId: fbdpsNf4oHiX79vMJ} } ``` + +You'll need to save the `userId` and `token` on the client, for subsequent authenticated requests. + +#### Logging Out -You also have an authenticated `GET /api/logout` endpoint for logging a user out. If successful, the +You also have an authenticated `POST /api/logout` endpoint for logging a user out. If successful, the auth token that is passed in the request header will be invalidated (removed from the user account), so it will not work in any subsequent requests. ```bash -curl http://localhost:3000/api/logout -H "X-Auth-Token: f2KpRW7KeN9aPmjSZ" -H "X-User-Id: fbdpsNf4oHiX79vMJ" +curl http://localhost:3000/api/logout -X POST -H "X-Auth-Token: f2KpRW7KeN9aPmjSZ" -H "X-User-Id: fbdpsNf4oHiX79vMJ" ``` -## Authenticated Calls +#### Authenticated Calls For any endpoints that require the default authentication, you must include the `userId` and `authToken` with each request under the following headers: diff --git a/lib/restivus.coffee b/lib/restivus.coffee index d7cdad4..82e7cc4 100644 --- a/lib/restivus.coffee +++ b/lib/restivus.coffee @@ -255,10 +255,15 @@ class @Restivus post: -> # Grab the username or email that the user is logging in with user = {} - if @bodyParams.user.indexOf('@') is -1 - user.username = @bodyParams.user - else - user.email = @bodyParams.user + if @bodyParams.user + if @bodyParams.user.indexOf('@') is -1 + user.username = @bodyParams.user + else + user.email = @bodyParams.user + else if @bodyParams.username + user.username = @bodyParams.username + else if @bodyParams.email + user.email = @bodyParams.email # Try to log the user into the user's account (if successful we'll get an auth token back) try diff --git a/test/authentication_tests.coffee b/test/authentication_tests.coffee index cabf79c..faa53cc 100644 --- a/test/authentication_tests.coffee +++ b/test/authentication_tests.coffee @@ -47,7 +47,7 @@ describe 'The default authentication endpoints', -> userId = Accounts.createUser { username: username - email + email: email password: password } @@ -93,8 +93,32 @@ describe 'The default authentication endpoints', -> test.isUndefined response?.data?.authToken - it 'should allow a user to login', (test, waitFor) -> + # Explicit username + HTTP.post Meteor.absoluteUrl('default-auth/login'), { + data: + username: username + password: password + }, waitFor (error, result) -> + response = result.data + test.equal result.statusCode, 200 + test.equal response.status, 'success' + test.equal response.data.userId, userId + test.isTrue response.data.authToken + + # Explicit email + HTTP.post Meteor.absoluteUrl('default-auth/login'), { + data: + email: email + password: password + }, waitFor (error, result) -> + response = result.data + test.equal result.statusCode, 200 + test.equal response.status, 'success' + test.equal response.data.userId, userId + test.isTrue response.data.authToken + + # Implicit username HTTP.post Meteor.absoluteUrl('default-auth/login'), { data: user: username @@ -106,6 +130,18 @@ describe 'The default authentication endpoints', -> test.equal response.data.userId, userId test.isTrue response.data.authToken + # Implicit email + HTTP.post Meteor.absoluteUrl('default-auth/login'), { + data: + user: email + password: password + }, waitFor (error, result) -> + response = result.data + test.equal result.statusCode, 200 + test.equal response.status, 'success' + test.equal response.data.userId, userId + test.isTrue response.data.authToken + # Store the token for later use token = response.data.authToken