From 0e4e259a683a374184aea3838f15ad65cc05bfe7 Mon Sep 17 00:00:00 2001 From: Appsaloon Toon Nelissen Date: Tue, 28 Apr 2015 16:52:01 +0200 Subject: [PATCH 1/8] add users command line via script --- add_user.js | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 add_user.js diff --git a/add_user.js b/add_user.js new file mode 100644 index 0000000..6772808 --- /dev/null +++ b/add_user.js @@ -0,0 +1,58 @@ +var colors = require('colors/safe'); +var fs = require('fs'); +var readline = require('readline'); + +var rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + terminal: false +}); + +var ticker = 0; +var user = {}; +var users; +var usersFile; + +if (fs.existsSync('users.json')) { + try { + var usersFile = fs.readFileSync('users.json', 'utf8'); + users = JSON.parse(usersFile); + console.info(colors.green('Found users.json file')); + console.info(colors.green('Contains '+ users.length + ' users')); + } catch (e) { + console.error(colors.red('users.json is not a valid json')); + } +} else { + var fd = fs.openSync('users.json', 'w'); + console.info(colors.green('users.json file created')); + users = []; +} + + +console.log(colors.yellow.underline('Create a user:')); +console.log(colors.yellow('Enter the username:')); + +rl.on('line', function(line){ + switch (ticker) { + case 0: + user.username = line; + console.log(colors.yellow('Enter the password:')); + + break; + case 1: + user.password = line; + user.id = users.length; + users.push(user); + fs.writeFile("users.json", JSON.stringify(users), function(err) { + if(err) { + return console.log(err); + } + + console.log("The file was saved!"); + }); + rl.close(); + break; + } + ticker++; +}); + From b40fec6a0338f2ea097d0e1affef0231bc35f3b8 Mon Sep 17 00:00:00 2001 From: Appsaloon Toon Nelissen Date: Tue, 28 Apr 2015 16:56:10 +0200 Subject: [PATCH 2/8] updated the documentation about the add_user.js file --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 51cbd46..3535d44 100644 --- a/README.md +++ b/README.md @@ -43,11 +43,13 @@ they will be visible to forever, via sudo only. [\[1\]][1] ## Add a users.json file Add a `users.json` to the root of forever-webui -``` [{ +``` +[{ "username" : "here the name of your user", "password" : "here the password for your user" }] ``` +or run this will create a users.json file if it doesn't exist yet and adds a new user via prompt. ```node add_user``` ## Run Tests From 0d4b57faa49645ad77b9b8c584ecce41650b60cc Mon Sep 17 00:00:00 2001 From: Appsaloon Toon Nelissen Date: Tue, 28 Apr 2015 16:59:07 +0200 Subject: [PATCH 3/8] readme changes --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3535d44..8beb0bd 100644 --- a/README.md +++ b/README.md @@ -42,14 +42,17 @@ they will be visible to forever, via sudo only. [\[1\]][1] ## Add a users.json file -Add a `users.json` to the root of forever-webui +``` + node add_user +``` +this will create a users.json file if it doesn't exist yet and adds a new user via prompt. +Or add a `users.json` to the root of forever-webui ``` [{ "username" : "here the name of your user", "password" : "here the password for your user" }] ``` -or run this will create a users.json file if it doesn't exist yet and adds a new user via prompt. ```node add_user``` ## Run Tests From 7b1dcca103cd00a2f641415e5f6fd88f8eb1cd6c Mon Sep 17 00:00:00 2001 From: Appsaloon Toon Nelissen Date: Tue, 28 Apr 2015 16:59:41 +0200 Subject: [PATCH 4/8] readme changes --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8beb0bd..bc246be 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ they will be visible to forever, via sudo only. [\[1\]][1] node add_user ``` this will create a users.json file if it doesn't exist yet and adds a new user via prompt. + Or add a `users.json` to the root of forever-webui ``` [{ From 492648df95976622fa439f4fa7630b8dd314fd8f Mon Sep 17 00:00:00 2001 From: Appsaloon Toon Nelissen Date: Wed, 29 Apr 2015 16:19:12 +0200 Subject: [PATCH 5/8] Bugfix find by Id should be by id and not by index otherwise call the function find by index --- app.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app.js b/app.js index 89881fe..ce9d2ec 100644 --- a/app.js +++ b/app.js @@ -34,6 +34,8 @@ logger.error(e); } + console.log(users); + process.on("uncaughtException", function(err) { return console.log("Caught exception: " + err); }); @@ -125,9 +127,9 @@ }; function findById(id, fn) { - var idx = id - 1; - if (users[idx]) { - fn(null, users[idx]); + var user = _.findWhere(users,{id:id}); + if (user) { + fn(null, user); } else { fn(new Error('User ' + id + ' does not exist')); } @@ -184,6 +186,7 @@ passport.use(new LocalStrategy( function(username, password, done) { process.nextTick(function () { + console.log(username); findByUsername(username, function(err, user) { if (err) { return done(err); From dd3f76b45c0592517e0f59795ffeebff2ae10bdd Mon Sep 17 00:00:00 2001 From: Appsaloon Toon Nelissen Date: Mon, 4 May 2015 10:24:05 +0200 Subject: [PATCH 6/8] SHA256 password implementation --- add_user.js | 3 ++- app.js | 4 ++-- package.json | 1 + public/dist/foreverui.min.css | 2 +- public/dist/foreverui.min.js | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/add_user.js b/add_user.js index 6772808..5d2c640 100644 --- a/add_user.js +++ b/add_user.js @@ -1,6 +1,7 @@ var colors = require('colors/safe'); var fs = require('fs'); var readline = require('readline'); +var CryptoJS = require("crypto-js"); var rl = readline.createInterface({ input: process.stdin, @@ -40,7 +41,7 @@ rl.on('line', function(line){ break; case 1: - user.password = line; + user.password = CryptoJS.SHA256(line).toString(CryptoJS.enc.Hex); user.id = users.length; users.push(user); fs.writeFile("users.json", JSON.stringify(users), function(err) { diff --git a/app.js b/app.js index ce9d2ec..24c13fb 100644 --- a/app.js +++ b/app.js @@ -23,6 +23,7 @@ session = require('express-session'); errorhandler = require('errorhandler'); router = express.Router(); + CryptoJS = require("crypto-js"); var users; try { @@ -186,13 +187,12 @@ passport.use(new LocalStrategy( function(username, password, done) { process.nextTick(function () { - console.log(username); findByUsername(username, function(err, user) { if (err) { return done(err); } if (!user) { return done(null, false, { message: 'Unknown user ' + username }); } - if (user.password != password) { return done(null, false, { message: 'Invalid password' }); } + if (user.password != CryptoJS.SHA256(password).toString(CryptoJS.enc.Hex)) { return done(null, false, { message: 'Invalid password' }); } return done(null, user); }); }); diff --git a/package.json b/package.json index 261c4ad..059ff64 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "coffee-script": "1.5.0", "colors": "^1.0.3", "cookie-parser": "^1.3.4", + "crypto-js": "^3.1.4", "ejs": "0.8.3", "errorhandler": "^1.3.5", "express": "4.12.2", diff --git a/public/dist/foreverui.min.css b/public/dist/foreverui.min.css index afd3f4a..4173940 100644 --- a/public/dist/foreverui.min.css +++ b/public/dist/foreverui.min.css @@ -1,4 +1,4 @@ -/*! forever-webui - v0.2.1 - 2015-04-28 +/*! forever-webui - v0.2.1 - 2015-05-04 * Copyright (c) 2015 ; */ html,body{margin:0;padding:0;} h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,cite,code,del,dfn,em,img,q,s,samp,small,strike,strong,sub,sup,tt,var,dd,dl,dt,li,ol,ul,fieldset,form,label,legend,button,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;font-weight:normal;font-style:normal;font-size:100%;line-height:1;font-family:inherit;} diff --git a/public/dist/foreverui.min.js b/public/dist/foreverui.min.js index 5498dd7..7404b7b 100644 --- a/public/dist/foreverui.min.js +++ b/public/dist/foreverui.min.js @@ -1,3 +1,3 @@ -/*! forever-webui - v0.2.1 - 2015-04-28 +/*! forever-webui - v0.2.1 - 2015-05-04 * Copyright (c) 2015 ; */ App.Process=Backbone.Model.extend({defaults:{uid:"",ctime:0,command:"",pid:0,foreverPid:0,logFile:"",options:[],file:"",pidFile:"",outFile:"",errFile:"",sourceDir:""},initialize:function(e){this.attributes.time=prettyDate(e.ctime),_.each(["info","stop","restart"],this._makeMethod,this)},_makeMethod:function(e){this[e]=function(t){$.ajax("/"+e+"/"+this.get("uid")).complete(function(e){t(JSON.parse(e.responseText))})}}}),App.ProcessList=Backbone.Collection.extend({model:App.Process,url:"/processes",comparator:function(e){return e.get("file")},getByPID:function(e){return this.detect(function(t){return t.get("pid")==e})}}),App.ProcessView=Backbone.View.extend({tagName:"div",className:"row",tmpl:$("#process-tmpl").html(),tmplInfo:$("#tplInfo"),events:{"click .info":"info","click .restart":"restart","click .stop":"stop"},initialize:function(){this.model.bind("destroy",this.remove,this)},render:function(){return $(this.el).html(Mustache.to_html(this.tmpl,this.model.toJSON())),this},info:function(e){e&&e.preventDefault();var t=$(this.el);t.addClass("load"),this.model.info(function(e){this._showInfo(t,e),t.removeClass("load")}.bind(this))},restart:function(e){e&&e.preventDefault();var t=$(this.el);t.addClass("load"),this.model.restart(function(){t.removeClass("load"),_.delay(this.model.collection.fetch.bind(this.model.collection),1e3)}.bind(this))},stop:function(e){e&&e.preventDefault();var t=$(this.el);t.addClass("load"),this.model.stop(function(){t.removeClass("load"),_.delay(this.model.collection.fetch.bind(this.model.collection),1e3)}.bind(this))},remove:function(){$(this.el).remove()},_formatInfo:function(e){if("error"==e.status)return $(""+e.details+"");var t=$("
");return e.details.forEach(function(e){var s="";t.append(e[0]);for(var o=0,i=e[1].length;i>o;o++)s+=""+e[1][o].text+"";t.append('
'+s+"
")}),t},_showInfo:function(e,t){var s=e.next();(0==s.length||s.is(".row"))&&(s=this.tmplInfo.clone().removeClass("hidden").insertAfter(e).alert()),"error"==t.status&&s.removeClass("info").addClass("error"),s.find(".alert-message-content").html(this._formatInfo(t)).find("pre").each(function(){this.scrollTop=9e5})}}),App.AppView=Backbone.View.extend({el:$(".container"),events:{"click .refresh":"refresh"},initialize:function(e){this.Processes=new App.ProcessList,this.Processes.bind("all",this.updateAll,this),this.Processes.reset(e),this.$("#app-version").text(App.version),document.title+=App.version},addOne:function(e){var t=new App.ProcessView({model:e});this.$("#process-list").append(t.render().el)},updateAll:function(){this.$("#process-list").empty(),this.Processes.each(this.addOne,this),this.render()},refresh:function(){this.Processes.fetch()},render:function(){this.$("#process-count").text(this.Processes.length)}}),App.ModalView=Backbone.View.extend({tmpl:$("#modal-template").html(),events:{"click .closeProcess":"close","click .addProcess":"addProcess"},initialize:function(){this.model=new Backbone.Model,this.model.bind("destroy",this.remove,this)},render:function(){return $(this.el).html(Mustache.to_html(this.tmpl,this.model.toJSON())),this},show:function(){$(document.body).append(this.render().el),$("#process-args-input").focus()},close:function(){this.remove()},addProcess:function(){if($("#process-args-input").val()){var e=$.ajax({url:"/addProcess",type:"post",data:{args:encodeURIComponent($("#process-args-input").val())}});e.success(function(){var e=setTimeout(function(){$(".refresh").trigger("click"),clearTimeout(e)},3e3)}),e.error(function(e,t,s){console.error("The following error occured: "+t,s)})}this.remove()}}),App.AddProcess=Backbone.View.extend({el:$("body"),events:{"click #addProcess-modal":"showmodal","click .closeProcess":"closemodal","click .addProcess":"addProcess"},initialize:function(){this.addProcessModal=new App.ModalView},showmodal:function(){this.addProcessModal.show()},closemodal:function(){this.addProcessModal.close()},addProcess:function(){this.addProcessModal.addProcess()}}); \ No newline at end of file From f3e71c617e43161d6f9af33cd80edc5ba7f1b795 Mon Sep 17 00:00:00 2001 From: Appsaloon Toon Nelissen Date: Mon, 4 May 2015 10:33:57 +0200 Subject: [PATCH 7/8] Generate UUID for user id instead of users.length --- README.md | 10 +--------- add_user.js | 14 +++++++++++++- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index bc246be..ae01822 100644 --- a/README.md +++ b/README.md @@ -45,15 +45,7 @@ they will be visible to forever, via sudo only. [\[1\]][1] ``` node add_user ``` -this will create a users.json file if it doesn't exist yet and adds a new user via prompt. - -Or add a `users.json` to the root of forever-webui -``` -[{ - "username" : "here the name of your user", - "password" : "here the password for your user" -}] -``` +this will create a users.json file if it doesn't exist yet and adds a new user via prompt. ## Run Tests diff --git a/add_user.js b/add_user.js index 5d2c640..0c5b427 100644 --- a/add_user.js +++ b/add_user.js @@ -33,6 +33,18 @@ if (fs.existsSync('users.json')) { console.log(colors.yellow.underline('Create a user:')); console.log(colors.yellow('Enter the username:')); +// found on http://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript +function generateUUID(){ + var d = new Date().getTime(); + var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = (d + Math.random()*16)%16 | 0; + d = Math.floor(d/16); + return (c=='x' ? r : (r&0x3|0x8)).toString(16); + }); + return uuid; +} + + rl.on('line', function(line){ switch (ticker) { case 0: @@ -42,7 +54,7 @@ rl.on('line', function(line){ break; case 1: user.password = CryptoJS.SHA256(line).toString(CryptoJS.enc.Hex); - user.id = users.length; + user.id = generateUUID(); users.push(user); fs.writeFile("users.json", JSON.stringify(users), function(err) { if(err) { From 7af3b17da09544cb98b1b74c9947589b178e872f Mon Sep 17 00:00:00 2001 From: Appsaloon Toon Nelissen Date: Mon, 4 May 2015 10:51:18 +0200 Subject: [PATCH 8/8] If no users return info to console and exit process --- app.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/app.js b/app.js index 24c13fb..0766b04 100644 --- a/app.js +++ b/app.js @@ -29,14 +29,16 @@ try { var usersFile = fs.readFileSync('users.json', 'utf8'); users = JSON.parse(usersFile); + if (users.length === 0) { + throw new Error('no users in users.json'); + } logger.info('Loaded users'); } catch (e) { - logger.warn('Make a users.json file in the root of the project'); + logger.warn('Run: node add_user.js to add a user.'); logger.error(e); + process.exit(0); } - console.log(users); - process.on("uncaughtException", function(err) { return console.log("Caught exception: " + err); }); @@ -186,6 +188,9 @@ passport.use(new LocalStrategy( function(username, password, done) { + if (!users) { + return done(null, false, { message: 'The system has no users'}); + } process.nextTick(function () { findByUsername(username, function(err, user) { if (err) {