From 462984b7cab1d53a0711317152ce86c8158d32f1 Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Sun, 11 May 2014 08:10:00 -0400 Subject: [PATCH 01/13] First draft of the new generator UI complete - Switched from inquirer to blessed. --- package.json | 6 +++--- setup.js | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 setup.js diff --git a/package.json b/package.json index ff8b73f0ab..e9b2629dd4 100755 --- a/package.json +++ b/package.json @@ -54,15 +54,15 @@ "twit": "^1.1.14", "uglify-js": "^2.4.13", "underscore": "^1.6.0", - "validator": "^3.11.0", + "validator": "^3.11.0" }, "devDependencies": { + "blessed": "0.0.29", "chai": "^1.9.1", "colors": "^0.6.2", "inquirer": "^0.4.1", "mocha": "^1.18.2", "mstring": "^0.1.2", - "supertest": "^0.11.0", - "workshop": "0.0.0" + "supertest": "^0.11.0" } } diff --git a/setup.js b/setup.js new file mode 100644 index 0000000000..f3a1558faf --- /dev/null +++ b/setup.js @@ -0,0 +1,57 @@ +var blessed = require('blessed') +var screen = blessed.screen({ +}); + +var list = blessed.list({ + parent: screen, + padding: { top: 2 }, + mouse: true, + keys: true, + vi: true, + fg: 'white', + bg: 'blue', + selectedFg: 'blue', + selectedBg: 'white', + items: [ + '» Add/Remove Authentication', + '» Change Email Service', + '» Enable Socket.IO', + '» Enable Node.js Cluster', + '» Exit' + ] +}); + +list.append(blessed.Text({ + align: 'center', + fg: 'blue', + bg: 'white', + content: 'Hackathon Starter (c) 2014' +})); + + +list.append(blessed.Text({ + bottom: 0, + fg: 'white', + bg: 'blue', + content: ' moves; selects' +})); + + + +screen.key('q', function() { + process.exit(0); +}); + +//var check = blessed.checkbox({ +// parent: form, +// keys: true, +// left: 0, +// top: 0, +// width: 30, +// height: 4, +// bg: 'blue', +// content: ' » Hello or cancel?' +//}); + +screen.render(); + From f5104110ce503b3694f8b992f3b95c39a0480ec8 Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Sun, 11 May 2014 08:10:15 -0400 Subject: [PATCH 02/13] Removed LICENSE, README is sufficient --- LICENSE | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 LICENSE diff --git a/LICENSE b/LICENSE deleted file mode 100644 index f9ee1a1f6a..0000000000 --- a/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Sahat Yalkabov - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From 2c570424431d4ce25b6ddcc333264252930e441d Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Sun, 11 May 2014 11:11:17 -0400 Subject: [PATCH 03/13] authentication screen is complete --- setup.js | 169 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 146 insertions(+), 23 deletions(-) diff --git a/setup.js b/setup.js index f3a1558faf..ff3c2089d7 100644 --- a/setup.js +++ b/setup.js @@ -1,40 +1,174 @@ var blessed = require('blessed') var screen = blessed.screen({ + autoPadding: true }); -var list = blessed.list({ +var home = blessed.list({ parent: screen, padding: { top: 2 }, mouse: true, keys: true, - vi: true, fg: 'white', bg: 'blue', selectedFg: 'blue', selectedBg: 'white', items: [ - '» Add/Remove Authentication', - '» Change Email Service', - '» Enable Socket.IO', - '» Enable Node.js Cluster', + '» Authentication', + '» Email Service', + '» Socket.IO', + '» Node.js Cluster', '» Exit' ] }); -list.append(blessed.Text({ +var authentication = blessed.form({ + mouse: true, + keys: true, + fg: 'white', + bg: 'blue', + padding: { left: 1, right: 1 } +}); + +var authText = blessed.text({ + parent: authentication, + content: 'Selecting a checkbox adds an authentication provider. Unselecting a checkbox removes it. If authentication provider is already present, no action will be taken.', + padding: 1, + bg: 'magenta', + fg: 'white' +}); + +var facebookCheckbox = blessed.checkbox({ + parent: authentication, + top: 6, + checked: true, + mouse: true, + fg: 'white', + bg: 'blue', + content: 'Facebook' +}); + +var githubCheckbox = blessed.checkbox({ + parent: authentication, + top: 7, + checked: true, + mouse: true, + fg: 'white', + bg: 'blue', + content: 'GitHub' +}); + +var googleCheckbox = blessed.checkbox({ + parent: authentication, + top: 8, + checked: true, + mouse: true, + fg: 'white', + bg: 'blue', + content: 'Google' +}); + +var twitterCheckbox = blessed.checkbox({ + parent: authentication, + top: 9, + checked: true, + mouse: true, + fg: 'white', + bg: 'blue', + content: 'Twitter' +}); + +var linkedinCheckbox = blessed.checkbox({ + parent: authentication, + top: 10, + checked: true, + mouse: true, + fg: 'white', + bg: 'blue', + content: 'LinkedIn' +}); + +var instagramCheckbox = blessed.checkbox({ + parent: authentication, + top: 11, + checked: true, + mouse: true, + fg: 'white', + bg: 'blue', + content: 'Instagram' +}); + +var authOk = blessed.button({ + parent: authentication, + top: 13, + mouse: true, + shrink: true, + name: 'ok', + content: ' SUBMIT ', + style: { + fg: 'blue', + bg: 'white', + focus: { + fg: 'white', + bg: 'red' + } + } +}); + +var authCancel = blessed.button({ + parent: authentication, + top: 13, + left: 9, + mouse: true, + shrink: true, + name: 'cancel', + content: ' CANCEL ', + style: { + fg: 'blue', + bg: 'white', + focus: { + fg: 'white', + bg: 'red' + } + } +}); + +var title = blessed.text({ + parent: screen, align: 'center', fg: 'blue', bg: 'white', content: 'Hackathon Starter (c) 2014' -})); +}); - -list.append(blessed.Text({ +var footer = blessed.text({ + parent: screen, bottom: 0, fg: 'white', bg: 'blue', - content: ' moves; selects' -})); + content: ' moves | selects | exits' +}); + +home.on('select', function(child, index) { + switch (index) { + case 0: + home.append(authentication); + authentication.focus(); + break; + case 1: + console.log('doh'); + break; + case 2: + console.log('doh'); + break; + case 3: + + console.log('doh'); + break; + default: + process.exit(0); + } +}); + @@ -42,16 +176,5 @@ screen.key('q', function() { process.exit(0); }); -//var check = blessed.checkbox({ -// parent: form, -// keys: true, -// left: 0, -// top: 0, -// width: 30, -// height: 4, -// bg: 'blue', -// content: ' » Hello or cancel?' -//}); - screen.render(); From 20c22aeef13888d1dd0274eaea8d1224df43a9a5 Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Sun, 11 May 2014 12:24:16 -0400 Subject: [PATCH 04/13] Email service UI is finished --- setup.js | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/setup.js b/setup.js index ff3c2089d7..a9b85ab802 100644 --- a/setup.js +++ b/setup.js @@ -21,6 +21,22 @@ var home = blessed.list({ ] }); +var inner = blessed.box({ + parent: home, + top: 'center', + left: 'center', + width: '50%', + height: '50%', + border: { + type: 'line', + fg: 'white', + bg: 'red' + }, + fg: 'white', + bg: 'red' +}); + + var authentication = blessed.form({ mouse: true, keys: true, @@ -132,6 +148,85 @@ var authCancel = blessed.button({ } }); +var email = blessed.form({ + mouse: true, + keys: true, + fg: 'whiqte', + bg: 'blue', + padding: { left: 1, right: 1 } +}); + +var emailText = blessed.text({ + parent: email, + content: 'Select one of the following email service providers for {underline}contact form{/underline} and {underline}password reset{/underline}.', + padding: 1, + bg: 'red', + fg: 'white', + tags: true +}); + +var sendgridRadio = blessed.radiobutton({ + parent: email, + top: 5, + mouse: true, + fg: 'white', + bg: 'blue', + content: 'SendGrid' +}); + +var mailgunRadio = blessed.radiobutton({ + parent: email, + top: 6, + mouse: true, + fg: 'white', + bg: 'blue', + content: 'Mailgun' +}); + +var mandrillRadio = blessed.radiobutton({ + parent: email, + top: 7, + mouse: true, + fg: 'white', + bg: 'blue', + content: 'Mandrill' +}); + +var emailOk = blessed.button({ + parent: email, + top: 9, + mouse: true, + shrink: true, + name: 'ok', + content: ' SUBMIT ', + style: { + fg: 'blue', + bg: 'white', + focus: { + fg: 'white', + bg: 'red' + } + } +}); + +var emailCancel = blessed.button({ + parent: email, + top: 9, + left: 9, + mouse: true, + shrink: true, + name: 'cancel', + content: ' CANCEL ', + style: { + fg: 'blue', + bg: 'white', + focus: { + fg: 'white', + bg: 'red' + } + } +}); + var title = blessed.text({ parent: screen, align: 'center', @@ -155,7 +250,8 @@ home.on('select', function(child, index) { authentication.focus(); break; case 1: - console.log('doh'); + home.append(email); + email.focus(); break; case 2: console.log('doh'); From 2a623700598330003a40f5dad92d3dd648f667be Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Sun, 11 May 2014 13:15:15 -0400 Subject: [PATCH 05/13] Socket.io and Cluster UI is complete --- setup.js | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 94 insertions(+), 6 deletions(-) diff --git a/setup.js b/setup.js index a9b85ab802..9c1e9adb1c 100644 --- a/setup.js +++ b/setup.js @@ -22,11 +22,10 @@ var home = blessed.list({ }); var inner = blessed.box({ - parent: home, top: 'center', left: 'center', - width: '50%', - height: '50%', + width: 33, + height: 10, border: { type: 'line', fg: 'white', @@ -36,6 +35,90 @@ var inner = blessed.box({ bg: 'red' }); +var socketText = blessed.text({ + top: 'top', + bg: 'red', + fg: 'white', + tags: true, + content: 'Add real-time support to your application with Socket.IO.' +}); + +var clusterText = blessed.text({ + top: 'top', + bg: 'red', + fg: 'white', + tags: true, + content: 'Take advantage of multi-core systems using built-in {underline}cluster{/underline} module.' +}); + + +var enable = blessed.button({ + parent: inner, + bottom: 0, + mouse: true, + shrink: true, + name: 'enable', + content: ' ENABLE ', + border: { + type: 'line', + fg: 'white', + bg: 'red' + }, + style: { + fg: 'white', + bg: 'red', + focus: { + fg: 'white', + bg: 'red' + } + } +}); + +var disable = blessed.button({ + parent: inner, + bottom: 0, + left: 10, + mouse: true, + shrink: true, + name: 'disable', + content: ' DISABLE ', + border: { + type: 'line', + fg: 'white', + bg: 'red' + }, + style: { + fg: 'white', + bg: 'red', + focus: { + fg: 'white', + bg: 'red' + } + } +}); + +var cancel = blessed.button({ + parent: inner, + bottom: 0, + left: 21, + mouse: true, + shrink: true, + name: 'cancel', + content: ' CANCEL ', + border: { + type: 'line', + fg: 'white', + bg: 'red' + }, + style: { + fg: 'white', + bg: 'red', + focus: { + fg: 'white', + bg: 'red' + } + } +}); var authentication = blessed.form({ mouse: true, @@ -254,11 +337,16 @@ home.on('select', function(child, index) { email.focus(); break; case 2: - console.log('doh'); + home.append(inner); + inner.append(socketText); + inner.focus(); + screen.render(); break; case 3: - - console.log('doh'); + home.append(inner); + inner.append(clusterText); + inner.focus(); + screen.render(); break; default: process.exit(0); From be7643a1211cef1869b47246c4b40865a1274fcf Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Sun, 11 May 2014 15:07:58 -0400 Subject: [PATCH 06/13] Removed cluster_app.js, moved to the new generator --- cluster_app.js | 15 ----- setup.js | 147 +++++++++++++++++++++++++++++++++++++------------ 2 files changed, 113 insertions(+), 49 deletions(-) delete mode 100755 cluster_app.js diff --git a/cluster_app.js b/cluster_app.js deleted file mode 100755 index fb236f2b08..0000000000 --- a/cluster_app.js +++ /dev/null @@ -1,15 +0,0 @@ -var os = require('os'); -var cluster = require('cluster'); - -cluster.setupMaster({ - exec: 'app.js' -}); - -cluster.on('exit', function(worker) { - console.log('worker ' + worker.id + ' died'); - cluster.fork(); -}); - -for (var i = 0; i < os.cpus().length; i++) { - cluster.fork(); -} \ No newline at end of file diff --git a/setup.js b/setup.js index 9c1e9adb1c..892a3996c2 100644 --- a/setup.js +++ b/setup.js @@ -1,4 +1,7 @@ -var blessed = require('blessed') +var fs = require('fs'); +var blessed = require('blessed'); +var multiline = require('multiline'); + var screen = blessed.screen({ autoPadding: true }); @@ -13,17 +16,19 @@ var home = blessed.list({ selectedFg: 'blue', selectedBg: 'white', items: [ - '» Authentication', - '» Email Service', - '» Socket.IO', - '» Node.js Cluster', - '» Exit' + '» REMOVE AUTHENTICATION', + '» CHANGE EMAIL SERVICE', + '» ENABLE SOCKET.IO', + '» ADD NODE.JS CLUSTER SUPPORT', + '» EXIT' ] }); -var inner = blessed.box({ +var inner = blessed.form({ top: 'center', left: 'center', + mouse: true, + keys: true, width: 33, height: 10, border: { @@ -35,6 +40,29 @@ var inner = blessed.box({ bg: 'red' }); +var success = blessed.box({ + top: 'center', + left: 'center', + mouse: true, + keys: true, + tags: true, + width: '50%', + height: '40%', + border: { + type: 'line', + fg: 'white', + bg: 'green' + }, + fg: 'white', + bg: 'green', + padding: 1 +}); + +success.on('keypress', function() { + home.focus(); + home.remove(success); +}); + var socketText = blessed.text({ top: 'top', bg: 'red', @@ -68,12 +96,13 @@ var enable = blessed.button({ fg: 'white', bg: 'red', focus: { - fg: 'white', - bg: 'red' + fg: 'red', + bg: 'white' } } }); + var disable = blessed.button({ parent: inner, bottom: 0, @@ -91,8 +120,8 @@ var disable = blessed.button({ fg: 'white', bg: 'red', focus: { - fg: 'white', - bg: 'red' + fg: 'red', + bg: 'white' } } }); @@ -114,13 +143,20 @@ var cancel = blessed.button({ fg: 'white', bg: 'red', focus: { - fg: 'white', - bg: 'red' + fg: 'red', + bg: 'white' } } }); -var authentication = blessed.form({ +cancel.on('press', function() { + home.focus(); + home.remove(inner); + screen.render(); + +}); + +var auth = blessed.form({ mouse: true, keys: true, fg: 'white', @@ -129,7 +165,7 @@ var authentication = blessed.form({ }); var authText = blessed.text({ - parent: authentication, + parent: auth, content: 'Selecting a checkbox adds an authentication provider. Unselecting a checkbox removes it. If authentication provider is already present, no action will be taken.', padding: 1, bg: 'magenta', @@ -137,7 +173,7 @@ var authText = blessed.text({ }); var facebookCheckbox = blessed.checkbox({ - parent: authentication, + parent: auth, top: 6, checked: true, mouse: true, @@ -147,7 +183,7 @@ var facebookCheckbox = blessed.checkbox({ }); var githubCheckbox = blessed.checkbox({ - parent: authentication, + parent: auth, top: 7, checked: true, mouse: true, @@ -157,7 +193,7 @@ var githubCheckbox = blessed.checkbox({ }); var googleCheckbox = blessed.checkbox({ - parent: authentication, + parent: auth, top: 8, checked: true, mouse: true, @@ -167,7 +203,7 @@ var googleCheckbox = blessed.checkbox({ }); var twitterCheckbox = blessed.checkbox({ - parent: authentication, + parent: auth, top: 9, checked: true, mouse: true, @@ -177,7 +213,7 @@ var twitterCheckbox = blessed.checkbox({ }); var linkedinCheckbox = blessed.checkbox({ - parent: authentication, + parent: auth, top: 10, checked: true, mouse: true, @@ -187,7 +223,7 @@ var linkedinCheckbox = blessed.checkbox({ }); var instagramCheckbox = blessed.checkbox({ - parent: authentication, + parent: auth, top: 11, checked: true, mouse: true, @@ -196,12 +232,12 @@ var instagramCheckbox = blessed.checkbox({ content: 'Instagram' }); -var authOk = blessed.button({ - parent: authentication, +var authSubmit = blessed.button({ + parent: auth, top: 13, mouse: true, shrink: true, - name: 'ok', + name: 'submit', content: ' SUBMIT ', style: { fg: 'blue', @@ -214,7 +250,7 @@ var authOk = blessed.button({ }); var authCancel = blessed.button({ - parent: authentication, + parent: auth, top: 13, left: 9, mouse: true, @@ -231,14 +267,21 @@ var authCancel = blessed.button({ } }); +authCancel.on('press', function() { + home.focus(); + home.remove(auth); + screen.render(); +}); + var email = blessed.form({ mouse: true, keys: true, - fg: 'whiqte', + fg: 'white', bg: 'blue', padding: { left: 1, right: 1 } }); + var emailText = blessed.text({ parent: email, content: 'Select one of the following email service providers for {underline}contact form{/underline} and {underline}password reset{/underline}.', @@ -310,6 +353,13 @@ var emailCancel = blessed.button({ } }); +emailCancel.on('press', function() { + home.focus(); + home.remove(email); + screen.render(); + +}); + var title = blessed.text({ parent: screen, align: 'center', @@ -323,14 +373,16 @@ var footer = blessed.text({ bottom: 0, fg: 'white', bg: 'blue', - content: ' moves | selects | exits' + tags: true, + content: ' {cyan-fg}{/cyan-fg} moves | {cyan-fg}{/cyan-fg} selects | {cyan-fg}{/cyan-fg} exits' }); home.on('select', function(child, index) { switch (index) { case 0: - home.append(authentication); - authentication.focus(); + home.append(auth); + auth.focus(); + screen.render(); break; case 1: home.append(email); @@ -343,10 +395,13 @@ home.on('select', function(child, index) { screen.render(); break; case 3: - home.append(inner); - inner.append(clusterText); - inner.focus(); + // Cluster + addClusterSupport(); + home.append(success); + success.setContent('New file {underline}cluster_app.js{/underline} has been created. Your app is now able to use more than 1 CPU by running node {underline}cluster_app.js{/underline}, which in turn spawns multiple instances of {underline}app.js{/underline}'); + success.focus(); screen.render(); + break; default: process.exit(0); @@ -354,11 +409,35 @@ home.on('select', function(child, index) { }); - - screen.key('q', function() { process.exit(0); }); screen.render(); + +function addClusterSupport() { + + var fileContents = multiline(function() { +/* +var os = require('os'); +var cluster = require('cluster'); + +cluster.setupMaster({ + exec: 'app.js' +}); + +cluster.on('exit', function(worker) { + console.log('worker ' + worker.id + ' died'); + cluster.fork(); +}); + +for (var i = 0; i < os.cpus().length; i++) { + cluster.fork(); +} +*/ + }); + + fs.writeFileSync('cluster_app.js', fileContents); +} + From 573657d6434fb54b8e46f239faf638dd7624c793 Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Sun, 11 May 2014 16:11:53 -0400 Subject: [PATCH 07/13] Updated module dependencies --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index e9b2629dd4..6cd0eafa55 100755 --- a/package.json +++ b/package.json @@ -60,9 +60,8 @@ "blessed": "0.0.29", "chai": "^1.9.1", "colors": "^0.6.2", - "inquirer": "^0.4.1", "mocha": "^1.18.2", - "mstring": "^0.1.2", + "multiline": "^0.3.4", "supertest": "^0.11.0" } } From bd27d39ecc2bae29a0b8906f065f1116131a4f7e Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Tue, 13 May 2014 01:13:27 -0400 Subject: [PATCH 08/13] Added socket.io generator UI --- package.json | 1 + setup.js | 26 ++++++++++++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 6cd0eafa55..c1c414ed29 100755 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "passport-oauth": "^1.0.0", "passport-twitter": "^1.0.2", "request": "^2.34.0", + "socket.io": "^0.9.16", "stripe": "^2.5.5", "tumblr.js": "^0.0.4", "twilio": "^1.6.0", diff --git a/setup.js b/setup.js index 892a3996c2..b68621e5ef 100644 --- a/setup.js +++ b/setup.js @@ -6,6 +6,10 @@ var screen = blessed.screen({ autoPadding: true }); +screen.key('q', function() { + process.exit(0); +}); + var home = blessed.list({ parent: screen, padding: { top: 2 }, @@ -389,19 +393,19 @@ home.on('select', function(child, index) { email.focus(); break; case 2: - home.append(inner); - inner.append(socketText); - inner.focus(); + enableSocketIo(); + home.append(success); + success.setContent('Socket.IO events have been added at the bottom of {underline}app.js{/underline}. To see a working example take a look at /dashboard. Be sure to run npm install socket.io'); + success.focus(); screen.render(); break; case 3: // Cluster addClusterSupport(); home.append(success); - success.setContent('New file {underline}cluster_app.js{/underline} has been created. Your app is now able to use more than 1 CPU by running node {underline}cluster_app.js{/underline}, which in turn spawns multiple instances of {underline}app.js{/underline}'); + success.setContent('New file {underline}cluster_app.js{/underline} has been created. Your app is now able to use more than 1 CPU by running {underline}node cluster_app.js{/underline}, which in turn spawns multiple instances of {underline}app.js{/underline}'); success.focus(); screen.render(); - break; default: process.exit(0); @@ -409,9 +413,7 @@ home.on('select', function(child, index) { }); -screen.key('q', function() { - process.exit(0); -}); + screen.render(); @@ -441,3 +443,11 @@ for (var i = 0; i < os.cpus().length; i++) { fs.writeFileSync('cluster_app.js', fileContents); } +function enableSocketIo() { + var fileContents = multiline(function() { + /* + + + */ + }); +} \ No newline at end of file From 0c485fecad27e4119550a347acfabd6808dc8da0 Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Tue, 13 May 2014 02:59:46 -0400 Subject: [PATCH 09/13] Email Service generator --- setup.js | 68 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 13 deletions(-) diff --git a/setup.js b/setup.js index b68621e5ef..a0d62bb04e 100644 --- a/setup.js +++ b/setup.js @@ -1,4 +1,5 @@ var fs = require('fs'); +var os = require('os'); var blessed = require('blessed'); var multiline = require('multiline'); @@ -277,7 +278,7 @@ authCancel.on('press', function() { screen.render(); }); -var email = blessed.form({ +var emailForm = blessed.form({ mouse: true, keys: true, fg: 'white', @@ -285,9 +286,44 @@ var email = blessed.form({ padding: { left: 1, right: 1 } }); +emailForm.on('submit', function(data) { + var contactCtrl = fs.readFileSync('controllers/contact.js').toString().split(os.EOL); + var userCtrl = fs.readFileSync('controllers/user.js').toString().split(os.EOL); + var choice = null; + + if (sendgridRadio.checked) { + choice = 'SendGrid'; + } else if (mailgunRadio.checked) { + choice = 'Mailgun'; + } else if (mandrillRadio.checked) { + choice = 'Mandrill'; + } + + var index = contactCtrl.indexOf('var smtpTransport = nodemailer.createTransport(\'SMTP\', {'); + contactCtrl.splice(index + 1, 1, " service: '" + choice + "',"); + contactCtrl.splice(index + 3, 1, ' user: secrets.' + choice.toLowerCase() +'.user,'); + contactCtrl.splice(index + 4, 1, ' pass: secrets.' + choice.toLowerCase() + '.password'); + fs.writeFileSync('controllers/contact.js', contactCtrl.join(os.EOL)); + + index = userCtrl.indexOf(' var smtpTransport = nodemailer.createTransport(\'SMTP\', {'); + userCtrl.splice(index + 1, 1, " service: '" + choice + "',"); + userCtrl.splice(index + 3, 1, ' user: secrets.' + choice.toLowerCase() + '.user,'); + userCtrl.splice(index + 4, 1, ' pass: secrets.' + choice.toLowerCase() + '.password'); + index = userCtrl.indexOf(' var smtpTransport = nodemailer.createTransport(\'SMTP\', {', (index + 1)); + userCtrl.splice(index + 1, 1, " service: '" + choice + "',"); + userCtrl.splice(index + 3, 1, ' user: secrets.' + choice.toLowerCase() + '.user,'); + userCtrl.splice(index + 4, 1, ' pass: secrets.' + choice.toLowerCase() + '.password'); + fs.writeFileSync('controllers/user.js', userCtrl.join(os.EOL)); + + home.remove(emailForm); + home.append(success); + success.setContent('Email Service has been switched to ' + choice); + success.focus(); + screen.render(); +}); var emailText = blessed.text({ - parent: email, + parent: emailForm, content: 'Select one of the following email service providers for {underline}contact form{/underline} and {underline}password reset{/underline}.', padding: 1, bg: 'red', @@ -296,8 +332,9 @@ var emailText = blessed.text({ }); var sendgridRadio = blessed.radiobutton({ - parent: email, + parent: emailForm, top: 5, + checked: true, mouse: true, fg: 'white', bg: 'blue', @@ -305,7 +342,7 @@ var sendgridRadio = blessed.radiobutton({ }); var mailgunRadio = blessed.radiobutton({ - parent: email, + parent: emailForm, top: 6, mouse: true, fg: 'white', @@ -314,7 +351,7 @@ var mailgunRadio = blessed.radiobutton({ }); var mandrillRadio = blessed.radiobutton({ - parent: email, + parent: emailForm, top: 7, mouse: true, fg: 'white', @@ -322,12 +359,12 @@ var mandrillRadio = blessed.radiobutton({ content: 'Mandrill' }); -var emailOk = blessed.button({ - parent: email, +var emailSubmit = blessed.button({ + parent: emailForm, top: 9, mouse: true, shrink: true, - name: 'ok', + name: 'submit', content: ' SUBMIT ', style: { fg: 'blue', @@ -339,8 +376,12 @@ var emailOk = blessed.button({ } }); +emailSubmit.on('press', function() { + emailForm.submit(); +}); + var emailCancel = blessed.button({ - parent: email, + parent: emailForm, top: 9, left: 9, mouse: true, @@ -357,9 +398,11 @@ var emailCancel = blessed.button({ } }); + + emailCancel.on('press', function() { home.focus(); - home.remove(email); + home.remove(emailForm); screen.render(); }); @@ -389,8 +432,8 @@ home.on('select', function(child, index) { screen.render(); break; case 1: - home.append(email); - email.focus(); + home.append(emailForm); + emailForm.focus(); break; case 2: enableSocketIo(); @@ -400,7 +443,6 @@ home.on('select', function(child, index) { screen.render(); break; case 3: - // Cluster addClusterSupport(); home.append(success); success.setContent('New file {underline}cluster_app.js{/underline} has been created. Your app is now able to use more than 1 CPU by running {underline}node cluster_app.js{/underline}, which in turn spawns multiple instances of {underline}app.js{/underline}'); From cfb30686879a74baa9e074c708359f6c14efed2d Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Tue, 13 May 2014 03:57:23 -0400 Subject: [PATCH 10/13] Added Facebook authentication remover --- setup.js | 73 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 15 deletions(-) diff --git a/setup.js b/setup.js index a0d62bb04e..8f7fdc8da7 100644 --- a/setup.js +++ b/setup.js @@ -21,7 +21,7 @@ var home = blessed.list({ selectedFg: 'blue', selectedBg: 'white', items: [ - '» REMOVE AUTHENTICATION', + '» REMOVE AUTHENTICATION PROVIDER', '» CHANGE EMAIL SERVICE', '» ENABLE SOCKET.IO', '» ADD NODE.JS CLUSTER SUPPORT', @@ -161,7 +161,7 @@ cancel.on('press', function() { }); -var auth = blessed.form({ +var authForm = blessed.form({ mouse: true, keys: true, fg: 'white', @@ -169,8 +169,47 @@ var auth = blessed.form({ padding: { left: 1, right: 1 } }); +authForm.on('submit', function(data) { + var passportConfig = fs.readFileSync('config/passport.js').toString().split(os.EOL); + var loginTemplate = fs.readFileSync('views/account/login.jade').toString().split(os.EOL); + var profileTemplate = fs.readFileSync('views/account/profile.jade').toString().split(os.EOL); + var userModel = fs.readFileSync('models/User.js').toString().split(os.EOL); + var app = fs.readFileSync('app.js').toString().split(os.EOL); + var secrets = fs.readFileSync('config/secrets.js').toString().split(os.EOL); + + if (facebookCheckbox.checked) { + var index = passportConfig.indexOf("var FacebookStrategy = require('passport-facebook').Strategy;"); + passportConfig.splice(index, 1); + index = passportConfig.indexOf('// Sign in with Facebook.'); + passportConfig.splice(index, 47); + fs.writeFileSync('config/passport.js', passportConfig.join(os.EOL)); + + index = loginTemplate.indexOf(" a.btn.btn-block.btn-facebook.btn-social(href='/auth/facebook')"); + loginTemplate.splice(index, 3); + fs.writeFileSync('views/account/login.jade', loginTemplate.join(os.EOL)); + + index = profileTemplate.indexOf(" if user.facebook"); + profileTemplate.splice(index - 1, 5); + fs.writeFileSync('views/account/profile.jade', profileTemplate.join(os.EOL)); + + index = userModel.indexOf(' facebook: String,'); + userModel.splice(index, 1); + fs.writeFileSync('models/User.js', userModel.join(os.EOL)); + + index = app.indexOf("app.get('/auth/facebook', passport.authenticate('facebook', { scope: ['email', 'user_location'] }));"); + app.splice(index, 4); + fs.writeFileSync('app.js', app.join(os.EOL)); + } + + home.remove(authForm); + home.append(success); + success.setContent('Selected authentication providers have been removed from passportConfig.js, User.js, secrets.js, app.js, login.jade and profile.jade!'); + success.focus(); + screen.render(); +}); + var authText = blessed.text({ - parent: auth, + parent: authForm, content: 'Selecting a checkbox adds an authentication provider. Unselecting a checkbox removes it. If authentication provider is already present, no action will be taken.', padding: 1, bg: 'magenta', @@ -178,7 +217,7 @@ var authText = blessed.text({ }); var facebookCheckbox = blessed.checkbox({ - parent: auth, + parent: authForm, top: 6, checked: true, mouse: true, @@ -188,7 +227,7 @@ var facebookCheckbox = blessed.checkbox({ }); var githubCheckbox = blessed.checkbox({ - parent: auth, + parent: authForm, top: 7, checked: true, mouse: true, @@ -198,7 +237,7 @@ var githubCheckbox = blessed.checkbox({ }); var googleCheckbox = blessed.checkbox({ - parent: auth, + parent: authForm, top: 8, checked: true, mouse: true, @@ -208,7 +247,7 @@ var googleCheckbox = blessed.checkbox({ }); var twitterCheckbox = blessed.checkbox({ - parent: auth, + parent: authForm, top: 9, checked: true, mouse: true, @@ -218,7 +257,7 @@ var twitterCheckbox = blessed.checkbox({ }); var linkedinCheckbox = blessed.checkbox({ - parent: auth, + parent: authForm, top: 10, checked: true, mouse: true, @@ -228,7 +267,7 @@ var linkedinCheckbox = blessed.checkbox({ }); var instagramCheckbox = blessed.checkbox({ - parent: auth, + parent: authForm, top: 11, checked: true, mouse: true, @@ -238,7 +277,7 @@ var instagramCheckbox = blessed.checkbox({ }); var authSubmit = blessed.button({ - parent: auth, + parent: authForm, top: 13, mouse: true, shrink: true, @@ -254,8 +293,12 @@ var authSubmit = blessed.button({ } }); +authSubmit.on('press', function() { + authForm.submit(); +}); + var authCancel = blessed.button({ - parent: auth, + parent: authForm, top: 13, left: 9, mouse: true, @@ -274,7 +317,7 @@ var authCancel = blessed.button({ authCancel.on('press', function() { home.focus(); - home.remove(auth); + home.remove(authForm); screen.render(); }); @@ -407,7 +450,7 @@ emailCancel.on('press', function() { }); -var title = blessed.text({ +var homeTitle = blessed.text({ parent: screen, align: 'center', fg: 'blue', @@ -427,8 +470,8 @@ var footer = blessed.text({ home.on('select', function(child, index) { switch (index) { case 0: - home.append(auth); - auth.focus(); + home.append(authForm); + authForm.focus(); screen.render(); break; case 1: From e4de372167f4fd5ea184af23ead1b55a202238de Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Tue, 13 May 2014 04:40:28 -0400 Subject: [PATCH 11/13] Added all the remaining auth removers --- setup.js | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 124 insertions(+), 11 deletions(-) diff --git a/setup.js b/setup.js index 8f7fdc8da7..797d46a1aa 100644 --- a/setup.js +++ b/setup.js @@ -169,7 +169,7 @@ var authForm = blessed.form({ padding: { left: 1, right: 1 } }); -authForm.on('submit', function(data) { +authForm.on('submit', function() { var passportConfig = fs.readFileSync('config/passport.js').toString().split(os.EOL); var loginTemplate = fs.readFileSync('views/account/login.jade').toString().split(os.EOL); var profileTemplate = fs.readFileSync('views/account/profile.jade').toString().split(os.EOL); @@ -177,8 +177,8 @@ authForm.on('submit', function(data) { var app = fs.readFileSync('app.js').toString().split(os.EOL); var secrets = fs.readFileSync('config/secrets.js').toString().split(os.EOL); - if (facebookCheckbox.checked) { - var index = passportConfig.indexOf("var FacebookStrategy = require('passport-facebook').Strategy;"); + var index = passportConfig.indexOf("var FacebookStrategy = require('passport-facebook').Strategy;"); + if (facebookCheckbox.checked && index !== -1) { passportConfig.splice(index, 1); index = passportConfig.indexOf('// Sign in with Facebook.'); passportConfig.splice(index, 47); @@ -201,9 +201,128 @@ authForm.on('submit', function(data) { fs.writeFileSync('app.js', app.join(os.EOL)); } + index = "var GitHubStrategy = require('passport-github').Strategy;";; + if (githubCheckbox.checked && index !== -1) { + passportConfig.splice(index, 1); + index = passportConfig.indexOf('// Sign in with GitHub.'); + passportConfig.splice(index, 48); + fs.writeFileSync('config/passport.js', passportConfig.join(os.EOL)); + + index = loginTemplate.indexOf(" a.btn.btn-block.btn-github.btn-social(href='/auth/github')"); + loginTemplate.splice(index, 3); + fs.writeFileSync('views/account/login.jade', loginTemplate.join(os.EOL)); + + index = profileTemplate.indexOf(' if user.github'); + profileTemplate.splice(index - 1, 5); + fs.writeFileSync('views/account/profile.jade', profileTemplate.join(os.EOL)); + + index = userModel.indexOf(' github: String,'); + userModel.splice(index, 1); + fs.writeFileSync('models/User.js', userModel.join(os.EOL)); + + index = app.indexOf("app.get('/auth/github', passport.authenticate('github'));"); + app.splice(index, 4); + fs.writeFileSync('app.js', app.join(os.EOL)); + } + + index = "var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;"; + if (googleCheckbox.checked && index !== -1) { + passportConfig.splice(index, 1); + index = passportConfig.indexOf('// Sign in with Google.'); + passportConfig.splice(index, 46); + fs.writeFileSync('config/passport.js', passportConfig.join(os.EOL)); + + index = loginTemplate.indexOf(" a.btn.btn-block.btn-google-plus.btn-social(href='/auth/google')"); + loginTemplate.splice(index, 3); + fs.writeFileSync('views/account/login.jade', loginTemplate.join(os.EOL)); + + index = profileTemplate.indexOf(' if user.google'); + profileTemplate.splice(index - 1, 5); + fs.writeFileSync('views/account/profile.jade', profileTemplate.join(os.EOL)); + + index = userModel.indexOf(' google: String,'); + userModel.splice(index, 1); + fs.writeFileSync('models/User.js', userModel.join(os.EOL)); + + index = app.indexOf("app.get('/auth/google', passport.authenticate('google', { scope: 'profile email' }));"); + app.splice(index, 4); + fs.writeFileSync('app.js', app.join(os.EOL)); + } + + index = "var TwitterStrategy = require('passport-twitter').Strategy;"; + if (twitterCheckbox.checked && index !== -1) { + passportConfig.splice(index, 1); + index = passportConfig.indexOf('// Sign in with Twitter.'); + passportConfig.splice(index, 43); + fs.writeFileSync('config/passport.js', passportConfig.join(os.EOL)); + + index = loginTemplate.indexOf(" a.btn.btn-block.btn-twitter.btn-social(href='/auth/twitter')"); + loginTemplate.splice(index, 3); + fs.writeFileSync('views/account/login.jade', loginTemplate.join(os.EOL)); + + index = profileTemplate.indexOf(' if user.twitter'); + profileTemplate.splice(index - 1, 5); + fs.writeFileSync('views/account/profile.jade', profileTemplate.join(os.EOL)); + + index = userModel.indexOf(' twitter: String,'); + userModel.splice(index, 1); + fs.writeFileSync('models/User.js', userModel.join(os.EOL)); + + index = app.indexOf("app.get('/auth/twitter', passport.authenticate('twitter'));"); + app.splice(index, 4); + fs.writeFileSync('app.js', app.join(os.EOL)); + } + + index = "var LinkedInStrategy = require('passport-linkedin-oauth2').Strategy;"; + if (linkedinCheckbox.checked && index !== -1) { + passportConfig.splice(index, 1); + index = passportConfig.indexOf('// Sign in with LinkedIn.'); + passportConfig.splice(index, 51); + fs.writeFileSync('config/passport.js', passportConfig.join(os.EOL)); + + index = loginTemplate.indexOf(" a.btn.btn-block.btn-linkedin.btn-social(href='/auth/linkedin')"); + loginTemplate.splice(index, 3); + fs.writeFileSync('views/account/login.jade', loginTemplate.join(os.EOL)); + + index = profileTemplate.indexOf(' if user.linkedin'); + profileTemplate.splice(index - 1, 5); + fs.writeFileSync('views/account/profile.jade', profileTemplate.join(os.EOL)); + + index = userModel.indexOf(' linkedin: String,'); + userModel.splice(index, 1); + fs.writeFileSync('models/User.js', userModel.join(os.EOL)); + + index = app.indexOf("app.get('/auth/linkedin', passport.authenticate('linkedin', { state: 'SOME STATE' }));"); + app.splice(index, 4); + fs.writeFileSync('app.js', app.join(os.EOL)); + } + + index = "var InstagramStrategy = require('passport-instagram').Strategy;"; + if (instagramCheckbox.checked && index !== -1) { + passportConfig.splice(index, 1); + index = passportConfig.indexOf('// Sign in with Instagram.'); + passportConfig.splice(index, 40); + fs.writeFileSync('config/passport.js', passportConfig.join(os.EOL)); + + index = loginTemplate.indexOf(" a.btn.btn-block.btn-instagram.btn-social(href='/auth/instagram')"); + loginTemplate.splice(index, 3); + fs.writeFileSync('views/account/login.jade', loginTemplate.join(os.EOL)); + + index = profileTemplate.indexOf(' if user.instagram'); + profileTemplate.splice(index - 1, 5); + fs.writeFileSync('views/account/profile.jade', profileTemplate.join(os.EOL)); + + index = app.indexOf("app.get('/auth/instagram', passport.authenticate('instagram'));"); + app.splice(index, 4); + fs.writeFileSync('app.js', app.join(os.EOL)); + + userModel.splice(index, 1); + fs.writeFileSync('models/User.js', userModel.join(os.EOL)); + } + home.remove(authForm); home.append(success); - success.setContent('Selected authentication providers have been removed from passportConfig.js, User.js, secrets.js, app.js, login.jade and profile.jade!'); + success.setContent('Selected authentication providers have been removed from passportConfig.js, User.js, app.js, login.jade and profile.jade!'); success.focus(); screen.render(); }); @@ -219,7 +338,6 @@ var authText = blessed.text({ var facebookCheckbox = blessed.checkbox({ parent: authForm, top: 6, - checked: true, mouse: true, fg: 'white', bg: 'blue', @@ -229,7 +347,6 @@ var facebookCheckbox = blessed.checkbox({ var githubCheckbox = blessed.checkbox({ parent: authForm, top: 7, - checked: true, mouse: true, fg: 'white', bg: 'blue', @@ -239,7 +356,6 @@ var githubCheckbox = blessed.checkbox({ var googleCheckbox = blessed.checkbox({ parent: authForm, top: 8, - checked: true, mouse: true, fg: 'white', bg: 'blue', @@ -249,7 +365,6 @@ var googleCheckbox = blessed.checkbox({ var twitterCheckbox = blessed.checkbox({ parent: authForm, top: 9, - checked: true, mouse: true, fg: 'white', bg: 'blue', @@ -259,7 +374,6 @@ var twitterCheckbox = blessed.checkbox({ var linkedinCheckbox = blessed.checkbox({ parent: authForm, top: 10, - checked: true, mouse: true, fg: 'white', bg: 'blue', @@ -269,7 +383,6 @@ var linkedinCheckbox = blessed.checkbox({ var instagramCheckbox = blessed.checkbox({ parent: authForm, top: 11, - checked: true, mouse: true, fg: 'white', bg: 'blue', @@ -329,7 +442,7 @@ var emailForm = blessed.form({ padding: { left: 1, right: 1 } }); -emailForm.on('submit', function(data) { +emailForm.on('submit', function() { var contactCtrl = fs.readFileSync('controllers/contact.js').toString().split(os.EOL); var userCtrl = fs.readFileSync('controllers/user.js').toString().split(os.EOL); var choice = null; From 4d85f2ddcd628955522b66039a494734b430180a Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Tue, 13 May 2014 05:15:28 -0400 Subject: [PATCH 12/13] Fixed a bug with authentication remover --- setup.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/setup.js b/setup.js index 797d46a1aa..ddc4203778 100644 --- a/setup.js +++ b/setup.js @@ -201,8 +201,9 @@ authForm.on('submit', function() { fs.writeFileSync('app.js', app.join(os.EOL)); } - index = "var GitHubStrategy = require('passport-github').Strategy;";; + index = passportConfig.indexOf("var GitHubStrategy = require('passport-github').Strategy;"); if (githubCheckbox.checked && index !== -1) { + console.log(index); passportConfig.splice(index, 1); index = passportConfig.indexOf('// Sign in with GitHub.'); passportConfig.splice(index, 48); @@ -225,7 +226,7 @@ authForm.on('submit', function() { fs.writeFileSync('app.js', app.join(os.EOL)); } - index = "var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;"; + index = passportConfig.indexOf("var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;"); if (googleCheckbox.checked && index !== -1) { passportConfig.splice(index, 1); index = passportConfig.indexOf('// Sign in with Google.'); @@ -249,7 +250,7 @@ authForm.on('submit', function() { fs.writeFileSync('app.js', app.join(os.EOL)); } - index = "var TwitterStrategy = require('passport-twitter').Strategy;"; + index = passportConfig.indexOf("var TwitterStrategy = require('passport-twitter').Strategy;"); if (twitterCheckbox.checked && index !== -1) { passportConfig.splice(index, 1); index = passportConfig.indexOf('// Sign in with Twitter.'); @@ -273,11 +274,11 @@ authForm.on('submit', function() { fs.writeFileSync('app.js', app.join(os.EOL)); } - index = "var LinkedInStrategy = require('passport-linkedin-oauth2').Strategy;"; + index = passportConfig.indexOf("var LinkedInStrategy = require('passport-linkedin-oauth2').Strategy;"); if (linkedinCheckbox.checked && index !== -1) { passportConfig.splice(index, 1); index = passportConfig.indexOf('// Sign in with LinkedIn.'); - passportConfig.splice(index, 51); + passportConfig.splice(index, 47); fs.writeFileSync('config/passport.js', passportConfig.join(os.EOL)); index = loginTemplate.indexOf(" a.btn.btn-block.btn-linkedin.btn-social(href='/auth/linkedin')"); @@ -297,7 +298,7 @@ authForm.on('submit', function() { fs.writeFileSync('app.js', app.join(os.EOL)); } - index = "var InstagramStrategy = require('passport-instagram').Strategy;"; + index = passportConfig.indexOf("var InstagramStrategy = require('passport-instagram').Strategy;"); if (instagramCheckbox.checked && index !== -1) { passportConfig.splice(index, 1); index = passportConfig.indexOf('// Sign in with Instagram.'); From 3d5b71671614b4b17de89d1f9397ade306bc362d Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Tue, 13 May 2014 18:39:25 -0400 Subject: [PATCH 13/13] Removed old generator --- generator.js | 1062 -------------------------------------------------- setup.js | 64 +-- 2 files changed, 17 insertions(+), 1109 deletions(-) delete mode 100644 generator.js diff --git a/generator.js b/generator.js deleted file mode 100644 index 788ead2d11..0000000000 --- a/generator.js +++ /dev/null @@ -1,1062 +0,0 @@ -var _ = require('underscore'); -var colors = require('colors'); -var fs = require('fs'); -var inquirer = require('inquirer'); -var M = require('mstring'); -var os = require('os'); - -colors.setTheme({ - silly: 'rainbow', - input: 'grey', - verbose: 'cyan', - prompt: 'grey', - info: 'green', - data: 'grey', - help: 'white', - warn: 'yellow', - debug: 'blue', - error: 'red' -}); - -inquirer.prompt({ - type: 'list', - name: 'category', - message: 'Hackathon Starter:', - choices: ['☂ Authentication', '☎ Email Service', '☱ Exit'] -}, function(answer) { - - if (answer.category.match('Email Service')) { - inquirer.prompt({ - type: 'list', - name: 'email', - message: 'Choose Email Delivery Service:', - choices: ['SendGrid', 'Mailgun', 'Mandrill', 'Cancel'] - }, function(answer) { - - var index; - - var contactControllerFile = 'controllers/contact.js'; - var userControllerFile = 'controllers/user.js'; - - var contactController = fs.readFileSync(contactControllerFile).toString().split(os.EOL); - var userController = fs.readFileSync(userControllerFile).toString().split(os.EOL); - - if (answer.email.match('SendGrid')) { - - // Change SMPT Transport to SendGrid in controllers/contact.js - index = contactController.indexOf('var smtpTransport = nodemailer.createTransport(\'SMTP\', {'); - contactController.splice(index + 1, 1, ' service: \'SendGrid\','); - contactController.splice(index + 3, 1, ' user: secrets.sendgrid.user,'); - contactController.splice(index + 4, 1, ' pass: secrets.sendgrid.password'); - fs.writeFileSync(contactControllerFile, contactController.join(os.EOL)); - - // Change SMPT Transport to SendGrid in controllers/user.js - index = userController.indexOf(' var smtpTransport = nodemailer.createTransport(\'SMTP\', {'); - userController.splice(index + 1, 1, ' service: \'SendGrid\','); - userController.splice(index + 3, 1, ' user: secrets.sendgrid.user,'); - userController.splice(index + 4, 1, ' pass: secrets.sendgrid.password'); - index = userController.indexOf(' var smtpTransport = nodemailer.createTransport(\'SMTP\', {', (index + 1)); - userController.splice(index + 1, 1, ' service: \'SendGrid\','); - userController.splice(index + 3, 1, ' user: secrets.sendgrid.user,'); - userController.splice(index + 4, 1, ' pass: secrets.sendgrid.password'); - fs.writeFileSync(userControllerFile, userController.join(os.EOL)); - - console.log('✓ Email Delivery Service has been switched to'.info, 'SendGrid'.help); - } - - if (answer.email.match('Mailgun')) { - - // Change SMPT Transport to Mailgun in controllers/contact.js - index = contactController.indexOf('var smtpTransport = nodemailer.createTransport(\'SMTP\', {'); - contactController.splice(index + 1, 1, ' service: \'Mailgun\','); - contactController.splice(index + 3, 1, ' user: secrets.mailgun.login,'); - contactController.splice(index + 4, 1, ' pass: secrets.mailgun.password'); - fs.writeFileSync(contactControllerFile, contactController.join(os.EOL)); - - // Change SMPT Transport to Mailgun in controllers/user.js - index = userController.indexOf(' var smtpTransport = nodemailer.createTransport(\'SMTP\', {'); - userController.splice(index + 1, 1, ' service: \'Mailgun\','); - userController.splice(index + 3, 1, ' user: secrets.mailgun.login,'); - userController.splice(index + 4, 1, ' pass: secrets.mailgun.password'); - index = userController.indexOf(' var smtpTransport = nodemailer.createTransport(\'SMTP\', {', (index + 1)); - userController.splice(index + 1, 1, ' service: \'Mailgun\','); - userController.splice(index + 3, 1, ' user: secrets.mailgun.login,'); - userController.splice(index + 4, 1, ' pass: secrets.mailgun.password'); - fs.writeFileSync(userControllerFile, userController.join(os.EOL)); - - console.log('✓ Email Delivery Service has been switched to'.info, '@'.error + 'mail'.data + 'gun'.error); - } - - if (answer.email.match('Mandrill')) { - - // Change SMPT Transport to Mailgun in controllers/contact.js - index = contactController.indexOf('var smtpTransport = nodemailer.createTransport(\'SMTP\', {'); - contactController.splice(index + 1, 1, ' service: \'Mandrill\','); - contactController.splice(index + 3, 1, ' user: secrets.mandrill.login,'); - contactController.splice(index + 4, 1, ' pass: secrets.mandrill.password'); - fs.writeFileSync(contactControllerFile, contactController.join(os.EOL)); - - // Change SMPT Transport to Mailgun in controllers/user.js - index = userController.indexOf(' var smtpTransport = nodemailer.createTransport(\'SMTP\', {'); - userController.splice(index + 1, 1, ' service: \'Mandrill\','); - userController.splice(index + 3, 1, ' user: secrets.mandrill.login,'); - userController.splice(index + 4, 1, ' pass: secrets.mandrill.password'); - index = userController.indexOf(' var smtpTransport = nodemailer.createTransport(\'SMTP\', {', (index + 1)); - userController.splice(index + 1, 1, ' service: \'Mandrill\','); - userController.splice(index + 3, 1, ' user: secrets.mandrill.login,'); - userController.splice(index + 4, 1, ' pass: secrets.mandrill.password'); - fs.writeFileSync(userControllerFile, userController.join(os.EOL)); - - console.log('✓ Email Delivery Service has been switched to'.info, 'Mandrill'.help); - } - }); - } - - if (answer.category.match('Authentication')) { - inquirer.prompt({ - type: 'checkbox', - message: 'Select Authentication Providers', - name: 'auth', - choices: [ - new inquirer.Separator(M(function() { - /*** - - ╔══════════════════════════════════════════════════════════════════════╗ - ║ THIS TOOL IS STILL IN EXPERIMENTAL STAGE! USE AT YOUR OWN RISK. ║ - ║ ALWAYS USE VERSION CONTROL SYSTEM SO YOU COULD REVERT THE CHANGES. ║ - ║ REPORT BUGS AT HTTPS://GITHUB.COM/SAHAT/HACKATHON-STARTER/ISSUES/NEW ║ - ╚══════════════════════════════════════════════════════════════════════╝ - - ***/ - })), - { name: 'Facebook', checked: true }, - { name: 'GitHub', checked: true }, - { name: 'Google', checked: true }, - { name: 'Twitter', checked: true }, - { name: 'LinkedIn', checked: true }, - { name: 'Instagram', checked: true }, - new inquirer.Separator('Press ctrl+c to cancel'.warn) - ] - }, function(answer) { - var index; - - var passportConfigFile = 'config/passport.js'; - var userModelFile = 'models/User.js'; - var appFile = 'app.js'; - var secretsFile = 'config/secrets.js'; - var profileTemplateFile = 'views/account/profile.jade'; - var loginTemplateFile = 'views/account/login.jade'; - - var passportConfig = fs.readFileSync(passportConfigFile).toString().split(os.EOL); - var loginTemplate = fs.readFileSync(loginTemplateFile).toString().split(os.EOL); - var profileTemplate = fs.readFileSync(profileTemplateFile).toString().split(os.EOL); - var userModel = fs.readFileSync(userModelFile).toString().split(os.EOL); - var app = fs.readFileSync(appFile).toString().split(os.EOL); - var secrets = fs.readFileSync(secretsFile).toString().split(os.EOL); - - ///////////////////////////// - // Facebook Authentication // - ///////////////////////////// - - var facebookRoutes = M(function() { - /*** - app.get('/auth/facebook', passport.authenticate('facebook', { scope: ['email', 'user_location'] })); - app.get('/auth/facebook/callback', passport.authenticate('facebook', { failureRedirect: '/login' }), function(req, res) { - res.redirect(req.session.returnTo || '/'); - }); - ***/ - }); - var facebookStrategyRequire = "var FacebookStrategy = require('passport-facebook').Strategy;"; - var facebookStrategy = M(function() { - /*** - // Sign in with Facebook. - - passport.use(new FacebookStrategy(secrets.facebook, function(req, accessToken, refreshToken, profile, done) { - if (req.user) { - User.findOne({ facebook: profile.id }, function(err, existingUser) { - if (existingUser) { - req.flash('errors', { msg: 'There is already a Facebook account that belongs to you. Sign in with that account or delete it, then link it with your current account.' }); - done(err); - } else { - User.findById(req.user.id, function(err, user) { - user.facebook = profile.id; - user.tokens.push({ kind: 'facebook', accessToken: accessToken }); - user.profile.name = user.profile.name || profile.displayName; - user.profile.gender = user.profile.gender || profile._json.gender; - user.profile.picture = user.profile.picture || 'https://graph.facebook.com/' + profile.id + '/picture?type=large'; - user.save(function(err) { - req.flash('info', { msg: 'Facebook account has been linked.' }); - done(err, user); - }); - }); - } - }); - } else { - User.findOne({ facebook: profile.id }, function(err, existingUser) { - if (existingUser) return done(null, existingUser); - User.findOne({ email: profile._json.email }, function(err, existingEmailUser) { - if (existingEmailUser) { - req.flash('errors', { msg: 'There is already an account using this email address. Sign in to that account and link it with Facebook manually from Account Settings.' }); - done(err); - } else { - var user = new User(); - user.email = profile._json.email; - user.facebook = profile.id; - user.tokens.push({ kind: 'facebook', accessToken: accessToken }); - user.profile.name = profile.displayName; - user.profile.gender = profile._json.gender; - user.profile.picture = 'https://graph.facebook.com/' + profile.id + '/picture?type=large'; - user.profile.location = (profile._json.location) ? profile._json.location.name : ''; - user.save(function(err) { - done(err, user); - }); - } - }); - }); - } - })); - - ***/ - }); - var facebookButton = M(function() { - /*** - a.btn.btn-block.btn-facebook.btn-social(href='/auth/facebook') - i.fa.fa-facebook - | Sign in with Facebook - ***/ - }); - var facebookLinkUnlink = M(function() { - /*** - - if user.facebook - p: a.text-danger(href='/account/unlink/facebook') Unlink your Facebook account - else - p: a(href='/auth/facebook') Link your Facebook account - ***/ - }); - var facebookModel = ' facebook: String,'; - - if (_.contains(answer.auth, 'Facebook')) { - if (passportConfig.indexOf(facebookStrategyRequire) < 0) { - - // Add Facebook to config/passport.js - index = passportConfig.indexOf("var passport = require('passport');"); - passportConfig.splice(index + 1, 0, facebookStrategyRequire); - index = passportConfig.indexOf('passport.deserializeUser(function(id, done) {'); - passportConfig.splice(index + 6, 0, facebookStrategy); - fs.writeFileSync(passportConfigFile, passportConfig.join(os.EOL)); - - // Add Facebook to views/account/login.jade - loginTemplate.push(facebookButton); - fs.writeFileSync(loginTemplateFile, loginTemplate.join(os.EOL)); - - // Add Facebook to views/account/profile.jade - index = profileTemplate.indexOf(' h3 Linked Accounts'); - profileTemplate.splice(index + 1, 0, facebookLinkUnlink); - fs.writeFileSync(profileTemplateFile, profileTemplate.join(os.EOL)); - - // Add Facebook to models/User.js - index = userModel.indexOf(' tokens: Array,'); - userModel.splice(index - 1, 0, facebookModel); - fs.writeFileSync(userModelFile, userModel.join(os.EOL)); - - // Add Facebook to app.js - index = app.indexOf(' * OAuth routes for sign-in.'); - app.splice(index + 3, 0, facebookRoutes); - fs.writeFileSync(appFile, app.join(os.EOL)); - - console.log('✓ Facebook authentication has been added.'.info); - } else { - console.log('✓ Facebook authentication is already active.'.data); - } - } else { - - // config/passport.js - index = passportConfig.indexOf(facebookStrategyRequire); - passportConfig.splice(index, 1); - index = passportConfig.indexOf('// Sign in with Facebook.'); - passportConfig.splice(index, 47); - fs.writeFileSync(passportConfigFile, passportConfig.join(os.EOL)); - - // views/account/login.jade - index = loginTemplate.indexOf(" a.btn.btn-block.btn-facebook.btn-social(href='/auth/facebook')"); - loginTemplate.splice(index, 3); - fs.writeFileSync(loginTemplateFile, loginTemplate.join(os.EOL)); - - // views/account/profile.jade - index = profileTemplate.indexOf(" if user.facebook"); - profileTemplate.splice(index - 1, 5); - fs.writeFileSync(profileTemplateFile, profileTemplate.join(os.EOL)); - - // models/User.js - index = userModel.indexOf(' facebook: String,'); - userModel.splice(index, 1); - fs.writeFileSync(userModelFile, userModel.join(os.EOL)); - - // Remove Facebook from app.js - index = app.indexOf("app.get('/auth/facebook', passport.authenticate('facebook', { scope: ['email', 'user_location'] }));"); - app.splice(index, 4); - fs.writeFileSync(appFile, app.join(os.EOL)); - - console.log('✗ Facebook authentication has been removed.'.error); - } - - /////////////////////////// - // GitHub Authentication // - /////////////////////////// - - var githubRoutes = M(function() { - /*** - app.get('/auth/github', passport.authenticate('github')); - app.get('/auth/github/callback', passport.authenticate('github', { failureRedirect: '/login' }), function(req, res) { - res.redirect(req.session.returnTo || '/'); - }); - ***/ - }); - var githubStrategyRequire = "var GitHubStrategy = require('passport-github').Strategy;"; - var githubStrategy = M(function() { - /*** - // Sign in with GitHub. - - passport.use(new GitHubStrategy(secrets.github, function(req, accessToken, refreshToken, profile, done) { - if (req.user) { - User.findOne({ github: profile.id }, function(err, existingUser) { - if (existingUser) { - req.flash('errors', { msg: 'There is already a GitHub account that belongs to you. Sign in with that account or delete it, then link it with your current account.' }); - done(err); - } else { - User.findById(req.user.id, function(err, user) { - user.github = profile.id; - user.tokens.push({ kind: 'github', accessToken: accessToken }); - user.profile.name = user.profile.name || profile.displayName; - user.profile.picture = user.profile.picture || profile._json.avatar_url; - user.profile.location = user.profile.location || profile._json.location; - user.profile.website = user.profile.website || profile._json.blog; - user.save(function(err) { - req.flash('info', { msg: 'GitHub account has been linked.' }); - done(err, user); - }); - }); - } - }); - } else { - User.findOne({ github: profile.id }, function(err, existingUser) { - if (existingUser) return done(null, existingUser); - User.findOne({ email: profile._json.email }, function(err, existingEmailUser) { - if (existingEmailUser) { - req.flash('errors', { msg: 'There is already an account using this email address. Sign in to that account and link it with GitHub manually from Account Settings.' }); - done(err); - } else { - var user = new User(); - user.email = profile._json.email; - user.github = profile.id; - user.tokens.push({ kind: 'github', accessToken: accessToken }); - user.profile.name = profile.displayName; - user.profile.picture = profile._json.avatar_url; - user.profile.location = profile._json.location; - user.profile.website = profile._json.blog; - user.save(function(err) { - done(err, user); - }); - } - }); - }); - } - })); - - ***/ - }); - - var githubButton = M(function() { - /*** - a.btn.btn-block.btn-github.btn-social(href='/auth/github') - i.fa.fa-github - | Sign in with GitHub - ***/ - }); - var githubLinkUnlink = M(function() { - /*** - - if user.github - p: a.text-danger(href='/account/unlink/github') Unlink your GitHub account - else - p: a(href='/auth/github') Link your GitHub account - ***/ - }); - var githubModel = ' github: String,'; - - if (_.contains(answer.auth, 'GitHub')) { - if (passportConfig.indexOf(githubStrategyRequire) < 0) { - - // config/passport.js - index = passportConfig.indexOf("var passport = require('passport');"); - passportConfig.splice(index + 1, 0, githubStrategyRequire); - index = passportConfig.indexOf('passport.deserializeUser(function(id, done) {'); - passportConfig.splice(index + 6, 0, githubStrategy); - fs.writeFileSync(passportConfigFile, passportConfig.join(os.EOL)); - - // views/account/login.jade - loginTemplate.push(githubButton); - fs.writeFileSync(loginTemplateFile, loginTemplate.join(os.EOL)); - - // views/account/profile.jade - index = profileTemplate.indexOf(' h3 Linked Accounts'); - profileTemplate.splice(index + 1, 0, githubLinkUnlink); - fs.writeFileSync(profileTemplateFile, profileTemplate.join(os.EOL)); - - // models/User.js - index = userModel.indexOf(' tokens: Array,'); - userModel.splice(index - 1, 0, githubModel); - fs.writeFileSync(userModelFile, userModel.join(os.EOL)); - - // Add GitHub to app.js - index = app.indexOf(' * OAuth routes for sign-in.'); - app.splice(index + 3, 0, githubRoutes); - fs.writeFileSync(appFile, app.join(os.EOL)); - - console.log('✓ GitHub authentication has been added.'.info); - } else { - console.log('✓ GitHub authentication is already active.'.data); - } - } else { - - // config/passport.js - index = passportConfig.indexOf(githubStrategyRequire); - passportConfig.splice(index, 1); - index = passportConfig.indexOf('// Sign in with GitHub.'); - passportConfig.splice(index, 48); - fs.writeFileSync(passportConfigFile, passportConfig.join(os.EOL)); - - // views/account/login.jade - index = loginTemplate.indexOf(" a.btn.btn-block.btn-github.btn-social(href='/auth/github')"); - loginTemplate.splice(index, 3); - fs.writeFileSync(loginTemplateFile, loginTemplate.join(os.EOL)); - - // views/account/profile.jade - index = profileTemplate.indexOf(' if user.github'); - profileTemplate.splice(index - 1, 5); - fs.writeFileSync(profileTemplateFile, profileTemplate.join(os.EOL)); - - // models/User.js - index = userModel.indexOf(' github: String,'); - userModel.splice(index, 1); - fs.writeFileSync(userModelFile, userModel.join(os.EOL)); - - // Remove GitHub from app.js - index = app.indexOf("app.get('/auth/github', passport.authenticate('github'));"); - app.splice(index, 4); - fs.writeFileSync(appFile, app.join(os.EOL)); - - console.log('✗ GitHub authentication has been removed.'.error); - } - - /////////////////////////// - // Google Authentication // - /////////////////////////// - - var googleRoutes = M(function() { - /*** - app.get('/auth/google', passport.authenticate('google', { scope: 'profile email' })); - app.get('/auth/google/callback', passport.authenticate('google', { failureRedirect: '/login' }), function(req, res) { - res.redirect(req.session.returnTo || '/'); - }); - ***/ - }); - var googleStrategyRequire = "var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;"; - var googleStrategy = M(function() { - /*** - // Sign in with Google. - - passport.use(new GoogleStrategy(secrets.google, function(req, accessToken, refreshToken, profile, done) { - if (req.user) { - User.findOne({ google: profile.id }, function(err, existingUser) { - if (existingUser) { - req.flash('errors', { msg: 'There is already a Google account that belongs to you. Sign in with that account or delete it, then link it with your current account.' }); - done(err); - } else { - User.findById(req.user.id, function(err, user) { - user.google = profile.id; - user.tokens.push({ kind: 'google', accessToken: accessToken }); - user.profile.name = user.profile.name || profile.displayName; - user.profile.gender = user.profile.gender || profile._json.gender; - user.profile.picture = user.profile.picture || profile._json.picture; - user.save(function(err) { - req.flash('info', { msg: 'Google account has been linked.' }); - done(err, user); - }); - }); - } - }); - } else { - User.findOne({ google: profile.id }, function(err, existingUser) { - if (existingUser) return done(null, existingUser); - User.findOne({ email: profile._json.email }, function(err, existingEmailUser) { - if (existingEmailUser) { - req.flash('errors', { msg: 'There is already an account using this email address. Sign in to that account and link it with Google manually from Account Settings.' }); - done(err); - } else { - var user = new User(); - user.email = profile._json.email; - user.google = profile.id; - user.tokens.push({ kind: 'google', accessToken: accessToken }); - user.profile.name = profile.displayName; - user.profile.gender = profile._json.gender; - user.profile.picture = profile._json.picture; - user.save(function(err) { - done(err, user); - }); - } - }); - }); - } - })); - - ***/ - }); - - var googleButton = M(function() { - /*** - a.btn.btn-block.btn-google-plus.btn-social(href='/auth/google') - i.fa.fa-google-plus - | Sign in with Google - ***/ - }); - var googleLinkUnlink = M(function() { - /*** - - if user.google - p: a.text-danger(href='/account/unlink/google') Unlink your Google account - else - p: a(href='/auth/google') Link your Google account - ***/ - }); - var googleModel = ' google: String,'; - - if (_.contains(answer.auth, 'Google')) { - if (passportConfig.indexOf(googleStrategyRequire) < 0) { - - // Add Google to config/passport.js - index = passportConfig.indexOf("var passport = require('passport');"); - passportConfig.splice(index + 1, 0, googleStrategyRequire); - index = passportConfig.indexOf('passport.deserializeUser(function(id, done) {'); - passportConfig.splice(index + 6, 0, googleStrategy); - fs.writeFileSync(passportConfigFile, passportConfig.join(os.EOL)); - - // Add Google to views/account/login.jade - loginTemplate.push(googleButton); - fs.writeFileSync(loginTemplateFile, loginTemplate.join(os.EOL)); - - // Add Google to views/account/profile.jade - index = profileTemplate.indexOf(' h3 Linked Accounts'); - profileTemplate.splice(index + 1, 0, googleLinkUnlink); - fs.writeFileSync(profileTemplateFile, profileTemplate.join(os.EOL)); - - // Add Google to models/User.js - index = userModel.indexOf(' tokens: Array,'); - userModel.splice(index - 1, 0, googleModel); - fs.writeFileSync(userModelFile, userModel.join(os.EOL)); - - // Add Google to app.js - index = app.indexOf(' * OAuth routes for sign-in.'); - app.splice(index + 3, 0, googleRoutes); - fs.writeFileSync(appFile, app.join(os.EOL)); - - console.log('✓ Google authentication has been added.'.info); - } else { - console.log('✓ Google authentication is already active.'.data); - } - } else { - - // Remove Google from config/passport.js - index = passportConfig.indexOf(googleStrategyRequire); - passportConfig.splice(index, 1); - index = passportConfig.indexOf('// Sign in with Google.'); - passportConfig.splice(index, 46); - fs.writeFileSync(passportConfigFile, passportConfig.join(os.EOL)); - - // Remove Google from views/account/login.jade - index = loginTemplate.indexOf(" a.btn.btn-block.btn-google-plus.btn-social(href='/auth/google')"); - loginTemplate.splice(index, 3); - fs.writeFileSync(loginTemplateFile, loginTemplate.join(os.EOL)); - - // Remove Google from views/account/profile.jade - index = profileTemplate.indexOf(' if user.google'); - profileTemplate.splice(index - 1, 5); - fs.writeFileSync(profileTemplateFile, profileTemplate.join(os.EOL)); - - // Remove Google from models/User.js - index = userModel.indexOf(' google: String,'); - userModel.splice(index, 1); - fs.writeFileSync(userModelFile, userModel.join(os.EOL)); - - // Remove Google from app.js - index = app.indexOf("app.get('/auth/google', passport.authenticate('google', { scope: 'profile email' }));"); - app.splice(index, 4); - fs.writeFileSync(appFile, app.join(os.EOL)); - - console.log('✗ Google authentication has been removed.'.error); - } - - //////////////////////////// - // Twitter Authentication // - //////////////////////////// - - var twitterRoutes = M(function() { - /*** - app.get('/auth/twitter', passport.authenticate('twitter')); - app.get('/auth/twitter/callback', passport.authenticate('twitter', { failureRedirect: '/login' }), function(req, res) { - res.redirect(req.session.returnTo || '/'); - }); - ***/ - }); - var twitterStrategyRequire = "var TwitterStrategy = require('passport-twitter').Strategy;"; - var twitterStrategy = M(function() { - /*** - // Sign in with Twitter. - - passport.use(new TwitterStrategy(secrets.twitter, function(req, accessToken, tokenSecret, profile, done) { - if (req.user) { - User.findOne({ twitter: profile.id }, function(err, existingUser) { - if (existingUser) { - req.flash('errors', { msg: 'There is already a Twitter account that belongs to you. Sign in with that account or delete it, then link it with your current account.' }); - done(err); - } else { - User.findById(req.user.id, function(err, user) { - user.twitter = profile.id; - user.tokens.push({ kind: 'twitter', accessToken: accessToken, tokenSecret: tokenSecret }); - user.profile.name = user.profile.name || profile.displayName; - user.profile.location = user.profile.location || profile._json.location; - user.profile.picture = user.profile.picture || profile._json.profile_image_url; - user.save(function(err) { - req.flash('info', { msg: 'Twitter account has been linked.' }); - done(err, user); - }); - }); - } - }); - } else { - User.findOne({ twitter: profile.id }, function(err, existingUser) { - if (existingUser) return done(null, existingUser); - var user = new User(); - // Twitter will not provide an email address. Period. - // But a person’s twitter username is guaranteed to be unique - // so we can "fake" a twitter email address as follows: - user.email = profile.username + "@twitter.com"; - user.twitter = profile.id; - user.tokens.push({ kind: 'twitter', accessToken: accessToken, tokenSecret: tokenSecret }); - user.profile.name = profile.displayName; - user.profile.location = profile._json.location; - user.profile.picture = profile._json.profile_image_url; - user.save(function(err) { - done(err, user); - }); - }); - } - })); - ***/ - }); - - var twitterButton = M(function() { - /*** - a.btn.btn-block.btn-twitter-plus.btn-social(href='/auth/twitter') - i.fa.fa-twitter - | Sign in with Twitter - ***/ - }); - var twitterLinkUnlink = M(function() { - /*** - - if user.twitter - p: a.text-danger(href='/account/unlink/twitter') Unlink your Twitter account - else - p: a(href='/auth/twitter') Link your Twitter account - ***/ - }); - var twitterModel = ' twitter: String,'; - - if (_.contains(answer.auth, 'Twitter')) { - if (passportConfig.indexOf(twitterStrategyRequire) < 0) { - - // config/passport.js - index = passportConfig.indexOf("var passport = require('passport');"); - passportConfig.splice(index + 1, 0, twitterStrategyRequire); - index = passportConfig.indexOf('passport.deserializeUser(function(id, done) {'); - passportConfig.splice(index + 6, 0, twitterStrategy); - fs.writeFileSync(passportConfigFile, passportConfig.join(os.EOL)); - - // views/account/login.jade - loginTemplate.push(twitterButton); - fs.writeFileSync(loginTemplateFile, loginTemplate.join(os.EOL)); - - // views/account/profile.jade - index = profileTemplate.indexOf(' h3 Linked Accounts'); - profileTemplate.splice(index + 1, 0, twitterLinkUnlink); - fs.writeFileSync(profileTemplateFile, profileTemplate.join(os.EOL)); - - // models/User.js - index = userModel.indexOf(' tokens: Array,'); - userModel.splice(index - 1, 0, twitterModel); - fs.writeFileSync(userModelFile, userModel.join(os.EOL)); - - // Add Twitter to app.js - index = app.indexOf(' * OAuth routes for sign-in.'); - app.splice(index + 3, 0, twitterRoutes); - fs.writeFileSync(appFile, app.join(os.EOL)); - - console.log('✓ Twitter authentication has been added.'.info); - } else { - console.log('✓ Twitter authentication is already active.'.data); - } - } else { - - // Remove Twitter from config/passport.js - index = passportConfig.indexOf(twitterStrategyRequire); - passportConfig.splice(index, 1); - index = passportConfig.indexOf('// Sign in with Twitter.'); - passportConfig.splice(index, 43); - fs.writeFileSync(passportConfigFile, passportConfig.join(os.EOL)); - - // Remove Twitter from views/account/login.jade - index = loginTemplate.indexOf(" a.btn.btn-block.btn-twitter.btn-social(href='/auth/twitter')"); - loginTemplate.splice(index, 3); - fs.writeFileSync(loginTemplateFile, loginTemplate.join(os.EOL)); - - // Remove Twitter from views/account/profile.jade - index = profileTemplate.indexOf(' if user.twitter'); - profileTemplate.splice(index - 1, 5); - fs.writeFileSync(profileTemplateFile, profileTemplate.join(os.EOL)); - - // Remove Twitter from models/User.js - index = userModel.indexOf(' twitter: String,'); - userModel.splice(index, 1); - fs.writeFileSync(userModelFile, userModel.join(os.EOL)); - - // Remove Twitter from app.js - index = app.indexOf("app.get('/auth/twitter', passport.authenticate('twitter'));"); - app.splice(index, 4); - fs.writeFileSync(appFile, app.join(os.EOL)); - - console.log('✗ Twitter authentication has been removed.'.error); - } - - ///////////////////////////// - // LinkedIn Authentication // - ///////////////////////////// - - var linkedinRoutes = M(function() { - /*** - app.get('/auth/linkedin', passport.authenticate('linkedin', { state: 'SOME STATE' })); - app.get('/auth/linkedin/callback', passport.authenticate('linkedin', { failureRedirect: '/login' }), function(req, res) { - res.redirect(req.session.returnTo || '/'); - }); - ***/ - }); - var linkedinStrategyRequire = "var LinkedInStrategy = require('passport-linkedin-oauth2').Strategy;"; - var linkedinStrategy = M(function() { - /*** - // Sign in with LinkedIn. - - passport.use(new LinkedInStrategy(secrets.linkedin, function(req, accessToken, refreshToken, profile, done) { - if (req.user) { - User.findOne({ linkedin: profile.id }, function(err, existingUser) { - if (existingUser) { - req.flash('errors', { msg: 'There is already a LinkedIn account that belongs to you. Sign in with that account or delete it, then link it with your current account.' }); - done(err); - } else { - User.findById(req.user.id, function(err, user) { - user.linkedin = profile.id; - user.tokens.push({ kind: 'linkedin', accessToken: accessToken }); - user.profile.name = user.profile.name || profile.displayName; - user.profile.location = user.profile.location || profile._json.location.name; - user.profile.picture = user.profile.picture || profile._json.pictureUrl; - user.profile.website = user.profile.website || profile._json.publicProfileUrl; - user.save(function(err) { - req.flash('info', { msg: 'LinkedIn account has been linked.' }); - done(err, user); - }); - }); - } - }); - } else { - User.findOne({ linkedin: profile.id }, function(err, existingUser) { - if (existingUser) return done(null, existingUser); - User.findOne({ email: profile._json.emailAddress }, function(err, existingEmailUser) { - if (existingEmailUser) { - req.flash('errors', { msg: 'There is already an account using this email address. Sign in to that account and link it with LinkedIn manually from Account Settings.' }); - done(err); - } else { - var user = new User(); - user.linkedin = profile.id; - user.tokens.push({ kind: 'linkedin', accessToken: accessToken }); - user.email = profile._json.emailAddress; - user.profile.name = profile.displayName; - user.profile.location = profile._json.location.name; - user.profile.picture = profile._json.pictureUrl; - user.profile.website = profile._json.publicProfileUrl; - user.save(function(err) { - done(err, user); - }); - } - }); - }); - } - })); - ***/ - }); - - var linkedinButton = M(function() { - /*** - a.btn.btn-block.btn-linkedin.btn-social(href='/auth/linkedin') - i.fa.fa-linkedin - | Sign in with LinkedIn - ***/ - }); - var linkedinLinkUnlink = M(function() { - /*** - - if user.linkedin - p: a.text-danger(href='/account/unlink/linkedin') Unlink your LinkedIn account - else - p: a(href='/auth/linkedin') Link your LinkedIn account - ***/ - }); - var linkedinModel = ' linkedin: String,'; - - if (_.contains(answer.auth, 'LinkedIn')) { - if (passportConfig.indexOf(linkedinStrategyRequire) < 0) { - - // Add LinkedIn to passport.js - index = passportConfig.indexOf("var passport = require('passport');"); - passportConfig.splice(index + 1, 0, linkedinStrategyRequire); - index = passportConfig.indexOf('passport.deserializeUser(function(id, done) {'); - passportConfig.splice(index + 6, 0, linkedinStrategy); - fs.writeFileSync(passportConfigFile, passportConfig.join(os.EOL)); - - // Add LinkedIn to login.jade - loginTemplate.push(linkedinButton); - fs.writeFileSync(loginTemplateFile, loginTemplate.join(os.EOL)); - - // Add LinkedIn to profile.jade - index = profileTemplate.indexOf(' h3 Linked Accounts'); - profileTemplate.splice(index + 1, 0, linkedinLinkUnlink); - fs.writeFileSync(profileTemplateFile, profileTemplate.join(os.EOL)); - - // Add LinkedIn to models/User.js - index = userModel.indexOf(' tokens: Array,'); - userModel.splice(index - 1, 0, linkedinModel); - fs.writeFileSync(userModelFile, userModel.join(os.EOL)); - - // Add LinkedIn to app.js - index = app.indexOf(' * OAuth routes for sign-in.'); - app.splice(index + 3, 0, linkedinRoutes); - fs.writeFileSync(appFile, app.join(os.EOL)); - - console.log('✓ LinkedIn authentication has been added.'.info); - } else { - console.log('✓ LinkedIn authentication is already active.'.data); - } - } else { - - // Check if we have LinkedIn authentication to begin with. - if (passportConfig.indexOf(linkedinStrategyRequire) < 0) return; - - // Removed LinkedIn from passport.js - index = passportConfig.indexOf(linkedinStrategyRequire); - passportConfig.splice(index, 1); - index = passportConfig.indexOf('// Sign in with LinkedIn.'); - passportConfig.splice(index, 51); - fs.writeFileSync(passportConfigFile, passportConfig.join(os.EOL)); - - // Remove LinkedIn from login.jade - index = loginTemplate.indexOf(" a.btn.btn-block.btn-linkedin.btn-social(href='/auth/linkedin')"); - loginTemplate.splice(index, 3); - fs.writeFileSync(loginTemplateFile, loginTemplate.join(os.EOL)); - - // Remove LinkedIn from profile.jade - index = profileTemplate.indexOf(' if user.linkedin'); - profileTemplate.splice(index - 1, 5); - fs.writeFileSync(profileTemplateFile, profileTemplate.join(os.EOL)); - - // Remove LinkedIn from app.js - index = app.indexOf("app.get('/auth/linkedin', passport.authenticate('linkedin', { state: 'SOME STATE' }));"); - app.splice(index, 4); - fs.writeFileSync(appFile, app.join(os.EOL)); - - // Remove LinkedIn from User.js - index = userModel.indexOf(' linkedin: String,'); - userModel.splice(index, 1); - fs.writeFileSync(userModelFile, userModel.join(os.EOL)); - - console.log('✗ LinkedIn authentication has been removed.'.error); - } - - ////////////////////////////// - // Instagram Authentication // - ////////////////////////////// - - var instagramRoutes = M(function() { - /*** - app.get('/auth/instagram', passport.authenticate('instagram')); - app.get('/auth/instagram/callback', passport.authenticate('instagram', { failureRedirect: '/login' }), function(req, res) { - res.redirect(req.session.returnTo || '/'); - }); - ***/ - }); - var instagramSecrets = M(function() { - /*** - instagram: { - clientID: process.env.INSTAGRAM_ID || 'Your Client ID', - clientSecret: process.env.INSTAGRAM_SECRET || 'Your Client Secret', - callbackURL: '/auth/instagram/callback', - passReqToCallback: true - }, - - ***/ - }); - var instagramStrategyRequire = "var InstagramStrategy = require('passport-instagram').Strategy;"; - var instagramStrategy = M(function() { - /*** - // Sign in with Instagram. - - passport.use(new InstagramStrategy(secrets.instagram,function(req, accessToken, refreshToken, profile, done) { - if (req.user) { - User.findOne({ instagram: profile.id }, function(err, existingUser) { - if (existingUser) { - req.flash('errors', { msg: 'There is already an Instagram account that belongs to you. Sign in with that account or delete it, then link it with your current account.' }); - done(err); - } else { - User.findById(req.user.id, function(err, user) { - user.instagram = profile.id; - user.tokens.push({ kind: 'instagram', accessToken: accessToken }); - user.profile.name = user.profile.name || profile.displayName; - user.profile.picture = user.profile.picture || profile._json.data.profile_picture; - user.profile.website = user.profile.website || profile._json.data.website; - user.save(function(err) { - req.flash('info', { msg: 'Instagram account has been linked.' }); - done(err, user); - }); - }); - } - }); - } else { - User.findOne({ instagram: profile.id }, function(err, existingUser) { - if (existingUser) return done(null, existingUser); - - var user = new User(); - user.instagram = profile.id; - user.tokens.push({ kind: 'instagram', accessToken: accessToken }); - user.profile.name = profile.displayName; - // Similar to Twitter API, assigns a temporary e-mail address - // to get on with the registration process. It can be changed later - // to a valid e-mail address in Profile Management. - user.email = profile.username + "@instagram.com"; - user.profile.website = profile._json.data.website; - user.profile.picture = profile._json.data.profile_picture; - user.save(function(err) { - done(err, user); - }); - }); - } - })); - - ***/ - }); - - var instagramButton = M(function() { - /*** - a.btn.btn-block.btn-instagram.btn-social(href='/auth/instagram') - i.fa.fa-instagram - | Sign in with Instagram - ***/ - }); - var instagramLinkUnlink = M(function() { - /*** - - if user.instagram - p: a.text-danger(href='/account/unlink/instagram') Unlink your Instagram account - else - p: a(href='/auth/instagram') Link your Instagram account - ***/ - }); - var instagramModel = ' instagram: String,'; - - if (_.contains(answer.auth, 'Instagram')) { - - if (passportConfig.indexOf(instagramStrategyRequire) < 0) { - - // Add Instagram to passport.js - index = passportConfig.indexOf("var passport = require('passport');"); - passportConfig.splice(index + 1, 0, instagramStrategyRequire); - index = passportConfig.indexOf('passport.deserializeUser(function(id, done) {'); - passportConfig.splice(index + 6, 0, instagramStrategy); - fs.writeFileSync(passportConfigFile, passportConfig.join(os.EOL)); - - // Add Instagram to login.jade - loginTemplate.push(instagramButton); - fs.writeFileSync(loginTemplateFile, loginTemplate.join(os.EOL)); - - // Add Instagram to profile.jade - index = profileTemplate.indexOf(' h3 Linked Accounts'); - profileTemplate.splice(index + 1, 0, instagramLinkUnlink); - fs.writeFileSync(profileTemplateFile, profileTemplate.join(os.EOL)); - - // Add Instagram to User.js - index = userModel.indexOf(' tokens: Array,'); - userModel.splice(index - 1, 0, instagramModel); - fs.writeFileSync(userModelFile, userModel.join(os.EOL)); - - // Add Instagram to app.js - index = app.indexOf(' * OAuth routes for sign-in.'); - app.splice(index + 3, 0, instagramRoutes); - fs.writeFileSync(appFile, app.join(os.EOL)); - - // Add Instagram to secrets.js - index = secrets.indexOf('module.exports = {'); - secrets.splice(index + 1, 0, instagramSecrets); - fs.writeFileSync(secretsFile, secrets.join(os.EOL)); - - console.log('✓ Instagram authentication has been added.'.info); - } else { - console.log('✓ Instagram authentication is already active.'.data); - } - } else { - - if (passportConfig.indexOf(instagramStrategyRequire) < 0) return; - - // Remove Instagram from passport.js - index = passportConfig.indexOf(instagramStrategyRequire); - passportConfig.splice(index, 1); - index = passportConfig.indexOf('// Sign in with Instagram.'); - passportConfig.splice(index, 40); - fs.writeFileSync(passportConfigFile, passportConfig.join(os.EOL)); - - // Remove Instagram from login.jade - index = loginTemplate.indexOf(" a.btn.btn-block.btn-instagram.btn-social(href='/auth/instagram')"); - loginTemplate.splice(index, 3); - fs.writeFileSync(loginTemplateFile, loginTemplate.join(os.EOL)); - - // Remove Instagram from profile.jade - index = profileTemplate.indexOf(' if user.instagram'); - profileTemplate.splice(index - 1, 5); - fs.writeFileSync(profileTemplateFile, profileTemplate.join(os.EOL)); - - // Remove Instagram from app.js - index = app.indexOf("app.get('/auth/instagram', passport.authenticate('instagram'));"); - app.splice(index, 4); - fs.writeFileSync(appFile, app.join(os.EOL)); - - // Remove Instagram from secrets.js - index = secrets.indexOf(' instagram: {'); - secrets.splice(index, 7); - fs.writeFileSync(secretsFile, secrets.join(os.EOL)); - - // Remove Instagram from User.js - index = userModel.indexOf(' instagram: String,'); - userModel.splice(index, 1); - fs.writeFileSync(userModelFile, userModel.join(os.EOL)); - - console.log('✗ Instagram authentication has been removed.'.error); - } - }); - } -}); diff --git a/setup.js b/setup.js index ddc4203778..4a71b149ee 100644 --- a/setup.js +++ b/setup.js @@ -23,12 +23,28 @@ var home = blessed.list({ items: [ '» REMOVE AUTHENTICATION PROVIDER', '» CHANGE EMAIL SERVICE', - '» ENABLE SOCKET.IO', '» ADD NODE.JS CLUSTER SUPPORT', '» EXIT' ] }); +var homeTitle = blessed.text({ + parent: screen, + align: 'center', + fg: 'blue', + bg: 'white', + content: 'Hackathon Starter (c) 2014' +}); + +var footer = blessed.text({ + parent: screen, + bottom: 0, + fg: 'white', + bg: 'blue', + tags: true, + content: ' {cyan-fg}{/cyan-fg} moves | {cyan-fg}{/cyan-fg} selects | {cyan-fg}{/cyan-fg} exits' +}); + var inner = blessed.form({ top: 'center', left: 'center', @@ -68,14 +84,6 @@ success.on('keypress', function() { home.remove(success); }); -var socketText = blessed.text({ - top: 'top', - bg: 'red', - fg: 'white', - tags: true, - content: 'Add real-time support to your application with Socket.IO.' -}); - var clusterText = blessed.text({ top: 'top', bg: 'red', @@ -555,8 +563,6 @@ var emailCancel = blessed.button({ } }); - - emailCancel.on('press', function() { home.focus(); home.remove(emailForm); @@ -564,23 +570,6 @@ emailCancel.on('press', function() { }); -var homeTitle = blessed.text({ - parent: screen, - align: 'center', - fg: 'blue', - bg: 'white', - content: 'Hackathon Starter (c) 2014' -}); - -var footer = blessed.text({ - parent: screen, - bottom: 0, - fg: 'white', - bg: 'blue', - tags: true, - content: ' {cyan-fg}{/cyan-fg} moves | {cyan-fg}{/cyan-fg} selects | {cyan-fg}{/cyan-fg} exits' -}); - home.on('select', function(child, index) { switch (index) { case 0: @@ -593,13 +582,6 @@ home.on('select', function(child, index) { emailForm.focus(); break; case 2: - enableSocketIo(); - home.append(success); - success.setContent('Socket.IO events have been added at the bottom of {underline}app.js{/underline}. To see a working example take a look at /dashboard. Be sure to run npm install socket.io'); - success.focus(); - screen.render(); - break; - case 3: addClusterSupport(); home.append(success); success.setContent('New file {underline}cluster_app.js{/underline} has been created. Your app is now able to use more than 1 CPU by running {underline}node cluster_app.js{/underline}, which in turn spawns multiple instances of {underline}app.js{/underline}'); @@ -611,9 +593,6 @@ home.on('select', function(child, index) { } }); - - - screen.render(); @@ -640,13 +619,4 @@ for (var i = 0; i < os.cpus().length; i++) { }); fs.writeFileSync('cluster_app.js', fileContents); -} - -function enableSocketIo() { - var fileContents = multiline(function() { - /* - - - */ - }); } \ No newline at end of file