From 00a9ec0f1293a2da05d5bf36ccc88226b7ec05d3 Mon Sep 17 00:00:00 2001 From: Julian Lam <julian@designcreateplay.com> Date: Fri, 24 May 2013 13:14:41 -0400 Subject: [PATCH 1/4] interim commit --- app.js | 2 +- public/templates/config.json | 2 ++ public/templates/install/basic.tpl | 28 ++++++++++++++++++ public/templates/install/footer.tpl | 3 ++ public/templates/install/header.tpl | 45 +++++++++++++++++++++++++++++ src/routes/install.js | 44 ++++++++++++++++++++++++++++ src/webserver.js | 2 ++ 7 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 public/templates/install/basic.tpl create mode 100644 public/templates/install/footer.tpl create mode 100644 public/templates/install/header.tpl create mode 100644 src/routes/install.js diff --git a/app.js b/app.js index 818968e0fb..56b95a1cee 100644 --- a/app.js +++ b/app.js @@ -18,7 +18,7 @@ global.templates = {}; templates.init([ 'header', 'footer', 'logout', 'admin/header', 'admin/footer', 'admin/index', 'emails/reset', 'emails/reset_plaintext', 'emails/email_confirm', 'emails/email_confirm_plaintext', - 'emails/header.tpl', 'emails/footer.tpl' + 'emails/header', 'emails/footer', 'install/header', 'install/footer', 'install/basic' ]); templates.ready(function() { diff --git a/public/templates/config.json b/public/templates/config.json index 8a35b78e0b..04aa514a26 100644 --- a/public/templates/config.json +++ b/public/templates/config.json @@ -10,6 +10,8 @@ "admin/twitter[^]*": "admin/twitter", "admin/facebook[^]*": "admin/facebook", "admin/gplus[^]*": "admin/gplus", + "install/?$": "install/basic", + "install/basic/?$": "install/basic", "users[^]*edit": "accountedit", "users[^]*friends": "friends", "users/[^]*": "account", diff --git a/public/templates/install/basic.tpl b/public/templates/install/basic.tpl new file mode 100644 index 0000000000..9ab273509e --- /dev/null +++ b/public/templates/install/basic.tpl @@ -0,0 +1,28 @@ + +<h1>Step 1 – Basic Information</h1> + +<p class="lead"> + Thanks for choosing to install NodeBB! We'll need some information to set up your installation + configuration... +</p> + +<h3>Path Information</h3> +<p> + Please enter the web-accessible url that will be used to point to the NodeBB installation. If you are using a port number in the address, + <strong>include it in the field below, not here</strong> + <input type="text" class="input-large" data-field="base_url" placeholder="http://www.example.org" /> +</p> + +<p> + <label class="checkbox"><input type="checkbox" data-field="use_port" /> Use port</label> +</p> + +<form class="form-inline"> + <label>Port</label> <input type="text" data-field="port" /> +</form> + +<h3>NodeBB Secret</h3> +<p> + This "secret" is used to encode user sessions, so they are not stored in plaintext. Enter a bunch of random characters below: +</p> +<input type="text" class="input-xxlarge" data-field="secret" placeholder="n239he#dh9j9$jc4h%y4yuhnx9y(&#y9ryn9c3" /> \ No newline at end of file diff --git a/public/templates/install/footer.tpl b/public/templates/install/footer.tpl new file mode 100644 index 0000000000..9c25607790 --- /dev/null +++ b/public/templates/install/footer.tpl @@ -0,0 +1,3 @@ + + </div> +</body> \ No newline at end of file diff --git a/public/templates/install/header.tpl b/public/templates/install/header.tpl new file mode 100644 index 0000000000..535efe3092 --- /dev/null +++ b/public/templates/install/header.tpl @@ -0,0 +1,45 @@ +<!DOCTYPE html> +<html> +<head> + <title>NodeBB</title> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="title" CONTENT="NodeBB"> + <meta name="description" content="Node.js/Redis/Socket.io powered forums for a new generation"> + <link href="/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen"> + <link href="/vendor/bootstrap/css/bootstrap-responsive.min.css" rel="stylesheet" media="screen"> + <link rel="stylesheet" href="/vendor/fontawesome/css/font-awesome.min.css"> + <script type="text/javascript" src="http://code.jquery.com/jquery.js"></script> + <script type="text/javascript" src="/vendor/jquery/js/jquery-ui-1.10.3.custom.min.js"></script> + <script type="text/javascript" src="/vendor/bootstrap/js/bootstrap.min.js"></script> + <script type="text/javascript" src="/socket.io/socket.io.js"></script> + <script type="text/javascript" src="/src/app.js"></script> + <script type="text/javascript" src="/src/templates.js"></script> + <script type="text/javascript" src="/src/ajaxify.js"></script> + <script type="text/javascript" src="/src/jquery.form.js"></script> + <script type="text/javascript" src="/src/utils.js"></script> + + <link rel="stylesheet" type="text/css" href="/css/style.css" /> +</head> + +<body> + <div class="navbar navbar-inverse navbar-fixed-top"> + <div class="navbar-inner"> + <div class="container"> + <a class="brand" href="/">NodeBB Installation</a> + <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <div class="nav-collapse collapse"> + <ul class="nav nodebb-inline-block"> + <li> + <a data-tab="basic" href="#"><i class="icon-cog"></i> Basic</a> + </li> + </ul> + </div> + </div> + </div> + </div> + + <div class="container" id="content"> \ No newline at end of file diff --git a/src/routes/install.js b/src/routes/install.js new file mode 100644 index 0000000000..e882aa954a --- /dev/null +++ b/src/routes/install.js @@ -0,0 +1,44 @@ + +var RDB = require('../redis.js'); + +(function(Install) { + Install.create_routes = function(app) { + + (function() { + var routes = ['basic']; + + for (var i=0, ii=routes.length; i<ii; i++) { + (function(route) { + app.get('/install/' + route, function(req, res) { + res.send(templates['install/header'] + app.create_route('install/' + route) + templates['install/footer']); + }); + }(routes[i])); + } + }()); + + //todo consolidate. + app.get('/install', function(req, res) { + res.send(templates['install/header'] + app.create_route('install/basic') + templates['install/footer']); + }); + app.get('/install/index', function(req, res) { + res.send(templates['install/header'] + app.create_route('install/index') + templates['install/footer']); + }); + + + function api_method(req, res) { + switch(req.params.method) { + case 'basic' : + res.send('{}'); + break; + + default : + res.send('{}'); + } + } + + app.get('/api/install/:method/:tab?*', api_method); + app.get('/api/install/:method*', api_method); + }; + + +}(exports)); \ No newline at end of file diff --git a/src/webserver.js b/src/webserver.js index f7b8028b4b..111b50b40e 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -17,6 +17,7 @@ var express = require('express'), notifications = require('./notifications.js'), admin = require('./routes/admin.js'), userRoute = require('./routes/user.js'), + installRoute = require('./routes/install.js'), auth = require('./routes/authentication.js'); (function(app) { @@ -62,6 +63,7 @@ var express = require('express'), auth.create_routes(app); admin.create_routes(app); userRoute.create_routes(app); + installRoute.create_routes(app); app.create_route = function(url, tpl) { // to remove From 65b6010d74a0a45e6de255984657316d2f7948a5 Mon Sep 17 00:00:00 2001 From: Julian Lam <julian.lam@gmail.com> Date: Sat, 25 May 2013 20:32:22 -0400 Subject: [PATCH 2/4] installation wizard under /install --- app.js | 2 +- public/templates/config.json | 50 +++++----- public/templates/install/basic.tpl | 59 +++++++---- public/templates/install/footer.tpl | 127 ++++++++++++++++++++++++ public/templates/install/header.tpl | 17 +++- public/templates/install/mail.tpl | 36 +++++++ public/templates/install/privileges.tpl | 40 ++++++++ public/templates/install/redis.tpl | 81 +++++++++++++++ public/templates/install/social.tpl | 47 +++++++++ src/meta.js | 59 +++++++++++ src/routes/install.js | 4 +- src/webserver.js | 12 +-- src/websockets.js | 33 +++++- 13 files changed, 512 insertions(+), 55 deletions(-) create mode 100644 public/templates/install/mail.tpl create mode 100644 public/templates/install/privileges.tpl create mode 100644 public/templates/install/redis.tpl create mode 100644 public/templates/install/social.tpl create mode 100644 src/meta.js diff --git a/app.js b/app.js index 56b95a1cee..4005af1aa1 100644 --- a/app.js +++ b/app.js @@ -18,7 +18,7 @@ global.templates = {}; templates.init([ 'header', 'footer', 'logout', 'admin/header', 'admin/footer', 'admin/index', 'emails/reset', 'emails/reset_plaintext', 'emails/email_confirm', 'emails/email_confirm_plaintext', - 'emails/header', 'emails/footer', 'install/header', 'install/footer', 'install/basic' + 'emails/header', 'emails/footer', 'install/header', 'install/footer', 'install/redis' ]); templates.ready(function() { diff --git a/public/templates/config.json b/public/templates/config.json index 04aa514a26..5af89957fb 100644 --- a/public/templates/config.json +++ b/public/templates/config.json @@ -1,25 +1,29 @@ { - "custom_mapping": { - "admin/topics[^]*": "admin/topics", - "admin/categories[^]*": "admin/categories", - "admin/users[^]*": "admin/users", - "admin/redis[^]*": "admin/redis", - "admin/index[^]*": "admin/index", - "admin/themes[^]*": "admin/themes", - "admin/settings[^]*": "admin/settings", - "admin/twitter[^]*": "admin/twitter", - "admin/facebook[^]*": "admin/facebook", - "admin/gplus[^]*": "admin/gplus", - "install/?$": "install/basic", - "install/basic/?$": "install/basic", - "users[^]*edit": "accountedit", - "users[^]*friends": "friends", - "users/[^]*": "account", - "latest": "category", - "popular": "category", - "active": "category" - }, - "force_refresh": { - "logout": true - } + "custom_mapping": { + "admin/topics[^]*": "admin/topics", + "admin/categories[^]*": "admin/categories", + "admin/users[^]*": "admin/users", + "admin/redis[^]*": "admin/redis", + "admin/index[^]*": "admin/index", + "admin/themes[^]*": "admin/themes", + "admin/settings[^]*": "admin/settings", + "admin/twitter[^]*": "admin/twitter", + "admin/facebook[^]*": "admin/facebook", + "admin/gplus[^]*": "admin/gplus", + "install/?$": "install/redis", + "install/basic/?": "install/basic", + "install/redis/?": "install/redis", + "install/mail/?": "install/mail", + "install/social/?": "install/social", + "install/privileges/?": "install/privileges", + "users[^]*edit": "accountedit", + "users[^]*friends": "friends", + "users/[^]*": "account", + "latest": "category", + "popular": "category", + "active": "category" + }, + "force_refresh": { + "logout": true + } } \ No newline at end of file diff --git a/public/templates/install/basic.tpl b/public/templates/install/basic.tpl index 9ab273509e..5a656fc21d 100644 --- a/public/templates/install/basic.tpl +++ b/public/templates/install/basic.tpl @@ -1,28 +1,51 @@ -<h1>Step 1 – Basic Information</h1> +<h1>Step 2 – Basic Information</h1> -<p class="lead"> - Thanks for choosing to install NodeBB! We'll need some information to set up your installation - configuration... -</p> - -<h3>Path Information</h3> -<p> - Please enter the web-accessible url that will be used to point to the NodeBB installation. If you are using a port number in the address, - <strong>include it in the field below, not here</strong> - <input type="text" class="input-large" data-field="base_url" placeholder="http://www.example.org" /> -</p> +<form class="form-inline"> + <h3>Path Information</h3> + <p> + Please enter the web-accessible url that will be used to point to the NodeBB installation. If you are using a port number in the address, + <strong>include it in the field below, not here</strong>. Do not include a trailing slash.<br /> + <input type="text" class="input-large" data-field="base_url" placeholder="http://www.example.org" /> + </p> -<p> - <label class="checkbox"><input type="checkbox" data-field="use_port" /> Use port</label> -</p> + <p> + <label class="checkbox"><input type="checkbox" data-field="use_port" checked /> Use port</label> + </p> + <p> + <label>Port</label> <input type="number" class="input-mini" data-field="port" value="4567" placeholder="4567" /> + </p> -<form class="form-inline"> - <label>Port</label> <input type="text" data-field="port" /> + <p> + Path to uploads folder (relative to the root of the NodeBB install)<br /> + <input type="text" class="input-large" data-field="upload_url" value="/public/uploads" placeholder="/public/uploads" /> + </p> </form> <h3>NodeBB Secret</h3> <p> This "secret" is used to encode user sessions, so they are not stored in plaintext. Enter a bunch of random characters below: </p> -<input type="text" class="input-xxlarge" data-field="secret" placeholder="n239he#dh9j9$jc4h%y4yuhnx9y(&#y9ryn9c3" /> \ No newline at end of file +<input type="text" class="input-xxlarge" data-field="secret" placeholder="n239he#dh9j9$jc4h%y4yuhnx9y(&#y9ryn9c3" /> + +<hr /> +<div class="pull-right"> + <button data-path="mail" class="btn btn-primary btn-large">Next – <i class="icon-envelope"></i> Mail</button> +</div> +<div> + <button data-path="redis" class="btn btn-primary btn-large">Previous – <i class="icon-hdd"></i> Redis</button> +</div> + +<script> + (function() { + nodebb_setup.prepare(); + + var portToggle = document.querySelector('input[data-field="use_port"]'), + portEl = document.querySelector('input[data-field="port"]'); + + portToggle.addEventListener('change', function(e) { + if (e.target.checked) portEl.disabled = false; + else portEl.disabled = true; + }); + })(); +</script> \ No newline at end of file diff --git a/public/templates/install/footer.tpl b/public/templates/install/footer.tpl index 9c25607790..9823d43371 100644 --- a/public/templates/install/footer.tpl +++ b/public/templates/install/footer.tpl @@ -1,3 +1,130 @@ </div> + <script> + var nodebb_setup = { + config: undefined, + prepare: function() { + // Bounce if config is not ready + if (nodebb_setup.config === undefined) { + ajaxify.go('install/redis'); + app.alert({ + alert_id: 'config-ready', + type: 'error', + timeout: 10000, + title: 'NodeBB Configuration Not Ready!', + message: 'NodeBB cannot proceed with setup at this time as Redis database information ' + + 'was not found. Please enter the information below.' + }); + + return; + } + + // Populate the fields on the page from the config + var fields = document.querySelectorAll('#content [data-field]'), + numFields = fields.length, + x, key, inputType; + for(x=0;x<numFields;x++) { + key = fields[x].getAttribute('data-field'); + inputType = fields[x].getAttribute('type'); + if (nodebb_setup.config[key]) { + switch(inputType) { + case 'text': + case 'textarea': + case 'number': + fields[x].value = nodebb_setup.config[key]; + break; + + case 'checkbox': + fields[x].checked = nodebb_setup.config[key] ? true : false; + break; + } + } else { + // Save defaults, if they're not found in the config + var defaultFields = [ + 'use_port', 'port', 'upload_url', 'mailer:host', + 'mailer:port', 'privileges:manage_content', + 'privileges:manage_topic' + ], + defaultVal; + if (defaultFields.indexOf(key) !== -1) { + console.log('saving default value: ', key); + switch(inputType) { + case 'text': + case 'textarea': + case 'number': + defaultVal = fields[x].value; + break; + + case 'checkbox': + defaultVal = fields[x].checked ? '1' : '0'; + break; + } + socket.emit('api:config.set', { + key: key, + value: defaultVal + }); + nodebb_setup.config[key] = defaultVal; + } + } + } + } + }; + + (function() { + // Listen for field changes and auto-save on change + var contentEl = document.getElementById('content'); + + contentEl.addEventListener('change', function(e) { + if (e.target.hasAttribute('data-field')) { + var key = e.target.getAttribute('data-field'), + value; + + switch(e.target.getAttribute('type')) { + case 'text': + case 'textarea': + case 'number': + value = e.target.value; + break; + case 'checkbox': + value = e.target.checked ? 1 : 0; + break; + + default: + return false; + break; + } + + socket.emit('api:config.set', { key: key, value: value }); + nodebb_setup.config[key] = value; + } + }, false); + contentEl.addEventListener('click', function(e) { + if (e.target.hasAttribute('data-path')) { + var href = 'install/' + e.target.getAttribute('data-path'); + console.log(href); + if (!e.target.disabled) ajaxify.go(href); + } + }, false); + + socket.on('api:config.set', function(data) { + if (data.status === 'ok') { + app.alert({ + alert_id: 'config_status', + timeout: 2500, + title: 'Configuration Saved', + message: 'Your changes to the NodeBB configuration have been saved', + type: 'success' + }); + } else { + app.alert({ + alert_id: 'config_status', + timeout: 2500, + title: 'Configuration Not Saved', + message: 'NodeBB encountered a problem saving your changes', + type: 'error' + }); + } + }); + })(); + </script> </body> \ No newline at end of file diff --git a/public/templates/install/header.tpl b/public/templates/install/header.tpl index 535efe3092..d598b0bb06 100644 --- a/public/templates/install/header.tpl +++ b/public/templates/install/header.tpl @@ -25,7 +25,7 @@ <div class="navbar navbar-inverse navbar-fixed-top"> <div class="navbar-inner"> <div class="container"> - <a class="brand" href="/">NodeBB Installation</a> + <a class="brand" href="/install">NodeBB Installation</a> <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> @@ -34,12 +34,25 @@ <div class="nav-collapse collapse"> <ul class="nav nodebb-inline-block"> <li> - <a data-tab="basic" href="#"><i class="icon-cog"></i> Basic</a> + <a data-tab="redis" href="/install/redis"><i class="icon-hdd"></i> Redis</a> + </li> + <li> + <a data-tab="basic" href="/install/basic"><i class="icon-cog"></i> Basic</a> + </li> + <li> + <a data-tab="email" href="/install/email"><i class="icon-envelope"></i> Mail</a> + </li> + <li> + <a data-tab="social" href="/install/social"><i class="icon-facebook"></i> Social</a> + </li> + <li> + <a data-tab="privileges" href="/install/privileges"><i class="icon-legal"></i> Privileges</a> </li> </ul> </div> </div> </div> </div> + <div id="alert_window"></div> <div class="container" id="content"> \ No newline at end of file diff --git a/public/templates/install/mail.tpl b/public/templates/install/mail.tpl new file mode 100644 index 0000000000..42ba612a18 --- /dev/null +++ b/public/templates/install/mail.tpl @@ -0,0 +1,36 @@ + +<h1>Step 3 – Mailer Information</h1> + +<form class="form-inline"> + <p> + The mailer information is used when sending out registration confirmation emails to new users. + It is also used to send password reset emails to users who have forgotten their password. + </p> + <p> + The defaults here correspond to a local <code>sendmail</code> server, although any third-party + mail server can be used. + </p> + <p> + <label>Hostname</label> <input type="text" class="input-medium" data-field="mailer:host" value="127.0.0.1" placeholder="127.0.0.1" /> + </p> + <p> + <label>Port</label> <input type="number" class="input-mini" data-field="mailer:port" value="25" placeholder="25" /> + </p> + <p> + <label>From</label> <input type="text" class="input-large" data-field="mailer:from" placeholder="John Smith <jsmith@example.org>" /> + </p> +</form> + +<hr /> +<div class="pull-right"> + <button data-path="social" class="btn btn-primary btn-large">Next – <i class="icon-facebook"></i> Social</button> +</div> +<div> + <button data-path="basic" class="btn btn-primary btn-large">Previous – <i class="icon-cog"></i> Basic</button> +</div> + +<script> + (function() { + nodebb_setup.prepare(); + })(); +</script> \ No newline at end of file diff --git a/public/templates/install/privileges.tpl b/public/templates/install/privileges.tpl new file mode 100644 index 0000000000..466febc9c5 --- /dev/null +++ b/public/templates/install/privileges.tpl @@ -0,0 +1,40 @@ + +<h1>Step 5 – User Privilege Thresholds</h1> + +<form class="form-inline"> + <p> + Privilege thresholds grants a community membership the ability to moderate itself. + These numbers denote the minimum amount of user reputation required before the + corresponding privilege is unlocked. + </p> + <p> + Reputation is gained when other users favourite posts that you have made. + </p> + + <p> + <label>Manage Content</label> <input type="number" class="input-mini" value="1000" placeholder="1000" data-field="privileges:manage_content" /> + </p> + <p> + Users with reach the "Manage Content" threshold are able to edit/delete other users' posts. + </p> + <p> + <label>Manage Topics</label> <input type="number" class="input-mini" value="2000" placeholder="2000" data-field="privileges:manage_topic" /> + </p> + <p> + Users with reach the "Manage Topics" threshold are able to edit, lock, pin, close, and delete topics. + </p> +</form> + +<hr /> +<div class="pull-right"> + <a href="/" class="btn btn-success btn-large"><i class="icon-thumbs-up"></i> Start using NodeBB!</a> +</div> +<div> + <button data-path="social" class="btn btn-primary btn-large">Previous – <i class="icon-facebook"></i> Social</button> +</div> + +<script> + (function() { + nodebb_setup.prepare(); + })(); +</script> \ No newline at end of file diff --git a/public/templates/install/redis.tpl b/public/templates/install/redis.tpl new file mode 100644 index 0000000000..e60954ee89 --- /dev/null +++ b/public/templates/install/redis.tpl @@ -0,0 +1,81 @@ + +<h1>Step 1 – Establish Redis Connection</h1> + +<p class="lead"> + Thanks for choosing to install NodeBB! We'll need some information to set up your installation + configuration... +</p> +<p> + Please enter the details of your Redis server here. If redis is hosted on the same + server as NodeBB, you can leave the default values as-is. +</p> + +<form class="form-horizontal"> + <div class="control-group"> + <label class="control-label" for="redis-hostname">Hostname</label> + <div class="controls"> + <input type="text" id="redis-hostname" class="input-medium" placeholder="127.0.0.1" value="127.0.0.1" /> + </div> + </div> + <div class="control-group"> + <label class="control-label" for="redis-port">Port</label> + <div class="controls"> + <input type="number" id="redis-port" class="input-mini" placeholder="6379" value="6379" /> + </div> + </div> + <div class="control-group"> + <div class="controls"> + <button class="btn" id="test-redis">Test</button> + </div> + </div> +</form> + +<hr /> +<div class="pull-right"> + <button data-path="basic" class="btn btn-primary btn-large" disabled>Next – <i class="icon-cog"></i> Basic</button> +</div> + +<script> + (function() { + var testRedisEl = document.getElementById('test-redis'); + testRedisEl.addEventListener('click', function(e) { + e.preventDefault(); + + if (e.target.className.indexOf('testing') === -1) { + e.target.className += ' testing'; + e.target.innerHTML = '<i class="icon-spinner icon-spin"></i> Testing'; + socket.once('api:config.redisTest', function(data) { + if (data && data.status === 'ok') { + e.target.className = 'btn btn-success testing'; + e.target.innerHTML = 'Redis Connection Successful!'; + + app.alert({ + type: 'success', + timeout: 10000, + alert_id: 'config-ready', + title: 'Setup Ready!', + message: 'NodeBB is ready to continue with the setup process. ' + + 'Any changes you make now will be saved automatically' + }); + + // Grab configs from the db and enable the 'next' button + socket.emit('api:config.setup', { + 'redis/host': document.getElementById('redis-hostname').value, + 'redis/port': document.getElementById('redis-port').value + }); + } else { + e.target.className = 'btn btn-danger'; + e.target.innerHTML = 'Could not connect to Redis, click here to test again'; + } + }); + socket.emit('api:config.redisTest'); + } + }); + + var nextBtn = document.querySelector('button[data-path="basic"]'); + socket.once('api:config.setup', function(data) { + nodebb_setup.config = data; + nextBtn.disabled = false; + }); + })(); +</script> diff --git a/public/templates/install/social.tpl b/public/templates/install/social.tpl new file mode 100644 index 0000000000..046021dbf5 --- /dev/null +++ b/public/templates/install/social.tpl @@ -0,0 +1,47 @@ + +<h1>Step 4 – Social Media Logins (Optional)</h1> + +<form class="form-inline"> + <p> + You may opt to allow users to register and login in via a social media account, if that + social network supports doing so. + </p> + + <h3>Facebook</h3> + <p> + <label>Application ID</label> <input type="text" class="input-medium" data-field="social/facebook/app_id" /> + </p> + <p> + <label>Application Secret</label> <input type="text" class="input-large" data-field="social/facebook/secret" /> + </p> + + <h3>Twitter</h3> + <p> + <label>Application Key</label> <input type="text" class="input-medium" data-field="social/twitter/key" /> + </p> + <p> + <label>Application Secret</label> <input type="text" class="input-large" data-field="social/twitter/secret" /> + </p> + + <h3>Google</h3> + <p> + <label>Application Key</label> <input type="text" class="input-xxlarge" data-field="social/google/key" /> + </p> + <p> + <label>Application Secret</label> <input type="text" class="input-large" data-field="social/google/secret" /> + </p> +</form> + +<hr /> +<div class="pull-right"> + <button data-path="privileges" class="btn btn-primary btn-large">Next – <i class="icon-legal"></i> Privileges</button> +</div> +<div> + <button data-path="mail" class="btn btn-primary btn-large">Previous – <i class="icon-envelope"></i> Mail</button> +</div> + +<script> + (function() { + nodebb_setup.prepare(); + })(); +</script> \ No newline at end of file diff --git a/src/meta.js b/src/meta.js new file mode 100644 index 0000000000..f4fd57edc2 --- /dev/null +++ b/src/meta.js @@ -0,0 +1,59 @@ +var config = require('../config.js'), + utils = require('./../public/src/utils.js'), + RDB = require('./redis.js'), + async = require('async'); + +(function(Meta) { + Meta.testRedis = function(callback) { + RDB.set('nodebb-redis-test', 'foobar', function(err, res) { + if (!err) { + RDB.get('nodebb-redis-test', function(err, res) { + if (!err && res === 'foobar') { + callback(true); + } else { + callback(false); + } + }); + } else { + callback(false); + } + }); + } + + Meta.config = { + get: function(callback) { + var config = {}; + + async.waterfall([ + function(next) { + RDB.hkeys('config', function(err, keys) { + next(err, keys); + }); + }, + function(keys, next) { + async.each(keys, function(key, next) { + RDB.hget('config', key, function(err, value) { + if (!err) { + config[key] = value; + } + + next(err); + }); + }, next); + } + ], function(err) { + if (!err) { + config.status = 'ok'; + callback(config); + } else callback({ + status: 'error' + }); + }); + }, + set: function(field, value, callback) { + RDB.hset('config', field, value, function(err, res) { + callback(err); + }); + } + } +}(exports)); \ No newline at end of file diff --git a/src/routes/install.js b/src/routes/install.js index e882aa954a..5b352fcd71 100644 --- a/src/routes/install.js +++ b/src/routes/install.js @@ -5,7 +5,7 @@ var RDB = require('../redis.js'); Install.create_routes = function(app) { (function() { - var routes = ['basic']; + var routes = ['basic', 'redis', 'mail', 'social', 'privileges']; for (var i=0, ii=routes.length; i<ii; i++) { (function(route) { @@ -21,7 +21,7 @@ var RDB = require('../redis.js'); res.send(templates['install/header'] + app.create_route('install/basic') + templates['install/footer']); }); app.get('/install/index', function(req, res) { - res.send(templates['install/header'] + app.create_route('install/index') + templates['install/footer']); + res.send(templates['install/header'] + app.create_route('install/basic') + templates['install/footer']); }); diff --git a/src/webserver.js b/src/webserver.js index 111b50b40e..48c3b9fca2 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -18,7 +18,8 @@ var express = require('express'), admin = require('./routes/admin.js'), userRoute = require('./routes/user.js'), installRoute = require('./routes/install.js'), - auth = require('./routes/authentication.js'); + auth = require('./routes/authentication.js'), + meta = require('./meta.js'); (function(app) { var templates = null; @@ -222,13 +223,8 @@ var express = require('express'), app.get('/api/:method/:id*', api_method); app.get('/test', function(req, res) { - // notifications.remove_by_uniqueId('foobar', 1, function(success) { - // res.send('remove: ' + success); - // }); - notifications.create('a bunch more text', 5, '/category/2/general-discussion', 'foobar', function(nid) { - notifications.push(nid, 1, function() { - res.send('nid: ' + nid) - }); + meta.config.get(function(config) { + res.send(JSON.stringify(config, null, 4)); }); }); diff --git a/src/websockets.js b/src/websockets.js index 0a3c15d826..a40f5216b6 100644 --- a/src/websockets.js +++ b/src/websockets.js @@ -11,7 +11,9 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }), categories = require('./categories.js'), notifications = require('./notifications.js'), threadTools = require('./threadTools.js'), - postTools = require('./postTools.js'); + postTools = require('./postTools.js'), + meta = require('./meta.js'), + async = require('async'); (function(io) { var users = {}, @@ -292,6 +294,35 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }), }); } }); + + socket.on('api:config.redisTest', function() { + meta.testRedis(function(success) { + socket.emit('api:config.redisTest', { + status: success ? 'ok' : 'error' + }); + }); + }); + + socket.on('api:config.setup', function(data) { + async.parallel([ + function(next) { + meta.config.set('redis/host', data['redis/host'], next); + }, + function(next) { + meta.config.set('redis/port', data['redis/port'], next); + } + ], function(err) { + meta.config.get(function(config) { + socket.emit('api:config.setup', config); + }); + }); + }); + + socket.on('api:config.set', function(data) { + meta.config.set(data.key, data.value, function(err) { + if (!err) socket.emit('api:config.set', { status: 'ok' }); + }); + }); }); }(SocketIO)); From 069cf5c6cbfd5ba135cdf5ab6f1a54628a65957f Mon Sep 17 00:00:00 2001 From: Julian Lam <julian.lam@gmail.com> Date: Sat, 25 May 2013 20:42:27 -0400 Subject: [PATCH 3/4] minor tweak to 'start' button at end of install wizard --- public/templates/install/privileges.tpl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/public/templates/install/privileges.tpl b/public/templates/install/privileges.tpl index 466febc9c5..a35a1cfe7a 100644 --- a/public/templates/install/privileges.tpl +++ b/public/templates/install/privileges.tpl @@ -27,7 +27,7 @@ <hr /> <div class="pull-right"> - <a href="/" class="btn btn-success btn-large"><i class="icon-thumbs-up"></i> Start using NodeBB!</a> + <button id="start-nodebb" class="btn btn-success btn-large"><i class="icon-thumbs-up"></i> Start using NodeBB!</button> </div> <div> <button data-path="social" class="btn btn-primary btn-large">Previous – <i class="icon-facebook"></i> Social</button> @@ -36,5 +36,11 @@ <script> (function() { nodebb_setup.prepare(); + + var startEl = document.getElementById('start-nodebb'); + startEl.addEventListener('click', function(e) { + e.preventDefault(); + document.location.href = '/'; + }); })(); </script> \ No newline at end of file From 88bf9425db8d63b6b04e49390e9853e35fc8433e Mon Sep 17 00:00:00 2001 From: Julian Lam <julian.lam@gmail.com> Date: Mon, 27 May 2013 14:02:57 -0400 Subject: [PATCH 4/4] install script + patching up integration with install wizard --- app.js | 185 +++++++++++++++++------- public/templates/config.json | 4 +- public/templates/install/footer.tpl | 34 +++-- public/templates/install/header.tpl | 6 - public/templates/install/mail.tpl | 5 +- public/templates/install/privileges.tpl | 2 +- public/templates/install/social.tpl | 14 +- src/meta.js | 3 +- src/notifications.js | 3 +- src/postTools.js | 5 +- src/posts.js | 1 - src/redis.js | 4 +- src/routes/authentication.js | 25 ++-- src/routes/user.js | 3 - src/threadTools.js | 3 +- src/topics.js | 1 - src/user.js | 3 +- src/webserver.js | 5 +- src/websockets.js | 18 +-- 19 files changed, 188 insertions(+), 136 deletions(-) diff --git a/app.js b/app.js index 4005af1aa1..38bcdfd222 100644 --- a/app.js +++ b/app.js @@ -1,54 +1,131 @@ -var categories = require('./src/categories.js'), - templates = require('./public/src/templates.js'), - webserver = require('./src/webserver.js'), - websockets = require('./src/websockets.js'), - admin = { - 'categories': require('./src/admin/categories.js') - }, - fs = require('fs'); - -DEVELOPMENT = true; - -global.configuration = {}; -global.templates = {}; - -(function(config) { - config['ROOT_DIRECTORY'] = __dirname; - - templates.init([ - 'header', 'footer', 'logout', 'admin/header', 'admin/footer', 'admin/index', - 'emails/reset', 'emails/reset_plaintext', 'emails/email_confirm', 'emails/email_confirm_plaintext', - 'emails/header', 'emails/footer', 'install/header', 'install/footer', 'install/redis' - ]); - - templates.ready(function() { - webserver.init(); - }); - - //setup scripts to be moved outside of the app in future. - function setup_categories() { - console.log('Checking categories...'); - categories.getAllCategories(function(data) { - if (data.categories.length === 0) { - console.log('Setting up default categories...'); - - fs.readFile(config.ROOT_DIRECTORY + '/install/data/categories.json', function(err, default_categories) { - default_categories = JSON.parse(default_categories); - - for (var category in default_categories) { - admin.categories.create(default_categories[category]); - } - }); - - } else { - console.log('Good.'); - } - }); - } - - - setup_categories(); - - - -}(global.configuration)); \ No newline at end of file +// Read config.js to grab redis info +var fs = require('fs'), + path = require('path'), + utils = require('./public/src/utils.js'); + +console.log('Info: Checking for valid base configuration file'); +fs.readFile(path.join(__dirname, 'config.json'), function(err, data) { + if (!err) { + global.config = JSON.parse(data); + global.config.url = global.config.base_url + (global.config.use_port ? ':' + global.config.port : '') + '/'; + global.config.upload_url = global.config.url + 'uploads/'; + console.log('Info: Base Configuration OK.'); + + var meta = require('./src/meta.js'); + meta.config.get(function(config) { + for(c in config) { + if (config.hasOwnProperty(c)) { + global.config[c] = config[c]; + } + } + + var categories = require('./src/categories.js'), + templates = require('./public/src/templates.js'), + webserver = require('./src/webserver.js'), + websockets = require('./src/websockets.js'), + admin = { + 'categories': require('./src/admin/categories.js') + }; + + DEVELOPMENT = true; + + global.configuration = {}; + global.templates = {}; + + (function(config) { + config['ROOT_DIRECTORY'] = __dirname; + + templates.init([ + 'header', 'footer', 'logout', 'admin/header', 'admin/footer', 'admin/index', + 'emails/reset', 'emails/reset_plaintext', 'emails/email_confirm', 'emails/email_confirm_plaintext', + 'emails/header', 'emails/footer', 'install/header', 'install/footer', 'install/redis' + ]); + + templates.ready(function() { + webserver.init(); + }); + + //setup scripts to be moved outside of the app in future. + function setup_categories() { + console.log('Info: Checking categories...'); + categories.getAllCategories(function(data) { + if (data.categories.length === 0) { + console.log('Info: Setting up default categories...'); + + fs.readFile(config.ROOT_DIRECTORY + '/install/data/categories.json', function(err, default_categories) { + default_categories = JSON.parse(default_categories); + + for (var category in default_categories) { + admin.categories.create(default_categories[category]); + } + }); + + } else { + console.log('Info: Good.'); + } + }); + } + setup_categories(); + }(global.configuration)); + }); + } else { + // New install, ask setup questions + console.log('Info: Configuration not found, starting NodeBB setup'); + var ask = function(question, callback) { + process.stdin.resume(); + process.stdout.write(question + ': '); + + process.stdin.once('data', function(data) { + callback(data.toString().trim()); + }); + } + + process.stdout.write( + "\nWelcome to NodeBB!\nThis looks like a new installation, so you'll have to answer a " + + "few questions about your environment before we can proceed with the setup.\n\n\nWhat is...\n\n" + ); + + ask('... the publically accessible URL of this installation? (http://localhost)', function(base_url) { + ask('... the port number of your install? (4567)', function(port) { + ask('Will you be using a port number to access NodeBB? (y)', function(use_port) { + ask('... the host IP or address of your Redis instance? (127.0.0.1)', function(redis_host) { + ask('... the host port of your Redis instance? (6379)', function(redis_port) { + ask('... your NodeBB secret? (keyboard mash for a bit here)', function(secret) { + if (!base_url) base_url = 'http://localhost'; + if (!port) port = 4567; + if (!use_port) use_port = true; else use_port = (use_port === 'y' ? true : false); + if (!redis_host) redis_host = '127.0.0.1'; + if (!redis_port) redis_port = 6379; + if (!secret) secret = utils.generateUUID(); + + var fs = require('fs'), + path = require('path'), + config = { + secret: secret, + base_url: base_url, + port: port, + use_port: use_port, + redis: { + host: redis_host, + port: redis_port + } + } + + fs.writeFile(path.join(__dirname, 'config.json'), JSON.stringify(config, null, 4), function(err) { + if (err) throw err; + else { + process.stdout.write( + "\n\nConfiguration Saved OK\n\nPlease start NodeBB again and navigate to " + + base_url + (use_port ? ':' + port : '') + "/install to continue setup.\n\n" + ); + process.exit(); + } + }); + }); + }); + }); + }); + }); + }); + } +}); \ No newline at end of file diff --git a/public/templates/config.json b/public/templates/config.json index 5af89957fb..551606ba59 100644 --- a/public/templates/config.json +++ b/public/templates/config.json @@ -10,9 +10,7 @@ "admin/twitter[^]*": "admin/twitter", "admin/facebook[^]*": "admin/facebook", "admin/gplus[^]*": "admin/gplus", - "install/?$": "install/redis", - "install/basic/?": "install/basic", - "install/redis/?": "install/redis", + "install/?$": "install/mail", "install/mail/?": "install/mail", "install/social/?": "install/social", "install/privileges/?": "install/privileges", diff --git a/public/templates/install/footer.tpl b/public/templates/install/footer.tpl index 9823d43371..e76153ecb1 100644 --- a/public/templates/install/footer.tpl +++ b/public/templates/install/footer.tpl @@ -5,17 +5,26 @@ config: undefined, prepare: function() { // Bounce if config is not ready - if (nodebb_setup.config === undefined) { - ajaxify.go('install/redis'); - app.alert({ - alert_id: 'config-ready', - type: 'error', - timeout: 10000, - title: 'NodeBB Configuration Not Ready!', - message: 'NodeBB cannot proceed with setup at this time as Redis database information ' + - 'was not found. Please enter the information below.' - }); + // if (nodebb_setup.config === undefined) { + // ajaxify.go('install/redis'); + // app.alert({ + // alert_id: 'config-ready', + // type: 'error', + // timeout: 10000, + // title: 'NodeBB Configuration Not Ready!', + // message: 'NodeBB cannot proceed with setup at this time as Redis database information ' + + // 'was not found. Please enter the information below.' + // }); + + // return; + // } + // Come back in 500ms if the config isn't ready yet + if (nodebb_setup.config === undefined) { + console.log('Config not ready...'); + setTimeout(function() { + nodebb_setup.prepare(); + }, 500); return; } @@ -106,6 +115,11 @@ } }, false); + socket.emit('api:config.get'); + socket.on('api:config.get', function(data) { + nodebb_setup.config = data; + }); + socket.on('api:config.set', function(data) { if (data.status === 'ok') { app.alert({ diff --git a/public/templates/install/header.tpl b/public/templates/install/header.tpl index d598b0bb06..d9f66909cb 100644 --- a/public/templates/install/header.tpl +++ b/public/templates/install/header.tpl @@ -33,12 +33,6 @@ </button> <div class="nav-collapse collapse"> <ul class="nav nodebb-inline-block"> - <li> - <a data-tab="redis" href="/install/redis"><i class="icon-hdd"></i> Redis</a> - </li> - <li> - <a data-tab="basic" href="/install/basic"><i class="icon-cog"></i> Basic</a> - </li> <li> <a data-tab="email" href="/install/email"><i class="icon-envelope"></i> Mail</a> </li> diff --git a/public/templates/install/mail.tpl b/public/templates/install/mail.tpl index 42ba612a18..f8dcb261f2 100644 --- a/public/templates/install/mail.tpl +++ b/public/templates/install/mail.tpl @@ -1,5 +1,5 @@ -<h1>Step 3 – Mailer Information</h1> +<h1>Mailer Information</h1> <form class="form-inline"> <p> @@ -25,9 +25,6 @@ <div class="pull-right"> <button data-path="social" class="btn btn-primary btn-large">Next – <i class="icon-facebook"></i> Social</button> </div> -<div> - <button data-path="basic" class="btn btn-primary btn-large">Previous – <i class="icon-cog"></i> Basic</button> -</div> <script> (function() { diff --git a/public/templates/install/privileges.tpl b/public/templates/install/privileges.tpl index a35a1cfe7a..5a3659e5e1 100644 --- a/public/templates/install/privileges.tpl +++ b/public/templates/install/privileges.tpl @@ -1,5 +1,5 @@ -<h1>Step 5 – User Privilege Thresholds</h1> +<h1>User Privilege Thresholds</h1> <form class="form-inline"> <p> diff --git a/public/templates/install/social.tpl b/public/templates/install/social.tpl index 046021dbf5..16654f8f93 100644 --- a/public/templates/install/social.tpl +++ b/public/templates/install/social.tpl @@ -1,5 +1,5 @@ -<h1>Step 4 – Social Media Logins (Optional)</h1> +<h1>Social Media Logins</h1> <form class="form-inline"> <p> @@ -9,26 +9,26 @@ <h3>Facebook</h3> <p> - <label>Application ID</label> <input type="text" class="input-medium" data-field="social/facebook/app_id" /> + <label>Application ID</label> <input type="text" class="input-medium" data-field="social:facebook:app_id" /> </p> <p> - <label>Application Secret</label> <input type="text" class="input-large" data-field="social/facebook/secret" /> + <label>Application Secret</label> <input type="text" class="input-large" data-field="social:facebook:secret" /> </p> <h3>Twitter</h3> <p> - <label>Application Key</label> <input type="text" class="input-medium" data-field="social/twitter/key" /> + <label>Application Key</label> <input type="text" class="input-medium" data-field="social:twitter:key" /> </p> <p> - <label>Application Secret</label> <input type="text" class="input-large" data-field="social/twitter/secret" /> + <label>Application Secret</label> <input type="text" class="input-large" data-field="social:twitter:secret" /> </p> <h3>Google</h3> <p> - <label>Application Key</label> <input type="text" class="input-xxlarge" data-field="social/google/key" /> + <label>Application ID</label> <input type="text" class="input-xxlarge" data-field="social:google:id" /> </p> <p> - <label>Application Secret</label> <input type="text" class="input-large" data-field="social/google/secret" /> + <label>Application Secret</label> <input type="text" class="input-large" data-field="social:google:secret" /> </p> </form> diff --git a/src/meta.js b/src/meta.js index f4fd57edc2..44d31f2abc 100644 --- a/src/meta.js +++ b/src/meta.js @@ -1,5 +1,4 @@ -var config = require('../config.js'), - utils = require('./../public/src/utils.js'), +var utils = require('./../public/src/utils.js'), RDB = require('./redis.js'), async = require('async'); diff --git a/src/notifications.js b/src/notifications.js index 8ea7dc9f24..3e63628068 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -1,5 +1,4 @@ -var config = require('../config.js'), - RDB = require('./redis.js'), +var RDB = require('./redis.js'), async = require('async'), utils = require('../public/src/utils.js'); diff --git a/src/postTools.js b/src/postTools.js index 682ae1d51d..74cce37873 100644 --- a/src/postTools.js +++ b/src/postTools.js @@ -2,7 +2,6 @@ var RDB = require('./redis.js'), posts = require('./posts.js'), threadTools = require('./threadTools.js'), user = require('./user.js'), - config = require('../config.js'), async = require('async'), marked = require('marked'); @@ -35,8 +34,8 @@ marked.setOptions({ // DRY fail in threadTools. user.getUserField(uid, 'reputation', function(reputation) { - next(null, reputation >= config.privilege_thresholds.manage_content); - }); + next(null, reputation >= global.config['privileges:manage_content']); + }); } async.parallel([getThreadPrivileges, isOwnPost, hasEnoughRep], function(err, results) { diff --git a/src/posts.js b/src/posts.js index 58bdce5d36..3d737c70d2 100644 --- a/src/posts.js +++ b/src/posts.js @@ -4,7 +4,6 @@ var RDB = require('./redis.js'), user = require('./user.js'), topics = require('./topics.js'), favourites = require('./favourites.js'), - config = require('../config.js'), threadTools = require('./threadTools.js'), async = require('async'); diff --git a/src/redis.js b/src/redis.js index 935e8afe06..5ac950f057 100644 --- a/src/redis.js +++ b/src/redis.js @@ -3,11 +3,9 @@ ERROR_LOGS = true, redis = require('redis'), - config = require('../config.js'), utils = require('./../public/src/utils.js'); - - RedisDB.exports = redis.createClient(config.redis.port, config.redis.host, config.redis.options); + RedisDB.exports = redis.createClient(global.config.redis.port, global.config.redis.host); RedisDB.exports.handle = function(error) { if (error !== null) { diff --git a/src/routes/authentication.js b/src/routes/authentication.js index e9c17d29ea..3777e2f478 100644 --- a/src/routes/authentication.js +++ b/src/routes/authentication.js @@ -1,5 +1,4 @@ (function(Auth) { - var passport = require('passport'), passportLocal = require('passport-local').Strategy, passportTwitter = require('passport-twitter').Strategy, @@ -7,11 +6,7 @@ passportFacebook = require('passport-facebook').Strategy, login_strategies = [], - user_module = require('./../user.js'), - config = require('./../../config.js'); - - - + user_module = require('./../user.js'); passport.use(new passportLocal(function(user, password, next) { user_module.loginViaLocal(user, password, function(login) { @@ -20,10 +15,10 @@ }); })); - if (config.twitter && config.twitter.key && config.twitter.key.length > 0 && config.twitter.secret.length > 0) { + if (global.config['social:twitter:key'] && global.config['social:twitter:secret']) { passport.use(new passportTwitter({ - consumerKey: config.twitter.key, - consumerSecret: config.twitter.secret, + consumerKey: global.config['social:twitter:key'], + consumerSecret: global.config['social:twitter:secret'], callbackURL: config.url + 'auth/twitter/callback' }, function(token, tokenSecret, profile, done) { user_module.loginViaTwitter(profile.id, profile.username, function(err, user) { @@ -35,10 +30,10 @@ login_strategies.push('twitter'); } - if (config.google && config.google.id.length > 0 && config.google.secret.length > 0) { + if (global.config['social:google:id'] && global.config['social:google:secret']) { passport.use(new passportGoogle({ - clientID: config.google.id, - clientSecret: config.google.secret, + clientID: global.config['social:google:id'], + clientSecret: global.config['social:google:secret'], callbackURL: config.url + 'auth/google/callback' }, function(accessToken, refreshToken, profile, done) { user_module.loginViaGoogle(profile.id, profile.displayName, profile.emails[0].value, function(err, user) { @@ -50,10 +45,10 @@ login_strategies.push('google'); } - if (config.facebook && config.facebook.app_id.length > 0 && config.facebook.secret.length > 0) { + if (global.config['social:facebook:app_id'] && global.config['social:facebook:secret']) { passport.use(new passportFacebook({ - clientID: config.facebook.app_id, - clientSecret: config.facebook.secret, + clientID: global.config['social:facebook:app_id'], + clientSecret: global.config['social:facebook:secret'], callbackURL: config.url + 'auth/facebook/callback' }, function(accessToken, refreshToken, profile, done) { user_module.loginViaFacebook(profile.id, profile.displayName, profile.emails[0].value, function(err, user) { diff --git a/src/routes/user.js b/src/routes/user.js index 213f44275b..6ec3a91103 100644 --- a/src/routes/user.js +++ b/src/routes/user.js @@ -1,12 +1,9 @@ - var user = require('./../user.js'), fs = require('fs'), utils = require('./../../public/src/utils.js'), - config = require('../../config.js'), marked = require('marked'); - (function(User) { User.create_routes = function(app) { diff --git a/src/threadTools.js b/src/threadTools.js index 82acdca15c..391aba631b 100644 --- a/src/threadTools.js +++ b/src/threadTools.js @@ -2,7 +2,6 @@ var RDB = require('./redis.js'), topics = require('./topics.js'), categories = require('./categories.js'), user = require('./user.js'), - config = require('../config.js'), async = require('async'); @@ -23,7 +22,7 @@ var RDB = require('./redis.js'), // DRY fail in postTools user.getUserField(uid, 'reputation', function(reputation) { - next(null, reputation >= config.privilege_thresholds.manage_thread); + next(null, reputation >= global.config['privileges:manage_topic']); }); } diff --git a/src/topics.js b/src/topics.js index 82f353cc3e..82e14d0bf8 100644 --- a/src/topics.js +++ b/src/topics.js @@ -3,7 +3,6 @@ var RDB = require('./redis.js') posts = require('./posts.js'), utils = require('./../public/src/utils.js'), user = require('./user.js'), - config = require('../config.js'), categories = require('./categories.js'), posts = require('./posts.js'), marked = require('marked'), diff --git a/src/user.js b/src/user.js index aa59326810..008e93838c 100644 --- a/src/user.js +++ b/src/user.js @@ -1,5 +1,4 @@ -var config = require('../config.js'), - utils = require('./../public/src/utils.js'), +var utils = require('./../public/src/utils.js'), RDB = require('./redis.js'), crypto = require('crypto'), emailjs = require('emailjs'), diff --git a/src/webserver.js b/src/webserver.js index 831da86b20..4f3a25f606 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -3,9 +3,8 @@ var express = require('express'), server = require('http').createServer(WebServer), RedisStore = require('connect-redis')(express), path = require('path'), - config = require('../config.js'), redis = require('redis'), - redisServer = redis.createClient(config.redis.port, config.redis.host, config.redis.options), + redisServer = redis.createClient(global.config.redis.port, global.config.redis.host), marked = require('marked'), utils = require('../public/src/utils.js'), fs = require('fs'), @@ -36,7 +35,7 @@ var express = require('express'), client: redisServer, ttl: 60*60*24*14 }), - secret: config.secret, + secret: global.config.secret, key: 'express.sid' })); diff --git a/src/websockets.js b/src/websockets.js index a94566e10d..05bdfb0a2d 100644 --- a/src/websockets.js +++ b/src/websockets.js @@ -2,7 +2,6 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }), cookie = require('cookie'), connect = require('connect'), - config = require('../config.js'), user = require('./user.js'), posts = require('./posts.js'), favourites = require('./favourites.js'), @@ -26,7 +25,7 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }), io.set('authorization', function(handshakeData, accept) { if (handshakeData.headers.cookie) { handshakeData.cookie = cookie.parse(handshakeData.headers.cookie); - handshakeData.sessionID = connect.utils.parseSignedCookie(handshakeData.cookie['express.sid'], config.secret); + handshakeData.sessionID = connect.utils.parseSignedCookie(handshakeData.cookie['express.sid'], global.config.secret); if (handshakeData.cookie['express.sid'] == handshakeData.sessionID) { return accept('Cookie is invalid.', false); @@ -302,18 +301,9 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }), }); }); - socket.on('api:config.setup', function(data) { - async.parallel([ - function(next) { - meta.config.set('redis/host', data['redis/host'], next); - }, - function(next) { - meta.config.set('redis/port', data['redis/port'], next); - } - ], function(err) { - meta.config.get(function(config) { - socket.emit('api:config.setup', config); - }); + socket.on('api:config.get', function(data) { + meta.config.get(function(config) { + socket.emit('api:config.get', config); }); });