diff --git a/.editorconfig b/.editorconfig index 61617beec8..636ceea4c0 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,9 +14,7 @@ insert_final_newline = true # Standard at: https://github.com/felixge/node-style-guide [**.js, **.json] trim_trailing_whitespace = true -indent_style = space -indent_size = 2 -max_line_length = 80 +indent_style = tab quote_type = single curly_bracket_next_line = false spaces_around_operators = true @@ -24,26 +22,15 @@ space_after_control_statements = true space_after_anonymous_functions = false spaces_in_brackets = false -# https://github.com/jedmao/codepainter -[node_modules/**.js] -codepaint = false - # No Standard. Please document a standard if different from .js [**.yml, **.html, **.css] trim_trailing_whitespace = true -indent_style = space -indent_size = 2 +indent_style = tab # No standard. Please document a standard if different from .js [**.md] -indent_style = space - -# Standard at: -[**.py] -indent_style = space -indent_size = 4 +indent_style = tab # Standard at: [Makefile] -indent_style = tab -indent_size = 8 +indent_style = tab \ No newline at end of file diff --git a/README.md b/README.md index 68ab3dafe9..bf0b133e0f 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,14 @@ $ $ docker run -p 3000:3000 -p 35729:35729 -v /Users/mdl/workspace/mean-stack/mean/public:/home/mean/public -v /Users/mdl/workspace/mean-stack/mean/app:/home/mean/app --link db:db_1 mean ``` +## Running in a secure environment +To run your application in a secure manner you'll need to use OpenSSL and generate a set of self-signed certificates. Unix-based users can use the following commnad: +``` +$ sh generate-ssl-certs.sh +``` +Windows users can follow instructions found [here](http://www.websense.com/support/article/kbarticle/How-to-use-OpenSSL-and-Microsoft-Certification-Authority) +To generate the key and certificate and place them in the [config/sslcerts](config/sslcerts) folder. + ## Getting Started With MEAN.JS You have your application running but there are a lot of stuff to understand, we recommend you'll go over the [Official Documentation](http://meanjs.org/docs.html). In the docs we'll try to explain both general concepts of MEAN components and give you some guidelines to help you improve your development process. We tried covering as many aspects as possible, and will keep update it by your request, you can also help us develop the documentation better by checking out the *gh-pages* branch of this repository. diff --git a/app/controllers/errors.server.controller.js b/app/controllers/errors.server.controller.js index 935a9299d4..41078b4d3a 100644 --- a/app/controllers/errors.server.controller.js +++ b/app/controllers/errors.server.controller.js @@ -10,7 +10,7 @@ var getUniqueErrorMessage = function(err) { var fieldName = err.err.substring(err.err.lastIndexOf('.$') + 2, err.err.lastIndexOf('_1')); output = fieldName.charAt(0).toUpperCase() + fieldName.slice(1) + ' already exists'; - } catch(ex) { + } catch (ex) { output = 'Unique field already exists'; } @@ -22,7 +22,7 @@ var getUniqueErrorMessage = function(err) { */ exports.getErrorMessage = function(err) { var message = ''; - + if (err.code) { switch (err.code) { case 11000: @@ -39,4 +39,4 @@ exports.getErrorMessage = function(err) { } return message; -}; +}; \ No newline at end of file diff --git a/app/controllers/users/users.password.server.controller.js b/app/controllers/users/users.password.server.controller.js index d857cd13f6..1d4ae65e8a 100644 --- a/app/controllers/users/users.password.server.controller.js +++ b/app/controllers/users/users.password.server.controller.js @@ -174,7 +174,7 @@ exports.reset = function(req, res, next) { subject: 'Your password has been changed', html: emailHTML }; - + smtpTransport.sendMail(mailOptions, function(err) { done(err, 'done'); }); @@ -242,4 +242,4 @@ exports.changePassword = function(req, res) { message: 'User is not signed in' }); } -}; +}; \ No newline at end of file diff --git a/app/models/user.server.model.js b/app/models/user.server.model.js index 76ff071ba2..9370da01c6 100755 --- a/app/models/user.server.model.js +++ b/app/models/user.server.model.js @@ -86,9 +86,9 @@ var UserSchema = new Schema({ resetPasswordToken: { type: String }, - resetPasswordExpires: { - type: Date - } + resetPasswordExpires: { + type: Date + } }); /** diff --git a/app/routes/users.server.routes.js b/app/routes/users.server.routes.js index bd0a361fed..3120e9abb6 100644 --- a/app/routes/users.server.routes.js +++ b/app/routes/users.server.routes.js @@ -47,11 +47,11 @@ module.exports = function(app) { // Setting the linkedin oauth routes app.route('/auth/linkedin').get(passport.authenticate('linkedin')); app.route('/auth/linkedin/callback').get(users.oauthCallback('linkedin')); - + // Setting the github oauth routes app.route('/auth/github').get(passport.authenticate('github')); app.route('/auth/github/callback').get(users.oauthCallback('github')); // Finish by binding the user middleware app.param('userId', users.userByID); -}; +}; \ No newline at end of file diff --git a/app/tests/article.server.routes.test.js b/app/tests/article.server.routes.test.js index 160f19e0ed..2576095ae1 100644 --- a/app/tests/article.server.routes.test.js +++ b/app/tests/article.server.routes.test.js @@ -1,219 +1,269 @@ 'use strict'; var should = require('should'), - request = require('supertest'), - app = require('../../server'), - mongoose = require('mongoose'), - User = mongoose.model('User'), - Article = mongoose.model('Article'), - // note: the agent allows us to preserve a session and cookies for the logged in user - agent = request.agent(app); - + request = require('supertest'), + app = require('../../server'), + mongoose = require('mongoose'), + User = mongoose.model('User'), + Article = mongoose.model('Article'), + agent = request.agent(app); /** * Globals */ -var user, article; - -describe('Article CRUD tests', function () { - - beforeEach(function(done) { - // saves a user to the test db. - user = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: 'username', - password: 'password', - provider: 'local' - }); - user.save(); - - article = new Article({ - title: 'Article Title', - content: 'Article Content', - user: user - }); - - done(); - }); - - // ------------ CREATE (SAVE) operations ------------ - it('should be able to save an article if logged in', function (done) { - agent - .post('/auth/signin') - .send(user) - .end(function (err, res){ - var userId = res.body._id; - agent - .post('/articles') - .send(article) - .expect(200) - .end(function (err, res) { - agent - .get('/articles') - .end(function(error, res) { - (res.body[0].user._id).should.equal(userId); - (res.body[0].title).should.match('Article Title'); - done(); - }); - }); - }); - }); - - - it('should not be able to save an article if not logged in', function (done) { - agent - .post('/articles') - .send(article) - .expect(200) - .end(function (err, res) { - should.exist(err); - (res.status).should.equal(401); - (res.unauthorized).should.equal(true); - done(); - }); - }); - - it('should not be able to save an article if no title is provided', function (done) { - article.title = ''; - agent - .post('/auth/signin') - .send(user) - .end(function (err, res){ - agent - .post('/articles') - .send(article) - .expect(200) - .end(function (err, res) { - should.exist(err); - (res.body.message).should.match('Title cannot be blank'); - done(); - }); - }); - }); - - - // ------------ PUT (UPDATE) operations ------------ - it('should be able to update an article if signed in', function(done){ - agent - .post('/auth/signin') - .send(user) - .end(function (err, res){ - var userId = res.body._id; - agent - .post('/articles') - .send(article) - .expect(200) - .end(function (err, res) { - agent - .get('/articles') - .end(function(error, res) { - (res.body[0].user._id).should.equal(userId); - (res.body[0].title).should.match('Article Title'); - var article_Id = res.body[0]._id; - article.title = 'WHY YOU GOTTA BE SO MEAN?'; - agent - .put('/articles/' + article_Id) - .send(article) - .end(function (err, res) { - (res.body._id).should.equal(article_Id); - (res.body.title).should.match('WHY YOU GOTTA BE SO MEAN?'); - done(); - }); - }); - }); - }); - }); - - // ------------ READ operations ------------ - it('should be able to get a list of articles if not signed in', function (done) { - // Adding 10 articles to the db - var numArticles = 10; - while (numArticles--) { - var article = new Article({ - title: numArticles + ' Another Article Title', - content: numArticles + ' Another Article Content', - user: user - }); - article.save(); - } - - // note there is no need to use the supertest agent here as we do not need to be signed in - request(app) - .get('/articles') - .end(function (req, res) { - (res.body[0].title).should.match('0 Another Article Title'); - done(); - }); - - }); - - - it('should be able to get a single article if not signed in', function (done) { - var article = new Article({ - title: 'Another Article Title', - content: 'Another Article Content', - user: user - }); - article.save(); - - request(app) - .get('/articles/' + article._id) - .end(function (req, res) { - (res.body.title).should.match('Another Article Title'); - done(); - }); - - }); - - // ------------ DELETE operations ------------ - it('should be able to delete an article if signed in', function (done) { - var article = new Article({ - title: 'Another Article Title', - content: 'Another Article Content', - user: user - }); - article.save(); - - agent - .post('/auth/signin') - .send(user) - .end(function (err, res) { - (err === null).should.equal(true); - agent - .delete('/articles/' + article._id) - .end(function (err, res) { - (res.req.method).should.match('DELETE'); - (res.body.title).should.match('Another Article Title'); - done(); - }); - }); - }); - - it('should not be able to delete an article if not signed in', function (done) { - var article = new Article({ - title: 'Another Article Title', - content: 'Another Article Content', - user: user - }); - article.save(); - - request(app) - .delete('/articles/' + article._id) - .end(function (err, res) { - (res.req.method).should.match('DELETE'); - (res.status).should.equal(401); - (res.unauthorized).should.equal(true); - done(); - }); - }); - - afterEach(function(done) { - User.remove().exec(); - Article.remove().exec(); - done(); - }); +var credentials, user, article; + +/** + * Article routes tests + */ +describe('Article CRUD tests', function() { + 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('/auth/signin') + .send(credentials) + .expect(200) + .end(function(signinErr, signinRes) { + // Handle signin error + if (signinErr) done(signinErr); + + // Get the userId + var userId = user.id; + + // Save a new article + agent.post('/articles') + .send(article) + .expect(200) + .end(function(articleSaveErr, articleSaveRes) { + // Handle article save error + if (articleSaveErr) done(articleSaveErr); + + // Get a list of articles + agent.get('/articles') + .end(function(articlesGetErr, articlesGetRes) { + // Handle article save error + if (articlesGetErr) 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('/articles') + .send(article) + .expect(401) + .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('/auth/signin') + .send(credentials) + .expect(200) + .end(function(signinErr, signinRes) { + // Handle signin error + if (signinErr) done(signinErr); + + // Get the userId + var userId = user.id; + + // Save a new article + agent.post('/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('/auth/signin') + .send(credentials) + .expect(200) + .end(function(signinErr, signinRes) { + // Handle signin error + if (signinErr) done(signinErr); + + // Get the userId + var userId = user.id; + + // Save a new article + agent.post('/articles') + .send(article) + .expect(200) + .end(function(articleSaveErr, articleSaveRes) { + // Handle article save error + if (articleSaveErr) done(articleSaveErr); + + // Update article title + article.title = 'WHY YOU GOTTA BE SO MEAN?'; + + // Update an existing article + agent.put('/articles/' + articleSaveRes.body._id) + .send(article) + .expect(200) + .end(function(articleUpdateErr, articleUpdateRes) { + // Handle article update error + if (articleUpdateErr) 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('/articles') + .end(function(req, res) { + // Set assertion + res.body.should.be.an.Array.with.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('/articles/' + articleObj._id) + .end(function(req, res) { + // Set assertion + res.body.should.be.an.Object.with.property('title', article.title); + + // Call the assertion callback + done(); + }); + }); + }); + + it('should be able to delete an article if signed in', function(done) { + agent.post('/auth/signin') + .send(credentials) + .expect(200) + .end(function(signinErr, signinRes) { + // Handle signin error + if (signinErr) done(signinErr); + + // Get the userId + var userId = user.id; + + // Save a new article + agent.post('/articles') + .send(article) + .expect(200) + .end(function(articleSaveErr, articleSaveRes) { + // Handle article save error + if (articleSaveErr) done(articleSaveErr); + + // Delete an existing article + agent.delete('/articles/' + articleSaveRes.body._id) + .send(article) + .expect(200) + .end(function(articleDeleteErr, articleDeleteRes) { + // Handle article error error + if (articleDeleteErr) 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('/articles/' + articleObj._id) + .expect(401) + .end(function(articleDeleteErr, articleDeleteRes) { + // Set message assertion + (articleDeleteRes.body.message).should.match('User is not logged in'); + + // Handle article error error + done(articleDeleteErr); + }); + + }); + }); + afterEach(function(done) { + User.remove().exec(); + Article.remove().exec(); + done(); + }); }); \ No newline at end of file diff --git a/app/views/layout.server.view.html b/app/views/layout.server.view.html index b831bf2853..9f47509e80 100644 --- a/app/views/layout.server.view.html +++ b/app/views/layout.server.view.html @@ -35,8 +35,7 @@ - {% for cssFile in cssFiles %} - {% endfor %} + {% for cssFile in cssFiles %}{% endfor %} - {% for jsFile in jsFiles %} - {% endfor %} + {% for jsFile in jsFiles %}{% endfor %} {% if process.env.NODE_ENV === 'development' %} - {% endif %} diff --git a/app/views/templates/reset-password-confirm-email.server.view.html b/app/views/templates/reset-password-confirm-email.server.view.html index eec61a672c..626ddc3fa4 100644 --- a/app/views/templates/reset-password-confirm-email.server.view.html +++ b/app/views/templates/reset-password-confirm-email.server.view.html @@ -1,9 +1,7 @@ - -

Dear {{name}},

@@ -12,5 +10,4 @@

The {{appName}} Support Team

- \ No newline at end of file diff --git a/app/views/templates/reset-password-email.server.view.html b/app/views/templates/reset-password-email.server.view.html index eb73cb83e3..262edf0020 100644 --- a/app/views/templates/reset-password-email.server.view.html +++ b/app/views/templates/reset-password-email.server.view.html @@ -1,11 +1,8 @@ - - -

Dear {{name}},


@@ -18,5 +15,4 @@

The {{appName}} Support Team

- \ No newline at end of file diff --git a/config/env/secure.js b/config/env/secure.js index 0b52f3a4e8..20cd8256ca 100644 --- a/config/env/secure.js +++ b/config/env/secure.js @@ -1,60 +1,59 @@ 'use strict'; module.exports = { - secure: true, - port: 443, - db: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://localhost/mean', - assets: { - 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' - ] - }, - css: 'public/dist/application.min.css', - js: 'public/dist/application.min.js' - }, - facebook: { - clientID: process.env.FACEBOOK_ID || 'APP_ID', - clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET', - callbackURL: 'https://localhost:443/auth/facebook/callback' - }, - twitter: { - clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY', - clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET', - callbackURL: 'https://localhost:443/auth/twitter/callback' - }, - google: { - clientID: process.env.GOOGLE_ID || 'APP_ID', - clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET', - callbackURL: 'https://localhost:443/auth/google/callback' - }, - linkedin: { - clientID: process.env.LINKEDIN_ID || 'APP_ID', - clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET', - callbackURL: 'https://localhost:443/auth/linkedin/callback' - }, - github: { - clientID: process.env.GITHUB_ID || 'APP_ID', - clientSecret: process.env.GITHUB_SECRET || 'APP_SECRET', - callbackURL: 'https://localhost:443/auth/github/callback' - }, - 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' - } - } - } -}; + port: 443, + db: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://localhost/mean', + assets: { + 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' + ] + }, + css: 'public/dist/application.min.css', + js: 'public/dist/application.min.js' + }, + facebook: { + clientID: process.env.FACEBOOK_ID || 'APP_ID', + clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET', + callbackURL: 'https://localhost:443/auth/facebook/callback' + }, + twitter: { + clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY', + clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET', + callbackURL: 'https://localhost:443/auth/twitter/callback' + }, + google: { + clientID: process.env.GOOGLE_ID || 'APP_ID', + clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET', + callbackURL: 'https://localhost:443/auth/google/callback' + }, + linkedin: { + clientID: process.env.LINKEDIN_ID || 'APP_ID', + clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET', + callbackURL: 'https://localhost:443/auth/linkedin/callback' + }, + github: { + clientID: process.env.GITHUB_ID || 'APP_ID', + clientSecret: process.env.GITHUB_SECRET || 'APP_SECRET', + callbackURL: 'https://localhost:443/auth/github/callback' + }, + 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' + } + } + } +}; \ No newline at end of file diff --git a/config/express.js b/config/express.js index 383c88983a..46cf0dc2a3 100755 --- a/config/express.js +++ b/config/express.js @@ -5,7 +5,8 @@ */ var fs = require('fs'), http = require('http'), - express = require('express'), + https = require('https'), + express = require('express'), morgan = require('morgan'), bodyParser = require('body-parser'), session = require('express-session'), @@ -38,7 +39,6 @@ module.exports = function(db) { app.locals.facebookAppId = config.facebook.clientID; app.locals.jsFiles = config.getJavaScriptAssets(); app.locals.cssFiles = config.getCSSAssets(); - app.locals.secure = config.secure; // Passing the request url to environment locals app.use(function(req, res, next) { @@ -140,17 +140,24 @@ module.exports = function(db) { }); }); - if (app.locals.secure) { + if (process.env.NODE_ENV === 'secure') { + // Log SSL usage console.log('Securely using https protocol'); - var https = require('https'), - privateKey = fs.readFileSync('./config/sslcert/key.pem', 'utf8'), - certificate = fs.readFileSync('./config/sslcert/cert.pem', 'utf8'), - credentials = {key: privateKey, cert: certificate}, - httpsServer = https.createServer(credentials, app); + + // Load SSL key and certificate + var privateKey = fs.readFileSync('./config/sslcerts/key.pem', 'utf8'); + var certificate = fs.readFileSync('./config/sslcerts/cert.pem', 'utf8'); + + // Create HTTPS Server + var httpsServer = https.createServer({ + key: privateKey, + cert: certificate + }, app); + + // Return HTTPS server instance return httpsServer; - } else { - console.log('Insecurely using http protocol'); - var httpServer = http.createServer(app); - return httpServer; } -}; + + // Return Express server instance + return app; +}; \ No newline at end of file diff --git a/config/init.js b/config/init.js index 9b129275e1..6facd9d0f8 100644 --- a/config/init.js +++ b/config/init.js @@ -29,5 +29,5 @@ module.exports = function() { console.log(chalk.black.bgWhite('Application loaded using the "' + process.env.NODE_ENV + '" environment configuration')); } }); - + }; \ No newline at end of file diff --git a/config/passport.js b/config/passport.js index 9e3a31ae5a..fabbf77c05 100755 --- a/config/passport.js +++ b/config/passport.js @@ -1,10 +1,16 @@ 'use strict'; +/** + * Module dependencies. + */ var passport = require('passport'), User = require('mongoose').model('User'), path = require('path'), config = require('./config'); - + +/** + * Module init function. + */ module.exports = function() { // Serialize sessions passport.serializeUser(function(user, done) { diff --git a/config/sslcert/gen-certs b/config/sslcert/gen-certs deleted file mode 100755 index 70519705fd..0000000000 --- a/config/sslcert/gen-certs +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -echo "Generating self-signed certificates..." -openssl genrsa -out key.pem -aes256 1024 -openssl req -new -key key.pem -out csr.pem -openssl x509 -req -days 9999 -in csr.pem -signkey key.pem -out cert.pem -rm csr.pem -chmod 600 key.pem cert.pem diff --git a/config/strategies/local.js b/config/strategies/local.js index ad56052422..7101cac2bc 100644 --- a/config/strategies/local.js +++ b/config/strategies/local.js @@ -35,4 +35,4 @@ module.exports = function() { }); } )); -}; +}; \ No newline at end of file diff --git a/generate-ssl-certs.sh b/generate-ssl-certs.sh new file mode 100644 index 0000000000..fda44bb0c4 --- /dev/null +++ b/generate-ssl-certs.sh @@ -0,0 +1,7 @@ +#!/bin/bash +echo "Generating self-signed certificates..." +openssl genrsa -out ./config/sslcerts/key.pem -aes256 1024 +openssl req -new -key ./config/sslcerts/key.pem -out ./config/sslcerts/csr.pem +openssl x509 -req -days 9999 -in ./config/sslcerts/csr.pem -signkey ./config/sslcerts/key.pem -out ./config/sslcerts/cert.pem +rm ./config/sslcerts/csr.pem +chmod 600 ./config/sslcerts/key.pem ./config/sslcerts/cert.pem diff --git a/gruntfile.js b/gruntfile.js index 9bd7a8c61a..4555485743 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -105,13 +105,13 @@ module.exports = function(grunt) { } } }, - ngAnnotate: { - production: { - files: { - 'public/dist/application.js': '<%= applicationJavaScriptFiles %>' - } - } - }, + ngAnnotate: { + production: { + files: { + 'public/dist/application.js': '<%= applicationJavaScriptFiles %>' + } + } + }, concurrent: { default: ['nodemon', 'watch'], debug: ['nodemon', 'watch', 'node-inspector'], @@ -123,6 +123,9 @@ module.exports = function(grunt) { env: { test: { NODE_ENV: 'test' + }, + secure: { + NODE_ENV: 'secure' } }, mochaTest: { @@ -160,6 +163,9 @@ module.exports = function(grunt) { // Debug task. grunt.registerTask('debug', ['lint', 'concurrent:debug']); + // Secure task(s). + grunt.registerTask('secure', ['env:secure', 'lint', 'concurrent:default']); + // Lint task(s). grunt.registerTask('lint', ['jshint', 'csslint']); @@ -168,4 +174,4 @@ module.exports = function(grunt) { // Test task. grunt.registerTask('test', ['env:test', 'mochaTest', 'karma:unit']); -}; +}; \ No newline at end of file diff --git a/package.json b/package.json index 1e6474d11f..1055b88c6b 100755 --- a/package.json +++ b/package.json @@ -70,4 +70,4 @@ "karma-firefox-launcher": "~0.1.3", "karma-phantomjs-launcher": "~0.1.2" } -} +} \ No newline at end of file diff --git a/public/dist/application.js b/public/dist/application.js index 4e9506e403..4d0efe1ece 100644 --- a/public/dist/application.js +++ b/public/dist/application.js @@ -53,7 +53,6 @@ ApplicationConfiguration.registerModule('core'); // Use Applicaion configuration module to register a new module ApplicationConfiguration.registerModule('users'); - 'use strict'; // Configuring the Articles module @@ -566,10 +565,10 @@ angular.module('users').controller('SettingsController', ['$scope', '$http', '$l // Update a user profile $scope.updateUserProfile = function(isValid) { - if (isValid){ + if (isValid) { $scope.success = $scope.error = null; var user = new Users($scope.user); - + user.$update(function(response) { $scope.success = true; Authentication.user = response; @@ -595,12 +594,10 @@ angular.module('users').controller('SettingsController', ['$scope', '$http', '$l }; } ]); - 'use strict'; // Authentication service for user variables angular.module('users').factory('Authentication', [ - function() { var _this = this; diff --git a/public/modules/core/css/core.css b/public/modules/core/css/core.css index a352d4fc47..c510891448 100644 --- a/public/modules/core/css/core.css +++ b/public/modules/core/css/core.css @@ -7,9 +7,9 @@ [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-valid.ng-dirty{ - border-color:#78FA89; +.ng-invalid.ng-dirty { + border-color: #FA787E; } +.ng-valid.ng-dirty { + border-color: #78FA89; +} \ No newline at end of file diff --git a/public/modules/core/views/home.client.view.html b/public/modules/core/views/home.client.view.html index 3f8242f280..64b968b147 100644 --- a/public/modules/core/views/home.client.view.html +++ b/public/modules/core/views/home.client.view.html @@ -91,4 +91,4 @@

MEAN.JS Documentation


Enjoy & Keep Us Updated,
The MEAN.JS Team. - + \ No newline at end of file diff --git a/public/modules/users/controllers/settings.client.controller.js b/public/modules/users/controllers/settings.client.controller.js index 1d4b4e92a0..8616fc9463 100644 --- a/public/modules/users/controllers/settings.client.controller.js +++ b/public/modules/users/controllers/settings.client.controller.js @@ -40,10 +40,10 @@ angular.module('users').controller('SettingsController', ['$scope', '$http', '$l // Update a user profile $scope.updateUserProfile = function(isValid) { - if (isValid){ + if (isValid) { $scope.success = $scope.error = null; var user = new Users($scope.user); - + user.$update(function(response) { $scope.success = true; Authentication.user = response; @@ -68,4 +68,4 @@ angular.module('users').controller('SettingsController', ['$scope', '$http', '$l }); }; } -]); +]); \ No newline at end of file diff --git a/public/modules/users/css/users.css b/public/modules/users/css/users.css index 7dd49e2173..de67bf94f5 100644 --- a/public/modules/users/css/users.css +++ b/public/modules/users/css/users.css @@ -3,14 +3,12 @@ position: fixed; } } - .remove-account-container { display: inline-block; position: relative; } - .btn-remove-account { top: 10px; right: 10px; position: absolute; -} +} \ No newline at end of file diff --git a/public/modules/users/services/authentication.client.service.js b/public/modules/users/services/authentication.client.service.js index 2cbe0d8716..4418b2d7fd 100644 --- a/public/modules/users/services/authentication.client.service.js +++ b/public/modules/users/services/authentication.client.service.js @@ -2,7 +2,6 @@ // Authentication service for user variables angular.module('users').factory('Authentication', [ - function() { var _this = this; diff --git a/public/modules/users/users.client.module.js b/public/modules/users/users.client.module.js index 569aba8c16..b11998607b 100755 --- a/public/modules/users/users.client.module.js +++ b/public/modules/users/users.client.module.js @@ -1,4 +1,4 @@ 'use strict'; // Use Applicaion configuration module to register a new module -ApplicationConfiguration.registerModule('users'); +ApplicationConfiguration.registerModule('users'); \ No newline at end of file diff --git a/public/modules/users/views/authentication/signin.client.view.html b/public/modules/users/views/authentication/signin.client.view.html index 8543b8f472..91e256eff2 100644 --- a/public/modules/users/views/authentication/signin.client.view.html +++ b/public/modules/users/views/authentication/signin.client.view.html @@ -42,4 +42,4 @@

Or with your account

- + \ No newline at end of file diff --git a/public/modules/users/views/password/forgot-password.client.view.html b/public/modules/users/views/password/forgot-password.client.view.html index fc7763c04b..e6275f941f 100644 --- a/public/modules/users/views/password/forgot-password.client.view.html +++ b/public/modules/users/views/password/forgot-password.client.view.html @@ -1,22 +1,22 @@
-

Restore your password

-

Enter your account username.

-
- + +
\ No newline at end of file diff --git a/public/modules/users/views/password/reset-password.client.view.html b/public/modules/users/views/password/reset-password.client.view.html index 69d1f346d2..dc8b2ea0c4 100644 --- a/public/modules/users/views/password/reset-password.client.view.html +++ b/public/modules/users/views/password/reset-password.client.view.html @@ -1,26 +1,26 @@
-

Reset your password

-
- -
-
+

Reset your password

+
+
+
+
+ + +
+
+ + +
+
+ +
+
+ {{error}} +
+
+ {{success}} +
+
+
+
+ \ No newline at end of file diff --git a/public/modules/users/views/settings/edit-profile.client.view.html b/public/modules/users/views/settings/edit-profile.client.view.html index cfeac6a609..a4be680f41 100644 --- a/public/modules/users/views/settings/edit-profile.client.view.html +++ b/public/modules/users/views/settings/edit-profile.client.view.html @@ -31,4 +31,4 @@

Edit your profile

- + \ No newline at end of file