From ef3a3f954852c7717844fe0c18647ad4290b2945 Mon Sep 17 00:00:00 2001 From: Ryan Hutchison Date: Sat, 25 Jul 2015 16:53:11 -0400 Subject: [PATCH] formatting reboot (space-2 and consistency) JSCS fixes update editorconfig --- .bowerrc | 2 +- .csslintrc | 26 +- .editorconfig | 5 +- .jshintrc | 68 +- config/assets/default.js | 90 +-- config/assets/development.js | 2 +- config/assets/production.js | 38 +- config/assets/test.js | 10 +- config/config.js | 233 +++---- config/env/default.js | 24 +- config/env/development.js | 124 ++-- config/env/local.example.js | 26 +- config/env/production.js | 122 ++-- config/env/test.js | 108 +-- config/lib/express.js | 310 ++++----- config/lib/mongoose.js | 52 +- config/lib/socket.io.js | 38 +- gruntfile.js | 483 +++++++------- gulpfile.js | 206 +++--- karma.conf.js | 4 +- .../client/config/articles.client.config.js | 36 +- .../client/config/articles.client.routes.js | 56 +- .../controllers/articles.client.controller.js | 108 +-- .../services/articles.client.service.js | 18 +- .../views/create-article.client.view.html | 54 +- .../views/edit-article.client.view.html | 54 +- .../views/list-articles.client.view.html | 36 +- .../views/view-article.client.view.html | 40 +- .../controllers/articles.server.controller.js | 137 ++-- .../server/models/article.server.model.js | 40 +- .../server/policies/articles.server.policy.js | 102 +-- .../server/routes/articles.server.routes.js | 26 +- .../articles.client.controller.tests.js | 44 +- .../articles/tests/e2e/articles.e2e.tests.js | 14 +- .../server/article.server.model.tests.js | 84 +-- .../server/article.server.routes.tests.js | 613 +++++++++--------- .../chat/client/config/chat.client.config.js | 14 +- .../chat/client/config/chat.client.routes.js | 20 +- .../controllers/chat.client.controller.js | 73 ++- modules/chat/client/css/chat.css | 17 +- .../chat/client/views/chat.client.view.html | 45 +- .../sockets/chat.server.socket.config.js | 52 +- .../client/chat.client.controller.tests.js | 36 +- modules/chat/tests/e2e/chat.e2e.tests.js | 4 +- .../chat/tests/server/chat.socket.tests.js | 4 +- modules/core/client/app/config.js | 32 +- modules/core/client/app/init.js | 77 +-- .../client/config/core-admin.client.menus.js | 16 +- .../client/config/core-admin.client.routes.js | 22 +- .../core/client/config/core.client.routes.js | 28 +- .../controllers/header.client.controller.js | 32 +- .../controllers/home.client.controller.js | 8 +- modules/core/client/css/core.css | 44 +- .../client/services/menus.client.service.js | 23 +- .../services/socket.io.client.service.js | 65 +- .../core/client/views/404.client.view.html | 5 +- .../core/client/views/header.client.view.html | 114 ++-- .../core/client/views/home.client.view.html | 172 +++-- .../controllers/core.server.controller.js | 46 +- .../controllers/errors.server.controller.js | 56 +- .../core/server/routes/core.server.routes.js | 18 +- .../core/server/views/404.server.view.html | 6 +- .../core/server/views/500.server.view.html | 2 +- .../core/server/views/index.server.view.html | 2 +- .../core/server/views/layout.server.view.html | 108 +-- .../core/tests/client/core.client.tests.js | 6 +- .../client/header.client.controller.tests.js | 26 +- .../client/home.client.controller.tests.js | 34 +- .../client/config/users-admin.client.menus.js | 12 +- .../config/users-admin.client.routes.js | 64 +- .../client/config/users.client.config.js | 46 +- .../client/config/users.client.routes.js | 134 ++-- .../admin/user-list.client.controller.js | 48 +- .../admin/user.client.controller.js | 52 +- .../authentication.client.controller.js | 92 +-- .../controllers/password.client.controller.js | 82 +-- .../change-password.client.controller.js | 28 +- ...hange-profile-picture.client.controller.js | 112 ++-- .../edit-profile.client.controller.js | 36 +- ...anage-social-accounts.client.controller.js | 58 +- .../settings/settings.client.controller.js | 6 +- modules/users/client/css/users.css | 53 +- .../services/authentication.client.service.js | 12 +- .../client/services/users.client.service.js | 33 +- .../views/admin/user-edit.client.view.html | 66 +- .../views/admin/user-list.client.view.html | 34 +- .../client/views/admin/user.client.view.html | 96 +-- .../authentication.client.view.html | 20 +- .../authentication/signin.client.view.html | 56 +- .../authentication/signup.client.view.html | 80 +-- .../password/forgot-password.client.view.html | 6 +- .../reset-password-invalid.client.view.html | 4 +- .../reset-password-success.client.view.html | 4 +- .../settings/change-password.client.view.html | 54 +- .../change-profile-picture.client.view.html | 48 +- .../settings/edit-profile.client.view.html | 62 +- .../manage-social-accounts.client.view.html | 96 +-- .../views/settings/settings.client.view.html | 48 +- .../server/config/strategies/facebook.js | 62 +- .../users/server/config/strategies/github.js | 72 +- .../users/server/config/strategies/google.js | 62 +- .../server/config/strategies/linkedin.js | 64 +- .../users/server/config/strategies/local.js | 48 +- .../users/server/config/strategies/paypal.js | 60 +- .../users/server/config/strategies/twitter.js | 68 +- .../server/config/users.server.config.js | 46 +- .../controllers/admin.server.controller.js | 96 +-- .../controllers/users.server.controller.js | 8 +- .../users.authentication.server.controller.js | 379 +++++------ .../users.authorization.server.controller.js | 34 +- .../users/users.password.server.controller.js | 448 ++++++------- .../users/users.profile.server.controller.js | 134 ++-- .../users/server/models/user.server.model.js | 214 +++--- .../server/policies/admin.server.policy.js | 54 +- .../server/routes/admin.server.routes.js | 26 +- .../users/server/routes/auth.server.routes.js | 98 +-- .../server/routes/users.server.routes.js | 20 +- ...et-password-confirm-email.server.view.html | 12 +- .../reset-password-email.server.view.html | 22 +- .../authentication.client.controller.tests.js | 34 +- modules/users/tests/e2e/users.e2e.tests.js | 20 +- .../tests/server/user.server.model.tests.js | 196 +++--- .../tests/server/user.server.routes.tests.js | 186 +++--- protractor.conf.js | 2 +- 124 files changed, 4330 insertions(+), 4317 deletions(-) diff --git a/.bowerrc b/.bowerrc index 1b84277940..47ad66735b 100644 --- a/.bowerrc +++ b/.bowerrc @@ -1,3 +1,3 @@ { - "directory": "public/lib" + "directory": "public/lib" } diff --git a/.csslintrc b/.csslintrc index 0dab227ebb..09f7bf209a 100644 --- a/.csslintrc +++ b/.csslintrc @@ -1,15 +1,15 @@ { - "adjoining-classes": false, - "box-model": false, - "box-sizing": false, - "floats": false, - "font-sizes": false, - "important": false, - "known-properties": false, - "overqualified-elements": false, - "qualified-headings": false, - "regex-selectors": false, - "unique-headings": false, - "universal-selector": false, - "unqualified-attributes": false + "adjoining-classes": false, + "box-model": false, + "box-sizing": false, + "floats": false, + "font-sizes": false, + "important": false, + "known-properties": false, + "overqualified-elements": false, + "qualified-headings": false, + "regex-selectors": false, + "unique-headings": false, + "universal-selector": false, + "unqualified-attributes": false } diff --git a/.editorconfig b/.editorconfig index 6c012e5334..d27bd05b8a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,12 +14,13 @@ insert_final_newline = true # Standard at: https://github.com/felixge/node-style-guide [**.js, **.json] trim_trailing_whitespace = true -indent_style = tab +indent_style = space +indent_size = 2 quote_type = single curly_bracket_next_line = false spaces_around_operators = true space_after_control_statements = true -space_after_anonymous_functions = false +space_after_anonymous_functions = true spaces_in_brackets = false # No Standard. Please document a standard if different from .js diff --git a/.jshintrc b/.jshintrc index b3a00dc361..b1c735f190 100644 --- a/.jshintrc +++ b/.jshintrc @@ -1,36 +1,36 @@ { - "node": true, // Enable globals available when code is running inside of the NodeJS runtime environment. - "mocha": true, // Enable globals available when code is running inside of the Mocha tests. - "jasmine": true, // Enable globals available when code is running inside of the Jasmine tests. - "browser": true, // Standard browser globals e.g. `window`, `document`. - "esnext": true, // Allow ES.next specific features such as `const` and `let`. - "bitwise": false, // Prohibit bitwise operators (&, |, ^, etc.). - "camelcase": false, // Permit only camelcase for `var` and `object indexes`. - "curly": false, // Require {} for every new block or scope. - "eqeqeq": true, // Require triple equals i.e. `===`. - "immed": true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );` - "latedef": true, // Prohibit variable use before definition. - "newcap": true, // Require capitalization of all constructor functions e.g. `new F()`. - "noarg": true, // Prohibit use of `arguments.caller` and `arguments.callee`. - "quotmark": "single", // Define quotes to string values. - "regexp": true, // Prohibit `.` and `[^...]` in regular expressions. - "undef": true, // Require all non-global variables be declared before they are used. - "unused": false, // Warn unused variables. - "strict": true, // Require `use strict` pragma in every file. - "trailing": true, // Prohibit trailing whitespaces. - "smarttabs": false, // Suppresses warnings about mixed tabs and spaces - "globals": { // Globals variables. - "angular": true, - "io": true, - "ApplicationConfiguration": true - }, - "predef": [ // Extra globals. - "inject", - "by", - "browser", - "element" - ], - "indent": 4, // Specify indentation spacing - "devel": true, // Allow development statements e.g. `console.log();`. - "noempty": true // Prohibit use of empty blocks. + "node": true, // Enable globals available when code is running inside of the NodeJS runtime environment. + "mocha": true, // Enable globals available when code is running inside of the Mocha tests. + "jasmine": true, // Enable globals available when code is running inside of the Jasmine tests. + "browser": true, // Standard browser globals e.g. `window`, `document`. + "esnext": true, // Allow ES.next specific features such as `const` and `let`. + "bitwise": false, // Prohibit bitwise operators (&, |, ^, etc.). + "camelcase": false, // Permit only camelcase for `var` and `object indexes`. + "curly": false, // Require {} for every new block or scope. + "eqeqeq": true, // Require triple equals i.e. `===`. + "immed": true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );` + "latedef": true, // Prohibit variable use before definition. + "newcap": true, // Require capitalization of all constructor functions e.g. `new F()`. + "noarg": true, // Prohibit use of `arguments.caller` and `arguments.callee`. + "quotmark": "single", // Define quotes to string values. + "regexp": true, // Prohibit `.` and `[^...]` in regular expressions. + "undef": true, // Require all non-global variables be declared before they are used. + "unused": false, // Warn unused variables. + "strict": true, // Require `use strict` pragma in every file. + "trailing": true, // Prohibit trailing whitespaces. + "smarttabs": false, // Suppresses warnings about mixed tabs and spaces + "globals": { // Globals variables. + "angular": true, + "io": true, + "ApplicationConfiguration": true + }, + "predef": [ // Extra globals. + "inject", + "by", + "browser", + "element" + ], + "indent": 4, // Specify indentation spacing + "devel": true, // Allow development statements e.g. `console.log();`. + "noempty": true // Prohibit use of empty blocks. } diff --git a/config/assets/default.js b/config/assets/default.js index 27eece02fe..ce8d70a65d 100644 --- a/config/assets/default.js +++ b/config/assets/default.js @@ -1,49 +1,49 @@ 'use strict'; module.exports = { - client: { - lib: { - css: [ - 'public/lib/bootstrap/dist/css/bootstrap.css', - 'public/lib/bootstrap/dist/css/bootstrap-theme.css' - ], - js: [ - 'public/lib/angular/angular.js', - 'public/lib/angular-resource/angular-resource.js', - 'public/lib/angular-animate/angular-animate.js', - 'public/lib/angular-ui-router/release/angular-ui-router.js', - 'public/lib/angular-ui-utils/ui-utils.js', - 'public/lib/angular-bootstrap/ui-bootstrap-tpls.js', - 'public/lib/angular-file-upload/angular-file-upload.js' - ], - tests: ['public/lib/angular-mocks/angular-mocks.js'] - }, - css: [ - 'modules/*/client/css/*.css' - ], - less: [ - 'modules/*/client/less/*.less' - ], - sass: [ - 'modules/*/client/scss/*.scss' - ], - js: [ - 'modules/core/client/app/config.js', - 'modules/core/client/app/init.js', - 'modules/*/client/*.js', - 'modules/*/client/**/*.js' - ], - views: ['modules/*/client/views/**/*.html'] - }, - server: { - gruntConfig: 'gruntfile.js', - gulpConfig: 'gulpfile.js', - allJS: ['server.js', 'config/**/*.js', 'modules/*/server/**/*.js'], - models: 'modules/*/server/models/**/*.js', - routes: ['modules/!(core)/server/routes/**/*.js', 'modules/core/server/routes/**/*.js'], - sockets: 'modules/*/server/sockets/**/*.js', - config: 'modules/*/server/config/*.js', - policies: 'modules/*/server/policies/*.js', - views: 'modules/*/server/views/*.html' - } + client: { + lib: { + css: [ + 'public/lib/bootstrap/dist/css/bootstrap.css', + 'public/lib/bootstrap/dist/css/bootstrap-theme.css' + ], + js: [ + 'public/lib/angular/angular.js', + 'public/lib/angular-resource/angular-resource.js', + 'public/lib/angular-animate/angular-animate.js', + 'public/lib/angular-ui-router/release/angular-ui-router.js', + 'public/lib/angular-ui-utils/ui-utils.js', + 'public/lib/angular-bootstrap/ui-bootstrap-tpls.js', + 'public/lib/angular-file-upload/angular-file-upload.js' + ], + tests: ['public/lib/angular-mocks/angular-mocks.js'] + }, + css: [ + 'modules/*/client/css/*.css' + ], + less: [ + 'modules/*/client/less/*.less' + ], + sass: [ + 'modules/*/client/scss/*.scss' + ], + js: [ + 'modules/core/client/app/config.js', + 'modules/core/client/app/init.js', + 'modules/*/client/*.js', + 'modules/*/client/**/*.js' + ], + views: ['modules/*/client/views/**/*.html'] + }, + server: { + gruntConfig: 'gruntfile.js', + gulpConfig: 'gulpfile.js', + allJS: ['server.js', 'config/**/*.js', 'modules/*/server/**/*.js'], + models: 'modules/*/server/models/**/*.js', + routes: ['modules/!(core)/server/routes/**/*.js', 'modules/core/server/routes/**/*.js'], + sockets: 'modules/*/server/sockets/**/*.js', + config: 'modules/*/server/config/*.js', + policies: 'modules/*/server/policies/*.js', + views: 'modules/*/server/views/*.html' + } }; diff --git a/config/assets/development.js b/config/assets/development.js index b521b6577d..bdd0b25c01 100644 --- a/config/assets/development.js +++ b/config/assets/development.js @@ -1,5 +1,5 @@ 'use strict'; module.exports = { - // Development assets + // Development assets }; diff --git a/config/assets/production.js b/config/assets/production.js index 9a664c455b..ed4f296173 100644 --- a/config/assets/production.js +++ b/config/assets/production.js @@ -1,23 +1,23 @@ 'use strict'; module.exports = { - client: { - lib: { - css: [ - 'public/lib/bootstrap/dist/css/bootstrap.min.css', - 'public/lib/bootstrap/dist/css/bootstrap-theme.min.css', - ], - js: [ - 'public/lib/angular/angular.min.js', - 'public/lib/angular-resource/angular-resource.min.js', - 'public/lib/angular-animate/angular-animate.min.js', - 'public/lib/angular-ui-router/release/angular-ui-router.min.js', - 'public/lib/angular-ui-utils/ui-utils.min.js', - 'public/lib/angular-bootstrap/ui-bootstrap-tpls.min.js', - 'public/lib/angular-file-upload/angular-file-upload.min.js' - ] - }, - css: 'public/dist/application.min.css', - js: 'public/dist/application.min.js' - } + client: { + lib: { + css: [ + 'public/lib/bootstrap/dist/css/bootstrap.min.css', + 'public/lib/bootstrap/dist/css/bootstrap-theme.min.css', + ], + js: [ + 'public/lib/angular/angular.min.js', + 'public/lib/angular-resource/angular-resource.min.js', + 'public/lib/angular-animate/angular-animate.min.js', + 'public/lib/angular-ui-router/release/angular-ui-router.min.js', + 'public/lib/angular-ui-utils/ui-utils.min.js', + 'public/lib/angular-bootstrap/ui-bootstrap-tpls.min.js', + 'public/lib/angular-file-upload/angular-file-upload.min.js' + ] + }, + css: 'public/dist/application.min.css', + js: 'public/dist/application.min.js' + } }; diff --git a/config/assets/test.js b/config/assets/test.js index 29ffa89c9e..365d6510ee 100644 --- a/config/assets/test.js +++ b/config/assets/test.js @@ -1,9 +1,9 @@ 'use strict'; module.exports = { - tests: { - client: ['modules/*/tests/client/**/*.js'], - server: ['modules/*/tests/server/**/*.js'], - e2e: ['modules/*/tests/e2e/**/*.js'] - } + tests: { + client: ['modules/*/tests/client/**/*.js'], + server: ['modules/*/tests/server/**/*.js'], + e2e: ['modules/*/tests/e2e/**/*.js'] + } }; diff --git a/config/config.js b/config/config.js index 6a0dacdaed..f2db078212 100644 --- a/config/config.js +++ b/config/config.js @@ -4,179 +4,180 @@ * Module dependencies. */ var _ = require('lodash'), - chalk = require('chalk'), - glob = require('glob'), - fs = require('fs'), - path = require('path'); + chalk = require('chalk'), + glob = require('glob'), + fs = require('fs'), + path = require('path'); /** * Get files by glob patterns */ -var getGlobbedPaths = function(globPatterns, excludes) { - // URL paths regex - var urlRegex = new RegExp('^(?:[a-z]+:)?\/\/', 'i'); - - // The output array - var output = []; - - // If glob pattern is array so we use each pattern in a recursive way, otherwise we use glob - if (_.isArray(globPatterns)) { - globPatterns.forEach(function(globPattern) { - output = _.union(output, getGlobbedPaths(globPattern, excludes)); - }); - } else if (_.isString(globPatterns)) { - if (urlRegex.test(globPatterns)) { - output.push(globPatterns); - } else { - var files = glob.sync(globPatterns); - if (excludes) { - files = files.map(function(file) { - if (_.isArray(excludes)) { - for (var i in excludes) { - file = file.replace(excludes[i], ''); - } - } else { - file = file.replace(excludes, ''); - } - return file; - }); +var getGlobbedPaths = function (globPatterns, excludes) { + // URL paths regex + var urlRegex = new RegExp('^(?:[a-z]+:)?\/\/', 'i'); + + // The output array + var output = []; + + // If glob pattern is array so we use each pattern in a recursive way, otherwise we use glob + if (_.isArray(globPatterns)) { + globPatterns.forEach(function (globPattern) { + output = _.union(output, getGlobbedPaths(globPattern, excludes)); + }); + } else if (_.isString(globPatterns)) { + if (urlRegex.test(globPatterns)) { + output.push(globPatterns); + } else { + var files = glob.sync(globPatterns); + if (excludes) { + files = files.map(function (file) { + if (_.isArray(excludes)) { + for (var i in excludes) { + file = file.replace(excludes[i], ''); } - output = _.union(output, files); - } + } else { + file = file.replace(excludes, ''); + } + return file; + }); + } + output = _.union(output, files); } + } - return output; + return output; }; /** * Validate NODE_ENV existance */ -var validateEnvironmentVariable = function() { - var environmentFiles = glob.sync('./config/env/' + process.env.NODE_ENV + '.js'); - console.log(); - if (!environmentFiles.length) { - if (process.env.NODE_ENV) { - console.error(chalk.red('+ Error: No configuration file found for "' + process.env.NODE_ENV + '" environment using development instead')); - } else { - console.error(chalk.red('+ Error: NODE_ENV is not defined! Using default development environment')); - } - process.env.NODE_ENV = 'development'; +var validateEnvironmentVariable = function () { + var environmentFiles = glob.sync('./config/env/' + process.env.NODE_ENV + '.js'); + console.log(); + if (!environmentFiles.length) { + if (process.env.NODE_ENV) { + console.error(chalk.red('+ Error: No configuration file found for "' + process.env.NODE_ENV + '" environment using development instead')); + } else { + console.error(chalk.red('+ Error: NODE_ENV is not defined! Using default development environment')); } - // Reset console color - console.log(chalk.white('')); + process.env.NODE_ENV = 'development'; + } + // Reset console color + console.log(chalk.white('')); }; /** * Validate Secure=true parameter can actually be turned on * because it requires certs and key files to be available */ -var validateSecureMode = function(config) { +var validateSecureMode = function (config) { - if (config.secure !== true) - return true; + if (config.secure !== true) { + return true; + } - var privateKey = fs.existsSync('./config/sslcerts/key.pem'); - var certificate = fs.existsSync('./config/sslcerts/cert.pem'); + var privateKey = fs.existsSync('./config/sslcerts/key.pem'); + var certificate = fs.existsSync('./config/sslcerts/cert.pem'); - if (!privateKey || !certificate) { - console.log(chalk.red('+ Error: Certificate file or key file is missing, falling back to non-SSL mode')); - console.log(chalk.red(' To create them, simply run the following from your shell: sh ./scripts/generate-ssl-certs.sh')); - console.log(); - config.secure = false; - } + if (!privateKey || !certificate) { + console.log(chalk.red('+ Error: Certificate file or key file is missing, falling back to non-SSL mode')); + console.log(chalk.red(' To create them, simply run the following from your shell: sh ./scripts/generate-ssl-certs.sh')); + console.log(); + config.secure = false; + } }; /** * Initialize global configuration files */ -var initGlobalConfigFolders = function(config, assets) { - // Appending files - config.folders = { - server: {}, - client: {} - }; - - // Setting globbed client paths - config.folders.client = getGlobbedPaths(path.join(process.cwd(), 'modules/*/client/'), process.cwd().replace(new RegExp(/\\/g),'/')); +var initGlobalConfigFolders = function (config, assets) { + // Appending files + config.folders = { + server: {}, + client: {} + }; + + // Setting globbed client paths + config.folders.client = getGlobbedPaths(path.join(process.cwd(), 'modules/*/client/'), process.cwd().replace(new RegExp(/\\/g), '/')); }; /** * Initialize global configuration files */ -var initGlobalConfigFiles = function(config, assets) { - // Appending files - config.files = { - server: {}, - client: {} - }; +var initGlobalConfigFiles = function (config, assets) { + // Appending files + config.files = { + server: {}, + client: {} + }; - // Setting Globbed model files - config.files.server.models = getGlobbedPaths(assets.server.models); + // Setting Globbed model files + config.files.server.models = getGlobbedPaths(assets.server.models); - // Setting Globbed route files - config.files.server.routes = getGlobbedPaths(assets.server.routes); + // Setting Globbed route files + config.files.server.routes = getGlobbedPaths(assets.server.routes); - // Setting Globbed config files - config.files.server.configs = getGlobbedPaths(assets.server.config); + // Setting Globbed config files + config.files.server.configs = getGlobbedPaths(assets.server.config); - // Setting Globbed socket files - config.files.server.sockets = getGlobbedPaths(assets.server.sockets); + // Setting Globbed socket files + config.files.server.sockets = getGlobbedPaths(assets.server.sockets); - // Setting Globbed policies files - config.files.server.policies = getGlobbedPaths(assets.server.policies); + // Setting Globbed policies files + config.files.server.policies = getGlobbedPaths(assets.server.policies); - // Setting Globbed js files - config.files.client.js = getGlobbedPaths(assets.client.lib.js, 'public/').concat(getGlobbedPaths(assets.client.js, ['client/', 'public/'])); + // Setting Globbed js files + config.files.client.js = getGlobbedPaths(assets.client.lib.js, 'public/').concat(getGlobbedPaths(assets.client.js, ['client/', 'public/'])); - // Setting Globbed css files - config.files.client.css = getGlobbedPaths(assets.client.lib.css, 'public/').concat(getGlobbedPaths(assets.client.css, ['client/', 'public/'])); + // Setting Globbed css files + config.files.client.css = getGlobbedPaths(assets.client.lib.css, 'public/').concat(getGlobbedPaths(assets.client.css, ['client/', 'public/'])); - // Setting Globbed test files - config.files.client.tests = getGlobbedPaths(assets.client.tests); + // Setting Globbed test files + config.files.client.tests = getGlobbedPaths(assets.client.tests); }; /** * Initialize global configuration */ -var initGlobalConfig = function() { - // Validate NDOE_ENV existance - validateEnvironmentVariable(); +var initGlobalConfig = function () { + // Validate NDOE_ENV existance + validateEnvironmentVariable(); - // Get the default assets - var defaultAssets = require(path.join(process.cwd(), 'config/assets/default')); + // Get the default assets + var defaultAssets = require(path.join(process.cwd(), 'config/assets/default')); - // Get the current assets - var environmentAssets = require(path.join(process.cwd(), 'config/assets/', process.env.NODE_ENV)) || {}; + // Get the current assets + var environmentAssets = require(path.join(process.cwd(), 'config/assets/', process.env.NODE_ENV)) || {}; - // Merge assets - var assets = _.merge(defaultAssets, environmentAssets); + // Merge assets + var assets = _.merge(defaultAssets, environmentAssets); - // Get the default config - var defaultConfig = require(path.join(process.cwd(), 'config/env/default')); + // Get the default config + var defaultConfig = require(path.join(process.cwd(), 'config/env/default')); - // Get the current config - var environmentConfig = require(path.join(process.cwd(), 'config/env/', process.env.NODE_ENV)) || {}; + // Get the current config + var environmentConfig = require(path.join(process.cwd(), 'config/env/', process.env.NODE_ENV)) || {}; - // Merge config files - var envConf = _.merge(defaultConfig, environmentConfig); + // Merge config files + var envConf = _.merge(defaultConfig, environmentConfig); - var config = _.merge(envConf, (fs.existsSync(path.join(process.cwd(), 'config/env/local.js')) && require(path.join(process.cwd(), 'config/env/local.js'))) || {}); + var config = _.merge(envConf, (fs.existsSync(path.join(process.cwd(), 'config/env/local.js')) && require(path.join(process.cwd(), 'config/env/local.js'))) || {}); - // Initialize global globbed files - initGlobalConfigFiles(config, assets); + // Initialize global globbed files + initGlobalConfigFiles(config, assets); - // Initialize global globbed folders - initGlobalConfigFolders(config, assets); + // Initialize global globbed folders + initGlobalConfigFolders(config, assets); - // Validate Secure SSL mode can be used - validateSecureMode(config); + // Validate Secure SSL mode can be used + validateSecureMode(config); - // Expose configuration utilities - config.utils = { - getGlobbedPaths: getGlobbedPaths - }; + // Expose configuration utilities + config.utils = { + getGlobbedPaths: getGlobbedPaths + }; - return config; + return config; }; /** diff --git a/config/env/default.js b/config/env/default.js index 5034bc6263..bc3e6e6010 100644 --- a/config/env/default.js +++ b/config/env/default.js @@ -1,16 +1,16 @@ 'use strict'; module.exports = { - app: { - title: 'MEAN.JS', - description: 'Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js', - keywords: 'mongodb, express, angularjs, node.js, mongoose, passport', - googleAnalyticsTrackingID: process.env.GOOGLE_ANALYTICS_TRACKING_ID || 'GOOGLE_ANALYTICS_TRACKING_ID' - }, - port: process.env.PORT || 3000, - templateEngine: 'swig', - sessionSecret: 'MEAN', - sessionCollection: 'sessions', - logo: 'modules/core/img/brand/logo.png', - favicon: 'modules/core/img/brand/favicon.ico' + app: { + title: 'MEAN.JS', + description: 'Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js', + keywords: 'mongodb, express, angularjs, node.js, mongoose, passport', + googleAnalyticsTrackingID: process.env.GOOGLE_ANALYTICS_TRACKING_ID || 'GOOGLE_ANALYTICS_TRACKING_ID' + }, + port: process.env.PORT || 3000, + templateEngine: 'swig', + sessionSecret: 'MEAN', + sessionCollection: 'sessions', + logo: 'modules/core/img/brand/logo.png', + favicon: 'modules/core/img/brand/favicon.ico' }; diff --git a/config/env/development.js b/config/env/development.js index 99df90cd65..1f31ec53f6 100644 --- a/config/env/development.js +++ b/config/env/development.js @@ -3,67 +3,67 @@ var defaultEnvConfig = require('./default'); module.exports = { - db: { - uri: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://' + (process.env.DB_1_PORT_27017_TCP_ADDR || 'localhost') + '/mean-dev', - options: { - user: '', - pass: '' - }, - // Enable mongoose debug mode - debug: process.env.MONGODB_DEBUG || false - }, - log: { - // Can specify one of 'combined', 'common', 'dev', 'short', 'tiny' - format: 'dev', - // Stream defaults to process.stdout - // Uncomment to enable logging to a log on the file system - options: { - //stream: 'access.log' - } - }, - app: { - title: defaultEnvConfig.app.title + ' - Development Environment' - }, - facebook: { - clientID: process.env.FACEBOOK_ID || 'APP_ID', - clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET', - callbackURL: '/api/auth/facebook/callback' + db: { + uri: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://' + (process.env.DB_1_PORT_27017_TCP_ADDR || 'localhost') + '/mean-dev', + options: { + user: '', + pass: '' }, - twitter: { - clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY', - clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET', - callbackURL: '/api/auth/twitter/callback' - }, - google: { - clientID: process.env.GOOGLE_ID || 'APP_ID', - clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET', - callbackURL: '/api/auth/google/callback' - }, - linkedin: { - clientID: process.env.LINKEDIN_ID || 'APP_ID', - clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET', - callbackURL: '/api/auth/linkedin/callback' - }, - github: { - clientID: process.env.GITHUB_ID || 'APP_ID', - clientSecret: process.env.GITHUB_SECRET || 'APP_SECRET', - callbackURL: '/api/auth/github/callback' - }, - paypal: { - clientID: process.env.PAYPAL_ID || 'CLIENT_ID', - clientSecret: process.env.PAYPAL_SECRET || 'CLIENT_SECRET', - callbackURL: '/api/auth/paypal/callback', - sandbox: true - }, - mailer: { - from: process.env.MAILER_FROM || 'MAILER_FROM', - options: { - service: process.env.MAILER_SERVICE_PROVIDER || 'MAILER_SERVICE_PROVIDER', - auth: { - user: process.env.MAILER_EMAIL_ID || 'MAILER_EMAIL_ID', - pass: process.env.MAILER_PASSWORD || 'MAILER_PASSWORD' - } - } - }, - livereload: true + // Enable mongoose debug mode + debug: process.env.MONGODB_DEBUG || false + }, + log: { + // Can specify one of 'combined', 'common', 'dev', 'short', 'tiny' + format: 'dev', + // Stream defaults to process.stdout + // Uncomment to enable logging to a log on the file system + options: { + //stream: 'access.log' + } + }, + app: { + title: defaultEnvConfig.app.title + ' - Development Environment' + }, + facebook: { + clientID: process.env.FACEBOOK_ID || 'APP_ID', + clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET', + callbackURL: '/api/auth/facebook/callback' + }, + twitter: { + clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY', + clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET', + callbackURL: '/api/auth/twitter/callback' + }, + google: { + clientID: process.env.GOOGLE_ID || 'APP_ID', + clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET', + callbackURL: '/api/auth/google/callback' + }, + linkedin: { + clientID: process.env.LINKEDIN_ID || 'APP_ID', + clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET', + callbackURL: '/api/auth/linkedin/callback' + }, + github: { + clientID: process.env.GITHUB_ID || 'APP_ID', + clientSecret: process.env.GITHUB_SECRET || 'APP_SECRET', + callbackURL: '/api/auth/github/callback' + }, + paypal: { + clientID: process.env.PAYPAL_ID || 'CLIENT_ID', + clientSecret: process.env.PAYPAL_SECRET || 'CLIENT_SECRET', + callbackURL: '/api/auth/paypal/callback', + sandbox: true + }, + mailer: { + from: process.env.MAILER_FROM || 'MAILER_FROM', + options: { + service: process.env.MAILER_SERVICE_PROVIDER || 'MAILER_SERVICE_PROVIDER', + auth: { + user: process.env.MAILER_EMAIL_ID || 'MAILER_EMAIL_ID', + pass: process.env.MAILER_PASSWORD || 'MAILER_PASSWORD' + } + } + }, + livereload: true }; diff --git a/config/env/local.example.js b/config/env/local.example.js index 824a29930f..8fd65b2f6f 100644 --- a/config/env/local.example.js +++ b/config/env/local.example.js @@ -7,17 +7,17 @@ /* For example: module.exports = { - db: { - uri: 'mongodb://localhost/local-dev', - options: { - user: '', - pass: '' - } - }, - facebook: { - clientID: process.env.FACEBOOK_ID || 'APP_ID', - clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET', - callbackURL: '/auth/facebook/callback' - } + db: { + uri: 'mongodb://localhost/local-dev', + options: { + user: '', + pass: '' + } + }, + facebook: { + clientID: process.env.FACEBOOK_ID || 'APP_ID', + clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET', + callbackURL: '/auth/facebook/callback' + } }; -*/ \ No newline at end of file +*/ diff --git a/config/env/production.js b/config/env/production.js index 8e5832c75d..3bf482cc85 100644 --- a/config/env/production.js +++ b/config/env/production.js @@ -1,65 +1,65 @@ 'use strict'; module.exports = { - secure: true, - port: process.env.PORT || 8443, - db: { - uri: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://' + (process.env.DB_1_PORT_27017_TCP_ADDR || 'localhost') + '/mean', - options: { - user: '', - pass: '' - }, - // Enable mongoose debug mode - debug: process.env.MONGODB_DEBUG || false - }, - log: { - // Can specify one of 'combined', 'common', 'dev', 'short', 'tiny' - format: 'combined', - // Stream defaults to process.stdout - // Uncomment to enable logging to a log on the file system - options: { - stream: 'access.log' - } - }, - facebook: { - clientID: process.env.FACEBOOK_ID || 'APP_ID', - clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET', - callbackURL: '/api/auth/facebook/callback' - }, - twitter: { - clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY', - clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET', - callbackURL: '/api/auth/twitter/callback' - }, - google: { - clientID: process.env.GOOGLE_ID || 'APP_ID', - clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET', - callbackURL: '/api/auth/google/callback' - }, - linkedin: { - clientID: process.env.LINKEDIN_ID || 'APP_ID', - clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET', - callbackURL: '/api/auth/linkedin/callback' - }, - github: { - clientID: process.env.GITHUB_ID || 'APP_ID', - clientSecret: process.env.GITHUB_SECRET || 'APP_SECRET', - callbackURL: '/api/auth/github/callback' - }, - paypal: { - clientID: process.env.PAYPAL_ID || 'CLIENT_ID', - clientSecret: process.env.PAYPAL_SECRET || 'CLIENT_SECRET', - callbackURL: '/api/auth/paypal/callback', - sandbox: false - }, - mailer: { - from: process.env.MAILER_FROM || 'MAILER_FROM', - options: { - service: process.env.MAILER_SERVICE_PROVIDER || 'MAILER_SERVICE_PROVIDER', - auth: { - user: process.env.MAILER_EMAIL_ID || 'MAILER_EMAIL_ID', - pass: process.env.MAILER_PASSWORD || 'MAILER_PASSWORD' - } - } - } + secure: true, + port: process.env.PORT || 8443, + db: { + uri: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://' + (process.env.DB_1_PORT_27017_TCP_ADDR || 'localhost') + '/mean', + options: { + user: '', + pass: '' + }, + // Enable mongoose debug mode + debug: process.env.MONGODB_DEBUG || false + }, + log: { + // Can specify one of 'combined', 'common', 'dev', 'short', 'tiny' + format: 'combined', + // Stream defaults to process.stdout + // Uncomment to enable logging to a log on the file system + options: { + stream: 'access.log' + } + }, + facebook: { + clientID: process.env.FACEBOOK_ID || 'APP_ID', + clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET', + callbackURL: '/api/auth/facebook/callback' + }, + twitter: { + clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY', + clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET', + callbackURL: '/api/auth/twitter/callback' + }, + google: { + clientID: process.env.GOOGLE_ID || 'APP_ID', + clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET', + callbackURL: '/api/auth/google/callback' + }, + linkedin: { + clientID: process.env.LINKEDIN_ID || 'APP_ID', + clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET', + callbackURL: '/api/auth/linkedin/callback' + }, + github: { + clientID: process.env.GITHUB_ID || 'APP_ID', + clientSecret: process.env.GITHUB_SECRET || 'APP_SECRET', + callbackURL: '/api/auth/github/callback' + }, + paypal: { + clientID: process.env.PAYPAL_ID || 'CLIENT_ID', + clientSecret: process.env.PAYPAL_SECRET || 'CLIENT_SECRET', + callbackURL: '/api/auth/paypal/callback', + sandbox: false + }, + mailer: { + from: process.env.MAILER_FROM || 'MAILER_FROM', + options: { + service: process.env.MAILER_SERVICE_PROVIDER || 'MAILER_SERVICE_PROVIDER', + auth: { + user: process.env.MAILER_EMAIL_ID || 'MAILER_EMAIL_ID', + pass: process.env.MAILER_PASSWORD || 'MAILER_PASSWORD' + } + } + } }; diff --git a/config/env/test.js b/config/env/test.js index 08fb6a8485..cbd9821795 100644 --- a/config/env/test.js +++ b/config/env/test.js @@ -3,58 +3,58 @@ var defaultEnvConfig = require('./default'); module.exports = { - db: { - uri: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://' + (process.env.DB_1_PORT_27017_TCP_ADDR || 'localhost') + '/mean-test', - options: { - user: '', - pass: '' - }, - // Enable mongoose debug mode - debug: process.env.MONGODB_DEBUG || false - }, - port: process.env.PORT || 3001, - app: { - title: defaultEnvConfig.app.title + ' - Test Environment' - }, - facebook: { - clientID: process.env.FACEBOOK_ID || 'APP_ID', - clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET', - callbackURL: '/api/auth/facebook/callback' - }, - twitter: { - clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY', - clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET', - callbackURL: '/api/auth/twitter/callback' - }, - google: { - clientID: process.env.GOOGLE_ID || 'APP_ID', - clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET', - callbackURL: '/api/auth/google/callback' - }, - linkedin: { - clientID: process.env.LINKEDIN_ID || 'APP_ID', - clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET', - callbackURL: '/api/auth/linkedin/callback' - }, - github: { - clientID: process.env.GITHUB_ID || 'APP_ID', - clientSecret: process.env.GITHUB_SECRET || 'APP_SECRET', - callbackURL: '/api/auth/github/callback' - }, - paypal: { - clientID: process.env.PAYPAL_ID || 'CLIENT_ID', - clientSecret: process.env.PAYPAL_SECRET || 'CLIENT_SECRET', - callbackURL: '/api/auth/paypal/callback', - sandbox: true - }, - mailer: { - from: process.env.MAILER_FROM || 'MAILER_FROM', - options: { - service: process.env.MAILER_SERVICE_PROVIDER || 'MAILER_SERVICE_PROVIDER', - auth: { - user: process.env.MAILER_EMAIL_ID || 'MAILER_EMAIL_ID', - pass: process.env.MAILER_PASSWORD || 'MAILER_PASSWORD' - } - } - } + db: { + uri: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://' + (process.env.DB_1_PORT_27017_TCP_ADDR || 'localhost') + '/mean-test', + options: { + user: '', + pass: '' + }, + // Enable mongoose debug mode + debug: process.env.MONGODB_DEBUG || false + }, + port: process.env.PORT || 3001, + app: { + title: defaultEnvConfig.app.title + ' - Test Environment' + }, + facebook: { + clientID: process.env.FACEBOOK_ID || 'APP_ID', + clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET', + callbackURL: '/api/auth/facebook/callback' + }, + twitter: { + clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY', + clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET', + callbackURL: '/api/auth/twitter/callback' + }, + google: { + clientID: process.env.GOOGLE_ID || 'APP_ID', + clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET', + callbackURL: '/api/auth/google/callback' + }, + linkedin: { + clientID: process.env.LINKEDIN_ID || 'APP_ID', + clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET', + callbackURL: '/api/auth/linkedin/callback' + }, + github: { + clientID: process.env.GITHUB_ID || 'APP_ID', + clientSecret: process.env.GITHUB_SECRET || 'APP_SECRET', + callbackURL: '/api/auth/github/callback' + }, + paypal: { + clientID: process.env.PAYPAL_ID || 'CLIENT_ID', + clientSecret: process.env.PAYPAL_SECRET || 'CLIENT_SECRET', + callbackURL: '/api/auth/paypal/callback', + sandbox: true + }, + mailer: { + from: process.env.MAILER_FROM || 'MAILER_FROM', + options: { + service: process.env.MAILER_SERVICE_PROVIDER || 'MAILER_SERVICE_PROVIDER', + auth: { + user: process.env.MAILER_EMAIL_ID || 'MAILER_EMAIL_ID', + pass: process.env.MAILER_PASSWORD || 'MAILER_PASSWORD' + } + } + } }; diff --git a/config/lib/express.js b/config/lib/express.js index 0b006dd871..70b4e3e644 100644 --- a/config/lib/express.js +++ b/config/lib/express.js @@ -4,244 +4,246 @@ * Module dependencies. */ var config = require('../config'), - express = require('express'), - morgan = require('morgan'), - bodyParser = require('body-parser'), - session = require('express-session'), - MongoStore = require('connect-mongo')(session), - multer = require('multer'), - favicon = require('serve-favicon'), - compress = require('compression'), - methodOverride = require('method-override'), - cookieParser = require('cookie-parser'), - helmet = require('helmet'), - flash = require('connect-flash'), - consolidate = require('consolidate'), - path = require('path'); + express = require('express'), + morgan = require('morgan'), + bodyParser = require('body-parser'), + session = require('express-session'), + MongoStore = require('connect-mongo')(session), + multer = require('multer'), + favicon = require('serve-favicon'), + compress = require('compression'), + methodOverride = require('method-override'), + cookieParser = require('cookie-parser'), + helmet = require('helmet'), + flash = require('connect-flash'), + consolidate = require('consolidate'), + path = require('path'); /** * Initialize local variables */ module.exports.initLocalVariables = function (app) { - // Setting application local variables - app.locals.title = config.app.title; - app.locals.description = config.app.description; - app.locals.secure = config.secure; - app.locals.keywords = config.app.keywords; - app.locals.googleAnalyticsTrackingID = config.app.googleAnalyticsTrackingID; - app.locals.facebookAppId = config.facebook.clientID; - app.locals.jsFiles = config.files.client.js; - app.locals.cssFiles = config.files.client.css; - app.locals.livereload = config.livereload; - app.locals.logo = config.logo; - app.locals.favicon = config.favicon; - - // Passing the request url to environment locals - app.use(function (req, res, next) { - res.locals.host = req.protocol + '://' + req.hostname; - res.locals.url = req.protocol + '://' + req.headers.host + req.originalUrl; - next(); - }); + // Setting application local variables + app.locals.title = config.app.title; + app.locals.description = config.app.description; + app.locals.secure = config.secure; + app.locals.keywords = config.app.keywords; + app.locals.googleAnalyticsTrackingID = config.app.googleAnalyticsTrackingID; + app.locals.facebookAppId = config.facebook.clientID; + app.locals.jsFiles = config.files.client.js; + app.locals.cssFiles = config.files.client.css; + app.locals.livereload = config.livereload; + app.locals.logo = config.logo; + app.locals.favicon = config.favicon; + + // Passing the request url to environment locals + app.use(function (req, res, next) { + res.locals.host = req.protocol + '://' + req.hostname; + res.locals.url = req.protocol + '://' + req.headers.host + req.originalUrl; + next(); + }); }; /** * Initialize application middleware */ module.exports.initMiddleware = function (app) { - // Showing stack errors - app.set('showStackError', true); - - // Enable jsonp - app.enable('jsonp callback'); - - // Should be placed before express.static - app.use(compress({ - filter: function (req, res) { - return (/json|text|javascript|css|font|svg/).test(res.getHeader('Content-Type')); - }, - level: 9 - })); - - // Initialize favicon middleware - app.use(favicon('./modules/core/client/img/brand/favicon.ico')); - - // Environment dependent middleware - if (process.env.NODE_ENV === 'development') { - // Enable logger (morgan) - app.use(morgan('dev')); - - // Disable views cache - app.set('view cache', false); - } else if (process.env.NODE_ENV === 'production') { - app.locals.cache = 'memory'; - } - - // Request body parsing middleware should be above methodOverride - app.use(bodyParser.urlencoded({ - extended: true - })); - app.use(bodyParser.json()); - app.use(methodOverride()); - - // Add the cookie parser and flash middleware - app.use(cookieParser()); - app.use(flash()); - - // Add multipart handling middleware - app.use(multer({ - dest: './uploads/', - inMemory: true - })); + // Showing stack errors + app.set('showStackError', true); + + // Enable jsonp + app.enable('jsonp callback'); + + // Should be placed before express.static + app.use(compress({ + filter: function (req, res) { + return (/json|text|javascript|css|font|svg/).test(res.getHeader('Content-Type')); + }, + level: 9 + })); + + // Initialize favicon middleware + app.use(favicon('./modules/core/client/img/brand/favicon.ico')); + + // Environment dependent middleware + if (process.env.NODE_ENV === 'development') { + // Enable logger (morgan) + app.use(morgan('dev')); + + // Disable views cache + app.set('view cache', false); + } else if (process.env.NODE_ENV === 'production') { + app.locals.cache = 'memory'; + } + + // Request body parsing middleware should be above methodOverride + app.use(bodyParser.urlencoded({ + extended: true + })); + app.use(bodyParser.json()); + app.use(methodOverride()); + + // Add the cookie parser and flash middleware + app.use(cookieParser()); + app.use(flash()); + + // Add multipart handling middleware + app.use(multer({ + dest: './uploads/', + inMemory: true + })); }; /** * Configure view engine */ module.exports.initViewEngine = function (app) { - // Set swig as the template engine - app.engine('server.view.html', consolidate[config.templateEngine]); + // Set swig as the template engine + app.engine('server.view.html', consolidate[config.templateEngine]); - // Set views path and view engine - app.set('view engine', 'server.view.html'); - app.set('views', './'); + // Set views path and view engine + app.set('view engine', 'server.view.html'); + app.set('views', './'); }; /** * Configure Express session */ module.exports.initSession = function (app, db) { - // Express MongoDB session storage - app.use(session({ - saveUninitialized: true, - resave: true, - secret: config.sessionSecret, - store: new MongoStore({ - mongooseConnection: db.connection, - collection: config.sessionCollection - }) - })); + // Express MongoDB session storage + app.use(session({ + saveUninitialized: true, + resave: true, + secret: config.sessionSecret, + store: new MongoStore({ + mongooseConnection: db.connection, + collection: config.sessionCollection + }) + })); }; /** * Invoke modules server configuration */ module.exports.initModulesConfiguration = function (app, db) { - config.files.server.configs.forEach(function (configPath) { - require(path.resolve(configPath))(app, db); - }); + config.files.server.configs.forEach(function (configPath) { + require(path.resolve(configPath))(app, db); + }); }; /** * Configure Helmet headers configuration */ module.exports.initHelmetHeaders = function (app) { - // Use helmet to secure Express headers - app.use(helmet.xframe()); - app.use(helmet.xssFilter()); - app.use(helmet.nosniff()); - app.use(helmet.ienoopen()); - app.disable('x-powered-by'); + // Use helmet to secure Express headers + app.use(helmet.xframe()); + app.use(helmet.xssFilter()); + app.use(helmet.nosniff()); + app.use(helmet.ienoopen()); + app.disable('x-powered-by'); }; /** * Configure the modules static routes */ module.exports.initModulesClientRoutes = function (app) { - // Setting the app router and static folder - app.use('/', express.static(path.resolve('./public'))); + // Setting the app router and static folder + app.use('/', express.static(path.resolve('./public'))); - // Globbing static routing - config.folders.client.forEach(function (staticPath) { - app.use(staticPath.replace('/client', ''), express.static(path.resolve('./' + staticPath))); - }); + // Globbing static routing + config.folders.client.forEach(function (staticPath) { + app.use(staticPath.replace('/client', ''), express.static(path.resolve('./' + staticPath))); + }); }; /** * Configure the modules ACL policies */ module.exports.initModulesServerPolicies = function (app) { - // Globbing policy files - config.files.server.policies.forEach(function (policyPath) { - require(path.resolve(policyPath)).invokeRolesPolicies(); - }); + // Globbing policy files + config.files.server.policies.forEach(function (policyPath) { + require(path.resolve(policyPath)).invokeRolesPolicies(); + }); }; /** * Configure the modules server routes */ module.exports.initModulesServerRoutes = function (app) { - // Globbing routing files - config.files.server.routes.forEach(function (routePath) { - require(path.resolve(routePath))(app); - }); + // Globbing routing files + config.files.server.routes.forEach(function (routePath) { + require(path.resolve(routePath))(app); + }); }; /** * Configure error handling */ module.exports.initErrorRoutes = function (app) { - app.use(function (err, req, res, next) { - // If the error object doesn't exists - if (!err) return next(); - - // Log it - console.error(err.stack); - - // Redirect to error page - res.redirect('/server-error'); - }); + app.use(function (err, req, res, next) { + // If the error object doesn't exists + if (!err) { + return next(); + } + + // Log it + console.error(err.stack); + + // Redirect to error page + res.redirect('/server-error'); + }); }; /** * Configure Socket.io */ module.exports.configureSocketIO = function (app, db) { - // Load the Socket.io configuration - var server = require('./socket.io')(app, db); + // Load the Socket.io configuration + var server = require('./socket.io')(app, db); - // Return server object - return server; + // Return server object + return server; }; /** * Initialize the Express application */ module.exports.init = function (db) { - // Initialize express app - var app = express(); + // Initialize express app + var app = express(); - // Initialize local variables - this.initLocalVariables(app); + // Initialize local variables + this.initLocalVariables(app); - // Initialize Express middleware - this.initMiddleware(app); + // Initialize Express middleware + this.initMiddleware(app); - // Initialize Express view engine - this.initViewEngine(app); + // Initialize Express view engine + this.initViewEngine(app); - // Initialize Express session - this.initSession(app, db); + // Initialize Express session + this.initSession(app, db); - // Initialize Modules configuration - this.initModulesConfiguration(app); + // Initialize Modules configuration + this.initModulesConfiguration(app); - // Initialize Helmet security headers - this.initHelmetHeaders(app); + // Initialize Helmet security headers + this.initHelmetHeaders(app); - // Initialize modules static client routes - this.initModulesClientRoutes(app); + // Initialize modules static client routes + this.initModulesClientRoutes(app); - // Initialize modules server authorization policies - this.initModulesServerPolicies(app); + // Initialize modules server authorization policies + this.initModulesServerPolicies(app); - // Initialize modules server routes - this.initModulesServerRoutes(app); + // Initialize modules server routes + this.initModulesServerRoutes(app); - // Initialize error routes - this.initErrorRoutes(app); + // Initialize error routes + this.initErrorRoutes(app); - // Configure Socket.io - app = this.configureSocketIO(app, db); + // Configure Socket.io + app = this.configureSocketIO(app, db); - return app; + return app; }; diff --git a/config/lib/mongoose.js b/config/lib/mongoose.js index b6597919a5..9f48135366 100644 --- a/config/lib/mongoose.js +++ b/config/lib/mongoose.js @@ -4,41 +4,41 @@ * Module dependencies. */ var config = require('../config'), - chalk = require('chalk'), - path = require('path'), - mongoose = require('mongoose'); + chalk = require('chalk'), + path = require('path'), + mongoose = require('mongoose'); // Load the mongoose models -module.exports.loadModels = function() { - // Globbing model files - config.files.server.models.forEach(function(modelPath) { - require(path.resolve(modelPath)); - }); +module.exports.loadModels = function () { + // Globbing model files + config.files.server.models.forEach(function (modelPath) { + require(path.resolve(modelPath)); + }); }; // Initialize Mongoose -module.exports.connect = function(cb) { - var _this = this; +module.exports.connect = function (cb) { + var _this = this; - var db = mongoose.connect(config.db.uri, config.db.options, function (err) { - // Log Error - if (err) { - console.error(chalk.red('Could not connect to MongoDB!')); - console.log(err); - } else { + var db = mongoose.connect(config.db.uri, config.db.options, function (err) { + // Log Error + if (err) { + console.error(chalk.red('Could not connect to MongoDB!')); + console.log(err); + } else { - // Enabling mongoose debug mode if required - mongoose.set('debug', config.db.debug); + // Enabling mongoose debug mode if required + mongoose.set('debug', config.db.debug); - // Call callback FN - if (cb) cb(db); - } - }); + // Call callback FN + if (cb) cb(db); + } + }); }; -module.exports.disconnect = function(cb) { - mongoose.disconnect(function(err) { - console.info(chalk.yellow('Disconnected from MongoDB.')); - cb(err); +module.exports.disconnect = function (cb) { + mongoose.disconnect(function (err) { + console.info(chalk.yellow('Disconnected from MongoDB.')); + cb(err); }); }; diff --git a/config/lib/socket.io.js b/config/lib/socket.io.js index 18adffd0d0..e3e7659b6e 100644 --- a/config/lib/socket.io.js +++ b/config/lib/socket.io.js @@ -2,18 +2,18 @@ // Load the module dependencies var config = require('../config'), - path = require('path'), - fs = require('fs'), - http = require('http'), - https = require('https'), - cookieParser = require('cookie-parser'), - passport = require('passport'), - socketio = require('socket.io'), - session = require('express-session'), - MongoStore = require('connect-mongo')(session); + path = require('path'), + fs = require('fs'), + http = require('http'), + https = require('https'), + cookieParser = require('cookie-parser'), + passport = require('passport'), + socketio = require('socket.io'), + session = require('express-session'), + MongoStore = require('connect-mongo')(session); // Define the Socket.io configuration method -module.exports = function(app, db) { +module.exports = function (app, db) { var server; if (config.secure === true) { // Load SSL key and certificate @@ -35,25 +35,25 @@ module.exports = function(app, db) { // Create a MongoDB storage object var mongoStore = new MongoStore({ - mongooseConnection: db.connection, - collection: config.sessionCollection + mongooseConnection: db.connection, + collection: config.sessionCollection }); // Intercept Socket.io's handshake request - io.use(function(socket, next) { + io.use(function (socket, next) { // Use the 'cookie-parser' module to parse the request cookies - cookieParser(config.sessionSecret)(socket.request, {}, function(err) { + cookieParser(config.sessionSecret)(socket.request, {}, function (err) { // Get the session id from the request cookies var sessionId = socket.request.signedCookies['connect.sid']; // Use the mongoStorage instance to get the Express session information - mongoStore.get(sessionId, function(err, session) { + mongoStore.get(sessionId, function (err, session) { // Set the Socket.io session information socket.request.session = session; // Use Passport to populate the user details - passport.initialize()(socket.request, {}, function() { - passport.session()(socket.request, {}, function() { + passport.initialize()(socket.request, {}, function () { + passport.session()(socket.request, {}, function () { if (socket.request.user) { next(null, true); } else { @@ -66,8 +66,8 @@ module.exports = function(app, db) { }); // Add an event listener to the 'connection' event - io.on('connection', function(socket) { - config.files.server.sockets.forEach(function(socketConfiguration) { + io.on('connection', function (socket) { + config.files.server.sockets.forEach(function (socketConfiguration) { require(path.resolve(socketConfiguration))(io, socket); }); }); diff --git a/gruntfile.js b/gruntfile.js index b602aceb30..39dfceee6e 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -4,266 +4,263 @@ * Module dependencies. */ var _ = require('lodash'), - defaultAssets = require('./config/assets/default'), - testAssets = require('./config/assets/test'), - fs = require('fs'), - path = require('path'); + defaultAssets = require('./config/assets/default'), + testAssets = require('./config/assets/test'), + fs = require('fs'), + path = require('path'); module.exports = function (grunt) { - // Project Configuration - grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), - env: { - test: { - NODE_ENV: 'test' - }, - dev: { - NODE_ENV: 'development' - }, - prod: { - NODE_ENV: 'production' - } - }, - watch: { - serverViews: { - files: defaultAssets.server.views, - options: { - livereload: true - } - }, - serverJS: { - files: _.union(defaultAssets.server.gruntConfig, defaultAssets.server.allJS), - tasks: ['jshint'], - options: { - livereload: true - } - }, - clientViews: { - files: defaultAssets.client.views, - options: { - livereload: true - } - }, - clientJS: { - files: defaultAssets.client.js, - tasks: ['jshint'], - options: { - livereload: true - } - }, - clientCSS: { - files: defaultAssets.client.css, - tasks: ['csslint'], - options: { - livereload: true - } - }, - clientSCSS: { - files: defaultAssets.client.sass, - tasks: ['sass', 'csslint'], - options: { - livereload: true - } - }, - clientLESS: { - files: defaultAssets.client.less, - tasks: ['less', 'csslint'], - options: { - livereload: true - } - } - }, - nodemon: { - dev: { - script: 'server.js', - options: { - nodeArgs: ['--debug'], - ext: 'js,html', - watch: _.union(defaultAssets.server.gruntConfig, defaultAssets.server.views, defaultAssets.server.allJS, defaultAssets.server.config) - } - } - }, - concurrent: { - default: ['nodemon', 'watch'], - debug: ['nodemon', 'watch', 'node-inspector'], - options: { - logConcurrentOutput: true - } - }, - jshint: { - all: { - src: _.union(defaultAssets.server.gruntConfig, defaultAssets.server.allJS, defaultAssets.client.js, testAssets.tests.server, testAssets.tests.client, testAssets.tests.e2e), - options: { - jshintrc: true, - node: true, - mocha: true, - jasmine: true - } - } - }, - csslint: { - options: { - csslintrc: '.csslintrc' - }, - all: { - src: defaultAssets.client.css - } - }, - ngAnnotate: { - production: { - files: { - 'public/dist/application.js': defaultAssets.client.js - } - } - }, - uglify: { - production: { - options: { - mangle: false - }, - files: { - 'public/dist/application.min.js': 'public/dist/application.js' - } - } - }, - cssmin: { - combine: { - files: { - 'public/dist/application.min.css': defaultAssets.client.css - } - } - }, - sass: { - dist: { - files: [{ - expand: true, - src: defaultAssets.client.sass, - ext: '.css', - rename: function(base, src) { - return src.replace('/scss/', '/css/'); - } + // Project Configuration + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + env: { + test: { + NODE_ENV: 'test' + }, + dev: { + NODE_ENV: 'development' + }, + prod: { + NODE_ENV: 'production' + } + }, + watch: { + serverViews: { + files: defaultAssets.server.views, + options: { + livereload: true + } + }, + serverJS: { + files: _.union(defaultAssets.server.gruntConfig, defaultAssets.server.allJS), + tasks: ['jshint'], + options: { + livereload: true + } + }, + clientViews: { + files: defaultAssets.client.views, + options: { + livereload: true + } + }, + clientJS: { + files: defaultAssets.client.js, + tasks: ['jshint'], + options: { + livereload: true + } + }, + clientCSS: { + files: defaultAssets.client.css, + tasks: ['csslint'], + options: { + livereload: true + } + }, + clientSCSS: { + files: defaultAssets.client.sass, + tasks: ['sass', 'csslint'], + options: { + livereload: true + } + }, + clientLESS: { + files: defaultAssets.client.less, + tasks: ['less', 'csslint'], + options: { + livereload: true + } + } + }, + nodemon: { + dev: { + script: 'server.js', + options: { + nodeArgs: ['--debug'], + ext: 'js,html', + watch: _.union(defaultAssets.server.gruntConfig, defaultAssets.server.views, defaultAssets.server.allJS, defaultAssets.server.config) + } + } + }, + concurrent: { + default: ['nodemon', 'watch'], + debug: ['nodemon', 'watch', 'node-inspector'], + options: { + logConcurrentOutput: true + } + }, + jshint: { + all: { + src: _.union(defaultAssets.server.gruntConfig, defaultAssets.server.allJS, defaultAssets.client.js, testAssets.tests.server, testAssets.tests.client, testAssets.tests.e2e), + options: { + jshintrc: true, + node: true, + mocha: true, + jasmine: true + } + } + }, + csslint: { + options: { + csslintrc: '.csslintrc' + }, + all: { + src: defaultAssets.client.css + } + }, + ngAnnotate: { + production: { + files: { + 'public/dist/application.js': defaultAssets.client.js + } + } + }, + uglify: { + production: { + options: { + mangle: false + }, + files: { + 'public/dist/application.min.js': 'public/dist/application.js' + } + } + }, + cssmin: { + combine: { + files: { + 'public/dist/application.min.css': defaultAssets.client.css + } + } + }, + sass: { + dist: { + files: [{ + expand: true, + src: defaultAssets.client.sass, + ext: '.css', + rename: function (base, src) { + return src.replace('/scss/', '/css/'); + } }] - } - }, - less: { - dist: { - files: [{ - expand: true, - src: defaultAssets.client.less, - ext: '.css', - rename: function(base, src) { - return src.replace('/less/', '/css/'); - } + } + }, + less: { + dist: { + files: [{ + expand: true, + src: defaultAssets.client.less, + ext: '.css', + rename: function (base, src) { + return src.replace('/less/', '/css/'); + } }] - } - }, - 'node-inspector': { - custom: { - options: { - 'web-port': 1337, - 'web-host': 'localhost', - 'debug-port': 5858, - 'save-live-edit': true, - 'no-preload': true, - 'stack-trace-limit': 50, - 'hidden': [] - } - } - }, - mochaTest: { - src: testAssets.tests.server, - options: { - reporter: 'spec' - } - }, - karma: { - unit: { - configFile: 'karma.conf.js' - } - }, - protractor: { - options: { - configFile: 'protractor.conf.js', - keepAlive: true, - noColor: false - }, - e2e: { - options: { - args: {} // Target-specific arguments - } - } - }, - copy: { - localConfig: { - src: 'config/env/local.example.js', - dest: 'config/env/local.js', - filter: function() { - return !fs.existsSync('config/env/local.js'); - } - } - } - }); + } + }, + 'node-inspector': { + custom: { + options: { + 'web-port': 1337, + 'web-host': 'localhost', + 'debug-port': 5858, + 'save-live-edit': true, + 'no-preload': true, + 'stack-trace-limit': 50, + 'hidden': [] + } + } + }, + mochaTest: { + src: testAssets.tests.server, + options: { + reporter: 'spec' + } + }, + karma: { + unit: { + configFile: 'karma.conf.js' + } + }, + protractor: { + options: { + configFile: 'protractor.conf.js', + keepAlive: true, + noColor: false + }, + e2e: { + options: { + args: {} // Target-specific arguments + } + } + }, + copy: { + localConfig: { + src: 'config/env/local.example.js', + dest: 'config/env/local.js', + filter: function () { + return !fs.existsSync('config/env/local.js'); + } + } + } + }); - // Load NPM tasks - require('load-grunt-tasks')(grunt); + // Load NPM tasks + require('load-grunt-tasks')(grunt); - // Making grunt default to force in order not to break the project. - grunt.option('force', true); + // Making grunt default to force in order not to break the project. + grunt.option('force', true); - // Make sure upload directory exists - grunt.task.registerTask('mkdir:upload', 'Task that makes sure upload directory exists.', function() { - // Get the callback - var done = this.async(); + // Make sure upload directory exists + grunt.task.registerTask('mkdir:upload', 'Task that makes sure upload directory exists.', function () { + // Get the callback + var done = this.async(); - grunt.file.mkdir(path.normalize(__dirname + '/modules/users/client/img/profile/uploads')); + grunt.file.mkdir(path.normalize(__dirname + '/modules/users/client/img/profile/uploads')); - done(); - }); + done(); + }); - // Connect to the MongoDB instance and load the models - grunt.task.registerTask('mongoose', 'Task that connects to the MongoDB instance and loads the application models.', function() { - // Get the callback - var done = this.async(); + // Connect to the MongoDB instance and load the models + grunt.task.registerTask('mongoose', 'Task that connects to the MongoDB instance and loads the application models.', function () { + // Get the callback + var done = this.async(); - // Use mongoose configuration - var mongoose = require('./config/lib/mongoose.js'); + // Use mongoose configuration + var mongoose = require('./config/lib/mongoose.js'); - // Connect to database - mongoose.connect(function(db) { - done(); - }); - }); + // Connect to database + mongoose.connect(function (db) { + done(); + }); + }); - grunt.task.registerTask('server', 'Starting the server', function() { - // Get the callback - var done = this.async(); + grunt.task.registerTask('server', 'Starting the server', function () { + // Get the callback + var done = this.async(); - var path = require('path'); - var app = require(path.resolve('./config/lib/app')); - var server = app.start(function() { - done(); - }); + var path = require('path'); + var app = require(path.resolve('./config/lib/app')); + var server = app.start(function () { + done(); + }); + }); - }); + // Lint CSS and JavaScript files. + grunt.registerTask('lint', ['sass', 'less', 'jshint', 'csslint']); + // Lint project files and minify them into two production files. + grunt.registerTask('build', ['env:dev', 'lint', 'ngAnnotate', 'uglify', 'cssmin']); + // Run the project tests + grunt.registerTask('test', ['env:test', 'lint', 'mkdir:upload', 'copy:localConfig', 'server', 'mochaTest', 'karma:unit']); + grunt.registerTask('test:server', ['env:test', 'lint', 'server', 'mochaTest']); + grunt.registerTask('test:client', ['env:test', 'lint', 'server', 'karma:unit']); + // Run the project in development mode + grunt.registerTask('default', ['env:dev', 'lint', 'mkdir:upload', 'copy:localConfig', 'concurrent:default']); - // Lint CSS and JavaScript files. - grunt.registerTask('lint', ['sass', 'less', 'jshint', 'csslint']); + // Run the project in debug mode + grunt.registerTask('debug', ['env:dev', 'lint', 'mkdir:upload', 'copy:localConfig', 'concurrent:debug']); - // Lint project files and minify them into two production files. - grunt.registerTask('build', ['env:dev', 'lint', 'ngAnnotate', 'uglify', 'cssmin']); - - // Run the project tests - grunt.registerTask('test', ['env:test', 'lint', 'mkdir:upload', 'copy:localConfig', 'server', 'mochaTest', 'karma:unit']); - grunt.registerTask('test:server', ['env:test', 'lint', 'server', 'mochaTest']); - grunt.registerTask('test:client', ['env:test', 'lint', 'server', 'karma:unit']); - // Run the project in development mode - grunt.registerTask('default', ['env:dev', 'lint', 'mkdir:upload', 'copy:localConfig', 'concurrent:default']); - - // Run the project in debug mode - grunt.registerTask('debug', ['env:dev', 'lint', 'mkdir:upload', 'copy:localConfig', 'concurrent:debug']); - - // Run the project in production mode - grunt.registerTask('prod', ['build', 'env:prod', 'mkdir:upload', 'copy:localConfig', 'concurrent:default']); + // Run the project in production mode + grunt.registerTask('prod', ['build', 'env:prod', 'mkdir:upload', 'copy:localConfig', 'concurrent:default']); }; diff --git a/gulpfile.js b/gulpfile.js index 6d39dfa13e..2c260cebcf 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -4,150 +4,150 @@ * Module dependencies. */ var _ = require('lodash'), - defaultAssets = require('./config/assets/default'), - testAssets = require('./config/assets/test'), - gulp = require('gulp'), - gulpLoadPlugins = require('gulp-load-plugins'), - runSequence = require('run-sequence'), - plugins = gulpLoadPlugins(), - path = require('path'); + defaultAssets = require('./config/assets/default'), + testAssets = require('./config/assets/test'), + gulp = require('gulp'), + gulpLoadPlugins = require('gulp-load-plugins'), + runSequence = require('run-sequence'), + plugins = gulpLoadPlugins(), + path = require('path'); // Set NODE_ENV to 'test' gulp.task('env:test', function () { - process.env.NODE_ENV = 'test'; + process.env.NODE_ENV = 'test'; }); // Set NODE_ENV to 'development' gulp.task('env:dev', function () { - process.env.NODE_ENV = 'development'; + process.env.NODE_ENV = 'development'; }); // Set NODE_ENV to 'production' gulp.task('env:prod', function () { - process.env.NODE_ENV = 'production'; + process.env.NODE_ENV = 'production'; }); // Nodemon task gulp.task('nodemon', function () { - return plugins.nodemon({ - script: 'server.js', - nodeArgs: ['--debug'], - ext: 'js,html', - watch: _.union(defaultAssets.server.views, defaultAssets.server.allJS, defaultAssets.server.config) - }); + return plugins.nodemon({ + script: 'server.js', + nodeArgs: ['--debug'], + ext: 'js,html', + watch: _.union(defaultAssets.server.views, defaultAssets.server.allJS, defaultAssets.server.config) + }); }); // Watch Files For Changes gulp.task('watch', function() { - // Start livereload - plugins.livereload.listen(); + // Start livereload + plugins.livereload.listen(); - // Add watch rules - gulp.watch(defaultAssets.server.gulpConfig, ['jshint']); - gulp.watch(defaultAssets.server.views).on('change', plugins.livereload.changed); - gulp.watch(defaultAssets.server.allJS, ['jshint']).on('change', plugins.livereload.changed); - gulp.watch(defaultAssets.client.views).on('change', plugins.livereload.changed); - gulp.watch(defaultAssets.client.js, ['jshint']).on('change', plugins.livereload.changed); - gulp.watch(defaultAssets.client.css, ['csslint']).on('change', plugins.livereload.changed); - gulp.watch(defaultAssets.client.sass, ['sass', 'csslint']).on('change', plugins.livereload.changed); - gulp.watch(defaultAssets.client.less, ['less', 'csslint']).on('change', plugins.livereload.changed); + // Add watch rules + gulp.watch(defaultAssets.server.gulpConfig, ['jshint']); + gulp.watch(defaultAssets.server.views).on('change', plugins.livereload.changed); + gulp.watch(defaultAssets.server.allJS, ['jshint']).on('change', plugins.livereload.changed); + gulp.watch(defaultAssets.client.views).on('change', plugins.livereload.changed); + gulp.watch(defaultAssets.client.js, ['jshint']).on('change', plugins.livereload.changed); + gulp.watch(defaultAssets.client.css, ['csslint']).on('change', plugins.livereload.changed); + gulp.watch(defaultAssets.client.sass, ['sass', 'csslint']).on('change', plugins.livereload.changed); + gulp.watch(defaultAssets.client.less, ['less', 'csslint']).on('change', plugins.livereload.changed); }); // CSS linting task gulp.task('csslint', function (done) { - return gulp.src(defaultAssets.client.css) - .pipe(plugins.csslint('.csslintrc')) - .pipe(plugins.csslint.reporter()) - .pipe(plugins.csslint.reporter(function (file) { - if (!file.csslint.errorCount) { - done(); - } - })); + return gulp.src(defaultAssets.client.css) + .pipe(plugins.csslint('.csslintrc')) + .pipe(plugins.csslint.reporter()) + .pipe(plugins.csslint.reporter(function (file) { + if (!file.csslint.errorCount) { + done(); + } + })); }); // JS linting task gulp.task('jshint', function () { - return gulp.src(_.union(defaultAssets.server.gulpConfig, defaultAssets.server.allJS, defaultAssets.client.js, testAssets.tests.server, testAssets.tests.client, testAssets.tests.e2e)) - .pipe(plugins.jshint()) - .pipe(plugins.jshint.reporter('default')) - .pipe(plugins.jshint.reporter('fail')); + return gulp.src(_.union(defaultAssets.server.gulpConfig, defaultAssets.server.allJS, defaultAssets.client.js, testAssets.tests.server, testAssets.tests.client, testAssets.tests.e2e)) + .pipe(plugins.jshint()) + .pipe(plugins.jshint.reporter('default')) + .pipe(plugins.jshint.reporter('fail')); }); // JS minifying task gulp.task('uglify', function () { - return gulp.src(defaultAssets.client.js) - .pipe(plugins.ngAnnotate()) - .pipe(plugins.uglify({ - mangle: false - })) - .pipe(plugins.concat('application.min.js')) - .pipe(gulp.dest('public/dist')); + return gulp.src(defaultAssets.client.js) + .pipe(plugins.ngAnnotate()) + .pipe(plugins.uglify({ + mangle: false + })) + .pipe(plugins.concat('application.min.js')) + .pipe(gulp.dest('public/dist')); }); // CSS minifying task gulp.task('cssmin', function () { - return gulp.src(defaultAssets.client.css) - .pipe(plugins.cssmin()) - .pipe(plugins.concat('application.min.css')) - .pipe(gulp.dest('public/dist')); + return gulp.src(defaultAssets.client.css) + .pipe(plugins.cssmin()) + .pipe(plugins.concat('application.min.css')) + .pipe(gulp.dest('public/dist')); }); // Sass task gulp.task('sass', function () { - return gulp.src(defaultAssets.client.sass) - .pipe(plugins.sass()) - .pipe(plugins.rename(function (file) { - file.dirname = file.dirname.replace(path.sep + 'scss', path.sep + 'css'); - })) - .pipe(gulp.dest('./modules/')); + return gulp.src(defaultAssets.client.sass) + .pipe(plugins.sass()) + .pipe(plugins.rename(function (file) { + file.dirname = file.dirname.replace(path.sep + 'scss', path.sep + 'css'); + })) + .pipe(gulp.dest('./modules/')); }); // Less task gulp.task('less', function () { - return gulp.src(defaultAssets.client.less) - .pipe(plugins.less()) - .pipe(plugins.rename(function (file) { - file.dirname = file.dirname.replace(path.sep + 'less', path.sep + 'css'); - })) - .pipe(gulp.dest('./modules/')); + return gulp.src(defaultAssets.client.less) + .pipe(plugins.less()) + .pipe(plugins.rename(function (file) { + file.dirname = file.dirname.replace(path.sep + 'less', path.sep + 'css'); + })) + .pipe(gulp.dest('./modules/')); }); // Mocha tests task gulp.task('mocha', function (done) { - // Open mongoose connections - var mongoose = require('./config/lib/mongoose.js'); - var error; - - // Connect mongoose - mongoose.connect(function() { - // Run the tests - gulp.src(testAssets.tests.server) - .pipe(plugins.mocha({ - reporter: 'spec' - })) - .on('error', function (err) { - // If an error occurs, save it - error = err; - }) - .on('end', function() { - // When the tests are done, disconnect mongoose and pass the error state back to gulp - mongoose.disconnect(function() { - done(error); - }); - }); - }); + // Open mongoose connections + var mongoose = require('./config/lib/mongoose.js'); + var error; + + // Connect mongoose + mongoose.connect(function() { + // Run the tests + gulp.src(testAssets.tests.server) + .pipe(plugins.mocha({ + reporter: 'spec' + })) + .on('error', function (err) { + // If an error occurs, save it + error = err; + }) + .on('end', function() { + // When the tests are done, disconnect mongoose and pass the error state back to gulp + mongoose.disconnect(function() { + done(error); + }); + }); + }); }); // Karma test runner task gulp.task('karma', function (done) { - return gulp.src([]) - .pipe(plugins.karma({ - configFile: 'karma.conf.js', - action: 'run', - singleRun: true - })); + return gulp.src([]) + .pipe(plugins.karma({ + configFile: 'karma.conf.js', + action: 'run', + singleRun: true + })); }); // Selenium standalone WebDriver update task @@ -155,41 +155,41 @@ gulp.task('webdriver-update', plugins.protractor.webdriver_update); // Protractor test runner task gulp.task('protractor', function () { - gulp.src([]) - .pipe(plugins.protractor.protractor({ - configFile: 'protractor.conf.js' - })) - .on('error', function (e) { - throw e; - }); + gulp.src([]) + .pipe(plugins.protractor.protractor({ + configFile: 'protractor.conf.js' + })) + .on('error', function (e) { + throw e; + }); }); // Lint CSS and JavaScript files. gulp.task('lint', function(done) { - runSequence('less', 'sass', ['csslint', 'jshint'], done); + runSequence('less', 'sass', ['csslint', 'jshint'], done); }); // Lint project files and minify them into two production files. gulp.task('build', function(done) { - runSequence('env:dev' ,'lint', ['uglify', 'cssmin'], done); + runSequence('env:dev' ,'lint', ['uglify', 'cssmin'], done); }); // Run the project tests gulp.task('test', function(done) { - runSequence('env:test', ['karma', 'mocha'], done); + runSequence('env:test', ['karma', 'mocha'], done); }); // Run the project in development mode gulp.task('default', function(done) { - runSequence('env:dev', 'lint', ['nodemon', 'watch'], done); + runSequence('env:dev', 'lint', ['nodemon', 'watch'], done); }); // Run the project in debug mode gulp.task('debug', function(done) { - runSequence('env:dev', 'lint', ['nodemon', 'watch'], done); + runSequence('env:dev', 'lint', ['nodemon', 'watch'], done); }); // Run the project in production mode gulp.task('prod', function(done) { - runSequence('build', 'lint', ['nodemon', 'watch'], done); + runSequence('build', 'lint', ['nodemon', 'watch'], done); }); diff --git a/karma.conf.js b/karma.conf.js index ecd20fc4a6..cdf1cd2421 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -8,7 +8,7 @@ var _ = require('lodash'), testAssets = require('./config/assets/test'); // Karma configuration -module.exports = function(karmaConfig) { +module.exports = function (karmaConfig) { karmaConfig.set({ // Frameworks to use frameworks: ['jasmine'], @@ -20,7 +20,7 @@ module.exports = function(karmaConfig) { ngHtml2JsPreprocessor: { moduleName: 'mean', - cacheIdFromPath: function(filepath) { + cacheIdFromPath: function (filepath) { return filepath.replace('/client', ''); }, }, diff --git a/modules/articles/client/config/articles.client.config.js b/modules/articles/client/config/articles.client.config.js index d43e0893f4..5ad71e82dd 100644 --- a/modules/articles/client/config/articles.client.config.js +++ b/modules/articles/client/config/articles.client.config.js @@ -2,24 +2,24 @@ // Configuring the Articles module angular.module('articles').run(['Menus', - function(Menus) { - // Add the articles dropdown item - Menus.addMenuItem('topbar', { - title: 'Articles', - state: 'articles', - type: 'dropdown' - }); + function (Menus) { + // Add the articles dropdown item + Menus.addMenuItem('topbar', { + title: 'Articles', + state: 'articles', + type: 'dropdown' + }); - // Add the dropdown list item - Menus.addSubMenuItem('topbar', 'articles', { - title: 'List Articles', - state: 'articles.list' - }); + // Add the dropdown list item + Menus.addSubMenuItem('topbar', 'articles', { + title: 'List Articles', + state: 'articles.list' + }); - // Add the dropdown create item - Menus.addSubMenuItem('topbar', 'articles', { - title: 'Create Articles', - state: 'articles.create' - }); - } + // Add the dropdown create item + Menus.addSubMenuItem('topbar', 'articles', { + title: 'Create Articles', + state: 'articles.create' + }); + } ]); diff --git a/modules/articles/client/config/articles.client.routes.js b/modules/articles/client/config/articles.client.routes.js index 2505bec742..df7024c4c2 100644 --- a/modules/articles/client/config/articles.client.routes.js +++ b/modules/articles/client/config/articles.client.routes.js @@ -2,32 +2,32 @@ // Setting up route angular.module('articles').config(['$stateProvider', - function($stateProvider) { - // Articles state routing - $stateProvider. - state('articles', { - abstract: true, - url: '/articles', - template: '', - data: { - roles: ['user', 'admin'] - } - }). - state('articles.list', { - url: '', - templateUrl: 'modules/articles/views/list-articles.client.view.html' - }). - state('articles.create', { - url: '/create', - templateUrl: 'modules/articles/views/create-article.client.view.html' - }). - state('articles.view', { - url: '/:articleId', - templateUrl: 'modules/articles/views/view-article.client.view.html' - }). - state('articles.edit', { - url: '/:articleId/edit', - templateUrl: 'modules/articles/views/edit-article.client.view.html' - }); - } + function ($stateProvider) { + // Articles state routing + $stateProvider + .state('articles', { + abstract: true, + url: '/articles', + template: '', + data: { + roles: ['user', 'admin'] + } + }) + .state('articles.list', { + url: '', + templateUrl: 'modules/articles/views/list-articles.client.view.html' + }) + .state('articles.create', { + url: '/create', + templateUrl: 'modules/articles/views/create-article.client.view.html' + }) + .state('articles.view', { + url: '/:articleId', + templateUrl: 'modules/articles/views/view-article.client.view.html' + }) + .state('articles.edit', { + url: '/:articleId/edit', + templateUrl: 'modules/articles/views/edit-article.client.view.html' + }); + } ]); diff --git a/modules/articles/client/controllers/articles.client.controller.js b/modules/articles/client/controllers/articles.client.controller.js index a54e32ea7e..4a47d5a27b 100644 --- a/modules/articles/client/controllers/articles.client.controller.js +++ b/modules/articles/client/controllers/articles.client.controller.js @@ -2,67 +2,67 @@ // Articles controller angular.module('articles').controller('ArticlesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Articles', - function($scope, $stateParams, $location, Authentication, Articles) { - $scope.authentication = Authentication; + function ($scope, $stateParams, $location, Authentication, Articles) { + $scope.authentication = Authentication; - // Create new Article - $scope.create = function() { - // Create new Article object - var article = new Articles({ - title: this.title, - content: this.content - }); + // Create new Article + $scope.create = function () { + // Create new Article object + var article = new Articles({ + title: this.title, + content: this.content + }); - // Redirect after save - article.$save(function(response) { - $location.path('articles/' + response._id); + // Redirect after save + article.$save(function (response) { + $location.path('articles/' + response._id); - // Clear form fields - $scope.title = ''; - $scope.content = ''; - }, function(errorResponse) { - $scope.error = errorResponse.data.message; - }); - }; + // Clear form fields + $scope.title = ''; + $scope.content = ''; + }, function (errorResponse) { + $scope.error = errorResponse.data.message; + }); + }; - // Remove existing Article - $scope.remove = function(article) { - if (article) { - article.$remove(); + // Remove existing Article + $scope.remove = function (article) { + if (article) { + article.$remove(); - for (var i in $scope.articles) { - if ($scope.articles[i] === article) { - $scope.articles.splice(i, 1); - } - } - } else { - $scope.article.$remove(function() { - $location.path('articles'); - }); - } - }; + for (var i in $scope.articles) { + if ($scope.articles[i] === article) { + $scope.articles.splice(i, 1); + } + } + } else { + $scope.article.$remove(function () { + $location.path('articles'); + }); + } + }; - // Update existing Article - $scope.update = function() { - var article = $scope.article; + // Update existing Article + $scope.update = function () { + var article = $scope.article; - article.$update(function() { - $location.path('articles/' + article._id); - }, function(errorResponse) { - $scope.error = errorResponse.data.message; - }); - }; + article.$update(function () { + $location.path('articles/' + article._id); + }, function (errorResponse) { + $scope.error = errorResponse.data.message; + }); + }; - // Find a list of Articles - $scope.find = function() { - $scope.articles = Articles.query(); - }; + // Find a list of Articles + $scope.find = function () { + $scope.articles = Articles.query(); + }; - // Find existing Article - $scope.findOne = function() { - $scope.article = Articles.get({ - articleId: $stateParams.articleId - }); - }; - } + // Find existing Article + $scope.findOne = function () { + $scope.article = Articles.get({ + articleId: $stateParams.articleId + }); + }; + } ]); diff --git a/modules/articles/client/services/articles.client.service.js b/modules/articles/client/services/articles.client.service.js index 5c8967f5a0..73a8251221 100644 --- a/modules/articles/client/services/articles.client.service.js +++ b/modules/articles/client/services/articles.client.service.js @@ -2,13 +2,13 @@ //Articles service used for communicating with the articles REST endpoints angular.module('articles').factory('Articles', ['$resource', - function($resource) { - return $resource('api/articles/:articleId', { - articleId: '@_id' - }, { - update: { - method: 'PUT' - } - }); - } + function ($resource) { + return $resource('api/articles/:articleId', { + articleId: '@_id' + }, { + update: { + method: 'PUT' + } + }); + } ]); diff --git a/modules/articles/client/views/create-article.client.view.html b/modules/articles/client/views/create-article.client.view.html index 79ea510e65..235e6b37af 100644 --- a/modules/articles/client/views/create-article.client.view.html +++ b/modules/articles/client/views/create-article.client.view.html @@ -1,29 +1,29 @@
- -
-
-
-
- -
- -
-
-
- -
- -
-
-
- -
-
- -
-
-
-
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+ +
+
+
+
diff --git a/modules/articles/client/views/edit-article.client.view.html b/modules/articles/client/views/edit-article.client.view.html index 7a4d4ca01a..69eb621b2e 100644 --- a/modules/articles/client/views/edit-article.client.view.html +++ b/modules/articles/client/views/edit-article.client.view.html @@ -1,29 +1,29 @@
- -
-
-
-
- -
- -
-
-
- -
- -
-
-
- -
-
- -
-
-
-
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+ +
+
+
+
diff --git a/modules/articles/client/views/list-articles.client.view.html b/modules/articles/client/views/list-articles.client.view.html index 0d8c3b7900..689c9c030a 100644 --- a/modules/articles/client/views/list-articles.client.view.html +++ b/modules/articles/client/views/list-articles.client.view.html @@ -1,20 +1,20 @@
- - -
- No articles yet, why don't you create one? -
+ + +
+ No articles yet, why don't you create one? +
diff --git a/modules/articles/client/views/view-article.client.view.html b/modules/articles/client/views/view-article.client.view.html index a298412b4e..83a0c40b89 100644 --- a/modules/articles/client/views/view-article.client.view.html +++ b/modules/articles/client/views/view-article.client.view.html @@ -1,22 +1,22 @@
- - - - - Posted on - - by - - - -

+ + + + + Posted on + + by + + + +

diff --git a/modules/articles/server/controllers/articles.server.controller.js b/modules/articles/server/controllers/articles.server.controller.js index 02c9b9df0e..2c146c64d8 100644 --- a/modules/articles/server/controllers/articles.server.controller.js +++ b/modules/articles/server/controllers/articles.server.controller.js @@ -4,106 +4,107 @@ * Module dependencies. */ var path = require('path'), - mongoose = require('mongoose'), - Article = mongoose.model('Article'), - errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')); + mongoose = require('mongoose'), + Article = mongoose.model('Article'), + errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')); /** * Create a article */ -exports.create = function(req, res) { - var article = new Article(req.body); - article.user = req.user; +exports.create = function (req, res) { + var article = new Article(req.body); + article.user = req.user; - article.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.json(article); - } - }); + article.save(function (err) { + if (err) { + return res.status(400).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + res.json(article); + } + }); }; /** * Show the current article */ -exports.read = function(req, res) { - res.json(req.article); +exports.read = function (req, res) { + res.json(req.article); }; /** * Update a article */ -exports.update = function(req, res) { - var article = req.article; +exports.update = function (req, res) { + var article = req.article; - article.title = req.body.title; - article.content = req.body.content; + article.title = req.body.title; + article.content = req.body.content; - article.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.json(article); - } - }); + article.save(function (err) { + if (err) { + return res.status(400).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + res.json(article); + } + }); }; /** * Delete an article */ -exports.delete = function(req, res) { - var article = req.article; +exports.delete = function (req, res) { + var article = req.article; - article.remove(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.json(article); - } - }); + article.remove(function (err) { + if (err) { + return res.status(400).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + res.json(article); + } + }); }; /** * List of Articles */ -exports.list = function(req, res) { - Article.find().sort('-created').populate('user', 'displayName').exec(function(err, articles) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.json(articles); - } - }); +exports.list = function (req, res) { + Article.find().sort('-created').populate('user', 'displayName').exec(function (err, articles) { + if (err) { + return res.status(400).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + res.json(articles); + } + }); }; /** * Article middleware */ -exports.articleByID = function(req, res, next, id) { +exports.articleByID = function (req, res, next, id) { - if (!mongoose.Types.ObjectId.isValid(id)) { - return res.status(400).send({ - message: 'Article is invalid' - }); - } + if (!mongoose.Types.ObjectId.isValid(id)) { + return res.status(400).send({ + message: 'Article is invalid' + }); + } - Article.findById(id).populate('user', 'displayName').exec(function(err, article) { - if (err) return next(err); - if (!article) { - return res.status(404).send({ - message: 'No article with that identifier has been found' - }); - } - req.article = article; - next(); - }); -}; \ No newline at end of file + Article.findById(id).populate('user', 'displayName').exec(function (err, article) { + if (err) { + return next(err); + } else if (!article) { + return res.status(404).send({ + message: 'No article with that identifier has been found' + }); + } + req.article = article; + next(); + }); +}; diff --git a/modules/articles/server/models/article.server.model.js b/modules/articles/server/models/article.server.model.js index f2b89db815..2ccb91e370 100644 --- a/modules/articles/server/models/article.server.model.js +++ b/modules/articles/server/models/article.server.model.js @@ -4,31 +4,31 @@ * Module dependencies. */ var mongoose = require('mongoose'), - Schema = mongoose.Schema; + Schema = mongoose.Schema; /** * Article Schema */ var ArticleSchema = new Schema({ - created: { - type: Date, - default: Date.now - }, - title: { - type: String, - default: '', - trim: true, - required: 'Title cannot be blank' - }, - content: { - type: String, - default: '', - trim: true - }, - user: { - type: Schema.ObjectId, - ref: 'User' - } + created: { + type: Date, + default: Date.now + }, + title: { + type: String, + default: '', + trim: true, + required: 'Title cannot be blank' + }, + content: { + type: String, + default: '', + trim: true + }, + user: { + type: Schema.ObjectId, + ref: 'User' + } }); mongoose.model('Article', ArticleSchema); diff --git a/modules/articles/server/policies/articles.server.policy.js b/modules/articles/server/policies/articles.server.policy.js index a8572d9e92..536f8bccb1 100644 --- a/modules/articles/server/policies/articles.server.policy.js +++ b/modules/articles/server/policies/articles.server.policy.js @@ -11,62 +11,62 @@ acl = new acl(new acl.memoryBackend()); /** * Invoke Articles Permissions */ -exports.invokeRolesPolicies = function() { - acl.allow([{ - roles: ['admin'], - allows: [{ - resources: '/api/articles', - permissions: '*' - }, { - resources: '/api/articles/:articleId', - permissions: '*' - }] - }, { - roles: ['user'], - allows: [{ - resources: '/api/articles', - permissions: ['get', 'post'] - }, { - resources: '/api/articles/:articleId', - permissions: ['get'] - }] - }, { - roles: ['guest'], - allows: [{ - resources: '/api/articles', - permissions: ['get'] - }, { - resources: '/api/articles/:articleId', - permissions: ['get'] - }] - }]); +exports.invokeRolesPolicies = function () { + acl.allow([{ + roles: ['admin'], + allows: [{ + resources: '/api/articles', + permissions: '*' + }, { + resources: '/api/articles/:articleId', + permissions: '*' + }] + }, { + roles: ['user'], + allows: [{ + resources: '/api/articles', + permissions: ['get', 'post'] + }, { + resources: '/api/articles/:articleId', + permissions: ['get'] + }] + }, { + roles: ['guest'], + allows: [{ + resources: '/api/articles', + permissions: ['get'] + }, { + resources: '/api/articles/:articleId', + permissions: ['get'] + }] + }]); }; /** * Check If Articles Policy Allows */ -exports.isAllowed = function(req, res, next) { - var roles = (req.user) ? req.user.roles : ['guest']; +exports.isAllowed = function (req, res, next) { + var roles = (req.user) ? req.user.roles : ['guest']; - // If an article is being processed and the current user created it then allow any manipulation - if (req.article && req.user && req.article.user.id === req.user.id) { - return next(); - } + // If an article is being processed and the current user created it then allow any manipulation + if (req.article && req.user && req.article.user.id === req.user.id) { + return next(); + } - // Check for user roles - acl.areAnyRolesAllowed(roles, req.route.path, req.method.toLowerCase(), function(err, isAllowed) { - if (err) { - // An authorization error occurred. - return res.status(500).send('Unexpected authorization error'); - } else { - if (isAllowed) { - // Access granted! Invoke next middleware - return next(); - } else { - return res.status(403).json({ - message: 'User is not authorized' - }); - } - } - }); + // Check for user roles + acl.areAnyRolesAllowed(roles, req.route.path, req.method.toLowerCase(), function (err, isAllowed) { + if (err) { + // An authorization error occurred. + return res.status(500).send('Unexpected authorization error'); + } else { + if (isAllowed) { + // Access granted! Invoke next middleware + return next(); + } else { + return res.status(403).json({ + message: 'User is not authorized' + }); + } + } + }); }; diff --git a/modules/articles/server/routes/articles.server.routes.js b/modules/articles/server/routes/articles.server.routes.js index 49e3697f9f..dd7bab41e4 100644 --- a/modules/articles/server/routes/articles.server.routes.js +++ b/modules/articles/server/routes/articles.server.routes.js @@ -4,20 +4,20 @@ * Module dependencies. */ var articlesPolicy = require('../policies/articles.server.policy'), - articles = require('../controllers/articles.server.controller'); + articles = require('../controllers/articles.server.controller'); -module.exports = function(app) { - // Articles collection routes - app.route('/api/articles').all(articlesPolicy.isAllowed) - .get(articles.list) - .post(articles.create); +module.exports = function (app) { + // Articles collection routes + app.route('/api/articles').all(articlesPolicy.isAllowed) + .get(articles.list) + .post(articles.create); - // Single article routes - app.route('/api/articles/:articleId').all(articlesPolicy.isAllowed) - .get(articles.read) - .put(articles.update) - .delete(articles.delete); + // Single article routes + app.route('/api/articles/:articleId').all(articlesPolicy.isAllowed) + .get(articles.read) + .put(articles.update) + .delete(articles.delete); - // Finish by binding the article middleware - app.param('articleId', articles.articleByID); + // Finish by binding the article middleware + app.param('articleId', articles.articleByID); }; diff --git a/modules/articles/tests/client/articles.client.controller.tests.js b/modules/articles/tests/client/articles.client.controller.tests.js index 3ecc3a1b80..2e6f317f34 100644 --- a/modules/articles/tests/client/articles.client.controller.tests.js +++ b/modules/articles/tests/client/articles.client.controller.tests.js @@ -1,8 +1,8 @@ 'use strict'; -(function() { +(function () { // Articles Controller Spec - describe('Articles Controller Tests', function() { + describe('Articles Controller Tests', function () { // Initialize global variables var ArticlesController, scope, @@ -18,11 +18,11 @@ // the responses exactly. To solve the problem, we define a new toEqualData Jasmine matcher. // When the toEqualData matcher compares two objects, it takes only object properties into // account and ignores methods. - beforeEach(function() { + beforeEach(function () { jasmine.addMatchers({ - toEqualData: function(util, customEqualityTesters) { + toEqualData: function (util, customEqualityTesters) { return { - compare: function(actual, expected) { + compare: function (actual, expected) { return { pass: angular.equals(actual, expected) }; @@ -38,7 +38,7 @@ // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_). // This allows us to inject a service but then attach it to a variable // with the same name as the service. - beforeEach(inject(function($controller, $rootScope, _$location_, _$stateParams_, _$httpBackend_, _Authentication_, _Articles_) { + beforeEach(inject(function ($controller, $rootScope, _$location_, _$stateParams_, _$httpBackend_, _Authentication_, _Articles_) { // Set a new global scope scope = $rootScope.$new(); @@ -67,7 +67,7 @@ }); })); - it('$scope.find() should create an array with at least one article object fetched from XHR', inject(function(Articles) { + it('$scope.find() should create an array with at least one article object fetched from XHR', inject(function (Articles) { // Create a sample articles array that includes the new article var sampleArticles = [mockArticle]; @@ -82,7 +82,7 @@ expect(scope.articles).toEqualData(sampleArticles); })); - it('$scope.findOne() should create an array with one article object fetched from XHR using a articleId URL parameter', inject(function(Articles) { + it('$scope.findOne() should create an array with one article object fetched from XHR using a articleId URL parameter', inject(function (Articles) { // Set the URL parameter $stateParams.articleId = mockArticle._id; @@ -97,10 +97,10 @@ expect(scope.article).toEqualData(mockArticle); })); - describe('$scope.craete()', function() { + describe('$scope.craete()', function () { var sampleArticlePostData; - beforeEach(function() { + beforeEach(function () { // Create a sample article object sampleArticlePostData = new Articles({ title: 'An Article about MEAN', @@ -114,7 +114,7 @@ spyOn($location, 'path'); }); - it('should send a POST request with the form input values and then locate to new object URL', inject(function(Articles) { + it('should send a POST request with the form input values and then locate to new object URL', inject(function (Articles) { // Set POST response $httpBackend.expectPOST('api/articles', sampleArticlePostData).respond(mockArticle); @@ -130,7 +130,7 @@ expect($location.path.calls.mostRecent().args[0]).toBe('articles/' + mockArticle._id); })); - it('should set scope.error if save error', function() { + it('should set scope.error if save error', function () { var errorMessage = 'this is an error message'; $httpBackend.expectPOST('api/articles', sampleArticlePostData).respond(400, { message: errorMessage @@ -143,13 +143,13 @@ }); }); - describe('$scope.update()', function() { - beforeEach(function() { + describe('$scope.update()', function () { + beforeEach(function () { // Mock article in scope scope.article = mockArticle; }); - it('should update a valid article', inject(function(Articles) { + it('should update a valid article', inject(function (Articles) { // Set PUT response $httpBackend.expectPUT(/api\/articles\/([0-9a-fA-F]{24})$/).respond(); @@ -161,7 +161,7 @@ expect($location.path()).toBe('/articles/' + mockArticle._id); })); - it('should set scope.error to error response message', inject(function(Articles) { + it('should set scope.error to error response message', inject(function (Articles) { var errorMessage = 'error'; $httpBackend.expectPUT(/api\/articles\/([0-9a-fA-F]{24})$/).respond(400, { message: errorMessage @@ -174,8 +174,8 @@ })); }); - describe('$scope.remove(article)', function() { - beforeEach(function() { + describe('$scope.remove(article)', function () { + beforeEach(function () { // Create new articles array and include the article scope.articles = [mockArticle, {}]; @@ -186,13 +186,13 @@ scope.remove(mockArticle); }); - it('should send a DELETE request with a valid articleId and remove the article from the scope', inject(function(Articles) { + it('should send a DELETE request with a valid articleId and remove the article from the scope', inject(function (Articles) { expect(scope.articles.length).toBe(1); })); }); - describe('scope.remove()', function() { - beforeEach(function() { + describe('scope.remove()', function () { + beforeEach(function () { spyOn($location, 'path'); scope.article = mockArticle; @@ -202,7 +202,7 @@ $httpBackend.flush(); }); - it('should redirect to articles', function() { + it('should redirect to articles', function () { expect($location.path).toHaveBeenCalledWith('articles'); }); }); diff --git a/modules/articles/tests/e2e/articles.e2e.tests.js b/modules/articles/tests/e2e/articles.e2e.tests.js index af49a60eec..96b0791361 100644 --- a/modules/articles/tests/e2e/articles.e2e.tests.js +++ b/modules/articles/tests/e2e/articles.e2e.tests.js @@ -1,10 +1,10 @@ 'use strict'; -describe('Articles E2E Tests:', function() { - describe('Test articles page', function() { - it('Should report missing credentials', function() { - browser.get('http://localhost:3000/articles'); - expect(element.all(by.repeater('article in articles')).count()).toEqual(0); - }); - }); +describe('Articles E2E Tests:', function () { + describe('Test articles page', function () { + it('Should report missing credentials', function () { + browser.get('http://localhost:3000/articles'); + expect(element.all(by.repeater('article in articles')).count()).toEqual(0); + }); + }); }); diff --git a/modules/articles/tests/server/article.server.model.tests.js b/modules/articles/tests/server/article.server.model.tests.js index b4b76b8a93..0031f1191d 100644 --- a/modules/articles/tests/server/article.server.model.tests.js +++ b/modules/articles/tests/server/article.server.model.tests.js @@ -4,9 +4,9 @@ * Module dependencies. */ var should = require('should'), - mongoose = require('mongoose'), - User = mongoose.model('User'), - Article = mongoose.model('Article'); + mongoose = require('mongoose'), + User = mongoose.model('User'), + Article = mongoose.model('Article'); /** * Globals @@ -16,49 +16,49 @@ var user, article; /** * Unit tests */ -describe('Article Model Unit Tests:', function() { - beforeEach(function(done) { - user = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: 'username', - password: 'password' - }); +describe('Article Model Unit Tests:', function () { + beforeEach(function (done) { + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: 'username', + password: 'password' + }); - user.save(function() { - article = new Article({ - title: 'Article Title', - content: 'Article Content', - user: user - }); + user.save(function () { + article = new Article({ + title: 'Article Title', + content: 'Article Content', + user: user + }); - done(); - }); - }); + done(); + }); + }); - describe('Method Save', function() { - it('should be able to save without problems', function(done) { - return article.save(function(err) { - should.not.exist(err); - done(); - }); - }); + describe('Method Save', function () { + it('should be able to save without problems', function (done) { + return article.save(function (err) { + should.not.exist(err); + done(); + }); + }); - it('should be able to show an error when try to save without title', function(done) { - article.title = ''; + it('should be able to show an error when try to save without title', function (done) { + article.title = ''; - return article.save(function(err) { - should.exist(err); - done(); - }); - }); - }); + return article.save(function (err) { + should.exist(err); + done(); + }); + }); + }); - afterEach(function(done) { - Article.remove().exec(function() { - User.remove().exec(done); - }); - }); + afterEach(function (done) { + Article.remove().exec(function () { + User.remove().exec(done); + }); + }); }); diff --git a/modules/articles/tests/server/article.server.routes.tests.js b/modules/articles/tests/server/article.server.routes.tests.js index 3c76cc6442..ef0f1ac781 100644 --- a/modules/articles/tests/server/article.server.routes.tests.js +++ b/modules/articles/tests/server/article.server.routes.tests.js @@ -1,12 +1,12 @@ 'use strict'; var should = require('should'), - request = require('supertest'), - path = require('path'), - mongoose = require('mongoose'), - User = mongoose.model('User'), - Article = mongoose.model('Article'), - express = require(path.resolve('./config/lib/express')); + request = require('supertest'), + path = require('path'), + mongoose = require('mongoose'), + User = mongoose.model('User'), + Article = mongoose.model('Article'), + express = require(path.resolve('./config/lib/express')); /** * Globals @@ -17,305 +17,304 @@ var app, agent, credentials, user, article; * Article routes tests */ describe('Article CRUD tests', function () { - before(function (done) { - // Get application - app = express.init(mongoose); - agent = request.agent(app); - - done(); - }); - - beforeEach(function (done) { - // Create user credentials - credentials = { - username: 'username', - password: 'password' - }; - - // Create a new user - user = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: credentials.username, - password: credentials.password, - provider: 'local' - }); - - // Save a user to the test db and create new article - user.save(function () { - article = { - title: 'Article Title', - content: 'Article Content' - }; - - done(); - }); - }); - - it('should be able to save an article if logged in', function (done) { - agent.post('/api/auth/signin') - .send(credentials) - .expect(200) - .end(function (signinErr, signinRes) { - // Handle signin error - if (signinErr) { - return done(signinErr); - } - - // Get the userId - var userId = user.id; - - // Save a new article - agent.post('/api/articles') - .send(article) - .expect(200) - .end(function (articleSaveErr, articleSaveRes) { - // Handle article save error - if (articleSaveErr) { - return done(articleSaveErr); - } - - // Get a list of articles - agent.get('/api/articles') - .end(function (articlesGetErr, articlesGetRes) { - // Handle article save error - if (articlesGetErr) { - return done(articlesGetErr); - } - - // Get articles list - var articles = articlesGetRes.body; - - // Set assertions - (articles[0].user._id).should.equal(userId); - (articles[0].title).should.match('Article Title'); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should not be able to save an article if not logged in', function (done) { - agent.post('/api/articles') - .send(article) - .expect(403) - .end(function (articleSaveErr, articleSaveRes) { - // Call the assertion callback - done(articleSaveErr); - }); - }); - - it('should not be able to save an article if no title is provided', function (done) { - // Invalidate title field - article.title = ''; - - agent.post('/api/auth/signin') - .send(credentials) - .expect(200) - .end(function (signinErr, signinRes) { - // Handle signin error - if (signinErr) { - return done(signinErr); - } - - // Get the userId - var userId = user.id; - - // Save a new article - agent.post('/api/articles') - .send(article) - .expect(400) - .end(function (articleSaveErr, articleSaveRes) { - // Set message assertion - (articleSaveRes.body.message).should.match('Title cannot be blank'); - - // Handle article save error - done(articleSaveErr); - }); - }); - }); - - it('should be able to update an article if signed in', function (done) { - agent.post('/api/auth/signin') - .send(credentials) - .expect(200) - .end(function (signinErr, signinRes) { - // Handle signin error - if (signinErr) { - return done(signinErr); - } - - // Get the userId - var userId = user.id; - - // Save a new article - agent.post('/api/articles') - .send(article) - .expect(200) - .end(function (articleSaveErr, articleSaveRes) { - // Handle article save error - if (articleSaveErr) { - return done(articleSaveErr); - } - - // Update article title - article.title = 'WHY YOU GOTTA BE SO MEAN?'; - - // Update an existing article - agent.put('/api/articles/' + articleSaveRes.body._id) - .send(article) - .expect(200) - .end(function (articleUpdateErr, articleUpdateRes) { - // Handle article update error - if (articleUpdateErr) { - return done(articleUpdateErr); - } - - // Set assertions - (articleUpdateRes.body._id).should.equal(articleSaveRes.body._id); - (articleUpdateRes.body.title).should.match('WHY YOU GOTTA BE SO MEAN?'); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should be able to get a list of articles if not signed in', function (done) { - // Create new article model instance - var articleObj = new Article(article); - - // Save the article - articleObj.save(function () { - // Request articles - request(app).get('/api/articles') - .end(function (req, res) { - // Set assertion - res.body.should.be.instanceof(Array).and.have.lengthOf(1); - - // Call the assertion callback - done(); - }); - - }); - }); - - - it('should be able to get a single article if not signed in', function (done) { - // Create new article model instance - var articleObj = new Article(article); - - // Save the article - articleObj.save(function () { - request(app).get('/api/articles/' + articleObj._id) - .end(function (req, res) { - // Set assertion - res.body.should.be.instanceof(Object).and.have.property('title', article.title); - - // Call the assertion callback - done(); - }); - }); - }); - - it('should return proper error for single article with an invalid Id, if not signed in', function (done) { - // test is not a valid mongoose Id - request(app).get('/api/articles/test') - .end(function (req, res) { - // Set assertion - res.body.should.be.instanceof(Object).and.have.property('message', 'Article is invalid'); - - // Call the assertion callback - done(); - }); - }); - - it('should return proper error for single article which doesnt exist, if not signed in', function (done) { - // This is a valid mongoose Id but a non-existent article - request(app).get('/api/articles/559e9cd815f80b4c256a8f41') - .end(function (req, res) { - // Set assertion - res.body.should.be.instanceof(Object).and.have.property('message', 'No article with that identifier has been found'); - - // Call the assertion callback - done(); - }); - }); - - it('should be able to delete an article if signed in', function (done) { - agent.post('/api/auth/signin') - .send(credentials) - .expect(200) - .end(function (signinErr, signinRes) { - // Handle signin error - if (signinErr) { - return done(signinErr); - } - - // Get the userId - var userId = user.id; - - // Save a new article - agent.post('/api/articles') - .send(article) - .expect(200) - .end(function (articleSaveErr, articleSaveRes) { - // Handle article save error - if (articleSaveErr) { - return done(articleSaveErr); - } - - // Delete an existing article - agent.delete('/api/articles/' + articleSaveRes.body._id) - .send(article) - .expect(200) - .end(function (articleDeleteErr, articleDeleteRes) { - // Handle article error error - if (articleDeleteErr) { - return done(articleDeleteErr); - } - - // Set assertions - (articleDeleteRes.body._id).should.equal(articleSaveRes.body._id); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should not be able to delete an article if not signed in', function (done) { - // Set article user - article.user = user; - - // Create new article model instance - var articleObj = new Article(article); - - // Save the article - articleObj.save(function () { - // Try deleting article - request(app).delete('/api/articles/' + articleObj._id) - .expect(403) - .end(function (articleDeleteErr, articleDeleteRes) { - // Set message assertion - (articleDeleteRes.body.message).should.match('User is not authorized'); - - // Handle article error error - done(articleDeleteErr); - }); - - }); - }); - - afterEach(function (done) { - User.remove().exec(function () { - Article.remove().exec(done); - }); - }); + before(function (done) { + // Get application + app = express.init(mongoose); + agent = request.agent(app); + + done(); + }); + + beforeEach(function (done) { + // Create user credentials + credentials = { + username: 'username', + password: 'password' + }; + + // Create a new user + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: credentials.username, + password: credentials.password, + provider: 'local' + }); + + // Save a user to the test db and create new article + user.save(function () { + article = { + title: 'Article Title', + content: 'Article Content' + }; + + done(); + }); + }); + + it('should be able to save an article if logged in', function (done) { + agent.post('/api/auth/signin') + .send(credentials) + .expect(200) + .end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) { + return done(signinErr); + } + + // Get the userId + var userId = user.id; + + // Save a new article + agent.post('/api/articles') + .send(article) + .expect(200) + .end(function (articleSaveErr, articleSaveRes) { + // Handle article save error + if (articleSaveErr) { + return done(articleSaveErr); + } + + // Get a list of articles + agent.get('/api/articles') + .end(function (articlesGetErr, articlesGetRes) { + // Handle article save error + if (articlesGetErr) { + return done(articlesGetErr); + } + + // Get articles list + var articles = articlesGetRes.body; + + // Set assertions + (articles[0].user._id).should.equal(userId); + (articles[0].title).should.match('Article Title'); + + // Call the assertion callback + done(); + }); + }); + }); + }); + + it('should not be able to save an article if not logged in', function (done) { + agent.post('/api/articles') + .send(article) + .expect(403) + .end(function (articleSaveErr, articleSaveRes) { + // Call the assertion callback + done(articleSaveErr); + }); + }); + + it('should not be able to save an article if no title is provided', function (done) { + // Invalidate title field + article.title = ''; + + agent.post('/api/auth/signin') + .send(credentials) + .expect(200) + .end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) { + return done(signinErr); + } + + // Get the userId + var userId = user.id; + + // Save a new article + agent.post('/api/articles') + .send(article) + .expect(400) + .end(function (articleSaveErr, articleSaveRes) { + // Set message assertion + (articleSaveRes.body.message).should.match('Title cannot be blank'); + + // Handle article save error + done(articleSaveErr); + }); + }); + }); + + it('should be able to update an article if signed in', function (done) { + agent.post('/api/auth/signin') + .send(credentials) + .expect(200) + .end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) { + return done(signinErr); + } + + // Get the userId + var userId = user.id; + + // Save a new article + agent.post('/api/articles') + .send(article) + .expect(200) + .end(function (articleSaveErr, articleSaveRes) { + // Handle article save error + if (articleSaveErr) { + return done(articleSaveErr); + } + + // Update article title + article.title = 'WHY YOU GOTTA BE SO MEAN?'; + + // Update an existing article + agent.put('/api/articles/' + articleSaveRes.body._id) + .send(article) + .expect(200) + .end(function (articleUpdateErr, articleUpdateRes) { + // Handle article update error + if (articleUpdateErr) { + return done(articleUpdateErr); + } + + // Set assertions + (articleUpdateRes.body._id).should.equal(articleSaveRes.body._id); + (articleUpdateRes.body.title).should.match('WHY YOU GOTTA BE SO MEAN?'); + + // Call the assertion callback + done(); + }); + }); + }); + }); + + it('should be able to get a list of articles if not signed in', function (done) { + // Create new article model instance + var articleObj = new Article(article); + + // Save the article + articleObj.save(function () { + // Request articles + request(app).get('/api/articles') + .end(function (req, res) { + // Set assertion + res.body.should.be.instanceof(Array).and.have.lengthOf(1); + + // Call the assertion callback + done(); + }); + + }); + }); + + it('should be able to get a single article if not signed in', function (done) { + // Create new article model instance + var articleObj = new Article(article); + + // Save the article + articleObj.save(function () { + request(app).get('/api/articles/' + articleObj._id) + .end(function (req, res) { + // Set assertion + res.body.should.be.instanceof(Object).and.have.property('title', article.title); + + // Call the assertion callback + done(); + }); + }); + }); + + it('should return proper error for single article with an invalid Id, if not signed in', function (done) { + // test is not a valid mongoose Id + request(app).get('/api/articles/test') + .end(function (req, res) { + // Set assertion + res.body.should.be.instanceof(Object).and.have.property('message', 'Article is invalid'); + + // Call the assertion callback + done(); + }); + }); + + it('should return proper error for single article which doesnt exist, if not signed in', function (done) { + // This is a valid mongoose Id but a non-existent article + request(app).get('/api/articles/559e9cd815f80b4c256a8f41') + .end(function (req, res) { + // Set assertion + res.body.should.be.instanceof(Object).and.have.property('message', 'No article with that identifier has been found'); + + // Call the assertion callback + done(); + }); + }); + + it('should be able to delete an article if signed in', function (done) { + agent.post('/api/auth/signin') + .send(credentials) + .expect(200) + .end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) { + return done(signinErr); + } + + // Get the userId + var userId = user.id; + + // Save a new article + agent.post('/api/articles') + .send(article) + .expect(200) + .end(function (articleSaveErr, articleSaveRes) { + // Handle article save error + if (articleSaveErr) { + return done(articleSaveErr); + } + + // Delete an existing article + agent.delete('/api/articles/' + articleSaveRes.body._id) + .send(article) + .expect(200) + .end(function (articleDeleteErr, articleDeleteRes) { + // Handle article error error + if (articleDeleteErr) { + return done(articleDeleteErr); + } + + // Set assertions + (articleDeleteRes.body._id).should.equal(articleSaveRes.body._id); + + // Call the assertion callback + done(); + }); + }); + }); + }); + + it('should not be able to delete an article if not signed in', function (done) { + // Set article user + article.user = user; + + // Create new article model instance + var articleObj = new Article(article); + + // Save the article + articleObj.save(function () { + // Try deleting article + request(app).delete('/api/articles/' + articleObj._id) + .expect(403) + .end(function (articleDeleteErr, articleDeleteRes) { + // Set message assertion + (articleDeleteRes.body.message).should.match('User is not authorized'); + + // Handle article error error + done(articleDeleteErr); + }); + + }); + }); + + afterEach(function (done) { + User.remove().exec(function () { + Article.remove().exec(done); + }); + }); }); diff --git a/modules/chat/client/config/chat.client.config.js b/modules/chat/client/config/chat.client.config.js index 67a4719f4a..381ef5d6e3 100644 --- a/modules/chat/client/config/chat.client.config.js +++ b/modules/chat/client/config/chat.client.config.js @@ -2,11 +2,11 @@ // Configuring the Chat module angular.module('chat').run(['Menus', - function(Menus) { - // Set top bar menu items - Menus.addMenuItem('topbar', { - title: 'Chat', - state: 'chat' - }); - } + function (Menus) { + // Set top bar menu items + Menus.addMenuItem('topbar', { + title: 'Chat', + state: 'chat' + }); + } ]); diff --git a/modules/chat/client/config/chat.client.routes.js b/modules/chat/client/config/chat.client.routes.js index becabe53e0..d289e22d01 100644 --- a/modules/chat/client/config/chat.client.routes.js +++ b/modules/chat/client/config/chat.client.routes.js @@ -2,14 +2,14 @@ // Configure the 'chat' module routes angular.module('chat').config(['$stateProvider', - function($stateProvider) { - $stateProvider. - state('chat', { - url: '/chat', - templateUrl: 'modules/chat/views/chat.client.view.html', - data: { - roles: ['user', 'admin'] - } - }); - } + function ($stateProvider) { + $stateProvider + .state('chat', { + url: '/chat', + templateUrl: 'modules/chat/views/chat.client.view.html', + data: { + roles: ['user', 'admin'] + } + }); + } ]); diff --git a/modules/chat/client/controllers/chat.client.controller.js b/modules/chat/client/controllers/chat.client.controller.js index 8ce1c9e5c2..edb9b2727f 100644 --- a/modules/chat/client/controllers/chat.client.controller.js +++ b/modules/chat/client/controllers/chat.client.controller.js @@ -2,41 +2,42 @@ // Create the 'chat' controller angular.module('chat').controller('ChatController', ['$scope', '$location', 'Authentication', 'Socket', - function($scope, $location, Authentication, Socket) { - // Create a messages array - $scope.messages = []; - - // If user is not signed in then redirect back home - if (!Authentication.user) $location.path('/'); - - // Make sure the Socket is connected - if (!Socket.socket) { - Socket.connect(); - } - - // Add an event listener to the 'chatMessage' event - Socket.on('chatMessage', function(message) { - $scope.messages.unshift(message); - }); - - // Create a controller method for sending messages - $scope.sendMessage = function() { - // Create a new message object - var message = { - text: this.messageText - }; - - // Emit a 'chatMessage' message event - Socket.emit('chatMessage', message); - - // Clear the message text - this.messageText = ''; - }; - - // Remove the event listener when the controller instance is destroyed - $scope.$on('$destroy', function() { - Socket.removeListener('chatMessage'); - }); + function ($scope, $location, Authentication, Socket) { + // Create a messages array + $scope.messages = []; + // If user is not signed in then redirect back home + if (!Authentication.user) { + $location.path('/'); } -]); + + // Make sure the Socket is connected + if (!Socket.socket) { + Socket.connect(); + } + + // Add an event listener to the 'chatMessage' event + Socket.on('chatMessage', function (message) { + $scope.messages.unshift(message); + }); + + // Create a controller method for sending messages + $scope.sendMessage = function () { + // Create a new message object + var message = { + text: this.messageText + }; + + // Emit a 'chatMessage' message event + Socket.emit('chatMessage', message); + + // Clear the message text + this.messageText = ''; + }; + + // Remove the event listener when the controller instance is destroyed + $scope.$on('$destroy', function () { + Socket.removeListener('chatMessage'); + }); + } +]); diff --git a/modules/chat/client/css/chat.css b/modules/chat/client/css/chat.css index d04a8689e3..a64df1fa64 100644 --- a/modules/chat/client/css/chat.css +++ b/modules/chat/client/css/chat.css @@ -1,18 +1,15 @@ .chat-message { - margin-top: 10px; - padding-top: 10px; + margin-top: 10px; + padding-top: 10px; } - .chat-message:not(:first-child) { - border-top: 1px solid #e7e7e7; + border-top: 1px solid #e7e7e7; } - .chat-message-details { - margin-left: 10px; + margin-left: 10px; } - .chat-profile-image { - height: 28px; - width: 28px; - border-radius: 50%; + height: 28px; + width: 28px; + border-radius: 50%; } diff --git a/modules/chat/client/views/chat.client.view.html b/modules/chat/client/views/chat.client.view.html index c3cd60190b..7f072c9f22 100644 --- a/modules/chat/client/views/chat.client.view.html +++ b/modules/chat/client/views/chat.client.view.html @@ -1,28 +1,29 @@
- - -
-
-
- - - - -
-
-
-
    + + +
    +
    +
    + + + + +
    +
    +
    +
    • - - {{message.username}} -
      -
      - -
      + + {{message.username}} +
      + +
      + +
    • -
    +
diff --git a/modules/chat/server/sockets/chat.server.socket.config.js b/modules/chat/server/sockets/chat.server.socket.config.js index d48791d66d..8bb88db80f 100644 --- a/modules/chat/server/sockets/chat.server.socket.config.js +++ b/modules/chat/server/sockets/chat.server.socket.config.js @@ -1,34 +1,34 @@ 'use strict'; // Create the chat configuration -module.exports = function(io, socket) { - // Emit the status event when a new socket client is connected - io.emit('chatMessage', { - type: 'status', - text: 'Is now connected', - created: Date.now(), - profileImageURL: socket.request.user.profileImageURL, - username: socket.request.user.username - }); +module.exports = function (io, socket) { + // Emit the status event when a new socket client is connected + io.emit('chatMessage', { + type: 'status', + text: 'Is now connected', + created: Date.now(), + profileImageURL: socket.request.user.profileImageURL, + username: socket.request.user.username + }); - // Send a chat messages to all connected sockets when a message is received - socket.on('chatMessage', function(message) { - message.type = 'message'; - message.created = Date.now(); - message.profileImageURL = socket.request.user.profileImageURL; - message.username = socket.request.user.username; + // Send a chat messages to all connected sockets when a message is received + socket.on('chatMessage', function (message) { + message.type = 'message'; + message.created = Date.now(); + message.profileImageURL = socket.request.user.profileImageURL; + message.username = socket.request.user.username; - // Emit the 'chatMessage' event - io.emit('chatMessage', message); - }); + // Emit the 'chatMessage' event + io.emit('chatMessage', message); + }); - // Emit the status event when a socket client is disconnected - socket.on('disconnect', function() { - io.emit('chatMessage', { - type: 'status', - text: 'disconnected', - created: Date.now(), - username: socket.request.user.username - }); + // Emit the status event when a socket client is disconnected + socket.on('disconnect', function () { + io.emit('chatMessage', { + type: 'status', + text: 'disconnected', + created: Date.now(), + username: socket.request.user.username }); + }); }; diff --git a/modules/chat/tests/client/chat.client.controller.tests.js b/modules/chat/tests/client/chat.client.controller.tests.js index cf677b0220..23c3e31f6d 100644 --- a/modules/chat/tests/client/chat.client.controller.tests.js +++ b/modules/chat/tests/client/chat.client.controller.tests.js @@ -3,8 +3,8 @@ /** * Chat client controller tests */ -(function() { - describe('ChatController', function() { +(function () { + describe('ChatController', function () { //Initialize global variables var scope, Socket, @@ -16,7 +16,7 @@ // Load the main application module beforeEach(module(ApplicationConfiguration.applicationModuleName)); - beforeEach(inject(function($controller, $rootScope, _Socket_, _Authentication_, _$timeout_, _$location_) { + beforeEach(inject(function ($controller, $rootScope, _Socket_, _Authentication_, _$timeout_, _$location_) { scope = $rootScope.$new(); Socket = _Socket_; $timeout = _$timeout_; @@ -24,8 +24,8 @@ Authentication = _Authentication_; })); - describe('when user logged out', function() { - beforeEach(inject(function($controller, $rootScope, _Socket_, _Authentication_, _$timeout_, _$location_) { + describe('when user logged out', function () { + beforeEach(inject(function ($controller, $rootScope, _Socket_, _Authentication_, _$timeout_, _$location_) { Authentication.user = undefined; spyOn($location, 'path'); ChatController = $controller('ChatController', { @@ -33,13 +33,13 @@ }); })); - it('should redirect logged out user to /', function() { + it('should redirect logged out user to /', function () { expect($location.path).toHaveBeenCalledWith('/'); }); }); - describe('when user logged in', function() { - beforeEach(inject(function($controller, $rootScope, _Socket_, _Authentication_, _$timeout_, _$location_) { + describe('when user logged in', function () { + beforeEach(inject(function ($controller, $rootScope, _Socket_, _Authentication_, _$timeout_, _$location_) { Authentication.user = { name: 'user', roles: ['user'] @@ -50,42 +50,42 @@ }); })); - it('should make sure socket is connected', function() { + it('should make sure socket is connected', function () { expect(Socket.socket).toBeTruthy(); }); - it('should define messages array', function() { + it('should define messages array', function () { expect(scope.messages).toBeDefined(); expect(scope.messages.length).toBe(0); }); - describe('sendMessage', function() { + describe('sendMessage', function () { var text = 'hello world!'; - beforeEach(function() { + beforeEach(function () { scope.messageText = text; scope.sendMessage(); $timeout.flush(); }); - it('should add message to messages', function() { + it('should add message to messages', function () { expect(scope.messages.length).toBe(1); }); - it('should add message with proper text attribute set', function() { + it('should add message with proper text attribute set', function () { expect(scope.messages[0].text).toBe(text); }); - it('should clear messageText', function() { + it('should clear messageText', function () { expect(scope.messageText).toBe(''); }); }); - describe('$destroy()', function() { - beforeEach(function() { + describe('$destroy()', function () { + beforeEach(function () { scope.$destroy(); }); - it('should remove chatMessage listener', function() { + it('should remove chatMessage listener', function () { expect(Socket.socket.cbs.chatMessage).toBeUndefined(); }); }); diff --git a/modules/chat/tests/e2e/chat.e2e.tests.js b/modules/chat/tests/e2e/chat.e2e.tests.js index d3fd973c29..3b117ac146 100644 --- a/modules/chat/tests/e2e/chat.e2e.tests.js +++ b/modules/chat/tests/e2e/chat.e2e.tests.js @@ -3,6 +3,6 @@ /** * Chat e2e tests */ -describe('Chat E2E Tests:', function() { - // TODO: Add chat e2e tests +describe('Chat E2E Tests:', function () { + // TODO: Add chat e2e tests }); diff --git a/modules/chat/tests/server/chat.socket.tests.js b/modules/chat/tests/server/chat.socket.tests.js index f900e2f626..21f94e4056 100644 --- a/modules/chat/tests/server/chat.socket.tests.js +++ b/modules/chat/tests/server/chat.socket.tests.js @@ -3,6 +3,6 @@ /** * Chat socket tests */ -describe('Chat Socket Tests:', function() { - // TODO: Add chat socket tests +describe('Chat Socket Tests:', function () { + // TODO: Add chat socket tests }); diff --git a/modules/core/client/app/config.js b/modules/core/client/app/config.js index b4b5947cd3..98b48bffff 100644 --- a/modules/core/client/app/config.js +++ b/modules/core/client/app/config.js @@ -1,23 +1,23 @@ 'use strict'; // Init the application configuration module for AngularJS application -var ApplicationConfiguration = (function() { - // Init module configuration options - var applicationModuleName = 'mean'; - var applicationModuleVendorDependencies = ['ngResource', 'ngAnimate', 'ui.router', 'ui.bootstrap', 'ui.utils', 'angularFileUpload']; +var ApplicationConfiguration = (function () { + // Init module configuration options + var applicationModuleName = 'mean'; + var applicationModuleVendorDependencies = ['ngResource', 'ngAnimate', 'ui.router', 'ui.bootstrap', 'ui.utils', 'angularFileUpload']; - // Add a new vertical module - var registerModule = function(moduleName, dependencies) { - // Create angular module - angular.module(moduleName, dependencies || []); + // Add a new vertical module + var registerModule = function (moduleName, dependencies) { + // Create angular module + angular.module(moduleName, dependencies || []); - // Add the module to the AngularJS configuration file - angular.module(applicationModuleName).requires.push(moduleName); - }; + // Add the module to the AngularJS configuration file + angular.module(applicationModuleName).requires.push(moduleName); + }; - return { - applicationModuleName: applicationModuleName, - applicationModuleVendorDependencies: applicationModuleVendorDependencies, - registerModule: registerModule - }; + return { + applicationModuleName: applicationModuleName, + applicationModuleVendorDependencies: applicationModuleVendorDependencies, + registerModule: registerModule + }; })(); diff --git a/modules/core/client/app/init.js b/modules/core/client/app/init.js index c05d9ea3d6..33470bae9a 100644 --- a/modules/core/client/app/init.js +++ b/modules/core/client/app/init.js @@ -5,48 +5,51 @@ angular.module(ApplicationConfiguration.applicationModuleName, ApplicationConfig // Setting HTML5 Location Mode angular.module(ApplicationConfiguration.applicationModuleName).config(['$locationProvider', - function($locationProvider) { - $locationProvider.html5Mode(true).hashPrefix('!'); - } + function ($locationProvider) { + $locationProvider.html5Mode(true).hashPrefix('!'); + } ]); -angular.module(ApplicationConfiguration.applicationModuleName).run(function($rootScope, $state, Authentication) { - // Check authentication before changing state - $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) { - if (toState.data && toState.data.roles && toState.data.roles.length > 0) { - var allowed = false; - toState.data.roles.forEach(function (role) { - if (Authentication.user.roles !== undefined && Authentication.user.roles.indexOf(role) !== -1) { - allowed = true; - return true; - } - }); - - if (!allowed) { - event.preventDefault(); - $state.go('authentication.signin', {}, { - notify: false - }).then(function() { - $rootScope.$broadcast('$stateChangeSuccess', 'authentication.signin', {}, toState, toParams); - }); - } +angular.module(ApplicationConfiguration.applicationModuleName).run(function ($rootScope, $state, Authentication) { + // Check authentication before changing state + $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) { + if (toState.data && toState.data.roles && toState.data.roles.length > 0) { + var allowed = false; + toState.data.roles.forEach(function (role) { + if (Authentication.user.roles !== undefined && Authentication.user.roles.indexOf(role) !== -1) { + allowed = true; + return true; } - }); - // Record previous state - $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) { - $state.previous = { - state: fromState, - params: fromParams, - href: $state.href(fromState, fromParams) - }; - }); + }); + + if (!allowed) { + event.preventDefault(); + $state.go('authentication.signin', {}, { + notify: false + }).then(function () { + $rootScope.$broadcast('$stateChangeSuccess', 'authentication.signin', {}, toState, toParams); + }); + } + } + }); + + // Record previous state + $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) { + $state.previous = { + state: fromState, + params: fromParams, + href: $state.href(fromState, fromParams) + }; + }); }); //Then define the init function for starting up the application -angular.element(document).ready(function() { - //Fixing facebook bug with redirect - if (window.location.hash === '#_=_') window.location.hash = '#!'; +angular.element(document).ready(function () { + //Fixing facebook bug with redirect + if (window.location.hash === '#_=_') { + window.location.hash = '#!'; + } - //Then init the app - angular.bootstrap(document, [ApplicationConfiguration.applicationModuleName]); + //Then init the app + angular.bootstrap(document, [ApplicationConfiguration.applicationModuleName]); }); diff --git a/modules/core/client/config/core-admin.client.menus.js b/modules/core/client/config/core-admin.client.menus.js index a2afa83668..b048f6f020 100644 --- a/modules/core/client/config/core-admin.client.menus.js +++ b/modules/core/client/config/core-admin.client.menus.js @@ -1,12 +1,12 @@ 'use strict'; angular.module('core.admin').run(['Menus', - function (Menus) { - Menus.addMenuItem('topbar', { - title: 'Admin', - state: 'admin', - type: 'dropdown', - roles: ['admin'] - }); - } + function (Menus) { + Menus.addMenuItem('topbar', { + title: 'Admin', + state: 'admin', + type: 'dropdown', + roles: ['admin'] + }); + } ]); diff --git a/modules/core/client/config/core-admin.client.routes.js b/modules/core/client/config/core-admin.client.routes.js index 1697246fa7..b7f5f45a6d 100644 --- a/modules/core/client/config/core-admin.client.routes.js +++ b/modules/core/client/config/core-admin.client.routes.js @@ -2,15 +2,15 @@ // Setting up route angular.module('core.admin.routes').config(['$stateProvider', - function ($stateProvider) { - $stateProvider - .state('admin', { - abstract: true, - url: '/admin', - template: '', - data: { - roles: ['admin'] - } - }); - } + function ($stateProvider) { + $stateProvider + .state('admin', { + abstract: true, + url: '/admin', + template: '', + data: { + roles: ['admin'] + } + }); + } ]); diff --git a/modules/core/client/config/core.client.routes.js b/modules/core/client/config/core.client.routes.js index fe5692bd35..e9e64c82cf 100644 --- a/modules/core/client/config/core.client.routes.js +++ b/modules/core/client/config/core.client.routes.js @@ -2,20 +2,20 @@ // Setting up route angular.module('core').config(['$stateProvider', '$urlRouterProvider', - function($stateProvider, $urlRouterProvider) { + function ($stateProvider, $urlRouterProvider) { - // Redirect to 404 when route not found - $urlRouterProvider.otherwise('not-found'); + // Redirect to 404 when route not found + $urlRouterProvider.otherwise('not-found'); - // Home state routing - $stateProvider. - state('home', { - url: '/', - templateUrl: 'modules/core/views/home.client.view.html' - }). - state('not-found', { - url: '/not-found', - templateUrl: 'modules/core/views/404.client.view.html' - }); - } + // Home state routing + $stateProvider + .state('home', { + url: '/', + templateUrl: 'modules/core/views/home.client.view.html' + }) + .state('not-found', { + url: '/not-found', + templateUrl: 'modules/core/views/404.client.view.html' + }); + } ]); diff --git a/modules/core/client/controllers/header.client.controller.js b/modules/core/client/controllers/header.client.controller.js index 64c3019724..e688ad3c96 100644 --- a/modules/core/client/controllers/header.client.controller.js +++ b/modules/core/client/controllers/header.client.controller.js @@ -1,23 +1,23 @@ 'use strict'; angular.module('core').controller('HeaderController', ['$scope', '$state', 'Authentication', 'Menus', - function($scope, $state, Authentication, Menus) { - // Expose view variables - $scope.$state = $state; - $scope.authentication = Authentication; + function ($scope, $state, Authentication, Menus) { + // Expose view variables + $scope.$state = $state; + $scope.authentication = Authentication; - // Get the topbar menu - $scope.menu = Menus.getMenu('topbar'); + // Get the topbar menu + $scope.menu = Menus.getMenu('topbar'); - // Toggle the menu items - $scope.isCollapsed = false; - $scope.toggleCollapsibleMenu = function() { - $scope.isCollapsed = !$scope.isCollapsed; - }; + // Toggle the menu items + $scope.isCollapsed = false; + $scope.toggleCollapsibleMenu = function () { + $scope.isCollapsed = !$scope.isCollapsed; + }; - // Collapsing the menu after navigation - $scope.$on('$stateChangeSuccess', function() { - $scope.isCollapsed = false; - }); - } + // Collapsing the menu after navigation + $scope.$on('$stateChangeSuccess', function () { + $scope.isCollapsed = false; + }); + } ]); diff --git a/modules/core/client/controllers/home.client.controller.js b/modules/core/client/controllers/home.client.controller.js index ea80b59e60..a76343c7f1 100644 --- a/modules/core/client/controllers/home.client.controller.js +++ b/modules/core/client/controllers/home.client.controller.js @@ -1,8 +1,8 @@ 'use strict'; angular.module('core').controller('HomeController', ['$scope', 'Authentication', - function($scope, Authentication) { - // This provides Authentication context. - $scope.authentication = Authentication; - } + function ($scope, Authentication) { + // This provides Authentication context. + $scope.authentication = Authentication; + } ]); diff --git a/modules/core/client/css/core.css b/modules/core/client/css/core.css index e89af83986..861e085d37 100644 --- a/modules/core/client/css/core.css +++ b/modules/core/client/css/core.css @@ -1,33 +1,35 @@ .content { - margin-top: 50px; + margin-top: 50px; } .undecorated-link:hover { - text-decoration: none; + text-decoration: none; } -[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { - display: none !important; +[ng\:cloak], +[ng-cloak], +[data-ng-cloak], +[x-ng-cloak], +.ng-cloak, +.x-ng-cloak { + display: none !important; } -.ng-invalid.ng-dirty{ - border-color:#FA787E; +.ng-invalid.ng-dirty { + border-color: #FA787E; } -.ng-valid.ng-dirty{ - border-color:#78FA89; +.ng-valid.ng-dirty { + border-color: #78FA89; } - .header-profile-image { - opacity: 0.8; - height: 28px; - width: 28px; - border-radius: 50%; - margin-right: 5px; -} - -.open .header-profile-image, + opacity: 0.8; + height: 28px; + width: 28px; + border-radius: 50%; + margin-right: 5px; +} +.open .header-profile-image, a:hover .header-profile-image { - opacity: 1; + opacity: 1; } - .user-header-dropdown-toggle { - padding-top: 11px !important; - padding-bottom: 11px !important; + padding-top: 11px !important; + padding-bottom: 11px !important; } diff --git a/modules/core/client/services/menus.client.service.js b/modules/core/client/services/menus.client.service.js index cac12a4419..df9b5eafe2 100644 --- a/modules/core/client/services/menus.client.service.js +++ b/modules/core/client/services/menus.client.service.js @@ -2,8 +2,7 @@ //Menu service used for managing menus angular.module('core').service('Menus', [ - - function() { + function () { // Define a set of default roles this.defaultRoles = ['*']; @@ -11,7 +10,7 @@ angular.module('core').service('Menus', [ this.menus = {}; // A private function for rendering decision - var shouldRender = function(user) { + var shouldRender = function (user) { if (user) { if (!!~this.roles.indexOf('*')) { return true; @@ -32,7 +31,7 @@ angular.module('core').service('Menus', [ }; // Validate menu existance - this.validateMenuExistance = function(menuId) { + this.validateMenuExistance = function (menuId) { if (menuId && menuId.length) { if (this.menus[menuId]) { return true; @@ -42,10 +41,12 @@ angular.module('core').service('Menus', [ } else { throw new Error('MenuId was not provided'); } + + return false; }; // Get the menu object by menu id - this.getMenu = function(menuId) { + this.getMenu = function (menuId) { // Validate that the menu exists this.validateMenuExistance(menuId); @@ -54,7 +55,7 @@ angular.module('core').service('Menus', [ }; // Add new menu object by menu id - this.addMenu = function(menuId, options) { + this.addMenu = function (menuId, options) { options = options || {}; // Create the new menu @@ -70,7 +71,7 @@ angular.module('core').service('Menus', [ }; // Remove existing menu object by menu id - this.removeMenu = function(menuId) { + this.removeMenu = function (menuId) { // Validate that the menu exists this.validateMenuExistance(menuId); @@ -79,7 +80,7 @@ angular.module('core').service('Menus', [ }; // Add menu item object - this.addMenuItem = function(menuId, options) { + this.addMenuItem = function (menuId, options) { options = options || {}; // Validate that the menu exists @@ -110,7 +111,7 @@ angular.module('core').service('Menus', [ }; // Add submenu item object - this.addSubMenuItem = function(menuId, parentItemState, options) { + this.addSubMenuItem = function (menuId, parentItemState, options) { options = options || {}; // Validate that the menu exists @@ -136,7 +137,7 @@ angular.module('core').service('Menus', [ }; // Remove existing menu object by menu id - this.removeMenuItem = function(menuId, menuItemURL) { + this.removeMenuItem = function (menuId, menuItemURL) { // Validate that the menu exists this.validateMenuExistance(menuId); @@ -152,7 +153,7 @@ angular.module('core').service('Menus', [ }; // Remove existing menu object by menu id - this.removeSubMenuItem = function(menuId, submenuItemURL) { + this.removeSubMenuItem = function (menuId, submenuItemURL) { // Validate that the menu exists this.validateMenuExistance(menuId); diff --git a/modules/core/client/services/socket.io.client.service.js b/modules/core/client/services/socket.io.client.service.js index 6f47bd6863..7031a0d2de 100644 --- a/modules/core/client/services/socket.io.client.service.js +++ b/modules/core/client/services/socket.io.client.service.js @@ -2,40 +2,39 @@ // Create the Socket.io wrapper service angular.module('core').service('Socket', ['Authentication', '$state', '$timeout', - function(Authentication, $state, $timeout) { - - // Connect to Socket.io server - this.connect = function () { - // Connect only when authenticated - if (Authentication.user) { - this.socket = io(); - } - }; - this.connect(); + function (Authentication, $state, $timeout) { + // Connect to Socket.io server + this.connect = function () { + // Connect only when authenticated + if (Authentication.user) { + this.socket = io(); + } + }; + this.connect(); - // Wrap the Socket.io 'on' method - this.on = function(eventName, callback) { - if (this.socket) { - this.socket.on(eventName, function(data) { - $timeout(function() { - callback(data); - }); - }); - } - }; + // Wrap the Socket.io 'on' method + this.on = function (eventName, callback) { + if (this.socket) { + this.socket.on(eventName, function (data) { + $timeout(function () { + callback(data); + }); + }); + } + }; - // Wrap the Socket.io 'emit' method - this.emit = function(eventName, data) { - if (this.socket) { - this.socket.emit(eventName, data); - } - }; + // Wrap the Socket.io 'emit' method + this.emit = function (eventName, data) { + if (this.socket) { + this.socket.emit(eventName, data); + } + }; - // Wrap the Socket.io 'removeListener' method - this.removeListener = function(eventName) { - if (this.socket) { - this.socket.removeListener(eventName); - } - }; - } + // Wrap the Socket.io 'removeListener' method + this.removeListener = function (eventName) { + if (this.socket) { + this.socket.removeListener(eventName); + } + }; + } ]); diff --git a/modules/core/client/views/404.client.view.html b/modules/core/client/views/404.client.view.html index 6e79d29f44..e8e6d82cc1 100644 --- a/modules/core/client/views/404.client.view.html +++ b/modules/core/client/views/404.client.view.html @@ -1,6 +1,5 @@

Page Not Found

diff --git a/modules/core/client/views/header.client.view.html b/modules/core/client/views/header.client.view.html index 486b104219..94d2dd9aee 100644 --- a/modules/core/client/views/header.client.view.html +++ b/modules/core/client/views/header.client.view.html @@ -1,59 +1,59 @@
- - + +
diff --git a/modules/core/client/views/home.client.view.html b/modules/core/client/views/home.client.view.html index d257916f03..b34905cdfc 100644 --- a/modules/core/client/views/home.client.view.html +++ b/modules/core/client/views/home.client.view.html @@ -1,94 +1,84 @@
-
-
-
- MEAN.JS -
-
-
-
-

- Open-Source Full-Stack Solution For MEAN Applications -

-
-
-

- Learn more -

-
-
-
-

Congrats! You've configured and run the sample application.

-

MEAN.JS is a web application boilerplate, which means you should start changing everything :-)

-

This sample application tracks users and articles.

-
    -
  • - Click - Signup - to get started. -
  • -
  • - Configure your app to work with your social accounts, by editing the - /config/env/*.js - files. -
  • -
  • - Edit your users module. -
  • -
  • - Add new CRUD modules. -
  • -
  • - Have fun... -
  • -
-
-
-
-

- MongoDB -

-

MongoDB is a database. MongoDB's great manual is the place to get started with NoSQL and MongoDB.

-
-
-

- Express -

-

Express is an app server. Check out The ExpressJS API reference for more information or StackOverflow for more info.

-
-
-

- AngularJS -

-

AngularJS is web app framework. Angular's website offers a lot. The Thinkster Popular Guide and Egghead Videos are great resources.

-
-
-

- Node.js -

-

Node.js is a web server. Node's website and this stackOverflow thread offer excellent starting points to get to grasps with node.

-
-
-
-

MEAN.JS Documentation

-

- Once you're familiar with the foundation technology, check out the MEAN.JS Documentation: -

-

-
-
Enjoy & Keep Us Updated, -
The MEAN.JS Team. +
  • Modules +
  • +
  • Changelog +
  • +
  • Community +
  • +
  • Blog +
  • + +

    + +
    Enjoy & Keep Us Updated, +
    The MEAN.JS Team.
    diff --git a/modules/core/server/controllers/core.server.controller.js b/modules/core/server/controllers/core.server.controller.js index 45d5d76468..0f216b8063 100644 --- a/modules/core/server/controllers/core.server.controller.js +++ b/modules/core/server/controllers/core.server.controller.js @@ -3,38 +3,40 @@ /** * Render the main application page */ -exports.renderIndex = function(req, res) { - res.render('modules/core/server/views/index', { - user: req.user || null - }); +exports.renderIndex = function (req, res) { + res.render('modules/core/server/views/index', { + user: req.user || null + }); }; /** * Render the server error page */ -exports.renderServerError = function(req, res) { - res.status(500).render('modules/core/server/views/500', { - error: 'Oops! Something went wrong...' - }); +exports.renderServerError = function (req, res) { + res.status(500).render('modules/core/server/views/500', { + error: 'Oops! Something went wrong...' + }); }; /** * Render the server not found responses * Performs content-negotiation on the Accept HTTP header */ -exports.renderNotFound = function(req, res) { +exports.renderNotFound = function (req, res) { - res.status(404).format({ - 'text/html': function(){ - res.render('modules/core/server/views/404', { - url: req.originalUrl - }); - }, - 'application/json': function(){ - res.json({ error: 'Path not found' }); - }, - 'default': function(){ - res.send('Path not found'); - } - }); + res.status(404).format({ + 'text/html': function () { + res.render('modules/core/server/views/404', { + url: req.originalUrl + }); + }, + 'application/json': function () { + res.json({ + error: 'Path not found' + }); + }, + 'default': function () { + res.send('Path not found'); + } + }); }; diff --git a/modules/core/server/controllers/errors.server.controller.js b/modules/core/server/controllers/errors.server.controller.js index fd06d70f8e..f0b96bdfb7 100644 --- a/modules/core/server/controllers/errors.server.controller.js +++ b/modules/core/server/controllers/errors.server.controller.js @@ -3,40 +3,42 @@ /** * Get unique error field name */ -var getUniqueErrorMessage = function(err) { - var output; +var getUniqueErrorMessage = function (err) { + var output; - try { - var fieldName = err.errmsg.substring(err.errmsg.lastIndexOf('.$') + 2, err.errmsg.lastIndexOf('_1')); - output = fieldName.charAt(0).toUpperCase() + fieldName.slice(1) + ' already exists'; + try { + var fieldName = err.errmsg.substring(err.errmsg.lastIndexOf('.$') + 2, err.errmsg.lastIndexOf('_1')); + output = fieldName.charAt(0).toUpperCase() + fieldName.slice(1) + ' already exists'; - } catch(ex) { - output = 'Unique field already exists'; - } + } catch (ex) { + output = 'Unique field already exists'; + } - return output; + return output; }; /** * Get the error message from error object */ -exports.getErrorMessage = function(err) { - var message = ''; - - if (err.code) { - switch (err.code) { - case 11000: - case 11001: - message = getUniqueErrorMessage(err); - break; - default: - message = 'Something went wrong'; - } - } else { - for (var errName in err.errors) { - if (err.errors[errName].message) message = err.errors[errName].message; - } - } +exports.getErrorMessage = function (err) { + var message = ''; - return message; + if (err.code) { + switch (err.code) { + case 11000: + case 11001: + message = getUniqueErrorMessage(err); + break; + default: + message = 'Something went wrong'; + } + } else { + for (var errName in err.errors) { + if (err.errors[errName].message) { + message = err.errors[errName].message; + } + } + } + + return message; }; diff --git a/modules/core/server/routes/core.server.routes.js b/modules/core/server/routes/core.server.routes.js index d58861fc91..d4e546131e 100644 --- a/modules/core/server/routes/core.server.routes.js +++ b/modules/core/server/routes/core.server.routes.js @@ -1,15 +1,15 @@ 'use strict'; -module.exports = function(app) { - // Root routing - var core = require('../controllers/core.server.controller'); +module.exports = function (app) { + // Root routing + var core = require('../controllers/core.server.controller'); - // Define error pages - app.route('/server-error').get(core.renderServerError); + // Define error pages + app.route('/server-error').get(core.renderServerError); - // Return a 404 for all undefined api, module or lib routes - app.route('/:url(api|modules|lib)/*').get(core.renderNotFound); + // Return a 404 for all undefined api, module or lib routes + app.route('/:url(api|modules|lib)/*').get(core.renderNotFound); - // Define application route - app.route('/*').get(core.renderIndex); + // Define application route + app.route('/*').get(core.renderIndex); }; diff --git a/modules/core/server/views/404.server.view.html b/modules/core/server/views/404.server.view.html index 94e371926a..d5c785f63a 100644 --- a/modules/core/server/views/404.server.view.html +++ b/modules/core/server/views/404.server.view.html @@ -3,8 +3,8 @@ {% block content %}

    Page Not Found

    {% endblock %} diff --git a/modules/core/server/views/500.server.view.html b/modules/core/server/views/500.server.view.html index cc3b14785c..34359bfae5 100644 --- a/modules/core/server/views/500.server.view.html +++ b/modules/core/server/views/500.server.view.html @@ -3,6 +3,6 @@ {% block content %}

    Server Error

    -	{{error}}
    +  {{error}}
     
    {% endblock %} diff --git a/modules/core/server/views/index.server.view.html b/modules/core/server/views/index.server.view.html index 7e60893b1f..8a94dc81b1 100644 --- a/modules/core/server/views/index.server.view.html +++ b/modules/core/server/views/index.server.view.html @@ -1,5 +1,5 @@ {% extends 'layout.server.view.html' %} {% block content %} -
    +
    {% endblock %} diff --git a/modules/core/server/views/layout.server.view.html b/modules/core/server/views/layout.server.view.html index 20d52a519b..7f8c83934f 100644 --- a/modules/core/server/views/layout.server.view.html +++ b/modules/core/server/views/layout.server.view.html @@ -1,63 +1,63 @@ - - - - - {{title}} - - - - - - - - - - - - - - - - - - - - - - - - - - - {% for cssFile in cssFiles %}{% endfor %} + + + + + {{title}} + + + + + + + + + + + + + + + + + + + + + + + + + + + {% for cssFile in cssFiles %}{% endfor %} - -
    -
    - {% block content %}{% endblock %} -
    -
    - - - - - - - - - {% for jsFile in jsFiles %}{% endfor %} - - {% if livereload %} - - - {% endif %} + +
    +
    + {% block content %}{% endblock %} +
    +
    + + + + + + + + + {% for jsFile in jsFiles %}{% endfor %} + + {% if livereload %} + + + {% endif %} diff --git a/modules/core/tests/client/core.client.tests.js b/modules/core/tests/client/core.client.tests.js index dcc095b6e3..655f5c68a1 100644 --- a/modules/core/tests/client/core.client.tests.js +++ b/modules/core/tests/client/core.client.tests.js @@ -1,7 +1,7 @@ 'use strict'; -(function() { - beforeAll(function() { +(function () { + beforeAll(function () { angular.element(document.querySelector('head')).append(''); }); -}()); \ No newline at end of file +}()); diff --git a/modules/core/tests/client/header.client.controller.tests.js b/modules/core/tests/client/header.client.controller.tests.js index 3b193f688f..569e3c6e82 100644 --- a/modules/core/tests/client/header.client.controller.tests.js +++ b/modules/core/tests/client/header.client.controller.tests.js @@ -1,7 +1,7 @@ 'use strict'; -(function() { - describe('HeaderController', function() { +(function () { + describe('HeaderController', function () { //Initialize global variables var scope, HeaderController, @@ -11,7 +11,7 @@ // Load the main application module beforeEach(module(ApplicationConfiguration.applicationModuleName)); - beforeEach(inject(function($controller, $rootScope, _$state_, _Authentication_) { + beforeEach(inject(function ($controller, $rootScope, _$state_, _Authentication_) { scope = $rootScope.$new(); $state = _$state_; Authentication = _Authentication_; @@ -21,42 +21,42 @@ }); })); - it('should expose the authentication service', function() { + it('should expose the authentication service', function () { expect(scope.authentication).toBe(Authentication); }); - it('should expose the $state service', function() { + it('should expose the $state service', function () { expect(scope.$state).toBe($state); }); - it('should default menu to collapsed', function() { + it('should default menu to collapsed', function () { expect(scope.isCollapsed).toBeFalsy(); }); - describe('when toggleCollapsibleMenu', function() { + describe('when toggleCollapsibleMenu', function () { var defaultCollapse; - beforeEach(function() { + beforeEach(function () { defaultCollapse = scope.isCollapsed; scope.toggleCollapsibleMenu(); }); - it('should toggle isCollapsed to non default value', function() { + it('should toggle isCollapsed to non default value', function () { expect(scope.isCollapsed).not.toBe(defaultCollapse); }); - it('should then toggle isCollapsed back to default value', function() { + it('should then toggle isCollapsed back to default value', function () { scope.toggleCollapsibleMenu(); expect(scope.isCollapsed).toBe(defaultCollapse); }); }); - describe('when view state changes', function() { - beforeEach(function() { + describe('when view state changes', function () { + beforeEach(function () { scope.isCollapsed = true; scope.$broadcast('$stateChangeSuccess'); }); - it('should set isCollapsed to false', function() { + it('should set isCollapsed to false', function () { expect(scope.isCollapsed).toBeFalsy(); }); }); diff --git a/modules/core/tests/client/home.client.controller.tests.js b/modules/core/tests/client/home.client.controller.tests.js index b83b12d736..b6db0cb919 100644 --- a/modules/core/tests/client/home.client.controller.tests.js +++ b/modules/core/tests/client/home.client.controller.tests.js @@ -1,24 +1,24 @@ 'use strict'; -(function() { - describe('HomeController', function() { - //Initialize global variables - var scope, - HomeController; +(function () { + describe('HomeController', function () { + //Initialize global variables + var scope, + HomeController; - // Load the main application module - beforeEach(module(ApplicationConfiguration.applicationModuleName)); + // Load the main application module + beforeEach(module(ApplicationConfiguration.applicationModuleName)); - beforeEach(inject(function($controller, $rootScope) { - scope = $rootScope.$new(); + beforeEach(inject(function ($controller, $rootScope) { + scope = $rootScope.$new(); - HomeController = $controller('HomeController', { - $scope: scope - }); - })); + HomeController = $controller('HomeController', { + $scope: scope + }); + })); - it('should expose the authentication service', function() { - expect(scope.authentication).toBeTruthy(); - }); - }); + it('should expose the authentication service', function () { + expect(scope.authentication).toBeTruthy(); + }); + }); })(); diff --git a/modules/users/client/config/users-admin.client.menus.js b/modules/users/client/config/users-admin.client.menus.js index 33f998ae8f..eda2af52c0 100644 --- a/modules/users/client/config/users-admin.client.menus.js +++ b/modules/users/client/config/users-admin.client.menus.js @@ -2,10 +2,10 @@ // Configuring the Articles module angular.module('users.admin').run(['Menus', - function (Menus) { - Menus.addSubMenuItem('topbar', 'admin', { - title: 'Manage Users', - state: 'admin.users' - }); - } + function (Menus) { + Menus.addSubMenuItem('topbar', 'admin', { + title: 'Manage Users', + state: 'admin.users' + }); + } ]); diff --git a/modules/users/client/config/users-admin.client.routes.js b/modules/users/client/config/users-admin.client.routes.js index 8cf34221d0..fc9cb42d23 100644 --- a/modules/users/client/config/users-admin.client.routes.js +++ b/modules/users/client/config/users-admin.client.routes.js @@ -2,36 +2,36 @@ // Setting up route angular.module('users.admin.routes').config(['$stateProvider', - function ($stateProvider) { - $stateProvider - .state('admin.users', { - url: '/users', - templateUrl: 'modules/users/views/admin/user-list.client.view.html', - controller: 'UserListController' - }) - .state('admin.user', { - url: '/users/:userId', - templateUrl: 'modules/users/views/admin/user.client.view.html', - controller: 'UserController', - resolve: { - userResolve: ['$stateParams', 'Admin', function ($stateParams, Admin) { - return Admin.get({ - userId: $stateParams.userId - }); - }] - } - }) - .state('admin.user-edit', { - url: '/users/:userId/edit', - templateUrl: 'modules/users/views/admin/user-edit.client.view.html', - controller: 'UserController', - resolve: { - userResolve: ['$stateParams', 'Admin', function ($stateParams, Admin) { - return Admin.get({ - userId: $stateParams.userId - }); - }] - } - }); - } + function ($stateProvider) { + $stateProvider + .state('admin.users', { + url: '/users', + templateUrl: 'modules/users/views/admin/user-list.client.view.html', + controller: 'UserListController' + }) + .state('admin.user', { + url: '/users/:userId', + templateUrl: 'modules/users/views/admin/user.client.view.html', + controller: 'UserController', + resolve: { + userResolve: ['$stateParams', 'Admin', function ($stateParams, Admin) { + return Admin.get({ + userId: $stateParams.userId + }); + }] + } + }) + .state('admin.user-edit', { + url: '/users/:userId/edit', + templateUrl: 'modules/users/views/admin/user-edit.client.view.html', + controller: 'UserController', + resolve: { + userResolve: ['$stateParams', 'Admin', function ($stateParams, Admin) { + return Admin.get({ + userId: $stateParams.userId + }); + }] + } + }); + } ]); diff --git a/modules/users/client/config/users.client.config.js b/modules/users/client/config/users.client.config.js index 19d2c115e1..33e950713d 100644 --- a/modules/users/client/config/users.client.config.js +++ b/modules/users/client/config/users.client.config.js @@ -2,29 +2,29 @@ // Config HTTP Error Handling angular.module('users').config(['$httpProvider', - function ($httpProvider) { - // Set the httpProvider "not authorized" interceptor - $httpProvider.interceptors.push(['$q', '$location', 'Authentication', - function ($q, $location, Authentication) { - return { - responseError: function (rejection) { - switch (rejection.status) { - case 401: - // Deauthenticate the global user - Authentication.user = null; + function ($httpProvider) { + // Set the httpProvider "not authorized" interceptor + $httpProvider.interceptors.push(['$q', '$location', 'Authentication', + function ($q, $location, Authentication) { + return { + responseError: function (rejection) { + switch (rejection.status) { + case 401: + // Deauthenticate the global user + Authentication.user = null; - // Redirect to signin page - $location.path('signin'); - break; - case 403: - // Add unauthorized behaviour - break; - } + // Redirect to signin page + $location.path('signin'); + break; + case 403: + // Add unauthorized behaviour + break; + } - return $q.reject(rejection); - } - }; - } - ]); - } + return $q.reject(rejection); + } + }; + } + ]); + } ]); diff --git a/modules/users/client/config/users.client.routes.js b/modules/users/client/config/users.client.routes.js index c38632650a..b5c9efa9b9 100644 --- a/modules/users/client/config/users.client.routes.js +++ b/modules/users/client/config/users.client.routes.js @@ -2,71 +2,71 @@ // Setting up route angular.module('users').config(['$stateProvider', - function ($stateProvider) { - // Users state routing - $stateProvider. - state('settings', { - abstract: true, - url: '/settings', - templateUrl: 'modules/users/views/settings/settings.client.view.html', - data: { - roles: ['user', 'admin'] - } - }). - state('settings.profile', { - url: '/profile', - templateUrl: 'modules/users/views/settings/edit-profile.client.view.html' - }). - state('settings.password', { - url: '/password', - templateUrl: 'modules/users/views/settings/change-password.client.view.html' - }). - state('settings.accounts', { - url: '/accounts', - templateUrl: 'modules/users/views/settings/manage-social-accounts.client.view.html' - }). - state('settings.picture', { - url: '/picture', - templateUrl: 'modules/users/views/settings/change-profile-picture.client.view.html' - }). - state('authentication', { - abstract: true, - url: '/authentication', - templateUrl: 'modules/users/views/authentication/authentication.client.view.html' - }). - state('authentication.signup', { - url: '/signup', - templateUrl: 'modules/users/views/authentication/signup.client.view.html' - }). - state('authentication.signin', { - url: '/signin?err', - templateUrl: 'modules/users/views/authentication/signin.client.view.html' - }). - state('password', { - abstract: true, - url: '/password', - template: '' - }). - state('password.forgot', { - url: '/forgot', - templateUrl: 'modules/users/views/password/forgot-password.client.view.html' - }). - state('password.reset', { - abstract: true, - url: '/reset', - template: '' - }). - state('password.reset.invalid', { - url: '/invalid', - templateUrl: 'modules/users/views/password/reset-password-invalid.client.view.html' - }). - state('password.reset.success', { - url: '/success', - templateUrl: 'modules/users/views/password/reset-password-success.client.view.html' - }). - state('password.reset.form', { - url: '/:token', - templateUrl: 'modules/users/views/password/reset-password.client.view.html' - }); - } + function ($stateProvider) { + // Users state routing + $stateProvider + .state('settings', { + abstract: true, + url: '/settings', + templateUrl: 'modules/users/views/settings/settings.client.view.html', + data: { + roles: ['user', 'admin'] + } + }) + .state('settings.profile', { + url: '/profile', + templateUrl: 'modules/users/views/settings/edit-profile.client.view.html' + }) + .state('settings.password', { + url: '/password', + templateUrl: 'modules/users/views/settings/change-password.client.view.html' + }) + .state('settings.accounts', { + url: '/accounts', + templateUrl: 'modules/users/views/settings/manage-social-accounts.client.view.html' + }) + .state('settings.picture', { + url: '/picture', + templateUrl: 'modules/users/views/settings/change-profile-picture.client.view.html' + }) + .state('authentication', { + abstract: true, + url: '/authentication', + templateUrl: 'modules/users/views/authentication/authentication.client.view.html' + }) + .state('authentication.signup', { + url: '/signup', + templateUrl: 'modules/users/views/authentication/signup.client.view.html' + }) + .state('authentication.signin', { + url: '/signin?err', + templateUrl: 'modules/users/views/authentication/signin.client.view.html' + }) + .state('password', { + abstract: true, + url: '/password', + template: '' + }) + .state('password.forgot', { + url: '/forgot', + templateUrl: 'modules/users/views/password/forgot-password.client.view.html' + }) + .state('password.reset', { + abstract: true, + url: '/reset', + template: '' + }) + .state('password.reset.invalid', { + url: '/invalid', + templateUrl: 'modules/users/views/password/reset-password-invalid.client.view.html' + }) + .state('password.reset.success', { + url: '/success', + templateUrl: 'modules/users/views/password/reset-password-success.client.view.html' + }) + .state('password.reset.form', { + url: '/:token', + templateUrl: 'modules/users/views/password/reset-password.client.view.html' + }); + } ]); diff --git a/modules/users/client/controllers/admin/user-list.client.controller.js b/modules/users/client/controllers/admin/user-list.client.controller.js index a552dd0e47..0e0114947c 100644 --- a/modules/users/client/controllers/admin/user-list.client.controller.js +++ b/modules/users/client/controllers/admin/user-list.client.controller.js @@ -1,31 +1,31 @@ 'use strict'; angular.module('users.admin').controller('UserListController', ['$scope', '$filter', 'Admin', - function ($scope, $filter, Admin) { - Admin.query(function (data) { - $scope.users = data; - $scope.buildPager(); - }); + function ($scope, $filter, Admin) { + Admin.query(function (data) { + $scope.users = data; + $scope.buildPager(); + }); - $scope.buildPager = function () { - $scope.pagedItems = []; - $scope.itemsPerPage = 15; - $scope.currentPage = 1; - $scope.figureOutItemsToDisplay(); - }; + $scope.buildPager = function () { + $scope.pagedItems = []; + $scope.itemsPerPage = 15; + $scope.currentPage = 1; + $scope.figureOutItemsToDisplay(); + }; - $scope.figureOutItemsToDisplay = function () { - $scope.filteredItems = $filter('filter')($scope.users, { - $: $scope.search - }); - $scope.filterLength = $scope.filteredItems.length; - var begin = (($scope.currentPage - 1) * $scope.itemsPerPage); - var end = begin + $scope.itemsPerPage; - $scope.pagedItems = $scope.filteredItems.slice(begin, end); - }; + $scope.figureOutItemsToDisplay = function () { + $scope.filteredItems = $filter('filter')($scope.users, { + $: $scope.search + }); + $scope.filterLength = $scope.filteredItems.length; + var begin = (($scope.currentPage - 1) * $scope.itemsPerPage); + var end = begin + $scope.itemsPerPage; + $scope.pagedItems = $scope.filteredItems.slice(begin, end); + }; - $scope.pageChanged = function () { - $scope.figureOutItemsToDisplay(); - }; - } + $scope.pageChanged = function () { + $scope.figureOutItemsToDisplay(); + }; + } ]); diff --git a/modules/users/client/controllers/admin/user.client.controller.js b/modules/users/client/controllers/admin/user.client.controller.js index 754316ec20..22a1dd4de4 100644 --- a/modules/users/client/controllers/admin/user.client.controller.js +++ b/modules/users/client/controllers/admin/user.client.controller.js @@ -1,34 +1,34 @@ 'use strict'; angular.module('users.admin').controller('UserController', ['$scope', '$state', 'Authentication', 'userResolve', - function ($scope, $state, Authentication, userResolve) { - $scope.authentication = Authentication; - $scope.user = userResolve; + function ($scope, $state, Authentication, userResolve) { + $scope.authentication = Authentication; + $scope.user = userResolve; - $scope.remove = function (user) { - if (confirm('Are you sure you want to delete this user?')) { - if (user) { - user.$remove(); + $scope.remove = function (user) { + if (confirm('Are you sure you want to delete this user?')) { + if (user) { + user.$remove(); - $scope.users.splice($scope.users.indexOf(user), 1); - } else { - $scope.user.$remove(function () { - $state.go('admin.users'); - }); - } - } - }; + $scope.users.splice($scope.users.indexOf(user), 1); + } else { + $scope.user.$remove(function () { + $state.go('admin.users'); + }); + } + } + }; - $scope.update = function () { - var user = $scope.user; + $scope.update = function () { + var user = $scope.user; - user.$update(function () { - $state.go('admin.user', { - userId: user._id - }); - }, function (errorResponse) { - $scope.error = errorResponse.data.message; - }); - }; - } + user.$update(function () { + $state.go('admin.user', { + userId: user._id + }); + }, function (errorResponse) { + $scope.error = errorResponse.data.message; + }); + }; + } ]); diff --git a/modules/users/client/controllers/authentication.client.controller.js b/modules/users/client/controllers/authentication.client.controller.js index 469f190ee2..e0e29e918e 100644 --- a/modules/users/client/controllers/authentication.client.controller.js +++ b/modules/users/client/controllers/authentication.client.controller.js @@ -1,49 +1,51 @@ 'use strict'; angular.module('users').controller('AuthenticationController', ['$scope', '$state', '$http', '$location', '$window', 'Authentication', - function($scope, $state, $http, $location, $window, Authentication) { - $scope.authentication = Authentication; - - // Get an eventual error defined in the URL query string: - $scope.error = $location.search().err; - - // If user is signed in then redirect back home - if ($scope.authentication.user) $location.path('/'); - - $scope.signup = function() { - $http.post('/api/auth/signup', $scope.credentials).success(function(response) { - // If successful we assign the response to the global user model - $scope.authentication.user = response; - - // And redirect to the previous or home page - $state.go($state.previous.state.name || 'home', $state.previous.params); - }).error(function(response) { - $scope.error = response.message; - }); - }; - - $scope.signin = function() { - $http.post('/api/auth/signin', $scope.credentials).success(function(response) { - // If successful we assign the response to the global user model - $scope.authentication.user = response; - - // And redirect to the previous or home page - $state.go($state.previous.state.name || 'home', $state.previous.params); - }).error(function(response) { - $scope.error = response.message; - }); - }; - - // OAuth provider request - $scope.callOauthProvider = function(url) { - var redirect_to; - - if ($state.previous) { - redirect_to = $state.previous.href; - } - - // Effectively call OAuth authentication route: - $window.location.href = url + (redirect_to ? '?redirect_to=' + encodeURIComponent(redirect_to) : ''); - }; - } + function ($scope, $state, $http, $location, $window, Authentication) { + $scope.authentication = Authentication; + + // Get an eventual error defined in the URL query string: + $scope.error = $location.search().err; + + // If user is signed in then redirect back home + if ($scope.authentication.user) { + $location.path('/'); + } + + $scope.signup = function () { + $http.post('/api/auth/signup', $scope.credentials).success(function (response) { + // If successful we assign the response to the global user model + $scope.authentication.user = response; + + // And redirect to the previous or home page + $state.go($state.previous.state.name || 'home', $state.previous.params); + }).error(function (response) { + $scope.error = response.message; + }); + }; + + $scope.signin = function () { + $http.post('/api/auth/signin', $scope.credentials).success(function (response) { + // If successful we assign the response to the global user model + $scope.authentication.user = response; + + // And redirect to the previous or home page + $state.go($state.previous.state.name || 'home', $state.previous.params); + }).error(function (response) { + $scope.error = response.message; + }); + }; + + // OAuth provider request + $scope.callOauthProvider = function (url) { + var redirect_to; + + if ($state.previous) { + redirect_to = $state.previous.href; + } + + // Effectively call OAuth authentication route: + $window.location.href = url + (redirect_to ? '?redirect_to=' + encodeURIComponent(redirect_to) : ''); + }; + } ]); diff --git a/modules/users/client/controllers/password.client.controller.js b/modules/users/client/controllers/password.client.controller.js index 6c95125750..e24c556296 100644 --- a/modules/users/client/controllers/password.client.controller.js +++ b/modules/users/client/controllers/password.client.controller.js @@ -1,44 +1,46 @@ 'use strict'; angular.module('users').controller('PasswordController', ['$scope', '$stateParams', '$http', '$location', 'Authentication', - function($scope, $stateParams, $http, $location, Authentication) { - $scope.authentication = Authentication; - - //If user is signed in then redirect back home - if ($scope.authentication.user) $location.path('/'); - - // Submit forgotten password account id - $scope.askForPasswordReset = function() { - $scope.success = $scope.error = null; - - $http.post('/api/auth/forgot', $scope.credentials).success(function(response) { - // Show user success message and clear form - $scope.credentials = null; - $scope.success = response.message; - - }).error(function(response) { - // Show user error message and clear form - $scope.credentials = null; - $scope.error = response.message; - }); - }; - - // Change user password - $scope.resetUserPassword = function() { - $scope.success = $scope.error = null; - - $http.post('/api/auth/reset/' + $stateParams.token, $scope.passwordDetails).success(function(response) { - // If successful show success message and clear form - $scope.passwordDetails = null; - - // Attach user profile - Authentication.user = response; - - // And redirect to the index page - $location.path('/password/reset/success'); - }).error(function(response) { - $scope.error = response.message; - }); - }; - } + function ($scope, $stateParams, $http, $location, Authentication) { + $scope.authentication = Authentication; + + //If user is signed in then redirect back home + if ($scope.authentication.user) { + $location.path('/'); + } + + // Submit forgotten password account id + $scope.askForPasswordReset = function () { + $scope.success = $scope.error = null; + + $http.post('/api/auth/forgot', $scope.credentials).success(function (response) { + // Show user success message and clear form + $scope.credentials = null; + $scope.success = response.message; + + }).error(function (response) { + // Show user error message and clear form + $scope.credentials = null; + $scope.error = response.message; + }); + }; + + // Change user password + $scope.resetUserPassword = function () { + $scope.success = $scope.error = null; + + $http.post('/api/auth/reset/' + $stateParams.token, $scope.passwordDetails).success(function (response) { + // If successful show success message and clear form + $scope.passwordDetails = null; + + // Attach user profile + Authentication.user = response; + + // And redirect to the index page + $location.path('/password/reset/success'); + }).error(function (response) { + $scope.error = response.message; + }); + }; + } ]); diff --git a/modules/users/client/controllers/settings/change-password.client.controller.js b/modules/users/client/controllers/settings/change-password.client.controller.js index 3c0effa403..d5ac3b2186 100644 --- a/modules/users/client/controllers/settings/change-password.client.controller.js +++ b/modules/users/client/controllers/settings/change-password.client.controller.js @@ -1,20 +1,20 @@ 'use strict'; angular.module('users').controller('ChangePasswordController', ['$scope', '$http', 'Authentication', - function($scope, $http, Authentication) { - $scope.user = Authentication.user; + function ($scope, $http, Authentication) { + $scope.user = Authentication.user; - // Change user password - $scope.changeUserPassword = function() { - $scope.success = $scope.error = null; + // Change user password + $scope.changeUserPassword = function () { + $scope.success = $scope.error = null; - $http.post('/api/users/password', $scope.passwordDetails).success(function(response) { - // If successful show success message and clear form - $scope.success = true; - $scope.passwordDetails = null; - }).error(function(response) { - $scope.error = response.message; - }); - }; - } + $http.post('/api/users/password', $scope.passwordDetails).success(function (response) { + // If successful show success message and clear form + $scope.success = true; + $scope.passwordDetails = null; + }).error(function (response) { + $scope.error = response.message; + }); + }; + } ]); diff --git a/modules/users/client/controllers/settings/change-profile-picture.client.controller.js b/modules/users/client/controllers/settings/change-profile-picture.client.controller.js index d131c720fe..36f5bb10b3 100644 --- a/modules/users/client/controllers/settings/change-profile-picture.client.controller.js +++ b/modules/users/client/controllers/settings/change-profile-picture.client.controller.js @@ -1,72 +1,72 @@ 'use strict'; angular.module('users').controller('ChangeProfilePictureController', ['$scope', '$timeout', '$window', 'Authentication', 'FileUploader', - function ($scope, $timeout, $window, Authentication, FileUploader) { - $scope.user = Authentication.user; - $scope.imageURL = $scope.user.profileImageURL; + function ($scope, $timeout, $window, Authentication, FileUploader) { + $scope.user = Authentication.user; + $scope.imageURL = $scope.user.profileImageURL; - // Create file uploader instance - $scope.uploader = new FileUploader({ - url: 'api/users/picture' - }); + // Create file uploader instance + $scope.uploader = new FileUploader({ + url: 'api/users/picture' + }); - // Set file uploader image filter - $scope.uploader.filters.push({ - name: 'imageFilter', - fn: function (item, options) { - var type = '|' + item.type.slice(item.type.lastIndexOf('/') + 1) + '|'; - return '|jpg|png|jpeg|bmp|gif|'.indexOf(type) !== -1; - } - }); + // Set file uploader image filter + $scope.uploader.filters.push({ + name: 'imageFilter', + fn: function (item, options) { + var type = '|' + item.type.slice(item.type.lastIndexOf('/') + 1) + '|'; + return '|jpg|png|jpeg|bmp|gif|'.indexOf(type) !== -1; + } + }); - // Called after the user selected a new picture file - $scope.uploader.onAfterAddingFile = function (fileItem) { - if ($window.FileReader) { - var fileReader = new FileReader(); - fileReader.readAsDataURL(fileItem._file); + // Called after the user selected a new picture file + $scope.uploader.onAfterAddingFile = function (fileItem) { + if ($window.FileReader) { + var fileReader = new FileReader(); + fileReader.readAsDataURL(fileItem._file); - fileReader.onload = function (fileReaderEvent) { - $timeout(function () { - $scope.imageURL = fileReaderEvent.target.result; - }, 0); - }; - } - }; + fileReader.onload = function (fileReaderEvent) { + $timeout(function () { + $scope.imageURL = fileReaderEvent.target.result; + }, 0); + }; + } + }; - // Called after the user has successfully uploaded a new picture - $scope.uploader.onSuccessItem = function (fileItem, response, status, headers) { - // Show success message - $scope.success = true; + // Called after the user has successfully uploaded a new picture + $scope.uploader.onSuccessItem = function (fileItem, response, status, headers) { + // Show success message + $scope.success = true; - // Populate user object - $scope.user = Authentication.user = response; + // Populate user object + $scope.user = Authentication.user = response; - // Clear upload buttons - $scope.cancelUpload(); - }; + // Clear upload buttons + $scope.cancelUpload(); + }; - // Called after the user has failed to uploaded a new picture - $scope.uploader.onErrorItem = function (fileItem, response, status, headers) { - // Clear upload buttons - $scope.cancelUpload(); + // Called after the user has failed to uploaded a new picture + $scope.uploader.onErrorItem = function (fileItem, response, status, headers) { + // Clear upload buttons + $scope.cancelUpload(); - // Show error message - $scope.error = response.message; - }; + // Show error message + $scope.error = response.message; + }; - // Change user profile picture - $scope.uploadProfilePicture = function () { - // Clear messages - $scope.success = $scope.error = null; + // Change user profile picture + $scope.uploadProfilePicture = function () { + // Clear messages + $scope.success = $scope.error = null; - // Start upload - $scope.uploader.uploadAll(); - }; + // Start upload + $scope.uploader.uploadAll(); + }; - // Cancel the upload process - $scope.cancelUpload = function () { - $scope.uploader.clearQueue(); - $scope.imageURL = $scope.user.profileImageURL; - }; - } + // Cancel the upload process + $scope.cancelUpload = function () { + $scope.uploader.clearQueue(); + $scope.imageURL = $scope.user.profileImageURL; + }; + } ]); diff --git a/modules/users/client/controllers/settings/edit-profile.client.controller.js b/modules/users/client/controllers/settings/edit-profile.client.controller.js index 8e1d423819..cb985ad51b 100644 --- a/modules/users/client/controllers/settings/edit-profile.client.controller.js +++ b/modules/users/client/controllers/settings/edit-profile.client.controller.js @@ -1,24 +1,24 @@ 'use strict'; angular.module('users').controller('EditProfileController', ['$scope', '$http', '$location', 'Users', 'Authentication', - function($scope, $http, $location, Users, Authentication) { - $scope.user = Authentication.user; + function ($scope, $http, $location, Users, Authentication) { + $scope.user = Authentication.user; - // Update a user profile - $scope.updateUserProfile = function(isValid) { - if (isValid){ - $scope.success = $scope.error = null; - var user = new Users($scope.user); + // Update a user profile + $scope.updateUserProfile = function (isValid) { + if (isValid) { + $scope.success = $scope.error = null; + var user = new Users($scope.user); - user.$update(function(response) { - $scope.success = true; - Authentication.user = response; - }, function(response) { - $scope.error = response.data.message; - }); - } else { - $scope.submitted = true; - } - }; - } + user.$update(function (response) { + $scope.success = true; + Authentication.user = response; + }, function (response) { + $scope.error = response.data.message; + }); + } else { + $scope.submitted = true; + } + }; + } ]); diff --git a/modules/users/client/controllers/settings/manage-social-accounts.client.controller.js b/modules/users/client/controllers/settings/manage-social-accounts.client.controller.js index 45483425e7..0cb16aea04 100644 --- a/modules/users/client/controllers/settings/manage-social-accounts.client.controller.js +++ b/modules/users/client/controllers/settings/manage-social-accounts.client.controller.js @@ -1,38 +1,38 @@ 'use strict'; angular.module('users').controller('SocialAccountsController', ['$scope', '$http', 'Authentication', - function($scope, $http, Authentication) { - $scope.user = Authentication.user; + function ($scope, $http, Authentication) { + $scope.user = Authentication.user; - // Check if there are additional accounts - $scope.hasConnectedAdditionalSocialAccounts = function(provider) { - for (var i in $scope.user.additionalProvidersData) { - return true; - } + // Check if there are additional accounts + $scope.hasConnectedAdditionalSocialAccounts = function (provider) { + for (var i in $scope.user.additionalProvidersData) { + return true; + } - return false; - }; + return false; + }; - // Check if provider is already in use with current user - $scope.isConnectedSocialAccount = function(provider) { - return $scope.user.provider === provider || ($scope.user.additionalProvidersData && $scope.user.additionalProvidersData[provider]); - }; + // Check if provider is already in use with current user + $scope.isConnectedSocialAccount = function (provider) { + return $scope.user.provider === provider || ($scope.user.additionalProvidersData && $scope.user.additionalProvidersData[provider]); + }; - // Remove a user social account - $scope.removeUserSocialAccount = function(provider) { - $scope.success = $scope.error = null; + // Remove a user social account + $scope.removeUserSocialAccount = function (provider) { + $scope.success = $scope.error = null; - $http.delete('/api/users/accounts', { - params: { - provider: provider - } - }).success(function(response) { - // If successful show success message and clear form - $scope.success = true; - $scope.user = Authentication.user = response; - }).error(function(response) { - $scope.error = response.message; - }); - }; - } + $http.delete('/api/users/accounts', { + params: { + provider: provider + } + }).success(function (response) { + // If successful show success message and clear form + $scope.success = true; + $scope.user = Authentication.user = response; + }).error(function (response) { + $scope.error = response.message; + }); + }; + } ]); diff --git a/modules/users/client/controllers/settings/settings.client.controller.js b/modules/users/client/controllers/settings/settings.client.controller.js index 46c217cb0e..475a6b057c 100644 --- a/modules/users/client/controllers/settings/settings.client.controller.js +++ b/modules/users/client/controllers/settings/settings.client.controller.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('users').controller('SettingsController', ['$scope', 'Authentication', - function($scope, Authentication) { - $scope.user = Authentication.user; - } + function ($scope, Authentication) { + $scope.user = Authentication.user; + } ]); diff --git a/modules/users/client/css/users.css b/modules/users/client/css/users.css index e1727b2153..9bbc8961b5 100644 --- a/modules/users/client/css/users.css +++ b/modules/users/client/css/users.css @@ -1,41 +1,36 @@ @media (min-width: 992px) { - .nav-users { - position: fixed; - } + .nav-users { + position: fixed; + } } - .social-account-container { - display: inline-block; - position: relative; + display: inline-block; + position: relative; } - .btn-remove-account { - top: 10px; - right: 10px; - position: absolute; + top: 10px; + right: 10px; + position: absolute; } - .btn-file { - position: relative; - overflow: hidden; + position: relative; + overflow: hidden; } - .btn-file input[type=file] { - position: absolute; - top: 0; - right: 0; - min-width: 100%; - min-height: 100%; - font-size: 100px; - text-align: right; - filter: alpha(opacity=0); - opacity: 0; - background: white; - cursor: inherit; - display: block; + position: absolute; + top: 0; + right: 0; + min-width: 100%; + min-height: 100%; + font-size: 100px; + text-align: right; + filter: alpha(opacity=0); + opacity: 0; + background: white; + cursor: inherit; + display: block; } - .user-profile-picture { - min-height: 150px; - max-height: 150px; + min-height: 150px; + max-height: 150px; } diff --git a/modules/users/client/services/authentication.client.service.js b/modules/users/client/services/authentication.client.service.js index 8eadf2c06f..b535d46515 100644 --- a/modules/users/client/services/authentication.client.service.js +++ b/modules/users/client/services/authentication.client.service.js @@ -2,11 +2,11 @@ // Authentication service for user variables angular.module('users').factory('Authentication', ['$window', - function($window) { - var auth = { - user: $window.user - }; + function ($window) { + var auth = { + user: $window.user + }; - return auth; - } + return auth; + } ]); diff --git a/modules/users/client/services/users.client.service.js b/modules/users/client/services/users.client.service.js index eb3abfeee3..aaac9c3591 100644 --- a/modules/users/client/services/users.client.service.js +++ b/modules/users/client/services/users.client.service.js @@ -2,25 +2,24 @@ // Users service used for communicating with the users REST endpoint angular.module('users').factory('Users', ['$resource', - function ($resource) { - return $resource('api/users', {}, { - update: { - method: 'PUT' - } - }); - } + function ($resource) { + return $resource('api/users', {}, { + update: { + method: 'PUT' + } + }); + } ]); - //TODO this should be Users service angular.module('users.admin').factory('Admin', ['$resource', - function ($resource) { - return $resource('api/users/:userId', { - userId: '@_id' - }, { - update: { - method: 'PUT' - } - }); - } + function ($resource) { + return $resource('api/users/:userId', { + userId: '@_id' + }, { + update: { + method: 'PUT' + } + }); + } ]); diff --git a/modules/users/client/views/admin/user-edit.client.view.html b/modules/users/client/views/admin/user-edit.client.view.html index 26e274b96a..54f4a60ff8 100644 --- a/modules/users/client/views/admin/user-edit.client.view.html +++ b/modules/users/client/views/admin/user-edit.client.view.html @@ -1,35 +1,35 @@
    - -
    -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    -
    - -
    -
    -
    -
    + +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    + +
    +
    +
    +
    diff --git a/modules/users/client/views/admin/user-list.client.view.html b/modules/users/client/views/admin/user-list.client.view.html index dd933302b5..408aa6674e 100644 --- a/modules/users/client/views/admin/user-list.client.view.html +++ b/modules/users/client/views/admin/user-list.client.view.html @@ -1,20 +1,20 @@
    - - + + - +
    diff --git a/modules/users/client/views/admin/user.client.view.html b/modules/users/client/views/admin/user.client.view.html index eef7cf4703..366f852f71 100644 --- a/modules/users/client/views/admin/user.client.view.html +++ b/modules/users/client/views/admin/user.client.view.html @@ -1,51 +1,51 @@
    - + -
    -
    -
    -
    First Name
    -
    -
    -
    -
    -
    Last Name
    -
    -
    -
    -
    -
    Email
    -
    -
    -
    -
    -
    Provider
    -
    -
    -
    -
    -
    Created
    -
    -
    -
    -
    -
    Roles
    -
    -
    -
    -
    +
    +
    +
    +
    First Name
    +
    +
    +
    +
    +
    Last Name
    +
    +
    +
    +
    +
    Email
    +
    +
    +
    +
    +
    Provider
    +
    +
    +
    +
    +
    Created
    +
    +
    +
    +
    +
    Roles
    +
    +
    +
    +
    diff --git a/modules/users/client/views/authentication/authentication.client.view.html b/modules/users/client/views/authentication/authentication.client.view.html index 779184b6ab..af052fad2d 100644 --- a/modules/users/client/views/authentication/authentication.client.view.html +++ b/modules/users/client/views/authentication/authentication.client.view.html @@ -1,12 +1,12 @@
    -

    Sign in using your social accounts

    -
    - - - - - - -
    -
    +

    Sign in using your social accounts

    +
    + + + + + + +
    +
    diff --git a/modules/users/client/views/authentication/signin.client.view.html b/modules/users/client/views/authentication/signin.client.view.html index 0d78a1391f..cb2d908b3c 100644 --- a/modules/users/client/views/authentication/signin.client.view.html +++ b/modules/users/client/views/authentication/signin.client.view.html @@ -1,30 +1,30 @@
    -

    Or with your account

    -
    - -
    +

    Or with your account

    +
    + +
    diff --git a/modules/users/client/views/authentication/signup.client.view.html b/modules/users/client/views/authentication/signup.client.view.html index bb711b3e05..2227fab432 100644 --- a/modules/users/client/views/authentication/signup.client.view.html +++ b/modules/users/client/views/authentication/signup.client.view.html @@ -1,42 +1,42 @@
    -

    Or sign up using your email

    -
    - -
    +

    Or sign up using your email

    +
    + +
    diff --git a/modules/users/client/views/password/forgot-password.client.view.html b/modules/users/client/views/password/forgot-password.client.view.html index 02feebfc2d..793b7a0f58 100644 --- a/modules/users/client/views/password/forgot-password.client.view.html +++ b/modules/users/client/views/password/forgot-password.client.view.html @@ -4,9 +4,9 @@

    Restore your password

    -
    - -
    +
    + +
    diff --git a/modules/users/client/views/password/reset-password-invalid.client.view.html b/modules/users/client/views/password/reset-password-invalid.client.view.html index a9b8512b15..2c44e89420 100644 --- a/modules/users/client/views/password/reset-password-invalid.client.view.html +++ b/modules/users/client/views/password/reset-password-invalid.client.view.html @@ -1,4 +1,4 @@
    -

    Password reset is invalid

    - Ask for a new password reset +

    Password reset is invalid

    + Ask for a new password reset
    diff --git a/modules/users/client/views/password/reset-password-success.client.view.html b/modules/users/client/views/password/reset-password-success.client.view.html index a15df19248..252a879448 100644 --- a/modules/users/client/views/password/reset-password-success.client.view.html +++ b/modules/users/client/views/password/reset-password-success.client.view.html @@ -1,4 +1,4 @@
    -

    Password successfully reset

    - Continue to home page +

    Password successfully reset

    + Continue to home page
    diff --git a/modules/users/client/views/settings/change-password.client.view.html b/modules/users/client/views/settings/change-password.client.view.html index ee2e37d876..28e72dddce 100644 --- a/modules/users/client/views/settings/change-password.client.view.html +++ b/modules/users/client/views/settings/change-password.client.view.html @@ -1,29 +1,29 @@
    -
    - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - -
    -
    - Password Changed Successfully -
    -
    - -
    -
    - -
    +
    + +
    diff --git a/modules/users/client/views/settings/change-profile-picture.client.view.html b/modules/users/client/views/settings/change-profile-picture.client.view.html index e0e4f92572..17085f3d99 100644 --- a/modules/users/client/views/settings/change-profile-picture.client.view.html +++ b/modules/users/client/views/settings/change-profile-picture.client.view.html @@ -1,26 +1,26 @@
    -
    - -
    +
    + +
    diff --git a/modules/users/client/views/settings/edit-profile.client.view.html b/modules/users/client/views/settings/edit-profile.client.view.html index 1b3c0306ed..2f461127ad 100644 --- a/modules/users/client/views/settings/edit-profile.client.view.html +++ b/modules/users/client/views/settings/edit-profile.client.view.html @@ -1,33 +1,33 @@
    -
    - -
    +
    + +
    diff --git a/modules/users/client/views/settings/manage-social-accounts.client.view.html b/modules/users/client/views/settings/manage-social-accounts.client.view.html index 6a0b47300e..f07ad9ca1f 100644 --- a/modules/users/client/views/settings/manage-social-accounts.client.view.html +++ b/modules/users/client/views/settings/manage-social-accounts.client.view.html @@ -1,50 +1,50 @@
    -

    Connected social accounts:

    -
    - -
    -

    Unconnected social accounts:

    -
    - - - - - - -
    +

    Connected social accounts:

    +
    + +
    +

    Unconnected social accounts:

    +
    + + + + + + +
    diff --git a/modules/users/client/views/settings/settings.client.view.html b/modules/users/client/views/settings/settings.client.view.html index 9a05049fcd..8d5bd8c0b1 100644 --- a/modules/users/client/views/settings/settings.client.view.html +++ b/modules/users/client/views/settings/settings.client.view.html @@ -1,26 +1,26 @@
    - - + +
    diff --git a/modules/users/server/config/strategies/facebook.js b/modules/users/server/config/strategies/facebook.js index ed03ce267a..0f53a6a767 100644 --- a/modules/users/server/config/strategies/facebook.js +++ b/modules/users/server/config/strategies/facebook.js @@ -4,38 +4,38 @@ * Module dependencies. */ var passport = require('passport'), - FacebookStrategy = require('passport-facebook').Strategy, - users = require('../../controllers/users.server.controller'); + FacebookStrategy = require('passport-facebook').Strategy, + users = require('../../controllers/users.server.controller'); -module.exports = function(config) { - // Use facebook strategy - passport.use(new FacebookStrategy({ - clientID: config.facebook.clientID, - clientSecret: config.facebook.clientSecret, - callbackURL: config.facebook.callbackURL, - profileFields: ['id', 'name', 'displayName', 'emails', 'photos'], - passReqToCallback: true - }, - function(req, accessToken, refreshToken, profile, done) { - // Set the provider data and include tokens - var providerData = profile._json; - providerData.accessToken = accessToken; - providerData.refreshToken = refreshToken; +module.exports = function (config) { + // Use facebook strategy + passport.use(new FacebookStrategy({ + clientID: config.facebook.clientID, + clientSecret: config.facebook.clientSecret, + callbackURL: config.facebook.callbackURL, + profileFields: ['id', 'name', 'displayName', 'emails', 'photos'], + passReqToCallback: true + }, + function (req, accessToken, refreshToken, profile, done) { + // Set the provider data and include tokens + var providerData = profile._json; + providerData.accessToken = accessToken; + providerData.refreshToken = refreshToken; - // Create the user OAuth profile - var providerUserProfile = { - firstName: profile.name.givenName, - lastName: profile.name.familyName, - displayName: profile.displayName, - email: profile.emails[0].value, - profileImageURL: (profile.id) ? '//graph.facebook.com/' + profile.id + '/picture?type=large' : undefined, - provider: 'facebook', - providerIdentifierField: 'id', - providerData: providerData - }; + // Create the user OAuth profile + var providerUserProfile = { + firstName: profile.name.givenName, + lastName: profile.name.familyName, + displayName: profile.displayName, + email: profile.emails[0].value, + profileImageURL: (profile.id) ? '//graph.facebook.com/' + profile.id + '/picture?type=large' : undefined, + provider: 'facebook', + providerIdentifierField: 'id', + providerData: providerData + }; - // Save the user OAuth profile - users.saveOAuthUserProfile(req, providerUserProfile, done); - } - )); + // Save the user OAuth profile + users.saveOAuthUserProfile(req, providerUserProfile, done); + } + )); }; diff --git a/modules/users/server/config/strategies/github.js b/modules/users/server/config/strategies/github.js index 8ceafea06a..6e996e6306 100644 --- a/modules/users/server/config/strategies/github.js +++ b/modules/users/server/config/strategies/github.js @@ -4,43 +4,45 @@ * Module dependencies. */ var passport = require('passport'), - GithubStrategy = require('passport-github').Strategy, - users = require('../../controllers/users.server.controller'); + GithubStrategy = require('passport-github').Strategy, + users = require('../../controllers/users.server.controller'); -module.exports = function(config) { - // Use github strategy - passport.use(new GithubStrategy({ - clientID: config.github.clientID, - clientSecret: config.github.clientSecret, - callbackURL: config.github.callbackURL, - passReqToCallback: true - }, - function(req, accessToken, refreshToken, profile, done) { - // Set the provider data and include tokens - var providerData = profile._json; - providerData.accessToken = accessToken; - providerData.refreshToken = refreshToken; +module.exports = function (config) { + // Use github strategy + passport.use(new GithubStrategy({ + clientID: config.github.clientID, + clientSecret: config.github.clientSecret, + callbackURL: config.github.callbackURL, + passReqToCallback: true + }, + function (req, accessToken, refreshToken, profile, done) { + // Set the provider data and include tokens + var providerData = profile._json; + providerData.accessToken = accessToken; + providerData.refreshToken = refreshToken; - // Create the user OAuth profile - var displayName = profile.displayName ? profile.displayName.trim() : profile.username.trim(); - var iSpace = displayName.indexOf(' '); // index of the whitespace following the firstName - var firstName = iSpace !== -1 ? displayName.substring(0, iSpace) : displayName; - var lastName = iSpace !== -1 ? displayName.substring(iSpace + 1) : ''; + // Create the user OAuth profile + var displayName = profile.displayName ? profile.displayName.trim() : profile.username.trim(); + var iSpace = displayName.indexOf(' '); // index of the whitespace following the firstName + var firstName = iSpace !== -1 ? displayName.substring(0, iSpace) : displayName; + var lastName = iSpace !== -1 ? displayName.substring(iSpace + 1) : ''; - var providerUserProfile = { - firstName: firstName, - lastName: lastName, - displayName: displayName, - email: profile.emails[0].value, - username: profile.username, - profileImageURL: (providerData.avatar_url) ? providerData.avatar_url : undefined, - provider: 'github', - providerIdentifierField: 'id', - providerData: providerData - }; + var providerUserProfile = { + firstName: firstName, + lastName: lastName, + displayName: displayName, + email: profile.emails[0].value, + username: profile.username, + // jscs:disable requireCamelCaseOrUpperCaseIdentifiers + profileImageURL: (providerData.avatar_url) ? providerData.avatar_url : undefined, + // jscs:enable + provider: 'github', + providerIdentifierField: 'id', + providerData: providerData + }; - // Save the user OAuth profile - users.saveOAuthUserProfile(req, providerUserProfile, done); - } - )); + // Save the user OAuth profile + users.saveOAuthUserProfile(req, providerUserProfile, done); + } + )); }; diff --git a/modules/users/server/config/strategies/google.js b/modules/users/server/config/strategies/google.js index bd4df63f87..b2e023bd28 100644 --- a/modules/users/server/config/strategies/google.js +++ b/modules/users/server/config/strategies/google.js @@ -4,38 +4,38 @@ * Module dependencies. */ var passport = require('passport'), - GoogleStrategy = require('passport-google-oauth').OAuth2Strategy, - users = require('../../controllers/users.server.controller'); + GoogleStrategy = require('passport-google-oauth').OAuth2Strategy, + users = require('../../controllers/users.server.controller'); -module.exports = function(config) { - // Use google strategy - passport.use(new GoogleStrategy({ - clientID: config.google.clientID, - clientSecret: config.google.clientSecret, - callbackURL: config.google.callbackURL, - passReqToCallback: true - }, - function(req, accessToken, refreshToken, profile, done) { - // Set the provider data and include tokens - var providerData = profile._json; - providerData.accessToken = accessToken; - providerData.refreshToken = refreshToken; +module.exports = function (config) { + // Use google strategy + passport.use(new GoogleStrategy({ + clientID: config.google.clientID, + clientSecret: config.google.clientSecret, + callbackURL: config.google.callbackURL, + passReqToCallback: true + }, + function (req, accessToken, refreshToken, profile, done) { + // Set the provider data and include tokens + var providerData = profile._json; + providerData.accessToken = accessToken; + providerData.refreshToken = refreshToken; - // Create the user OAuth profile - var providerUserProfile = { - firstName: profile.name.givenName, - lastName: profile.name.familyName, - displayName: profile.displayName, - email: profile.emails[0].value, - username: profile.username, - profileImageURL: (providerData.picture) ? providerData.picture : undefined, - provider: 'google', - providerIdentifierField: 'id', - providerData: providerData - }; + // Create the user OAuth profile + var providerUserProfile = { + firstName: profile.name.givenName, + lastName: profile.name.familyName, + displayName: profile.displayName, + email: profile.emails[0].value, + username: profile.username, + profileImageURL: (providerData.picture) ? providerData.picture : undefined, + provider: 'google', + providerIdentifierField: 'id', + providerData: providerData + }; - // Save the user OAuth profile - users.saveOAuthUserProfile(req, providerUserProfile, done); - } - )); + // Save the user OAuth profile + users.saveOAuthUserProfile(req, providerUserProfile, done); + } + )); }; diff --git a/modules/users/server/config/strategies/linkedin.js b/modules/users/server/config/strategies/linkedin.js index 220269cf48..d6ae408d07 100644 --- a/modules/users/server/config/strategies/linkedin.js +++ b/modules/users/server/config/strategies/linkedin.js @@ -4,39 +4,39 @@ * Module dependencies. */ var passport = require('passport'), - LinkedInStrategy = require('passport-linkedin').Strategy, - users = require('../../controllers/users.server.controller'); + LinkedInStrategy = require('passport-linkedin').Strategy, + users = require('../../controllers/users.server.controller'); -module.exports = function(config) { - // Use linkedin strategy - passport.use(new LinkedInStrategy({ - consumerKey: config.linkedin.clientID, - consumerSecret: config.linkedin.clientSecret, - callbackURL: config.linkedin.callbackURL, - passReqToCallback: true, - profileFields: ['id', 'first-name', 'last-name', 'email-address', 'picture-url'] - }, - function(req, accessToken, refreshToken, profile, done) { - // Set the provider data and include tokens - var providerData = profile._json; - providerData.accessToken = accessToken; - providerData.refreshToken = refreshToken; +module.exports = function (config) { + // Use linkedin strategy + passport.use(new LinkedInStrategy({ + consumerKey: config.linkedin.clientID, + consumerSecret: config.linkedin.clientSecret, + callbackURL: config.linkedin.callbackURL, + passReqToCallback: true, + profileFields: ['id', 'first-name', 'last-name', 'email-address', 'picture-url'] + }, + function (req, accessToken, refreshToken, profile, done) { + // Set the provider data and include tokens + var providerData = profile._json; + providerData.accessToken = accessToken; + providerData.refreshToken = refreshToken; - // Create the user OAuth profile - var providerUserProfile = { - firstName: profile.name.givenName, - lastName: profile.name.familyName, - displayName: profile.displayName, - email: profile.emails[0].value, - username: profile.username, - profileImageURL: (providerData.pictureUrl) ? providerData.pictureUrl : undefined, - provider: 'linkedin', - providerIdentifierField: 'id', - providerData: providerData - }; + // Create the user OAuth profile + var providerUserProfile = { + firstName: profile.name.givenName, + lastName: profile.name.familyName, + displayName: profile.displayName, + email: profile.emails[0].value, + username: profile.username, + profileImageURL: (providerData.pictureUrl) ? providerData.pictureUrl : undefined, + provider: 'linkedin', + providerIdentifierField: 'id', + providerData: providerData + }; - // Save the user OAuth profile - users.saveOAuthUserProfile(req, providerUserProfile, done); - } - )); + // Save the user OAuth profile + users.saveOAuthUserProfile(req, providerUserProfile, done); + } + )); }; diff --git a/modules/users/server/config/strategies/local.js b/modules/users/server/config/strategies/local.js index 50ad14f142..684e7a8582 100644 --- a/modules/users/server/config/strategies/local.js +++ b/modules/users/server/config/strategies/local.js @@ -4,30 +4,30 @@ * Module dependencies. */ var passport = require('passport'), - LocalStrategy = require('passport-local').Strategy, - User = require('mongoose').model('User'); + LocalStrategy = require('passport-local').Strategy, + User = require('mongoose').model('User'); -module.exports = function() { - // Use local strategy - passport.use(new LocalStrategy({ - usernameField: 'username', - passwordField: 'password' - }, - function(username, password, done) { - User.findOne({ - username: username - }, function(err, user) { - if (err) { - return done(err); - } - if (!user || !user.authenticate(password)) { - return done(null, false, { - message: 'Invalid username or password' - }); - } +module.exports = function () { + // Use local strategy + passport.use(new LocalStrategy({ + usernameField: 'username', + passwordField: 'password' + }, + function (username, password, done) { + User.findOne({ + username: username + }, function (err, user) { + if (err) { + return done(err); + } + if (!user || !user.authenticate(password)) { + return done(null, false, { + message: 'Invalid username or password' + }); + } - return done(null, user); - }); - } - )); + return done(null, user); + }); + } + )); }; diff --git a/modules/users/server/config/strategies/paypal.js b/modules/users/server/config/strategies/paypal.js index 21271bf975..c0d97302ee 100644 --- a/modules/users/server/config/strategies/paypal.js +++ b/modules/users/server/config/strategies/paypal.js @@ -4,39 +4,39 @@ * Module dependencies. */ var passport = require('passport'), - PayPalStrategy = require('passport-paypal-openidconnect').Strategy, - users = require('../../controllers/users.server.controller'); + PayPalStrategy = require('passport-paypal-openidconnect').Strategy, + users = require('../../controllers/users.server.controller'); module.exports = function (config) { - passport.use(new PayPalStrategy({ - clientID: config.paypal.clientID, - clientSecret: config.paypal.clientSecret, - callbackURL: config.paypal.callbackURL, - scope: 'openid profile email', - sandbox: config.paypal.sandbox, - passReqToCallback: true + passport.use(new PayPalStrategy({ + clientID: config.paypal.clientID, + clientSecret: config.paypal.clientSecret, + callbackURL: config.paypal.callbackURL, + scope: 'openid profile email', + sandbox: config.paypal.sandbox, + passReqToCallback: true - }, - function(req, accessToken, refreshToken, profile, done) { - // Set the provider data and include tokens - var providerData = profile._json; - providerData.accessToken = accessToken; - providerData.refreshToken = refreshToken; + }, + function (req, accessToken, refreshToken, profile, done) { + // Set the provider data and include tokens + var providerData = profile._json; + providerData.accessToken = accessToken; + providerData.refreshToken = refreshToken; - // Create the user OAuth profile - var providerUserProfile = { - firstName: profile.name.givenName, - lastName: profile.name.familyName, - displayName: profile.displayName, - email: profile._json.email, - username: profile.username, - provider: 'paypal', - providerIdentifierField: 'user_id', - providerData: providerData - }; + // Create the user OAuth profile + var providerUserProfile = { + firstName: profile.name.givenName, + lastName: profile.name.familyName, + displayName: profile.displayName, + email: profile._json.email, + username: profile.username, + provider: 'paypal', + providerIdentifierField: 'user_id', + providerData: providerData + }; - // Save the user OAuth profile - users.saveOAuthUserProfile(req, providerUserProfile, done); - } - )); + // Save the user OAuth profile + users.saveOAuthUserProfile(req, providerUserProfile, done); + } + )); }; diff --git a/modules/users/server/config/strategies/twitter.js b/modules/users/server/config/strategies/twitter.js index 393a2bd9fe..2f1d5abe40 100644 --- a/modules/users/server/config/strategies/twitter.js +++ b/modules/users/server/config/strategies/twitter.js @@ -4,42 +4,42 @@ * Module dependencies. */ var passport = require('passport'), - TwitterStrategy = require('passport-twitter').Strategy, - users = require('../../controllers/users.server.controller'); + TwitterStrategy = require('passport-twitter').Strategy, + users = require('../../controllers/users.server.controller'); -module.exports = function(config) { - // Use twitter strategy - passport.use(new TwitterStrategy({ - consumerKey: config.twitter.clientID, - consumerSecret: config.twitter.clientSecret, - callbackURL: config.twitter.callbackURL, - passReqToCallback: true - }, - function(req, token, tokenSecret, profile, done) { - // Set the provider data and include tokens - var providerData = profile._json; - providerData.token = token; - providerData.tokenSecret = tokenSecret; +module.exports = function (config) { + // Use twitter strategy + passport.use(new TwitterStrategy({ + consumerKey: config.twitter.clientID, + consumerSecret: config.twitter.clientSecret, + callbackURL: config.twitter.callbackURL, + passReqToCallback: true + }, + function (req, token, tokenSecret, profile, done) { + // Set the provider data and include tokens + var providerData = profile._json; + providerData.token = token; + providerData.tokenSecret = tokenSecret; - // Create the user OAuth profile - var displayName = profile.displayName.trim(); - var iSpace = displayName.indexOf(' '); // index of the whitespace following the firstName - var firstName = iSpace !== -1 ? displayName.substring(0, iSpace) : displayName; - var lastName = iSpace !== -1 ? displayName.substring(iSpace + 1) : ''; + // Create the user OAuth profile + var displayName = profile.displayName.trim(); + var iSpace = displayName.indexOf(' '); // index of the whitespace following the firstName + var firstName = iSpace !== -1 ? displayName.substring(0, iSpace) : displayName; + var lastName = iSpace !== -1 ? displayName.substring(iSpace + 1) : ''; - var providerUserProfile = { - firstName: firstName, - lastName: lastName, - displayName: displayName, - username: profile.username, - profileImageURL: profile.photos[0].value.replace('normal', 'bigger'), - provider: 'twitter', - providerIdentifierField: 'id_str', - providerData: providerData - }; + var providerUserProfile = { + firstName: firstName, + lastName: lastName, + displayName: displayName, + username: profile.username, + profileImageURL: profile.photos[0].value.replace('normal', 'bigger'), + provider: 'twitter', + providerIdentifierField: 'id_str', + providerData: providerData + }; - // Save the user OAuth profile - users.saveOAuthUserProfile(req, providerUserProfile, done); - } - )); + // Save the user OAuth profile + users.saveOAuthUserProfile(req, providerUserProfile, done); + } + )); }; diff --git a/modules/users/server/config/users.server.config.js b/modules/users/server/config/users.server.config.js index fa883bd213..1f9fa19ed2 100644 --- a/modules/users/server/config/users.server.config.js +++ b/modules/users/server/config/users.server.config.js @@ -4,34 +4,34 @@ * Module dependencies. */ var passport = require('passport'), - User = require('mongoose').model('User'), - path = require('path'), - config = require(path.resolve('./config/config')); + User = require('mongoose').model('User'), + path = require('path'), + config = require(path.resolve('./config/config')); /** * Module init function. */ -module.exports = function(app, db) { - // Serialize sessions - passport.serializeUser(function(user, done) { - done(null, user.id); - }); +module.exports = function (app, db) { + // Serialize sessions + passport.serializeUser(function (user, done) { + done(null, user.id); + }); - // Deserialize sessions - passport.deserializeUser(function(id, done) { - User.findOne({ - _id: id - }, '-salt -password', function(err, user) { - done(err, user); - }); - }); + // Deserialize sessions + passport.deserializeUser(function (id, done) { + User.findOne({ + _id: id + }, '-salt -password', function (err, user) { + done(err, user); + }); + }); - // Initialize strategies - config.utils.getGlobbedPaths(path.join(__dirname, './strategies/**/*.js')).forEach(function(strategy) { - require(path.resolve(strategy))(config); - }); + // Initialize strategies + config.utils.getGlobbedPaths(path.join(__dirname, './strategies/**/*.js')).forEach(function (strategy) { + require(path.resolve(strategy))(config); + }); - // Add passport's middleware - app.use(passport.initialize()); - app.use(passport.session()); + // Add passport's middleware + app.use(passport.initialize()); + app.use(passport.session()); }; diff --git a/modules/users/server/controllers/admin.server.controller.js b/modules/users/server/controllers/admin.server.controller.js index 14063fb74f..ca3761d909 100644 --- a/modules/users/server/controllers/admin.server.controller.js +++ b/modules/users/server/controllers/admin.server.controller.js @@ -4,86 +4,90 @@ * Module dependencies. */ var path = require('path'), - mongoose = require('mongoose'), - User = mongoose.model('User'), - errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')); + mongoose = require('mongoose'), + User = mongoose.model('User'), + errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')); /** * Show the current user */ exports.read = function (req, res) { - res.json(req.model); + res.json(req.model); }; /** * Update a User */ exports.update = function (req, res) { - var user = req.model; + var user = req.model; - //For security purposes only merge these parameters - user.firstName = req.body.firstName; - user.lastName = req.body.lastName; - user.displayName = user.firstName + ' ' + user.lastName; - user.roles = req.body.roles; + //For security purposes only merge these parameters + user.firstName = req.body.firstName; + user.lastName = req.body.lastName; + user.displayName = user.firstName + ' ' + user.lastName; + user.roles = req.body.roles; - user.save(function (err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } + user.save(function (err) { + if (err) { + return res.status(400).send({ + message: errorHandler.getErrorMessage(err) + }); + } - res.json(user); - }); + res.json(user); + }); }; /** * Delete a user */ exports.delete = function (req, res) { - var user = req.model; + var user = req.model; - user.remove(function (err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } + user.remove(function (err) { + if (err) { + return res.status(400).send({ + message: errorHandler.getErrorMessage(err) + }); + } - res.json(user); - }); + res.json(user); + }); }; /** * List of Users */ exports.list = function (req, res) { - User.find({}, '-salt -password').sort('-created').populate('user', 'displayName').exec(function (err, users) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } + User.find({}, '-salt -password').sort('-created').populate('user', 'displayName').exec(function (err, users) { + if (err) { + return res.status(400).send({ + message: errorHandler.getErrorMessage(err) + }); + } - res.json(users); - }); + res.json(users); + }); }; /** * User middleware */ exports.userByID = function (req, res, next, id) { - if (!mongoose.Types.ObjectId.isValid(id)) { - return res.status(400).send({ - message: 'User is invalid' - }); - } + if (!mongoose.Types.ObjectId.isValid(id)) { + return res.status(400).send({ + message: 'User is invalid' + }); + } - User.findById(id, '-salt -password').exec(function (err, user) { - if (err) return next(err); - if (!user) return next(new Error('Failed to load user ' + id)); - req.model = user; - next(); - }); + User.findById(id, '-salt -password').exec(function (err, user) { + if (err) { + return next(err); + } else if (!user) { + return next(new Error('Failed to load user ' + id)); + } + + req.model = user; + next(); + }); }; diff --git a/modules/users/server/controllers/users.server.controller.js b/modules/users/server/controllers/users.server.controller.js index 06ef00ea31..37e0dcda6e 100644 --- a/modules/users/server/controllers/users.server.controller.js +++ b/modules/users/server/controllers/users.server.controller.js @@ -9,8 +9,8 @@ var _ = require('lodash'); * Extend user's controller */ module.exports = _.extend( - require('./users/users.authentication.server.controller'), - require('./users/users.authorization.server.controller'), - require('./users/users.password.server.controller'), - require('./users/users.profile.server.controller') + require('./users/users.authentication.server.controller'), + require('./users/users.authorization.server.controller'), + require('./users/users.password.server.controller'), + require('./users/users.profile.server.controller') ); diff --git a/modules/users/server/controllers/users/users.authentication.server.controller.js b/modules/users/server/controllers/users/users.authentication.server.controller.js index 00142eaa6c..40d8746f12 100644 --- a/modules/users/server/controllers/users/users.authentication.server.controller.js +++ b/modules/users/server/controllers/users/users.authentication.server.controller.js @@ -4,10 +4,10 @@ * Module dependencies. */ var path = require('path'), - errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')), - mongoose = require('mongoose'), - passport = require('passport'), - User = mongoose.model('User'); + errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')), + mongoose = require('mongoose'), + passport = require('passport'), + User = mongoose.model('User'); // URLs for which user can't be redirected on signin var noReturnUrls = [ @@ -19,223 +19,226 @@ var noReturnUrls = [ * Signup */ exports.signup = function (req, res) { - // For security measurement we remove the roles from the req.body object - delete req.body.roles; - - // Init Variables - var user = new User(req.body); - var message = null; - - // Add missing user fields - user.provider = 'local'; - user.displayName = user.firstName + ' ' + user.lastName; - - // Then save the user - user.save(function (err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - // Remove sensitive data before login - user.password = undefined; - user.salt = undefined; - - req.login(user, function (err) { - if (err) { - res.status(400).send(err); - } else { - res.json(user); - } - }); - } - }); + // For security measurement we remove the roles from the req.body object + delete req.body.roles; + + // Init Variables + var user = new User(req.body); + var message = null; + + // Add missing user fields + user.provider = 'local'; + user.displayName = user.firstName + ' ' + user.lastName; + + // Then save the user + user.save(function (err) { + if (err) { + return res.status(400).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + // Remove sensitive data before login + user.password = undefined; + user.salt = undefined; + + req.login(user, function (err) { + if (err) { + res.status(400).send(err); + } else { + res.json(user); + } + }); + } + }); }; /** * Signin after passport authentication */ exports.signin = function (req, res, next) { - passport.authenticate('local', function (err, user, info) { - if (err || !user) { - res.status(400).send(info); - } else { - // Remove sensitive data before login - user.password = undefined; - user.salt = undefined; - - req.login(user, function (err) { - if (err) { - res.status(400).send(err); - } else { - res.json(user); - } - }); - } - })(req, res, next); + passport.authenticate('local', function (err, user, info) { + if (err || !user) { + res.status(400).send(info); + } else { + // Remove sensitive data before login + user.password = undefined; + user.salt = undefined; + + req.login(user, function (err) { + if (err) { + res.status(400).send(err); + } else { + res.json(user); + } + }); + } + })(req, res, next); }; /** * Signout */ exports.signout = function (req, res) { - req.logout(); - res.redirect('/'); + req.logout(); + res.redirect('/'); }; /** * OAuth provider call */ -exports.oauthCall = function(strategy, scope) { - return function(req, res, next) { - // Set redirection path on session. - // Do not redirect to a signin or signup page - if (noReturnUrls.indexOf(req.query.redirect_to) === -1) { - req.session.redirect_to = req.query.redirect_to; - } - // Authenticate - passport.authenticate(strategy, scope)(req, res, next); - }; +exports.oauthCall = function (strategy, scope) { + return function (req, res, next) { + // Set redirection path on session. + // Do not redirect to a signin or signup page + if (noReturnUrls.indexOf(req.query.redirect_to) === -1) { + req.session.redirect_to = req.query.redirect_to; + } + // Authenticate + passport.authenticate(strategy, scope)(req, res, next); + }; }; /** * OAuth callback */ exports.oauthCallback = function (strategy) { - return function (req, res, next) { - // Pop redirect URL from session - var sessionRedirectURL = req.session.redirect_to; - delete req.session.redirect_to; - - passport.authenticate(strategy, function (err, user, redirectURL) { - if (err) { - return res.redirect('/authentication/signin?err=' + encodeURIComponent(errorHandler.getErrorMessage(err))); - } - if (!user) { - return res.redirect('/authentication/signin'); - } - req.login(user, function (err) { - if (err) { - return res.redirect('/authentication/signin'); - } - - return res.redirect(redirectURL || sessionRedirectURL || '/'); - }); - })(req, res, next); - }; + return function (req, res, next) { + // Pop redirect URL from session + var sessionRedirectURL = req.session.redirect_to; + delete req.session.redirect_to; + + passport.authenticate(strategy, function (err, user, redirectURL) { + if (err) { + return res.redirect('/authentication/signin?err=' + encodeURIComponent(errorHandler.getErrorMessage(err))); + } + if (!user) { + return res.redirect('/authentication/signin'); + } + req.login(user, function (err) { + if (err) { + return res.redirect('/authentication/signin'); + } + + return res.redirect(redirectURL || sessionRedirectURL || '/'); + }); + })(req, res, next); + }; }; /** * Helper function to save or update a OAuth user profile */ exports.saveOAuthUserProfile = function (req, providerUserProfile, done) { - if (!req.user) { - // Define a search query fields - var searchMainProviderIdentifierField = 'providerData.' + providerUserProfile.providerIdentifierField; - var searchAdditionalProviderIdentifierField = 'additionalProvidersData.' + providerUserProfile.provider + '.' + providerUserProfile.providerIdentifierField; - - // Define main provider search query - var mainProviderSearchQuery = {}; - mainProviderSearchQuery.provider = providerUserProfile.provider; - mainProviderSearchQuery[searchMainProviderIdentifierField] = providerUserProfile.providerData[providerUserProfile.providerIdentifierField]; - - // Define additional provider search query - var additionalProviderSearchQuery = {}; - additionalProviderSearchQuery[searchAdditionalProviderIdentifierField] = providerUserProfile.providerData[providerUserProfile.providerIdentifierField]; - - // Define a search query to find existing user with current provider profile - var searchQuery = { - $or: [mainProviderSearchQuery, additionalProviderSearchQuery] - }; - - User.findOne(searchQuery, function (err, user) { - if (err) { - return done(err); - } else { - if (!user) { - var possibleUsername = providerUserProfile.username || ((providerUserProfile.email) ? providerUserProfile.email.split('@')[0] : ''); - - User.findUniqueUsername(possibleUsername, null, function (availableUsername) { - user = new User({ - firstName: providerUserProfile.firstName, - lastName: providerUserProfile.lastName, - username: availableUsername, - displayName: providerUserProfile.displayName, - email: providerUserProfile.email, - profileImageURL: providerUserProfile.profileImageURL, - provider: providerUserProfile.provider, - providerData: providerUserProfile.providerData - }); - - // And save the user - user.save(function (err) { - return done(err, user); - }); - }); - } else { - return done(err, user); - } - } - }); - } else { - // User is already logged in, join the provider data to the existing user - var user = req.user; - - // Check if user exists, is not signed in using this provider, and doesn't have that provider data already configured - if (user.provider !== providerUserProfile.provider && (!user.additionalProvidersData || !user.additionalProvidersData[providerUserProfile.provider])) { - // Add the provider data to the additional provider data field - if (!user.additionalProvidersData) user.additionalProvidersData = {}; - user.additionalProvidersData[providerUserProfile.provider] = providerUserProfile.providerData; - - // Then tell mongoose that we've updated the additionalProvidersData field - user.markModified('additionalProvidersData'); - - // And save the user - user.save(function (err) { - return done(err, user, '/settings/accounts'); - }); - } else { - return done(new Error('User is already connected using this provider'), user); - } - } + if (!req.user) { + // Define a search query fields + var searchMainProviderIdentifierField = 'providerData.' + providerUserProfile.providerIdentifierField; + var searchAdditionalProviderIdentifierField = 'additionalProvidersData.' + providerUserProfile.provider + '.' + providerUserProfile.providerIdentifierField; + + // Define main provider search query + var mainProviderSearchQuery = {}; + mainProviderSearchQuery.provider = providerUserProfile.provider; + mainProviderSearchQuery[searchMainProviderIdentifierField] = providerUserProfile.providerData[providerUserProfile.providerIdentifierField]; + + // Define additional provider search query + var additionalProviderSearchQuery = {}; + additionalProviderSearchQuery[searchAdditionalProviderIdentifierField] = providerUserProfile.providerData[providerUserProfile.providerIdentifierField]; + + // Define a search query to find existing user with current provider profile + var searchQuery = { + $or: [mainProviderSearchQuery, additionalProviderSearchQuery] + }; + + User.findOne(searchQuery, function (err, user) { + if (err) { + return done(err); + } else { + if (!user) { + var possibleUsername = providerUserProfile.username || ((providerUserProfile.email) ? providerUserProfile.email.split('@')[0] : ''); + + User.findUniqueUsername(possibleUsername, null, function (availableUsername) { + user = new User({ + firstName: providerUserProfile.firstName, + lastName: providerUserProfile.lastName, + username: availableUsername, + displayName: providerUserProfile.displayName, + email: providerUserProfile.email, + profileImageURL: providerUserProfile.profileImageURL, + provider: providerUserProfile.provider, + providerData: providerUserProfile.providerData + }); + + // And save the user + user.save(function (err) { + return done(err, user); + }); + }); + } else { + return done(err, user); + } + } + }); + } else { + // User is already logged in, join the provider data to the existing user + var user = req.user; + + // Check if user exists, is not signed in using this provider, and doesn't have that provider data already configured + if (user.provider !== providerUserProfile.provider && (!user.additionalProvidersData || !user.additionalProvidersData[providerUserProfile.provider])) { + // Add the provider data to the additional provider data field + if (!user.additionalProvidersData) { + user.additionalProvidersData = {}; + } + + user.additionalProvidersData[providerUserProfile.provider] = providerUserProfile.providerData; + + // Then tell mongoose that we've updated the additionalProvidersData field + user.markModified('additionalProvidersData'); + + // And save the user + user.save(function (err) { + return done(err, user, '/settings/accounts'); + }); + } else { + return done(new Error('User is already connected using this provider'), user); + } + } }; /** * Remove OAuth provider */ exports.removeOAuthProvider = function (req, res, next) { - var user = req.user; - var provider = req.query.provider; - - if (!user) { - return res.status(401).json({ - message: 'User is not authenticated' - }); - } else if (!provider) { - return res.status(400).send(); - } - - // Delete the additional provider - if (user.additionalProvidersData[provider]) { - delete user.additionalProvidersData[provider]; - - // Then tell mongoose that we've updated the additionalProvidersData field - user.markModified('additionalProvidersData'); - } - - user.save(function (err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - req.login(user, function (err) { - if (err) { - return res.status(400).send(err); - } else { - return res.json(user); - } - }); - } - }); + var user = req.user; + var provider = req.query.provider; + + if (!user) { + return res.status(401).json({ + message: 'User is not authenticated' + }); + } else if (!provider) { + return res.status(400).send(); + } + + // Delete the additional provider + if (user.additionalProvidersData[provider]) { + delete user.additionalProvidersData[provider]; + + // Then tell mongoose that we've updated the additionalProvidersData field + user.markModified('additionalProvidersData'); + } + + user.save(function (err) { + if (err) { + return res.status(400).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + req.login(user, function (err) { + if (err) { + return res.status(400).send(err); + } else { + return res.json(user); + } + }); + } + }); }; diff --git a/modules/users/server/controllers/users/users.authorization.server.controller.js b/modules/users/server/controllers/users/users.authorization.server.controller.js index ea35abf346..f7fa09a145 100644 --- a/modules/users/server/controllers/users/users.authorization.server.controller.js +++ b/modules/users/server/controllers/users/users.authorization.server.controller.js @@ -4,25 +4,29 @@ * Module dependencies. */ var _ = require('lodash'), - mongoose = require('mongoose'), - User = mongoose.model('User'); + mongoose = require('mongoose'), + User = mongoose.model('User'); /** * User middleware */ exports.userByID = function (req, res, next, id) { - if (!mongoose.Types.ObjectId.isValid(id)) { - return res.status(400).send({ - message: 'User is invalid' - }); - } + if (!mongoose.Types.ObjectId.isValid(id)) { + return res.status(400).send({ + message: 'User is invalid' + }); + } - User.findOne({ - _id: id - }).exec(function (err, user) { - if (err) return next(err); - if (!user) return next(new Error('Failed to load User ' + id)); - req.profile = user; - next(); - }); + User.findOne({ + _id: id + }).exec(function (err, user) { + if (err) { + return next(err); + } else if (!user) { + return next(new Error('Failed to load User ' + id)); + } + + req.profile = user; + next(); + }); }; diff --git a/modules/users/server/controllers/users/users.password.server.controller.js b/modules/users/server/controllers/users/users.password.server.controller.js index b168339244..d59c73975a 100644 --- a/modules/users/server/controllers/users/users.password.server.controller.js +++ b/modules/users/server/controllers/users/users.password.server.controller.js @@ -4,247 +4,251 @@ * Module dependencies. */ var path = require('path'), - config = require(path.resolve('./config/config')), - errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')), - mongoose = require('mongoose'), - User = mongoose.model('User'), - nodemailer = require('nodemailer'), - async = require('async'), - crypto = require('crypto'); + config = require(path.resolve('./config/config')), + errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')), + mongoose = require('mongoose'), + User = mongoose.model('User'), + nodemailer = require('nodemailer'), + async = require('async'), + crypto = require('crypto'); var smtpTransport = nodemailer.createTransport(config.mailer.options); /** * Forgot for reset password (forgot POST) */ -exports.forgot = function(req, res, next) { - async.waterfall([ - // Generate random token - function(done) { - crypto.randomBytes(20, function(err, buffer) { - var token = buffer.toString('hex'); - done(err, token); - }); - }, - // Lookup user by username - function(token, done) { - if (req.body.username) { - User.findOne({ - username: req.body.username - }, '-salt -password', function(err, user) { - if (!user) { - return res.status(400).send({ - message: 'No account with that username has been found' - }); - } else if (user.provider !== 'local') { - return res.status(400).send({ - message: 'It seems like you signed up using your ' + user.provider + ' account' - }); - } else { - user.resetPasswordToken = token; - user.resetPasswordExpires = Date.now() + 3600000; // 1 hour - - user.save(function(err) { - done(err, token, user); - }); - } - }); - } else { - return res.status(400).send({ - message: 'Username field must not be blank' - }); - } - }, - function(token, user, done) { - res.render(path.resolve('modules/users/server/templates/reset-password-email'), { - name: user.displayName, - appName: config.app.title, - url: 'http://' + req.headers.host + '/api/auth/reset/' + token - }, function(err, emailHTML) { - done(err, emailHTML, user); - }); - }, - // If valid email, send reset email using service - function(emailHTML, user, done) { - var mailOptions = { - to: user.email, - from: config.mailer.from, - subject: 'Password Reset', - html: emailHTML - }; - smtpTransport.sendMail(mailOptions, function(err) { - if (!err) { - res.send({ - message: 'An email has been sent to the provided email with further instructions.' - }); - } else { - return res.status(400).send({ - message: 'Failure sending email' - }); - } - - done(err); - }); - } - ], function(err) { - if (err) return next(err); - }); +exports.forgot = function (req, res, next) { + async.waterfall([ + // Generate random token + function (done) { + crypto.randomBytes(20, function (err, buffer) { + var token = buffer.toString('hex'); + done(err, token); + }); + }, + // Lookup user by username + function (token, done) { + if (req.body.username) { + User.findOne({ + username: req.body.username + }, '-salt -password', function (err, user) { + if (!user) { + return res.status(400).send({ + message: 'No account with that username has been found' + }); + } else if (user.provider !== 'local') { + return res.status(400).send({ + message: 'It seems like you signed up using your ' + user.provider + ' account' + }); + } else { + user.resetPasswordToken = token; + user.resetPasswordExpires = Date.now() + 3600000; // 1 hour + + user.save(function (err) { + done(err, token, user); + }); + } + }); + } else { + return res.status(400).send({ + message: 'Username field must not be blank' + }); + } + }, + function (token, user, done) { + res.render(path.resolve('modules/users/server/templates/reset-password-email'), { + name: user.displayName, + appName: config.app.title, + url: 'http://' + req.headers.host + '/api/auth/reset/' + token + }, function (err, emailHTML) { + done(err, emailHTML, user); + }); + }, + // If valid email, send reset email using service + function (emailHTML, user, done) { + var mailOptions = { + to: user.email, + from: config.mailer.from, + subject: 'Password Reset', + html: emailHTML + }; + smtpTransport.sendMail(mailOptions, function (err) { + if (!err) { + res.send({ + message: 'An email has been sent to the provided email with further instructions.' + }); + } else { + return res.status(400).send({ + message: 'Failure sending email' + }); + } + + done(err); + }); + } + ], function (err) { + if (err) { + return next(err); + } + }); }; /** * Reset password GET from email token */ -exports.validateResetToken = function(req, res) { - User.findOne({ - resetPasswordToken: req.params.token, - resetPasswordExpires: { - $gt: Date.now() - } - }, function(err, user) { - if (!user) { - return res.redirect('/password/reset/invalid'); - } - - res.redirect('/password/reset/' + req.params.token); - }); +exports.validateResetToken = function (req, res) { + User.findOne({ + resetPasswordToken: req.params.token, + resetPasswordExpires: { + $gt: Date.now() + } + }, function (err, user) { + if (!user) { + return res.redirect('/password/reset/invalid'); + } + + res.redirect('/password/reset/' + req.params.token); + }); }; /** * Reset password POST from email token */ -exports.reset = function(req, res, next) { - // Init Variables - var passwordDetails = req.body; - var message = null; - - async.waterfall([ - - function(done) { - User.findOne({ - resetPasswordToken: req.params.token, - resetPasswordExpires: { - $gt: Date.now() - } - }, function(err, user) { - if (!err && user) { - if (passwordDetails.newPassword === passwordDetails.verifyPassword) { - user.password = passwordDetails.newPassword; - user.resetPasswordToken = undefined; - user.resetPasswordExpires = undefined; - - user.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - req.login(user, function(err) { - if (err) { - res.status(400).send(err); - } else { - // Return authenticated user - res.json(user); - - done(err, user); - } - }); - } - }); - } else { - return res.status(400).send({ - message: 'Passwords do not match' - }); - } - } else { - return res.status(400).send({ - message: 'Password reset token is invalid or has expired.' - }); - } - }); - }, - function(user, done) { - res.render('modules/users/server/templates/reset-password-confirm-email', { - name: user.displayName, - appName: config.app.title - }, function(err, emailHTML) { - done(err, emailHTML, user); - }); - }, - // If valid email, send reset email using service - function(emailHTML, user, done) { - var mailOptions = { - to: user.email, - from: config.mailer.from, - subject: 'Your password has been changed', - html: emailHTML - }; - - smtpTransport.sendMail(mailOptions, function(err) { - done(err, 'done'); - }); - } - ], function(err) { - if (err) return next(err); - }); +exports.reset = function (req, res, next) { + // Init Variables + var passwordDetails = req.body; + var message = null; + + async.waterfall([ + + function (done) { + User.findOne({ + resetPasswordToken: req.params.token, + resetPasswordExpires: { + $gt: Date.now() + } + }, function (err, user) { + if (!err && user) { + if (passwordDetails.newPassword === passwordDetails.verifyPassword) { + user.password = passwordDetails.newPassword; + user.resetPasswordToken = undefined; + user.resetPasswordExpires = undefined; + + user.save(function (err) { + if (err) { + return res.status(400).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + req.login(user, function (err) { + if (err) { + res.status(400).send(err); + } else { + // Return authenticated user + res.json(user); + + done(err, user); + } + }); + } + }); + } else { + return res.status(400).send({ + message: 'Passwords do not match' + }); + } + } else { + return res.status(400).send({ + message: 'Password reset token is invalid or has expired.' + }); + } + }); + }, + function (user, done) { + res.render('modules/users/server/templates/reset-password-confirm-email', { + name: user.displayName, + appName: config.app.title + }, function (err, emailHTML) { + done(err, emailHTML, user); + }); + }, + // If valid email, send reset email using service + function (emailHTML, user, done) { + var mailOptions = { + to: user.email, + from: config.mailer.from, + subject: 'Your password has been changed', + html: emailHTML + }; + + smtpTransport.sendMail(mailOptions, function (err) { + done(err, 'done'); + }); + } + ], function (err) { + if (err) { + return next(err); + } + }); }; /** * Change Password */ -exports.changePassword = function(req, res, next) { - // Init Variables - var passwordDetails = req.body; - var message = null; - - if (req.user) { - if (passwordDetails.newPassword) { - User.findById(req.user.id, function(err, user) { - if (!err && user) { - if (user.authenticate(passwordDetails.currentPassword)) { - if (passwordDetails.newPassword === passwordDetails.verifyPassword) { - user.password = passwordDetails.newPassword; - - user.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - req.login(user, function(err) { - if (err) { - res.status(400).send(err); - } else { - res.send({ - message: 'Password changed successfully' - }); - } - }); - } - }); - } else { - res.status(400).send({ - message: 'Passwords do not match' - }); - } - } else { - res.status(400).send({ - message: 'Current password is incorrect' - }); - } - } else { - res.status(400).send({ - message: 'User is not found' - }); - } - }); - } else { - res.status(400).send({ - message: 'Please provide a new password' - }); - } - } else { - res.status(400).send({ - message: 'User is not signed in' - }); - } +exports.changePassword = function (req, res, next) { + // Init Variables + var passwordDetails = req.body; + var message = null; + + if (req.user) { + if (passwordDetails.newPassword) { + User.findById(req.user.id, function (err, user) { + if (!err && user) { + if (user.authenticate(passwordDetails.currentPassword)) { + if (passwordDetails.newPassword === passwordDetails.verifyPassword) { + user.password = passwordDetails.newPassword; + + user.save(function (err) { + if (err) { + return res.status(400).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + req.login(user, function (err) { + if (err) { + res.status(400).send(err); + } else { + res.send({ + message: 'Password changed successfully' + }); + } + }); + } + }); + } else { + res.status(400).send({ + message: 'Passwords do not match' + }); + } + } else { + res.status(400).send({ + message: 'Current password is incorrect' + }); + } + } else { + res.status(400).send({ + message: 'User is not found' + }); + } + }); + } else { + res.status(400).send({ + message: 'Please provide a new password' + }); + } + } else { + res.status(400).send({ + message: 'User is not signed in' + }); + } }; diff --git a/modules/users/server/controllers/users/users.profile.server.controller.js b/modules/users/server/controllers/users/users.profile.server.controller.js index 63e18e8705..8dde7e6e55 100644 --- a/modules/users/server/controllers/users/users.profile.server.controller.js +++ b/modules/users/server/controllers/users/users.profile.server.controller.js @@ -4,93 +4,93 @@ * Module dependencies. */ var _ = require('lodash'), - fs = require('fs'), - path = require('path'), - errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')), - mongoose = require('mongoose'), - User = mongoose.model('User'); + fs = require('fs'), + path = require('path'), + errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')), + mongoose = require('mongoose'), + User = mongoose.model('User'); /** * Update user details */ exports.update = function (req, res) { - // Init Variables - var user = req.user; + // Init Variables + var user = req.user; - // For security measurement we remove the roles from the req.body object - delete req.body.roles; + // For security measurement we remove the roles from the req.body object + delete req.body.roles; - if (user) { - // Merge existing user - user = _.extend(user, req.body); - user.updated = Date.now(); - user.displayName = user.firstName + ' ' + user.lastName; + if (user) { + // Merge existing user + user = _.extend(user, req.body); + user.updated = Date.now(); + user.displayName = user.firstName + ' ' + user.lastName; - user.save(function (err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - req.login(user, function (err) { - if (err) { - res.status(400).send(err); - } else { - res.json(user); - } - }); - } - }); - } else { - res.status(400).send({ - message: 'User is not signed in' - }); - } + user.save(function (err) { + if (err) { + return res.status(400).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + req.login(user, function (err) { + if (err) { + res.status(400).send(err); + } else { + res.json(user); + } + }); + } + }); + } else { + res.status(400).send({ + message: 'User is not signed in' + }); + } }; /** * Update profile picture */ exports.changeProfilePicture = function (req, res) { - var user = req.user; - var message = null; + var user = req.user; + var message = null; - if (user) { - fs.writeFile('./modules/users/client/img/profile/uploads/' + req.files.file.name, req.files.file.buffer, function (uploadError) { - if (uploadError) { - return res.status(400).send({ - message: 'Error occurred while uploading profile picture' - }); - } else { - user.profileImageURL = 'modules/users/img/profile/uploads/' + req.files.file.name; + if (user) { + fs.writeFile('./modules/users/client/img/profile/uploads/' + req.files.file.name, req.files.file.buffer, function (uploadError) { + if (uploadError) { + return res.status(400).send({ + message: 'Error occurred while uploading profile picture' + }); + } else { + user.profileImageURL = 'modules/users/img/profile/uploads/' + req.files.file.name; - user.save(function (saveError) { - if (saveError) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(saveError) - }); - } else { - req.login(user, function (err) { - if (err) { - res.status(400).send(err); - } else { - res.json(user); - } - }); - } - }); - } - }); - } else { - res.status(400).send({ - message: 'User is not signed in' - }); - } + user.save(function (saveError) { + if (saveError) { + return res.status(400).send({ + message: errorHandler.getErrorMessage(saveError) + }); + } else { + req.login(user, function (err) { + if (err) { + res.status(400).send(err); + } else { + res.json(user); + } + }); + } + }); + } + }); + } else { + res.status(400).send({ + message: 'User is not signed in' + }); + } }; /** * Send User */ exports.me = function (req, res) { - res.json(req.user || null); + res.json(req.user || null); }; diff --git a/modules/users/server/models/user.server.model.js b/modules/users/server/models/user.server.model.js index 4ffd1f1738..8a4ff0e8da 100644 --- a/modules/users/server/models/user.server.model.js +++ b/modules/users/server/models/user.server.model.js @@ -4,155 +4,155 @@ * Module dependencies. */ var mongoose = require('mongoose'), - Schema = mongoose.Schema, - crypto = require('crypto'), - validator = require('validator'); + Schema = mongoose.Schema, + crypto = require('crypto'), + validator = require('validator'); /** * A Validation function for local strategy properties */ -var validateLocalStrategyProperty = function(property) { - return ((this.provider !== 'local' && !this.updated) || property.length); +var validateLocalStrategyProperty = function (property) { + return ((this.provider !== 'local' && !this.updated) || property.length); }; /** * A Validation function for local strategy password */ -var validateLocalStrategyPassword = function(password) { - return (this.provider !== 'local' || validator.isLength(password, 6)); +var validateLocalStrategyPassword = function (password) { + return (this.provider !== 'local' || validator.isLength(password, 6)); }; /** * A Validation function for local strategy email */ -var validateLocalStrategyEmail = function(email) { - return ((this.provider !== 'local' && !this.updated) || validator.isEmail(email)); +var validateLocalStrategyEmail = function (email) { + return ((this.provider !== 'local' && !this.updated) || validator.isEmail(email)); }; /** * User Schema */ var UserSchema = new Schema({ - firstName: { - type: String, - trim: true, - default: '', - validate: [validateLocalStrategyProperty, 'Please fill in your first name'] - }, - lastName: { - type: String, - trim: true, - default: '', - validate: [validateLocalStrategyProperty, 'Please fill in your last name'] - }, - displayName: { - type: String, - trim: true - }, - email: { - type: String, - trim: true, - unique: true, - default: '', - validate: [validateLocalStrategyEmail, 'Please fill a valid email address'] - }, - username: { - type: String, - unique: 'Username already exists', - required: 'Please fill in a username', - trim: true - }, - password: { - type: String, - default: '', - validate: [validateLocalStrategyPassword, 'Password should be longer'] - }, - salt: { - type: String - }, - profileImageURL: { - type: String, - default: 'modules/users/img/profile/default.png' - }, - provider: { - type: String, - required: 'Provider is required' - }, - providerData: {}, - additionalProvidersData: {}, - roles: { - type: [{ - type: String, - enum: ['user', 'admin'] - }], - default: ['user'] - }, - updated: { - type: Date - }, - created: { - type: Date, - default: Date.now - }, - /* For reset password */ - resetPasswordToken: { - type: String - }, - resetPasswordExpires: { - type: Date - } + firstName: { + type: String, + trim: true, + default: '', + validate: [validateLocalStrategyProperty, 'Please fill in your first name'] + }, + lastName: { + type: String, + trim: true, + default: '', + validate: [validateLocalStrategyProperty, 'Please fill in your last name'] + }, + displayName: { + type: String, + trim: true + }, + email: { + type: String, + trim: true, + unique: true, + default: '', + validate: [validateLocalStrategyEmail, 'Please fill a valid email address'] + }, + username: { + type: String, + unique: 'Username already exists', + required: 'Please fill in a username', + trim: true + }, + password: { + type: String, + default: '', + validate: [validateLocalStrategyPassword, 'Password should be longer'] + }, + salt: { + type: String + }, + profileImageURL: { + type: String, + default: 'modules/users/img/profile/default.png' + }, + provider: { + type: String, + required: 'Provider is required' + }, + providerData: {}, + additionalProvidersData: {}, + roles: { + type: [{ + type: String, + enum: ['user', 'admin'] + }], + default: ['user'] + }, + updated: { + type: Date + }, + created: { + type: Date, + default: Date.now + }, + /* For reset password */ + resetPasswordToken: { + type: String + }, + resetPasswordExpires: { + type: Date + } }); /** * Hook a pre save method to hash the password */ -UserSchema.pre('save', function(next) { - if (this.password && this.isModified('password') && this.password.length > 6) { - this.salt = crypto.randomBytes(16).toString('base64'); - this.password = this.hashPassword(this.password); - } +UserSchema.pre('save', function (next) { + if (this.password && this.isModified('password') && this.password.length > 6) { + this.salt = crypto.randomBytes(16).toString('base64'); + this.password = this.hashPassword(this.password); + } - next(); + next(); }); /** * Create instance method for hashing a password */ -UserSchema.methods.hashPassword = function(password) { - if (this.salt && password) { - return crypto.pbkdf2Sync(password, new Buffer(this.salt, 'base64'), 10000, 64).toString('base64'); - } else { - return password; - } +UserSchema.methods.hashPassword = function (password) { + if (this.salt && password) { + return crypto.pbkdf2Sync(password, new Buffer(this.salt, 'base64'), 10000, 64).toString('base64'); + } else { + return password; + } }; /** * Create instance method for authenticating user */ -UserSchema.methods.authenticate = function(password) { - return this.password === this.hashPassword(password); +UserSchema.methods.authenticate = function (password) { + return this.password === this.hashPassword(password); }; /** * Find possible not used username */ -UserSchema.statics.findUniqueUsername = function(username, suffix, callback) { - var _this = this; - var possibleUsername = username + (suffix || ''); +UserSchema.statics.findUniqueUsername = function (username, suffix, callback) { + var _this = this; + var possibleUsername = username + (suffix || ''); - _this.findOne({ - username: possibleUsername - }, function(err, user) { - if (!err) { - if (!user) { - callback(possibleUsername); - } else { - return _this.findUniqueUsername(username, (suffix || 0) + 1, callback); - } - } else { - callback(null); - } - }); + _this.findOne({ + username: possibleUsername + }, function (err, user) { + if (!err) { + if (!user) { + callback(possibleUsername); + } else { + return _this.findUniqueUsername(username, (suffix || 0) + 1, callback); + } + } else { + callback(null); + } + }); }; mongoose.model('User', UserSchema); diff --git a/modules/users/server/policies/admin.server.policy.js b/modules/users/server/policies/admin.server.policy.js index d7b7a43fdb..83dbc8957e 100644 --- a/modules/users/server/policies/admin.server.policy.js +++ b/modules/users/server/policies/admin.server.policy.js @@ -12,38 +12,38 @@ acl = new acl(new acl.memoryBackend()); * Invoke Admin Permissions */ exports.invokeRolesPolicies = function () { - acl.allow([{ - roles: ['admin'], - allows: [{ - resources: '/api/users', - permissions: '*' - }, { - resources: '/api/users/:userId', - permissions: '*' - }] - }]); + acl.allow([{ + roles: ['admin'], + allows: [{ + resources: '/api/users', + permissions: '*' + }, { + resources: '/api/users/:userId', + permissions: '*' + }] + }]); }; /** * Check If Admin Policy Allows */ exports.isAllowed = function (req, res, next) { - var roles = (req.user) ? req.user.roles : ['guest']; + var roles = (req.user) ? req.user.roles : ['guest']; - // Check for user roles - acl.areAnyRolesAllowed(roles, req.route.path, req.method.toLowerCase(), function (err, isAllowed) { - if (err) { - // An authorization error occurred. - return res.status(500).send('Unexpected authorization error'); - } else { - if (isAllowed) { - // Access granted! Invoke next middleware - return next(); - } else { - return res.status(403).json({ - message: 'User is not authorized' - }); - } - } - }); + // Check for user roles + acl.areAnyRolesAllowed(roles, req.route.path, req.method.toLowerCase(), function (err, isAllowed) { + if (err) { + // An authorization error occurred. + return res.status(500).send('Unexpected authorization error'); + } else { + if (isAllowed) { + // Access granted! Invoke next middleware + return next(); + } else { + return res.status(403).json({ + message: 'User is not authorized' + }); + } + } + }); }; diff --git a/modules/users/server/routes/admin.server.routes.js b/modules/users/server/routes/admin.server.routes.js index c98acb2ce6..1c3e5d2a46 100644 --- a/modules/users/server/routes/admin.server.routes.js +++ b/modules/users/server/routes/admin.server.routes.js @@ -4,22 +4,22 @@ * Module dependencies. */ var adminPolicy = require('../policies/admin.server.policy'), - admin = require('../controllers/admin.server.controller'); + admin = require('../controllers/admin.server.controller'); module.exports = function (app) { - // User route registration first. Ref: #713 - require('./users.server.routes.js')(app); + // User route registration first. Ref: #713 + require('./users.server.routes.js')(app); - // Users collection routes - app.route('/api/users') - .get(adminPolicy.isAllowed, admin.list); + // Users collection routes + app.route('/api/users') + .get(adminPolicy.isAllowed, admin.list); - // Single user routes - app.route('/api/users/:userId') - .get(adminPolicy.isAllowed, admin.read) - .put(adminPolicy.isAllowed, admin.update) - .delete(adminPolicy.isAllowed, admin.delete); + // Single user routes + app.route('/api/users/:userId') + .get(adminPolicy.isAllowed, admin.read) + .put(adminPolicy.isAllowed, admin.update) + .delete(adminPolicy.isAllowed, admin.delete); - // Finish by binding the user middleware - app.param('userId', admin.userByID); + // Finish by binding the user middleware + app.param('userId', admin.userByID); }; diff --git a/modules/users/server/routes/auth.server.routes.js b/modules/users/server/routes/auth.server.routes.js index 4c5ed66e54..a3ff220581 100644 --- a/modules/users/server/routes/auth.server.routes.js +++ b/modules/users/server/routes/auth.server.routes.js @@ -5,53 +5,53 @@ */ var passport = require('passport'); -module.exports = function(app) { - // User Routes - var users = require('../controllers/users.server.controller'); - - // Setting up the users password api - app.route('/api/auth/forgot').post(users.forgot); - app.route('/api/auth/reset/:token').get(users.validateResetToken); - app.route('/api/auth/reset/:token').post(users.reset); - - // Setting up the users authentication api - app.route('/api/auth/signup').post(users.signup); - app.route('/api/auth/signin').post(users.signin); - app.route('/api/auth/signout').get(users.signout); - - // Setting the facebook oauth routes - app.route('/api/auth/facebook').get(users.oauthCall('facebook', { - scope: ['email'] - })); - app.route('/api/auth/facebook/callback').get(users.oauthCallback('facebook')); - - // Setting the twitter oauth routes - app.route('/api/auth/twitter').get(users.oauthCall('twitter')); - app.route('/api/auth/twitter/callback').get(users.oauthCallback('twitter')); - - // Setting the google oauth routes - app.route('/api/auth/google').get(users.oauthCall('google', { - scope: [ - 'https://www.googleapis.com/auth/userinfo.profile', - 'https://www.googleapis.com/auth/userinfo.email' - ] - })); - app.route('/api/auth/google/callback').get(users.oauthCallback('google')); - - // Setting the linkedin oauth routes - app.route('/api/auth/linkedin').get(users.oauthCall('linkedin', { - scope: [ - 'r_basicprofile', - 'r_emailaddress' - ] - })); - app.route('/api/auth/linkedin/callback').get(users.oauthCallback('linkedin')); - - // Setting the github oauth routes - app.route('/api/auth/github').get(users.oauthCall('github')); - app.route('/api/auth/github/callback').get(users.oauthCallback('github')); - - // Setting the paypal oauth routes - app.route('/api/auth/paypal').get(users.oauthCall('paypal')); - app.route('/api/auth/paypal/callback').get(users.oauthCallback('paypal')); +module.exports = function (app) { + // User Routes + var users = require('../controllers/users.server.controller'); + + // Setting up the users password api + app.route('/api/auth/forgot').post(users.forgot); + app.route('/api/auth/reset/:token').get(users.validateResetToken); + app.route('/api/auth/reset/:token').post(users.reset); + + // Setting up the users authentication api + app.route('/api/auth/signup').post(users.signup); + app.route('/api/auth/signin').post(users.signin); + app.route('/api/auth/signout').get(users.signout); + + // Setting the facebook oauth routes + app.route('/api/auth/facebook').get(users.oauthCall('facebook', { + scope: ['email'] + })); + app.route('/api/auth/facebook/callback').get(users.oauthCallback('facebook')); + + // Setting the twitter oauth routes + app.route('/api/auth/twitter').get(users.oauthCall('twitter')); + app.route('/api/auth/twitter/callback').get(users.oauthCallback('twitter')); + + // Setting the google oauth routes + app.route('/api/auth/google').get(users.oauthCall('google', { + scope: [ + 'https://www.googleapis.com/auth/userinfo.profile', + 'https://www.googleapis.com/auth/userinfo.email' + ] + })); + app.route('/api/auth/google/callback').get(users.oauthCallback('google')); + + // Setting the linkedin oauth routes + app.route('/api/auth/linkedin').get(users.oauthCall('linkedin', { + scope: [ + 'r_basicprofile', + 'r_emailaddress' + ] + })); + app.route('/api/auth/linkedin/callback').get(users.oauthCallback('linkedin')); + + // Setting the github oauth routes + app.route('/api/auth/github').get(users.oauthCall('github')); + app.route('/api/auth/github/callback').get(users.oauthCallback('github')); + + // Setting the paypal oauth routes + app.route('/api/auth/paypal').get(users.oauthCall('paypal')); + app.route('/api/auth/paypal/callback').get(users.oauthCallback('paypal')); }; diff --git a/modules/users/server/routes/users.server.routes.js b/modules/users/server/routes/users.server.routes.js index 0feb276478..47cef3df49 100644 --- a/modules/users/server/routes/users.server.routes.js +++ b/modules/users/server/routes/users.server.routes.js @@ -1,16 +1,16 @@ 'use strict'; module.exports = function (app) { - // User Routes - var users = require('../controllers/users.server.controller'); + // User Routes + var users = require('../controllers/users.server.controller'); - // Setting up the users profile api - app.route('/api/users/me').get(users.me); - app.route('/api/users').put(users.update); - app.route('/api/users/accounts').delete(users.removeOAuthProvider); - app.route('/api/users/password').post(users.changePassword); - app.route('/api/users/picture').post(users.changeProfilePicture); + // Setting up the users profile api + app.route('/api/users/me').get(users.me); + app.route('/api/users').put(users.update); + app.route('/api/users/accounts').delete(users.removeOAuthProvider); + app.route('/api/users/password').post(users.changePassword); + app.route('/api/users/picture').post(users.changeProfilePicture); - // Finish by binding the user middleware - app.param('userId', users.userByID); + // Finish by binding the user middleware + app.param('userId', users.userByID); }; diff --git a/modules/users/server/templates/reset-password-confirm-email.server.view.html b/modules/users/server/templates/reset-password-confirm-email.server.view.html index baeddbf957..a52c32615b 100644 --- a/modules/users/server/templates/reset-password-confirm-email.server.view.html +++ b/modules/users/server/templates/reset-password-confirm-email.server.view.html @@ -5,12 +5,12 @@ -

    Dear {{name}},

    -

    -

    This is a confirmation that the password for your account has just been changed

    -
    -
    -

    The {{appName}} Support Team

    +

    Dear {{name}},

    +

    +

    This is a confirmation that the password for your account has just been changed

    +
    +
    +

    The {{appName}} Support Team

    diff --git a/modules/users/server/templates/reset-password-email.server.view.html b/modules/users/server/templates/reset-password-email.server.view.html index e5934a95af..590926fd25 100644 --- a/modules/users/server/templates/reset-password-email.server.view.html +++ b/modules/users/server/templates/reset-password-email.server.view.html @@ -6,17 +6,17 @@ -

    Dear {{name}},

    -
    -

    - You have requested to have your password reset for your account at {{appName}} -

    -

    Please visit this url to reset your password:

    -

    {{url}}

    - If you didn't make this request, you can ignore this email. -
    -
    -

    The {{appName}} Support Team

    +

    Dear {{name}},

    +
    +

    + You have requested to have your password reset for your account at {{appName}} +

    +

    Please visit this url to reset your password:

    +

    {{url}}

    + If you didn't make this request, you can ignore this email. +
    +
    +

    The {{appName}} Support Team

    diff --git a/modules/users/tests/client/authentication.client.controller.tests.js b/modules/users/tests/client/authentication.client.controller.tests.js index ac86701874..9322d23a8a 100644 --- a/modules/users/tests/client/authentication.client.controller.tests.js +++ b/modules/users/tests/client/authentication.client.controller.tests.js @@ -1,8 +1,8 @@ 'use strict'; -(function() { +(function () { // Authentication controller Spec - describe('AuthenticationController', function() { + describe('AuthenticationController', function () { // Initialize global variables var AuthenticationController, scope, @@ -10,11 +10,11 @@ $stateParams, $location; - beforeEach(function() { + beforeEach(function () { jasmine.addMatchers({ - toEqualData: function(util, customEqualityTesters) { + toEqualData: function (util, customEqualityTesters) { return { - compare: function(actual, expected) { + compare: function (actual, expected) { return { pass: angular.equals(actual, expected) }; @@ -27,11 +27,11 @@ // Load the main application module beforeEach(module(ApplicationConfiguration.applicationModuleName)); - describe('Logged out user', function() { + describe('Logged out user', function () { // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_). // This allows us to inject a service but then attach it to a variable // with the same name as the service. - beforeEach(inject(function($controller, $rootScope, _$location_, _$stateParams_, _$httpBackend_) { + beforeEach(inject(function ($controller, $rootScope, _$location_, _$stateParams_, _$httpBackend_) { // Set a new global scope scope = $rootScope.$new(); @@ -46,8 +46,8 @@ }); })); - describe('$scope.signin()', function() { - it('should login with a correct user and password', function() { + describe('$scope.signin()', function () { + it('should login with a correct user and password', function () { // Test expected GET request $httpBackend.when('POST', '/api/auth/signin').respond(200, 'Fred'); @@ -59,7 +59,7 @@ expect($location.url()).toEqual('/'); }); - it('should fail to log in with nothing', function() { + it('should fail to log in with nothing', function () { // Test expected POST request $httpBackend.expectPOST('/api/auth/signin').respond(400, { 'message': 'Missing credentials' @@ -72,7 +72,7 @@ expect(scope.error).toEqual('Missing credentials'); }); - it('should fail to log in with wrong credentials', function() { + it('should fail to log in with wrong credentials', function () { // Foo/Bar combo assumed to not exist scope.authentication.user = 'Foo'; scope.credentials = 'Bar'; @@ -90,8 +90,8 @@ }); }); - describe('$scope.signup()', function() { - it('should register with correct data', function() { + describe('$scope.signup()', function () { + it('should register with correct data', function () { // Test expected GET request scope.authentication.user = 'Fred'; $httpBackend.when('POST', '/api/auth/signup').respond(200, 'Fred'); @@ -105,7 +105,7 @@ expect($location.url()).toBe('/'); }); - it('should fail to register with duplicate Username', function() { + it('should fail to register with duplicate Username', function () { // Test expected POST request $httpBackend.when('POST', '/api/auth/signup').respond(400, { 'message': 'Username already exists' @@ -120,8 +120,8 @@ }); }); - describe('Logged in user', function() { - beforeEach(inject(function($controller, $rootScope, _$location_, _Authentication_) { + describe('Logged in user', function () { + beforeEach(inject(function ($controller, $rootScope, _$location_, _Authentication_) { scope = $rootScope.$new(); $location = _$location_; @@ -138,7 +138,7 @@ }); })); - it('should be redirected to home', function() { + it('should be redirected to home', function () { expect($location.path).toHaveBeenCalledWith('/'); }); }); diff --git a/modules/users/tests/e2e/users.e2e.tests.js b/modules/users/tests/e2e/users.e2e.tests.js index 920be6b4e0..d7b30c0411 100644 --- a/modules/users/tests/e2e/users.e2e.tests.js +++ b/modules/users/tests/e2e/users.e2e.tests.js @@ -1,13 +1,13 @@ 'use strict'; -describe('Users E2E Tests:', function() { - describe('Signin Validation', function() { - it('Should report missing credentials', function() { - browser.get('http://localhost:3000/authentication/signin'); - element(by.css('button[type=submit]')).click(); - element(by.binding('error')).getText().then(function(errorText) { - expect(errorText).toBe('Missing credentials'); - }); - }); - }); +describe('Users E2E Tests:', function () { + describe('Signin Validation', function () { + it('Should report missing credentials', function () { + browser.get('http://localhost:3000/authentication/signin'); + element(by.css('button[type=submit]')).click(); + element(by.binding('error')).getText().then(function (errorText) { + expect(errorText).toBe('Missing credentials'); + }); + }); + }); }); diff --git a/modules/users/tests/server/user.server.model.tests.js b/modules/users/tests/server/user.server.model.tests.js index 6a0db65257..d43320cf99 100644 --- a/modules/users/tests/server/user.server.model.tests.js +++ b/modules/users/tests/server/user.server.model.tests.js @@ -4,8 +4,8 @@ * Module dependencies. */ var should = require('should'), - mongoose = require('mongoose'), - User = mongoose.model('User'); + mongoose = require('mongoose'), + User = mongoose.model('User'); /** * Globals @@ -15,111 +15,111 @@ var user, user2, user3; /** * Unit tests */ -describe('User Model Unit Tests:', function() { - before(function(done) { - user = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: 'username', - password: 'password', - provider: 'local' - }); - user2 = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: 'username', - password: 'password', - provider: 'local' - }); - user3 = new User({ - firstName: 'Different', - lastName: 'User', - displayName: 'Full Different Name', - email: 'test3@test.com', - username: 'different_username', - password: 'different_password', - provider: 'local' - }); +describe('User Model Unit Tests:', function () { + before(function (done) { + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: 'username', + password: 'password', + provider: 'local' + }); + user2 = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: 'username', + password: 'password', + provider: 'local' + }); + user3 = new User({ + firstName: 'Different', + lastName: 'User', + displayName: 'Full Different Name', + email: 'test3@test.com', + username: 'different_username', + password: 'different_password', + provider: 'local' + }); - done(); - }); + done(); + }); - describe('Method Save', function() { - it('should begin with no users', function(done) { - User.find({}, function(err, users) { - users.should.have.length(0); - done(); - }); - }); + describe('Method Save', function () { + it('should begin with no users', function (done) { + User.find({}, function (err, users) { + users.should.have.length(0); + done(); + }); + }); - it('should be able to save without problems', function(done) { - user.save(done); - }); + it('should be able to save without problems', function (done) { + user.save(done); + }); - it('should fail to save an existing user again', function(done) { - user.save(function() { - user2.save(function(err) { - should.exist(err); - done(); - }); - }); - }); + it('should fail to save an existing user again', function (done) { + user.save(function () { + user2.save(function (err) { + should.exist(err); + done(); + }); + }); + }); - it('should be able to show an error when try to save without first name', function(done) { - user.firstName = ''; - return user.save(function(err) { - should.exist(err); - done(); - }); - }); + it('should be able to show an error when try to save without first name', function (done) { + user.firstName = ''; + return user.save(function (err) { + should.exist(err); + done(); + }); + }); - it('should confirm that saving user model doesnt change the password', function(done) { - user.firstName = 'test'; - var passwordBefore = user.password; - return user.save(function(err) { - var passwordAfter = user.password; - passwordBefore.should.equal(passwordAfter); - done(); - }); - }); + it('should confirm that saving user model doesnt change the password', function (done) { + user.firstName = 'test'; + var passwordBefore = user.password; + return user.save(function (err) { + var passwordAfter = user.password; + passwordBefore.should.equal(passwordAfter); + done(); + }); + }); - it('should be able to save 2 different users', function(done) { - user.remove(function(err) { - should.not.exist(err); - user.save(function(err) { - user3.save(function(err) { - should.not.exist(err); - user3.remove(function(err) { - should.not.exist(err); - done(); - }); - - }); - }); - }); - }); + it('should be able to save 2 different users', function (done) { + user.remove(function (err) { + should.not.exist(err); + user.save(function (err) { + user3.save(function (err) { + should.not.exist(err); + user3.remove(function (err) { + should.not.exist(err); + done(); + }); - it('should not be able to save different user with the same email address', function(done) { - user.remove(function(err) { - should.not.exist(err); - user.save(function(err) { - user3.email = user.email; - user3.save(function(err) { - should.exist(err); - done(); - }); - }); - }); + }); + }); + }); + }); - }); + it('should not be able to save different user with the same email address', function (done) { + user.remove(function (err) { + should.not.exist(err); + user.save(function (err) { + user3.email = user.email; + user3.save(function (err) { + should.exist(err); + done(); + }); + }); + }); - }); + }); - after(function(done) { - User.remove().exec(done); - }); + }); + + after(function (done) { + User.remove().exec(done); + }); }); diff --git a/modules/users/tests/server/user.server.routes.tests.js b/modules/users/tests/server/user.server.routes.tests.js index e897691aef..1bce3ee03d 100644 --- a/modules/users/tests/server/user.server.routes.tests.js +++ b/modules/users/tests/server/user.server.routes.tests.js @@ -1,11 +1,11 @@ 'use strict'; var should = require('should'), - request = require('supertest'), - path = require('path'), - mongoose = require('mongoose'), - User = mongoose.model('User'), - express = require(path.resolve('./config/lib/express')); + request = require('supertest'), + path = require('path'), + mongoose = require('mongoose'), + User = mongoose.model('User'), + express = require(path.resolve('./config/lib/express')); /** * Globals @@ -16,92 +16,92 @@ var app, agent, credentials, user, admin; * User routes tests */ describe('User CRUD tests', function () { - before(function (done) { - // Get application - app = express.init(mongoose); - agent = request.agent(app); - - done(); - }); - - beforeEach(function (done) { - // Create user credentials - credentials = { - username: 'username', - password: 'password' - }; - - // Create a new user - user = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: credentials.username, - password: credentials.password, - provider: 'local' - }); - - // Save a user to the test db and create new article - user.save(function () { - done(); - }); - }); - - it('should not be able to retrieve a list of users if not admin', function (done) { - agent.post('/api/auth/signin') - .send(credentials) - .expect(200) - .end(function (signinErr, signinRes) { - // Handle signin error - if (signinErr) { - return done(signinErr); - } - - // Save a new article - agent.get('/api/users') - .expect(403) - .end(function (usersGetErr, usersGetRes) { - if (usersGetErr) { - return done(usersGetErr); - } - - return done(); - }); - }); - }); - - it('should be able to retrieve a list of users if admin', function (done) { - user.roles = ['user', 'admin']; - - user.save(function () { - agent.post('/api/auth/signin') - .send(credentials) - .expect(200) - .end(function (signinErr, signinRes) { - // Handle signin error - if (signinErr) { - return done(signinErr); - } - - // Save a new article - agent.get('/api/users') - .expect(200) - .end(function (usersGetErr, usersGetRes) { - if (usersGetErr) { - return done(usersGetErr); - } - - usersGetRes.body.should.be.instanceof(Array).and.have.lengthOf(1); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - afterEach(function (done) { - User.remove().exec(done); - }); + before(function (done) { + // Get application + app = express.init(mongoose); + agent = request.agent(app); + + done(); + }); + + beforeEach(function (done) { + // Create user credentials + credentials = { + username: 'username', + password: 'password' + }; + + // Create a new user + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: credentials.username, + password: credentials.password, + provider: 'local' + }); + + // Save a user to the test db and create new article + user.save(function () { + done(); + }); + }); + + it('should not be able to retrieve a list of users if not admin', function (done) { + agent.post('/api/auth/signin') + .send(credentials) + .expect(200) + .end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) { + return done(signinErr); + } + + // Save a new article + agent.get('/api/users') + .expect(403) + .end(function (usersGetErr, usersGetRes) { + if (usersGetErr) { + return done(usersGetErr); + } + + return done(); + }); + }); + }); + + it('should be able to retrieve a list of users if admin', function (done) { + user.roles = ['user', 'admin']; + + user.save(function () { + agent.post('/api/auth/signin') + .send(credentials) + .expect(200) + .end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) { + return done(signinErr); + } + + // Save a new article + agent.get('/api/users') + .expect(200) + .end(function (usersGetErr, usersGetRes) { + if (usersGetErr) { + return done(usersGetErr); + } + + usersGetRes.body.should.be.instanceof(Array).and.have.lengthOf(1); + + // Call the assertion callback + done(); + }); + }); + }); + }); + + afterEach(function (done) { + User.remove().exec(done); + }); }); diff --git a/protractor.conf.js b/protractor.conf.js index a2308500e5..cf92640b55 100644 --- a/protractor.conf.js +++ b/protractor.conf.js @@ -2,5 +2,5 @@ // Protractor configuration exports.config = { - specs: ['modules/*/tests/e2e/*.js'] + specs: ['modules/*/tests/e2e/*.js'] };