1.2. What can you build with Sails?
1.4. Fundamental concepts of a web application
1.6. Putting it all together in a backend API
1.7. Our backend design philosophy
1.7.1. Starting with just the frontend code
1.8. Delivering frontend assets
1.9. Frontend vs. backend validations
2.1.1. Mac, Windows, and Linux ... oh my!
2.1.2. Choosing a text editor vs. an IDE
2.2. How code is organized in Node.js
2.2.2. Creating your first Sails application
2.2.3. Using a module from npm
2.2.4. Starting the Sails server
2.3. Online resources for this book
Chapter 3. Using static assets
3.1. Introduction to static routing
3.2.1. A quick look at the .tmp/ folder
3.2.2. Grunt: the other white meat
3.2.3. Putting it all together: Chad’s sweet homepage
3.3. Managing scripts and stylesheets
3.4. Frontend-first API design
Chapter 4. Using the blueprint API
4.1. Prototyping with blueprints
4.1.1. Designing an API around a user interface
4.1.2. Obtaining the example materials for this chapter
4.2. Shortcut blueprint routes
4.3. Connecting the frontend to your new API
4.4. Exploring the REST of the blueprint API
4.4.1. Locating a particular record with AJAX
Chapter 5. Custom backend code
5.3. A deeper understanding of model methods
5.4.1. Finding a package to work with the YouTube API
5.4.2. Installing a machinepack
5.4.5. Understanding machine inputs
5.4.6. Setting your own custom configuration in local.js
5.4.7. Using custom configuration in your code
6.1. Understanding Sails models
6.2.1. Obtaining the example materials for this chapter
6.2.2. A frontend-first approach to data modeling
6.2.4. Building a user profile page
6.4.1. Models, connections, and adapters
6.5. Understanding model methods
6.5.1. Anatomy of a Sails model method
6.5.2. The .create() model method
6.5.3. The .find() model method
6.5.4. The .update() model method
7.1. Demystifying routes and actions
7.2. Identifying the requirements for your custom actions
7.3.3. Introducing req.param()
7.3.4. Validating email addresses
7.3.6. Profile images with Gravatar
7.3.8. Preventing duplicate accounts
7.3.9. Understanding response methods
7.3.10. Quick diversion: adding a dummy user in bootstrap.js
7.4. Providing data for a user profile page
7.4.1. Retrieving user profile information
7.6.1. Retrieving the record for a particular user
7.6.2. Retrieving a user’s Gravatar URL
Chapter 8. Server-rendered views
8.1.1. Client-side vs. server-side routing
8.2.1. A review of explicit routes
8.2.2. Defining an explicit route
8.2.4. Using partials and layout.ejs
Chapter 9. Authentication and sessions
9.2.1. Obtaining the example materials for the chapter
9.2.2. Understanding the backend for a login form
9.2.3. Creating a /login route
9.2.5. What does “stateless” mean?
9.2.6. Understanding the Sails session
9.2.7. Saving the user’s logged-in status
9.2.8. Creating the logout endpoint
9.2.9. Updating the session when a user is deleted or restored
9.3. Personalizing page content for logged-in users
9.4. Implementing the backend application flow
9.4.1. Personalizing your list of videos
9.4.2. Securing your administration page
9.4.3. Personalizing the user profile page
9.4.4. Securing the edit-profile page
Chapter 10. Policies and access control
10.1. A farewell to blueprints
10.1.1. Obtaining the example materials for this chapter
10.2.5. Preventing an inconsistent user experience
10.2.6. Restricting access to account management endpoints
10.2.7. Preventing users from messing with each other’s data
11.1. Maintaining your sanity when requirements change
11.1.1. Obtaining and revising requirements
11.1.2. Organizing views into five categories
11.1.3. Obtaining the example materials for this chapter
11.2. Custom routing and error pages
11.3. Adjusting access control rules
11.4. Patterns and best practices
11.4.1. Refactoring repetitive action names
11.4.2. Using folders to organize views
11.5. In depth: adding a password-recovery flow
Chapter 12. Embedded data and associations
12.1. Obtaining the example materials for this chapter
12.2. Understanding relationships between data
12.3. Associating data using embedded JSON
12.3.1. Setting up an embedded relationship
12.3.2. Creating a record with embedded JSON
12.4. Understanding Sails associations
12.4.1. Configuring an association between two models
12.4.2. Using .add(), .remove(), and .save()
12.4.3. Using via to create a two-way association
12.5.1. Example: using associations for the tutorials-detail page
Chapter 13. Ratings, followers, and search
13.1. Obtaining the example materials for this chapter
13.3.2. Review: adding a record to a collection association
13.3.4. Managing the sort order of videos using an embedded array
13.4. Implementing support for followers
Chapter 14. Realtime with WebSockets
14.1. Obtaining the example materials for this chapter
14.2. Understanding WebSockets
14.3.2. Adding chat to an existing page
14.3.3. Subscribing a socket to a room
14.4. Sending typing and stoppedTyping notifications
14.4.1. Listening for different kinds of notifications
14.5. Understanding resourceful pubsub
14.6. Understanding how the blueprint API uses RPS methods
Chapter 15. Deployment, testing, and security
15.1. Obtaining the example materials for this chapter
15.2. Deploying your Sails app
15.2.2. Scaling to multiple dynos
15.3. Using environment variables with Sails
15.3.1. Storing credentials in environment variables
15.4.1. Setting a default datastore for production
15.4.2. Configuring auto-migration settings
15.4.3. Creating tables in PostgreSQL
15.4.4. Runtime vs. build-time process
15.5. Configuring sessions and sockets for production
15.5.1. Provisioning a remote Redis To Go instance
15.5.2. Configuring a remote session store
15.5.3. Using Redis to deliver notifications
15.5.4. Using Redis in development (so you don’t have to log in all the time)
15.6.1. Installing dependencies for your test suite
15.6.2. Using before() and after()
15.6.3. Running tests from the command line
15.6.4. Configuring your test environment
15.6.7. Refactoring a test using fixtures and helper functions
15.7.1. Frontend, network, and backend security
15.7.2. Understanding cross-site scripting attacks
15.7.3. Protecting against XSS attacks
15.7.4. Understanding cross-site request forgery attacks
15.7.5. Enabling CSRF token protection
15.7.6. Sending the CSRF token
15.7.7. Disabling CSRF protection in tests
15.7.8. Understanding cross-origin resource sharing
15.7.9. Understanding man-in-the-middle attacks