Objective: Implement Angular authentication with Satellizer. Your goal is to have working sign up and log in functionality.
-
Fork and clone this repo
-
Once you're in your app directory, run
npm install
to install the requirednode_modules
. -
In one Terminal window, run
mongod
, and in another, runnodemon
. -
Navigate to
localhost:9000
in the browser. You should see an empty page and an angry red error message in the Chrome console. -
BEFORE WRITING ANY CODE, open up
models/user.js
,resources/auth.js
, andserver.js
. Go through these files and look through each code block to see what is already in place for you. -
Open up
index.hbs
andapp.js
, and see what's in there also. -
Add a "dot" file, called
.env
to the root directory. Add this line to the file:
TOKEN_SECRET=yoursupersecrettoken
This is the secret your server will use to encode the JWT token for each user.
- Before hooking up the front-end, test your server routes via Postman:
- Send a
GET
request to/api/me
just going to that route in your browser. You should see the message: "Please make sure your request has an Authorization header." - Send a
POST
request using Postman tolocalhost:9000/auth/signup
with a testemail
andpassword
. You should see a token that was generated by the server. (You are simulating a form submission, so make sure to usex-www-form-urlencoded
and send your data(email and password) in thebody
of the request). - Send a
POST
request tolocalhost:9000/auth/login
with theemail
andpassword
you just used to create a new user. You should again see a token that was generated by the server.
- Now it's time to implement authentication from the client. First, you need to include Satellizer in your Angular app:
- Add the Satellizer CDN to
index.hbs
(TODO #1).<script src="https://cdn.jsdelivr.net/satellizer/0.14.1/satellizer.min.js"></script>
- Add the Satellizer module to your Angular app in
app.js
(TODO #2). - Check that you can navigate between your routes (
/
,/signup
,/login
, and/profile
).
-
Follow the instructions to finish implementing
Account.login()
(TODO #3, #4, #5).TODO #3 Hint
``` js $auth.setToken(response.data.token) ```TODO #4 Hint
``` js vm.new_user = {} ```TODO #5 Hint
inject $location into your controller
$location.path('/profile')
-
Click the "Log Out" link to logout (TODO #6) and make sure it redirects to
/login
(TODO #7).TODO #6 Hint:
```js return ( $auth .logout() // delete token .then(function() { $auth.removeToken(); self.user = null; }) ) ```TODO #7 Hint:
add $location into this controller also$location.path('/login')
-
Implement the functionality outlined in
Account.signup()
(TODO #8, #9, #10).TODO #8 Hint
return ( $auth .signup(userData) .then(function(response) { // Redirect user here to login page or perhaps some other intermediate page // that requires email address verification before any other part of the site can be accessed. $auth.setToken(response.data.token); }) .catch(function(response) { console.log("handling errors?", response); }) );
TODO #9 Hint
inject $location into your controller
vm.new_user = {}
TODO #10 Hint
inject $location into your controller ```js $location.path('/profile') ``` -
At this point, you should be able to sign up a user, log them in, and view their profile page from the client.
-
Add a
username
field to the Sign Up form, and add theusername
attribute toUser
model (server-side). Sign up a new user with ausername
(TODO #11 in signup.html, #12 in user.js).TODO #11 Hint
```html -
On the user profile page, make a form to edit the user's details. The form should initially be hidden, and when the user clicks a button or link to "Edit Profile", the form should show (Hint:
ng-show
) (TODO #13). -
When the user submits the form, it should call a function in the
ProfileCtrl
(Hint:ng-submit
). The function should send an$http.put
request to/api/me
. Verify that this works. (TODO #14) -
Bonus: Decouple the edit form from the user's other details. For instance, when I type into the edit form it shouldn't instantly change my email or my username, but it should still change those values on (a successful) submit!
No more TODOs! You're on your own from here on out!
-
Create a form on the homepage for the user to add a blog-post (that's right - you're turning your Angular app into a microblog). The blog-post form should have input (
title
) and textarea (content
) fields. Hint: Useng-model
. -
Only show the form if there is a
currentUser
logged in. -
Use the
ng-submit
directive to run a function calledcreatePost
when the user submits the form. -
createPost
should make an$http.post
request to/api/posts
(which isn't defined on the server yet!) with thevm.post
object. -
The next step is to implement posts on the server. First, create a Mongoose model
Post
(models/post.js
). -
A user should have many posts, so add an attribute to the
User
model calledposts
that references thePost
model:
/*
* models/user.js
*/
var userSchema = new Schema({
...
posts: [{ type: Schema.Types.ObjectId, ref: 'Post' }]
});
- In
server.js
, define two new API routes:
GET /api/posts
should retrieve all the posts from the database.POST /api/posts
should create a new post that belongs to the current user (Hint: Use theauth.ensureAuthenticated
function in the route to find the current user).
- Refresh
localhost:9000
in the browser. Make sure you have a user logged in, and try to create a new post. Check the Chrome developer tools to make sure it's working.
-
Validate blog-posts! Ensure a user can't submit an empty title or content. (Use both backend AND frontend validations).
-
On the user's profile page, display the number of posts the user has written. Hint: You'll need to add
.populate('posts')
to yourGET /api/me
route inserver.js
. -
On the user profile page, the "Joined" date isn't formatted very nicely. Use Angular's built-in date filter to display the date in this format:
January 25, 2016
.