From 2ac17f78681982ed38051de65d04c2280d07be44 Mon Sep 17 00:00:00 2001 From: jloveland Date: Thu, 14 Aug 2014 20:28:24 -0500 Subject: [PATCH 1/3] adding https option for running with TLS/SSL --- .gitignore | 1 + README.md | 42 +++++++++++++++++++++++++++++---------- config/env/all.js | 3 ++- config/env/development.js | 2 +- config/env/production.js | 14 +++++++------ config/express.js | 21 +++++++++++++++++--- config/sslcert/gen-certs | 7 +++++++ 7 files changed, 69 insertions(+), 21 deletions(-) create mode 100755 config/sslcert/gen-certs diff --git a/.gitignore b/.gitignore index 3c36febe..79f6cf28 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ public/lib app/tests/coverage/ .bower-*/ .idea/ +config/sslcert/*.pem diff --git a/README.md b/README.md index dec285d1..58a6e618 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,10 @@ [![Build Status](https://travis-ci.org/meanjs/mean.svg?branch=master)](https://travis-ci.org/meanjs/mean) [![Dependencies Status](https://david-dm.org/meanjs/mean.svg)](https://david-dm.org/meanjs/mean) -MEAN.JS is a full-stack JavaScript open-source solution, which provides a solid starting point for [MongoDB](http://www.mongodb.org/), [Node.js](http://www.nodejs.org/), [Express](http://expressjs.com/), and [AngularJS](http://angularjs.org/) based applications. The idea is to solve the common issues with connecting those frameworks, build a robust framework to support daily development needs, and help developers use better practices while working with popular JavaScript components. +MEAN.JS is a full-stack JavaScript open-source solution, which provides a solid starting point for [MongoDB](http://www.mongodb.org/), [Node.js](http://www.nodejs.org/), [Express](http://expressjs.com/), and [AngularJS](http://angularjs.org/) based applications. The idea is to solve the common issues with connecting those frameworks, build a robust framework to support daily development needs, and help developers use better practices while working with popular JavaScript components. -## Before You Begin -Before you begin we recommend you read about the basic building blocks that assemble a MEAN.JS application: +## Before You Begin +Before you begin we recommend you read about the basic building blocks that assemble a MEAN.JS application: * MongoDB - Go through [MongoDB Official Website](http://mongodb.org/) and proceed to their [Official Manual](http://docs.mongodb.org/manual/), which should help you understand NoSQL and MongoDB better. * Express - The best way to understand express is through its [Official Website](http://expressjs.com/), particularly [The Express Guide](http://expressjs.com/guide.html); you can also go through this [StackOverflow Thread](http://stackoverflow.com/questions/8144214/learning-express-for-node-js) for more resources. * AngularJS - Angular's [Official Website](http://angularjs.org/) is a great starting point. You can also use [Thinkster Popular Guide](http://www.thinkster.io/), and the [Egghead Videos](https://egghead.io/). @@ -30,9 +30,9 @@ $ sudo npm install -g grunt-cli ``` ## Downloading MEAN.JS -There are several ways you can get the MEAN.JS boilerplate: +There are several ways you can get the MEAN.JS boilerplate: -### Yo Generator +### Yo Generator The recommended way would be to use the [Official Yo Generator](http://meanjs.org/generator.html) which will generate the latest stable copy of the MEAN.JS boilerplate and supplies multiple sub-generators to ease your daily development cycles. ### Cloning The GitHub Repository @@ -73,16 +73,38 @@ $ grunt ``` Your application should run on the 3000 port so in your browser just go to [http://localhost:3000](http://localhost:3000) - -That's it! your application should be running by now, to proceed with your development check the other sections in this documentation. + +That's it! your application should be running by now, to proceed with your development check the other sections in this documentation. If you encounter any problem try the Troubleshooting section. -## Development and deployment With Docker +## Securely Running Your Application +To create an HTTPS server, you need an SSL certificate. + +You can provide a certificate signed by a Certificate Authority (CA) or a self-signed certificate. In a production environment, it is recommended to use a CA-signed certificate. For development and test environment, a self-signed certificate can be used. + +To generate a self-signed certificate, run the following in your shell: +``` +$ cd config/sslcert/ +$ openssl genrsa -out key.pem +$ 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 +``` +This will leave you with cert.pem (the certificate) and key.pem (the private key) + +Now you can run your app securely in production mode: +``` +sudo NODE_ENV=production grunt +``` +NOTE: if you use higher port numbers, you don't need to run with sudo + +## Development and Deployment With Docker * Install [Docker](http://www.docker.com/) * Install [Fig](https://github.com/orchardup/fig) -* Local development and testing with fig: +* Local development and testing with fig: ```bash $ fig up ``` @@ -101,7 +123,7 @@ $ docker run -p 3000:3000 -p 35729:35729 -v /Users/mdl/workspace/mean-stack/mean ``` ## 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 [Offical Documentation](http://meanjs.org/docs.html). +You have your application running but there are a lot of stuff to understand, we recommend you'll go over the [Offical 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 procees. 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. ## Community diff --git a/config/env/all.js b/config/env/all.js index 33ca9948..fe23c146 100644 --- a/config/env/all.js +++ b/config/env/all.js @@ -7,6 +7,7 @@ module.exports = { keywords: 'mongodb, express, angularjs, node.js, mongoose, passport' }, port: process.env.PORT || 3000, + secure: process.env.SECURE || false, templateEngine: 'swig', sessionSecret: 'MEAN', sessionCollection: 'sessions', @@ -39,4 +40,4 @@ module.exports = { 'public/modules/*/tests/*.js' ] } -}; \ No newline at end of file +}; diff --git a/config/env/development.js b/config/env/development.js index fabdcedb..52090bac 100644 --- a/config/env/development.js +++ b/config/env/development.js @@ -40,4 +40,4 @@ module.exports = { } } } -}; \ No newline at end of file +}; diff --git a/config/env/production.js b/config/env/production.js index 25118ee2..9473e1c7 100644 --- a/config/env/production.js +++ b/config/env/production.js @@ -1,6 +1,8 @@ 'use strict'; module.exports = { + secure: true, + port: 443, db: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://localhost/mean', assets: { lib: { @@ -23,27 +25,27 @@ module.exports = { facebook: { clientID: process.env.FACEBOOK_ID || 'APP_ID', clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET', - callbackURL: 'http://localhost:3000/auth/facebook/callback' + callbackURL: 'https://localhost:443/auth/facebook/callback' }, twitter: { clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY', clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET', - callbackURL: 'http://localhost:3000/auth/twitter/callback' + callbackURL: 'https://localhost:443/auth/twitter/callback' }, google: { clientID: process.env.GOOGLE_ID || 'APP_ID', clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET', - callbackURL: 'http://localhost:3000/auth/google/callback' + callbackURL: 'https://localhost:443/auth/google/callback' }, linkedin: { clientID: process.env.LINKEDIN_ID || 'APP_ID', clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET', - callbackURL: 'http://localhost:3000/auth/linkedin/callback' + callbackURL: 'https://localhost:443/auth/linkedin/callback' }, github: { clientID: process.env.GITHUB_ID || 'APP_ID', clientSecret: process.env.GITHUB_SECRET || 'APP_SECRET', - callbackURL: 'http://localhost:3000/auth/github/callback' + callbackURL: 'https://localhost:443/auth/github/callback' }, mailer: { from: process.env.MAILER_FROM || 'MAILER_FROM', @@ -55,4 +57,4 @@ module.exports = { } } } -}; \ No newline at end of file +}; diff --git a/config/express.js b/config/express.js index bea1c88d..63003bc9 100755 --- a/config/express.js +++ b/config/express.js @@ -3,7 +3,13 @@ /** * Module dependencies. */ -var express = require('express'), +var fs = require('fs'), + http = require('http'), + https = require('https'), + privateKey = fs.readFileSync('./config/sslcert/key.pem', 'utf8'), + certificate = fs.readFileSync('./config/sslcert/cert.pem', 'utf8'), + credentials = {key: privateKey, cert: certificate}, + express = require('express'), morgan = require('morgan'), bodyParser = require('body-parser'), session = require('express-session'), @@ -36,6 +42,7 @@ 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,5 +147,13 @@ module.exports = function(db) { }); }); - return app; -}; \ No newline at end of file + if (app.locals.secure) { + console.log('Securely using https protocol'); + var httpsServer = https.createServer(credentials, app); + return httpsServer; + } else { + console.log('Insecurely using http protocol'); + var httpServer = http.createServer(app); + return httpServer; + } +}; diff --git a/config/sslcert/gen-certs b/config/sslcert/gen-certs new file mode 100755 index 00000000..20462a68 --- /dev/null +++ b/config/sslcert/gen-certs @@ -0,0 +1,7 @@ +#!/bin/bash +echo "Generating self-signed certificates..." +aopenssl genrsa -out key.pem +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 From 7946cfe3c12dc21c05d8f46a24c0eb0019f8faae Mon Sep 17 00:00:00 2001 From: jloveland Date: Sat, 16 Aug 2014 14:16:07 -0400 Subject: [PATCH 2/3] adding secure.js environment option, reverting production.js, and adding openssl options to gen-certs --- README.md | 11 ++++++-- config/env/production.js | 12 ++++---- config/env/secure.js | 60 ++++++++++++++++++++++++++++++++++++++++ config/sslcert/gen-certs | 2 +- 4 files changed, 74 insertions(+), 11 deletions(-) create mode 100644 config/env/secure.js diff --git a/README.md b/README.md index 58a6e618..6f0d1f0f 100644 --- a/README.md +++ b/README.md @@ -82,10 +82,15 @@ To create an HTTPS server, you need an SSL certificate. You can provide a certificate signed by a Certificate Authority (CA) or a self-signed certificate. In a production environment, it is recommended to use a CA-signed certificate. For development and test environment, a self-signed certificate can be used. -To generate a self-signed certificate, run the following in your shell: +To generate a self-signed certificate, run script: ``` $ cd config/sslcert/ -$ openssl genrsa -out key.pem +$ ./gen-certs +``` +or run the following in your shell: +``` +$ cd config/sslcert/ +$ 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 @@ -95,7 +100,7 @@ This will leave you with cert.pem (the certificate) and key.pem (the private key Now you can run your app securely in production mode: ``` -sudo NODE_ENV=production grunt +sudo NODE_ENV=secure grunt ``` NOTE: if you use higher port numbers, you don't need to run with sudo diff --git a/config/env/production.js b/config/env/production.js index 9473e1c7..0bcb1dff 100644 --- a/config/env/production.js +++ b/config/env/production.js @@ -1,8 +1,6 @@ 'use strict'; module.exports = { - secure: true, - port: 443, db: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://localhost/mean', assets: { lib: { @@ -25,27 +23,27 @@ module.exports = { facebook: { clientID: process.env.FACEBOOK_ID || 'APP_ID', clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET', - callbackURL: 'https://localhost:443/auth/facebook/callback' + callbackURL: 'http://localhost:3000/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' + callbackURL: 'http://localhost:3000/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' + callbackURL: 'http://localhost:3000/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' + callbackURL: 'http://localhost:3000/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' + callbackURL: 'http://localhost:3000/auth/github/callback' }, mailer: { from: process.env.MAILER_FROM || 'MAILER_FROM', diff --git a/config/env/secure.js b/config/env/secure.js new file mode 100644 index 00000000..0b52f3a4 --- /dev/null +++ b/config/env/secure.js @@ -0,0 +1,60 @@ +'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' + } + } + } +}; diff --git a/config/sslcert/gen-certs b/config/sslcert/gen-certs index 20462a68..70519705 100755 --- a/config/sslcert/gen-certs +++ b/config/sslcert/gen-certs @@ -1,6 +1,6 @@ #!/bin/bash echo "Generating self-signed certificates..." -aopenssl genrsa -out key.pem +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 From f786ddaa1c19c720313d81535b8f36cd4ce79646 Mon Sep 17 00:00:00 2001 From: jloveland Date: Sun, 31 Aug 2014 15:05:07 -0400 Subject: [PATCH 3/3] moving security configs to secure code block to remove requirement for private key and certificate --- config/express.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config/express.js b/config/express.js index 63003bc9..3cfe0dd5 100755 --- a/config/express.js +++ b/config/express.js @@ -5,10 +5,6 @@ */ var fs = require('fs'), http = require('http'), - https = require('https'), - privateKey = fs.readFileSync('./config/sslcert/key.pem', 'utf8'), - certificate = fs.readFileSync('./config/sslcert/cert.pem', 'utf8'), - credentials = {key: privateKey, cert: certificate}, express = require('express'), morgan = require('morgan'), bodyParser = require('body-parser'), @@ -149,7 +145,11 @@ module.exports = function(db) { if (app.locals.secure) { console.log('Securely using https protocol'); - var httpsServer = https.createServer(credentials, app); + 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); return httpsServer; } else { console.log('Insecurely using http protocol');