├── .slugignore ├── .bowerrc ├── Procfile ├── public ├── robots.txt ├── modules │ ├── core │ │ ├── img │ │ │ ├── brand │ │ │ │ ├── favicon.ico │ │ │ │ └── northwind.png │ │ │ └── loaders │ │ │ │ └── loader.gif │ │ ├── core.client.module.js │ │ ├── controllers │ │ │ ├── home.client.controller.js │ │ │ └── header.client.controller.js │ │ ├── css │ │ │ └── core.css │ │ ├── config │ │ │ └── core.client.routes.js │ │ ├── tests │ │ │ ├── home.client.controller.test.js │ │ │ └── header.client.controller.test.js │ │ ├── views │ │ │ ├── header.client.view.html │ │ │ └── home.client.view.html │ │ └── services │ │ │ └── menus.client.service.js │ ├── users │ │ ├── img │ │ │ └── buttons │ │ │ │ ├── github.png │ │ │ │ ├── google.png │ │ │ │ ├── facebook.png │ │ │ │ ├── linkedin.png │ │ │ │ └── twitter.png │ │ ├── users.client.module.js │ │ ├── views │ │ │ ├── password │ │ │ │ ├── reset-password-success.client.view.html │ │ │ │ ├── reset-password-invalid.client.view.html │ │ │ │ ├── forgot-password.client.view.html │ │ │ │ └── reset-password.client.view.html │ │ │ ├── settings │ │ │ │ ├── change-password.client.view.html │ │ │ │ ├── social-accounts.client.view.html │ │ │ │ └── edit-profile.client.view.html │ │ │ └── authentication │ │ │ │ ├── signin.client.view.html │ │ │ │ └── signup.client.view.html │ │ ├── css │ │ │ └── users.css │ │ ├── services │ │ │ ├── authentication.client.service.js │ │ │ └── users.client.service.js │ │ ├── config │ │ │ ├── users.client.config.js │ │ │ └── users.client.routes.js │ │ ├── controllers │ │ │ ├── authentication.client.controller.js │ │ │ ├── password.client.controller.js │ │ │ └── settings.client.controller.js │ │ └── tests │ │ │ └── authentication.client.controller.test.js │ ├── products │ │ ├── products.client.module.js │ │ ├── services │ │ │ └── products.client.service.js │ │ ├── config │ │ │ ├── products.client.config.js │ │ │ └── products.client.routes.js │ │ ├── views │ │ │ ├── view-product.client.view.html │ │ │ ├── list-products.client.view.html │ │ │ ├── create-product.client.view.html │ │ │ └── edit-product.client.view.html │ │ ├── controllers │ │ │ └── products.client.controller.js │ │ └── tests │ │ │ └── products.client.controller.test.js │ └── categories │ │ ├── categories.client.module.js │ │ ├── services │ │ └── categories.client.service.js │ │ ├── config │ │ ├── categories.client.config.js │ │ └── categories.client.routes.js │ │ ├── views │ │ ├── view-category.client.view.html │ │ ├── list-categories.client.view.html │ │ ├── create-category.client.view.html │ │ └── edit-category.client.view.html │ │ ├── controllers │ │ └── categories.client.controller.js │ │ └── tests │ │ └── categories.client.controller.test.js ├── humans.txt ├── application.js └── config.js ├── .travis.yml ├── app ├── views │ ├── index.server.view.html │ ├── 500.server.view.html │ ├── 404.server.view.html │ ├── templates │ │ ├── reset-password-confirm-email.server.view.html │ │ └── reset-password-email.server.view.html │ └── layout.server.view.html ├── routes │ ├── core.server.routes.js │ ├── products.server.routes.js │ ├── categories.server.routes.js │ └── users.server.routes.js ├── controllers │ ├── core.server.controller.js │ ├── products.server.controller.js │ ├── categories.server.controller.js │ ├── api.authorization.server.controller.js │ ├── users.server.controller.js │ ├── errors.server.controller.js │ ├── users │ │ ├── users.authorization.server.controller.js │ │ ├── users.profile.server.controller.js │ │ ├── users.authentication.server.controller.js │ │ └── users.password.server.controller.js │ └── crud.server.controller.js ├── models │ ├── validation.server.model.js │ ├── category.server.model.js │ ├── product.server.model.js │ └── user.server.model.js └── tests │ ├── _.tests.js │ ├── models.server.routes.tests.api.js │ ├── user.server.model.test.js │ ├── products.server.routes.tests.js │ └── categories.server.routes.tests.js ├── .gitignore ├── fig.yml ├── .csslintrc ├── generate-ssl-certs.sh ├── bower.json ├── README.md ├── Dockerfile ├── config ├── passport.js ├── strategies │ ├── local.js │ ├── basic.js │ ├── twitter.js │ ├── github.js │ ├── google.js │ ├── facebook.js │ └── linkedin.js ├── init.js ├── env │ ├── all.js │ ├── development.js │ ├── test.js │ ├── secure.js │ └── production.js ├── config.js └── express.js ├── server.js ├── .editorconfig ├── LICENSE.md ├── migrations ├── 1422219657037-add-categories.js └── 1422753894413-add-products.js ├── karma.conf.js ├── .jshintrc ├── package.json └── gruntfile.js /.slugignore: -------------------------------------------------------------------------------- 1 | /app/tests -------------------------------------------------------------------------------- /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "public/lib" 3 | } 4 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: ./node_modules/.bin/forever -m 5 server.js 2 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # robotstxt.org/ 2 | 3 | User-agent: * 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | env: 5 | - NODE_ENV=travis 6 | services: 7 | - mongodb -------------------------------------------------------------------------------- /public/modules/core/img/brand/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbraithwaite/NorthwindNode/HEAD/public/modules/core/img/brand/favicon.ico -------------------------------------------------------------------------------- /public/modules/core/img/brand/northwind.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbraithwaite/NorthwindNode/HEAD/public/modules/core/img/brand/northwind.png -------------------------------------------------------------------------------- /public/modules/core/img/loaders/loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbraithwaite/NorthwindNode/HEAD/public/modules/core/img/loaders/loader.gif -------------------------------------------------------------------------------- /public/modules/users/img/buttons/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbraithwaite/NorthwindNode/HEAD/public/modules/users/img/buttons/github.png -------------------------------------------------------------------------------- /public/modules/users/img/buttons/google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbraithwaite/NorthwindNode/HEAD/public/modules/users/img/buttons/google.png -------------------------------------------------------------------------------- /public/modules/users/img/buttons/facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbraithwaite/NorthwindNode/HEAD/public/modules/users/img/buttons/facebook.png -------------------------------------------------------------------------------- /public/modules/users/img/buttons/linkedin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbraithwaite/NorthwindNode/HEAD/public/modules/users/img/buttons/linkedin.png -------------------------------------------------------------------------------- /public/modules/users/img/buttons/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbraithwaite/NorthwindNode/HEAD/public/modules/users/img/buttons/twitter.png -------------------------------------------------------------------------------- /app/views/index.server.view.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout.server.view.html' %} 2 | 3 | {% block content %} 4 | 5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /app/views/500.server.view.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout.server.view.html' %} 2 | 3 | {% block content %} 4 |
6 | {{error}}
7 |
8 | {% endblock %}
--------------------------------------------------------------------------------
/public/modules/core/core.client.module.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Use Applicaion configuration module to register a new module
4 | ApplicationConfiguration.registerModule('core');
--------------------------------------------------------------------------------
/public/modules/users/users.client.module.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Use Applicaion configuration module to register a new module
4 | ApplicationConfiguration.registerModule('users');
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .nodemonignore
3 | .sass-cache/
4 | npm-debug.log
5 | node_modules/
6 | public/lib
7 | app/tests/coverage/
8 | .bower-*/
9 | .idea/
10 | .migrate
11 |
--------------------------------------------------------------------------------
/public/modules/products/products.client.module.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Use applicaion configuration module to register a new module
4 | ApplicationConfiguration.registerModule('products');
--------------------------------------------------------------------------------
/app/views/404.server.view.html:
--------------------------------------------------------------------------------
1 | {% extends 'layout.server.view.html' %}
2 |
3 | {% block content %}
4 |
6 | {{url}} is not a valid path.
7 |
8 | {% endblock %}
--------------------------------------------------------------------------------
/public/modules/categories/categories.client.module.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Use application configuration module to register a new module
4 | ApplicationConfiguration.registerModule('categories');
5 |
--------------------------------------------------------------------------------
/fig.yml:
--------------------------------------------------------------------------------
1 | web:
2 | build: .
3 | links:
4 | - db
5 | ports:
6 | - "3000:3000"
7 | environment:
8 | NODE_ENV: development
9 | db:
10 | image: mongo
11 | ports:
12 | - "27017:27017"
--------------------------------------------------------------------------------
/app/routes/core.server.routes.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function(app) {
4 | // Root routing
5 | var core = require('../../app/controllers/core.server.controller');
6 | app.route('/').get(core.index);
7 | };
--------------------------------------------------------------------------------
/app/controllers/core.server.controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Module dependencies.
5 | */
6 | exports.index = function(req, res) {
7 | res.render('index', {
8 | user: req.user || null,
9 | request: req
10 | });
11 | };
--------------------------------------------------------------------------------
/public/modules/users/views/password/reset-password-success.client.view.html:
--------------------------------------------------------------------------------
1 | Dear {{name}},
7 | 8 |This is a confirmation that the password for your account has just been changed
9 |The {{appName}} Support Team
12 | 13 | -------------------------------------------------------------------------------- /public/modules/products/services/products.client.service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | //Products service used to communicate Products REST endpoints 4 | angular.module('products').factory('Products', ['$resource', 5 | function($resource) { 6 | return $resource('products/:productId', { productId: '@_id' 7 | }, { 8 | update: { 9 | method: 'PUT' 10 | } 11 | }); 12 | } 13 | ]); -------------------------------------------------------------------------------- /app/controllers/products.server.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | var mongoose = require('mongoose'), 7 | errorHandler = require('./errors.server.controller'), 8 | Category = mongoose.model('Category'), 9 | _ = require('lodash'); 10 | 11 | var crud = require('./crud.server.controller')('Product', 'name'); 12 | 13 | module.exports = crud; 14 | -------------------------------------------------------------------------------- /app/controllers/categories.server.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | var mongoose = require('mongoose'), 7 | errorHandler = require('./errors.server.controller'), 8 | Category = mongoose.model('Category'), 9 | _ = require('lodash'); 10 | 11 | var crud = require('./crud.server.controller')('Category', 'name'); 12 | 13 | module.exports = crud; 14 | -------------------------------------------------------------------------------- /public/modules/categories/services/categories.client.service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | //Categories service used to communicate Categories REST endpoints 4 | angular.module('categories').factory('Categories', ['$resource', 5 | function($resource) { 6 | return $resource('categories/:categoryId', { categoryId: '@_id' 7 | }, { 8 | update: { 9 | method: 'PUT' 10 | } 11 | }); 12 | } 13 | ]); 14 | -------------------------------------------------------------------------------- /.csslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "adjoining-classes": false, 3 | "box-model": false, 4 | "box-sizing": false, 5 | "floats": false, 6 | "font-sizes": false, 7 | "important": false, 8 | "known-properties": false, 9 | "overqualified-elements": false, 10 | "qualified-headings": false, 11 | "regex-selectors": false, 12 | "unique-headings": false, 13 | "universal-selector": false, 14 | "unqualified-attributes": false 15 | } 16 | -------------------------------------------------------------------------------- /app/controllers/api.authorization.server.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var passport = require('passport'); 4 | 5 | module.exports = function(req, res, next) { 6 | if (req.headers.authorization) { 7 | passport.authenticate('basic', { session: false }, function(err, user, info) { 8 | if (user) { 9 | req.apiAuthed = true; 10 | } 11 | next(); 12 | })(req, res, next); 13 | 14 | } else { 15 | next(); 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /generate-ssl-certs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Generating self-signed certificates..." 3 | openssl genrsa -out ./config/sslcerts/key.pem -aes256 1024 4 | openssl req -new -key ./config/sslcerts/key.pem -out ./config/sslcerts/csr.pem 5 | openssl x509 -req -days 9999 -in ./config/sslcerts/csr.pem -signkey ./config/sslcerts/key.pem -out ./config/sslcerts/cert.pem 6 | rm ./config/sslcerts/csr.pem 7 | chmod 600 ./config/sslcerts/key.pem ./config/sslcerts/cert.pem 8 | -------------------------------------------------------------------------------- /app/controllers/users.server.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | var _ = require('lodash'); 7 | 8 | /** 9 | * Extend user's controller 10 | */ 11 | module.exports = _.extend( 12 | require('./users/users.authentication.server.controller'), 13 | require('./users/users.authorization.server.controller'), 14 | require('./users/users.password.server.controller'), 15 | require('./users/users.profile.server.controller') 16 | ); -------------------------------------------------------------------------------- /public/modules/products/config/products.client.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Configuring the Articles module 4 | angular.module('products').run(['Menus', 5 | function(Menus) { 6 | // Set top bar menu items 7 | Menus.addMenuItem('topbar', 'Products', 'products', 'dropdown', '/products(/create)?'); 8 | Menus.addSubMenuItem('topbar', 'products', 'List Products', 'products'); 9 | Menus.addSubMenuItem('topbar', 'products', 'New Product', 'products/create'); 10 | } 11 | ]); -------------------------------------------------------------------------------- /public/modules/core/config/core.client.routes.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Setting up route 4 | angular.module('core').config(['$stateProvider', '$urlRouterProvider', 5 | function($stateProvider, $urlRouterProvider) { 6 | // Redirect to home view when route not found 7 | $urlRouterProvider.otherwise('/'); 8 | 9 | // Home state routing 10 | $stateProvider. 11 | state('home', { 12 | url: '/', 13 | templateUrl: 'modules/core/views/home.client.view.html' 14 | }); 15 | } 16 | ]); -------------------------------------------------------------------------------- /public/modules/categories/config/categories.client.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Configuring the Articles module 4 | angular.module('categories').run(['Menus', 5 | function(Menus) { 6 | // Set top bar menu items 7 | Menus.addMenuItem('topbar', 'Categories', 'categories', 'dropdown', '/categories(/create)?'); 8 | Menus.addSubMenuItem('topbar', 'categories', 'List Categories', 'categories'); 9 | Menus.addSubMenuItem('topbar', 'categories', 'New Category', 'categories/create'); 10 | } 11 | ]); 12 | -------------------------------------------------------------------------------- /app/views/templates/reset-password-email.server.view.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |Dear {{name}},
7 |9 | You have requested to have your password reset for your account at {{appName}} 10 |
11 |Please visit this url to reset your password:
12 |{{url}}
13 | If you didn't make this request, you can ignore this email. 14 |The {{appName}} Support Team
17 | 18 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "northwindnode", 3 | "version": "0.0.1", 4 | "description": "Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js", 5 | "dependencies": { 6 | "bootstrap": "~3", 7 | "angular": "~1.2", 8 | "angular-resource": "~1.2", 9 | "angular-mocks": "~1.2", 10 | "angular-cookies": "~1.2", 11 | "angular-animate": "~1.2", 12 | "angular-touch": "~1.2", 13 | "angular-sanitize": "~1.2", 14 | "angular-bootstrap": "~0.12.0", 15 | "angular-ui-utils": "~0.1.1", 16 | "angular-ui-router": "~0.2.11" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /public/modules/products/views/view-product.client.view.html: -------------------------------------------------------------------------------- 1 |{{ product.category.name }}
5 |Enter your account username.
4 |
6 | 11 | Welcome to the Northwind Node Example App. 12 |
13 |16 | See the full tutorial 17 |
18 |This app makes use of the MEAN.JS stack for creating a web application boilerplate.
23 |This sample application has registration and login, category management and product search.
24 |MongoDB is a database. MongoDB's great manual is the place to get started with NoSQL and MongoDB.
44 |Express is an app server. Check out The Express Guide or StackOverflow for more info.
50 |AngularJS is web app framework. Angular's website offers a lot. The Thinkster Popular Guide and Egghead Videos are great resources.
56 |Node.js is a web server. Node's website and this stackOverflow thread offer excellent starting points to get to grasps with node.
62 |