mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 11:05:54 +01:00 
			
		
		
		
	fixed conflicts
This commit is contained in:
		| @@ -1,8 +1,4 @@ | |||||||
| root = true | root = true | ||||||
|  |  | ||||||
| [*] |  | ||||||
| end_of_line = lf |  | ||||||
| insert_final_newline = true |  | ||||||
|  |  | ||||||
| [*.js, *.css, *.tpl] | [*.js, *.css, *.tpl] | ||||||
| indent_style = tab | indent_style = tab | ||||||
							
								
								
									
										17
									
								
								.jsbeautifyrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								.jsbeautifyrc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | { | ||||||
|  |     "indent_size": 4, | ||||||
|  |     "indent_char": " ", | ||||||
|  |     "indent_level": 0, | ||||||
|  |     "indent_with_tabs": false, | ||||||
|  |     "preserve_newlines": true, | ||||||
|  |     "max_preserve_newlines": 10, | ||||||
|  |     "jslint_happy": false, | ||||||
|  |     "brace_style": "collapse", | ||||||
|  |     "keep_array_indentation": false, | ||||||
|  |     "keep_function_indentation": false, | ||||||
|  |     "space_before_conditional": true, | ||||||
|  |     "break_chained_methods": false, | ||||||
|  |     "eval_code": false, | ||||||
|  |     "unescape_strings": false, | ||||||
|  |     "wrap_line_length": 0 | ||||||
|  | } | ||||||
							
								
								
									
										86
									
								
								.jshintrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								.jshintrc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | |||||||
|  | { | ||||||
|  |     // JSHint Default Configuration File (as on JSHint website) | ||||||
|  |     // See http://jshint.com/docs/ for more details | ||||||
|  |  | ||||||
|  |     "maxerr" : 50, // {int} Maximum error before stopping | ||||||
|  |  | ||||||
|  |     // Enforcing | ||||||
|  |     "bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.) | ||||||
|  |     "camelcase" : false, // true: Identifiers must be in camelCase | ||||||
|  |     "curly" : true, // true: Require {} for every new block or scope | ||||||
|  |     "eqeqeq" : true, // true: Require triple equals (===) for comparison | ||||||
|  |     "forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty() | ||||||
|  |     "immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());` | ||||||
|  |     "indent" : 4, // {int} Number of spaces to use for indentation | ||||||
|  |     "latedef" : false, // true: Require variables/functions to be defined before being used | ||||||
|  |     "newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()` | ||||||
|  |     "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee` | ||||||
|  |     "noempty" : true, // true: Prohibit use of empty blocks | ||||||
|  |     "nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment) | ||||||
|  |     "plusplus" : false, // true: Prohibit use of `++` & `--` | ||||||
|  |     "quotmark" : false, // Quotation mark consistency: | ||||||
|  |                                 // false : do nothing (default) | ||||||
|  |                                 // true : ensure whatever is used is consistent | ||||||
|  |                                 // "single" : require single quotes | ||||||
|  |                                 // "double" : require double quotes | ||||||
|  |     "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks) | ||||||
|  |     "unused" : true, // true: Require all defined variables be used | ||||||
|  |     "strict" : true, // true: Requires all functions run in ES5 Strict Mode | ||||||
|  |     "trailing" : false, // true: Prohibit trailing whitespaces | ||||||
|  |     "maxparams" : false, // {int} Max number of formal params allowed per function | ||||||
|  |     "maxdepth" : false, // {int} Max depth of nested blocks (within functions) | ||||||
|  |     "maxstatements" : false, // {int} Max number statements per function | ||||||
|  |     "maxcomplexity" : false, // {int} Max cyclomatic complexity per function | ||||||
|  |     "maxlen" : false, // {int} Max number of characters per line | ||||||
|  |  | ||||||
|  |     // Relaxing | ||||||
|  |     "asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons) | ||||||
|  |     "boss" : false, // true: Tolerate assignments where comparisons would be expected | ||||||
|  |     "debug" : false, // true: Allow debugger statements e.g. browser breakpoints. | ||||||
|  |     "eqnull" : false, // true: Tolerate use of `== null` | ||||||
|  |     "es5" : false, // true: Allow ES5 syntax (ex: getters and setters) | ||||||
|  |     "esnext" : false, // true: Allow ES.next (ES6) syntax (ex: `const`) | ||||||
|  |     "moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features) | ||||||
|  |                                  // (ex: `for each`, multiple try/catch, function expression…) | ||||||
|  |     "evil" : false, // true: Tolerate use of `eval` and `new Function()` | ||||||
|  |     "expr" : false, // true: Tolerate `ExpressionStatement` as Programs | ||||||
|  |     "funcscope" : false, // true: Tolerate defining variables inside control statements" | ||||||
|  |     "globalstrict" : false, // true: Allow global "use strict" (also enables 'strict') | ||||||
|  |     "iterator" : false, // true: Tolerate using the `__iterator__` property | ||||||
|  |     "lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block | ||||||
|  |     "laxbreak" : false, // true: Tolerate possibly unsafe line breakings | ||||||
|  |     "laxcomma" : false, // true: Tolerate comma-first style coding | ||||||
|  |     "loopfunc" : false, // true: Tolerate functions being defined in loops | ||||||
|  |     "multistr" : false, // true: Tolerate multi-line strings | ||||||
|  |     "proto" : false, // true: Tolerate using the `__proto__` property | ||||||
|  |     "scripturl" : false, // true: Tolerate script-targeted URLs | ||||||
|  |     "smarttabs" : false, // true: Tolerate mixed tabs/spaces when used for alignment | ||||||
|  |     "shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;` | ||||||
|  |     "sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation | ||||||
|  |     "supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;` | ||||||
|  |     "validthis" : false, // true: Tolerate using this in a non-constructor function | ||||||
|  |  | ||||||
|  |     // Environments | ||||||
|  |     "browser" : true, // Web Browser (window, document, etc) | ||||||
|  |     "couch" : false, // CouchDB | ||||||
|  |     "devel" : true, // Development/debugging (alert, confirm, etc) | ||||||
|  |     "dojo" : false, // Dojo Toolkit | ||||||
|  |     "jquery" : true, // jQuery | ||||||
|  |     "mootools" : false, // MooTools | ||||||
|  |     "node" : true, // Node.js | ||||||
|  |     "nonstandard" : false, // Widely adopted globals (escape, unescape, etc) | ||||||
|  |     "prototypejs" : false, // Prototype and Scriptaculous | ||||||
|  |     "rhino" : false, // Rhino | ||||||
|  |     "worker" : false, // Web Workers | ||||||
|  |     "wsh" : false, // Windows Scripting Host | ||||||
|  |     "yui" : false, // Yahoo User Interface | ||||||
|  |  | ||||||
|  |     // Legacy | ||||||
|  |     "nomen" : false, // true: Prohibit dangling `_` in variables | ||||||
|  |     "onevar" : false, // true: Allow only one `var` statement per function | ||||||
|  |     "passfail" : false, // true: Stop on first error | ||||||
|  |     "white" : false, // true: Check against strict whitespace and indentation rules | ||||||
|  |  | ||||||
|  |     // Custom Globals | ||||||
|  |     "globals" : {} // additional predefined global variables | ||||||
|  | } | ||||||
							
								
								
									
										24
									
								
								app.js
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								app.js
									
									
									
									
									
								
							| @@ -32,12 +32,12 @@ global.env = process.env.NODE_ENV || 'production'; | |||||||
|  |  | ||||||
| winston.remove(winston.transports.Console); | winston.remove(winston.transports.Console); | ||||||
| winston.add(winston.transports.Console, { | winston.add(winston.transports.Console, { | ||||||
| 	colorize:true | 	colorize: true | ||||||
| }); | }); | ||||||
|  |  | ||||||
| winston.add(winston.transports.File, { | winston.add(winston.transports.File, { | ||||||
| 	filename:'error.log', | 	filename: 'error.log', | ||||||
| 	level:'error' | 	level: 'error' | ||||||
| }); | }); | ||||||
|  |  | ||||||
| // TODO: remove once https://github.com/flatiron/winston/issues/280 is fixed | // TODO: remove once https://github.com/flatiron/winston/issues/280 is fixed | ||||||
| @@ -53,9 +53,11 @@ winston.info(''); | |||||||
|  |  | ||||||
| if (fs.existsSync(__dirname + '/config.json') && (!nconf.get('setup') && !nconf.get('upgrade'))) { | if (fs.existsSync(__dirname + '/config.json') && (!nconf.get('setup') && !nconf.get('upgrade'))) { | ||||||
| 	// Load server-side config | 	// Load server-side config | ||||||
| 	nconf.file({ file: __dirname + '/config.json'}); | 	nconf.file({ | ||||||
|  | 		file: __dirname + '/config.json' | ||||||
|  | 	}); | ||||||
|  |  | ||||||
| 	var	meta = require('./src/meta.js'); | 	var meta = require('./src/meta.js'); | ||||||
|  |  | ||||||
| 	nconf.set('url', nconf.get('base_url') + (nconf.get('use_port') ? ':' + nconf.get('port') : '') + nconf.get('relative_path') + '/'); | 	nconf.set('url', nconf.get('base_url') + (nconf.get('use_port') ? ':' + nconf.get('port') : '') + nconf.get('relative_path') + '/'); | ||||||
| 	nconf.set('upload_url', nconf.get('url') + 'uploads/'); | 	nconf.set('upload_url', nconf.get('url') + 'uploads/'); | ||||||
| @@ -65,7 +67,7 @@ if (fs.existsSync(__dirname + '/config.json') && (!nconf.get('setup') && !nconf. | |||||||
|  |  | ||||||
| 	meta.configs.init(function() { | 	meta.configs.init(function() { | ||||||
| 		// Initial setup for Redis & Reds | 		// Initial setup for Redis & Reds | ||||||
| 		var	reds = require('reds'); | 		var reds = require('reds'); | ||||||
| 		RDB = require('./src/redis.js'); | 		RDB = require('./src/redis.js'); | ||||||
| 		reds.createClient = function() { | 		reds.createClient = function() { | ||||||
| 			return reds.client || (reds.client = RDB); | 			return reds.client || (reds.client = RDB); | ||||||
| @@ -75,7 +77,7 @@ if (fs.existsSync(__dirname + '/config.json') && (!nconf.get('setup') && !nconf. | |||||||
| 			templates = require('./public/src/templates.js'), | 			templates = require('./public/src/templates.js'), | ||||||
| 			webserver = require('./src/webserver.js'), | 			webserver = require('./src/webserver.js'), | ||||||
| 			websockets = require('./src/websockets.js'), | 			websockets = require('./src/websockets.js'), | ||||||
| 			plugins = require('./src/plugins'),	// Don't remove this - plugins initializes itself | 			plugins = require('./src/plugins'), // Don't remove this - plugins initializes itself | ||||||
| 			admin = { | 			admin = { | ||||||
| 				'categories': require('./src/admin/categories.js') | 				'categories': require('./src/admin/categories.js') | ||||||
| 			}; | 			}; | ||||||
| @@ -93,8 +95,10 @@ if (fs.existsSync(__dirname + '/config.json') && (!nconf.get('setup') && !nconf. | |||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| } else if (nconf.get('upgrade')) { | } else if (nconf.get('upgrade')) { | ||||||
| 	nconf.file({ file: __dirname + '/config.json'}); | 	nconf.file({ | ||||||
| 	var	meta = require('./src/meta.js'); | 		file: __dirname + '/config.json' | ||||||
|  | 	}); | ||||||
|  | 	var meta = require('./src/meta.js'); | ||||||
|  |  | ||||||
| 	meta.configs.init(function() { | 	meta.configs.init(function() { | ||||||
| 		require('./src/upgrade').upgrade(); | 		require('./src/upgrade').upgrade(); | ||||||
| @@ -104,7 +108,7 @@ if (fs.existsSync(__dirname + '/config.json') && (!nconf.get('setup') && !nconf. | |||||||
| 	if (nconf.get('setup')) winston.info('NodeBB Setup Triggered via Command Line'); | 	if (nconf.get('setup')) winston.info('NodeBB Setup Triggered via Command Line'); | ||||||
| 	else winston.warn('Configuration not found, starting NodeBB setup'); | 	else winston.warn('Configuration not found, starting NodeBB setup'); | ||||||
|  |  | ||||||
| 	var	install = require('./src/install'), | 	var install = require('./src/install'), | ||||||
| 		meta = { | 		meta = { | ||||||
| 			config: {} | 			config: {} | ||||||
| 		}; | 		}; | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ var ajaxify = {}; | |||||||
|  |  | ||||||
| 	var events = []; | 	var events = []; | ||||||
| 	ajaxify.register_events = function(new_page_events) { | 	ajaxify.register_events = function(new_page_events) { | ||||||
| 		for (var i = 0, ii = events.length; i<ii; i++) { | 		for (var i = 0, ii = events.length; i < ii; i++) { | ||||||
| 			socket.removeAllListeners(events[i]); // optimize this to user removeListener(event, listener) instead. | 			socket.removeAllListeners(events[i]); // optimize this to user removeListener(event, listener) instead. | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -42,14 +42,14 @@ var ajaxify = {}; | |||||||
|  |  | ||||||
| 		var hash = window.location.hash; | 		var hash = window.location.hash; | ||||||
|  |  | ||||||
| 		if(url.indexOf(RELATIVE_PATH.slice(1)) !== -1) { | 		if (url.indexOf(RELATIVE_PATH.slice(1)) !== -1) { | ||||||
| 			url = url.slice(RELATIVE_PATH.length); | 			url = url.slice(RELATIVE_PATH.length); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		var tpl_url = templates.get_custom_map(url.split('?')[0]); | 		var tpl_url = templates.get_custom_map(url.split('?')[0]); | ||||||
|  |  | ||||||
| 		if (tpl_url == false && !templates[url]) { | 		if (tpl_url == false && !templates[url]) { | ||||||
| 			if(url === '' || url === '/') { | 			if (url === '' || url === '/') { | ||||||
| 				tpl_url = 'home'; | 				tpl_url = 'home'; | ||||||
| 			} else { | 			} else { | ||||||
| 				tpl_url = url.split('/')[0].split('?')[0]; | 				tpl_url = url.split('/')[0].split('?')[0]; | ||||||
| @@ -79,9 +79,9 @@ var ajaxify = {}; | |||||||
| 				app.process_page(); | 				app.process_page(); | ||||||
|  |  | ||||||
| 				jQuery('#content, #footer').stop(true, true).fadeIn(200, function() { | 				jQuery('#content, #footer').stop(true, true).fadeIn(200, function() { | ||||||
| 					if(window.location.hash) | 					if (window.location.hash) | ||||||
| 						hash = window.location.hash; | 						hash = window.location.hash; | ||||||
| 					if(hash) | 					if (hash) | ||||||
| 						app.scrollToPost(hash.substr(1)); | 						app.scrollToPost(hash.substr(1)); | ||||||
| 				}); | 				}); | ||||||
|  |  | ||||||
| @@ -107,9 +107,9 @@ var ajaxify = {}; | |||||||
| 				return href == 'javascript:;' || href == window.location.href + "#" || href.slice(-1) === "#"; | 				return href == 'javascript:;' || href == window.location.href + "#" || href.slice(-1) === "#"; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if(hrefEmpty(this.href)) return; | 			if (hrefEmpty(this.href)) return; | ||||||
|  |  | ||||||
| 			var url = this.href.replace(rootUrl +'/', ''); | 			var url = this.href.replace(rootUrl + '/', ''); | ||||||
|  |  | ||||||
| 			if (this.target !== '') return; | 			if (this.target !== '') return; | ||||||
|  |  | ||||||
| @@ -130,16 +130,16 @@ var ajaxify = {}; | |||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
| 		function evalScript(elem) { | 		function evalScript(elem) { | ||||||
| 			var data = (elem.text || elem.textContent || elem.innerHTML || "" ), | 			var data = (elem.text || elem.textContent || elem.innerHTML || ""), | ||||||
| 				head =	document.getElementsByTagName("head")[0] || | 				head = document.getElementsByTagName("head")[0] || | ||||||
| 						document.documentElement, | 					document.documentElement, | ||||||
| 				script = document.createElement("script"); | 				script = document.createElement("script"); | ||||||
|  |  | ||||||
| 			script.type = "text/javascript"; | 			script.type = "text/javascript"; | ||||||
| 			try { | 			try { | ||||||
| 			  script.appendChild(document.createTextNode(data)); | 				script.appendChild(document.createTextNode(data)); | ||||||
| 			} catch(e) { | 			} catch (e) { | ||||||
| 			  script.text = data; | 				script.text = data; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if (elem.src) { | 			if (elem.src) { | ||||||
| @@ -159,8 +159,8 @@ var ajaxify = {}; | |||||||
|  |  | ||||||
| 		for (i = 0; children_nodes[i]; i++) { | 		for (i = 0; children_nodes[i]; i++) { | ||||||
| 			child = children_nodes[i]; | 			child = children_nodes[i]; | ||||||
| 			if (nodeName(child, "script" ) && | 			if (nodeName(child, "script") && | ||||||
| 			(!child.type || child.type.toLowerCase() === "text/javascript")) { | 				(!child.type || child.type.toLowerCase() === "text/javascript")) { | ||||||
| 				scripts.push(child); | 				scripts.push(child); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -30,9 +30,9 @@ var socket, | |||||||
| 					app.alert(data); | 					app.alert(data); | ||||||
| 				}); | 				}); | ||||||
|  |  | ||||||
| 				socket.on('connect', function(data){ | 				socket.on('connect', function(data) { | ||||||
| 					if(reconnecting) { | 					if (reconnecting) { | ||||||
| 						setTimeout(function(){ | 						setTimeout(function() { | ||||||
| 							app.alert({ | 							app.alert({ | ||||||
| 								alert_id: 'connection_alert', | 								alert_id: 'connection_alert', | ||||||
| 								title: 'Connected', | 								title: 'Connected', | ||||||
| @@ -43,18 +43,20 @@ var socket, | |||||||
| 						}, 1000); | 						}, 1000); | ||||||
| 						reconnecting = false; | 						reconnecting = false; | ||||||
| 						reconnectTries = 0; | 						reconnectTries = 0; | ||||||
| 						socket.emit('api:updateHeader', { fields: ['username', 'picture', 'userslug'] }); | 						socket.emit('api:updateHeader', { | ||||||
|  | 							fields: ['username', 'picture', 'userslug'] | ||||||
|  | 						}); | ||||||
| 					} | 					} | ||||||
| 				}); | 				}); | ||||||
|  |  | ||||||
| 				socket.on('reconnecting', function(data) { | 				socket.on('reconnecting', function(data) { | ||||||
| 					function showDisconnectModal() { | 					function showDisconnectModal() { | ||||||
| 						$('#disconnect-modal').modal({ | 						$('#disconnect-modal').modal({ | ||||||
| 							backdrop:'static', | 							backdrop: 'static', | ||||||
| 							show:true | 							show: true | ||||||
| 						}); | 						}); | ||||||
|  |  | ||||||
| 						$('#reload-button').on('click',function(){ | 						$('#reload-button').on('click', function() { | ||||||
| 							$('#disconnect-modal').modal('hide'); | 							$('#disconnect-modal').modal('hide'); | ||||||
| 							window.location.reload(); | 							window.location.reload(); | ||||||
| 						}); | 						}); | ||||||
| @@ -63,7 +65,7 @@ var socket, | |||||||
| 					reconnecting = true; | 					reconnecting = true; | ||||||
| 					reconnectTries++; | 					reconnectTries++; | ||||||
|  |  | ||||||
| 					if(reconnectTries > 4) { | 					if (reconnectTries > 4) { | ||||||
| 						showDisconnectModal(); | 						showDisconnectModal(); | ||||||
| 						return; | 						return; | ||||||
| 					} | 					} | ||||||
| @@ -129,10 +131,10 @@ var socket, | |||||||
| 	// Willingly stolen from: http://phpjs.org/functions/strip_tags/ | 	// Willingly stolen from: http://phpjs.org/functions/strip_tags/ | ||||||
| 	app.strip_tags = function(input, allowed) { | 	app.strip_tags = function(input, allowed) { | ||||||
| 		allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>) | 		allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>) | ||||||
| 		var	tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi, | 		var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi, | ||||||
| 			commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi; | 			commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi; | ||||||
|  |  | ||||||
| 		return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) { | 		return input.replace(commentsAndPhpTags, '').replace(tags, function($0, $1) { | ||||||
| 			return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : ''; | 			return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : ''; | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| @@ -146,7 +148,7 @@ var socket, | |||||||
| 	app.alert = function(params) { | 	app.alert = function(params) { | ||||||
| 		var alert_id = 'alert_button_' + ((params.alert_id) ? params.alert_id : new Date().getTime()); | 		var alert_id = 'alert_button_' + ((params.alert_id) ? params.alert_id : new Date().getTime()); | ||||||
|  |  | ||||||
| 		var alert = $('#'+alert_id); | 		var alert = $('#' + alert_id); | ||||||
|  |  | ||||||
| 		function startTimeout(div, timeout) { | 		function startTimeout(div, timeout) { | ||||||
| 			var timeoutId = setTimeout(function() { | 			var timeoutId = setTimeout(function() { | ||||||
| @@ -158,15 +160,14 @@ var socket, | |||||||
| 			$(div).attr('timeoutId', timeoutId); | 			$(div).attr('timeoutId', timeoutId); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if(alert.length > 0) { | 		if (alert.length > 0) { | ||||||
| 			alert.find('strong').html(params.title); | 			alert.find('strong').html(params.title); | ||||||
| 			alert.find('p').html(params.message); | 			alert.find('p').html(params.message); | ||||||
| 			alert.attr('class', "alert toaster-alert " + "alert-" + params.type); | 			alert.attr('class', "alert toaster-alert " + "alert-" + params.type); | ||||||
|  |  | ||||||
| 			clearTimeout(alert.attr('timeoutId')); | 			clearTimeout(alert.attr('timeoutId')); | ||||||
| 			startTimeout(alert, params.timeout); | 			startTimeout(alert, params.timeout); | ||||||
| 		} | 		} else { | ||||||
| 		else { |  | ||||||
| 			var div = document.createElement('div'), | 			var div = document.createElement('div'), | ||||||
| 				button = document.createElement('button'), | 				button = document.createElement('button'), | ||||||
| 				strong = document.createElement('strong'), | 				strong = document.createElement('strong'), | ||||||
| @@ -191,7 +192,7 @@ var socket, | |||||||
| 			if (params.location == null) | 			if (params.location == null) | ||||||
| 				params.location = 'alert_window'; | 				params.location = 'alert_window'; | ||||||
|  |  | ||||||
| 			jQuery('#'+params.location).prepend(jQuery(div).fadeIn('100')); | 			jQuery('#' + params.location).prepend(jQuery(div).fadeIn('100')); | ||||||
|  |  | ||||||
| 			if (params.timeout) { | 			if (params.timeout) { | ||||||
| 				startTimeout(div, params.timeout); | 				startTimeout(div, params.timeout); | ||||||
| @@ -209,7 +210,7 @@ var socket, | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	app.alertSuccess = function(message, timeout) { | 	app.alertSuccess = function(message, timeout) { | ||||||
| 		if(!timeout) | 		if (!timeout) | ||||||
| 			timeout = 2000; | 			timeout = 2000; | ||||||
|  |  | ||||||
| 		app.alert({ | 		app.alert({ | ||||||
| @@ -221,7 +222,7 @@ var socket, | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	app.alertError = function(message, timeout) { | 	app.alertError = function(message, timeout) { | ||||||
| 		if(!timeout) | 		if (!timeout) | ||||||
| 			timeout = 2000; | 			timeout = 2000; | ||||||
|  |  | ||||||
| 		app.alert({ | 		app.alert({ | ||||||
| @@ -234,7 +235,7 @@ var socket, | |||||||
|  |  | ||||||
| 	app.current_room = null; | 	app.current_room = null; | ||||||
| 	app.enter_room = function(room) { | 	app.enter_room = function(room) { | ||||||
| 		if(socket) { | 		if (socket) { | ||||||
| 			if (app.current_room === room) | 			if (app.current_room === room) | ||||||
| 				return; | 				return; | ||||||
|  |  | ||||||
| @@ -268,13 +269,13 @@ var socket, | |||||||
|  |  | ||||||
| 		var url = window.location.href, | 		var url = window.location.href, | ||||||
| 			parts = url.split('/'), | 			parts = url.split('/'), | ||||||
| 			active = parts[parts.length-1]; | 			active = parts[parts.length - 1]; | ||||||
|  |  | ||||||
| 		jQuery('#main-nav li').removeClass('active'); | 		jQuery('#main-nav li').removeClass('active'); | ||||||
| 		if(active) { | 		if (active) { | ||||||
| 			jQuery('#main-nav li a').each(function() { | 			jQuery('#main-nav li a').each(function() { | ||||||
| 				var href = this.getAttribute('href'); | 				var href = this.getAttribute('href'); | ||||||
| 				if(active.match(/^users/)) | 				if (active.match(/^users/)) | ||||||
| 					active = 'users'; | 					active = 'users'; | ||||||
| 				if (href && href.match(active)) { | 				if (href && href.match(active)) { | ||||||
| 					jQuery(this.parentNode).addClass('active'); | 					jQuery(this.parentNode).addClass('active'); | ||||||
| @@ -298,9 +299,9 @@ var socket, | |||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if(showWelcomeMessage) { | 		if (showWelcomeMessage) { | ||||||
| 			showWelcomeMessage = false; | 			showWelcomeMessage = false; | ||||||
| 			if(document.readyState !== 'complete') { | 			if (document.readyState !== 'complete') { | ||||||
| 				$(document).ready(showAlert); | 				$(document).ready(showAlert); | ||||||
| 			} else { | 			} else { | ||||||
| 				showAlert(); | 				showAlert(); | ||||||
| @@ -317,7 +318,7 @@ var socket, | |||||||
| 	app.openChat = function(username, touid) { | 	app.openChat = function(username, touid) { | ||||||
| 		require(['chat'], function(chat) { | 		require(['chat'], function(chat) { | ||||||
| 			var chatModal; | 			var chatModal; | ||||||
| 			if(!chat.modalExists(touid)) { | 			if (!chat.modalExists(touid)) { | ||||||
| 				chatModal = chat.createModal(username, touid); | 				chatModal = chat.createModal(username, touid); | ||||||
| 			} else { | 			} else { | ||||||
| 				chatModal = chat.getModal(touid); | 				chatModal = chat.getModal(touid); | ||||||
| @@ -336,7 +337,7 @@ var socket, | |||||||
| 				.append(html) | 				.append(html) | ||||||
| 				.fadeIn('slow'); | 				.fadeIn('slow'); | ||||||
|  |  | ||||||
| 		for(var x=0,numPosts=data.posts.length;x<numPosts;x++) { | 		for (var x = 0, numPosts = data.posts.length; x < numPosts; x++) { | ||||||
| 			socket.emit('api:post.privileges', data.posts[x].pid); | 			socket.emit('api:post.privileges', data.posts[x].pid); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -350,11 +351,11 @@ var socket, | |||||||
| 	app.infiniteLoaderActive = false; | 	app.infiniteLoaderActive = false; | ||||||
|  |  | ||||||
| 	app.loadMorePosts = function(tid, callback) { | 	app.loadMorePosts = function(tid, callback) { | ||||||
| 		if(app.infiniteLoaderActive) | 		if (app.infiniteLoaderActive) | ||||||
| 			return; | 			return; | ||||||
| 		app.infiniteLoaderActive = true; | 		app.infiniteLoaderActive = true; | ||||||
|  |  | ||||||
| 		if($('#loading-indicator').attr('done') === '0') | 		if ($('#loading-indicator').attr('done') === '0') | ||||||
| 			$('#loading-indicator').removeClass('hide'); | 			$('#loading-indicator').removeClass('hide'); | ||||||
|  |  | ||||||
| 		socket.emit('api:topic.loadMore', { | 		socket.emit('api:topic.loadMore', { | ||||||
| @@ -362,14 +363,14 @@ var socket, | |||||||
| 			after: document.querySelectorAll('#post-container li[data-pid]').length | 			after: document.querySelectorAll('#post-container li[data-pid]').length | ||||||
| 		}, function(data) { | 		}, function(data) { | ||||||
| 			app.infiniteLoaderActive = false; | 			app.infiniteLoaderActive = false; | ||||||
| 			if(data.posts.length) { | 			if (data.posts.length) { | ||||||
| 				$('#loading-indicator').attr('done', '0'); | 				$('#loading-indicator').attr('done', '0'); | ||||||
| 				app.createNewPosts(data); | 				app.createNewPosts(data); | ||||||
| 			} else { | 			} else { | ||||||
| 				$('#loading-indicator').attr('done', '1'); | 				$('#loading-indicator').attr('done', '1'); | ||||||
| 			} | 			} | ||||||
| 			$('#loading-indicator').addClass('hide'); | 			$('#loading-indicator').addClass('hide'); | ||||||
| 			if(callback) | 			if (callback) | ||||||
| 				callback(data.posts); | 				callback(data.posts); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| @@ -388,7 +389,7 @@ var socket, | |||||||
|  |  | ||||||
| 	app.scrollToPost = function(pid) { | 	app.scrollToPost = function(pid) { | ||||||
|  |  | ||||||
| 		if(!pid) | 		if (!pid) | ||||||
| 			return; | 			return; | ||||||
|  |  | ||||||
| 		var container = $(document.body), | 		var container = $(document.body), | ||||||
| @@ -401,22 +402,22 @@ var socket, | |||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if(!scrollTo.length && tid) { | 		if (!scrollTo.length && tid) { | ||||||
|  |  | ||||||
| 			var intervalID = setInterval(function() { | 			var intervalID = setInterval(function() { | ||||||
| 				app.loadMorePosts(tid, function(posts) { | 				app.loadMorePosts(tid, function(posts) { | ||||||
| 					scrollTo = $('#post_anchor_' + pid); | 					scrollTo = $('#post_anchor_' + pid); | ||||||
|  |  | ||||||
| 					if(tid && scrollTo.length) { | 					if (tid && scrollTo.length) { | ||||||
| 						animateScroll(); | 						animateScroll(); | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					if(!posts.length || scrollTo.length) | 					if (!posts.length || scrollTo.length) | ||||||
| 						clearInterval(intervalID); | 						clearInterval(intervalID); | ||||||
| 				}); | 				}); | ||||||
| 			}, 100); | 			}, 100); | ||||||
|  |  | ||||||
| 		} else if(tid) { | 		} else if (tid) { | ||||||
| 			animateScroll(); | 			animateScroll(); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -425,7 +426,7 @@ var socket, | |||||||
| 	jQuery('document').ready(function() { | 	jQuery('document').ready(function() { | ||||||
| 		$('#search-form').on('submit', function() { | 		$('#search-form').on('submit', function() { | ||||||
| 			var input = $(this).find('input'); | 			var input = $(this).find('input'); | ||||||
| 			ajaxify.go("search/"+input.val(), null, "search"); | 			ajaxify.go("search/" + input.val(), null, "search"); | ||||||
| 			input.val(''); | 			input.val(''); | ||||||
| 			return false; | 			return false; | ||||||
| 		}) | 		}) | ||||||
|   | |||||||
| @@ -12,8 +12,8 @@ | |||||||
| 		var followBtn = $('#follow-btn'); | 		var followBtn = $('#follow-btn'); | ||||||
| 		var unfollowBtn = $('#unfollow-btn'); | 		var unfollowBtn = $('#unfollow-btn'); | ||||||
|  |  | ||||||
| 		if(yourid !== theirid) { | 		if (yourid !== theirid) { | ||||||
| 			if(isFollowing) { | 			if (isFollowing) { | ||||||
| 				followBtn.hide(); | 				followBtn.hide(); | ||||||
| 				unfollowBtn.show(); | 				unfollowBtn.show(); | ||||||
| 			} else { | 			} else { | ||||||
| @@ -26,8 +26,10 @@ | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		followBtn.on('click', function() { | 		followBtn.on('click', function() { | ||||||
| 			socket.emit('api:user.follow', {uid: theirid}, function(success) { | 			socket.emit('api:user.follow', { | ||||||
| 				if(success) { | 				uid: theirid | ||||||
|  | 			}, function(success) { | ||||||
|  | 				if (success) { | ||||||
| 					followBtn.hide(); | 					followBtn.hide(); | ||||||
| 					unfollowBtn.show(); | 					unfollowBtn.show(); | ||||||
| 					app.alertSuccess('You are now following ' + username + '!'); | 					app.alertSuccess('You are now following ' + username + '!'); | ||||||
| @@ -39,8 +41,10 @@ | |||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		unfollowBtn.on('click', function() { | 		unfollowBtn.on('click', function() { | ||||||
| 			socket.emit('api:user.unfollow', {uid: theirid}, function(success) { | 			socket.emit('api:user.unfollow', { | ||||||
| 				if(success) { | 				uid: theirid | ||||||
|  | 			}, function(success) { | ||||||
|  | 				if (success) { | ||||||
| 					followBtn.show(); | 					followBtn.show(); | ||||||
| 					unfollowBtn.hide(); | 					unfollowBtn.hide(); | ||||||
| 					app.alertSuccess('You are no longer following ' + username + '!'); | 					app.alertSuccess('You are no longer following ' + username + '!'); | ||||||
| @@ -58,7 +62,7 @@ | |||||||
| 		var onlineStatus = $('.account-online-status'); | 		var onlineStatus = $('.account-online-status'); | ||||||
|  |  | ||||||
| 		function handleUserOnline(data) { | 		function handleUserOnline(data) { | ||||||
| 			if(data.online) { | 			if (data.online) { | ||||||
| 				onlineStatus.find('span span').text('online'); | 				onlineStatus.find('span span').text('online'); | ||||||
| 				onlineStatus.find('i').attr('class', 'icon-circle'); | 				onlineStatus.find('i').attr('class', 'icon-circle'); | ||||||
| 			} else { | 			} else { | ||||||
|   | |||||||
| @@ -1,5 +1,3 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| var gravatarPicture = templates.get('gravatarpicture'); | var gravatarPicture = templates.get('gravatarpicture'); | ||||||
| var uploadedPicture = templates.get('uploadedpicture'); | var uploadedPicture = templates.get('uploadedpicture'); | ||||||
|  |  | ||||||
| @@ -14,7 +12,7 @@ $(document).ready(function() { | |||||||
| 		$('#upload-progress-box').show(); | 		$('#upload-progress-box').show(); | ||||||
| 		$('#upload-progress-box').removeClass('hide'); | 		$('#upload-progress-box').removeClass('hide'); | ||||||
|  |  | ||||||
| 		if(!$('#userPhotoInput').val()) { | 		if (!$('#userPhotoInput').val()) { | ||||||
| 			error('select an image to upload!'); | 			error('select an image to upload!'); | ||||||
| 			return false; | 			return false; | ||||||
| 		} | 		} | ||||||
| @@ -28,13 +26,13 @@ $(document).ready(function() { | |||||||
| 				error('Error: ' + xhr.status); | 				error('Error: ' + xhr.status); | ||||||
| 			}, | 			}, | ||||||
|  |  | ||||||
| 			uploadProgress : function(event, position, total, percent) { | 			uploadProgress: function(event, position, total, percent) { | ||||||
| 				$('#upload-progress-bar').css('width', percent+'%'); | 				$('#upload-progress-bar').css('width', percent + '%'); | ||||||
| 			}, | 			}, | ||||||
|  |  | ||||||
|  |  | ||||||
| 			success: function(response) { | 			success: function(response) { | ||||||
| 				if(response.error) { | 				if (response.error) { | ||||||
| 					error(response.error); | 					error(response.error); | ||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
| @@ -51,7 +49,9 @@ $(document).ready(function() { | |||||||
| 					$('#upload-picture-modal').modal('hide'); | 					$('#upload-picture-modal').modal('hide'); | ||||||
| 				}, 750); | 				}, 750); | ||||||
|  |  | ||||||
| 				socket.emit('api:updateHeader', { fields: ['username', 'picture', 'userslug'] }); | 				socket.emit('api:updateHeader', { | ||||||
|  | 					fields: ['username', 'picture', 'userslug'] | ||||||
|  | 				}); | ||||||
| 				success('File uploaded successfully!'); | 				success('File uploaded successfully!'); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| @@ -87,7 +87,7 @@ $(document).ready(function() { | |||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
| 		socket.emit('api:user.changePicture', userData, function(success) { | 		socket.emit('api:user.changePicture', userData, function(success) { | ||||||
| 			if(!success) { | 			if (!success) { | ||||||
| 				app.alertError('There was an error changing picture!'); | 				app.alertError('There was an error changing picture!'); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| @@ -95,26 +95,26 @@ $(document).ready(function() { | |||||||
|  |  | ||||||
| 	var selectedImageType = ''; | 	var selectedImageType = ''; | ||||||
|  |  | ||||||
| 	$('#submitBtn').on('click',function(){ | 	$('#submitBtn').on('click', function() { | ||||||
|  |  | ||||||
| 	   var userData = { | 		var userData = { | ||||||
| 			uid:$('#inputUID').val(), | 			uid: $('#inputUID').val(), | ||||||
| 			email:$('#inputEmail').val(), | 			email: $('#inputEmail').val(), | ||||||
| 			fullname:$('#inputFullname').val(), | 			fullname: $('#inputFullname').val(), | ||||||
| 			website:$('#inputWebsite').val(), | 			website: $('#inputWebsite').val(), | ||||||
| 			birthday:$('#inputBirthday').val(), | 			birthday: $('#inputBirthday').val(), | ||||||
| 			location:$('#inputLocation').val(), | 			location: $('#inputLocation').val(), | ||||||
| 			signature:$('#inputSignature').val() | 			signature: $('#inputSignature').val() | ||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
| 		socket.emit('api:user.updateProfile', userData, function(err, data) { | 		socket.emit('api:user.updateProfile', userData, function(err, data) { | ||||||
| 			if(data.success) { | 			if (data.success) { | ||||||
| 				app.alertSuccess('Your profile has been updated successfully!'); | 				app.alertSuccess('Your profile has been updated successfully!'); | ||||||
| 				if(data.picture) { | 				if (data.picture) { | ||||||
| 					$('#user-current-picture').attr('src', data.picture); | 					$('#user-current-picture').attr('src', data.picture); | ||||||
| 					$('#user_label img').attr('src', data.picture); | 					$('#user_label img').attr('src', data.picture); | ||||||
| 				} | 				} | ||||||
| 				if(data.gravatarpicture) { | 				if (data.gravatarpicture) { | ||||||
| 					$('#user-gravatar-picture').attr('src', data.gravatarpicture); | 					$('#user-gravatar-picture').attr('src', data.gravatarpicture); | ||||||
| 					gravatarPicture = data.gravatarpicture; | 					gravatarPicture = data.gravatarpicture; | ||||||
| 				} | 				} | ||||||
| @@ -128,27 +128,25 @@ $(document).ready(function() { | |||||||
| 	function updateImages() { | 	function updateImages() { | ||||||
| 		var currentPicture = $('#user-current-picture').attr('src'); | 		var currentPicture = $('#user-current-picture').attr('src'); | ||||||
|  |  | ||||||
| 		if(gravatarPicture) { | 		if (gravatarPicture) { | ||||||
| 			$('#user-gravatar-picture').attr('src', gravatarPicture); | 			$('#user-gravatar-picture').attr('src', gravatarPicture); | ||||||
| 			$('#gravatar-box').show(); | 			$('#gravatar-box').show(); | ||||||
| 		} | 		} else | ||||||
| 		else |  | ||||||
| 			$('#gravatar-box').hide(); | 			$('#gravatar-box').hide(); | ||||||
|  |  | ||||||
| 		if(uploadedPicture) { | 		if (uploadedPicture) { | ||||||
| 			$('#user-uploaded-picture').attr('src', uploadedPicture); | 			$('#user-uploaded-picture').attr('src', uploadedPicture); | ||||||
| 			$('#uploaded-box').show(); | 			$('#uploaded-box').show(); | ||||||
| 		} | 		} else | ||||||
| 		else |  | ||||||
| 			$('#uploaded-box').hide(); | 			$('#uploaded-box').hide(); | ||||||
|  |  | ||||||
|  |  | ||||||
| 		 if(currentPicture == gravatarPicture) | 		if (currentPicture == gravatarPicture) | ||||||
| 			$('#gravatar-box .icon-ok').show(); | 			$('#gravatar-box .icon-ok').show(); | ||||||
| 		else | 		else | ||||||
| 			$('#gravatar-box .icon-ok').hide(); | 			$('#gravatar-box .icon-ok').hide(); | ||||||
|  |  | ||||||
| 		if(currentPicture == uploadedPicture) | 		if (currentPicture == uploadedPicture) | ||||||
| 			$('#uploaded-box .icon-ok').show(); | 			$('#uploaded-box .icon-ok').show(); | ||||||
| 		else | 		else | ||||||
| 			$('#uploaded-box .icon-ok').hide(); | 			$('#uploaded-box .icon-ok').hide(); | ||||||
| @@ -165,13 +163,13 @@ $(document).ready(function() { | |||||||
| 		return false; | 		return false; | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	$('#gravatar-box').on('click', function(){ | 	$('#gravatar-box').on('click', function() { | ||||||
| 		$('#gravatar-box .icon-ok').show(); | 		$('#gravatar-box .icon-ok').show(); | ||||||
| 		$('#uploaded-box .icon-ok').hide(); | 		$('#uploaded-box .icon-ok').hide(); | ||||||
| 		selectedImageType = 'gravatar'; | 		selectedImageType = 'gravatar'; | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	$('#uploaded-box').on('click', function(){ | 	$('#uploaded-box').on('click', function() { | ||||||
| 		$('#gravatar-box .icon-ok').hide(); | 		$('#gravatar-box .icon-ok').hide(); | ||||||
| 		$('#uploaded-box .icon-ok').show(); | 		$('#uploaded-box .icon-ok').show(); | ||||||
| 		selectedImageType = 'uploaded'; | 		selectedImageType = 'uploaded'; | ||||||
| @@ -180,12 +178,12 @@ $(document).ready(function() { | |||||||
| 	$('#savePictureChangesBtn').on('click', function() { | 	$('#savePictureChangesBtn').on('click', function() { | ||||||
| 		$('#change-picture-modal').modal('hide'); | 		$('#change-picture-modal').modal('hide'); | ||||||
|  |  | ||||||
| 		if(selectedImageType) { | 		if (selectedImageType) { | ||||||
| 			changeUserPicture(selectedImageType); | 			changeUserPicture(selectedImageType); | ||||||
|  |  | ||||||
| 			if(selectedImageType == 'gravatar') | 			if (selectedImageType == 'gravatar') | ||||||
| 				$('#user-current-picture').attr('src', gravatarPicture); | 				$('#user-current-picture').attr('src', gravatarPicture); | ||||||
| 			else if(selectedImageType == 'uploaded') | 			else if (selectedImageType == 'uploaded') | ||||||
| 				$('#user-current-picture').attr('src', uploadedPicture); | 				$('#user-current-picture').attr('src', uploadedPicture); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -195,7 +193,7 @@ $(document).ready(function() { | |||||||
| 		$('#userPhotoInput').val(''); | 		$('#userPhotoInput').val(''); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	$('#uploadPictureBtn').on('click', function(){ | 	$('#uploadPictureBtn').on('click', function() { | ||||||
|  |  | ||||||
| 		$('#change-picture-modal').modal('hide'); | 		$('#change-picture-modal').modal('hide'); | ||||||
| 		$('#upload-picture-modal').modal('show'); | 		$('#upload-picture-modal').modal('show'); | ||||||
| @@ -226,7 +224,7 @@ $(document).ready(function() { | |||||||
| 				password_notify.html('Password too short'); | 				password_notify.html('Password too short'); | ||||||
| 				password_notify.attr('class', 'alert alert-danger'); | 				password_notify.attr('class', 'alert alert-danger'); | ||||||
| 				password_notify.removeClass('hide'); | 				password_notify.removeClass('hide'); | ||||||
| 			} else if(!passwordvalid) { | 			} else if (!passwordvalid) { | ||||||
| 				password_notify.html('Invalid password'); | 				password_notify.html('Invalid password'); | ||||||
| 				password_notify.attr('class', 'alert alert-danger'); | 				password_notify.attr('class', 'alert alert-danger'); | ||||||
| 				password_notify.removeClass('hide'); | 				password_notify.removeClass('hide'); | ||||||
| @@ -240,11 +238,11 @@ $(document).ready(function() { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		function onPasswordConfirmChanged() { | 		function onPasswordConfirmChanged() { | ||||||
| 			if(password_notify.hasClass('alert-danger') || !password_confirm.val()) { | 			if (password_notify.hasClass('alert-danger') || !password_confirm.val()) { | ||||||
| 				password_confirm_notify.addClass('hide'); | 				password_confirm_notify.addClass('hide'); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 			if(password.val() !== password_confirm.val()) { | 			if (password.val() !== password_confirm.val()) { | ||||||
| 				password_confirm_notify.html('Passwords must match!'); | 				password_confirm_notify.html('Passwords must match!'); | ||||||
| 				password_confirm_notify.attr('class', 'alert alert-danger'); | 				password_confirm_notify.attr('class', 'alert alert-danger'); | ||||||
| 				password_confirm_notify.removeClass('hide'); | 				password_confirm_notify.removeClass('hide'); | ||||||
| @@ -262,8 +260,11 @@ $(document).ready(function() { | |||||||
|  |  | ||||||
| 		$('#changePasswordBtn').on('click', function() { | 		$('#changePasswordBtn').on('click', function() { | ||||||
|  |  | ||||||
| 			if(passwordvalid && passwordsmatch && currentPassword.val()) { | 			if (passwordvalid && passwordsmatch && currentPassword.val()) { | ||||||
| 				socket.emit('api:user.changePassword', {'currentPassword': currentPassword.val(),'newPassword': password.val()	}, function(err) { | 				socket.emit('api:user.changePassword', { | ||||||
|  | 					'currentPassword': currentPassword.val(), | ||||||
|  | 					'newPassword': password.val() | ||||||
|  | 				}, function(err) { | ||||||
|  |  | ||||||
| 					currentPassword.val(''); | 					currentPassword.val(''); | ||||||
| 					password.val(''); | 					password.val(''); | ||||||
| @@ -273,7 +274,7 @@ $(document).ready(function() { | |||||||
| 					passwordsmatch = false; | 					passwordsmatch = false; | ||||||
| 					passwordvalid = false; | 					passwordvalid = false; | ||||||
|  |  | ||||||
| 					if(err) { | 					if (err) { | ||||||
| 						app.alertError(err.error); | 						app.alertError(err.error); | ||||||
| 						return; | 						return; | ||||||
| 					} | 					} | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ | |||||||
| 		var settingsLink = $('#settingsLink'); | 		var settingsLink = $('#settingsLink'); | ||||||
| 		var favouritesLink = $('#favouritesLink'); | 		var favouritesLink = $('#favouritesLink'); | ||||||
|  |  | ||||||
| 		if(yourid === "0" || yourid !== theirid) { | 		if (yourid === "0" || yourid !== theirid) { | ||||||
| 			editLink.hide(); | 			editLink.hide(); | ||||||
| 			settingsLink.hide(); | 			settingsLink.hide(); | ||||||
| 			favouritesLink.hide(); | 			favouritesLink.hide(); | ||||||
|   | |||||||
| @@ -1,16 +1,13 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| $(document).ready(function() { | $(document).ready(function() { | ||||||
|  |  | ||||||
| 	$('#submitBtn').on('click', function() { | 	$('#submitBtn').on('click', function() { | ||||||
|  |  | ||||||
| 		var settings = { | 		var settings = { | ||||||
| 			showemail: $('#showemailCheckBox').is(':checked')?1:0 | 			showemail: $('#showemailCheckBox').is(':checked') ? 1 : 0 | ||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
| 		socket.emit('api:user.saveSettings', settings, function(success) { | 		socket.emit('api:user.saveSettings', settings, function(success) { | ||||||
| 			if(success) { | 			if (success) { | ||||||
| 				app.alertSuccess('Settings saved!'); | 				app.alertSuccess('Settings saved!'); | ||||||
| 			} else { | 			} else { | ||||||
| 				app.alertError('There was an error saving settings!'); | 				app.alertError('There was an error saving settings!'); | ||||||
|   | |||||||
| @@ -1,4 +1,3 @@ | |||||||
|  |  | ||||||
| var modified_categories = {}; | var modified_categories = {}; | ||||||
|  |  | ||||||
| function modified(el) { | function modified(el) { | ||||||
| @@ -16,7 +15,7 @@ function save() { | |||||||
| function select_icon(el) { | function select_icon(el) { | ||||||
| 	var selected = el.attr('class').replace(' icon-2x', ''); | 	var selected = el.attr('class').replace(' icon-2x', ''); | ||||||
| 	jQuery('#icons .selected').removeClass('selected'); | 	jQuery('#icons .selected').removeClass('selected'); | ||||||
| 	if(selected) | 	if (selected) | ||||||
| 		jQuery('#icons .' + selected).parent().addClass('selected'); | 		jQuery('#icons .' + selected).parent().addClass('selected'); | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -57,14 +56,14 @@ jQuery('.blockclass').each(function() { | |||||||
|  |  | ||||||
| 	function createNewCategory() { | 	function createNewCategory() { | ||||||
| 		var category = { | 		var category = { | ||||||
| 			name:$('#inputName').val(), | 			name: $('#inputName').val(), | ||||||
| 			description:$('#inputDescription').val(), | 			description: $('#inputDescription').val(), | ||||||
| 			icon:$('#new-category-modal i').attr('value'), | 			icon: $('#new-category-modal i').attr('value'), | ||||||
| 			blockclass:$('#inputBlockclass').val() | 			blockclass: $('#inputBlockclass').val() | ||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
| 		socket.emit('api:admin.categories.create', category, function(err, data) { | 		socket.emit('api:admin.categories.create', category, function(err, data) { | ||||||
| 			if(!err) { | 			if (!err) { | ||||||
| 				app.alert({ | 				app.alert({ | ||||||
| 					alert_id: 'category_created', | 					alert_id: 'category_created', | ||||||
| 					title: 'Created', | 					title: 'Created', | ||||||
| @@ -73,7 +72,9 @@ jQuery('.blockclass').each(function() { | |||||||
| 					timeout: 2000 | 					timeout: 2000 | ||||||
| 				}); | 				}); | ||||||
|  |  | ||||||
| 				var html = templates.prepare(templates['admin/categories'].blocks['categories']).parse({categories:[data]}); | 				var html = templates.prepare(templates['admin/categories'].blocks['categories']).parse({ | ||||||
|  | 					categories: [data] | ||||||
|  | 				}); | ||||||
| 				$('#entry-container').append(html); | 				$('#entry-container').append(html); | ||||||
|  |  | ||||||
| 				$('#new-category-modal').modal('hide'); | 				$('#new-category-modal').modal('hide'); | ||||||
| @@ -84,7 +85,7 @@ jQuery('.blockclass').each(function() { | |||||||
| 	jQuery('document').ready(function() { | 	jQuery('document').ready(function() { | ||||||
| 		var url = window.location.href, | 		var url = window.location.href, | ||||||
| 			parts = url.split('/'), | 			parts = url.split('/'), | ||||||
| 			active = parts[parts.length-1]; | 			active = parts[parts.length - 1]; | ||||||
|  |  | ||||||
| 		jQuery('.nav-pills li').removeClass('active'); | 		jQuery('.nav-pills li').removeClass('active'); | ||||||
| 		jQuery('.nav-pills li a').each(function() { | 		jQuery('.nav-pills li a').each(function() { | ||||||
| @@ -112,7 +113,7 @@ jQuery('.blockclass').each(function() { | |||||||
|  |  | ||||||
| 		jQuery('.entry-row button').each(function(index, element) { | 		jQuery('.entry-row button').each(function(index, element) { | ||||||
| 			var disabled = $(element).attr('data-disabled'); | 			var disabled = $(element).attr('data-disabled'); | ||||||
| 			if(disabled == "0" || disabled == "") | 			if (disabled == "0" || disabled == "") | ||||||
| 				$(element).html('Disable'); | 				$(element).html('Disable'); | ||||||
| 			else | 			else | ||||||
| 				$(element).html('Enable'); | 				$(element).html('Enable'); | ||||||
| @@ -124,7 +125,7 @@ jQuery('.blockclass').each(function() { | |||||||
| 			var categoryRow = btn.parents('li'); | 			var categoryRow = btn.parents('li'); | ||||||
| 			var cid = categoryRow.attr('data-cid'); | 			var cid = categoryRow.attr('data-cid'); | ||||||
|  |  | ||||||
| 			var disabled = btn.html() == "Disable" ? "1":"0"; | 			var disabled = btn.html() == "Disable" ? "1" : "0"; | ||||||
| 			categoryRow.remove(); | 			categoryRow.remove(); | ||||||
| 			modified_categories[cid] = modified_categories[cid] || {}; | 			modified_categories[cid] = modified_categories[cid] || {}; | ||||||
| 			modified_categories[cid]['disabled'] = disabled; | 			modified_categories[cid]['disabled'] = disabled; | ||||||
|   | |||||||
| @@ -1,6 +1,3 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| var nodebb_admin = (function(nodebb_admin) { | var nodebb_admin = (function(nodebb_admin) { | ||||||
|  |  | ||||||
| 	nodebb_admin.config = undefined; | 	nodebb_admin.config = undefined; | ||||||
| @@ -19,21 +16,21 @@ var nodebb_admin = (function(nodebb_admin) { | |||||||
| 			numFields = fields.length, | 			numFields = fields.length, | ||||||
| 			saveBtn = document.getElementById('save'), | 			saveBtn = document.getElementById('save'), | ||||||
| 			x, key, inputType; | 			x, key, inputType; | ||||||
| 		for(x=0;x<numFields;x++) { | 		for (x = 0; x < numFields; x++) { | ||||||
| 			key = fields[x].getAttribute('data-field'); | 			key = fields[x].getAttribute('data-field'); | ||||||
| 			inputType = fields[x].getAttribute('type'); | 			inputType = fields[x].getAttribute('type'); | ||||||
| 			if (fields[x].nodeName === 'INPUT') { | 			if (fields[x].nodeName === 'INPUT') { | ||||||
| 				if (nodebb_admin.config[key]) { | 				if (nodebb_admin.config[key]) { | ||||||
| 					switch(inputType) { | 					switch (inputType) { | ||||||
| 						case 'text': | 						case 'text': | ||||||
| 						case 'textarea': | 						case 'textarea': | ||||||
| 						case 'number': | 						case 'number': | ||||||
| 							fields[x].value = nodebb_admin.config[key]; | 							fields[x].value = nodebb_admin.config[key]; | ||||||
| 						break; | 							break; | ||||||
|  |  | ||||||
| 						case 'checkbox': | 						case 'checkbox': | ||||||
| 							fields[x].checked = nodebb_admin.config[key] === '1' ? true : false; | 							fields[x].checked = nodebb_admin.config[key] === '1' ? true : false; | ||||||
| 						break; | 							break; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} else if (fields[x].nodeName === 'TEXTAREA') { | 			} else if (fields[x].nodeName === 'TEXTAREA') { | ||||||
| @@ -45,25 +42,28 @@ var nodebb_admin = (function(nodebb_admin) { | |||||||
| 			var key, value; | 			var key, value; | ||||||
| 			e.preventDefault(); | 			e.preventDefault(); | ||||||
|  |  | ||||||
| 			for(x=0;x<numFields;x++) { | 			for (x = 0; x < numFields; x++) { | ||||||
| 				key = fields[x].getAttribute('data-field'); | 				key = fields[x].getAttribute('data-field'); | ||||||
| 				if (fields[x].nodeName === 'INPUT') { | 				if (fields[x].nodeName === 'INPUT') { | ||||||
| 					inputType = fields[x].getAttribute('type'); | 					inputType = fields[x].getAttribute('type'); | ||||||
| 					switch(inputType) { | 					switch (inputType) { | ||||||
| 						case 'text': | 						case 'text': | ||||||
| 						case 'number': | 						case 'number': | ||||||
| 							value = fields[x].value; | 							value = fields[x].value; | ||||||
| 						break; | 							break; | ||||||
|  |  | ||||||
| 						case 'checkbox': | 						case 'checkbox': | ||||||
| 							value = fields[x].checked ? '1' : '0'; | 							value = fields[x].checked ? '1' : '0'; | ||||||
| 						break; | 							break; | ||||||
| 					} | 					} | ||||||
| 				} else if (fields[x].nodeName === 'TEXTAREA') { | 				} else if (fields[x].nodeName === 'TEXTAREA') { | ||||||
| 					value = fields[x].value; | 					value = fields[x].value; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				socket.emit('api:config.set', { key: key, value: value }); | 				socket.emit('api:config.set', { | ||||||
|  | 					key: key, | ||||||
|  | 					value: value | ||||||
|  | 				}); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| @@ -82,7 +82,7 @@ var nodebb_admin = (function(nodebb_admin) { | |||||||
| 		menuEl.addEventListener('click', function(e) { | 		menuEl.addEventListener('click', function(e) { | ||||||
| 			parentEl = e.target.parentNode; | 			parentEl = e.target.parentNode; | ||||||
| 			if (parentEl.nodeName === 'LI') { | 			if (parentEl.nodeName === 'LI') { | ||||||
| 				for(var x=0,numLis=liEls.length;x<numLis;x++) { | 				for (var x = 0, numLis = liEls.length; x < numLis; x++) { | ||||||
| 					if (liEls[x] !== parentEl) jQuery(liEls[x]).removeClass('active'); | 					if (liEls[x] !== parentEl) jQuery(liEls[x]).removeClass('active'); | ||||||
| 					else jQuery(parentEl).addClass('active'); | 					else jQuery(parentEl).addClass('active'); | ||||||
| 				} | 				} | ||||||
| @@ -119,4 +119,3 @@ var nodebb_admin = (function(nodebb_admin) { | |||||||
| 	return nodebb_admin; | 	return nodebb_admin; | ||||||
|  |  | ||||||
| }(nodebb_admin || {})); | }(nodebb_admin || {})); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| $(document).ready(function() { | $(document).ready(function() { | ||||||
| 	var	createEl = document.getElementById('create'), | 	var createEl = document.getElementById('create'), | ||||||
| 		createModal = $('#create-modal'), | 		createModal = $('#create-modal'), | ||||||
| 		createSubmitBtn = document.getElementById('create-modal-go'), | 		createSubmitBtn = document.getElementById('create-modal-go'), | ||||||
| 		createNameEl = $('#create-group-name'), | 		createNameEl = $('#create-group-name'), | ||||||
| @@ -19,25 +19,25 @@ $(document).ready(function() { | |||||||
| 	}, false); | 	}, false); | ||||||
|  |  | ||||||
| 	createSubmitBtn.addEventListener('click', function() { | 	createSubmitBtn.addEventListener('click', function() { | ||||||
| 		var	submitObj = { | 		var submitObj = { | ||||||
| 				name: createNameEl.val(), | 			name: createNameEl.val(), | ||||||
| 				description: $('#create-group-desc').val() | 			description: $('#create-group-desc').val() | ||||||
| 			}, | 		}, | ||||||
| 			errorEl = $('#create-modal-error'), | 			errorEl = $('#create-modal-error'), | ||||||
| 			errorText; | 			errorText; | ||||||
|  |  | ||||||
| 		socket.emit('api:groups.create', submitObj, function(err, data) { | 		socket.emit('api:groups.create', submitObj, function(err, data) { | ||||||
| 			if (err) { | 			if (err) { | ||||||
| 				switch(err) { | 				switch (err) { | ||||||
| 					case 'group-exists': | 					case 'group-exists': | ||||||
| 						errorText = '<strong>Please choose another name</strong><p>There seems to be a group with this name already.</p>'; | 						errorText = '<strong>Please choose another name</strong><p>There seems to be a group with this name already.</p>'; | ||||||
| 					break; | 						break; | ||||||
| 					case 'name-too-short': | 					case 'name-too-short': | ||||||
| 						errorText = '<strong>Please specify a grou name</strong><p>A group name is required for administrative purposes.</p>'; | 						errorText = '<strong>Please specify a grou name</strong><p>A group name is required for administrative purposes.</p>'; | ||||||
| 					break; | 						break; | ||||||
| 					default: | 					default: | ||||||
| 						errorText = '<strong>Uh-Oh</strong><p>There was a problem creating your group. Please try again later!</p>'; | 						errorText = '<strong>Uh-Oh</strong><p>There was a problem creating your group. Please try again later!</p>'; | ||||||
| 					break; | 						break; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				errorEl.html(errorText).removeClass('hide'); | 				errorEl.html(errorText).removeClass('hide'); | ||||||
| @@ -51,10 +51,10 @@ $(document).ready(function() { | |||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	listEl.on('click', 'button[data-action]', function() { | 	listEl.on('click', 'button[data-action]', function() { | ||||||
| 		var	action = this.getAttribute('data-action'), | 		var action = this.getAttribute('data-action'), | ||||||
| 			gid = $(this).parents('li[data-gid]').attr('data-gid'); | 			gid = $(this).parents('li[data-gid]').attr('data-gid'); | ||||||
|  |  | ||||||
| 		switch(action) { | 		switch (action) { | ||||||
| 			case 'delete': | 			case 'delete': | ||||||
| 				bootbox.confirm('Are you sure you wish to delete this group?', function(confirm) { | 				bootbox.confirm('Are you sure you wish to delete this group?', function(confirm) { | ||||||
| 					if (confirm) { | 					if (confirm) { | ||||||
| @@ -63,10 +63,10 @@ $(document).ready(function() { | |||||||
| 						}); | 						}); | ||||||
| 					} | 					} | ||||||
| 				}); | 				}); | ||||||
| 			break; | 				break; | ||||||
| 			case 'members': | 			case 'members': | ||||||
| 				socket.emit('api:groups.get', gid, function(err, groupObj) { | 				socket.emit('api:groups.get', gid, function(err, groupObj) { | ||||||
| 					var	formEl = detailsModal.find('form'), | 					var formEl = detailsModal.find('form'), | ||||||
| 						nameEl = formEl.find('#change-group-name'), | 						nameEl = formEl.find('#change-group-name'), | ||||||
| 						descEl = formEl.find('#change-group-desc'), | 						descEl = formEl.find('#change-group-desc'), | ||||||
| 						memberIcon = document.createElement('li'), | 						memberIcon = document.createElement('li'), | ||||||
| @@ -83,7 +83,7 @@ $(document).ready(function() { | |||||||
| 					memberIconImg = memberIcon.querySelector('img'); | 					memberIconImg = memberIcon.querySelector('img'); | ||||||
| 					memberIconLabel = memberIcon.querySelector('span'); | 					memberIconLabel = memberIcon.querySelector('span'); | ||||||
| 					if (numMembers > 0) { | 					if (numMembers > 0) { | ||||||
| 						for(x=0;x<numMembers;x++) { | 						for (x = 0; x < numMembers; x++) { | ||||||
| 							memberIconImg.src = groupObj.members[x].picture; | 							memberIconImg.src = groupObj.members[x].picture; | ||||||
| 							memberIconLabel.innerHTML = groupObj.members[x].username; | 							memberIconLabel.innerHTML = groupObj.members[x].username; | ||||||
| 							memberIcon.setAttribute('data-uid', groupObj.members[x].uid); | 							memberIcon.setAttribute('data-uid', groupObj.members[x].uid); | ||||||
| @@ -96,17 +96,17 @@ $(document).ready(function() { | |||||||
| 					detailsModal.attr('data-gid', groupObj.gid); | 					detailsModal.attr('data-gid', groupObj.gid); | ||||||
| 					detailsModal.modal('show'); | 					detailsModal.modal('show'); | ||||||
| 				}); | 				}); | ||||||
| 			break; | 				break; | ||||||
| 		} | 		} | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	detailsSearch.on('keyup', function() { | 	detailsSearch.on('keyup', function() { | ||||||
| 		var	searchEl = this; | 		var searchEl = this; | ||||||
|  |  | ||||||
| 		if (searchDelay) clearTimeout(searchDelay); | 		if (searchDelay) clearTimeout(searchDelay); | ||||||
|  |  | ||||||
| 		searchDelay = setTimeout(function() { | 		searchDelay = setTimeout(function() { | ||||||
| 			var	searchText = searchEl.value, | 			var searchText = searchEl.value, | ||||||
| 				resultsEl = document.getElementById('group-details-search-results'), | 				resultsEl = document.getElementById('group-details-search-results'), | ||||||
| 				foundUser = document.createElement('li'), | 				foundUser = document.createElement('li'), | ||||||
| 				foundUserImg, foundUserLabel; | 				foundUserImg, foundUserLabel; | ||||||
| @@ -117,11 +117,11 @@ $(document).ready(function() { | |||||||
|  |  | ||||||
| 			socket.emit('api:admin.user.search', searchText, function(err, results) { | 			socket.emit('api:admin.user.search', searchText, function(err, results) { | ||||||
| 				if (!err && results && results.length > 0) { | 				if (!err && results && results.length > 0) { | ||||||
| 					var	numResults = results.length, | 					var numResults = results.length, | ||||||
| 						resultsSlug = document.createDocumentFragment(), | 						resultsSlug = document.createDocumentFragment(), | ||||||
| 						x; | 						x; | ||||||
| 					if (numResults > 4) numResults = 4; | 					if (numResults > 4) numResults = 4; | ||||||
| 					for(x=0;x<numResults;x++) { | 					for (x = 0; x < numResults; x++) { | ||||||
| 						foundUserImg.src = results[x].picture; | 						foundUserImg.src = results[x].picture; | ||||||
| 						foundUserLabel.innerHTML = results[x].username; | 						foundUserLabel.innerHTML = results[x].username; | ||||||
| 						foundUser.setAttribute('title', results[x].username); | 						foundUser.setAttribute('title', results[x].username); | ||||||
| @@ -137,7 +137,7 @@ $(document).ready(function() { | |||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	searchResults.on('click', 'li[data-uid]', function() { | 	searchResults.on('click', 'li[data-uid]', function() { | ||||||
| 		var	userLabel = this, | 		var userLabel = this, | ||||||
| 			uid = parseInt(this.getAttribute('data-uid')), | 			uid = parseInt(this.getAttribute('data-uid')), | ||||||
| 			gid = detailsModal.attr('data-gid'), | 			gid = detailsModal.attr('data-gid'), | ||||||
| 			members = []; | 			members = []; | ||||||
| @@ -159,7 +159,7 @@ $(document).ready(function() { | |||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	groupMembersEl.on('click', 'li[data-uid]', function() { | 	groupMembersEl.on('click', 'li[data-uid]', function() { | ||||||
| 		var	uid = this.getAttribute('data-uid'), | 		var uid = this.getAttribute('data-uid'), | ||||||
| 			gid = detailsModal.attr('data-gid'); | 			gid = detailsModal.attr('data-gid'); | ||||||
|  |  | ||||||
| 		socket.emit('api:groups.leave', { | 		socket.emit('api:groups.leave', { | ||||||
| @@ -173,7 +173,7 @@ $(document).ready(function() { | |||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	detailsModalSave.on('click', function() { | 	detailsModalSave.on('click', function() { | ||||||
| 		var	formEl = detailsModal.find('form'), | 		var formEl = detailsModal.find('form'), | ||||||
| 			nameEl = formEl.find('#change-group-name'), | 			nameEl = formEl.find('#change-group-name'), | ||||||
| 			descEl = formEl.find('#change-group-desc'), | 			descEl = formEl.find('#change-group-desc'), | ||||||
| 			gid = detailsModal.attr('data-gid'); | 			gid = detailsModal.attr('data-gid'); | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
| 			total = 0; | 			total = 0; | ||||||
| 			active_users.innerHTML = ''; | 			active_users.innerHTML = ''; | ||||||
|  |  | ||||||
| 		for(var room in data) { | 		for (var room in data) { | ||||||
| 			if (room !== '') { | 			if (room !== '') { | ||||||
| 				var count = data[room].length; | 				var count = data[room].length; | ||||||
| 				total += count; | 				total += count; | ||||||
|   | |||||||
| @@ -1,35 +1,35 @@ | |||||||
| var	nodebb_admin = nodebb_admin || {}; | var nodebb_admin = nodebb_admin || {}; | ||||||
|  |  | ||||||
| (function() { | (function() { | ||||||
| 	var	plugins = { | 	var plugins = { | ||||||
| 			init: function() { | 		init: function() { | ||||||
| 				var	pluginsList = $('.plugins'), | 			var pluginsList = $('.plugins'), | ||||||
| 					numPlugins = pluginsList[0].querySelectorAll('li').length, | 				numPlugins = pluginsList[0].querySelectorAll('li').length, | ||||||
| 					pluginID, pluginTgl; | 				pluginID, pluginTgl; | ||||||
|  |  | ||||||
| 				if (numPlugins > 0) { | 			if (numPlugins > 0) { | ||||||
| 					pluginsList.on('click', 'button[data-action="toggleActive"]', function() { | 				pluginsList.on('click', 'button[data-action="toggleActive"]', function() { | ||||||
| 						pluginID = $(this).parents('li').attr('data-plugin-id'); | 					pluginID = $(this).parents('li').attr('data-plugin-id'); | ||||||
| 						socket.emit('api:admin.plugins.toggle', pluginID); | 					socket.emit('api:admin.plugins.toggle', pluginID); | ||||||
| 					}); | 				}); | ||||||
|  |  | ||||||
| 					socket.on('api:admin.plugins.toggle', function(status) { | 				socket.on('api:admin.plugins.toggle', function(status) { | ||||||
| 						pluginTgl = document.querySelector('.plugins li[data-plugin-id="' + status.id + '"] button'); | 					pluginTgl = document.querySelector('.plugins li[data-plugin-id="' + status.id + '"] button'); | ||||||
| 						pluginTgl.innerHTML = '<i class="icon-off"></i> ' + (status.active ? 'Dea' : 'A') + 'ctivate'; | 					pluginTgl.innerHTML = '<i class="icon-off"></i> ' + (status.active ? 'Dea' : 'A') + 'ctivate'; | ||||||
|  |  | ||||||
| 						app.alert({ | 					app.alert({ | ||||||
| 							alert_id: 'plugin_toggled_' + status.id, | 						alert_id: 'plugin_toggled_' + status.id, | ||||||
| 							title: 'Plugin Enabled', | 						title: 'Plugin Enabled', | ||||||
| 							message: 'You may need to restart NodeBB in order for these changes to be reflected.', | 						message: 'You may need to restart NodeBB in order for these changes to be reflected.', | ||||||
| 							type: 'warning', | 						type: 'warning', | ||||||
| 							timeout: 5000 | 						timeout: 5000 | ||||||
| 						}) | 					}) | ||||||
| 					}); | 				}); | ||||||
| 				} else { | 			} else { | ||||||
| 					pluginsList.append('<li><p><i>No plugins found.</i></p></li>'); | 				pluginsList.append('<li><p><i>No plugins found.</i></p></li>'); | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
| 		}; | 		} | ||||||
|  | 	}; | ||||||
|  |  | ||||||
| 	jQuery(document).ready(function() { | 	jQuery(document).ready(function() { | ||||||
| 		nodebb_admin.plugins = plugins; | 		nodebb_admin.plugins = plugins; | ||||||
|   | |||||||
| @@ -1,5 +1,3 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| var nodebb_admin = (function(nodebb_admin) { | var nodebb_admin = (function(nodebb_admin) { | ||||||
|  |  | ||||||
| 	var themes = {}; | 	var themes = {}; | ||||||
| @@ -10,20 +8,20 @@ var nodebb_admin = (function(nodebb_admin) { | |||||||
| 			themeContainer = document.querySelector('#bootstrap_themes'), | 			themeContainer = document.querySelector('#bootstrap_themes'), | ||||||
| 			numThemes = bootswatch.themes.length; | 			numThemes = bootswatch.themes.length; | ||||||
|  |  | ||||||
| 		for(var x=0;x<numThemes;x++) { | 		for (var x = 0; x < numThemes; x++) { | ||||||
| 			var theme = bootswatch.themes[x]; | 			var theme = bootswatch.themes[x]; | ||||||
| 			themeEl.setAttribute('data-css', theme.cssMin); | 			themeEl.setAttribute('data-css', theme.cssMin); | ||||||
| 			themeEl.setAttribute('data-theme', theme.name); | 			themeEl.setAttribute('data-theme', theme.name); | ||||||
| 			themeEl.innerHTML =	'<img src="' + theme.thumbnail + '" />' + | 			themeEl.innerHTML = '<img src="' + theme.thumbnail + '" />' + | ||||||
| 								'<div>' + | 				'<div>' + | ||||||
| 									'<div class="pull-right">' + | 				'<div class="pull-right">' + | ||||||
| 										'<button class="btn btn-primary" data-action="use">Use</button> ' + | 				'<button class="btn btn-primary" data-action="use">Use</button> ' + | ||||||
| 										'<button class="btn btn-default" data-action="preview">Preview</button>' + | 				'<button class="btn btn-default" data-action="preview">Preview</button>' + | ||||||
| 									'</div>' + | 				'</div>' + | ||||||
| 									'<h4>' + theme.name + '</h4>' + | 				'<h4>' + theme.name + '</h4>' + | ||||||
| 									'<p>' + theme.description + '</p>' + | 				'<p>' + theme.description + '</p>' + | ||||||
| 								'</div>' + | 				'</div>' + | ||||||
| 								'<div class="clear">'; | 				'<div class="clear">'; | ||||||
| 			themeFrag.appendChild(themeEl.cloneNode(true)); | 			themeFrag.appendChild(themeEl.cloneNode(true)); | ||||||
| 		} | 		} | ||||||
| 		themeContainer.innerHTML = ''; | 		themeContainer.innerHTML = ''; | ||||||
| @@ -42,28 +40,30 @@ var nodebb_admin = (function(nodebb_admin) { | |||||||
| 	scriptEl.src = 'http://api.bootswatch.com/3/?callback=nodebb_admin.themes.render'; | 	scriptEl.src = 'http://api.bootswatch.com/3/?callback=nodebb_admin.themes.render'; | ||||||
| 	document.body.appendChild(scriptEl); | 	document.body.appendChild(scriptEl); | ||||||
|  |  | ||||||
| 	var	bootstrapThemeContainer = document.querySelector('#bootstrap_themes'), | 	var bootstrapThemeContainer = document.querySelector('#bootstrap_themes'), | ||||||
| 		installedThemeContainer = document.querySelector('#installed_themes'), | 		installedThemeContainer = document.querySelector('#installed_themes'), | ||||||
| 		themeEvent = function(e) { | 		themeEvent = function(e) { | ||||||
| 			if (e.target.hasAttribute('data-action')) { | 			if (e.target.hasAttribute('data-action')) { | ||||||
| 				switch(e.target.getAttribute('data-action')) { | 				switch (e.target.getAttribute('data-action')) { | ||||||
| 					case 'preview': | 					case 'preview': | ||||||
| 						var	cssSrc = $(e.target).parents('li').attr('data-css'), | 						var cssSrc = $(e.target).parents('li').attr('data-css'), | ||||||
| 							cssEl = document.getElementById('base-theme'); | 							cssEl = document.getElementById('base-theme'); | ||||||
|  |  | ||||||
| 						cssEl.href = cssSrc; | 						cssEl.href = cssSrc; | ||||||
| 					break; | 						break; | ||||||
| 					case 'use': | 					case 'use': | ||||||
| 						var	parentEl = $(e.target).parents('li'), | 						var parentEl = $(e.target).parents('li'), | ||||||
| 							cssSrc = parentEl.attr('data-css'), | 							cssSrc = parentEl.attr('data-css'), | ||||||
| 							cssName = parentEl.attr('data-theme'); | 							cssName = parentEl.attr('data-theme'); | ||||||
| 						socket.emit('api:config.set', { | 						socket.emit('api:config.set', { | ||||||
| 							key: 'theme:id', value: 'bootswatch:' + cssName | 							key: 'theme:id', | ||||||
|  | 							value: 'bootswatch:' + cssName | ||||||
| 						}); | 						}); | ||||||
| 						socket.emit('api:config.set', { | 						socket.emit('api:config.set', { | ||||||
| 							key: 'theme:src', value: cssSrc | 							key: 'theme:src', | ||||||
|  | 							value: cssSrc | ||||||
| 						}); | 						}); | ||||||
| 					break; | 						break; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		}; | 		}; | ||||||
| @@ -82,27 +82,27 @@ var nodebb_admin = (function(nodebb_admin) { | |||||||
|  |  | ||||||
| 	// Installed Themes | 	// Installed Themes | ||||||
| 	socket.emit('api:admin.themes.getInstalled', function(themes) { | 	socket.emit('api:admin.themes.getInstalled', function(themes) { | ||||||
| 		var	instListEl = document.getElementById('installed_themes'), | 		var instListEl = document.getElementById('installed_themes'), | ||||||
| 			themeFrag = document.createDocumentFragment(), | 			themeFrag = document.createDocumentFragment(), | ||||||
| 			liEl = document.createElement('li'); | 			liEl = document.createElement('li'); | ||||||
|  |  | ||||||
| 		if (themes.length > 0) { | 		if (themes.length > 0) { | ||||||
| 			for(var x=0,numThemes=themes.length;x<numThemes;x++) { | 			for (var x = 0, numThemes = themes.length; x < numThemes; x++) { | ||||||
| 				liEl.setAttribute('data-theme', themes[x].id); | 				liEl.setAttribute('data-theme', themes[x].id); | ||||||
| 				liEl.setAttribute('data-css', themes[x].src); | 				liEl.setAttribute('data-css', themes[x].src); | ||||||
| 				liEl.innerHTML =	'<img src="' + themes[x].screenshot + '" />' + | 				liEl.innerHTML = '<img src="' + themes[x].screenshot + '" />' + | ||||||
| 									'<div>' + | 					'<div>' + | ||||||
| 										'<div class="pull-right">' + | 					'<div class="pull-right">' + | ||||||
| 											'<button class="btn btn-primary" data-action="use">Use</button> ' + | 					'<button class="btn btn-primary" data-action="use">Use</button> ' + | ||||||
| 											'<button class="btn btn-default" data-action="preview">Preview</button>' + | 					'<button class="btn btn-default" data-action="preview">Preview</button>' + | ||||||
| 										'</div>' + | 					'</div>' + | ||||||
| 										'<h4>' + themes[x].name + '</h4>' + | 					'<h4>' + themes[x].name + '</h4>' + | ||||||
| 										'<p>' + | 					'<p>' + | ||||||
| 											themes[x].description + | 					themes[x].description + | ||||||
| 											(themes[x].url ? ' (<a href="' + themes[x].url + '">Homepage</a>)' : '') + | 					(themes[x].url ? ' (<a href="' + themes[x].url + '">Homepage</a>)' : '') + | ||||||
| 										'</p>' + | 					'</p>' + | ||||||
| 									'</div>' + | 					'</div>' + | ||||||
| 									'<div class="clear">'; | 					'<div class="clear">'; | ||||||
| 				themeFrag.appendChild(liEl.cloneNode(true)); | 				themeFrag.appendChild(liEl.cloneNode(true)); | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
|   | |||||||
| @@ -7,25 +7,37 @@ $(document).ready(function() { | |||||||
| 			action = this.getAttribute('data-action'), | 			action = this.getAttribute('data-action'), | ||||||
| 			tid = $this.parents('[data-tid]').attr('data-tid'); | 			tid = $this.parents('[data-tid]').attr('data-tid'); | ||||||
|  |  | ||||||
| 		switch(action) { | 		switch (action) { | ||||||
| 			case 'pin': | 			case 'pin': | ||||||
| 				if (!$this.hasClass('active')) socket.emit('api:topic.pin', { tid: tid }); | 				if (!$this.hasClass('active')) socket.emit('api:topic.pin', { | ||||||
| 				else socket.emit('api:topic.unpin', { tid: tid }); | 					tid: tid | ||||||
| 			break; | 				}); | ||||||
|  | 				else socket.emit('api:topic.unpin', { | ||||||
|  | 					tid: tid | ||||||
|  | 				}); | ||||||
|  | 				break; | ||||||
| 			case 'lock': | 			case 'lock': | ||||||
| 				if (!$this.hasClass('active')) socket.emit('api:topic.lock', { tid: tid }); | 				if (!$this.hasClass('active')) socket.emit('api:topic.lock', { | ||||||
| 				else socket.emit('api:topic.unlock', { tid: tid }); | 					tid: tid | ||||||
| 			break; | 				}); | ||||||
|  | 				else socket.emit('api:topic.unlock', { | ||||||
|  | 					tid: tid | ||||||
|  | 				}); | ||||||
|  | 				break; | ||||||
| 			case 'delete': | 			case 'delete': | ||||||
| 				if (!$this.hasClass('active')) socket.emit('api:topic.delete', { tid: tid }); | 				if (!$this.hasClass('active')) socket.emit('api:topic.delete', { | ||||||
| 				else socket.emit('api:topic.restore', { tid: tid }); | 					tid: tid | ||||||
| 			break; | 				}); | ||||||
|  | 				else socket.emit('api:topic.restore', { | ||||||
|  | 					tid: tid | ||||||
|  | 				}); | ||||||
|  | 				break; | ||||||
| 		} | 		} | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	loadMoreEl.addEventListener('click', function() { | 	loadMoreEl.addEventListener('click', function() { | ||||||
| 		if (this.className.indexOf('disabled') === -1) { | 		if (this.className.indexOf('disabled') === -1) { | ||||||
| 			var	topics = document.querySelectorAll('.topics li[data-tid]'), | 			var topics = document.querySelectorAll('.topics li[data-tid]'), | ||||||
| 				lastTid = parseInt(topics[topics.length - 1].getAttribute('data-tid')); | 				lastTid = parseInt(topics[topics.length - 1].getAttribute('data-tid')); | ||||||
|  |  | ||||||
| 			this.innerHTML = '<i class="icon-refresh icon-spin"></i> Retrieving topics'; | 			this.innerHTML = '<i class="icon-refresh icon-spin"></i> Retrieving topics'; | ||||||
| @@ -37,9 +49,9 @@ $(document).ready(function() { | |||||||
|  |  | ||||||
| 				topics = JSON.parse(topics); | 				topics = JSON.parse(topics); | ||||||
| 				if (topics.length > 0) { | 				if (topics.length > 0) { | ||||||
| 					var	html = templates.prepare(templates['admin/topics'].blocks['topics']).parse({ | 					var html = templates.prepare(templates['admin/topics'].blocks['topics']).parse({ | ||||||
| 							topics: topics | 						topics: topics | ||||||
| 						}), | 					}), | ||||||
| 						topicsListEl = document.querySelector('.topics'); | 						topicsListEl = document.querySelector('.topics'); | ||||||
|  |  | ||||||
| 					topicsListEl.innerHTML += html; | 					topicsListEl.innerHTML += html; | ||||||
| @@ -54,9 +66,9 @@ $(document).ready(function() { | |||||||
| 	}, false); | 	}, false); | ||||||
|  |  | ||||||
| 	// Resolve proper button state for all topics | 	// Resolve proper button state for all topics | ||||||
| 	var	topicEls = topicsListEl.querySelectorAll('li'), | 	var topicEls = topicsListEl.querySelectorAll('li'), | ||||||
| 		numTopics = topicEls.length; | 		numTopics = topicEls.length; | ||||||
| 	for(var x=0;x<numTopics;x++) { | 	for (var x = 0; x < numTopics; x++) { | ||||||
| 		if (topicEls[x].getAttribute('data-pinned') === '1') topicEls[x].querySelector('[data-action="pin"]').className += ' active'; | 		if (topicEls[x].getAttribute('data-pinned') === '1') topicEls[x].querySelector('[data-action="pin"]').className += ' active'; | ||||||
| 		if (topicEls[x].getAttribute('data-locked') === '1') topicEls[x].querySelector('[data-action="lock"]').className += ' active'; | 		if (topicEls[x].getAttribute('data-locked') === '1') topicEls[x].querySelector('[data-action="lock"]').className += ' active'; | ||||||
| 		if (topicEls[x].getAttribute('data-deleted') === '1') topicEls[x].querySelector('[data-action="delete"]').className += ' active'; | 		if (topicEls[x].getAttribute('data-deleted') === '1') topicEls[x].querySelector('[data-action="delete"]').className += ' active'; | ||||||
|   | |||||||
| @@ -1,4 +1,3 @@ | |||||||
|  |  | ||||||
| (function() { | (function() { | ||||||
|  |  | ||||||
| 	var yourid = templates.get('yourid'); | 	var yourid = templates.get('yourid'); | ||||||
| @@ -24,19 +23,19 @@ | |||||||
| 			var adminBtn = $(element); | 			var adminBtn = $(element); | ||||||
| 			var uid = getUID(adminBtn); | 			var uid = getUID(adminBtn); | ||||||
|  |  | ||||||
| 			if(isUserAdmin(adminBtn)) | 			if (isUserAdmin(adminBtn)) | ||||||
| 				adminBtn.addClass('btn-success'); | 				adminBtn.addClass('btn-success'); | ||||||
| 			else | 			else | ||||||
| 				adminBtn.removeClass('btn-success'); | 				adminBtn.removeClass('btn-success'); | ||||||
|  |  | ||||||
| 			if(uid === yourid) | 			if (uid === yourid) | ||||||
| 				adminBtn.addClass('disabled'); | 				adminBtn.addClass('disabled'); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		jQuery('.delete-btn').each(function(index, element) { | 		jQuery('.delete-btn').each(function(index, element) { | ||||||
| 			var deleteBtn = $(element); | 			var deleteBtn = $(element); | ||||||
|  |  | ||||||
| 			if(isUserAdmin(deleteBtn)) | 			if (isUserAdmin(deleteBtn)) | ||||||
| 				deleteBtn.addClass('disabled'); | 				deleteBtn.addClass('disabled'); | ||||||
| 			else | 			else | ||||||
| 				deleteBtn.show(); | 				deleteBtn.show(); | ||||||
| @@ -45,9 +44,9 @@ | |||||||
| 		jQuery('.ban-btn').each(function(index, element) { | 		jQuery('.ban-btn').each(function(index, element) { | ||||||
| 			var banBtn = $(element); | 			var banBtn = $(element); | ||||||
|  |  | ||||||
| 			if(isUserAdmin(banBtn)) | 			if (isUserAdmin(banBtn)) | ||||||
| 				banBtn.addClass('disabled'); | 				banBtn.addClass('disabled'); | ||||||
| 			else if(isUserBanned(banBtn)) | 			else if (isUserBanned(banBtn)) | ||||||
| 				banBtn.addClass('btn-warning'); | 				banBtn.addClass('btn-warning'); | ||||||
| 			else | 			else | ||||||
| 				banBtn.removeClass('btn-warning'); | 				banBtn.removeClass('btn-warning'); | ||||||
| @@ -65,14 +64,14 @@ | |||||||
| 			var parent = adminBtn.parents('.users-box'); | 			var parent = adminBtn.parents('.users-box'); | ||||||
| 			var uid = getUID(adminBtn); | 			var uid = getUID(adminBtn); | ||||||
|  |  | ||||||
| 			if(isAdmin && uid != yourid) { | 			if (isAdmin && uid != yourid) { | ||||||
| 				socket.emit('api:admin.user.removeAdmin', uid); | 				socket.emit('api:admin.user.removeAdmin', uid); | ||||||
| 				adminBtn.removeClass('btn-success'); | 				adminBtn.removeClass('btn-success'); | ||||||
| 				parent.find('.delete-btn').removeClass('disabled'); | 				parent.find('.delete-btn').removeClass('disabled'); | ||||||
| 				parent.attr('data-admin', 0); | 				parent.attr('data-admin', 0); | ||||||
| 			} else if(uid != yourid) { | 			} else if (uid != yourid) { | ||||||
| 				bootbox.confirm('Do you really want to make "' + parent.attr('data-username') +'" an admin?', function(confirm) { | 				bootbox.confirm('Do you really want to make "' + parent.attr('data-username') + '" an admin?', function(confirm) { | ||||||
| 					if(confirm) { | 					if (confirm) { | ||||||
| 						socket.emit('api:admin.user.makeAdmin', uid); | 						socket.emit('api:admin.user.makeAdmin', uid); | ||||||
| 						adminBtn.addClass('btn-success'); | 						adminBtn.addClass('btn-success'); | ||||||
| 						parent.find('.delete-btn').addClass('disabled'); | 						parent.find('.delete-btn').addClass('disabled'); | ||||||
| @@ -90,8 +89,8 @@ | |||||||
| 			var parent = deleteBtn.parents('.users-box'); | 			var parent = deleteBtn.parents('.users-box'); | ||||||
| 			var uid = getUID(deleteBtn); | 			var uid = getUID(deleteBtn); | ||||||
|  |  | ||||||
| 			if(!isAdmin) { | 			if (!isAdmin) { | ||||||
| 				bootbox.confirm('Do you really want to delete "' + parent.attr('data-username') +'"?', function(confirm) { | 				bootbox.confirm('Do you really want to delete "' + parent.attr('data-username') + '"?', function(confirm) { | ||||||
| 					if (confirm) { | 					if (confirm) { | ||||||
| 						socket.emit('api:admin.user.deleteUser', uid); | 						socket.emit('api:admin.user.deleteUser', uid); | ||||||
| 					} | 					} | ||||||
| @@ -108,13 +107,13 @@ | |||||||
| 			var parent = banBtn.parents('.users-box'); | 			var parent = banBtn.parents('.users-box'); | ||||||
| 			var uid = getUID(banBtn); | 			var uid = getUID(banBtn); | ||||||
|  |  | ||||||
| 			if(!isAdmin) { | 			if (!isAdmin) { | ||||||
| 				if(isBanned) { | 				if (isBanned) { | ||||||
| 					socket.emit('api:admin.user.unbanUser', uid); | 					socket.emit('api:admin.user.unbanUser', uid); | ||||||
| 					banBtn.removeClass('btn-warning'); | 					banBtn.removeClass('btn-warning'); | ||||||
| 					parent.attr('data-banned', 0); | 					parent.attr('data-banned', 0); | ||||||
| 				} else { | 				} else { | ||||||
| 					bootbox.confirm('Do you really want to ban "' + parent.attr('data-username') +'"?', function(confirm) { | 					bootbox.confirm('Do you really want to ban "' + parent.attr('data-username') + '"?', function(confirm) { | ||||||
| 						if (confirm) { | 						if (confirm) { | ||||||
| 							socket.emit('api:admin.user.banUser', uid); | 							socket.emit('api:admin.user.banUser', uid); | ||||||
| 							banBtn.addClass('btn-warning'); | 							banBtn.addClass('btn-warning'); | ||||||
| @@ -136,7 +135,7 @@ | |||||||
|  |  | ||||||
| 		var url = window.location.href, | 		var url = window.location.href, | ||||||
| 			parts = url.split('/'), | 			parts = url.split('/'), | ||||||
| 			active = parts[parts.length-1]; | 			active = parts[parts.length - 1]; | ||||||
|  |  | ||||||
| 		jQuery('.nav-pills li').removeClass('active'); | 		jQuery('.nav-pills li').removeClass('active'); | ||||||
| 		jQuery('.nav-pills li a').each(function() { | 		jQuery('.nav-pills li a').each(function() { | ||||||
| @@ -146,8 +145,8 @@ | |||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		jQuery('#search-user').on('keyup', function () { | 		jQuery('#search-user').on('keyup', function() { | ||||||
| 			if(timeoutId !== 0) { | 			if (timeoutId !== 0) { | ||||||
| 				clearTimeout(timeoutId); | 				clearTimeout(timeoutId); | ||||||
| 				timeoutId = 0; | 				timeoutId = 0; | ||||||
| 			} | 			} | ||||||
| @@ -167,21 +166,20 @@ | |||||||
|  |  | ||||||
| 		socket.on('api:admin.user.search', function(data) { | 		socket.on('api:admin.user.search', function(data) { | ||||||
| 			var html = templates.prepare(templates['admin/users'].blocks['users']).parse({ | 			var html = templates.prepare(templates['admin/users'].blocks['users']).parse({ | ||||||
| 					users: data | 				users: data | ||||||
| 				}), | 			}), | ||||||
| 				userListEl = document.querySelector('.users'); | 				userListEl = document.querySelector('.users'); | ||||||
|  |  | ||||||
| 			userListEl.innerHTML = html; | 			userListEl.innerHTML = html; | ||||||
| 			jQuery('.icon-spinner').addClass('none'); | 			jQuery('.icon-spinner').addClass('none'); | ||||||
|  |  | ||||||
| 			if(data && data.length === 0) { | 			if (data && data.length === 0) { | ||||||
| 				$('#user-notfound-notify').html('User not found!') | 				$('#user-notfound-notify').html('User not found!') | ||||||
| 					.show() | 					.show() | ||||||
| 					.addClass('label-danger') | 					.addClass('label-danger') | ||||||
| 					.removeClass('label-success'); | 					.removeClass('label-success'); | ||||||
| 			} | 			} else { | ||||||
| 			else { | 				$('#user-notfound-notify').html(data.length + ' user' + (data.length > 1 ? 's' : '') + ' found!') | ||||||
| 				$('#user-notfound-notify').html(data.length + ' user'+(data.length>1?'s':'') + ' found!') |  | ||||||
| 					.show() | 					.show() | ||||||
| 					.addClass('label-success') | 					.addClass('label-success') | ||||||
| 					.removeClass('label-danger'); | 					.removeClass('label-danger'); | ||||||
| @@ -191,28 +189,30 @@ | |||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		function onUsersLoaded(users) { | 		function onUsersLoaded(users) { | ||||||
| 			var html = templates.prepare(templates['admin/users'].blocks['users']).parse({ users: users }); | 			var html = templates.prepare(templates['admin/users'].blocks['users']).parse({ | ||||||
|  | 				users: users | ||||||
|  | 			}); | ||||||
| 			$('#users-container').append(html); | 			$('#users-container').append(html); | ||||||
| 			updateUserButtons(); | 			updateUserButtons(); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		function loadMoreUsers() { | 		function loadMoreUsers() { | ||||||
| 			var set = ''; | 			var set = ''; | ||||||
| 			if(active === 'latest') { | 			if (active === 'latest') { | ||||||
| 				set = 'users:joindate'; | 				set = 'users:joindate'; | ||||||
| 			} else if(active === 'sort-posts') { | 			} else if (active === 'sort-posts') { | ||||||
| 				set = 'users:postcount'; | 				set = 'users:postcount'; | ||||||
| 			} else if(active === 'sort-reputation') { | 			} else if (active === 'sort-reputation') { | ||||||
| 				set = 'users:reputation'; | 				set = 'users:reputation'; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if(set) { | 			if (set) { | ||||||
| 				loadingMoreUsers = true; | 				loadingMoreUsers = true; | ||||||
| 				socket.emit('api:users.loadMore', { | 				socket.emit('api:users.loadMore', { | ||||||
| 					set: set, | 					set: set, | ||||||
| 					after: $('#users-container').children().length | 					after: $('#users-container').children().length | ||||||
| 				}, function(data) { | 				}, function(data) { | ||||||
| 					if(data.users.length) { | 					if (data.users.length) { | ||||||
| 						onUsersLoaded(data.users); | 						onUsersLoaded(data.users); | ||||||
| 					} | 					} | ||||||
| 					loadingMoreUsers = false; | 					loadingMoreUsers = false; | ||||||
|   | |||||||
| @@ -36,7 +36,9 @@ | |||||||
| 	]); | 	]); | ||||||
|  |  | ||||||
| 	function onNewTopic(data) { | 	function onNewTopic(data) { | ||||||
| 		var html = templates.prepare(templates['category'].blocks['topics']).parse({ topics: [data] }), | 		var html = templates.prepare(templates['category'].blocks['topics']).parse({ | ||||||
|  | 			topics: [data] | ||||||
|  | 		}), | ||||||
| 			topic = document.createElement('div'), | 			topic = document.createElement('div'), | ||||||
| 			container = document.getElementById('topics-container'), | 			container = document.getElementById('topics-container'), | ||||||
| 			topics = document.querySelectorAll('#topics-container a'), | 			topics = document.querySelectorAll('#topics-container a'), | ||||||
| @@ -50,7 +52,7 @@ | |||||||
| 		topic = topic.querySelector('a'); | 		topic = topic.querySelector('a'); | ||||||
|  |  | ||||||
| 		if (numTopics > 0) { | 		if (numTopics > 0) { | ||||||
| 			for(x=0;x<numTopics;x++) { | 			for (x = 0; x < numTopics; x++) { | ||||||
| 				if (topics[x].querySelector('.icon-pushpin')) continue; | 				if (topics[x].querySelector('.icon-pushpin')) continue; | ||||||
| 				container.insertBefore(topic, topics[x]); | 				container.insertBefore(topic, topics[x]); | ||||||
| 				$(topic).hide().fadeIn('slow'); | 				$(topic).hide().fadeIn('slow'); | ||||||
| @@ -76,20 +78,20 @@ | |||||||
|  |  | ||||||
| 		recent_replies.innerHTML = ''; | 		recent_replies.innerHTML = ''; | ||||||
|  |  | ||||||
| 		var	frag = document.createDocumentFragment(), | 		var frag = document.createDocumentFragment(), | ||||||
| 			li = document.createElement('li'); | 			li = document.createElement('li'); | ||||||
| 		for (var i=0,numPosts=posts.length; i<numPosts; i++) { | 		for (var i = 0, numPosts = posts.length; i < numPosts; i++) { | ||||||
| 			var dateString = utils.relativeTime(posts[i].timestamp); | 			var dateString = utils.relativeTime(posts[i].timestamp); | ||||||
| 			li.setAttribute('data-pid', posts[i].pid); | 			li.setAttribute('data-pid', posts[i].pid); | ||||||
|  |  | ||||||
|  |  | ||||||
| 			li.innerHTML =	'<a href="/users/' + posts[i].userslug + '"><img title="' + posts[i].username + '" style="width: 48px; height: 48px; /*temporary*/" class="img-rounded" src="' + posts[i].picture + '" class="" /></a>' + | 			li.innerHTML = '<a href="/users/' + posts[i].userslug + '"><img title="' + posts[i].username + '" style="width: 48px; height: 48px; /*temporary*/" class="img-rounded" src="' + posts[i].picture + '" class="" /></a>' + | ||||||
| 								'<a href="/topic/'+ posts[i].topicSlug + '#' + posts[i].pid + '">' + | 				'<a href="/topic/' + posts[i].topicSlug + '#' + posts[i].pid + '">' + | ||||||
| 									'<p>' + | 				'<p>' + | ||||||
| 										posts[i].content + | 				posts[i].content + | ||||||
| 									'</p>' + | 				'</p>' + | ||||||
| 									'<span><strong>' + posts[i].username + '</strong> - ' + utils.relativeTime(posts[i].timestamp) + ' ago</span>' + | 				'<span><strong>' + posts[i].username + '</strong> - ' + utils.relativeTime(posts[i].timestamp) + ' ago</span>' + | ||||||
| 								'</a>'; | 				'</a>'; | ||||||
|  |  | ||||||
| 			frag.appendChild(li.cloneNode(true)); | 			frag.appendChild(li.cloneNode(true)); | ||||||
| 			recent_replies.appendChild(frag); | 			recent_replies.appendChild(frag); | ||||||
| @@ -98,7 +100,9 @@ | |||||||
|  |  | ||||||
| 	function onTopicsLoaded(topics) { | 	function onTopicsLoaded(topics) { | ||||||
|  |  | ||||||
| 		var html = templates.prepare(templates['category'].blocks['topics']).parse({ topics: topics }), | 		var html = templates.prepare(templates['category'].blocks['topics']).parse({ | ||||||
|  | 			topics: topics | ||||||
|  | 		}), | ||||||
| 			container = $('#topics-container'); | 			container = $('#topics-container'); | ||||||
|  |  | ||||||
| 		jQuery('#topics-container, .category-sidebar').removeClass('hidden'); | 		jQuery('#topics-container, .category-sidebar').removeClass('hidden'); | ||||||
| @@ -115,7 +119,7 @@ | |||||||
| 			cid: cid, | 			cid: cid, | ||||||
| 			after: $('#topics-container').children().length | 			after: $('#topics-container').children().length | ||||||
| 		}, function(data) { | 		}, function(data) { | ||||||
| 			if(data.topics.length) { | 			if (data.topics.length) { | ||||||
| 				onTopicsLoaded(data.topics); | 				onTopicsLoaded(data.topics); | ||||||
| 			} | 			} | ||||||
| 			loadingMoreTopics = false; | 			loadingMoreTopics = false; | ||||||
|   | |||||||
| @@ -1,11 +1,7 @@ | |||||||
| (function() { | (function() { | ||||||
|  |  | ||||||
| 	$(document).ready(function() { | 	$(document).ready(function() { | ||||||
|  |  | ||||||
| 		$('.user-favourite-posts .topic-row').on('click', function() { | 		$('.user-favourite-posts .topic-row').on('click', function() { | ||||||
| 			ajaxify.go($(this).attr('topic-url')); | 			ajaxify.go($(this).attr('topic-url')); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| }()); | }()); | ||||||
| @@ -6,7 +6,7 @@ | |||||||
|  |  | ||||||
| 	$(document).ready(function() { | 	$(document).ready(function() { | ||||||
|  |  | ||||||
| 		if(parseInt(followersCount, 10) === 0) { | 		if (parseInt(followersCount, 10) === 0) { | ||||||
| 			$('#no-followers-notice').removeClass('hide'); | 			$('#no-followers-notice').removeClass('hide'); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,22 +6,23 @@ | |||||||
|  |  | ||||||
| 	$(document).ready(function() { | 	$(document).ready(function() { | ||||||
|  |  | ||||||
| 		if(parseInt(followingCount, 10) === 0) { | 		if (parseInt(followingCount, 10) === 0) { | ||||||
| 			$('#no-following-notice').removeClass('hide'); | 			$('#no-following-notice').removeClass('hide'); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  |  | ||||||
| 		if(yourid !== theirid) { | 		if (yourid !== theirid) { | ||||||
| 			$('.unfollow-btn').hide(); | 			$('.unfollow-btn').hide(); | ||||||
| 		} | 		} else { | ||||||
| 		else { | 			$('.unfollow-btn').on('click', function() { | ||||||
| 			$('.unfollow-btn').on('click',function() { |  | ||||||
| 				var unfollowBtn = $(this); | 				var unfollowBtn = $(this); | ||||||
| 				var followingUid = $(this).attr('followingUid'); | 				var followingUid = $(this).attr('followingUid'); | ||||||
|  |  | ||||||
| 				socket.emit('api:user.unfollow', {uid: followingUid}, function(success) { | 				socket.emit('api:user.unfollow', { | ||||||
|  | 					uid: followingUid | ||||||
|  | 				}, function(success) { | ||||||
| 					var username = unfollowBtn.attr('data-username'); | 					var username = unfollowBtn.attr('data-username'); | ||||||
| 					if(success) { | 					if (success) { | ||||||
| 						unfollowBtn.parent().remove(); | 						unfollowBtn.parent().remove(); | ||||||
| 						app.alertSuccess('You are no longer following ' + username + '!'); | 						app.alertSuccess('You are no longer following ' + username + '!'); | ||||||
| 					} else { | 					} else { | ||||||
|   | |||||||
| @@ -22,7 +22,9 @@ | |||||||
| 		stats_online.innerHTML = data.users; | 		stats_online.innerHTML = data.users; | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	socket.emit('api:updateHeader', { fields: ['username', 'picture', 'userslug'] }); | 	socket.emit('api:updateHeader', { | ||||||
|  | 		fields: ['username', 'picture', 'userslug'] | ||||||
|  | 	}); | ||||||
| 	socket.on('api:updateHeader', function(data) { | 	socket.on('api:updateHeader', function(data) { | ||||||
|  |  | ||||||
| 		jQuery('#search-button').on('click', function() { | 		jQuery('#search-button').on('click', function() { | ||||||
| @@ -49,18 +51,18 @@ | |||||||
| 			jQuery('.nodebb-loggedout').hide(); | 			jQuery('.nodebb-loggedout').hide(); | ||||||
|  |  | ||||||
| 			var userLabel = rightMenu.find('#user_label'); | 			var userLabel = rightMenu.find('#user_label'); | ||||||
| 			if(userLabel.length) { | 			if (userLabel.length) { | ||||||
| 				if(data['userslug']) | 				if (data['userslug']) | ||||||
| 					userLabel.attr('href','/users/' + data['userslug']); | 					userLabel.attr('href', '/users/' + data['userslug']); | ||||||
| 				if(data['picture']) | 				if (data['picture']) | ||||||
| 					userLabel.find('img').attr('src',data['picture']); | 					userLabel.find('img').attr('src', data['picture']); | ||||||
| 				if(data['username']) | 				if (data['username']) | ||||||
| 					userLabel.find('span').html(data['username']); | 					userLabel.find('span').html(data['username']); | ||||||
| 			} else { | 			} else { | ||||||
| 				var userli = $('<li> \ | 				var userli = $('<li> \ | ||||||
| 									<a id="user_label" href="/users/'+data['userslug']+'"> \ | 									<a id="user_label" href="/users/' + data['userslug'] + '"> \ | ||||||
| 										<img src="'+data['picture']+'"/> \ | 										<img src="' + data['picture'] + '"/> \ | ||||||
| 										<span>'+data['username']+'</span> \ | 										<span>' + data['username'] + '</span> \ | ||||||
| 									</a> \ | 									</a> \ | ||||||
| 								</li>'); | 								</li>'); | ||||||
| 				rightMenu.append(userli); | 				rightMenu.append(userli); | ||||||
| @@ -95,20 +97,20 @@ | |||||||
| 		e.preventDefault(); | 		e.preventDefault(); | ||||||
| 		if (notifContainer.className.indexOf('open') === -1) { | 		if (notifContainer.className.indexOf('open') === -1) { | ||||||
| 			socket.emit('api:notifications.get', null, function(data) { | 			socket.emit('api:notifications.get', null, function(data) { | ||||||
| 				var	notifFrag = document.createDocumentFragment(), | 				var notifFrag = document.createDocumentFragment(), | ||||||
| 					notifEl = document.createElement('li'), | 					notifEl = document.createElement('li'), | ||||||
| 					numRead = data.read.length, | 					numRead = data.read.length, | ||||||
| 					numUnread = data.unread.length, | 					numUnread = data.unread.length, | ||||||
| 					x; | 					x; | ||||||
| 				notifList.innerHTML = ''; | 				notifList.innerHTML = ''; | ||||||
| 				if ((data.read.length + data.unread.length) > 0) { | 				if ((data.read.length + data.unread.length) > 0) { | ||||||
| 					for(x=0;x<numUnread;x++) { | 					for (x = 0; x < numUnread; x++) { | ||||||
| 						notifEl.setAttribute('data-nid', data.unread[x].nid); | 						notifEl.setAttribute('data-nid', data.unread[x].nid); | ||||||
| 						notifEl.className = 'unread'; | 						notifEl.className = 'unread'; | ||||||
| 						notifEl.innerHTML = '<a href="' + data.unread[x].path + '"><span class="pull-right">' + utils.relativeTime(data.unread[x].datetime, true) + '</span>' + data.unread[x].text + '</a>'; | 						notifEl.innerHTML = '<a href="' + data.unread[x].path + '"><span class="pull-right">' + utils.relativeTime(data.unread[x].datetime, true) + '</span>' + data.unread[x].text + '</a>'; | ||||||
| 						notifFrag.appendChild(notifEl.cloneNode(true)); | 						notifFrag.appendChild(notifEl.cloneNode(true)); | ||||||
| 					} | 					} | ||||||
| 					for(x=0;x<numRead;x++) { | 					for (x = 0; x < numRead; x++) { | ||||||
| 						notifEl.setAttribute('data-nid', data.read[x].nid); | 						notifEl.setAttribute('data-nid', data.read[x].nid); | ||||||
| 						notifEl.className = ''; | 						notifEl.className = ''; | ||||||
| 						notifEl.innerHTML = '<a href="' + data.read[x].path + '"><span class="pull-right">' + utils.relativeTime(data.read[x].datetime, true) + '</span>' + data.read[x].text + '</a>'; | 						notifEl.innerHTML = '<a href="' + data.read[x].path + '"><span class="pull-right">' + utils.relativeTime(data.read[x].datetime, true) + '</span>' + data.read[x].text + '</a>'; | ||||||
| @@ -133,10 +135,16 @@ | |||||||
|  |  | ||||||
| 	notifList.addEventListener('click', function(e) { | 	notifList.addEventListener('click', function(e) { | ||||||
| 		var target; | 		var target; | ||||||
| 		switch(e.target.nodeName) { | 		switch (e.target.nodeName) { | ||||||
| 			case 'SPAN': target = e.target.parentNode.parentNode; break; | 			case 'SPAN': | ||||||
| 			case 'A': target = e.target.parentNode; break; | 				target = e.target.parentNode.parentNode; | ||||||
| 			case 'li': target = e.target; break; | 				break; | ||||||
|  | 			case 'A': | ||||||
|  | 				target = e.target.parentNode; | ||||||
|  | 				break; | ||||||
|  | 			case 'li': | ||||||
|  | 				target = e.target; | ||||||
|  | 				break; | ||||||
| 		} | 		} | ||||||
| 		if (target) { | 		if (target) { | ||||||
| 			var nid = parseInt(target.getAttribute('data-nid')); | 			var nid = parseInt(target.getAttribute('data-nid')); | ||||||
| @@ -161,7 +169,7 @@ | |||||||
|  |  | ||||||
| 		require(['chat'], function(chat) { | 		require(['chat'], function(chat) { | ||||||
| 			var modal = null; | 			var modal = null; | ||||||
| 			if(chat.modalExists(data.fromuid)) { | 			if (chat.modalExists(data.fromuid)) { | ||||||
| 				modal = chat.getModal(data.fromuid); | 				modal = chat.getModal(data.fromuid); | ||||||
| 				chat.appendChatMessage(modal, data.message, data.timestamp); | 				chat.appendChatMessage(modal, data.message, data.timestamp); | ||||||
| 			} else { | 			} else { | ||||||
|   | |||||||
| @@ -1,13 +1,15 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| (function() { | (function() { | ||||||
| 	// Alternate Logins | 	// Alternate Logins | ||||||
| 	var altLoginEl = document.querySelector('.alt-logins'); | 	var altLoginEl = document.querySelector('.alt-logins'); | ||||||
| 	altLoginEl.addEventListener('click', function(e) { | 	altLoginEl.addEventListener('click', function(e) { | ||||||
| 		var target; | 		var target; | ||||||
| 		switch(e.target.nodeName) { | 		switch (e.target.nodeName) { | ||||||
| 			case 'LI': target = e.target; break; | 			case 'LI': | ||||||
| 			case 'I': target = e.target.parentNode; break; | 				target = e.target; | ||||||
|  | 				break; | ||||||
|  | 			case 'I': | ||||||
|  | 				target = e.target.parentNode; | ||||||
|  | 				break; | ||||||
| 		} | 		} | ||||||
| 		if (target) { | 		if (target) { | ||||||
| 			document.location.href = target.getAttribute('data-url'); | 			document.location.href = target.getAttribute('data-url'); | ||||||
| @@ -26,14 +28,14 @@ | |||||||
| 			url: RELATIVE_PATH + '/login', | 			url: RELATIVE_PATH + '/login', | ||||||
| 			data: loginData, | 			data: loginData, | ||||||
| 			success: function(data, textStatus, jqXHR) { | 			success: function(data, textStatus, jqXHR) { | ||||||
| 				if(!data.success) { | 				if (!data.success) { | ||||||
| 					$('#login-error-notify').show(); | 					$('#login-error-notify').show(); | ||||||
| 				} else { | 				} else { | ||||||
| 					$('#login-error-notify').hide(); | 					$('#login-error-notify').hide(); | ||||||
| 					window.location.replace(RELATIVE_PATH + "/?loggedin"); | 					window.location.replace(RELATIVE_PATH + "/?loggedin"); | ||||||
| 				} | 				} | ||||||
| 			}, | 			}, | ||||||
| 			error : function(data, textStatus, jqXHR) { | 			error: function(data, textStatus, jqXHR) { | ||||||
| 				$('#login-error-notify').show(); | 				$('#login-error-notify').show(); | ||||||
| 			}, | 			}, | ||||||
| 			dataType: 'json', | 			dataType: 'json', | ||||||
|   | |||||||
| @@ -8,7 +8,8 @@ | |||||||
| 		'event:new_post' | 		'event:new_post' | ||||||
| 	]); | 	]); | ||||||
|  |  | ||||||
| 	var newTopicCount = 0, newPostCount = 0; | 	var newTopicCount = 0, | ||||||
|  | 		newPostCount = 0; | ||||||
|  |  | ||||||
| 	$('#new-topics-alert').on('click', function() { | 	$('#new-topics-alert').on('click', function() { | ||||||
| 		$(this).hide(); | 		$(this).hide(); | ||||||
| @@ -24,16 +25,16 @@ | |||||||
| 	function updateAlertText() { | 	function updateAlertText() { | ||||||
| 		var text = ''; | 		var text = ''; | ||||||
|  |  | ||||||
| 		if(newTopicCount > 1) | 		if (newTopicCount > 1) | ||||||
| 			text = 'There are ' + newTopicCount + ' new topics'; | 			text = 'There are ' + newTopicCount + ' new topics'; | ||||||
| 		else if(newTopicCount === 1) | 		else if (newTopicCount === 1) | ||||||
| 			text = 'There is 1 new topic'; | 			text = 'There is 1 new topic'; | ||||||
| 		else | 		else | ||||||
| 			text = 'There are no new topics'; | 			text = 'There are no new topics'; | ||||||
|  |  | ||||||
| 		if(newPostCount > 1) | 		if (newPostCount > 1) | ||||||
| 			text += ' and ' + newPostCount + ' new posts.'; | 			text += ' and ' + newPostCount + ' new posts.'; | ||||||
| 		else if(newPostCount === 1) | 		else if (newPostCount === 1) | ||||||
| 			text += ' and 1 new post.'; | 			text += ' and 1 new post.'; | ||||||
| 		else | 		else | ||||||
| 			text += ' and no new posts.'; | 			text += ' and no new posts.'; | ||||||
| @@ -50,7 +51,9 @@ | |||||||
|  |  | ||||||
| 	function onTopicsLoaded(topics) { | 	function onTopicsLoaded(topics) { | ||||||
|  |  | ||||||
| 		var html = templates.prepare(templates['recent'].blocks['topics']).parse({ topics: topics }), | 		var html = templates.prepare(templates['recent'].blocks['topics']).parse({ | ||||||
|  | 			topics: topics | ||||||
|  | 		}), | ||||||
| 			container = $('#topics-container'); | 			container = $('#topics-container'); | ||||||
|  |  | ||||||
| 		$('#category-no-topics').remove(); | 		$('#category-no-topics').remove(); | ||||||
| @@ -60,8 +63,10 @@ | |||||||
|  |  | ||||||
| 	function loadMoreTopics() { | 	function loadMoreTopics() { | ||||||
| 		loadingMoreTopics = true; | 		loadingMoreTopics = true; | ||||||
| 		socket.emit('api:topics.loadMoreRecentTopics', {after:$('#topics-container').children().length}, function(data) { | 		socket.emit('api:topics.loadMoreRecentTopics', { | ||||||
| 			if(data.topics && data.topics.length) { | 			after: $('#topics-container').children().length | ||||||
|  | 		}, function(data) { | ||||||
|  | 			if (data.topics && data.topics.length) { | ||||||
| 				onTopicsLoaded(data.topics); | 				onTopicsLoaded(data.topics); | ||||||
| 			} | 			} | ||||||
| 			loadingMoreTopics = false; | 			loadingMoreTopics = false; | ||||||
|   | |||||||
| @@ -29,16 +29,17 @@ | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	function validateEmail() { | 	function validateEmail() { | ||||||
| 		if(!emailEl.val()) { | 		if (!emailEl.val()) { | ||||||
| 			validationError = true; | 			validationError = true; | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if(!utils.isEmailValid(emailEl.val())) { | 		if (!utils.isEmailValid(emailEl.val())) { | ||||||
| 			showError(email_notify, 'Invalid email address.'); | 			showError(email_notify, 'Invalid email address.'); | ||||||
| 		} | 		} else | ||||||
| 		else | 			socket.emit('user.email.exists', { | ||||||
| 			socket.emit('user.email.exists', { email: emailEl.val() }); | 				email: emailEl.val() | ||||||
|  | 			}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	emailEl.on('blur', function() { | 	emailEl.on('blur', function() { | ||||||
| @@ -46,19 +47,21 @@ | |||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	function validateUsername() { | 	function validateUsername() { | ||||||
| 		if(!username.val()) { | 		if (!username.val()) { | ||||||
| 			validationError = true; | 			validationError = true; | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if(username.val().length < config.minimumUsernameLength) { | 		if (username.val().length < config.minimumUsernameLength) { | ||||||
| 			showError(username_notify, 'Username too short!'); | 			showError(username_notify, 'Username too short!'); | ||||||
| 		} else if(username.val().length > config.maximumUsernameLength) { | 		} else if (username.val().length > config.maximumUsernameLength) { | ||||||
| 			showError(username_notify, 'Username too long!'); | 			showError(username_notify, 'Username too long!'); | ||||||
| 		} else if(!utils.isUserNameValid(username.val())) { | 		} else if (!utils.isUserNameValid(username.val())) { | ||||||
| 			showError(username_notify, 'Invalid username!'); | 			showError(username_notify, 'Invalid username!'); | ||||||
| 		} else { | 		} else { | ||||||
| 			socket.emit('user.exists', {username: username.val()}); | 			socket.emit('user.exists', { | ||||||
|  | 				username: username.val() | ||||||
|  | 			}); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -70,20 +73,20 @@ | |||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	function validatePassword() { | 	function validatePassword() { | ||||||
| 		if(!password.val()){ | 		if (!password.val()) { | ||||||
| 			validationError = true; | 			validationError = true; | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (password.val().length < config.minimumPasswordLength) { | 		if (password.val().length < config.minimumPasswordLength) { | ||||||
| 			showError(password_notify, 'Password too short!'); | 			showError(password_notify, 'Password too short!'); | ||||||
| 		} else if(!utils.isPasswordValid(password.val())) { | 		} else if (!utils.isPasswordValid(password.val())) { | ||||||
| 			showError(password_notify, 'Invalid password!'); | 			showError(password_notify, 'Invalid password!'); | ||||||
| 		} else { | 		} else { | ||||||
| 			showSuccess(password_notify, successIcon); | 			showSuccess(password_notify, successIcon); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if(password.val() !== password_confirm.val() && password_confirm.val() !== '') { | 		if (password.val() !== password_confirm.val() && password_confirm.val() !== '') { | ||||||
| 			showError(password_confirm_notify, 'Passwords must match!'); | 			showError(password_confirm_notify, 'Passwords must match!'); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -93,11 +96,11 @@ | |||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	function validatePasswordConfirm() { | 	function validatePasswordConfirm() { | ||||||
| 		if(!password.val() || password_notify.hasClass('alert-error')) { | 		if (!password.val() || password_notify.hasClass('alert-error')) { | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if(password.val() !== password_confirm.val()) { | 		if (password.val() !== password_confirm.val()) { | ||||||
| 			showError(password_confirm_notify, 'Passwords must match!'); | 			showError(password_confirm_notify, 'Passwords must match!'); | ||||||
| 		} else { | 		} else { | ||||||
| 			showSuccess(password_confirm_notify, successIcon); | 			showSuccess(password_confirm_notify, successIcon); | ||||||
|   | |||||||
| @@ -1,11 +1,13 @@ | |||||||
| (function() { | (function() { | ||||||
| 	var	inputEl = document.getElementById('email'), | 	var inputEl = document.getElementById('email'), | ||||||
| 		errorEl = document.getElementById('error'), | 		errorEl = document.getElementById('error'), | ||||||
| 		errorTextEl = errorEl.querySelector('p'); | 		errorTextEl = errorEl.querySelector('p'); | ||||||
|  |  | ||||||
| 	document.getElementById('reset').onclick = function() { | 	document.getElementById('reset').onclick = function() { | ||||||
| 		if (inputEl.value.length > 0 && inputEl.value.indexOf('@') !== -1) { | 		if (inputEl.value.length > 0 && inputEl.value.indexOf('@') !== -1) { | ||||||
| 			socket.emit('user:reset.send', { email: inputEl.value }); | 			socket.emit('user:reset.send', { | ||||||
|  | 				email: inputEl.value | ||||||
|  | 			}); | ||||||
| 		} else { | 		} else { | ||||||
| 			jQuery('#success').hide(); | 			jQuery('#success').hide(); | ||||||
| 			jQuery(errorEl).show(); | 			jQuery(errorEl).show(); | ||||||
| @@ -16,7 +18,7 @@ | |||||||
| 	ajaxify.register_events(['user.send_reset']); | 	ajaxify.register_events(['user.send_reset']); | ||||||
|  |  | ||||||
| 	socket.on('user.send_reset', function(data) { | 	socket.on('user.send_reset', function(data) { | ||||||
| 		var	submitEl = document.getElementById('reset'); | 		var submitEl = document.getElementById('reset'); | ||||||
|  |  | ||||||
| 		if (data.status === 'ok') { | 		if (data.status === 'ok') { | ||||||
| 			jQuery('#error').hide(); | 			jQuery('#error').hide(); | ||||||
| @@ -26,13 +28,13 @@ | |||||||
| 		} else { | 		} else { | ||||||
| 			jQuery('#success').hide(); | 			jQuery('#success').hide(); | ||||||
| 			jQuery(errorEl).show(); | 			jQuery(errorEl).show(); | ||||||
| 			switch(data.message) { | 			switch (data.message) { | ||||||
| 				case 'invalid-email': | 				case 'invalid-email': | ||||||
| 					errorTextEl.innerHTML = 'The email you put in (<span>' + data.email + '</span>) is not registered with us. Please try again.'; | 					errorTextEl.innerHTML = 'The email you put in (<span>' + data.email + '</span>) is not registered with us. Please try again.'; | ||||||
| 				break; | 					break; | ||||||
| 				case 'send-failed': | 				case 'send-failed': | ||||||
| 					errorTextEl.innerHTML = 'There was a problem sending the reset code. Please try again later.'; | 					errorTextEl.innerHTML = 'There was a problem sending the reset code. Please try again later.'; | ||||||
| 				break; | 					break; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	}); | 	}); | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| (function() { | (function() { | ||||||
| 	var reset_code = templates.get('reset_code'); | 	var reset_code = templates.get('reset_code'); | ||||||
|  |  | ||||||
| 	var	resetEl = document.getElementById('reset'), | 	var resetEl = document.getElementById('reset'), | ||||||
| 		password = document.getElementById('password'), | 		password = document.getElementById('password'), | ||||||
| 		repeat = document.getElementById('repeat'), | 		repeat = document.getElementById('repeat'), | ||||||
| 		noticeEl = document.getElementById('notice'); | 		noticeEl = document.getElementById('notice'); | ||||||
| @@ -18,17 +18,22 @@ | |||||||
| 			noticeEl.querySelector('p').innerHTML = 'The two passwords you\'ve entered do not match.'; | 			noticeEl.querySelector('p').innerHTML = 'The two passwords you\'ve entered do not match.'; | ||||||
| 			noticeEl.style.display = 'block'; | 			noticeEl.style.display = 'block'; | ||||||
| 		} else { | 		} else { | ||||||
| 			socket.emit('user:reset.commit', { code: reset_code, password: password.value }); | 			socket.emit('user:reset.commit', { | ||||||
|  | 				code: reset_code, | ||||||
|  | 				password: password.value | ||||||
|  | 			}); | ||||||
| 		} | 		} | ||||||
| 	}, false); | 	}, false); | ||||||
|  |  | ||||||
| 	// Enable the form if the code is valid | 	// Enable the form if the code is valid | ||||||
| 	socket.emit('user:reset.valid', { code: reset_code }); | 	socket.emit('user:reset.valid', { | ||||||
|  | 		code: reset_code | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  |  | ||||||
| 	ajaxify.register_events(['user:reset.valid', 'user:reset.commit']); | 	ajaxify.register_events(['user:reset.valid', 'user:reset.commit']); | ||||||
| 	socket.on('user:reset.valid', function(data) { | 	socket.on('user:reset.valid', function(data) { | ||||||
| 		if (!!data.valid) resetEl.disabled = false; | 		if ( !! data.valid) resetEl.disabled = false; | ||||||
| 		else { | 		else { | ||||||
| 			var formEl = document.getElementById('reset-form'); | 			var formEl = document.getElementById('reset-form'); | ||||||
| 			// Show error message | 			// Show error message | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ | |||||||
| 		$('.search-result-text').each(function() { | 		$('.search-result-text').each(function() { | ||||||
| 			var text = $(this).html(); | 			var text = $(this).html(); | ||||||
| 			var regex = new RegExp(searchQuery, 'gi'); | 			var regex = new RegExp(searchQuery, 'gi'); | ||||||
| 			text = text.replace(regex, '<span class="label label-success">'+searchQuery+'</span>'); | 			text = text.replace(regex, '<span class="label label-success">' + searchQuery + '</span>'); | ||||||
| 			$(this).html(text); | 			$(this).html(text); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| (function() { | (function() { | ||||||
| 	var	expose_tools = templates.get('expose_tools'), | 	var expose_tools = templates.get('expose_tools'), | ||||||
| 		tid = templates.get('topic_id'), | 		tid = templates.get('topic_id'), | ||||||
| 		postListEl = document.getElementById('post-container'), | 		postListEl = document.getElementById('post-container'), | ||||||
| 		editBtns = document.querySelectorAll('#post-container .post-buttons .edit, #post-container .post-buttons .edit i'), | 		editBtns = document.querySelectorAll('#post-container .post-buttons .edit, #post-container .post-buttons .edit i'), | ||||||
| @@ -15,7 +15,7 @@ | |||||||
|  |  | ||||||
| 		app.addCommasToNumbers(); | 		app.addCommasToNumbers(); | ||||||
|  |  | ||||||
| 		var	room = 'topic_' + tid, | 		var room = 'topic_' + tid, | ||||||
| 			adminTools = document.getElementById('thread-tools'); | 			adminTools = document.getElementById('thread-tools'); | ||||||
|  |  | ||||||
| 		app.enter_room(room); | 		app.enter_room(room); | ||||||
| @@ -34,11 +34,15 @@ | |||||||
| 			$('#delete_thread').on('click', function(e) { | 			$('#delete_thread').on('click', function(e) { | ||||||
| 				if (thread_state.deleted !== '1') { | 				if (thread_state.deleted !== '1') { | ||||||
| 					bootbox.confirm('Are you sure you want to delete this thread?', function(confirm) { | 					bootbox.confirm('Are you sure you want to delete this thread?', function(confirm) { | ||||||
| 						if (confirm) socket.emit('api:topic.delete', { tid: tid }); | 						if (confirm) socket.emit('api:topic.delete', { | ||||||
|  | 							tid: tid | ||||||
|  | 						}); | ||||||
| 					}); | 					}); | ||||||
| 				} else { | 				} else { | ||||||
| 					bootbox.confirm('Are you sure you want to restore this thread?', function(confirm) { | 					bootbox.confirm('Are you sure you want to restore this thread?', function(confirm) { | ||||||
| 						if (confirm) socket.emit('api:topic.restore', { tid: tid }); | 						if (confirm) socket.emit('api:topic.restore', { | ||||||
|  | 							tid: tid | ||||||
|  | 						}); | ||||||
| 					}); | 					}); | ||||||
| 				} | 				} | ||||||
| 				return false; | 				return false; | ||||||
| @@ -46,18 +50,26 @@ | |||||||
|  |  | ||||||
| 			$('#lock_thread').on('click', function(e) { | 			$('#lock_thread').on('click', function(e) { | ||||||
| 				if (thread_state.locked !== '1') { | 				if (thread_state.locked !== '1') { | ||||||
| 					socket.emit('api:topic.lock', { tid: tid }); | 					socket.emit('api:topic.lock', { | ||||||
|  | 						tid: tid | ||||||
|  | 					}); | ||||||
| 				} else { | 				} else { | ||||||
| 					socket.emit('api:topic.unlock', { tid: tid }); | 					socket.emit('api:topic.unlock', { | ||||||
|  | 						tid: tid | ||||||
|  | 					}); | ||||||
| 				} | 				} | ||||||
| 				return false; | 				return false; | ||||||
| 			}); | 			}); | ||||||
|  |  | ||||||
| 			$('#pin_thread').on('click', function(e) { | 			$('#pin_thread').on('click', function(e) { | ||||||
| 				if (thread_state.pinned !== '1') { | 				if (thread_state.pinned !== '1') { | ||||||
| 					socket.emit('api:topic.pin', { tid: tid }); | 					socket.emit('api:topic.pin', { | ||||||
|  | 						tid: tid | ||||||
|  | 					}); | ||||||
| 				} else { | 				} else { | ||||||
| 					socket.emit('api:topic.unpin', { tid: tid }); | 					socket.emit('api:topic.unpin', { | ||||||
|  | 						tid: tid | ||||||
|  | 					}); | ||||||
| 				} | 				} | ||||||
| 				return false; | 				return false; | ||||||
| 			}); | 			}); | ||||||
| @@ -73,7 +85,7 @@ | |||||||
| 				if (loadingEl) { | 				if (loadingEl) { | ||||||
| 					socket.once('api:categories.get', function(data) { | 					socket.once('api:categories.get', function(data) { | ||||||
| 						// Render categories | 						// Render categories | ||||||
| 						var	categoriesFrag = document.createDocumentFragment(), | 						var categoriesFrag = document.createDocumentFragment(), | ||||||
| 							categoryEl = document.createElement('li'), | 							categoryEl = document.createElement('li'), | ||||||
| 							numCategories = data.categories.length, | 							numCategories = data.categories.length, | ||||||
| 							modalBody = moveThreadModal.find('.modal-body'), | 							modalBody = moveThreadModal.find('.modal-body'), | ||||||
| @@ -85,7 +97,7 @@ | |||||||
| 							x, info, targetCid, targetCatLabel; | 							x, info, targetCid, targetCatLabel; | ||||||
|  |  | ||||||
| 						categoriesEl.className = 'category-list'; | 						categoriesEl.className = 'category-list'; | ||||||
| 						for(x=0;x<numCategories;x++) { | 						for (x = 0; x < numCategories; x++) { | ||||||
| 							info = data.categories[x]; | 							info = data.categories[x]; | ||||||
| 							categoryEl.className = info.blockclass; | 							categoryEl.className = info.blockclass; | ||||||
| 							categoryEl.innerHTML = '<i class="' + info.icon + '"></i> ' + info.name; | 							categoryEl.innerHTML = '<i class="' + info.icon + '"></i> ' + info.name; | ||||||
| @@ -132,7 +144,10 @@ | |||||||
| 										}); | 										}); | ||||||
| 									} | 									} | ||||||
| 								}); | 								}); | ||||||
| 								socket.emit('api:topic.move', { tid: tid, cid: targetCid }); | 								socket.emit('api:topic.move', { | ||||||
|  | 									tid: tid, | ||||||
|  | 									cid: targetCid | ||||||
|  | 								}); | ||||||
| 							} | 							} | ||||||
| 						}); | 						}); | ||||||
| 					}); | 					}); | ||||||
| @@ -142,8 +157,8 @@ | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Fix delete state for this thread's posts | 		// Fix delete state for this thread's posts | ||||||
| 		var	postEls = document.querySelectorAll('#post-container li[data-deleted]'); | 		var postEls = document.querySelectorAll('#post-container li[data-deleted]'); | ||||||
| 		for(var x=0,numPosts=postEls.length;x<numPosts;x++) { | 		for (var x = 0, numPosts = postEls.length; x < numPosts; x++) { | ||||||
| 			if (postEls[x].getAttribute('data-deleted') === '1') toggle_post_delete_state(postEls[x].getAttribute('data-pid')); | 			if (postEls[x].getAttribute('data-deleted') === '1') toggle_post_delete_state(postEls[x].getAttribute('data-pid')); | ||||||
| 			postEls[x].removeAttribute('data-deleted'); | 			postEls[x].removeAttribute('data-deleted'); | ||||||
| 		} | 		} | ||||||
| @@ -194,7 +209,7 @@ | |||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.emit('api:topic.followCheck', tid); | 		socket.emit('api:topic.followCheck', tid); | ||||||
| 		if(followEl[0]) { | 		if (followEl[0]) { | ||||||
| 			followEl[0].addEventListener('click', function() { | 			followEl[0].addEventListener('click', function() { | ||||||
| 				socket.emit('api:topic.follow', tid); | 				socket.emit('api:topic.follow', tid); | ||||||
| 			}, false); | 			}, false); | ||||||
| @@ -214,20 +229,20 @@ | |||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	var reply_fn = function() { | 	var reply_fn = function() { | ||||||
| 			var	selectionText = '', | 		var selectionText = '', | ||||||
| 				selection = window.getSelection() || document.getSelection(); | 			selection = window.getSelection() || document.getSelection(); | ||||||
|  |  | ||||||
| 			if ($(selection.baseNode).parents('.post-content').length > 0) { | 		if ($(selection.baseNode).parents('.post-content').length > 0) { | ||||||
| 				var	snippet = selection.toString(); | 			var snippet = selection.toString(); | ||||||
| 				if (snippet.length > 0) selectionText = '> ' + snippet.replace(/\n/g, '\n> '); | 			if (snippet.length > 0) selectionText = '> ' + snippet.replace(/\n/g, '\n> '); | ||||||
| 			} | 		} | ||||||
|  |  | ||||||
| 			if (thread_state.locked !== '1') { | 		if (thread_state.locked !== '1') { | ||||||
| 				require(['composer'], function(cmp) { | 			require(['composer'], function(cmp) { | ||||||
| 					cmp.push(tid, null, null, selectionText.length > 0 ? selectionText + '\n\n' : ''); | 				cmp.push(tid, null, null, selectionText.length > 0 ? selectionText + '\n\n' : ''); | ||||||
| 				}); | 			}); | ||||||
| 			} | 		} | ||||||
| 		}; | 	}; | ||||||
| 	$('#post-container').on('click', '.post_reply', reply_fn); | 	$('#post-container').on('click', '.post_reply', reply_fn); | ||||||
| 	$('#post_reply').on('click', reply_fn); | 	$('#post_reply').on('click', reply_fn); | ||||||
|  |  | ||||||
| @@ -242,7 +257,9 @@ | |||||||
| 					cmp.push(tid, null, null, quoted); | 					cmp.push(tid, null, null, quoted); | ||||||
| 				}); | 				}); | ||||||
| 			}); | 			}); | ||||||
| 			socket.emit('api:posts.getRawPost', { pid: pid }); | 			socket.emit('api:posts.getRawPost', { | ||||||
|  | 				pid: pid | ||||||
|  | 			}); | ||||||
| 		} | 		} | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| @@ -251,11 +268,16 @@ | |||||||
| 		var uid = $(this).parents('li').attr('data-uid'); | 		var uid = $(this).parents('li').attr('data-uid'); | ||||||
|  |  | ||||||
| 		var element = $(this).find('i'); | 		var element = $(this).find('i'); | ||||||
| 		if(element.attr('class') == 'icon-star-empty') { | 		if (element.attr('class') == 'icon-star-empty') { | ||||||
| 			socket.emit('api:posts.favourite', {pid: pid, room_id: app.current_room}); | 			socket.emit('api:posts.favourite', { | ||||||
| 		} | 				pid: pid, | ||||||
| 		else { | 				room_id: app.current_room | ||||||
| 			socket.emit('api:posts.unfavourite', {pid: pid, room_id: app.current_room}); | 			}); | ||||||
|  | 		} else { | ||||||
|  | 			socket.emit('api:posts.unfavourite', { | ||||||
|  | 				pid: pid, | ||||||
|  | 				room_id: app.current_room | ||||||
|  | 			}); | ||||||
| 		} | 		} | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| @@ -276,8 +298,12 @@ | |||||||
|  |  | ||||||
| 		if (confirmDel) { | 		if (confirmDel) { | ||||||
| 			deleteAction ? | 			deleteAction ? | ||||||
| 			socket.emit('api:posts.delete', { pid: pid }) : | 				socket.emit('api:posts.delete', { | ||||||
| 			socket.emit('api:posts.restore', { pid: pid }); | 					pid: pid | ||||||
|  | 				}) : | ||||||
|  | 				socket.emit('api:posts.restore', { | ||||||
|  | 					pid: pid | ||||||
|  | 				}); | ||||||
| 		} | 		} | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| @@ -285,7 +311,7 @@ | |||||||
| 		var username = $(this).parents('li.row').attr('data-username'); | 		var username = $(this).parents('li.row').attr('data-username'); | ||||||
| 		var touid = $(this).parents('li.row').attr('data-uid'); | 		var touid = $(this).parents('li.row').attr('data-uid'); | ||||||
|  |  | ||||||
| 		if(username === app.username || !app.username) | 		if (username === app.username || !app.username) | ||||||
| 			return; | 			return; | ||||||
|  |  | ||||||
| 		app.openChat(username, touid); | 		app.openChat(username, touid); | ||||||
| @@ -302,7 +328,7 @@ | |||||||
|  |  | ||||||
| 	socket.on('api:get_users_in_room', function(data) { | 	socket.on('api:get_users_in_room', function(data) { | ||||||
| 		var activeEl = $('#thread_active_users'); | 		var activeEl = $('#thread_active_users'); | ||||||
| 		if(activeEl.length) | 		if (activeEl.length) | ||||||
| 			activeEl.html(data); | 			activeEl.html(data); | ||||||
|  |  | ||||||
| 		app.populate_online_users(); | 		app.populate_online_users(); | ||||||
| @@ -363,9 +389,9 @@ | |||||||
| 	socket.on('event:post_edited', function(data) { | 	socket.on('event:post_edited', function(data) { | ||||||
| 		var editedPostEl = document.getElementById('content_' + data.pid); | 		var editedPostEl = document.getElementById('content_' + data.pid); | ||||||
|  |  | ||||||
| 		var editedPostTitle = $('#topic_title_'+data.pid); | 		var editedPostTitle = $('#topic_title_' + data.pid); | ||||||
|  |  | ||||||
| 		if(editedPostTitle.length > 0) { | 		if (editedPostTitle.length > 0) { | ||||||
| 			editedPostTitle.fadeOut(250, function() { | 			editedPostTitle.fadeOut(250, function() { | ||||||
| 				editedPostTitle.html(data.title); | 				editedPostTitle.html(data.title); | ||||||
| 				editedPostTitle.fadeIn(250); | 				editedPostTitle.fadeIn(250); | ||||||
| @@ -421,12 +447,12 @@ | |||||||
| 		ptotal += value; | 		ptotal += value; | ||||||
| 		utotal += value; | 		utotal += value; | ||||||
|  |  | ||||||
| 		post_rep.html(ptotal+ ' '); | 		post_rep.html(ptotal + ' '); | ||||||
| 		user_rep.html(utotal+ ' '); | 		user_rep.html(utotal + ' '); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	function set_locked_state(locked, alert) { | 	function set_locked_state(locked, alert) { | ||||||
| 		var	threadReplyBtn = document.getElementById('post_reply'), | 		var threadReplyBtn = document.getElementById('post_reply'), | ||||||
| 			postReplyBtns = document.querySelectorAll('#post-container .post_reply'), | 			postReplyBtns = document.querySelectorAll('#post-container .post_reply'), | ||||||
| 			quoteBtns = document.querySelectorAll('#post-container .quote'), | 			quoteBtns = document.querySelectorAll('#post-container .quote'), | ||||||
| 			editBtns = document.querySelectorAll('#post-container .edit'), | 			editBtns = document.querySelectorAll('#post-container .edit'), | ||||||
| @@ -439,7 +465,7 @@ | |||||||
| 			lockThreadEl.innerHTML = '<i class="icon-unlock"></i> Unlock Thread'; | 			lockThreadEl.innerHTML = '<i class="icon-unlock"></i> Unlock Thread'; | ||||||
| 			threadReplyBtn.disabled = true; | 			threadReplyBtn.disabled = true; | ||||||
| 			threadReplyBtn.innerHTML = 'Locked <i class="icon-lock"></i>'; | 			threadReplyBtn.innerHTML = 'Locked <i class="icon-lock"></i>'; | ||||||
| 			for(x=0;x<numPosts;x++) { | 			for (x = 0; x < numPosts; x++) { | ||||||
| 				postReplyBtns[x].innerHTML = 'Locked <i class="icon-lock"></i>'; | 				postReplyBtns[x].innerHTML = 'Locked <i class="icon-lock"></i>'; | ||||||
| 				quoteBtns[x].style.display = 'none'; | 				quoteBtns[x].style.display = 'none'; | ||||||
| 				editBtns[x].style.display = 'none'; | 				editBtns[x].style.display = 'none'; | ||||||
| @@ -461,7 +487,7 @@ | |||||||
| 			lockThreadEl.innerHTML = '<i class="icon-lock"></i> Lock Thread'; | 			lockThreadEl.innerHTML = '<i class="icon-lock"></i> Lock Thread'; | ||||||
| 			threadReplyBtn.disabled = false; | 			threadReplyBtn.disabled = false; | ||||||
| 			threadReplyBtn.innerHTML = 'Reply'; | 			threadReplyBtn.innerHTML = 'Reply'; | ||||||
| 			for(x=0;x<numPosts;x++) { | 			for (x = 0; x < numPosts; x++) { | ||||||
| 				postReplyBtns[x].innerHTML = 'Reply <i class="icon-reply"></i>'; | 				postReplyBtns[x].innerHTML = 'Reply <i class="icon-reply"></i>'; | ||||||
| 				quoteBtns[x].style.display = 'inline-block'; | 				quoteBtns[x].style.display = 'inline-block'; | ||||||
| 				editBtns[x].style.display = 'inline-block'; | 				editBtns[x].style.display = 'inline-block'; | ||||||
| @@ -483,7 +509,7 @@ | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	function set_delete_state(deleted) { | 	function set_delete_state(deleted) { | ||||||
| 		var	deleteThreadEl = document.getElementById('delete_thread'), | 		var deleteThreadEl = document.getElementById('delete_thread'), | ||||||
| 			deleteTextEl = deleteThreadEl.getElementsByTagName('span')[0], | 			deleteTextEl = deleteThreadEl.getElementsByTagName('span')[0], | ||||||
| 			threadEl = $('#post-container'), | 			threadEl = $('#post-container'), | ||||||
| 			deleteNotice = document.getElementById('thread-deleted') || document.createElement('div'); | 			deleteNotice = document.getElementById('thread-deleted') || document.createElement('div'); | ||||||
| @@ -541,7 +567,7 @@ | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	function toggle_post_delete_state(pid) { | 	function toggle_post_delete_state(pid) { | ||||||
| 		var	postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]')); | 		var postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]')); | ||||||
|  |  | ||||||
| 		if (postEl[0]) { | 		if (postEl[0]) { | ||||||
| 			quoteEl = $(postEl[0].querySelector('.quote')), | 			quoteEl = $(postEl[0].querySelector('.quote')), | ||||||
| @@ -568,7 +594,7 @@ | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	function toggle_post_tools(pid, state) { | 	function toggle_post_tools(pid, state) { | ||||||
| 		var	postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]')), | 		var postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]')), | ||||||
| 			quoteEl = $(postEl[0].querySelector('.quote')), | 			quoteEl = $(postEl[0].querySelector('.quote')), | ||||||
| 			favEl = $(postEl[0].querySelector('.favourite')), | 			favEl = $(postEl[0].querySelector('.favourite')), | ||||||
| 			replyEl = $(postEl[0].querySelector('.post_reply')); | 			replyEl = $(postEl[0].querySelector('.post_reply')); | ||||||
| @@ -585,7 +611,7 @@ | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	function toggle_mod_tools(pid, state) { | 	function toggle_mod_tools(pid, state) { | ||||||
| 		var	postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]')), | 		var postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]')), | ||||||
| 			editEl = postEl.find('.edit'), | 			editEl = postEl.find('.edit'), | ||||||
| 			deleteEl = postEl.find('.delete'); | 			deleteEl = postEl.find('.delete'); | ||||||
|  |  | ||||||
| @@ -601,7 +627,7 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| 	var postAuthorImage, mobileAuthorOverlay, pagination; | 	var postAuthorImage, mobileAuthorOverlay, pagination; | ||||||
| 	var	postcount = templates.get('postcount'); | 	var postcount = templates.get('postcount'); | ||||||
|  |  | ||||||
| 	function updateHeader() { | 	function updateHeader() { | ||||||
| 		if (pagination == null) { | 		if (pagination == null) { | ||||||
| @@ -644,19 +670,18 @@ | |||||||
| 			var height = Math.floor(el.height()); | 			var height = Math.floor(el.height()); | ||||||
| 			var elBottom = elTop + (height < 300 ? height : 300); | 			var elBottom = elTop + (height < 300 ? height : 300); | ||||||
|  |  | ||||||
| 			var inView = ((elBottom >= scrollTop) && (elTop <= scrollBottom) | 			var inView = ((elBottom >= scrollTop) && (elTop <= scrollBottom) && (elBottom <= scrollBottom) && (elTop >= scrollTop)); | ||||||
| 					&& (elBottom <= scrollBottom) &&  (elTop >= scrollTop)); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 		    if (inView) { | 			if (inView) { | ||||||
| 		    	pagination.innerHTML = this.postnumber + ' out of ' + postcount; | 				pagination.innerHTML = this.postnumber + ' out of ' + postcount; | ||||||
| 				postAuthorImage.src = (jQuery(this).find('.profile-image-block img').attr('src')); | 				postAuthorImage.src = (jQuery(this).find('.profile-image-block img').attr('src')); | ||||||
| 				mobileAuthorOverlay.innerHTML = 'Posted by ' + jQuery(this).attr('data-username') + ', ' + jQuery(this).find('.relativeTimeAgo').html(); | 				mobileAuthorOverlay.innerHTML = 'Posted by ' + jQuery(this).attr('data-username') + ', ' + jQuery(this).find('.relativeTimeAgo').html(); | ||||||
| 		    } | 			} | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		setTimeout(function() { | 		setTimeout(function() { | ||||||
| 			if(scrollTop + windowHeight == jQuery(document).height()) { | 			if (scrollTop + windowHeight == jQuery(document).height()) { | ||||||
| 				pagination.innerHTML = postcount + ' out of ' + postcount; | 				pagination.innerHTML = postcount + ' out of ' + postcount; | ||||||
| 			} | 			} | ||||||
| 		}, 100); | 		}, 100); | ||||||
|   | |||||||
| @@ -8,7 +8,8 @@ | |||||||
| 		'event:new_post' | 		'event:new_post' | ||||||
| 	]); | 	]); | ||||||
|  |  | ||||||
| 	var newTopicCount = 0, newPostCount = 0; | 	var newTopicCount = 0, | ||||||
|  | 		newPostCount = 0; | ||||||
|  |  | ||||||
| 	$('#new-topics-alert').on('click', function() { | 	$('#new-topics-alert').on('click', function() { | ||||||
| 		$(this).hide(); | 		$(this).hide(); | ||||||
| @@ -24,16 +25,16 @@ | |||||||
| 	function updateAlertText() { | 	function updateAlertText() { | ||||||
| 		var text = ''; | 		var text = ''; | ||||||
|  |  | ||||||
| 		if(newTopicCount > 1) | 		if (newTopicCount > 1) | ||||||
| 			text = 'There are ' + newTopicCount + ' new topics'; | 			text = 'There are ' + newTopicCount + ' new topics'; | ||||||
| 		else if(newTopicCount === 1) | 		else if (newTopicCount === 1) | ||||||
| 			text = 'There is 1 new topic'; | 			text = 'There is 1 new topic'; | ||||||
| 		else | 		else | ||||||
| 			text = 'There are no new topics'; | 			text = 'There are no new topics'; | ||||||
|  |  | ||||||
| 		if(newPostCount > 1) | 		if (newPostCount > 1) | ||||||
| 			text += ' and ' + newPostCount + ' new posts.'; | 			text += ' and ' + newPostCount + ' new posts.'; | ||||||
| 		else if(newPostCount === 1) | 		else if (newPostCount === 1) | ||||||
| 			text += ' and 1 new post.'; | 			text += ' and 1 new post.'; | ||||||
| 		else | 		else | ||||||
| 			text += ' and no new posts.'; | 			text += ' and no new posts.'; | ||||||
| @@ -50,8 +51,8 @@ | |||||||
|  |  | ||||||
| 	$('#mark-allread-btn').on('click', function() { | 	$('#mark-allread-btn').on('click', function() { | ||||||
| 		var btn = $(this); | 		var btn = $(this); | ||||||
| 		socket.emit('api:topics.markAllRead', {} , function(success) { | 		socket.emit('api:topics.markAllRead', {}, function(success) { | ||||||
| 			if(success) { | 			if (success) { | ||||||
| 				btn.remove(); | 				btn.remove(); | ||||||
| 				$('#topics-container').empty(); | 				$('#topics-container').empty(); | ||||||
| 				$('#category-no-topics').removeClass('hidden'); | 				$('#category-no-topics').removeClass('hidden'); | ||||||
| @@ -68,7 +69,9 @@ | |||||||
|  |  | ||||||
| 	function onTopicsLoaded(topics) { | 	function onTopicsLoaded(topics) { | ||||||
|  |  | ||||||
| 		var html = templates.prepare(templates['unread'].blocks['topics']).parse({ topics: topics }), | 		var html = templates.prepare(templates['unread'].blocks['topics']).parse({ | ||||||
|  | 			topics: topics | ||||||
|  | 		}), | ||||||
| 			container = $('#topics-container'); | 			container = $('#topics-container'); | ||||||
|  |  | ||||||
| 		$('#category-no-topics').remove(); | 		$('#category-no-topics').remove(); | ||||||
| @@ -78,8 +81,10 @@ | |||||||
|  |  | ||||||
| 	function loadMoreTopics() { | 	function loadMoreTopics() { | ||||||
| 		loadingMoreTopics = true; | 		loadingMoreTopics = true; | ||||||
| 		socket.emit('api:topics.loadMoreUnreadTopics', {after:parseInt($('#topics-container').attr('data-next-start'), 10)}, function(data) { | 		socket.emit('api:topics.loadMoreUnreadTopics', { | ||||||
| 			if(data.topics && data.topics.length) { | 			after: parseInt($('#topics-container').attr('data-next-start'), 10) | ||||||
|  | 		}, function(data) { | ||||||
|  | 			if (data.topics && data.topics.length) { | ||||||
| 				onTopicsLoaded(data.topics); | 				onTopicsLoaded(data.topics); | ||||||
| 				$('#topics-container').attr('data-next-start', data.nextStart); | 				$('#topics-container').attr('data-next-start', data.nextStart); | ||||||
| 			} else { | 			} else { | ||||||
| @@ -99,7 +104,7 @@ | |||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
|  |  | ||||||
| 	if($("body").height() <= $(window).height() && $('#topics-container').children().length >= 20) | 	if ($("body").height() <= $(window).height() && $('#topics-container').children().length >= 20) | ||||||
| 		$('#load-more-btn').show(); | 		$('#load-more-btn').show(); | ||||||
|  |  | ||||||
| 	$('#load-more-btn').on('click', function() { | 	$('#load-more-btn').on('click', function() { | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ | |||||||
|  |  | ||||||
| 		var url = window.location.href, | 		var url = window.location.href, | ||||||
| 			parts = url.split('/'), | 			parts = url.split('/'), | ||||||
| 			active = parts[parts.length-1]; | 			active = parts[parts.length - 1]; | ||||||
|  |  | ||||||
| 		var lastSearch = null; | 		var lastSearch = null; | ||||||
|  |  | ||||||
| @@ -20,8 +20,8 @@ | |||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		jQuery('#search-user').on('keyup', function () { | 		jQuery('#search-user').on('keyup', function() { | ||||||
| 			if(timeoutId !== 0) { | 			if (timeoutId !== 0) { | ||||||
| 				clearTimeout(timeoutId); | 				clearTimeout(timeoutId); | ||||||
| 				timeoutId = 0; | 				timeoutId = 0; | ||||||
| 			} | 			} | ||||||
| @@ -50,26 +50,25 @@ | |||||||
| 		socket.removeAllListeners('api:admin.user.search'); | 		socket.removeAllListeners('api:admin.user.search'); | ||||||
|  |  | ||||||
| 		socket.on('api:admin.user.search', function(data) { | 		socket.on('api:admin.user.search', function(data) { | ||||||
| 			if(data === null) { | 			if (data === null) { | ||||||
| 				$('#user-notfound-notify').html('You need to be logged in to search!'); | 				$('#user-notfound-notify').html('You need to be logged in to search!'); | ||||||
| 				$('#user-notfound-notify').parent().addClass('btn-warning label-warning'); | 				$('#user-notfound-notify').parent().addClass('btn-warning label-warning'); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			var html = templates.prepare(templates['users'].blocks['users']).parse({ | 			var html = templates.prepare(templates['users'].blocks['users']).parse({ | ||||||
| 					users: data | 				users: data | ||||||
| 				}), | 			}), | ||||||
| 				userListEl = document.querySelector('#users-container'); | 				userListEl = document.querySelector('#users-container'); | ||||||
|  |  | ||||||
| 			userListEl.innerHTML = html; | 			userListEl.innerHTML = html; | ||||||
|  |  | ||||||
|  |  | ||||||
| 			if(data && data.length === 0) { | 			if (data && data.length === 0) { | ||||||
| 				$('#user-notfound-notify').html('User not found!'); | 				$('#user-notfound-notify').html('User not found!'); | ||||||
| 				$('#user-notfound-notify').parent().addClass('btn-warning label-warning'); | 				$('#user-notfound-notify').parent().addClass('btn-warning label-warning'); | ||||||
| 			} | 			} else { | ||||||
| 			else { | 				$('#user-notfound-notify').html(data.length + ' user' + (data.length > 1 ? 's' : '') + ' found!'); | ||||||
| 				$('#user-notfound-notify').html(data.length + ' user'+(data.length>1?'s':'') + ' found!'); |  | ||||||
| 				$('#user-notfound-notify').parent().addClass('btn-success label-success'); | 				$('#user-notfound-notify').parent().addClass('btn-success label-success'); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -78,27 +77,29 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| 		function onUsersLoaded(users) { | 		function onUsersLoaded(users) { | ||||||
| 			var html = templates.prepare(templates['users'].blocks['users']).parse({ users: users }); | 			var html = templates.prepare(templates['users'].blocks['users']).parse({ | ||||||
|  | 				users: users | ||||||
|  | 			}); | ||||||
| 			$('#users-container').append(html); | 			$('#users-container').append(html); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		function loadMoreUsers() { | 		function loadMoreUsers() { | ||||||
| 			var set = ''; | 			var set = ''; | ||||||
| 			if(active === 'users-latest' || active === 'users') { | 			if (active === 'users-latest' || active === 'users') { | ||||||
| 				set = 'users:joindate'; | 				set = 'users:joindate'; | ||||||
| 			} else if(active === 'users-sort-posts') { | 			} else if (active === 'users-sort-posts') { | ||||||
| 				set = 'users:postcount'; | 				set = 'users:postcount'; | ||||||
| 			} else if(active === 'users-sort-reputation') { | 			} else if (active === 'users-sort-reputation') { | ||||||
| 				set = 'users:reputation'; | 				set = 'users:reputation'; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if(set) { | 			if (set) { | ||||||
| 				loadingMoreUsers = true; | 				loadingMoreUsers = true; | ||||||
| 				socket.emit('api:users.loadMore', { | 				socket.emit('api:users.loadMore', { | ||||||
| 					set: set, | 					set: set, | ||||||
| 					after: $('#users-container').children().length | 					after: $('#users-container').children().length | ||||||
| 				}, function(data) { | 				}, function(data) { | ||||||
| 					if(data.users.length) { | 					if (data.users.length) { | ||||||
| 						onUsersLoaded(data.users); | 						onUsersLoaded(data.users); | ||||||
| 					} else { | 					} else { | ||||||
| 						$('#load-more-users-btn').addClass('disabled'); | 						$('#load-more-users-btn').addClass('disabled'); | ||||||
|   | |||||||
| @@ -1,6 +1,4 @@ | |||||||
|  | (function(module) { | ||||||
|  |  | ||||||
| (function (module) { |  | ||||||
|  |  | ||||||
| 	var config = {}, | 	var config = {}, | ||||||
| 		templates, | 		templates, | ||||||
| @@ -105,7 +103,7 @@ | |||||||
| 	templates.getTemplateNameFromUrl = function(url) { | 	templates.getTemplateNameFromUrl = function(url) { | ||||||
| 		var parts = url.split('?')[0].split('/'); | 		var parts = url.split('?')[0].split('/'); | ||||||
|  |  | ||||||
| 		for(var i=0; i<parts.length; ++i) { | 		for (var i = 0; i < parts.length; ++i) { | ||||||
| 			if (templates.is_available(parts[i])) { | 			if (templates.is_available(parts[i])) { | ||||||
| 				return parts[i]; | 				return parts[i]; | ||||||
| 			} | 			} | ||||||
| @@ -124,7 +122,7 @@ | |||||||
|  |  | ||||||
| 		var trimmed = api_url; | 		var trimmed = api_url; | ||||||
|  |  | ||||||
| 		if(!tpl_url) { | 		if (!tpl_url) { | ||||||
| 			tpl_url = templates.getTemplateNameFromUrl(api_url); | 			tpl_url = templates.getTemplateNameFromUrl(api_url); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -160,7 +158,7 @@ | |||||||
|  |  | ||||||
| 			jQuery.get(API_URL + api_url, function(data) { | 			jQuery.get(API_URL + api_url, function(data) { | ||||||
|  |  | ||||||
| 				if(!data) { | 				if (!data) { | ||||||
| 					ajaxify.go('404'); | 					ajaxify.go('404'); | ||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
| @@ -177,7 +175,7 @@ | |||||||
| 		function parse_template() { | 		function parse_template() { | ||||||
| 			if (!templates[tpl_url] || !template_data) return; | 			if (!templates[tpl_url] || !template_data) return; | ||||||
|  |  | ||||||
| 			if(typeof global !== "undefined") | 			if (typeof global !== "undefined") | ||||||
| 				template_data['relative_path'] = nconf.get('relative_path'); | 				template_data['relative_path'] = nconf.get('relative_path'); | ||||||
| 			else | 			else | ||||||
| 				template_data['relative_path'] = RELATIVE_PATH; | 				template_data['relative_path'] = RELATIVE_PATH; | ||||||
| @@ -187,17 +185,17 @@ | |||||||
| 			jQuery('#content [template-variable]').each(function(index, element) { | 			jQuery('#content [template-variable]').each(function(index, element) { | ||||||
| 				var value = null; | 				var value = null; | ||||||
|  |  | ||||||
| 				switch(element.getAttribute('template-type')) { | 				switch (element.getAttribute('template-type')) { | ||||||
| 					case 'boolean': | 					case 'boolean': | ||||||
| 						value = (element.value === 'true' || element.value === '1') ? true : false; | 						value = (element.value === 'true' || element.value === '1') ? true : false; | ||||||
| 					break; | 						break; | ||||||
| 					case 'int':	// Intentional fall-through | 					case 'int': // Intentional fall-through | ||||||
| 					case 'integer': | 					case 'integer': | ||||||
| 						value = parseInt(element.value); | 						value = parseInt(element.value); | ||||||
| 					break; | 						break; | ||||||
| 					default: | 					default: | ||||||
| 						value = element.value; | 						value = element.value; | ||||||
| 					break; | 						break; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				templates.set(element.getAttribute('template-variable'), value); | 				templates.set(element.getAttribute('template-variable'), value); | ||||||
| @@ -252,7 +250,8 @@ | |||||||
| 			return template.replace(regex, block); | 			return template.replace(regex, block); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		var template = this.html, regex, block; | 		var template = this.html, | ||||||
|  | 			regex, block; | ||||||
|  |  | ||||||
| 		return (function parse(data, namespace, template) { | 		return (function parse(data, namespace, template) { | ||||||
| 			if (!data || data.length == 0) { | 			if (!data || data.length == 0) { | ||||||
| @@ -267,14 +266,16 @@ | |||||||
| 						namespace += d + '.'; | 						namespace += d + '.'; | ||||||
|  |  | ||||||
| 						var regex = makeRegex(d), | 						var regex = makeRegex(d), | ||||||
| 							block = getBlock(regex, namespace.substring(0, namespace.length-1), template); | 							block = getBlock(regex, namespace.substring(0, namespace.length - 1), template); | ||||||
|  |  | ||||||
| 						if (block == null) { | 						if (block == null) { | ||||||
| 							namespace = namespace.replace(d + '.', ''); | 							namespace = namespace.replace(d + '.', ''); | ||||||
| 							continue; | 							continue; | ||||||
| 						} | 						} | ||||||
|  |  | ||||||
| 						var numblocks = data[d].length - 1, i = 0, result = ""; | 						var numblocks = data[d].length - 1, | ||||||
|  | 							i = 0, | ||||||
|  | 							result = ""; | ||||||
|  |  | ||||||
| 						do { | 						do { | ||||||
| 							result += parse(data[d][i], namespace, block); | 							result += parse(data[d][i], namespace, block); | ||||||
| @@ -312,7 +313,8 @@ | |||||||
| 		templates.init(); | 		templates.init(); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| })('undefined' === typeof module ? {module:{exports:{}}} : module) | })('undefined' === typeof module ? { | ||||||
|  | 	module: { | ||||||
|  | 		exports: {} | ||||||
|  | 	} | ||||||
|  | } : module) | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| (function (module) { | (function(module) { | ||||||
|  |  | ||||||
| 	var utils, fs; | 	var utils, fs; | ||||||
|  |  | ||||||
| @@ -10,7 +10,8 @@ | |||||||
| 	module.exports = utils = { | 	module.exports = utils = { | ||||||
| 		generateUUID: function() { | 		generateUUID: function() { | ||||||
| 			return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { | 			return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { | ||||||
| 				var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); | 				var r = Math.random() * 16 | 0, | ||||||
|  | 					v = c == 'x' ? r : (r & 0x3 | 0x8); | ||||||
| 				return v.toString(16); | 				return v.toString(16); | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
| @@ -43,7 +44,7 @@ | |||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		relativeTime: function(timestamp, min) { | 		relativeTime: function(timestamp, min) { | ||||||
| 			var	now = +new Date(), | 			var now = +new Date(), | ||||||
| 				difference = now - Math.floor(parseFloat(timestamp)); | 				difference = now - Math.floor(parseFloat(timestamp)); | ||||||
|  |  | ||||||
| 			difference = Math.floor(difference / 1000); | 			difference = Math.floor(difference / 1000); | ||||||
| @@ -73,14 +74,14 @@ | |||||||
|  |  | ||||||
| 			// remove accents, swap ñ for n, etc | 			// remove accents, swap ñ for n, etc | ||||||
| 			var from = "àáäâèéëêìíïîıòóöôùúüûñçşğ·/_,:;"; | 			var from = "àáäâèéëêìíïîıòóöôùúüûñçşğ·/_,:;"; | ||||||
| 			var to   = "aaaaeeeeiiiiioooouuuuncsg------"; | 			var to = "aaaaeeeeiiiiioooouuuuncsg------"; | ||||||
| 			for (var i=0, l=from.length ; i<l ; i++) { | 			for (var i = 0, l = from.length; i < l; i++) { | ||||||
| 				str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i)); | 				str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i)); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars | 			str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars | ||||||
| 					.replace(/\s+/g, '-') // collapse whitespace and replace by - | 			.replace(/\s+/g, '-') // collapse whitespace and replace by - | ||||||
| 					.replace(/-+/g, '-'); // collapse dashes | 			.replace(/-+/g, '-'); // collapse dashes | ||||||
|  |  | ||||||
| 			return str; | 			return str; | ||||||
| 		}, | 		}, | ||||||
| @@ -103,21 +104,21 @@ | |||||||
| 		// Blatently stolen from: http://phpjs.org/functions/strip_tags/ | 		// Blatently stolen from: http://phpjs.org/functions/strip_tags/ | ||||||
| 		'strip_tags': function(input, allowed) { | 		'strip_tags': function(input, allowed) { | ||||||
| 			allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>) | 			allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>) | ||||||
| 			var	tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi, | 			var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi, | ||||||
| 				commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi; | 				commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi; | ||||||
|  |  | ||||||
| 			return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) { | 			return input.replace(commentsAndPhpTags, '').replace(tags, function($0, $1) { | ||||||
| 				return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : ''; | 				return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : ''; | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		buildMetaTags: function(tagsArr) { | 		buildMetaTags: function(tagsArr) { | ||||||
| 			var	tags = '', | 			var tags = '', | ||||||
| 				tag; | 				tag; | ||||||
| 			for(var x=0,numTags=tagsArr.length;x<numTags;x++) { | 			for (var x = 0, numTags = tagsArr.length; x < numTags; x++) { | ||||||
| 				if (tags.length > 0) tags += "\n\t"; | 				if (tags.length > 0) tags += "\n\t"; | ||||||
| 				tag = '<meta'; | 				tag = '<meta'; | ||||||
| 				for(y in tagsArr[x]) { | 				for (y in tagsArr[x]) { | ||||||
| 					tag += ' ' + y + '="' + tagsArr[x][y] + '"'; | 					tag += ' ' + y + '="' + tagsArr[x][y] + '"'; | ||||||
| 				} | 				} | ||||||
| 				tag += ' />'; | 				tag += ' />'; | ||||||
| @@ -130,14 +131,14 @@ | |||||||
|  |  | ||||||
| 		refreshTitle: function(url) { | 		refreshTitle: function(url) { | ||||||
| 			if (!url) { | 			if (!url) { | ||||||
| 				var	a = document.createElement('a'); | 				var a = document.createElement('a'); | ||||||
| 				a.href = document.location; | 				a.href = document.location; | ||||||
| 				url = a.pathname.slice(1); | 				url = a.pathname.slice(1); | ||||||
| 			} | 			} | ||||||
| 			var notificationIcon; | 			var notificationIcon; | ||||||
|  |  | ||||||
| 			socket.emit('api:meta.buildTitle', url, function(title, numNotifications) { | 			socket.emit('api:meta.buildTitle', url, function(title, numNotifications) { | ||||||
| 				document.title = (numNotifications > 0 ? '(' + numNotifications + ') ' : '') +  title; | 				document.title = (numNotifications > 0 ? '(' + numNotifications + ') ' : '') + title; | ||||||
| 				notificationIcon = notificationIcon || document.querySelector('.notifications a i'); | 				notificationIcon = notificationIcon || document.querySelector('.notifications a i'); | ||||||
| 				if (numNotifications > 0 && notificationIcon) notificationIcon.className = 'icon-circle active'; | 				if (numNotifications > 0 && notificationIcon) notificationIcon.className = 'icon-circle active'; | ||||||
| 			}); | 			}); | ||||||
| @@ -150,8 +151,7 @@ | |||||||
| 					badge | 					badge | ||||||
| 						.removeClass('badge-inverse') | 						.removeClass('badge-inverse') | ||||||
| 						.addClass('badge-important') | 						.addClass('badge-important') | ||||||
| 				} | 				} else { | ||||||
| 				else { |  | ||||||
| 					badge | 					badge | ||||||
| 						.removeClass('badge-important') | 						.removeClass('badge-important') | ||||||
| 						.addClass('badge-inverse') | 						.addClass('badge-inverse') | ||||||
| @@ -160,26 +160,34 @@ | |||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		isRelativeUrl: function(url) { | 		isRelativeUrl: function(url) { | ||||||
| 			var	firstChar = url.slice(0, 1); | 			var firstChar = url.slice(0, 1); | ||||||
| 			return (firstChar === '.' || firstChar === '/'); | 			return (firstChar === '.' || firstChar === '/'); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	if (!String.prototype.trim) { | 	if (!String.prototype.trim) { | ||||||
| 		String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g, '');}; | 		String.prototype.trim = function() { | ||||||
|  | 			return this.replace(/^\s+|\s+$/g, ''); | ||||||
|  | 		}; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (!String.prototype.ltrim) { | 	if (!String.prototype.ltrim) { | ||||||
| 		String.prototype.ltrim=function(){return this.replace(/^\s+/,'');}; | 		String.prototype.ltrim = function() { | ||||||
|  | 			return this.replace(/^\s+/, ''); | ||||||
|  | 		}; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (!String.prototype.rtrim) { | 	if (!String.prototype.rtrim) { | ||||||
| 		String.prototype.rtrim=function(){return this.replace(/\s+$/,'');}; | 		String.prototype.rtrim = function() { | ||||||
|  | 			return this.replace(/\s+$/, ''); | ||||||
|  | 		}; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (!String.prototype.fulltrim) { | 	if (!String.prototype.fulltrim) { | ||||||
| 		String.prototype.fulltrim=function(){return this.replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g,'').replace(/\s+/g,' ');}; | 		String.prototype.fulltrim = function() { | ||||||
|  | 			return this.replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g, '').replace(/\s+/g, ' '); | ||||||
|  | 		}; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -187,4 +195,8 @@ | |||||||
| 		window.utils = module.exports; | 		window.utils = module.exports; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| })('undefined' === typeof module ? {module:{exports:{}}} : module) | })('undefined' === typeof module ? { | ||||||
|  | 	module: { | ||||||
|  | 		exports: {} | ||||||
|  | 	} | ||||||
|  | } : module) | ||||||
| @@ -1,6 +1,9 @@ | |||||||
|  |  | ||||||
| 		</div> | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
|  |  | ||||||
|  | 	<div id="alert_window"></div> | ||||||
|  |  | ||||||
| 	<div id="footer" class="container" style="padding-top: 50px; display:none;"> | 	<div id="footer" class="container" style="padding-top: 50px; display:none;"> | ||||||
| 		<footer class="footer">Copyright © 2013 <a target="_blank" href="http://www.nodebb.com">NodeBB</a> by <a target="_blank" href="https://github.com/psychobunny">psychobunny</a>, <a href="https://github.com/julianlam" target="_blank">julianlam</a>, <a href="https://github.com/barisusakli" target="_blank">barisusakli</a> from <a target="_blank" href="http://www.designcreateplay.com">designcreateplay</a></footer> | 		<footer class="footer">Copyright © 2013 <a target="_blank" href="http://www.nodebb.com">NodeBB</a> by <a target="_blank" href="https://github.com/psychobunny">psychobunny</a>, <a href="https://github.com/julianlam" target="_blank">julianlam</a>, <a href="https://github.com/barisusakli" target="_blank">barisusakli</a> from <a target="_blank" href="http://www.designcreateplay.com">designcreateplay</a></footer> | ||||||
| 	</div> | 	</div> | ||||||
|   | |||||||
| @@ -63,8 +63,6 @@ | |||||||
| 		</div> | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
|  |  | ||||||
| 	<div id="alert_window"></div> |  | ||||||
|  |  | ||||||
| 	<div class="container"> | 	<div class="container"> | ||||||
| 		<div class="row"> | 		<div class="row"> | ||||||
| 			<div class="col-md-3"> | 			<div class="col-md-3"> | ||||||
|   | |||||||
| @@ -57,7 +57,7 @@ | |||||||
|  |  | ||||||
| 						<div id="content_{main_posts.pid}" class="post-content">{main_posts.content}</div> | 						<div id="content_{main_posts.pid}" class="post-content">{main_posts.content}</div> | ||||||
| 						<div class="post-signature">{main_posts.signature}</div> | 						<div class="post-signature">{main_posts.signature}</div> | ||||||
| 						<div class="profile-block"> | 						<div class="post-info"> | ||||||
| 							<span class="pull-right"> | 							<span class="pull-right"> | ||||||
| 								posted <span class="relativeTimeAgo">{main_posts.relativeTime} ago</span> | 								posted <span class="relativeTimeAgo">{main_posts.relativeTime} ago</span> | ||||||
| 								<span class="{main_posts.edited-class}">| last edited by <strong><a href="/users/{main_posts.editorslug}">{main_posts.editorname}</a></strong> {main_posts.relativeEditTime} ago</span> | 								<span class="{main_posts.edited-class}">| last edited by <strong><a href="/users/{main_posts.editorslug}">{main_posts.editorname}</a></strong> {main_posts.relativeEditTime} ago</span> | ||||||
| @@ -112,7 +112,7 @@ | |||||||
|  |  | ||||||
| 						<div id="content_{posts.pid}" class="post-content">{posts.content}</div> | 						<div id="content_{posts.pid}" class="post-content">{posts.content}</div> | ||||||
| 						<div class="post-signature">{posts.signature}</div> | 						<div class="post-signature">{posts.signature}</div> | ||||||
| 						<div class="profile-block"> | 						<div class="post-info"> | ||||||
| 							<span class="pull-right"> | 							<span class="pull-right"> | ||||||
| 								posted <span class="relativeTimeAgo">{posts.relativeTime} ago</span> | 								posted <span class="relativeTimeAgo">{posts.relativeTime} ago</span> | ||||||
| 								<span class="{posts.edited-class}">| last edited by <strong><a href="/users/{posts.editorslug}">{posts.editorname}</a></strong> {posts.relativeEditTime} ago</span> | 								<span class="{posts.edited-class}">| last edited by <strong><a href="/users/{posts.editorslug}">{posts.editorname}</a></strong> {posts.relativeEditTime} ago</span> | ||||||
|   | |||||||
| @@ -35,16 +35,17 @@ | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	.profile-block { | 	.main-post, .sub-posts { | ||||||
| 		background: rgba(0, 0, 0, 0.02); | 		.post-info { | ||||||
| 		margin: 15px -11px -11px -11px; | 			background: rgba(0, 0, 0, 0.02); | ||||||
| 		border-radius: 0 0 5px 5px; | 			margin: 15px -11px -11px -11px; | ||||||
| 		font-size: 10px; | 			border-radius: 0 0 5px 5px; | ||||||
| 		line-height: 15px; | 			font-size: 10px; | ||||||
| 		padding: 5px 8px 5px 5px; | 			color: #777; | ||||||
| 		color: #777; | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	.active-users { | 	.active-users { | ||||||
| 		color: rgb(153,153,153); | 		color: rgb(153,153,153); | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -42,10 +42,10 @@ | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	.main-post, .sub-posts { | 	.main-post, .sub-posts { | ||||||
| 		.profile-block, .post-block { | 		.post-info, .post-block { | ||||||
| 			position: relative; | 			position: relative; | ||||||
| 			border: 1px solid rgba(0, 0, 0, 0.06); | 			border: 1px solid rgba(0, 0, 0, 0.06); | ||||||
| 			border-radius: 5px; | 			border-radius: 0 0 5px 5px; | ||||||
| 			padding: 10px; | 			padding: 10px; | ||||||
|  |  | ||||||
| 			.post-signature { | 			.post-signature { | ||||||
| @@ -64,6 +64,8 @@ | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		.post-block { | 		.post-block { | ||||||
|  | 			border-radius: 5px; | ||||||
|  |  | ||||||
| 			.topic-buttons { | 			.topic-buttons { | ||||||
| 				background: rgba(0, 0, 0, 0.02); | 				background: rgba(0, 0, 0, 0.02); | ||||||
| 				border: 1px solid rgba(0, 0, 0, 0.06); | 				border: 1px solid rgba(0, 0, 0, 0.06); | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| var	RDB = require('./../redis.js'), | var RDB = require('./../redis.js'), | ||||||
| 	utils = require('./../../public/src/utils.js'), | 	utils = require('./../../public/src/utils.js'), | ||||||
| 	categories = require('./../categories.js'); | 	categories = require('./../categories.js'); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| var	RDB = require('../redis'), | var RDB = require('../redis'), | ||||||
| 	utils = require('../../public/src/utils'), | 	utils = require('../../public/src/utils'), | ||||||
| 	user = require('../user'), | 	user = require('../user'), | ||||||
| 	Groups = require('../groups'); | 	Groups = require('../groups'); | ||||||
| @@ -7,7 +7,7 @@ var	RDB = require('../redis'), | |||||||
|  |  | ||||||
| 	UserAdmin.makeAdmin = function(uid, theirid, socket) { | 	UserAdmin.makeAdmin = function(uid, theirid, socket) { | ||||||
| 		user.isAdministrator(uid, function(isAdmin) { | 		user.isAdministrator(uid, function(isAdmin) { | ||||||
| 			if(isAdmin) { | 			if (isAdmin) { | ||||||
| 				Groups.getGidFromName('Administrators', function(err, gid) { | 				Groups.getGidFromName('Administrators', function(err, gid) { | ||||||
| 					Groups.join(gid, theirid, function(err) { | 					Groups.join(gid, theirid, function(err) { | ||||||
| 						if (!err) { | 						if (!err) { | ||||||
| @@ -35,7 +35,7 @@ var	RDB = require('../redis'), | |||||||
|  |  | ||||||
| 	UserAdmin.removeAdmin = function(uid, theirid, socket) { | 	UserAdmin.removeAdmin = function(uid, theirid, socket) { | ||||||
| 		user.isAdministrator(uid, function(isAdmin) { | 		user.isAdministrator(uid, function(isAdmin) { | ||||||
| 			if(isAdmin) { | 			if (isAdmin) { | ||||||
| 				Groups.getGidFromName('Administrators', function(err, gid) { | 				Groups.getGidFromName('Administrators', function(err, gid) { | ||||||
| 					Groups.leave(gid, theirid, function(err) { | 					Groups.leave(gid, theirid, function(err) { | ||||||
| 						if (!err) { | 						if (!err) { | ||||||
| @@ -57,7 +57,7 @@ var	RDB = require('../redis'), | |||||||
| 	UserAdmin.deleteUser = function(uid, theirid, socket) { | 	UserAdmin.deleteUser = function(uid, theirid, socket) { | ||||||
| 		user.isAdministrator(uid, function(amIAdmin) { | 		user.isAdministrator(uid, function(amIAdmin) { | ||||||
| 			user.isAdministrator(theirid, function(areTheyAdmin) { | 			user.isAdministrator(theirid, function(areTheyAdmin) { | ||||||
| 				if(amIAdmin && !areTheyAdmin) { | 				if (amIAdmin && !areTheyAdmin) { | ||||||
| 					user.delete(theirid, function(data) { | 					user.delete(theirid, function(data) { | ||||||
|  |  | ||||||
| 						socket.emit('event:alert', { | 						socket.emit('event:alert', { | ||||||
| @@ -75,7 +75,7 @@ var	RDB = require('../redis'), | |||||||
| 	UserAdmin.banUser = function(uid, theirid, socket) { | 	UserAdmin.banUser = function(uid, theirid, socket) { | ||||||
| 		user.isAdministrator(uid, function(amIAdmin) { | 		user.isAdministrator(uid, function(amIAdmin) { | ||||||
| 			user.isAdministrator(theirid, function(areTheyAdmin) { | 			user.isAdministrator(theirid, function(areTheyAdmin) { | ||||||
| 				if(amIAdmin && !areTheyAdmin) { | 				if (amIAdmin && !areTheyAdmin) { | ||||||
| 					user.ban(theirid, function(err, result) { | 					user.ban(theirid, function(err, result) { | ||||||
|  |  | ||||||
| 						socket.emit('event:alert', { | 						socket.emit('event:alert', { | ||||||
| @@ -92,7 +92,7 @@ var	RDB = require('../redis'), | |||||||
|  |  | ||||||
| 	UserAdmin.unbanUser = function(uid, theirid, socket) { | 	UserAdmin.unbanUser = function(uid, theirid, socket) { | ||||||
| 		user.isAdministrator(uid, function(amIAdmin) { | 		user.isAdministrator(uid, function(amIAdmin) { | ||||||
| 			if(amIAdmin) { | 			if (amIAdmin) { | ||||||
| 				user.unban(theirid, function(err, result) { | 				user.unban(theirid, function(err, result) { | ||||||
| 					socket.emit('event:alert', { | 					socket.emit('event:alert', { | ||||||
| 						title: 'User Unbanned', | 						title: 'User Unbanned', | ||||||
| @@ -106,4 +106,3 @@ var	RDB = require('../redis'), | |||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| }(exports)); | }(exports)); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| var	RDB = require('./redis.js'), | var RDB = require('./redis.js'), | ||||||
| 	posts = require('./posts.js'), | 	posts = require('./posts.js'), | ||||||
| 	utils = require('./../public/src/utils.js'), | 	utils = require('./../public/src/utils.js'), | ||||||
| 	user = require('./user.js'), | 	user = require('./user.js'), | ||||||
| @@ -10,7 +10,7 @@ var	RDB = require('./redis.js'), | |||||||
|  |  | ||||||
| 	Categories.create = function(data, callback) { | 	Categories.create = function(data, callback) { | ||||||
| 		RDB.incr('global:next_category_id', function(err, cid) { | 		RDB.incr('global:next_category_id', function(err, cid) { | ||||||
| 			if(err) | 			if (err) | ||||||
| 				return callback(err, null); | 				return callback(err, null); | ||||||
|  |  | ||||||
| 			var slug = cid + '/' + utils.slugify(data.name); | 			var slug = cid + '/' + utils.slugify(data.name); | ||||||
| @@ -57,16 +57,16 @@ var	RDB = require('./redis.js'), | |||||||
| 					active_users = results[1]; | 					active_users = results[1]; | ||||||
|  |  | ||||||
| 				var categoryData = { | 				var categoryData = { | ||||||
| 					'category_name' : category_name, | 					'category_name': category_name, | ||||||
| 					'category_description': category_description, | 					'category_description': category_description, | ||||||
| 					'disabled': disabled, | 					'disabled': disabled, | ||||||
| 					'show_sidebar' : 'show', | 					'show_sidebar': 'show', | ||||||
| 					'show_topic_button': 'inline-block', | 					'show_topic_button': 'inline-block', | ||||||
| 					'no_topics_message': 'hidden', | 					'no_topics_message': 'hidden', | ||||||
| 					'topic_row_size': 'col-md-9', | 					'topic_row_size': 'col-md-9', | ||||||
| 					'category_id': category_id, | 					'category_id': category_id, | ||||||
| 					'active_users': [], | 					'active_users': [], | ||||||
| 					'topics' : [], | 					'topics': [], | ||||||
| 					'twitter-intent-url': 'https://twitter.com/intent/tweet?url=' + encodeURIComponent(nconf.get('url') + 'category/' + category_slug) + '&text=' + encodeURIComponent(category_name), | 					'twitter-intent-url': 'https://twitter.com/intent/tweet?url=' + encodeURIComponent(nconf.get('url') + 'category/' + category_slug) + '&text=' + encodeURIComponent(category_name), | ||||||
| 					'facebook-share-url': 'https://www.facebook.com/sharer/sharer.php?u=' + encodeURIComponent(nconf.get('url') + 'category/' + category_slug), | 					'facebook-share-url': 'https://www.facebook.com/sharer/sharer.php?u=' + encodeURIComponent(nconf.get('url') + 'category/' + category_slug), | ||||||
| 					'google-share-url': 'https://plus.google.com/share?url=' + encodeURIComponent(nconf.get('url') + 'category/' + category_slug) | 					'google-share-url': 'https://plus.google.com/share?url=' + encodeURIComponent(nconf.get('url') + 'category/' + category_slug) | ||||||
| @@ -102,7 +102,7 @@ var	RDB = require('./redis.js'), | |||||||
| 						categoryData.moderator_block_class = results[1].length > 0 ? '' : 'none'; | 						categoryData.moderator_block_class = results[1].length > 0 ? '' : 'none'; | ||||||
| 						categoryData.moderators = results[1]; | 						categoryData.moderators = results[1]; | ||||||
| 						categoryData.active_users = results[2]; | 						categoryData.active_users = results[2]; | ||||||
| 						categoryData.show_sidebar = categoryData.topics.length > 0 ? 'show':'hidden'; | 						categoryData.show_sidebar = categoryData.topics.length > 0 ? 'show' : 'hidden'; | ||||||
| 						callback(null, categoryData); | 						callback(null, categoryData); | ||||||
| 					}); | 					}); | ||||||
| 				} | 				} | ||||||
| @@ -136,8 +136,8 @@ var	RDB = require('./redis.js'), | |||||||
|  |  | ||||||
| 	Categories.getModerators = function(cid, callback) { | 	Categories.getModerators = function(cid, callback) { | ||||||
| 		RDB.smembers('cid:' + cid + ':moderators', function(err, mods) { | 		RDB.smembers('cid:' + cid + ':moderators', function(err, mods) { | ||||||
| 			if(!err) { | 			if (!err) { | ||||||
| 				if(mods && mods.length) { | 				if (mods && mods.length) { | ||||||
| 					user.getMultipleUserFields(mods, ['username'], function(err, moderators) { | 					user.getMultipleUserFields(mods, ['username'], function(err, moderators) { | ||||||
| 						callback(err, moderators); | 						callback(err, moderators); | ||||||
| 					}); | 					}); | ||||||
| @@ -155,14 +155,14 @@ var	RDB = require('./redis.js'), | |||||||
| 	Categories.privileges = function(cid, uid, callback) { | 	Categories.privileges = function(cid, uid, callback) { | ||||||
| 		function isModerator(next) { | 		function isModerator(next) { | ||||||
| 			user.isModerator(uid, cid, function(isMod) { | 			user.isModerator(uid, cid, function(isMod) { | ||||||
| 					next(null, isMod); | 				next(null, isMod); | ||||||
| 				}); | 			}); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		function isAdministrator(next) { | 		function isAdministrator(next) { | ||||||
| 			user.isAdministrator(uid, function(isAdmin) { | 			user.isAdministrator(uid, function(isAdmin) { | ||||||
| 					next(null, isAdmin); | 				next(null, isAdmin); | ||||||
| 				}); | 			}); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		async.parallel([isModerator, isAdministrator], function(err, results) { | 		async.parallel([isModerator, isAdministrator], function(err, results) { | ||||||
| @@ -179,8 +179,8 @@ var	RDB = require('./redis.js'), | |||||||
| 			topics.hasReadTopics(tids, uid, function(hasRead) { | 			topics.hasReadTopics(tids, uid, function(hasRead) { | ||||||
|  |  | ||||||
| 				var allread = true; | 				var allread = true; | ||||||
| 				for (var i=0, ii=tids.length; i<ii; i++) { | 				for (var i = 0, ii = tids.length; i < ii; i++) { | ||||||
| 					if(hasRead[i] === 0) { | 					if (hasRead[i] === 0) { | ||||||
| 						allread = false; | 						allread = false; | ||||||
| 						break; | 						break; | ||||||
| 					} | 					} | ||||||
| @@ -197,7 +197,7 @@ var	RDB = require('./redis.js'), | |||||||
| 	Categories.hasReadCategories = function(cids, uid, callback) { | 	Categories.hasReadCategories = function(cids, uid, callback) { | ||||||
| 		var batch = RDB.multi(); | 		var batch = RDB.multi(); | ||||||
|  |  | ||||||
| 		for (var i=0, ii=cids.length; i<ii; i++) { | 		for (var i = 0, ii = cids.length; i < ii; i++) { | ||||||
| 			batch.sismember('cid:' + cids[i] + ':read_by_uid', uid); | 			batch.sismember('cid:' + cids[i] + ':read_by_uid', uid); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -215,9 +215,9 @@ var	RDB = require('./redis.js'), | |||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	Categories.getRecentReplies = function(cid, count, callback) { | 	Categories.getRecentReplies = function(cid, count, callback) { | ||||||
| 		RDB.zrevrange('categories:recent_posts:cid:' + cid, 0, (count<10)?10:count, function(err, pids) { | 		RDB.zrevrange('categories:recent_posts:cid:' + cid, 0, (count < 10) ? 10 : count, function(err, pids) { | ||||||
|  |  | ||||||
| 			if(err) { | 			if (err) { | ||||||
| 				winston.err(err); | 				winston.err(err); | ||||||
| 				callback([]); | 				callback([]); | ||||||
| 				return; | 				return; | ||||||
| @@ -229,7 +229,7 @@ var	RDB = require('./redis.js'), | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			posts.getPostSummaryByPids(pids, function(err, postData) { | 			posts.getPostSummaryByPids(pids, function(err, postData) { | ||||||
| 				if(postData.length > count) { | 				if (postData.length > count) { | ||||||
| 					postData = postData.slice(0, count); | 					postData = postData.slice(0, count); | ||||||
| 				} | 				} | ||||||
| 				callback(postData); | 				callback(postData); | ||||||
| @@ -246,9 +246,9 @@ var	RDB = require('./redis.js'), | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		topics.getPids(tid, function(err, pids) { | 		topics.getPids(tid, function(err, pids) { | ||||||
| 			if(!err) { | 			if (!err) { | ||||||
| 				async.each(pids, movePost, function(err) { | 				async.each(pids, movePost, function(err) { | ||||||
| 					if(!err) { | 					if (!err) { | ||||||
| 						callback(null, 1); | 						callback(null, 1); | ||||||
| 					} else { | 					} else { | ||||||
| 						winston.err(err); | 						winston.err(err); | ||||||
| @@ -267,15 +267,15 @@ var	RDB = require('./redis.js'), | |||||||
| 			Categories.addActiveUser(cid, uid); | 			Categories.addActiveUser(cid, uid); | ||||||
| 			Categories.isUserActiveIn(oldCid, uid, function(err, active) { | 			Categories.isUserActiveIn(oldCid, uid, function(err, active) { | ||||||
|  |  | ||||||
| 				if(!err && !active) { | 				if (!err && !active) { | ||||||
| 					Categories.removeActiveUser(oldCid, uid); | 					Categories.removeActiveUser(oldCid, uid); | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		topics.getUids(tid, function(err, uids) { | 		topics.getUids(tid, function(err, uids) { | ||||||
| 			if(!err && uids) { | 			if (!err && uids) { | ||||||
| 				for(var i=0; i<uids.length; ++i) { | 				for (var i = 0; i < uids.length; ++i) { | ||||||
| 					updateUser(uids[i]); | 					updateUser(uids[i]); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| @@ -295,7 +295,7 @@ var	RDB = require('./redis.js'), | |||||||
|  |  | ||||||
| 	Categories.getCategoryFields = function(cid, fields, callback) { | 	Categories.getCategoryFields = function(cid, fields, callback) { | ||||||
| 		RDB.hmgetObject('category:' + cid, fields, function(err, data) { | 		RDB.hmgetObject('category:' + cid, fields, function(err, data) { | ||||||
| 			if(err === null) | 			if (err === null) | ||||||
| 				callback(data); | 				callback(data); | ||||||
| 			else | 			else | ||||||
| 				winston.err(err); | 				winston.err(err); | ||||||
| @@ -312,7 +312,9 @@ var	RDB = require('./redis.js'), | |||||||
|  |  | ||||||
| 	Categories.getCategories = function(cids, callback, current_user) { | 	Categories.getCategories = function(cids, callback, current_user) { | ||||||
| 		if (!cids || !Array.isArray(cids) || cids.length === 0) { | 		if (!cids || !Array.isArray(cids) || cids.length === 0) { | ||||||
| 			callback({'categories' : []}); | 			callback({ | ||||||
|  | 				'categories': [] | ||||||
|  | 			}); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -321,7 +323,7 @@ var	RDB = require('./redis.js'), | |||||||
| 		function getCategory(cid, callback) { | 		function getCategory(cid, callback) { | ||||||
| 			Categories.getCategoryData(cid, function(err, categoryData) { | 			Categories.getCategoryData(cid, function(err, categoryData) { | ||||||
|  |  | ||||||
| 				if(err) { | 				if (err) { | ||||||
| 					callback(err); | 					callback(err); | ||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
| @@ -331,18 +333,20 @@ var	RDB = require('./redis.js'), | |||||||
|  |  | ||||||
| 					categories.push(categoryData); | 					categories.push(categoryData); | ||||||
| 					callback(null); | 					callback(null); | ||||||
| 				}) ; | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		async.eachSeries(cids, getCategory, function(err) { | 		async.eachSeries(cids, getCategory, function(err) { | ||||||
| 			if(err) { | 			if (err) { | ||||||
| 				winston.err(err); | 				winston.err(err); | ||||||
| 				callback(null); | 				callback(null); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			callback({'categories': categories}); | 			callback({ | ||||||
|  | 				'categories': categories | ||||||
|  | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 	}; | 	}; | ||||||
| @@ -350,14 +354,14 @@ var	RDB = require('./redis.js'), | |||||||
| 	Categories.isUserActiveIn = function(cid, uid, callback) { | 	Categories.isUserActiveIn = function(cid, uid, callback) { | ||||||
|  |  | ||||||
| 		RDB.lrange('uid:' + uid + ':posts', 0, -1, function(err, pids) { | 		RDB.lrange('uid:' + uid + ':posts', 0, -1, function(err, pids) { | ||||||
| 			if(err) | 			if (err) | ||||||
| 				return callback(err, null); | 				return callback(err, null); | ||||||
|  |  | ||||||
| 			function getPostCategory(pid, callback) { | 			function getPostCategory(pid, callback) { | ||||||
| 				posts.getPostField(pid, 'tid', function(tid) { | 				posts.getPostField(pid, 'tid', function(tid) { | ||||||
|  |  | ||||||
| 					topics.getTopicField(tid, 'cid', function(err, postCid) { | 					topics.getTopicField(tid, 'cid', function(err, postCid) { | ||||||
| 						if(err) | 						if (err) | ||||||
| 							return callback(err, null); | 							return callback(err, null); | ||||||
|  |  | ||||||
| 						return callback(null, postCid); | 						return callback(null, postCid); | ||||||
| @@ -374,16 +378,16 @@ var	RDB = require('./redis.js'), | |||||||
| 				}, | 				}, | ||||||
| 				function(callback) { | 				function(callback) { | ||||||
| 					getPostCategory(pids[index], function(err, postCid) { | 					getPostCategory(pids[index], function(err, postCid) { | ||||||
| 						if(err) | 						if (err) | ||||||
| 							return callback(err); | 							return callback(err); | ||||||
| 						if(postCid === cid) | 						if (postCid === cid) | ||||||
| 							active = true; | 							active = true; | ||||||
| 						++index; | 						++index; | ||||||
| 						callback(null); | 						callback(null); | ||||||
| 					}); | 					}); | ||||||
| 				}, | 				}, | ||||||
| 				function(err) { | 				function(err) { | ||||||
| 					if(err) | 					if (err) | ||||||
| 						return callback(err, null); | 						return callback(err, null); | ||||||
|  |  | ||||||
| 					callback(null, active); | 					callback(null, active); | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| var	RDB = require('./redis.js'), | var RDB = require('./redis.js'), | ||||||
| 	posts = require('./posts.js'), | 	posts = require('./posts.js'), | ||||||
| 	user = require('./user.js'); | 	user = require('./user.js'); | ||||||
|  |  | ||||||
| @@ -32,7 +32,10 @@ var	RDB = require('./redis.js'), | |||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					if (room_id) { | 					if (room_id) { | ||||||
| 						io.sockets.in(room_id).emit('event:rep_up', {uid: uid !== postData.uid ? postData.uid : 0, pid: pid}); | 						io.sockets. in (room_id).emit('event:rep_up', { | ||||||
|  | 							uid: uid !== postData.uid ? postData.uid : 0, | ||||||
|  | 							pid: pid | ||||||
|  | 						}); | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					socket.emit('api:posts.favourite', { | 					socket.emit('api:posts.favourite', { | ||||||
| @@ -71,7 +74,10 @@ var	RDB = require('./redis.js'), | |||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					if (room_id) { | 					if (room_id) { | ||||||
| 						io.sockets.in(room_id).emit('event:rep_down', {uid: uid !== uid_of_poster ? uid_of_poster : 0, pid: pid}); | 						io.sockets. in (room_id).emit('event:rep_down', { | ||||||
|  | 							uid: uid !== uid_of_poster ? uid_of_poster : 0, | ||||||
|  | 							pid: pid | ||||||
|  | 						}); | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					socket.emit('api:posts.unfavourite', { | 					socket.emit('api:posts.unfavourite', { | ||||||
| @@ -95,12 +101,12 @@ var	RDB = require('./redis.js'), | |||||||
| 		var loaded = 0; | 		var loaded = 0; | ||||||
| 		var data = {}; | 		var data = {}; | ||||||
|  |  | ||||||
| 		for (var i=0, ii=pids.length; i<ii; i++) { | 		for (var i = 0, ii = pids.length; i < ii; i++) { | ||||||
| 			(function(post_id) { | 			(function(post_id) { | ||||||
| 				Favourites.hasFavourited(post_id, uid, function(hasFavourited) { | 				Favourites.hasFavourited(post_id, uid, function(hasFavourited) { | ||||||
|  |  | ||||||
| 					data[post_id] = hasFavourited; | 					data[post_id] = hasFavourited; | ||||||
| 					loaded ++; | 					loaded++; | ||||||
| 					if (loaded === pids.length) | 					if (loaded === pids.length) | ||||||
| 						callback(data); | 						callback(data); | ||||||
| 				}); | 				}); | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								src/feed.js
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								src/feed.js
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | |||||||
| (function(Feed) { | (function(Feed) { | ||||||
| 	var	RDB = require('./redis.js'), | 	var RDB = require('./redis.js'), | ||||||
| 		schema = require('./schema.js'), | 		schema = require('./schema.js'), | ||||||
| 		posts = require('./posts.js'), | 		posts = require('./posts.js'), | ||||||
| 		topics = require('./topics.js'), | 		topics = require('./topics.js'), | ||||||
| @@ -15,10 +15,10 @@ | |||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	Feed.saveFeed = function(location, feed, callback) { | 	Feed.saveFeed = function(location, feed, callback) { | ||||||
| 		var	savePath = path.join(__dirname, '../', location); | 		var savePath = path.join(__dirname, '../', location); | ||||||
|  |  | ||||||
| 		fs.writeFile(savePath, feed.xml(), function (err) { | 		fs.writeFile(savePath, feed.xml(), function(err) { | ||||||
| 			if(err) return winston.err(err); | 			if (err) return winston.err(err); | ||||||
|  |  | ||||||
| 			if (callback) callback(err); | 			if (callback) callback(err); | ||||||
| 		}); | 		}); | ||||||
| @@ -30,15 +30,15 @@ | |||||||
| 		topics.getTopicWithPosts(tid, 0, 0, -1, function(err, topicData) { | 		topics.getTopicWithPosts(tid, 0, 0, -1, function(err, topicData) { | ||||||
| 			if (err) return callback(new Error('topic-invalid')); | 			if (err) return callback(new Error('topic-invalid')); | ||||||
|  |  | ||||||
| 			var	feed = new rss({ | 			var feed = new rss({ | ||||||
| 					title: topicData.topic_name, | 				title: topicData.topic_name, | ||||||
| 					description: topicData.main_posts[0].content, | 				description: topicData.main_posts[0].content, | ||||||
| 					feed_url: Feed.defaults.baseUrl + '/topics/' + tid + '.rss', | 				feed_url: Feed.defaults.baseUrl + '/topics/' + tid + '.rss', | ||||||
| 					site_url: nconf.get('url') + 'topic/' + topicData.slug, | 				site_url: nconf.get('url') + 'topic/' + topicData.slug, | ||||||
| 					image_url: topicData.main_posts[0].picture, | 				image_url: topicData.main_posts[0].picture, | ||||||
| 					author: topicData.main_posts[0].username, | 				author: topicData.main_posts[0].username, | ||||||
| 					ttl: Feed.defaults.ttl | 				ttl: Feed.defaults.ttl | ||||||
| 				}), | 			}), | ||||||
| 				topic_posts = topicData.main_posts.concat(topicData.posts), | 				topic_posts = topicData.main_posts.concat(topicData.posts), | ||||||
| 				title, postData, dateStamp; | 				title, postData, dateStamp; | ||||||
|  |  | ||||||
| @@ -73,13 +73,13 @@ | |||||||
| 		categories.getCategoryById(cid, 0, function(err, categoryData) { | 		categories.getCategoryById(cid, 0, function(err, categoryData) { | ||||||
| 			if (err) return callback(new Error('category-invalid')); | 			if (err) return callback(new Error('category-invalid')); | ||||||
|  |  | ||||||
| 			var	feed = new rss({ | 			var feed = new rss({ | ||||||
| 					title: categoryData.category_name, | 				title: categoryData.category_name, | ||||||
| 					description: categoryData.category_description, | 				description: categoryData.category_description, | ||||||
| 					feed_url: Feed.defaults.baseUrl + '/categories/' + cid + '.rss', | 				feed_url: Feed.defaults.baseUrl + '/categories/' + cid + '.rss', | ||||||
| 					site_url: nconf.get('url') + 'category/' + categoryData.category_id, | 				site_url: nconf.get('url') + 'category/' + categoryData.category_id, | ||||||
| 					ttl: Feed.defaults.ttl | 				ttl: Feed.defaults.ttl | ||||||
| 				}), | 			}), | ||||||
| 				topics = categoryData.topics, | 				topics = categoryData.topics, | ||||||
| 				title, topicData, dateStamp; | 				title, topicData, dateStamp; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| var	async = require('async'), | var async = require('async'), | ||||||
| 	User = require('./user'), | 	User = require('./user'), | ||||||
| 	RDB = RDB || require('./redis'), | 	RDB = RDB || require('./redis'), | ||||||
| 	Groups = { | 	Groups = { | ||||||
| @@ -68,9 +68,9 @@ var	async = require('async'), | |||||||
| 								description: description, | 								description: description, | ||||||
| 								deleted: '0' | 								deleted: '0' | ||||||
| 							}) | 							}) | ||||||
| 						.exec(function(err) { | 							.exec(function(err) { | ||||||
| 							Groups.get(gid, {}, callback); | 								Groups.get(gid, {}, callback); | ||||||
| 						}); | 							}); | ||||||
| 					}); | 					}); | ||||||
| 				} else callback(new Error('group-exists')) | 				} else callback(new Error('group-exists')) | ||||||
| 			}); | 			}); | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								src/imgur.js
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/imgur.js
									
									
									
									
									
								
							| @@ -1,5 +1,3 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| var request = require('request'); | var request = require('request'); | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -15,14 +13,17 @@ var request = require('request'); | |||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
| 		var post = request.post(options, function(err, req, body) { | 		var post = request.post(options, function(err, req, body) { | ||||||
| 			try{ | 			try { | ||||||
| 				callback(err, JSON.parse(body)); | 				callback(err, JSON.parse(body)); | ||||||
| 			} catch(e) { | 			} catch (e) { | ||||||
| 				callback(err, body); | 				callback(err, body); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		var upload = post.form({type:type, image:image}); | 		var upload = post.form({ | ||||||
|  | 			type: type, | ||||||
|  | 			image: image | ||||||
|  | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	imgur.setClientID = function(id) { | 	imgur.setClientID = function(id) { | ||||||
| @@ -30,4 +31,3 @@ var request = require('request'); | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| }(exports)); | }(exports)); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										165
									
								
								src/install.js
									
									
									
									
									
								
							
							
						
						
									
										165
									
								
								src/install.js
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| var	async = require('async'), | var async = require('async'), | ||||||
| 	utils = require('../public/src/utils.js'), | 	utils = require('../public/src/utils.js'), | ||||||
| 	fs = require('fs'), | 	fs = require('fs'), | ||||||
| 	url = require('url'), | 	url = require('url'), | ||||||
| @@ -8,46 +8,38 @@ var	async = require('async'), | |||||||
| 	reds = require('reds'), | 	reds = require('reds'), | ||||||
|  |  | ||||||
| 	install = { | 	install = { | ||||||
| 		questions: [ | 		questions: [{ | ||||||
| 			{ | 			name: 'base_url', | ||||||
| 				name: 'base_url', | 			description: 'URL of this installation', | ||||||
| 				description: 'URL of this installation', | 			'default': 'http://localhost', | ||||||
| 				'default': 'http://localhost', | 			pattern: /^http(?:s)?:\/\//, | ||||||
| 				pattern: /^http(?:s)?:\/\//, | 			message: 'Base URL must begin with \'http://\' or \'https://\'', | ||||||
| 				message: 'Base URL must begin with \'http://\' or \'https://\'', | 		}, { | ||||||
| 			}, | 			name: 'port', | ||||||
| 			{ | 			description: 'Port number of your NodeBB', | ||||||
| 				name: 'port', | 			'default': 4567 | ||||||
| 				description: 'Port number of your NodeBB', | 		}, { | ||||||
| 				'default': 4567 | 			name: 'use_port', | ||||||
| 			}, | 			description: 'Use a port number to access NodeBB?', | ||||||
| 			{ | 			'default': 'y', | ||||||
| 				name: 'use_port', | 			pattern: /y[es]*|n[o]?/, | ||||||
| 				description: 'Use a port number to access NodeBB?', | 			message: 'Please enter \'yes\' or \'no\'', | ||||||
| 				'default': 'y', | 		}, { | ||||||
| 				pattern: /y[es]*|n[o]?/, | 			name: 'secret', | ||||||
| 				message: 'Please enter \'yes\' or \'no\'', | 			description: 'Please enter a NodeBB secret', | ||||||
| 			}, | 			'default': utils.generateUUID() | ||||||
| 			{ | 		}, { | ||||||
| 				name: 'secret', | 			name: 'redis:host', | ||||||
| 				description: 'Please enter a NodeBB secret', | 			description: 'Host IP or address of your Redis instance', | ||||||
| 				'default': utils.generateUUID() | 			'default': '127.0.0.1' | ||||||
| 			}, | 		}, { | ||||||
| 			{ | 			name: 'redis:port', | ||||||
| 				name: 'redis:host', | 			description: 'Host port of your Redis instance', | ||||||
| 				description: 'Host IP or address of your Redis instance', | 			'default': 6379 | ||||||
| 				'default': '127.0.0.1' | 		}, { | ||||||
| 			}, | 			name: 'redis:password', | ||||||
| 			{ | 			description: 'Password of your Redis database' | ||||||
| 				name: 'redis:port', | 		}], | ||||||
| 				description: 'Host port of your Redis instance', |  | ||||||
| 				'default': 6379 |  | ||||||
| 			}, |  | ||||||
| 			{ |  | ||||||
| 				name: 'redis:password', |  | ||||||
| 				description: 'Password of your Redis database' |  | ||||||
| 			} |  | ||||||
| 		], |  | ||||||
| 		setup: function(callback) { | 		setup: function(callback) { | ||||||
| 			async.series([ | 			async.series([ | ||||||
| 				function(next) { | 				function(next) { | ||||||
| @@ -96,16 +88,29 @@ var	async = require('async'), | |||||||
| 				function(next) { | 				function(next) { | ||||||
| 					// Applying default database configs | 					// Applying default database configs | ||||||
| 					winston.info('Populating database with default configs, if not already set...') | 					winston.info('Populating database with default configs, if not already set...') | ||||||
| 					var	meta = require('./meta'), | 					var meta = require('./meta'), | ||||||
| 						defaults = [ | 						defaults = [{ | ||||||
| 							{ field: 'postDelay', value: 10000 }, | 							field: 'postDelay', | ||||||
| 							{ field: 'minimumPostLength', value: 8 }, | 							value: 10000 | ||||||
| 							{ field: 'minimumTitleLength', value: 3 }, | 						}, { | ||||||
| 							{ field: 'minimumUsernameLength', value: 2 }, | 							field: 'minimumPostLength', | ||||||
| 							{ field: 'maximumUsernameLength', value: 16 }, | 							value: 8 | ||||||
| 							{ field: 'minimumPasswordLength', value: 6 }, | 						}, { | ||||||
| 							{ field: 'imgurClientID', value: '' } | 							field: 'minimumTitleLength', | ||||||
| 						]; | 							value: 3 | ||||||
|  | 						}, { | ||||||
|  | 							field: 'minimumUsernameLength', | ||||||
|  | 							value: 2 | ||||||
|  | 						}, { | ||||||
|  | 							field: 'maximumUsernameLength', | ||||||
|  | 							value: 16 | ||||||
|  | 						}, { | ||||||
|  | 							field: 'minimumPasswordLength', | ||||||
|  | 							value: 6 | ||||||
|  | 						}, { | ||||||
|  | 							field: 'imgurClientID', | ||||||
|  | 							value: '' | ||||||
|  | 						}]; | ||||||
|  |  | ||||||
| 					async.each(defaults, function(configObj, next) { | 					async.each(defaults, function(configObj, next) { | ||||||
| 						meta.configs.setOnEmpty(configObj.field, configObj.value, next); | 						meta.configs.setOnEmpty(configObj.field, configObj.value, next); | ||||||
| @@ -115,7 +120,7 @@ var	async = require('async'), | |||||||
| 				}, | 				}, | ||||||
| 				function(next) { | 				function(next) { | ||||||
| 					// Check if an administrator needs to be created | 					// Check if an administrator needs to be created | ||||||
| 					var	Groups = require('./groups'); | 					var Groups = require('./groups'); | ||||||
|  |  | ||||||
| 					Groups.getGidFromName('Administrators', function(err, gid) { | 					Groups.getGidFromName('Administrators', function(err, gid) { | ||||||
| 						if (err) return next(err.message); | 						if (err) return next(err.message); | ||||||
| @@ -132,7 +137,7 @@ var	async = require('async'), | |||||||
| 				}, | 				}, | ||||||
| 				function(next) { | 				function(next) { | ||||||
| 					// Categories | 					// Categories | ||||||
| 					var	Categories = require('./categories'), | 					var Categories = require('./categories'), | ||||||
| 						admin = { | 						admin = { | ||||||
| 							categories: require('./admin/categories') | 							categories: require('./admin/categories') | ||||||
| 						}; | 						}; | ||||||
| @@ -159,13 +164,13 @@ var	async = require('async'), | |||||||
| 				}, | 				}, | ||||||
| 				function(next) { | 				function(next) { | ||||||
| 					// Default plugins | 					// Default plugins | ||||||
| 					var	Plugins = require('./plugins'); | 					var Plugins = require('./plugins'); | ||||||
|  |  | ||||||
| 					winston.info('Enabling default plugins'); | 					winston.info('Enabling default plugins'); | ||||||
|  |  | ||||||
| 					var	defaultEnabled = [ | 					var defaultEnabled = [ | ||||||
| 							'nodebb-plugin-markdown', 'nodebb-plugin-mentions' | 						'nodebb-plugin-markdown', 'nodebb-plugin-mentions' | ||||||
| 						]; | 					]; | ||||||
|  |  | ||||||
| 					async.each(defaultEnabled, function(pluginId, next) { | 					async.each(defaultEnabled, function(pluginId, next) { | ||||||
| 						Plugins.isActive(pluginId, function(err, active) { | 						Plugins.isActive(pluginId, function(err, active) { | ||||||
| @@ -185,31 +190,27 @@ var	async = require('async'), | |||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
| 		createAdmin: function(callback) { | 		createAdmin: function(callback) { | ||||||
| 			var	User = require('./user'), | 			var User = require('./user'), | ||||||
| 				Groups = require('./groups'); | 				Groups = require('./groups'); | ||||||
|  |  | ||||||
| 			winston.warn('No administrators have been detected, running initial user setup'); | 			winston.warn('No administrators have been detected, running initial user setup'); | ||||||
| 			var	questions = [ | 			var questions = [{ | ||||||
| 					{ | 				name: 'username', | ||||||
| 						name: 'username', | 				description: 'Administrator username', | ||||||
| 						description: 'Administrator username', | 				required: true, | ||||||
| 						required: true, | 				type: 'string' | ||||||
| 						type: 'string' | 			}, { | ||||||
| 					}, | 				name: 'email', | ||||||
| 					{ | 				description: 'Administrator email address', | ||||||
| 						name: 'email', | 				pattern: /.+@.+/, | ||||||
| 						description: 'Administrator email address', | 				required: true | ||||||
| 						pattern: /.+@.+/, | 			}, { | ||||||
| 						required: true | 				name: 'password', | ||||||
| 					}, | 				description: 'Password', | ||||||
| 					{ | 				required: true, | ||||||
| 						name: 'password', | 				hidden: true, | ||||||
| 						description: 'Password', | 				type: 'string' | ||||||
| 						required: true, | 			}], | ||||||
| 						hidden: true, |  | ||||||
| 						type: 'string' |  | ||||||
| 					} |  | ||||||
| 				], |  | ||||||
| 				getAdminInfo = function(callback) { | 				getAdminInfo = function(callback) { | ||||||
| 					prompt.get(questions, function(err, results) { | 					prompt.get(questions, function(err, results) { | ||||||
| 						if (!results) return callback(new Error('aborted')); | 						if (!results) return callback(new Error('aborted')); | ||||||
| @@ -251,9 +252,11 @@ var	async = require('async'), | |||||||
| 			], function(err) { | 			], function(err) { | ||||||
| 				winston.info('Configuration Saved OK'); | 				winston.info('Configuration Saved OK'); | ||||||
|  |  | ||||||
| 				nconf.file({ file: path.join(__dirname, '..', 'config.json') }); | 				nconf.file({ | ||||||
|  | 					file: path.join(__dirname, '..', 'config.json') | ||||||
|  | 				}); | ||||||
|  |  | ||||||
| 				var	RDB = require('./redis'); | 				var RDB = require('./redis'); | ||||||
| 				reds.createClient = function() { | 				reds.createClient = function() { | ||||||
| 					return reds.client || (reds.client = RDB); | 					return reds.client || (reds.client = RDB); | ||||||
| 				} | 				} | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								src/login.js
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								src/login.js
									
									
									
									
									
								
							| @@ -1,11 +1,10 @@ | |||||||
|  |  | ||||||
| var user = require('./user.js'), | var user = require('./user.js'), | ||||||
| 	bcrypt = require('bcrypt'), | 	bcrypt = require('bcrypt'), | ||||||
| 	RDB = require('./redis.js'), | 	RDB = require('./redis.js'), | ||||||
| 	path = require('path'), | 	path = require('path'), | ||||||
| 	winston = require('winston'); | 	winston = require('winston'); | ||||||
|  |  | ||||||
| (function(Login){ | (function(Login) { | ||||||
|  |  | ||||||
| 	Login.loginViaLocal = function(username, password, next) { | 	Login.loginViaLocal = function(username, password, next) { | ||||||
| 		if (!username || !password) { | 		if (!username || !password) { | ||||||
| @@ -24,9 +23,9 @@ var user = require('./user.js'), | |||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				user.getUserFields(uid, ['password', 'banned'], function(err, userData) { | 				user.getUserFields(uid, ['password', 'banned'], function(err, userData) { | ||||||
| 					if(err) return next(err); | 					if (err) return next(err); | ||||||
|  |  | ||||||
| 					if(userData.banned && userData.banned === '1') { | 					if (userData.banned && userData.banned === '1') { | ||||||
| 						return next({ | 						return next({ | ||||||
| 							status: "error", | 							status: "error", | ||||||
| 							message: "user-banned" | 							message: "user-banned" | ||||||
| @@ -34,14 +33,18 @@ var user = require('./user.js'), | |||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					bcrypt.compare(password, userData.password, function(err, res) { | 					bcrypt.compare(password, userData.password, function(err, res) { | ||||||
| 						if(err) { | 						if (err) { | ||||||
| 							winston.err(err.message); | 							winston.err(err.message); | ||||||
| 							next(new Error('bcrypt compare error')); | 							next(new Error('bcrypt compare error')); | ||||||
| 							return; | 							return; | ||||||
| 						} | 						} | ||||||
|  |  | ||||||
| 						if (res) { | 						if (res) { | ||||||
| 							next(null, { user: { uid: uid } }); | 							next(null, { | ||||||
|  | 								user: { | ||||||
|  | 									uid: uid | ||||||
|  | 								} | ||||||
|  | 							}); | ||||||
| 						} else { | 						} else { | ||||||
| 							next(new Error('invalid-password')); | 							next(new Error('invalid-password')); | ||||||
| 						} | 						} | ||||||
| @@ -70,7 +73,7 @@ var user = require('./user.js'), | |||||||
|  |  | ||||||
| 						// Save their photo, if present | 						// Save their photo, if present | ||||||
| 						if (photos && photos.length > 0) { | 						if (photos && photos.length > 0) { | ||||||
| 							var	photoUrl = photos[0].value; | 							var photoUrl = photos[0].value; | ||||||
| 							photoUrl = path.dirname(photoUrl) + '/' + path.basename(photoUrl, path.extname(photoUrl)).slice(0, -6) + 'bigger' + path.extname(photoUrl); | 							photoUrl = path.dirname(photoUrl) + '/' + path.basename(photoUrl, path.extname(photoUrl)).slice(0, -6) + 'bigger' + path.extname(photoUrl); | ||||||
| 							user.setUserField(uid, 'uploadedpicture', photoUrl); | 							user.setUserField(uid, 'uploadedpicture', photoUrl); | ||||||
| 							user.setUserField(uid, 'picture', photoUrl); | 							user.setUserField(uid, 'picture', photoUrl); | ||||||
| @@ -158,4 +161,3 @@ var user = require('./user.js'), | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| }(exports)); | }(exports)); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,3 @@ | |||||||
|  |  | ||||||
| var RDB = require('./redis'), | var RDB = require('./redis'), | ||||||
| 	async = require('async'); | 	async = require('async'); | ||||||
|  |  | ||||||
| @@ -15,7 +14,7 @@ var RDB = require('./redis'), | |||||||
| 		var uids = sortUids(fromuid, touid); | 		var uids = sortUids(fromuid, touid); | ||||||
|  |  | ||||||
| 		RDB.incr('global:next_message_id', function(err, mid) { | 		RDB.incr('global:next_message_id', function(err, mid) { | ||||||
| 			if(err) | 			if (err) | ||||||
| 				return callback(err, null); | 				return callback(err, null); | ||||||
|  |  | ||||||
| 			var message = { | 			var message = { | ||||||
| @@ -36,10 +35,10 @@ var RDB = require('./redis'), | |||||||
| 		var uids = sortUids(fromuid, touid); | 		var uids = sortUids(fromuid, touid); | ||||||
|  |  | ||||||
| 		RDB.lrange('messages:' + uids[0] + ':' + uids[1], 0, -1, function(err, mids) { | 		RDB.lrange('messages:' + uids[0] + ':' + uids[1], 0, -1, function(err, mids) { | ||||||
| 			if(err) | 			if (err) | ||||||
| 				return callback(err, null); | 				return callback(err, null); | ||||||
|  |  | ||||||
| 			if(!mids || !mids.length) { | 			if (!mids || !mids.length) { | ||||||
| 				return callback(null, []); | 				return callback(null, []); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -50,10 +49,10 @@ var RDB = require('./redis'), | |||||||
|  |  | ||||||
| 				function getMessage(mid, next) { | 				function getMessage(mid, next) { | ||||||
| 					RDB.hgetall('message:' + mid, function(err, message) { | 					RDB.hgetall('message:' + mid, function(err, message) { | ||||||
| 						if(err) | 						if (err) | ||||||
| 							return next(err); | 							return next(err); | ||||||
|  |  | ||||||
| 						if(message.fromuid === fromuid) | 						if (message.fromuid === fromuid) | ||||||
| 							message.content = 'You : ' + message.content; | 							message.content = 'You : ' + message.content; | ||||||
| 						else | 						else | ||||||
| 							message.content = tousername + ' : ' + message.content; | 							message.content = tousername + ' : ' + message.content; | ||||||
| @@ -64,7 +63,7 @@ var RDB = require('./redis'), | |||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				async.eachSeries(mids, getMessage, function(err) { | 				async.eachSeries(mids, getMessage, function(err) { | ||||||
| 					if(err) | 					if (err) | ||||||
| 						return callback(err, null); | 						return callback(err, null); | ||||||
|  |  | ||||||
| 					callback(null, messages); | 					callback(null, messages); | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								src/meta.js
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								src/meta.js
									
									
									
									
									
								
							| @@ -35,7 +35,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 		}, | 		}, | ||||||
| 		set: function(field, value, callback) { | 		set: function(field, value, callback) { | ||||||
| 			RDB.hset('config', field, value, function(err, res) { | 			RDB.hset('config', field, value, function(err, res) { | ||||||
| 				if(callback) | 				if (callback) | ||||||
| 					callback(err, res); | 					callback(err, res); | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
| @@ -52,7 +52,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
|  |  | ||||||
| 	Meta.themes = { | 	Meta.themes = { | ||||||
| 		get: function(callback) { | 		get: function(callback) { | ||||||
| 			var	themePath = path.join(__dirname, '../node_modules'); | 			var themePath = path.join(__dirname, '../node_modules'); | ||||||
| 			fs.readdir(themePath, function(err, files) { | 			fs.readdir(themePath, function(err, files) { | ||||||
| 				async.filter(files, function(file, next) { | 				async.filter(files, function(file, next) { | ||||||
| 					fs.stat(path.join(themePath, file), function(err, fileStat) { | 					fs.stat(path.join(themePath, file), function(err, fileStat) { | ||||||
| @@ -62,11 +62,11 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 					}); | 					}); | ||||||
| 				}, function(themes) { | 				}, function(themes) { | ||||||
| 					async.map(themes, function(theme, next) { | 					async.map(themes, function(theme, next) { | ||||||
| 						var	config = path.join(themePath, theme, 'theme.json'); | 						var config = path.join(themePath, theme, 'theme.json'); | ||||||
|  |  | ||||||
| 						if (fs.existsSync(config)) { | 						if (fs.existsSync(config)) { | ||||||
| 							fs.readFile(config, function(err, file) { | 							fs.readFile(config, function(err, file) { | ||||||
| 								var	configObj = JSON.parse(file.toString()); | 								var configObj = JSON.parse(file.toString()); | ||||||
| 								if (!configObj.screenshot) configObj.screenshot = nconf.get('relative_path') + '/images/themes/default.png'; | 								if (!configObj.screenshot) configObj.screenshot = nconf.get('relative_path') + '/images/themes/default.png'; | ||||||
| 								next(err, configObj); | 								next(err, configObj); | ||||||
| 							}); | 							}); | ||||||
| @@ -84,7 +84,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
|  |  | ||||||
| 	Meta.title = { | 	Meta.title = { | ||||||
| 		build: function(urlFragment, current_user, callback) { | 		build: function(urlFragment, current_user, callback) { | ||||||
| 			var	self = this, | 			var self = this, | ||||||
| 				user = require('./user'); | 				user = require('./user'); | ||||||
|  |  | ||||||
| 			async.parallel({ | 			async.parallel({ | ||||||
| @@ -95,7 +95,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 					user.notifications.getUnreadCount(current_user, next); | 					user.notifications.getUnreadCount(current_user, next); | ||||||
| 				} | 				} | ||||||
| 			}, function(err, values) { | 			}, function(err, values) { | ||||||
| 				var	title; | 				var title; | ||||||
|  |  | ||||||
| 				if (err) title = Meta.config.title || 'NodeBB'; | 				if (err) title = Meta.config.title || 'NodeBB'; | ||||||
| 				else title = (values.title ? values.title + ' | ' : '') + (Meta.config.title || 'NodeBB'); | 				else title = (values.title ? values.title + ' | ' : '') + (Meta.config.title || 'NodeBB'); | ||||||
| @@ -113,13 +113,13 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 			} else if (urlFragment === 'users') { | 			} else if (urlFragment === 'users') { | ||||||
| 				callback(null, 'Registered Users'); | 				callback(null, 'Registered Users'); | ||||||
| 			} else if (/^category\/\d+\/?/.test(urlFragment)) { | 			} else if (/^category\/\d+\/?/.test(urlFragment)) { | ||||||
| 				var	cid = urlFragment.match(/category\/(\d+)/)[1]; | 				var cid = urlFragment.match(/category\/(\d+)/)[1]; | ||||||
|  |  | ||||||
| 				require('./categories').getCategoryField(cid, 'name', function(err, name) { | 				require('./categories').getCategoryField(cid, 'name', function(err, name) { | ||||||
| 					callback(null, name); | 					callback(null, name); | ||||||
| 				}); | 				}); | ||||||
| 			} else if (/^topic\/\d+\/?/.test(urlFragment)) { | 			} else if (/^topic\/\d+\/?/.test(urlFragment)) { | ||||||
| 				var	tid = urlFragment.match(/topic\/(\d+)/)[1]; | 				var tid = urlFragment.match(/topic\/(\d+)/)[1]; | ||||||
|  |  | ||||||
| 				require('./topics').getTopicField(tid, 'title', function(err, title) { | 				require('./topics').getTopicField(tid, 'title', function(err, title) { | ||||||
| 					callback(null, title); | 					callback(null, title); | ||||||
| @@ -130,4 +130,3 @@ var utils = require('./../public/src/utils.js'), | |||||||
|  |  | ||||||
|  |  | ||||||
| }(exports)); | }(exports)); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| var	RDB = require('./redis.js'), | var RDB = require('./redis.js'), | ||||||
| 	async = require('async'), | 	async = require('async'), | ||||||
| 	utils = require('../public/src/utils.js'), | 	utils = require('../public/src/utils.js'), | ||||||
|  |  | ||||||
| @@ -35,25 +35,25 @@ var	RDB = require('./redis.js'), | |||||||
| 					'path', path || null, | 					'path', path || null, | ||||||
| 					'datetime', Date.now(), | 					'datetime', Date.now(), | ||||||
| 					'uniqueId', uniqueId || utils.generateUUID(), | 					'uniqueId', uniqueId || utils.generateUUID(), | ||||||
| 				function(err, status) { | 					function(err, status) { | ||||||
| 					if (status === 'OK') callback(nid); | 						if (status === 'OK') callback(nid); | ||||||
| 				}); | 					}); | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
| 		push: function(nid, uids, callback) { | 		push: function(nid, uids, callback) { | ||||||
| 			if (!Array.isArray(uids)) uids = [uids]; | 			if (!Array.isArray(uids)) uids = [uids]; | ||||||
|  |  | ||||||
| 			var	numUids = uids.length, | 			var numUids = uids.length, | ||||||
| 				x; | 				x; | ||||||
|  |  | ||||||
| 			notifications.get(nid, function(notif_data) { | 			notifications.get(nid, function(notif_data) { | ||||||
| 				for(x=0;x<numUids;x++) { | 				for (x = 0; x < numUids; x++) { | ||||||
| 					if (parseInt(uids[x]) > 0) { | 					if (parseInt(uids[x]) > 0) { | ||||||
| 						(function(uid) { | 						(function(uid) { | ||||||
| 							notifications.remove_by_uniqueId(notif_data.uniqueId, uid, function() { | 							notifications.remove_by_uniqueId(notif_data.uniqueId, uid, function() { | ||||||
| 								RDB.zadd('uid:' + uid + ':notifications:unread', notif_data.score, nid); | 								RDB.zadd('uid:' + uid + ':notifications:unread', notif_data.score, nid); | ||||||
| 								RDB.set('uid:' + uid + ':notifications:flag', 1); | 								RDB.set('uid:' + uid + ':notifications:flag', 1); | ||||||
| 								global.io.sockets.in('uid_' + uid).emit('event:new_notification'); | 								global.io.sockets. in ('uid_' + uid).emit('event:new_notification'); | ||||||
| 								if (callback) callback(true); | 								if (callback) callback(true); | ||||||
| 							}); | 							}); | ||||||
| 						})(uids[x]); | 						})(uids[x]); | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| var	fs = require('fs'), | var fs = require('fs'), | ||||||
| 	path = require('path'), | 	path = require('path'), | ||||||
| 	RDB = require('./redis.js'), | 	RDB = require('./redis.js'), | ||||||
| 	async = require('async'), | 	async = require('async'), | ||||||
| @@ -16,7 +16,7 @@ var	fs = require('fs'), | |||||||
| 			if (this.initialized) return; | 			if (this.initialized) return; | ||||||
| 			if (global.env === 'development') winston.info('[plugins] Initializing plugins system'); | 			if (global.env === 'development') winston.info('[plugins] Initializing plugins system'); | ||||||
|  |  | ||||||
| 			var	_self = this; | 			var _self = this; | ||||||
|  |  | ||||||
| 			// Read the list of activated plugins and require their libraries | 			// Read the list of activated plugins and require their libraries | ||||||
| 			async.waterfall([ | 			async.waterfall([ | ||||||
| @@ -27,13 +27,13 @@ var	fs = require('fs'), | |||||||
| 					if (plugins && Array.isArray(plugins) && plugins.length > 0) { | 					if (plugins && Array.isArray(plugins) && plugins.length > 0) { | ||||||
| 						async.each(plugins, function(plugin, next) { | 						async.each(plugins, function(plugin, next) { | ||||||
| 							// TODO: Update this check to also check node_modules | 							// TODO: Update this check to also check node_modules | ||||||
| 							var	pluginPath = path.join(__dirname, '../plugins/', plugin), | 							var pluginPath = path.join(__dirname, '../plugins/', plugin), | ||||||
| 								modulePath = path.join(__dirname, '../node_modules/', plugin); | 								modulePath = path.join(__dirname, '../node_modules/', plugin); | ||||||
| 							if (fs.existsSync(pluginPath)) _self.loadPlugin(pluginPath, next); | 							if (fs.existsSync(pluginPath)) _self.loadPlugin(pluginPath, next); | ||||||
| 							else if (fs.existsSync(modulePath)) _self.loadPlugin(modulePath, next); | 							else if (fs.existsSync(modulePath)) _self.loadPlugin(modulePath, next); | ||||||
| 							else { | 							else { | ||||||
| 								if (global.env === 'development') winston.warn('[plugins] Plugin \'' + plugin + '\' not found'); | 								if (global.env === 'development') winston.warn('[plugins] Plugin \'' + plugin + '\' not found'); | ||||||
| 								next();	// Ignore this plugin silently | 								next(); // Ignore this plugin silently | ||||||
| 							} | 							} | ||||||
| 						}, next); | 						}, next); | ||||||
| 					} else next(); | 					} else next(); | ||||||
| @@ -41,7 +41,7 @@ var	fs = require('fs'), | |||||||
| 				function(next) { | 				function(next) { | ||||||
| 					if (global.env === 'development') winston.info('[plugins] Sorting hooks to fire in priority sequence'); | 					if (global.env === 'development') winston.info('[plugins] Sorting hooks to fire in priority sequence'); | ||||||
| 					Object.keys(_self.loadedHooks).forEach(function(hook) { | 					Object.keys(_self.loadedHooks).forEach(function(hook) { | ||||||
| 						var	hooks = _self.loadedHooks[hook]; | 						var hooks = _self.loadedHooks[hook]; | ||||||
| 						hooks = hooks.sort(function(a, b) { | 						hooks = hooks.sort(function(a, b) { | ||||||
| 							return a[3] - b[3]; | 							return a[3] - b[3]; | ||||||
| 						}); | 						}); | ||||||
| @@ -65,12 +65,12 @@ var	fs = require('fs'), | |||||||
| 		}, | 		}, | ||||||
| 		initialized: false, | 		initialized: false, | ||||||
| 		loadPlugin: function(pluginPath, callback) { | 		loadPlugin: function(pluginPath, callback) { | ||||||
| 			var	_self = this; | 			var _self = this; | ||||||
|  |  | ||||||
| 			fs.readFile(path.join(pluginPath, 'plugin.json'), function(err, data) { | 			fs.readFile(path.join(pluginPath, 'plugin.json'), function(err, data) { | ||||||
| 				if (err) return callback(err); | 				if (err) return callback(err); | ||||||
|  |  | ||||||
| 				var	pluginData = JSON.parse(data), | 				var pluginData = JSON.parse(data), | ||||||
| 					libraryPath, staticDir; | 					libraryPath, staticDir; | ||||||
|  |  | ||||||
| 				async.parallel([ | 				async.parallel([ | ||||||
| @@ -119,30 +119,30 @@ var	fs = require('fs'), | |||||||
| 					`data.callbacked`, whether or not the hook expects a callback (true), or a return (false). Only used for filters. (Default: false) | 					`data.callbacked`, whether or not the hook expects a callback (true), or a return (false). Only used for filters. (Default: false) | ||||||
| 					`data.priority`, the relative priority of the method when it is eventually called (default: 10) | 					`data.priority`, the relative priority of the method when it is eventually called (default: 10) | ||||||
| 			*/ | 			*/ | ||||||
| 			var	_self = this; | 			var _self = this; | ||||||
|  |  | ||||||
| 			if (data.hook && data.method) { | 			if (data.hook && data.method) { | ||||||
| 				// Assign default priority of 10 if none is passed-in | 				// Assign default priority of 10 if none is passed-in | ||||||
| 				if (!data.priority) data.priority = 10; | 				if (!data.priority) data.priority = 10; | ||||||
|  |  | ||||||
| 				_self.loadedHooks[data.hook] = _self.loadedHooks[data.hook] || []; | 				_self.loadedHooks[data.hook] = _self.loadedHooks[data.hook] || []; | ||||||
| 				_self.loadedHooks[data.hook].push([id, data.method, !!data.callbacked, data.priority]); | 				_self.loadedHooks[data.hook].push([id, data.method, !! data.callbacked, data.priority]); | ||||||
|  |  | ||||||
| 				if (global.env === 'development') winston.info('[plugins] Hook registered: ' + data.hook + ' will call ' + id); | 				if (global.env === 'development') winston.info('[plugins] Hook registered: ' + data.hook + ' will call ' + id); | ||||||
| 				callback(); | 				callback(); | ||||||
| 			} else return; | 			} else return; | ||||||
| 		}, | 		}, | ||||||
| 		fireHook: function(hook, args, callback) { | 		fireHook: function(hook, args, callback) { | ||||||
| 			var	_self = this | 			var _self = this | ||||||
| 				hookList = this.loadedHooks[hook]; | 			hookList = this.loadedHooks[hook]; | ||||||
|  |  | ||||||
| 			if (hookList && Array.isArray(hookList)) { | 			if (hookList && Array.isArray(hookList)) { | ||||||
| 				if (global.env === 'development') winston.info('[plugins] Firing hook: \'' + hook + '\''); | 				if (global.env === 'development') winston.info('[plugins] Firing hook: \'' + hook + '\''); | ||||||
| 				var	hookType = hook.split(':')[0]; | 				var hookType = hook.split(':')[0]; | ||||||
| 				switch(hookType) { | 				switch (hookType) { | ||||||
| 					case 'filter': | 					case 'filter': | ||||||
| 						// Filters only take one argument, so only args[0] will be passed in | 						// Filters only take one argument, so only args[0] will be passed in | ||||||
| 						var	returnVal = (Array.isArray(args) ? args[0] : args); | 						var returnVal = (Array.isArray(args) ? args[0] : args); | ||||||
|  |  | ||||||
| 						async.eachSeries(hookList, function(hookObj, next) { | 						async.eachSeries(hookList, function(hookObj, next) { | ||||||
| 							if (hookObj[2]) { | 							if (hookObj[2]) { | ||||||
| @@ -163,7 +163,7 @@ var	fs = require('fs'), | |||||||
|  |  | ||||||
| 							callback(returnVal); | 							callback(returnVal); | ||||||
| 						}); | 						}); | ||||||
| 					break; | 						break; | ||||||
| 					case 'action': | 					case 'action': | ||||||
| 						async.each(hookList, function(hookObj) { | 						async.each(hookList, function(hookObj) { | ||||||
| 							if ( | 							if ( | ||||||
| @@ -176,14 +176,14 @@ var	fs = require('fs'), | |||||||
| 								if (global.env === 'development') winston.info('[plugins] Expected method \'' + hookObj[1] + '\' in plugin \'' + hookObj[0] + '\' not found, skipping.'); | 								if (global.env === 'development') winston.info('[plugins] Expected method \'' + hookObj[1] + '\' in plugin \'' + hookObj[0] + '\' not found, skipping.'); | ||||||
| 							} | 							} | ||||||
| 						}); | 						}); | ||||||
| 					break; | 						break; | ||||||
| 					default: | 					default: | ||||||
| 						// Do nothing... | 						// Do nothing... | ||||||
| 					break; | 						break; | ||||||
| 				} | 				} | ||||||
| 			} else { | 			} else { | ||||||
| 				// Otherwise, this hook contains no methods | 				// Otherwise, this hook contains no methods | ||||||
| 				var	returnVal = (Array.isArray(args) ? args[0] : args); | 				var returnVal = (Array.isArray(args) ? args[0] : args); | ||||||
| 				if (callback) callback(returnVal); | 				if (callback) callback(returnVal); | ||||||
| 			} | 			} | ||||||
| 		}, | 		}, | ||||||
| @@ -214,9 +214,9 @@ var	fs = require('fs'), | |||||||
| 		}, | 		}, | ||||||
| 		showInstalled: function(callback) { | 		showInstalled: function(callback) { | ||||||
| 			// TODO: Also check /node_modules | 			// TODO: Also check /node_modules | ||||||
| 			var	_self = this; | 			var _self = this; | ||||||
| 				localPluginPath = path.join(__dirname, '../plugins'), | 			localPluginPath = path.join(__dirname, '../plugins'), | ||||||
| 				npmPluginPath = path.join(__dirname, '../node_modules'); | 			npmPluginPath = path.join(__dirname, '../node_modules'); | ||||||
|  |  | ||||||
| 			async.waterfall([ | 			async.waterfall([ | ||||||
| 				function(next) { | 				function(next) { | ||||||
| @@ -233,7 +233,7 @@ var	fs = require('fs'), | |||||||
| 						dirs[0] = dirs[0].map(function(file) { | 						dirs[0] = dirs[0].map(function(file) { | ||||||
| 							return path.join(localPluginPath, file); | 							return path.join(localPluginPath, file); | ||||||
| 						}).filter(function(file) { | 						}).filter(function(file) { | ||||||
| 							var	stats = fs.statSync(file); | 							var stats = fs.statSync(file); | ||||||
| 							if (stats.isDirectory()) return true; | 							if (stats.isDirectory()) return true; | ||||||
| 							else return false; | 							else return false; | ||||||
| 						}); | 						}); | ||||||
| @@ -241,8 +241,8 @@ var	fs = require('fs'), | |||||||
| 						dirs[1] = dirs[1].map(function(file) { | 						dirs[1] = dirs[1].map(function(file) { | ||||||
| 							return path.join(npmPluginPath, file); | 							return path.join(npmPluginPath, file); | ||||||
| 						}).filter(function(file) { | 						}).filter(function(file) { | ||||||
| 							var	stats = fs.statSync(file); | 							var stats = fs.statSync(file); | ||||||
| 							if (stats.isDirectory() && file.substr(npmPluginPath.length+1, 14) === 'nodebb-plugin-') return true; | 							if (stats.isDirectory() && file.substr(npmPluginPath.length + 1, 14) === 'nodebb-plugin-') return true; | ||||||
| 							else return false; | 							else return false; | ||||||
| 						}); | 						}); | ||||||
|  |  | ||||||
| @@ -250,17 +250,17 @@ var	fs = require('fs'), | |||||||
| 					}); | 					}); | ||||||
| 				}, | 				}, | ||||||
| 				function(files, next) { | 				function(files, next) { | ||||||
| 					var	plugins = []; | 					var plugins = []; | ||||||
|  |  | ||||||
| 					async.each(files, function(file, next) { | 					async.each(files, function(file, next) { | ||||||
| 						var	configPath; | 						var configPath; | ||||||
|  |  | ||||||
| 						async.waterfall([ | 						async.waterfall([ | ||||||
| 							function(next) { | 							function(next) { | ||||||
| 								fs.readFile(path.join(file, 'plugin.json'), next); | 								fs.readFile(path.join(file, 'plugin.json'), next); | ||||||
| 							}, | 							}, | ||||||
| 							function(configJSON, next) { | 							function(configJSON, next) { | ||||||
| 								var	config = JSON.parse(configJSON); | 								var config = JSON.parse(configJSON); | ||||||
| 								_self.isActive(config.id, function(err, active) { | 								_self.isActive(config.id, function(err, active) { | ||||||
| 									if (err) next(new Error('no-active-state')); | 									if (err) next(new Error('no-active-state')); | ||||||
|  |  | ||||||
| @@ -272,7 +272,7 @@ var	fs = require('fs'), | |||||||
| 								}); | 								}); | ||||||
| 							} | 							} | ||||||
| 						], function(err, config) { | 						], function(err, config) { | ||||||
| 							if (err) return next();	// Silently fail | 							if (err) return next(); // Silently fail | ||||||
|  |  | ||||||
| 							plugins.push(config); | 							plugins.push(config); | ||||||
| 							next(); | 							next(); | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| var	RDB = require('./redis.js'), | var RDB = require('./redis.js'), | ||||||
| 	posts = require('./posts.js'), | 	posts = require('./posts.js'), | ||||||
| 	topics = require('./topics'), | 	topics = require('./topics'), | ||||||
| 	threadTools = require('./threadTools.js'), | 	threadTools = require('./threadTools.js'), | ||||||
| @@ -56,6 +56,7 @@ var	RDB = require('./redis.js'), | |||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	PostTools.edit = function(uid, pid, title, content) { | 	PostTools.edit = function(uid, pid, title, content) { | ||||||
| 		var	success = function() { | 		var	success = function() { | ||||||
| 			posts.setPostField(pid, 'content', content); | 			posts.setPostField(pid, 'content', content); | ||||||
| @@ -77,7 +78,10 @@ var	RDB = require('./redis.js'), | |||||||
| 								}); | 								}); | ||||||
| 							} | 							} | ||||||
|  |  | ||||||
| 							next(null, {tid:tid, isMainPost:isMainPost}); | 							next(null, { | ||||||
|  | 								tid: tid, | ||||||
|  | 								isMainPost: isMainPost | ||||||
|  | 							}); | ||||||
| 						}); | 						}); | ||||||
| 					}); | 					}); | ||||||
| 				}, | 				}, | ||||||
| @@ -85,12 +89,12 @@ var	RDB = require('./redis.js'), | |||||||
| 					PostTools.toHTML(content, next); | 					PostTools.toHTML(content, next); | ||||||
| 				} | 				} | ||||||
| 			], function(err, results) { | 			], function(err, results) { | ||||||
| 				console.log("TEEEST"); |  | ||||||
| 				io.sockets.in('topic_' + results[0].tid).emit('event:post_edited', { | 				io.sockets.in('topic_' + results[0].tid).emit('event:post_edited', { | ||||||
| 					pid: pid, | 					pid: pid, | ||||||
| 					title: title, | 					title: title, | ||||||
| 					isMainPost: results[0].isMainPost, | 					isMainPost: results[0].isMainPost, | ||||||
| 					content: results[1] | 					content: results[1] | ||||||
|  |  | ||||||
| 				}); | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		}; | 		}; | ||||||
| @@ -112,13 +116,13 @@ var	RDB = require('./redis.js'), | |||||||
| 			postSearch.remove(pid); | 			postSearch.remove(pid); | ||||||
|  |  | ||||||
| 			posts.getPostFields(pid, ['tid', 'uid'], function(postData) { | 			posts.getPostFields(pid, ['tid', 'uid'], function(postData) { | ||||||
| 				RDB.hincrby('topic:'+postData.tid, 'postcount', -1); | 				RDB.hincrby('topic:' + postData.tid, 'postcount', -1); | ||||||
|  |  | ||||||
| 				user.decrementUserFieldBy(postData.uid, 'postcount', 1, function(err, postcount) { | 				user.decrementUserFieldBy(postData.uid, 'postcount', 1, function(err, postcount) { | ||||||
| 					RDB.zadd('users:postcount', postcount, postData.uid); | 					RDB.zadd('users:postcount', postcount, postData.uid); | ||||||
| 				}); | 				}); | ||||||
|  |  | ||||||
| 				io.sockets.in('topic_' + postData.tid).emit('event:post_deleted', { | 				io.sockets. in ('topic_' + postData.tid).emit('event:post_deleted', { | ||||||
| 					pid: pid | 					pid: pid | ||||||
| 				}); | 				}); | ||||||
|  |  | ||||||
| @@ -148,35 +152,35 @@ var	RDB = require('./redis.js'), | |||||||
|  |  | ||||||
| 	PostTools.restore = function(uid, pid) { | 	PostTools.restore = function(uid, pid) { | ||||||
| 		var success = function() { | 		var success = function() { | ||||||
| 				posts.setPostField(pid, 'deleted', 0); | 			posts.setPostField(pid, 'deleted', 0); | ||||||
|  |  | ||||||
| 				posts.getPostFields(pid, ['tid', 'uid', 'content'], function(postData) { | 			posts.getPostFields(pid, ['tid', 'uid', 'content'], function(postData) { | ||||||
| 					RDB.hincrby('topic:'+postData.tid, 'postcount', 1); | 				RDB.hincrby('topic:' + postData.tid, 'postcount', 1); | ||||||
|  |  | ||||||
| 					user.incrementUserFieldBy(postData.uid, 'postcount', 1); | 				user.incrementUserFieldBy(postData.uid, 'postcount', 1); | ||||||
|  |  | ||||||
| 					io.sockets.in('topic_' + postData.tid).emit('event:post_restored', { | 				io.sockets. in ('topic_' + postData.tid).emit('event:post_restored', { | ||||||
| 						pid: pid | 					pid: pid | ||||||
| 					}); |  | ||||||
|  |  | ||||||
| 					threadTools.get_latest_undeleted_pid(postData.tid, function(err, pid) { |  | ||||||
| 						posts.getPostField(pid, 'timestamp', function(timestamp) { |  | ||||||
| 							topics.updateTimestamp(postData.tid, timestamp); |  | ||||||
| 						}); |  | ||||||
| 					}); |  | ||||||
|  |  | ||||||
| 					// Restore topic if it is the only post |  | ||||||
| 					topics.getTopicField(postData.tid, 'postcount', function(err, count) { |  | ||||||
| 						if (count === '1') { |  | ||||||
| 							threadTools.restore(postData.tid, uid); |  | ||||||
| 						} |  | ||||||
| 					}); |  | ||||||
|  |  | ||||||
| 					Feed.updateTopic(postData.tid); |  | ||||||
|  |  | ||||||
| 					postSearch.index(postData.content, pid); |  | ||||||
| 				}); | 				}); | ||||||
| 			}; |  | ||||||
|  | 				threadTools.get_latest_undeleted_pid(postData.tid, function(err, pid) { | ||||||
|  | 					posts.getPostField(pid, 'timestamp', function(timestamp) { | ||||||
|  | 						topics.updateTimestamp(postData.tid, timestamp); | ||||||
|  | 					}); | ||||||
|  | 				}); | ||||||
|  |  | ||||||
|  | 				// Restore topic if it is the only post | ||||||
|  | 				topics.getTopicField(postData.tid, 'postcount', function(err, count) { | ||||||
|  | 					if (count === '1') { | ||||||
|  | 						threadTools.restore(postData.tid, uid); | ||||||
|  | 					} | ||||||
|  | 				}); | ||||||
|  |  | ||||||
|  | 				Feed.updateTopic(postData.tid); | ||||||
|  |  | ||||||
|  | 				postSearch.index(postData.content, pid); | ||||||
|  | 			}); | ||||||
|  | 		}; | ||||||
|  |  | ||||||
| 		PostTools.privileges(pid, uid, function(privileges) { | 		PostTools.privileges(pid, uid, function(privileges) { | ||||||
| 			if (privileges.editable) { | 			if (privileges.editable) { | ||||||
| @@ -188,11 +192,11 @@ var	RDB = require('./redis.js'), | |||||||
| 	PostTools.toHTML = function(raw, callback) { | 	PostTools.toHTML = function(raw, callback) { | ||||||
| 		raw = raw || ''; | 		raw = raw || ''; | ||||||
| 		plugins.fireHook('filter:post.parse', raw, function(parsed) { | 		plugins.fireHook('filter:post.parse', raw, function(parsed) { | ||||||
| 			var	cheerio = require('cheerio'); | 			var cheerio = require('cheerio'); | ||||||
|  |  | ||||||
| 			if (parsed && parsed.length > 0) { | 			if (parsed && parsed.length > 0) { | ||||||
| 				var	parsedContentDOM = cheerio.load(parsed); | 				var parsedContentDOM = cheerio.load(parsed); | ||||||
| 				var	domain = nconf.get('url'); | 				var domain = nconf.get('url'); | ||||||
|  |  | ||||||
| 				parsedContentDOM('a').each(function() { | 				parsedContentDOM('a').each(function() { | ||||||
| 					this.attr('rel', 'nofollow'); | 					this.attr('rel', 'nofollow'); | ||||||
|   | |||||||
							
								
								
									
										66
									
								
								src/posts.js
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								src/posts.js
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| var	RDB = require('./redis.js'), | var RDB = require('./redis.js'), | ||||||
| 	utils = require('./../public/src/utils.js'), | 	utils = require('./../public/src/utils.js'), | ||||||
| 	schema = require('./schema.js'), | 	schema = require('./schema.js'), | ||||||
| 	user = require('./user.js'), | 	user = require('./user.js'), | ||||||
| @@ -34,7 +34,7 @@ var	RDB = require('./redis.js'), | |||||||
|  |  | ||||||
| 	Posts.addUserInfoToPost = function(post, callback) { | 	Posts.addUserInfoToPost = function(post, callback) { | ||||||
| 		user.getUserFields(post.uid, ['username', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned'], function(err, userData) { | 		user.getUserFields(post.uid, ['username', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned'], function(err, userData) { | ||||||
| 			if(err) return callback(); | 			if (err) return callback(); | ||||||
|  |  | ||||||
| 			postTools.toHTML(userData.signature, function(err, signature) { | 			postTools.toHTML(userData.signature, function(err, signature) { | ||||||
| 				post.username = userData.username || 'anonymous'; | 				post.username = userData.username || 'anonymous'; | ||||||
| @@ -42,12 +42,12 @@ var	RDB = require('./redis.js'), | |||||||
| 				post.user_rep = userData.reputation || 0; | 				post.user_rep = userData.reputation || 0; | ||||||
| 				post.user_postcount = userData.postcount || 0; | 				post.user_postcount = userData.postcount || 0; | ||||||
| 				post.user_banned = userData.banned || '0'; | 				post.user_banned = userData.banned || '0'; | ||||||
| 				post.picture = userData.picture || require('gravatar').url('', {}, https=nconf.get('https')); | 				post.picture = userData.picture || require('gravatar').url('', {}, https = nconf.get('https')); | ||||||
| 				post.signature = signature; | 				post.signature = signature; | ||||||
|  |  | ||||||
| 				if(post.editor !== '') { | 				if (post.editor !== '') { | ||||||
| 					user.getUserFields(post.editor, ['username', 'userslug'], function(err, editorData) { | 					user.getUserFields(post.editor, ['username', 'userslug'], function(err, editorData) { | ||||||
| 						if(err) return callback(); | 						if (err) return callback(); | ||||||
|  |  | ||||||
| 						post.editorname = editorData.username; | 						post.editorname = editorData.username; | ||||||
| 						post.editorslug = editorData.userslug; | 						post.editorslug = editorData.userslug; | ||||||
| @@ -104,7 +104,7 @@ var	RDB = require('./redis.js'), | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		async.eachSeries(pids, getPostSummary, function(err) { | 		async.eachSeries(pids, getPostSummary, function(err) { | ||||||
| 			if(!err) { | 			if (!err) { | ||||||
| 				callback(null, posts); | 				callback(null, posts); | ||||||
| 			} else { | 			} else { | ||||||
| 				callback(err, null); | 				callback(err, null); | ||||||
| @@ -120,22 +120,20 @@ var	RDB = require('./redis.js'), | |||||||
|  |  | ||||||
| 	Posts.getPostData = function(pid, callback) { | 	Posts.getPostData = function(pid, callback) { | ||||||
| 		RDB.hgetall('post:' + pid, function(err, data) { | 		RDB.hgetall('post:' + pid, function(err, data) { | ||||||
| 			if(err === null) { | 			if (err === null) { | ||||||
| 				plugins.fireHook('filter:post.get', data, function(data) { | 				plugins.fireHook('filter:post.get', data, function(data) { | ||||||
| 					callback(data); | 					callback(data); | ||||||
| 				}); | 				}); | ||||||
| 			} | 			} else | ||||||
| 			else |  | ||||||
| 				console.log(err); | 				console.log(err); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Posts.getPostFields = function(pid, fields, callback) { | 	Posts.getPostFields = function(pid, fields, callback) { | ||||||
| 		RDB.hmgetObject('post:' + pid, fields, function(err, data) { | 		RDB.hmgetObject('post:' + pid, fields, function(err, data) { | ||||||
| 			if(err === null) { | 			if (err === null) { | ||||||
| 				callback(data); | 				callback(data); | ||||||
| 			} | 			} else { | ||||||
| 			else { |  | ||||||
| 				console.log(err); | 				console.log(err); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| @@ -143,7 +141,7 @@ var	RDB = require('./redis.js'), | |||||||
|  |  | ||||||
| 	Posts.getPostField = function(pid, field, callback) { | 	Posts.getPostField = function(pid, field, callback) { | ||||||
| 		RDB.hget('post:' + pid, field, function(err, data) { | 		RDB.hget('post:' + pid, field, function(err, data) { | ||||||
| 			if(err === null) | 			if (err === null) | ||||||
| 				callback(data); | 				callback(data); | ||||||
| 			else | 			else | ||||||
| 				console.log(err); | 				console.log(err); | ||||||
| @@ -158,9 +156,9 @@ var	RDB = require('./redis.js'), | |||||||
| 	Posts.getPostsByPids = function(pids, callback) { | 	Posts.getPostsByPids = function(pids, callback) { | ||||||
| 		var posts = []; | 		var posts = []; | ||||||
|  |  | ||||||
| 		async.eachSeries(pids, function (pid, callback) { | 		async.eachSeries(pids, function(pid, callback) { | ||||||
| 			Posts.getPostData(pid, function(postData) { | 			Posts.getPostData(pid, function(postData) { | ||||||
| 				if(postData) { | 				if (postData) { | ||||||
| 					postData.relativeTime = utils.relativeTime(postData.timestamp); | 					postData.relativeTime = utils.relativeTime(postData.timestamp); | ||||||
| 					postData.post_rep = postData.reputation; | 					postData.post_rep = postData.reputation; | ||||||
| 					postData['edited-class'] = postData.editor !== '' ? '' : 'none'; | 					postData['edited-class'] = postData.editor !== '' ? '' : 'none'; | ||||||
| @@ -174,7 +172,7 @@ var	RDB = require('./redis.js'), | |||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
| 		}, function(err) { | 		}, function(err) { | ||||||
| 			if(!err) { | 			if (!err) { | ||||||
| 				callback(null, posts); | 				callback(null, posts); | ||||||
| 			} else { | 			} else { | ||||||
| 				callback(err, null); | 				callback(err, null); | ||||||
| @@ -209,7 +207,7 @@ var	RDB = require('./redis.js'), | |||||||
| 	Posts.emitTooManyPostsAlert = function(socket) { | 	Posts.emitTooManyPostsAlert = function(socket) { | ||||||
| 		socket.emit('event:alert', { | 		socket.emit('event:alert', { | ||||||
| 			title: 'Too many posts!', | 			title: 'Too many posts!', | ||||||
| 			message: 'You can only post every '+ meta.config.postDelay/1000 + ' seconds.', | 			message: 'You can only post every ' + meta.config.postDelay / 1000 + ' seconds.', | ||||||
| 			type: 'danger', | 			type: 'danger', | ||||||
| 			timeout: 2000 | 			timeout: 2000 | ||||||
| 		}); | 		}); | ||||||
| @@ -226,7 +224,7 @@ var	RDB = require('./redis.js'), | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		user.getUserField(uid, 'lastposttime', function(lastposttime) { | 		user.getUserField(uid, 'lastposttime', function(lastposttime) { | ||||||
| 			if(Date.now() - lastposttime < meta.config.postDelay) { | 			if (Date.now() - lastposttime < meta.config.postDelay) { | ||||||
| 				callback(new Error('too-many-posts'), null); | 				callback(new Error('too-many-posts'), null); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| @@ -245,10 +243,12 @@ var	RDB = require('./redis.js'), | |||||||
| 					threadTools.notify_followers(tid, uid); | 					threadTools.notify_followers(tid, uid); | ||||||
|  |  | ||||||
| 					Posts.addUserInfoToPost(postData, function() { | 					Posts.addUserInfoToPost(postData, function() { | ||||||
| 						var	socketData = { posts: [postData] }; | 						var socketData = { | ||||||
| 						io.sockets.in('topic_' + tid).emit('event:new_post', socketData); | 							posts: [postData] | ||||||
| 						io.sockets.in('recent_posts').emit('event:new_post', socketData); | 						}; | ||||||
| 						io.sockets.in('users/' + uid).emit('event:new_post', socketData); | 						io.sockets. in ('topic_' + tid).emit('event:new_post', socketData); | ||||||
|  | 						io.sockets. in ('recent_posts').emit('event:new_post', socketData); | ||||||
|  | 						io.sockets. in ('users/' + uid).emit('event:new_post', socketData); | ||||||
| 					}); | 					}); | ||||||
|  |  | ||||||
| 					callback(null, 'Reply successful'); | 					callback(null, 'Reply successful'); | ||||||
| @@ -369,28 +369,26 @@ var	RDB = require('./redis.js'), | |||||||
|  |  | ||||||
| 		user.getPostIds(uid, start, end, function(pids) { | 		user.getPostIds(uid, start, end, function(pids) { | ||||||
|  |  | ||||||
| 			if(pids && pids.length) { | 			if (pids && pids.length) { | ||||||
|  |  | ||||||
| 				Posts.getPostsByPids(pids, function(err, posts) { | 				Posts.getPostsByPids(pids, function(err, posts) { | ||||||
| 					callback(posts); | 					callback(posts); | ||||||
| 				}); | 				}); | ||||||
| 			} | 			} else | ||||||
| 			else |  | ||||||
| 				callback([]); | 				callback([]); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Posts.getTopicPostStats = function(socket) { | 	Posts.getTopicPostStats = function(socket) { | ||||||
| 		RDB.mget(['totaltopiccount', 'totalpostcount'], function(err, data) { | 		RDB.mget(['totaltopiccount', 'totalpostcount'], function(err, data) { | ||||||
| 			if(err === null) { | 			if (err === null) { | ||||||
| 				var stats = { | 				var stats = { | ||||||
| 					topics: data[0]?data[0]:0, | 					topics: data[0] ? data[0] : 0, | ||||||
| 					posts: data[1]?data[1]:0 | 					posts: data[1] ? data[1] : 0 | ||||||
| 				}; | 				}; | ||||||
|  |  | ||||||
| 				socket.emit('post.stats', stats); | 				socket.emit('post.stats', stats); | ||||||
| 			} | 			} else | ||||||
| 			else |  | ||||||
| 				console.log(err); | 				console.log(err); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| @@ -402,7 +400,7 @@ var	RDB = require('./redis.js'), | |||||||
| 			Posts.getPostField(pid, 'content', function(content) { | 			Posts.getPostField(pid, 'content', function(content) { | ||||||
| 				postSearch.remove(pid, function() { | 				postSearch.remove(pid, function() { | ||||||
|  |  | ||||||
| 					if(content && content.length) { | 					if (content && content.length) { | ||||||
| 						postSearch.index(content, pid); | 						postSearch.index(content, pid); | ||||||
| 					} | 					} | ||||||
| 					callback(null); | 					callback(null); | ||||||
| @@ -411,7 +409,7 @@ var	RDB = require('./redis.js'), | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		async.each(pids, reIndex, function(err) { | 		async.each(pids, reIndex, function(err) { | ||||||
| 			if(err) { | 			if (err) { | ||||||
| 				callback(err, null); | 				callback(err, null); | ||||||
| 			} else { | 			} else { | ||||||
| 				callback(null, 'Posts reindexed'); | 				callback(null, 'Posts reindexed'); | ||||||
| @@ -421,11 +419,11 @@ var	RDB = require('./redis.js'), | |||||||
|  |  | ||||||
| 	Posts.getFavourites = function(uid, callback) { | 	Posts.getFavourites = function(uid, callback) { | ||||||
| 		RDB.zrevrange('uid:' + uid + ':favourites', 0, -1, function(err, pids) { | 		RDB.zrevrange('uid:' + uid + ':favourites', 0, -1, function(err, pids) { | ||||||
| 			if(err) | 			if (err) | ||||||
| 				return callback(err, null); | 				return callback(err, null); | ||||||
|  |  | ||||||
| 			Posts.getPostSummaryByPids(pids, function(err, posts) { | 			Posts.getPostSummaryByPids(pids, function(err, posts) { | ||||||
| 				if(err) | 				if (err) | ||||||
| 					return callback(err, null); | 					return callback(err, null); | ||||||
|  |  | ||||||
| 				callback(null, posts); | 				callback(null, posts); | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								src/redis.js
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/redis.js
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ | |||||||
|  |  | ||||||
| 	RedisDB.exports = redis.createClient(nconf.get('redis:port'), nconf.get('redis:host')); | 	RedisDB.exports = redis.createClient(nconf.get('redis:port'), nconf.get('redis:host')); | ||||||
|  |  | ||||||
| 	if(nconf.get('redis:password')) { | 	if (nconf.get('redis:password')) { | ||||||
| 		RedisDB.exports.auth(nconf.get('redis:password')); | 		RedisDB.exports.auth(nconf.get('redis:password')); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -20,8 +20,8 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	* A possibly more efficient way of doing multiple sismember calls | 	 * A possibly more efficient way of doing multiple sismember calls | ||||||
| 	*/ | 	 */ | ||||||
| 	RedisDB.exports.sismembers = function(key, needles, callback) { | 	RedisDB.exports.sismembers = function(key, needles, callback) { | ||||||
| 		var tempkey = key + ':temp:' + utils.generateUUID(); | 		var tempkey = key + ':temp:' + utils.generateUUID(); | ||||||
| 		RedisDB.exports.sadd(tempkey, needles, function() { | 		RedisDB.exports.sadd(tempkey, needles, function() { | ||||||
| @@ -35,18 +35,17 @@ | |||||||
| 	/* | 	/* | ||||||
| 	 * gets fields of a hash as an object instead of an array | 	 * gets fields of a hash as an object instead of an array | ||||||
| 	 */ | 	 */ | ||||||
| 	RedisDB.exports.hmgetObject = function (key, fields, callback) { | 	RedisDB.exports.hmgetObject = function(key, fields, callback) { | ||||||
| 		RedisDB.exports.hmget(key, fields, function(err, data) { | 		RedisDB.exports.hmget(key, fields, function(err, data) { | ||||||
| 			if(err === null) { | 			if (err === null) { | ||||||
| 				var returnData = {}; | 				var returnData = {}; | ||||||
|  |  | ||||||
| 				for(var i=0, ii=fields.length; i<ii; ++i) { | 				for (var i = 0, ii = fields.length; i < ii; ++i) { | ||||||
| 					returnData[fields[i]] = data[i]; | 					returnData[fields[i]] = data[i]; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				callback(null, returnData); | 				callback(null, returnData); | ||||||
| 			} | 			} else { | ||||||
| 			else { |  | ||||||
| 				console.log(err); | 				console.log(err); | ||||||
| 				callback(err, null); | 				callback(err, null); | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -1,4 +1,3 @@ | |||||||
|  |  | ||||||
| var user = require('./../user.js'), | var user = require('./../user.js'), | ||||||
| 	Groups = require('../groups'), | 	Groups = require('../groups'), | ||||||
| 	topics = require('./../topics.js'), | 	topics = require('./../topics.js'), | ||||||
| @@ -18,7 +17,7 @@ var user = require('./../user.js'), | |||||||
|  |  | ||||||
| 	Admin.build_header = function(res) { | 	Admin.build_header = function(res) { | ||||||
| 		return templates['admin/header'].parse({ | 		return templates['admin/header'].parse({ | ||||||
| 			csrf:res.locals.csrf_token, | 			csrf: res.locals.csrf_token, | ||||||
| 			relative_path: nconf.get('relative_path') | 			relative_path: nconf.get('relative_path') | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| @@ -26,14 +25,14 @@ var user = require('./../user.js'), | |||||||
| 	Admin.create_routes = function(app) { | 	Admin.create_routes = function(app) { | ||||||
|  |  | ||||||
| 		(function() { | 		(function() { | ||||||
| 			var	routes = [ | 			var routes = [ | ||||||
| 					'categories/active', 'categories/disabled', 'users', 'topics', 'settings', 'themes', | 				'categories/active', 'categories/disabled', 'users', 'topics', 'settings', 'themes', | ||||||
| 					'twitter', 'facebook', 'gplus', 'redis', 'motd', 'groups', | 				'twitter', 'facebook', 'gplus', 'redis', 'motd', 'groups', | ||||||
| 					'users/latest', 'users/sort-posts', 'users/sort-reputation', | 				'users/latest', 'users/sort-posts', 'users/sort-reputation', | ||||||
| 					'users/search', 'plugins' | 				'users/search', 'plugins' | ||||||
| 				]; | 			]; | ||||||
|  |  | ||||||
| 			for (var i=0, ii=routes.length; i<ii; i++) { | 			for (var i = 0, ii = routes.length; i < ii; i++) { | ||||||
| 				(function(route) { | 				(function(route) { | ||||||
| 					app.get('/admin/' + route, Admin.isAdmin, function(req, res) { | 					app.get('/admin/' + route, Admin.isAdmin, function(req, res) { | ||||||
| 						res.send(Admin.build_header(res) + app.create_route('admin/' + route) + templates['admin/footer']); | 						res.send(Admin.build_header(res) + app.create_route('admin/' + route) + templates['admin/footer']); | ||||||
| @@ -43,7 +42,7 @@ var user = require('./../user.js'), | |||||||
|  |  | ||||||
| 			var unit_tests = ['categories']; | 			var unit_tests = ['categories']; | ||||||
|  |  | ||||||
| 			for (var i=0, ii=unit_tests.length; i<ii; i++) { | 			for (var i = 0, ii = unit_tests.length; i < ii; i++) { | ||||||
| 				(function(route) { | 				(function(route) { | ||||||
| 					app.get('/admin/testing/' + route, Admin.isAdmin, function(req, res) { | 					app.get('/admin/testing/' + route, Admin.isAdmin, function(req, res) { | ||||||
| 						res.send(Admin.build_header(res) + app.create_route('admin/testing/' + route) + templates['admin/footer']); | 						res.send(Admin.build_header(res) + app.create_route('admin/testing/' + route) + templates['admin/footer']); | ||||||
| @@ -62,34 +61,59 @@ var user = require('./../user.js'), | |||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/api/admin/index', function(req, res) { | 		app.get('/api/admin/index', function(req, res) { | ||||||
| 			res.json({version:pkg.version}); | 			res.json({ | ||||||
|  | 				version: pkg.version | ||||||
|  | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/api/admin/users/search', function(req, res) { | 		app.get('/api/admin/users/search', function(req, res) { | ||||||
| 			res.json({search_display: 'block', loadmore_display:'none', users: []}); | 			res.json({ | ||||||
|  | 				search_display: 'block', | ||||||
|  | 				loadmore_display: 'none', | ||||||
|  | 				users: [] | ||||||
|  | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/api/admin/users/latest', function(req, res) { | 		app.get('/api/admin/users/latest', function(req, res) { | ||||||
| 			user.getUsers('users:joindate', 0, 49, function(err, data) { | 			user.getUsers('users:joindate', 0, 49, function(err, data) { | ||||||
| 				res.json({ search_display: 'none', loadmore_display:'block', users:data, yourid:req.user.uid }); | 				res.json({ | ||||||
|  | 					search_display: 'none', | ||||||
|  | 					loadmore_display: 'block', | ||||||
|  | 					users: data, | ||||||
|  | 					yourid: req.user.uid | ||||||
|  | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/api/admin/users/sort-posts', function(req, res) { | 		app.get('/api/admin/users/sort-posts', function(req, res) { | ||||||
| 			user.getUsers('users:postcount', 0, 49, function(err, data) { | 			user.getUsers('users:postcount', 0, 49, function(err, data) { | ||||||
| 				res.json({ search_display: 'none', loadmore_display:'block', users:data, yourid:req.user.uid }); | 				res.json({ | ||||||
|  | 					search_display: 'none', | ||||||
|  | 					loadmore_display: 'block', | ||||||
|  | 					users: data, | ||||||
|  | 					yourid: req.user.uid | ||||||
|  | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/api/admin/users/sort-reputation', function(req, res) { | 		app.get('/api/admin/users/sort-reputation', function(req, res) { | ||||||
| 			user.getUsers('users:reputation', 0, 49, function(err, data) { | 			user.getUsers('users:reputation', 0, 49, function(err, data) { | ||||||
| 				res.json({ search_display: 'none', loadmore_display:'block', users:data, yourid:req.user.uid }); | 				res.json({ | ||||||
|  | 					search_display: 'none', | ||||||
|  | 					loadmore_display: 'block', | ||||||
|  | 					users: data, | ||||||
|  | 					yourid: req.user.uid | ||||||
|  | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/api/admin/users', function(req, res) { | 		app.get('/api/admin/users', function(req, res) { | ||||||
| 			user.getUsers('users:joindate', 0, 49, function(err, data) { | 			user.getUsers('users:joindate', 0, 49, function(err, data) { | ||||||
| 				res.json({ search_display: 'none', users:data, yourid:req.user.uid }); | 				res.json({ | ||||||
|  | 					search_display: 'none', | ||||||
|  | 					users: data, | ||||||
|  | 					yourid: req.user.uid | ||||||
|  | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| @@ -130,20 +154,20 @@ var user = require('./../user.js'), | |||||||
| 				data = data.split("\r\n"); | 				data = data.split("\r\n"); | ||||||
| 				var finalData = {}; | 				var finalData = {}; | ||||||
|  |  | ||||||
| 				for(var i in data) { | 				for (var i in data) { | ||||||
|  |  | ||||||
| 					if(data[i].indexOf(':') == -1 || !data[i]) | 					if (data[i].indexOf(':') == -1 || !data[i]) | ||||||
| 						continue; | 						continue; | ||||||
|  |  | ||||||
| 					try { | 					try { | ||||||
| 						data[i] = data[i].replace(/:/,"\":\""); | 						data[i] = data[i].replace(/:/, "\":\""); | ||||||
| 						var json = "{\"" + data[i] + "\"}"; | 						var json = "{\"" + data[i] + "\"}"; | ||||||
|  |  | ||||||
| 						var jsonObject = JSON.parse(json); | 						var jsonObject = JSON.parse(json); | ||||||
| 						for(var key in jsonObject) { | 						for (var key in jsonObject) { | ||||||
| 							finalData[key] = jsonObject[key]; | 							finalData[key] = jsonObject[key]; | ||||||
| 						} | 						} | ||||||
| 					} catch(err){ | 					} catch (err) { | ||||||
| 						winston.warn('can\'t parse redis status variable, ignoring', i, data[i], err); | 						winston.warn('can\'t parse redis status variable, ignoring', i, data[i], err); | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ var user = require('./../user.js'), | |||||||
| 			config['postDelay'] = meta.config['postDelay']; | 			config['postDelay'] = meta.config['postDelay']; | ||||||
| 			config['minimumTitleLength'] = meta.config['minimumTitleLength']; | 			config['minimumTitleLength'] = meta.config['minimumTitleLength']; | ||||||
| 			config['minimumPostLength'] = meta.config['minimumPostLength']; | 			config['minimumPostLength'] = meta.config['minimumPostLength']; | ||||||
| 			config['imgurClientIDSet'] = !!meta.config['imgurClientID']; | 			config['imgurClientIDSet'] = !! meta.config['imgurClientID']; | ||||||
| 			config['minimumUsernameLength'] = meta.config['minimumUsernameLength']; | 			config['minimumUsernameLength'] = meta.config['minimumUsernameLength']; | ||||||
| 			config['maximumUsernameLength'] = meta.config['maximumUsernameLength']; | 			config['maximumUsernameLength'] = meta.config['maximumUsernameLength']; | ||||||
| 			config['minimumPasswordLength'] = meta.config['minimumPasswordLength']; | 			config['minimumPasswordLength'] = meta.config['minimumPasswordLength']; | ||||||
| @@ -41,7 +41,7 @@ var user = require('./../user.js'), | |||||||
| 				function iterator(category, callback) { | 				function iterator(category, callback) { | ||||||
| 					categories.getRecentReplies(category.cid, 2, function(posts) { | 					categories.getRecentReplies(category.cid, 2, function(posts) { | ||||||
| 						category["posts"] = posts; | 						category["posts"] = posts; | ||||||
| 						category["post_count"] = posts.length>2 ? 2 : posts.length; | 						category["post_count"] = posts.length > 2 ? 2 : posts.length; | ||||||
| 						callback(null); | 						callback(null); | ||||||
| 					}); | 					}); | ||||||
| 				} | 				} | ||||||
| @@ -70,7 +70,7 @@ var user = require('./../user.js'), | |||||||
| 					'login_window:spansize': 'col-md-6', | 					'login_window:spansize': 'col-md-6', | ||||||
| 					'alternate_logins:display': 'block' | 					'alternate_logins:display': 'block' | ||||||
| 				} | 				} | ||||||
| 				for (var i=0, ii=num_strategies; i<ii; i++) { | 				for (var i = 0, ii = num_strategies; i < ii; i++) { | ||||||
| 					data[login_strategies[i] + ':display'] = 'active'; | 					data[login_strategies[i] + ':display'] = 'active'; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| @@ -95,7 +95,7 @@ var user = require('./../user.js'), | |||||||
| 					'register_window:spansize': 'col-md-6', | 					'register_window:spansize': 'col-md-6', | ||||||
| 					'alternate_logins:display': 'block' | 					'alternate_logins:display': 'block' | ||||||
| 				} | 				} | ||||||
| 				for (var i=0, ii=num_strategies; i<ii; i++) { | 				for (var i = 0, ii = num_strategies; i < ii; i++) { | ||||||
| 					data[login_strategies[i] + ':display'] = 'active'; | 					data[login_strategies[i] + ':display'] = 'active'; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| @@ -111,7 +111,7 @@ var user = require('./../user.js'), | |||||||
| 			var uid = (req.user) ? req.user.uid : 0; | 			var uid = (req.user) ? req.user.uid : 0; | ||||||
| 			topics.getTopicWithPosts(req.params.id, uid, 0, 10, function(err, data) { | 			topics.getTopicWithPosts(req.params.id, uid, 0, 10, function(err, data) { | ||||||
| 				if (!err) { | 				if (!err) { | ||||||
| 					if(data.deleted === '1' && data.expose_tools === 0) { | 					if (data.deleted === '1' && data.expose_tools === 0) { | ||||||
| 						return res.json(404, {}); | 						return res.json(404, {}); | ||||||
| 					} | 					} | ||||||
| 					res.json(data); | 					res.json(data); | ||||||
| @@ -184,11 +184,11 @@ var user = require('./../user.js'), | |||||||
|  |  | ||||||
| 		app.get('/api/search', function(req, res) { | 		app.get('/api/search', function(req, res) { | ||||||
| 			return res.json({ | 			return res.json({ | ||||||
| 				show_no_topics:'hide', | 				show_no_topics: 'hide', | ||||||
| 				show_no_posts:'hide', | 				show_no_posts: 'hide', | ||||||
| 				search_query:'', | 				search_query: '', | ||||||
| 				posts:[], | 				posts: [], | ||||||
| 				topics:[] | 				topics: [] | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| @@ -206,11 +206,11 @@ var user = require('./../user.js'), | |||||||
|  |  | ||||||
| 			function searchPosts(callback) { | 			function searchPosts(callback) { | ||||||
| 				search(postSearch, function(err, pids) { | 				search(postSearch, function(err, pids) { | ||||||
| 					if(err) | 					if (err) | ||||||
| 						return callback(err, null); | 						return callback(err, null); | ||||||
|  |  | ||||||
| 					posts.getPostSummaryByPids(pids, function(err, posts) { | 					posts.getPostSummaryByPids(pids, function(err, posts) { | ||||||
| 						if(err) | 						if (err) | ||||||
| 							return callback(err, null); | 							return callback(err, null); | ||||||
| 						callback(null, posts); | 						callback(null, posts); | ||||||
| 					}); | 					}); | ||||||
| @@ -219,7 +219,7 @@ var user = require('./../user.js'), | |||||||
|  |  | ||||||
| 			function searchTopics(callback) { | 			function searchTopics(callback) { | ||||||
| 				search(topicSearch, function(err, tids) { | 				search(topicSearch, function(err, tids) { | ||||||
| 					if(err) | 					if (err) | ||||||
| 						return callback(err, null); | 						return callback(err, null); | ||||||
|  |  | ||||||
| 					topics.getTopicsByTids(tids, 0, function(topics) { | 					topics.getTopicsByTids(tids, 0, function(topics) { | ||||||
| @@ -233,11 +233,11 @@ var user = require('./../user.js'), | |||||||
| 					return next(); | 					return next(); | ||||||
|  |  | ||||||
| 				return res.json({ | 				return res.json({ | ||||||
| 					show_no_topics: results[1].length? 'hide':'', | 					show_no_topics: results[1].length ? 'hide' : '', | ||||||
| 					show_no_posts: results[0].length? 'hide':'', | 					show_no_posts: results[0].length ? 'hide' : '', | ||||||
| 					search_query:req.params.term, | 					search_query: req.params.term, | ||||||
| 					posts:results[0], | 					posts: results[0], | ||||||
| 					topics:results[1] | 					topics: results[1] | ||||||
| 				}); | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| @@ -247,7 +247,9 @@ var user = require('./../user.js'), | |||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/api/reset/:code', function(req, res) { | 		app.get('/api/reset/:code', function(req, res) { | ||||||
| 			res.json({ reset_code: req.params.code }); | 			res.json({ | ||||||
|  | 				reset_code: req.params.code | ||||||
|  | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/api/404', function(req, res) { | 		app.get('/api/404', function(req, res) { | ||||||
|   | |||||||
| @@ -25,7 +25,9 @@ | |||||||
| 			callbackURL: nconf.get('url') + 'auth/twitter/callback' | 			callbackURL: nconf.get('url') + 'auth/twitter/callback' | ||||||
| 		}, function(token, tokenSecret, profile, done) { | 		}, function(token, tokenSecret, profile, done) { | ||||||
| 			login_module.loginViaTwitter(profile.id, profile.username, profile.photos, function(err, user) { | 			login_module.loginViaTwitter(profile.id, profile.username, profile.photos, function(err, user) { | ||||||
| 				if (err) { return done(err); } | 				if (err) { | ||||||
|  | 					return done(err); | ||||||
|  | 				} | ||||||
| 				done(null, user); | 				done(null, user); | ||||||
| 			}); | 			}); | ||||||
| 		})); | 		})); | ||||||
| @@ -40,7 +42,9 @@ | |||||||
| 			callbackURL: nconf.get('url') + 'auth/google/callback' | 			callbackURL: nconf.get('url') + 'auth/google/callback' | ||||||
| 		}, function(accessToken, refreshToken, profile, done) { | 		}, function(accessToken, refreshToken, profile, done) { | ||||||
| 			login_module.loginViaGoogle(profile.id, profile.displayName, profile.emails[0].value, function(err, user) { | 			login_module.loginViaGoogle(profile.id, profile.displayName, profile.emails[0].value, function(err, user) { | ||||||
| 				if (err) { return done(err); } | 				if (err) { | ||||||
|  | 					return done(err); | ||||||
|  | 				} | ||||||
| 				done(null, user); | 				done(null, user); | ||||||
| 			}); | 			}); | ||||||
| 		})); | 		})); | ||||||
| @@ -55,7 +59,9 @@ | |||||||
| 			callbackURL: nconf.get('url') + 'auth/facebook/callback' | 			callbackURL: nconf.get('url') + 'auth/facebook/callback' | ||||||
| 		}, function(accessToken, refreshToken, profile, done) { | 		}, function(accessToken, refreshToken, profile, done) { | ||||||
| 			login_module.loginViaFacebook(profile.id, profile.displayName, profile.emails[0].value, function(err, user) { | 			login_module.loginViaFacebook(profile.id, profile.displayName, profile.emails[0].value, function(err, user) { | ||||||
| 				if (err) { return done(err); } | 				if (err) { | ||||||
|  | 					return done(err); | ||||||
|  | 				} | ||||||
| 				done(null, user); | 				done(null, user); | ||||||
| 			}); | 			}); | ||||||
| 		})); | 		})); | ||||||
| @@ -90,7 +96,10 @@ | |||||||
| 				winston.info('[Auth] Session ' + req.sessionID + ' logout (uid: ' + req.user.uid + ')'); | 				winston.info('[Auth] Session ' + req.sessionID + ' logout (uid: ' + req.user.uid + ')'); | ||||||
| 				login_module.logout(req.sessionID, function(logout) { | 				login_module.logout(req.sessionID, function(logout) { | ||||||
| 					req.logout(); | 					req.logout(); | ||||||
| 					app.build_header({ req: req, res: res }, function(err, header) { | 					app.build_header({ | ||||||
|  | 						req: req, | ||||||
|  | 						res: res | ||||||
|  | 					}, function(err, header) { | ||||||
| 						res.send(header + templates['logout'] + templates['footer']); | 						res.send(header + templates['logout'] + templates['footer']); | ||||||
| 					}); | 					}); | ||||||
| 				}); | 				}); | ||||||
| @@ -107,7 +116,9 @@ | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (login_strategies.indexOf('google') !== -1) { | 		if (login_strategies.indexOf('google') !== -1) { | ||||||
| 			app.get('/auth/google', passport.authenticate('google', { scope: 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email' })); | 			app.get('/auth/google', passport.authenticate('google', { | ||||||
|  | 				scope: 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email' | ||||||
|  | 			})); | ||||||
|  |  | ||||||
| 			app.get('/auth/google/callback', passport.authenticate('google', { | 			app.get('/auth/google/callback', passport.authenticate('google', { | ||||||
| 				successRedirect: '/', | 				successRedirect: '/', | ||||||
| @@ -116,7 +127,9 @@ | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (login_strategies.indexOf('facebook') !== -1) { | 		if (login_strategies.indexOf('facebook') !== -1) { | ||||||
| 			app.get('/auth/facebook', passport.authenticate('facebook', { scope: 'email' })); | 			app.get('/auth/facebook', passport.authenticate('facebook', { | ||||||
|  | 				scope: 'email' | ||||||
|  | 			})); | ||||||
|  |  | ||||||
| 			app.get('/auth/facebook/callback', passport.authenticate('facebook', { | 			app.get('/auth/facebook/callback', passport.authenticate('facebook', { | ||||||
| 				successRedirect: '/', | 				successRedirect: '/', | ||||||
| @@ -127,29 +140,41 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| 		app.get('/reset/:code', function(req, res) { | 		app.get('/reset/:code', function(req, res) { | ||||||
| 			app.build_header({ req: req, res: res }, function(err, header) { | 			app.build_header({ | ||||||
| 				res.send(header + app.create_route('reset/'+req.params.code) + templates['footer']); | 				req: req, | ||||||
|  | 				res: res | ||||||
|  | 			}, function(err, header) { | ||||||
|  | 				res.send(header + app.create_route('reset/' + req.params.code) + templates['footer']); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/reset', function(req, res) { | 		app.get('/reset', function(req, res) { | ||||||
| 			app.build_header({ req: req, res: res }, function(err, header) { | 			app.build_header({ | ||||||
|  | 				req: req, | ||||||
|  | 				res: res | ||||||
|  | 			}, function(err, header) { | ||||||
| 				res.send(header + app.create_route('reset') + templates['footer']); | 				res.send(header + app.create_route('reset') + templates['footer']); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.post('/login', function(req, res, next) { | 		app.post('/login', function(req, res, next) { | ||||||
| 			passport.authenticate('local', function(err, user, info) { | 			passport.authenticate('local', function(err, user, info) { | ||||||
| 				if(err) { | 				if (err) { | ||||||
| 					return next(err); | 					return next(err); | ||||||
| 				} | 				} | ||||||
| 				if (!user) { | 				if (!user) { | ||||||
| 					return res.send({ success : false, message : info.message }); | 					return res.send({ | ||||||
|  | 						success: false, | ||||||
|  | 						message: info.message | ||||||
|  | 					}); | ||||||
| 				} | 				} | ||||||
| 				req.login({ | 				req.login({ | ||||||
| 					uid: user.uid | 					uid: user.uid | ||||||
| 				}, function() { | 				}, function() { | ||||||
| 					res.send({ success : true, message : 'authentication succeeded' }); | 					res.send({ | ||||||
|  | 						success: true, | ||||||
|  | 						message: 'authentication succeeded' | ||||||
|  | 					}); | ||||||
| 				}); | 				}); | ||||||
| 			})(req, res, next); | 			})(req, res, next); | ||||||
| 		}); | 		}); | ||||||
|   | |||||||
| @@ -1,5 +1,3 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| (function(TestBed) { | (function(TestBed) { | ||||||
| 	TestBed.create_routes = function(app) { | 	TestBed.create_routes = function(app) { | ||||||
|  |  | ||||||
| @@ -17,7 +15,7 @@ | |||||||
| 			function withCaching() { | 			function withCaching() { | ||||||
| 				var time = process.hrtime(); | 				var time = process.hrtime(); | ||||||
|  |  | ||||||
| 				for(var n=0; n<runCount; ++n) { | 				for (var n = 0; n < runCount; ++n) { | ||||||
| 					for (var i = 0, len = myArray.length; i < len; ++i) { | 					for (var i = 0, len = myArray.length; i < len; ++i) { | ||||||
| 						f(myArray[i]); | 						f(myArray[i]); | ||||||
| 					} | 					} | ||||||
| @@ -31,7 +29,7 @@ | |||||||
| 			function withoutCaching() { | 			function withoutCaching() { | ||||||
| 				var time = process.hrtime(); | 				var time = process.hrtime(); | ||||||
|  |  | ||||||
| 				for(var n=0; n<runCount; ++n) { | 				for (var n = 0; n < runCount; ++n) { | ||||||
| 					for (var i = 0; i < myArray.length; ++i) { | 					for (var i = 0; i < myArray.length; ++i) { | ||||||
| 						f(myArray[i]); | 						f(myArray[i]); | ||||||
| 					} | 					} | ||||||
| @@ -45,7 +43,7 @@ | |||||||
| 			function withForeach() { | 			function withForeach() { | ||||||
| 				var time = process.hrtime(); | 				var time = process.hrtime(); | ||||||
|  |  | ||||||
| 				for(var n=0; n<runCount; ++n) { | 				for (var n = 0; n < runCount; ++n) { | ||||||
| 					myArray.forEach(function(index) { | 					myArray.forEach(function(index) { | ||||||
|  |  | ||||||
| 					}); | 					}); | ||||||
|   | |||||||
| @@ -11,63 +11,83 @@ var user = require('./../user.js'), | |||||||
|  |  | ||||||
| 		app.get('/uid/:uid', function(req, res) { | 		app.get('/uid/:uid', function(req, res) { | ||||||
|  |  | ||||||
| 			if(!req.params.uid) | 			if (!req.params.uid) | ||||||
| 				return res.redirect('/404'); | 				return res.redirect('/404'); | ||||||
|  |  | ||||||
| 			user.getUserData(req.params.uid, function(err, data) { | 			user.getUserData(req.params.uid, function(err, data) { | ||||||
| 				if(data) { | 				if (data) { | ||||||
| 					res.send(data); | 					res.send(data); | ||||||
| 				} else { | 				} else { | ||||||
| 					res.json(404, {error:"User doesn't exist!"}); | 					res.json(404, { | ||||||
|  | 						error: "User doesn't exist!" | ||||||
|  | 					}); | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
|  |  | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/users', function(req, res) { | 		app.get('/users', function(req, res) { | ||||||
| 			app.build_header({ req: req, res: res }, function(err, header) { | 			app.build_header({ | ||||||
|  | 				req: req, | ||||||
|  | 				res: res | ||||||
|  | 			}, function(err, header) { | ||||||
| 				res.send(header + app.create_route("users", "users") + templates['footer']); | 				res.send(header + app.create_route("users", "users") + templates['footer']); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/users-latest', function(req, res) { | 		app.get('/users-latest', function(req, res) { | ||||||
| 			app.build_header({ req: req, res: res }, function(err, header) { | 			app.build_header({ | ||||||
|  | 				req: req, | ||||||
|  | 				res: res | ||||||
|  | 			}, function(err, header) { | ||||||
| 				res.send(header + app.create_route("users-latest", "users") + templates['footer']); | 				res.send(header + app.create_route("users-latest", "users") + templates['footer']); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/users-sort-posts', function(req, res) { | 		app.get('/users-sort-posts', function(req, res) { | ||||||
| 			app.build_header({ req: req, res: res }, function(err, header) { | 			app.build_header({ | ||||||
|  | 				req: req, | ||||||
|  | 				res: res | ||||||
|  | 			}, function(err, header) { | ||||||
| 				res.send(header + app.create_route("users-sort-posts", "users") + templates['footer']); | 				res.send(header + app.create_route("users-sort-posts", "users") + templates['footer']); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/users-sort-reputation', function(req, res) { | 		app.get('/users-sort-reputation', function(req, res) { | ||||||
| 			app.build_header({ req: req, res: res }, function(err, header) { | 			app.build_header({ | ||||||
|  | 				req: req, | ||||||
|  | 				res: res | ||||||
|  | 			}, function(err, header) { | ||||||
| 				res.send(header + app.create_route("users-sort-reputation", "users") + templates['footer']); | 				res.send(header + app.create_route("users-sort-reputation", "users") + templates['footer']); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/users-search', function(req, res) { | 		app.get('/users-search', function(req, res) { | ||||||
| 			app.build_header({ req: req, res: res }, function(err, header) { | 			app.build_header({ | ||||||
|  | 				req: req, | ||||||
|  | 				res: res | ||||||
|  | 			}, function(err, header) { | ||||||
| 				res.send(header + app.create_route("users-search", "users") + templates['footer']); | 				res.send(header + app.create_route("users-search", "users") + templates['footer']); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/users/:userslug', function(req, res, next) { | 		app.get('/users/:userslug', function(req, res, next) { | ||||||
|  |  | ||||||
| 			if(!req.params.userslug) { | 			if (!req.params.userslug) { | ||||||
| 				next(); | 				next(); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			user.get_uid_by_userslug(req.params.userslug, function(err, uid) { | 			user.get_uid_by_userslug(req.params.userslug, function(err, uid) { | ||||||
| 				if(!uid) { | 				if (!uid) { | ||||||
| 					return next(); | 					return next(); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				app.build_header({ req: req, res: res }, function(err, header) { | 				app.build_header({ | ||||||
| 					res.send(header + app.create_route('users/' + req.params.userslug, 'account')  + templates['footer']); | 					req: req, | ||||||
|  | 					res: res | ||||||
|  | 				}, function(err, header) { | ||||||
|  | 					res.send(header + app.create_route('users/' + req.params.userslug, 'account') + templates['footer']); | ||||||
| 				}); | 				}); | ||||||
|  |  | ||||||
| 			}); | 			}); | ||||||
| @@ -75,13 +95,16 @@ var user = require('./../user.js'), | |||||||
|  |  | ||||||
| 		app.get('/users/:userslug/edit', function(req, res) { | 		app.get('/users/:userslug/edit', function(req, res) { | ||||||
|  |  | ||||||
| 			if(!req.user) | 			if (!req.user) | ||||||
| 				return res.redirect('/403'); | 				return res.redirect('/403'); | ||||||
|  |  | ||||||
| 			user.getUserField(req.user.uid, 'userslug', function(err, userslug) { | 			user.getUserField(req.user.uid, 'userslug', function(err, userslug) { | ||||||
| 				if(req.params.userslug && userslug === req.params.userslug) { | 				if (req.params.userslug && userslug === req.params.userslug) { | ||||||
| 					app.build_header({ req: req, res: res }, function(err, header) { | 					app.build_header({ | ||||||
| 						res.send(header + app.create_route('users/'+req.params.userslug+'/edit','accountedit') + templates['footer']); | 						req: req, | ||||||
|  | 						res: res | ||||||
|  | 					}, function(err, header) { | ||||||
|  | 						res.send(header + app.create_route('users/' + req.params.userslug + '/edit', 'accountedit') + templates['footer']); | ||||||
| 					}); | 					}); | ||||||
| 				} else { | 				} else { | ||||||
| 					return res.redirect('/404'); | 					return res.redirect('/404'); | ||||||
| @@ -91,13 +114,16 @@ var user = require('./../user.js'), | |||||||
|  |  | ||||||
| 		app.get('/users/:userslug/settings', function(req, res) { | 		app.get('/users/:userslug/settings', function(req, res) { | ||||||
|  |  | ||||||
| 			if(!req.user) | 			if (!req.user) | ||||||
| 				return res.redirect('/403'); | 				return res.redirect('/403'); | ||||||
|  |  | ||||||
| 			user.getUserField(req.user.uid, 'userslug', function(err, userslug) { | 			user.getUserField(req.user.uid, 'userslug', function(err, userslug) { | ||||||
| 				if(req.params.userslug && userslug === req.params.userslug) { | 				if (req.params.userslug && userslug === req.params.userslug) { | ||||||
| 					app.build_header({ req: req, res: res }, function(err, header) { | 					app.build_header({ | ||||||
| 						res.send(header + app.create_route('users/'+req.params.userslug+'/settings','accountsettings') + templates['footer']); | 						req: req, | ||||||
|  | 						res: res | ||||||
|  | 					}, function(err, header) { | ||||||
|  | 						res.send(header + app.create_route('users/' + req.params.userslug + '/settings', 'accountsettings') + templates['footer']); | ||||||
| 					}) | 					}) | ||||||
| 				} else { | 				} else { | ||||||
| 					return res.redirect('/404'); | 					return res.redirect('/404'); | ||||||
| @@ -106,10 +132,10 @@ var user = require('./../user.js'), | |||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.post('/users/uploadpicture', function(req, res) { | 		app.post('/users/uploadpicture', function(req, res) { | ||||||
| 			if(!req.user) | 			if (!req.user) | ||||||
| 				return res.redirect('/403'); | 				return res.redirect('/403'); | ||||||
|  |  | ||||||
| 			if(req.files.userPhoto.size > 262144) { | 			if (req.files.userPhoto.size > 262144) { | ||||||
| 				res.send({ | 				res.send({ | ||||||
| 					error: 'Images must be smaller than 256kb!' | 					error: 'Images must be smaller than 256kb!' | ||||||
| 				}); | 				}); | ||||||
| @@ -118,7 +144,7 @@ var user = require('./../user.js'), | |||||||
|  |  | ||||||
| 			var allowedTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif']; | 			var allowedTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif']; | ||||||
|  |  | ||||||
| 			if(allowedTypes.indexOf(req.files.userPhoto.type) === -1) { | 			if (allowedTypes.indexOf(req.files.userPhoto.type) === -1) { | ||||||
| 				res.send({ | 				res.send({ | ||||||
| 					error: 'Allowed image types are png, jpg and gif!' | 					error: 'Allowed image types are png, jpg and gif!' | ||||||
| 				}); | 				}); | ||||||
| @@ -126,7 +152,7 @@ var user = require('./../user.js'), | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			user.getUserField(req.user.uid, 'uploadedpicture', function(err, oldpicture) { | 			user.getUserField(req.user.uid, 'uploadedpicture', function(err, oldpicture) { | ||||||
| 				if(!oldpicture) { | 				if (!oldpicture) { | ||||||
| 					uploadUserPicture(req.user.uid, path.extname(req.files.userPhoto.name), req.files.userPhoto.path, res); | 					uploadUserPicture(req.user.uid, path.extname(req.files.userPhoto.name), req.files.userPhoto.path, res); | ||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
| @@ -134,7 +160,7 @@ var user = require('./../user.js'), | |||||||
| 				var absolutePath = path.join(process.cwd(), global.nconf.get('upload_path'), path.basename(oldpicture)); | 				var absolutePath = path.join(process.cwd(), global.nconf.get('upload_path'), path.basename(oldpicture)); | ||||||
|  |  | ||||||
| 				fs.unlink(absolutePath, function(err) { | 				fs.unlink(absolutePath, function(err) { | ||||||
| 					if(err) { | 					if (err) { | ||||||
| 						winston.err(err); | 						winston.err(err); | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| @@ -144,7 +170,7 @@ var user = require('./../user.js'), | |||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		function uploadUserPicture(uid, extension, tempPath, res) { | 		function uploadUserPicture(uid, extension, tempPath, res) { | ||||||
| 			if(!extension) { | 			if (!extension) { | ||||||
| 				res.send({ | 				res.send({ | ||||||
| 					error: 'Error uploading file! Error : Invalid extension!' | 					error: 'Error uploading file! Error : Invalid extension!' | ||||||
| 				}); | 				}); | ||||||
| @@ -154,7 +180,7 @@ var user = require('./../user.js'), | |||||||
| 			var filename = uid + '-profileimg' + extension; | 			var filename = uid + '-profileimg' + extension; | ||||||
| 			var uploadPath = path.join(process.cwd(), global.nconf.get('upload_path'), filename); | 			var uploadPath = path.join(process.cwd(), global.nconf.get('upload_path'), filename); | ||||||
|  |  | ||||||
| 			winston.info('Attempting upload to: '+ uploadPath); | 			winston.info('Attempting upload to: ' + uploadPath); | ||||||
|  |  | ||||||
| 			var is = fs.createReadStream(tempPath); | 			var is = fs.createReadStream(tempPath); | ||||||
| 			var os = fs.createWriteStream(uploadPath); | 			var os = fs.createWriteStream(uploadPath); | ||||||
| @@ -169,15 +195,17 @@ var user = require('./../user.js'), | |||||||
|  |  | ||||||
| 				require('node-imagemagick').crop({ | 				require('node-imagemagick').crop({ | ||||||
| 					srcPath: uploadPath, | 					srcPath: uploadPath, | ||||||
|   					dstPath: uploadPath, | 					dstPath: uploadPath, | ||||||
| 					width: 128, | 					width: 128, | ||||||
| 					height: 128 | 					height: 128 | ||||||
| 				}, function(err, stdout, stderr){ | 				}, function(err, stdout, stderr) { | ||||||
| 					if (err) { | 					if (err) { | ||||||
| 						winston.err(err); | 						winston.err(err); | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					res.json({ path: imageUrl }); | 					res.json({ | ||||||
|  | 						path: imageUrl | ||||||
|  | 					}); | ||||||
| 				}); | 				}); | ||||||
| 			}); | 			}); | ||||||
|  |  | ||||||
| @@ -191,49 +219,58 @@ var user = require('./../user.js'), | |||||||
|  |  | ||||||
| 		app.get('/users/:userslug/following', function(req, res) { | 		app.get('/users/:userslug/following', function(req, res) { | ||||||
|  |  | ||||||
| 			if(!req.user) | 			if (!req.user) | ||||||
| 				return res.redirect('/403'); | 				return res.redirect('/403'); | ||||||
|  |  | ||||||
| 			user.get_uid_by_userslug(req.params.userslug, function(err, uid) { | 			user.get_uid_by_userslug(req.params.userslug, function(err, uid) { | ||||||
| 				if(!uid) { | 				if (!uid) { | ||||||
| 					res.redirect('/404'); | 					res.redirect('/404'); | ||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				app.build_header({ req: req, res: res }, function(err, header) { | 				app.build_header({ | ||||||
| 					res.send(header + app.create_route('users/'+req.params.userslug+'/following','following') + templates['footer']); | 					req: req, | ||||||
|  | 					res: res | ||||||
|  | 				}, function(err, header) { | ||||||
|  | 					res.send(header + app.create_route('users/' + req.params.userslug + '/following', 'following') + templates['footer']); | ||||||
| 				}); | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/users/:userslug/followers', function(req, res) { | 		app.get('/users/:userslug/followers', function(req, res) { | ||||||
|  |  | ||||||
| 			if(!req.user) | 			if (!req.user) | ||||||
| 				return res.redirect('/403'); | 				return res.redirect('/403'); | ||||||
|  |  | ||||||
| 			user.get_uid_by_userslug(req.params.userslug, function(err, uid) { | 			user.get_uid_by_userslug(req.params.userslug, function(err, uid) { | ||||||
| 				if(!uid) { | 				if (!uid) { | ||||||
| 					res.redirect('/404'); | 					res.redirect('/404'); | ||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
| 				app.build_header({ req: req, res: res }, function(err, header) { | 				app.build_header({ | ||||||
| 					res.send(header + app.create_route('users/'+req.params.userslug+'/followers','followers') + templates['footer']); | 					req: req, | ||||||
|  | 					res: res | ||||||
|  | 				}, function(err, header) { | ||||||
|  | 					res.send(header + app.create_route('users/' + req.params.userslug + '/followers', 'followers') + templates['footer']); | ||||||
| 				}); | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/users/:userslug/favourites', function(req, res) { | 		app.get('/users/:userslug/favourites', function(req, res) { | ||||||
|  |  | ||||||
| 			if(!req.user) | 			if (!req.user) | ||||||
| 				return res.redirect('/403'); | 				return res.redirect('/403'); | ||||||
|  |  | ||||||
| 			user.get_uid_by_userslug(req.params.userslug, function(err, uid) { | 			user.get_uid_by_userslug(req.params.userslug, function(err, uid) { | ||||||
| 				if(!uid) { | 				if (!uid) { | ||||||
| 					res.redirect('/404'); | 					res.redirect('/404'); | ||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
| 				app.build_header({ req: req, res: res }, function(err, header) { | 				app.build_header({ | ||||||
| 					res.send(header + app.create_route('users/'+req.params.userslug+'/favourites','favourites') + templates['footer']); | 					req: req, | ||||||
|  | 					res: res | ||||||
|  | 				}, function(err, header) { | ||||||
|  | 					res.send(header + app.create_route('users/' + req.params.userslug + '/favourites', 'favourites') + templates['footer']); | ||||||
| 				}); | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| @@ -242,7 +279,7 @@ var user = require('./../user.js'), | |||||||
| 			var callerUID = req.user ? req.user.uid : 0; | 			var callerUID = req.user ? req.user.uid : 0; | ||||||
|  |  | ||||||
| 			getUserDataByUserSlug(req.params.userslug, callerUID, function(userData) { | 			getUserDataByUserSlug(req.params.userslug, callerUID, function(userData) { | ||||||
| 				if(userData) { | 				if (userData) { | ||||||
| 					user.getFollowing(userData.uid, function(followingData) { | 					user.getFollowing(userData.uid, function(followingData) { | ||||||
| 						userData.following = followingData; | 						userData.following = followingData; | ||||||
| 						userData.followingCount = followingData.length; | 						userData.followingCount = followingData.length; | ||||||
| @@ -250,7 +287,9 @@ var user = require('./../user.js'), | |||||||
| 					}); | 					}); | ||||||
|  |  | ||||||
| 				} else { | 				} else { | ||||||
| 					res.json(404, { error: 'User not found!' })	; | 					res.json(404, { | ||||||
|  | 						error: 'User not found!' | ||||||
|  | 					}); | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| @@ -259,14 +298,16 @@ var user = require('./../user.js'), | |||||||
| 			var callerUID = req.user ? req.user.uid : 0; | 			var callerUID = req.user ? req.user.uid : 0; | ||||||
|  |  | ||||||
| 			getUserDataByUserSlug(req.params.userslug, callerUID, function(userData) { | 			getUserDataByUserSlug(req.params.userslug, callerUID, function(userData) { | ||||||
| 				if(userData) { | 				if (userData) { | ||||||
| 					user.getFollowers(userData.uid, function(followersData) { | 					user.getFollowers(userData.uid, function(followersData) { | ||||||
| 						userData.followers = followersData; | 						userData.followers = followersData; | ||||||
| 						userData.followersCount = followersData.length; | 						userData.followersCount = followersData.length; | ||||||
| 						res.json(userData); | 						res.json(userData); | ||||||
| 					}); | 					}); | ||||||
| 				} else { | 				} else { | ||||||
| 					res.json(404, { error: 'User not found!' })	; | 					res.json(404, { | ||||||
|  | 						error: 'User not found!' | ||||||
|  | 					}); | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| @@ -283,27 +324,33 @@ var user = require('./../user.js'), | |||||||
| 			var callerUID = req.user ? req.user.uid : 0; | 			var callerUID = req.user ? req.user.uid : 0; | ||||||
|  |  | ||||||
| 			user.get_uid_by_userslug(req.params.userslug, function(err, uid) { | 			user.get_uid_by_userslug(req.params.userslug, function(err, uid) { | ||||||
| 				if(!uid) { | 				if (!uid) { | ||||||
| 					res.json(404, { error: 'User not found!' })	; | 					res.json(404, { | ||||||
|  | 						error: 'User not found!' | ||||||
|  | 					}); | ||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				if(uid !== callerUID || callerUID === "0") { | 				if (uid !== callerUID || callerUID === "0") { | ||||||
| 					res.json(403, { error: 'Not allowed!' }); | 					res.json(403, { | ||||||
|  | 						error: 'Not allowed!' | ||||||
|  | 					}); | ||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
| 				user.getUserFields(uid, ['username','userslug','showemail'], function(err, userData) { | 				user.getUserFields(uid, ['username', 'userslug', 'showemail'], function(err, userData) { | ||||||
| 					if(err) | 					if (err) | ||||||
| 						return next(err); | 						return next(err); | ||||||
|  |  | ||||||
| 					if(userData) { | 					if (userData) { | ||||||
| 						if(userData.showemail && userData.showemail === "1") | 						if (userData.showemail && userData.showemail === "1") | ||||||
| 							userData.showemail = "checked"; | 							userData.showemail = "checked"; | ||||||
| 						else | 						else | ||||||
| 							userData.showemail = ""; | 							userData.showemail = ""; | ||||||
| 						res.json(userData); | 						res.json(userData); | ||||||
| 					} else { | 					} else { | ||||||
| 						res.json(404, { error: 'User not found!' })	; | 						res.json(404, { | ||||||
|  | 							error: 'User not found!' | ||||||
|  | 						}); | ||||||
| 					} | 					} | ||||||
| 				}); | 				}); | ||||||
| 			}); | 			}); | ||||||
| @@ -313,30 +360,36 @@ var user = require('./../user.js'), | |||||||
| 			var callerUID = req.user ? req.user.uid : 0; | 			var callerUID = req.user ? req.user.uid : 0; | ||||||
|  |  | ||||||
| 			user.get_uid_by_userslug(req.params.userslug, function(err, uid) { | 			user.get_uid_by_userslug(req.params.userslug, function(err, uid) { | ||||||
| 				if(!uid) { | 				if (!uid) { | ||||||
| 					res.json(404, { error: 'User not found!' })	; | 					res.json(404, { | ||||||
|  | 						error: 'User not found!' | ||||||
|  | 					}); | ||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				if(uid !== callerUID || callerUID === "0") { | 				if (uid !== callerUID || callerUID === "0") { | ||||||
| 					res.json(403, { error: 'Not allowed!' }); | 					res.json(403, { | ||||||
|  | 						error: 'Not allowed!' | ||||||
|  | 					}); | ||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				user.getUserFields(uid, ['username','userslug'], function(err, userData) { | 				user.getUserFields(uid, ['username', 'userslug'], function(err, userData) { | ||||||
| 					if(err) | 					if (err) | ||||||
| 						return next(err); | 						return next(err); | ||||||
|  |  | ||||||
| 					if(userData) { | 					if (userData) { | ||||||
| 						posts.getFavourites(uid, function(err, posts) { | 						posts.getFavourites(uid, function(err, posts) { | ||||||
| 							if(err) | 							if (err) | ||||||
| 								return next(err); | 								return next(err); | ||||||
| 							userData.posts = posts; | 							userData.posts = posts; | ||||||
| 							userData.show_nofavourites = posts.length?'hide':'show'; | 							userData.show_nofavourites = posts.length ? 'hide' : 'show'; | ||||||
| 							res.json(userData); | 							res.json(userData); | ||||||
| 						}); | 						}); | ||||||
| 					} else { | 					} else { | ||||||
| 						res.json(404, { error: 'User not found!' })	; | 						res.json(404, { | ||||||
|  | 							error: 'User not found!' | ||||||
|  | 						}); | ||||||
| 					} | 					} | ||||||
| 				}); | 				}); | ||||||
| 			}); | 			}); | ||||||
| @@ -346,15 +399,17 @@ var user = require('./../user.js'), | |||||||
| 			var callerUID = req.user ? req.user.uid : 0; | 			var callerUID = req.user ? req.user.uid : 0; | ||||||
|  |  | ||||||
| 			getUserDataByUserSlug(req.params.userslug, callerUID, function(userData) { | 			getUserDataByUserSlug(req.params.userslug, callerUID, function(userData) { | ||||||
| 				if(userData) { | 				if (userData) { | ||||||
| 					user.isFollowing(callerUID, userData.theirid, function(isFollowing) { | 					user.isFollowing(callerUID, userData.theirid, function(isFollowing) { | ||||||
| 						posts.getPostsByUid(userData.theirid, 0, 9, function(posts) { | 						posts.getPostsByUid(userData.theirid, 0, 9, function(posts) { | ||||||
|  |  | ||||||
| 							userData.posts = posts.filter(function(p) {return p.deleted !== "1";}); | 							userData.posts = posts.filter(function(p) { | ||||||
|  | 								return p.deleted !== "1"; | ||||||
|  | 							}); | ||||||
| 							userData.isFollowing = isFollowing; | 							userData.isFollowing = isFollowing; | ||||||
| 							if(!userData.profileviews) | 							if (!userData.profileviews) | ||||||
| 								userData.profileviews = 1; | 								userData.profileviews = 1; | ||||||
| 							if(callerUID !== userData.uid) | 							if (callerUID !== userData.uid) | ||||||
| 								user.incrementUserFieldBy(userData.uid, 'profileviews', 1); | 								user.incrementUserFieldBy(userData.uid, 'profileviews', 1); | ||||||
|  |  | ||||||
| 							postTools.toHTML(userData.signature, function(err, signature) { | 							postTools.toHTML(userData.signature, function(err, signature) { | ||||||
| @@ -364,7 +419,9 @@ var user = require('./../user.js'), | |||||||
| 						}); | 						}); | ||||||
| 					}); | 					}); | ||||||
| 				} else { | 				} else { | ||||||
| 					res.json(404, { error: 'User not found!' })	; | 					res.json(404, { | ||||||
|  | 						error: 'User not found!' | ||||||
|  | 					}); | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| @@ -378,39 +435,55 @@ var user = require('./../user.js'), | |||||||
|  |  | ||||||
| 		function getUsersSortedByJoinDate(req, res) { | 		function getUsersSortedByJoinDate(req, res) { | ||||||
| 			user.getUsers('users:joindate', 0, 49, function(err, data) { | 			user.getUsers('users:joindate', 0, 49, function(err, data) { | ||||||
| 				res.json({ search_display: 'none', loadmore_display:'block', users:data }); | 				res.json({ | ||||||
|  | 					search_display: 'none', | ||||||
|  | 					loadmore_display: 'block', | ||||||
|  | 					users: data | ||||||
|  | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		function getUsersSortedByPosts(req, res) { | 		function getUsersSortedByPosts(req, res) { | ||||||
| 			user.getUsers('users:postcount', 0, 49, function(err, data) { | 			user.getUsers('users:postcount', 0, 49, function(err, data) { | ||||||
| 				res.json({ search_display: 'none', loadmore_display:'block', users:data }); | 				res.json({ | ||||||
|  | 					search_display: 'none', | ||||||
|  | 					loadmore_display: 'block', | ||||||
|  | 					users: data | ||||||
|  | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		function getUsersSortedByReputation(req, res) { | 		function getUsersSortedByReputation(req, res) { | ||||||
| 			user.getUsers('users:reputation', 0, 49, function(err, data) { | 			user.getUsers('users:reputation', 0, 49, function(err, data) { | ||||||
| 				res.json({ search_display: 'none', loadmore_display:'block', users:data }); | 				res.json({ | ||||||
|  | 					search_display: 'none', | ||||||
|  | 					loadmore_display: 'block', | ||||||
|  | 					users: data | ||||||
|  | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		function getUsersForSearch(req, res) { | 		function getUsersForSearch(req, res) { | ||||||
| 			res.json({ search_display: 'block', loadmore_display:'none', users: [] }); | 			res.json({ | ||||||
|  | 				search_display: 'block', | ||||||
|  | 				loadmore_display: 'none', | ||||||
|  | 				users: [] | ||||||
|  | 			}); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		function getUserDataByUserSlug(userslug, callerUID, callback) { | 		function getUserDataByUserSlug(userslug, callerUID, callback) { | ||||||
| 			user.get_uid_by_userslug(userslug, function(err, uid) { | 			user.get_uid_by_userslug(userslug, function(err, uid) { | ||||||
|  |  | ||||||
| 				if(uid === null) { | 				if (uid === null) { | ||||||
| 					callback(null); | 					callback(null); | ||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				user.getUserData(uid, function(err, data) { | 				user.getUserData(uid, function(err, data) { | ||||||
| 					if(data) { | 					if (data) { | ||||||
| 						data.joindate = utils.relativeTime(data.joindate); | 						data.joindate = utils.relativeTime(data.joindate); | ||||||
|  |  | ||||||
| 						if(!data.birthday) { | 						if (!data.birthday) { | ||||||
| 							data.age = ''; | 							data.age = ''; | ||||||
| 						} else { | 						} else { | ||||||
| 							data.age = new Date().getFullYear() - new Date(data.birthday).getFullYear(); | 							data.age = new Date().getFullYear() - new Date(data.birthday).getFullYear(); | ||||||
| @@ -420,15 +493,15 @@ var user = require('./../user.js'), | |||||||
| 							return callerUID === uid || (data.email && (data.showemail && data.showemail === "1")); | 							return callerUID === uid || (data.email && (data.showemail && data.showemail === "1")); | ||||||
| 						} | 						} | ||||||
|  |  | ||||||
| 						if(!canSeeEmail()) | 						if (!canSeeEmail()) | ||||||
| 							data.email = ""; | 							data.email = ""; | ||||||
|  |  | ||||||
| 						if(callerUID === uid && (!data.showemail || data.showemail === "0")) | 						if (callerUID === uid && (!data.showemail || data.showemail === "0")) | ||||||
| 							data.emailClass = ""; | 							data.emailClass = ""; | ||||||
| 						else | 						else | ||||||
| 							data.emailClass = "hide"; | 							data.emailClass = "hide"; | ||||||
|  |  | ||||||
| 						data.show_banned = data.banned === '1'?'':'hide'; | 						data.show_banned = data.banned === '1' ? '' : 'hide'; | ||||||
|  |  | ||||||
| 						data.uid = uid; | 						data.uid = uid; | ||||||
| 						data.yourid = callerUID; | 						data.yourid = callerUID; | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| var	path = require('path'), | var path = require('path'), | ||||||
| 	async = require('async'), | 	async = require('async'), | ||||||
| 	sm = require('sitemap'), | 	sm = require('sitemap'), | ||||||
| 	url = require('url'), | 	url = require('url'), | ||||||
| @@ -6,14 +6,22 @@ var	path = require('path'), | |||||||
| 	topics = require('./topics'), | 	topics = require('./topics'), | ||||||
| 	sitemap = { | 	sitemap = { | ||||||
| 		getStaticUrls: function(callback) { | 		getStaticUrls: function(callback) { | ||||||
| 			callback(null, [ | 			callback(null, [{ | ||||||
| 				{ url: '', changefreq: 'weekly', priority: '0.6' }, | 				url: '', | ||||||
| 				{ url: 'recent', changefreq: 'daily', priority: '0.4' }, | 				changefreq: 'weekly', | ||||||
| 				{ url: 'users', changefreq: 'daily', priority: '0.4' } | 				priority: '0.6' | ||||||
| 			]); | 			}, { | ||||||
|  | 				url: 'recent', | ||||||
|  | 				changefreq: 'daily', | ||||||
|  | 				priority: '0.4' | ||||||
|  | 			}, { | ||||||
|  | 				url: 'users', | ||||||
|  | 				changefreq: 'daily', | ||||||
|  | 				priority: '0.4' | ||||||
|  | 			}]); | ||||||
| 		}, | 		}, | ||||||
| 		getDynamicUrls: function(callback) { | 		getDynamicUrls: function(callback) { | ||||||
| 			var	returnUrls = []; | 			var returnUrls = []; | ||||||
|  |  | ||||||
| 			async.parallel([ | 			async.parallel([ | ||||||
| 				function(next) { | 				function(next) { | ||||||
| @@ -33,7 +41,7 @@ var	path = require('path'), | |||||||
| 					}, 0); | 					}, 0); | ||||||
| 				}, | 				}, | ||||||
| 				function(next) { | 				function(next) { | ||||||
| 					var	topicUrls = []; | 					var topicUrls = []; | ||||||
| 					topics.getAllTopics(null, null, function(topics) { | 					topics.getAllTopics(null, null, function(topics) { | ||||||
| 						topics.forEach(function(topic) { | 						topics.forEach(function(topic) { | ||||||
| 							if (topic.deleted !== '1') { | 							if (topic.deleted !== '1') { | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| var	RDB = require('./redis.js'), | var RDB = require('./redis.js'), | ||||||
| 	topics = require('./topics.js'), | 	topics = require('./topics.js'), | ||||||
| 	categories = require('./categories.js'), | 	categories = require('./categories.js'), | ||||||
| 	user = require('./user.js'), | 	user = require('./user.js'), | ||||||
| @@ -15,7 +15,7 @@ var	RDB = require('./redis.js'), | |||||||
| 	ThreadTools.exists = function(tid, callback) { | 	ThreadTools.exists = function(tid, callback) { | ||||||
| 		RDB.sismember('topics:tid', tid, function(err, ismember) { | 		RDB.sismember('topics:tid', tid, function(err, ismember) { | ||||||
| 			if (err) RDB.handle(err); | 			if (err) RDB.handle(err); | ||||||
| 			callback(!!ismember || false); | 			callback( !! ismember || false); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -52,7 +52,7 @@ var	RDB = require('./redis.js'), | |||||||
| 				topics.setTopicField(tid, 'locked', 1); | 				topics.setTopicField(tid, 'locked', 1); | ||||||
|  |  | ||||||
| 				if (socket) { | 				if (socket) { | ||||||
| 					io.sockets.in('topic_' + tid).emit('event:topic_locked', { | 					io.sockets. in ('topic_' + tid).emit('event:topic_locked', { | ||||||
| 						tid: tid, | 						tid: tid, | ||||||
| 						status: 'ok' | 						status: 'ok' | ||||||
| 					}); | 					}); | ||||||
| @@ -72,7 +72,7 @@ var	RDB = require('./redis.js'), | |||||||
| 				topics.setTopicField(tid, 'locked', 0); | 				topics.setTopicField(tid, 'locked', 0); | ||||||
|  |  | ||||||
| 				if (socket) { | 				if (socket) { | ||||||
| 					io.sockets.in('topic_' + tid).emit('event:topic_unlocked', { | 					io.sockets. in ('topic_' + tid).emit('event:topic_unlocked', { | ||||||
| 						tid: tid, | 						tid: tid, | ||||||
| 						status: 'ok' | 						status: 'ok' | ||||||
| 					}); | 					}); | ||||||
| @@ -95,7 +95,7 @@ var	RDB = require('./redis.js'), | |||||||
|  |  | ||||||
| 				topicSearch.remove(tid); | 				topicSearch.remove(tid); | ||||||
|  |  | ||||||
| 				io.sockets.in('topic_' + tid).emit('event:topic_deleted', { | 				io.sockets. in ('topic_' + tid).emit('event:topic_deleted', { | ||||||
| 					tid: tid, | 					tid: tid, | ||||||
| 					status: 'ok' | 					status: 'ok' | ||||||
| 				}); | 				}); | ||||||
| @@ -112,7 +112,7 @@ var	RDB = require('./redis.js'), | |||||||
| 				topics.restore(tid); | 				topics.restore(tid); | ||||||
| 				ThreadTools.unlock(tid, uid); | 				ThreadTools.unlock(tid, uid); | ||||||
|  |  | ||||||
| 				io.sockets.in('topic_' + tid).emit('event:topic_restored', { | 				io.sockets. in ('topic_' + tid).emit('event:topic_restored', { | ||||||
| 					tid: tid, | 					tid: tid, | ||||||
| 					status: 'ok' | 					status: 'ok' | ||||||
| 				}); | 				}); | ||||||
| @@ -137,11 +137,11 @@ var	RDB = require('./redis.js'), | |||||||
|  |  | ||||||
| 				topics.setTopicField(tid, 'pinned', 1); | 				topics.setTopicField(tid, 'pinned', 1); | ||||||
| 				topics.getTopicField(tid, 'cid', function(err, cid) { | 				topics.getTopicField(tid, 'cid', function(err, cid) { | ||||||
| 					RDB.zadd('categories:' + cid + ':tid', Math.pow(2,53), tid); | 					RDB.zadd('categories:' + cid + ':tid', Math.pow(2, 53), tid); | ||||||
| 				}); | 				}); | ||||||
|  |  | ||||||
| 				if (socket) { | 				if (socket) { | ||||||
| 					io.sockets.in('topic_' + tid).emit('event:topic_pinned', { | 					io.sockets. in ('topic_' + tid).emit('event:topic_pinned', { | ||||||
| 						tid: tid, | 						tid: tid, | ||||||
| 						status: 'ok' | 						status: 'ok' | ||||||
| 					}); | 					}); | ||||||
| @@ -164,7 +164,7 @@ var	RDB = require('./redis.js'), | |||||||
| 					RDB.zadd('categories:' + topicData.cid + ':tid', topicData.lastposttime, tid); | 					RDB.zadd('categories:' + topicData.cid + ':tid', topicData.lastposttime, tid); | ||||||
| 				}); | 				}); | ||||||
| 				if (socket) { | 				if (socket) { | ||||||
| 					io.sockets.in('topic_' + tid).emit('event:topic_unpinned', { | 					io.sockets. in ('topic_' + tid).emit('event:topic_unpinned', { | ||||||
| 						tid: tid, | 						tid: tid, | ||||||
| 						status: 'ok' | 						status: 'ok' | ||||||
| 					}); | 					}); | ||||||
| @@ -194,13 +194,13 @@ var	RDB = require('./redis.js'), | |||||||
| 					topics.setTopicField(tid, 'cid', cid); | 					topics.setTopicField(tid, 'cid', cid); | ||||||
|  |  | ||||||
| 					categories.moveRecentReplies(tid, oldCid, cid, function(err, data) { | 					categories.moveRecentReplies(tid, oldCid, cid, function(err, data) { | ||||||
| 						if(err) { | 						if (err) { | ||||||
| 							winston.err(err); | 							winston.err(err); | ||||||
| 						} | 						} | ||||||
| 					}); | 					}); | ||||||
|  |  | ||||||
| 					categories.moveActiveUsers(tid, oldCid, cid, function(err, data) { | 					categories.moveActiveUsers(tid, oldCid, cid, function(err, data) { | ||||||
| 						if(err) { | 						if (err) { | ||||||
| 							winston.err(err); | 							winston.err(err); | ||||||
| 						} | 						} | ||||||
| 					}); | 					}); | ||||||
| @@ -212,7 +212,7 @@ var	RDB = require('./redis.js'), | |||||||
| 						status: 'ok' | 						status: 'ok' | ||||||
| 					}); | 					}); | ||||||
|  |  | ||||||
| 					io.sockets.in('topic_' + tid).emit('event:topic_moved', { | 					io.sockets. in ('topic_' + tid).emit('event:topic_moved', { | ||||||
| 						tid: tid | 						tid: tid | ||||||
| 					}); | 					}); | ||||||
| 				} else { | 				} else { | ||||||
| @@ -240,7 +240,9 @@ var	RDB = require('./redis.js'), | |||||||
| 								status: 'ok', | 								status: 'ok', | ||||||
| 								follow: true | 								follow: true | ||||||
| 							}); | 							}); | ||||||
| 						} else callback({ status: 'error' }); | 						} else callback({ | ||||||
|  | 							status: 'error' | ||||||
|  | 						}); | ||||||
| 					} | 					} | ||||||
| 				}); | 				}); | ||||||
| 			} else { | 			} else { | ||||||
| @@ -251,7 +253,9 @@ var	RDB = require('./redis.js'), | |||||||
| 								status: 'ok', | 								status: 'ok', | ||||||
| 								follow: false | 								follow: false | ||||||
| 							}); | 							}); | ||||||
| 						} else callback({ status: 'error' }); | 						} else callback({ | ||||||
|  | 							status: 'error' | ||||||
|  | 						}); | ||||||
| 					} | 					} | ||||||
| 				}); | 				}); | ||||||
| 			} | 			} | ||||||
| @@ -297,11 +301,11 @@ var	RDB = require('./redis.js'), | |||||||
| 		posts.getPostsByTid(tid, 0, -1, function(posts) { | 		posts.getPostsByTid(tid, 0, -1, function(posts) { | ||||||
|  |  | ||||||
| 			var numPosts = posts.length; | 			var numPosts = posts.length; | ||||||
| 			if(!numPosts) | 			if (!numPosts) | ||||||
| 				return callback(new Error('no-undeleted-pids-found')); | 				return callback(new Error('no-undeleted-pids-found')); | ||||||
|  |  | ||||||
| 			while(numPosts--) { | 			while (numPosts--) { | ||||||
| 				if(posts[numPosts].deleted !== '1') { | 				if (posts[numPosts].deleted !== '1') { | ||||||
| 					callback(null, posts[numPosts].pid); | 					callback(null, posts[numPosts].pid); | ||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
|   | |||||||
							
								
								
									
										153
									
								
								src/topics.js
									
									
									
									
									
								
							
							
						
						
									
										153
									
								
								src/topics.js
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | |||||||
| var	RDB = require('./redis.js') | var RDB = require('./redis.js') | ||||||
| 	schema = require('./schema.js'), | schema = require('./schema.js'), | ||||||
| 	posts = require('./posts.js'), | 	posts = require('./posts.js'), | ||||||
| 	utils = require('./../public/src/utils.js'), | 	utils = require('./../public/src/utils.js'), | ||||||
| 	user = require('./user.js'), | 	user = require('./user.js'), | ||||||
| @@ -19,7 +19,7 @@ var	RDB = require('./redis.js') | |||||||
|  |  | ||||||
| 	Topics.getTopicData = function(tid, callback) { | 	Topics.getTopicData = function(tid, callback) { | ||||||
| 		RDB.hgetall('topic:' + tid, function(err, data) { | 		RDB.hgetall('topic:' + tid, function(err, data) { | ||||||
| 			if(err === null) | 			if (err === null) | ||||||
| 				callback(data); | 				callback(data); | ||||||
| 			else | 			else | ||||||
| 				console.log(err); | 				console.log(err); | ||||||
| @@ -37,12 +37,12 @@ var	RDB = require('./redis.js') | |||||||
|  |  | ||||||
| 	Topics.getTopicPosts = function(tid, start, end, current_user, callback) { | 	Topics.getTopicPosts = function(tid, start, end, current_user, callback) { | ||||||
| 		posts.getPostsByTid(tid, start, end, function(postData) { | 		posts.getPostsByTid(tid, start, end, function(postData) { | ||||||
| 			if(Array.isArray(postData) && !postData.length) | 			if (Array.isArray(postData) && !postData.length) | ||||||
| 				return callback([]); | 				return callback([]); | ||||||
|  |  | ||||||
| 			function getFavouritesData(next) { | 			function getFavouritesData(next) { | ||||||
| 				var pids = []; | 				var pids = []; | ||||||
| 				for(var i=0; i<postData.length; ++i) | 				for (var i = 0; i < postData.length; ++i) | ||||||
| 					pids.push(postData[i].pid); | 					pids.push(postData[i].pid); | ||||||
|  |  | ||||||
| 				favourites.getFavouritesByPostIDs(pids, current_user, function(fav_data) { | 				favourites.getFavouritesByPostIDs(pids, current_user, function(fav_data) { | ||||||
| @@ -72,11 +72,11 @@ var	RDB = require('./redis.js') | |||||||
| 				var fav_data = results[0], | 				var fav_data = results[0], | ||||||
| 					privileges = results[2]; | 					privileges = results[2]; | ||||||
|  |  | ||||||
| 				for(var i=0; i<postData.length; ++i) { | 				for (var i = 0; i < postData.length; ++i) { | ||||||
| 					postData[i].fav_button_class = fav_data[postData[i].pid]? 'btn-warning' : ''; | 					postData[i].fav_button_class = fav_data[postData[i].pid] ? 'btn-warning' : ''; | ||||||
| 					postData[i].fav_star_class = fav_data[postData[i].pid] ? 'icon-star' : 'icon-star-empty'; | 					postData[i].fav_star_class = fav_data[postData[i].pid] ? 'icon-star' : 'icon-star-empty'; | ||||||
| 					postData[i]['display_moderator_tools'] = (postData[i].uid == current_user || privileges.editable) ? 'show' : 'none'; | 					postData[i]['display_moderator_tools'] = (postData[i].uid == current_user || privileges.editable) ? 'show' : 'none'; | ||||||
| 					postData[i].show_banned = postData[i].user_banned === '1'?'show':'hide'; | 					postData[i].show_banned = postData[i].user_banned === '1' ? 'show' : 'hide'; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				callback(postData); | 				callback(postData); | ||||||
| @@ -94,18 +94,18 @@ var	RDB = require('./redis.js') | |||||||
|  |  | ||||||
| 		var timestamp = Date.now(); | 		var timestamp = Date.now(); | ||||||
|  |  | ||||||
| 		var args = [ 'topics:recent', '+inf', timestamp - 86400000, 'WITHSCORES', 'LIMIT', start, end - start + 1]; | 		var args = ['topics:recent', '+inf', timestamp - 86400000, 'WITHSCORES', 'LIMIT', start, end - start + 1]; | ||||||
|  |  | ||||||
| 		RDB.zrevrangebyscore(args, function(err, tids) { | 		RDB.zrevrangebyscore(args, function(err, tids) { | ||||||
|  |  | ||||||
| 			var latestTopics = { | 			var latestTopics = { | ||||||
| 				'category_name' : 'Recent', | 				'category_name': 'Recent', | ||||||
| 				'show_sidebar' : 'hidden', | 				'show_sidebar': 'hidden', | ||||||
| 				'show_topic_button' : 'hidden', | 				'show_topic_button': 'hidden', | ||||||
| 				'no_topics_message' : 'hidden', | 				'no_topics_message': 'hidden', | ||||||
| 				'topic_row_size': 'col-md-12', | 				'topic_row_size': 'col-md-12', | ||||||
| 				'category_id': false, | 				'category_id': false, | ||||||
| 				'topics' : [] | 				'topics': [] | ||||||
| 			}; | 			}; | ||||||
|  |  | ||||||
| 			if (!tids || !tids.length) { | 			if (!tids || !tids.length) { | ||||||
| @@ -129,14 +129,16 @@ var	RDB = require('./redis.js') | |||||||
| 			done = false; | 			done = false; | ||||||
|  |  | ||||||
| 		async.whilst( | 		async.whilst( | ||||||
| 			function () { return unreadTids.length < 21 && !done; }, | 			function() { | ||||||
| 			function (callback) { | 				return unreadTids.length < 21 && !done; | ||||||
|  | 			}, | ||||||
|  | 			function(callback) { | ||||||
| 				RDB.zrevrange('topics:recent', start, stop, function(err, tids) { | 				RDB.zrevrange('topics:recent', start, stop, function(err, tids) { | ||||||
|  |  | ||||||
| 					if(err) | 					if (err) | ||||||
| 						return callback(err); | 						return callback(err); | ||||||
|  |  | ||||||
| 					if(tids && !tids.length) { | 					if (tids && !tids.length) { | ||||||
| 						done = true; | 						done = true; | ||||||
| 						return callback(null); | 						return callback(null); | ||||||
| 					} | 					} | ||||||
| @@ -155,7 +157,7 @@ var	RDB = require('./redis.js') | |||||||
| 					}); | 					}); | ||||||
| 				}); | 				}); | ||||||
| 			}, | 			}, | ||||||
| 			function (err) { | 			function(err) { | ||||||
| 				callback({ | 				callback({ | ||||||
| 					count: unreadTids.length | 					count: unreadTids.length | ||||||
| 				}); | 				}); | ||||||
| @@ -166,13 +168,13 @@ var	RDB = require('./redis.js') | |||||||
| 	Topics.getUnreadTopics = function(uid, start, stop, callback) { | 	Topics.getUnreadTopics = function(uid, start, stop, callback) { | ||||||
|  |  | ||||||
| 		var unreadTopics = { | 		var unreadTopics = { | ||||||
| 			'category_name' : 'Unread', | 			'category_name': 'Unread', | ||||||
| 			'show_sidebar' : 'hidden', | 			'show_sidebar': 'hidden', | ||||||
| 			'show_topic_button' : 'hidden', | 			'show_topic_button': 'hidden', | ||||||
| 			'show_markallread_button': 'show', | 			'show_markallread_button': 'show', | ||||||
| 			'no_topics_message' : 'hidden', | 			'no_topics_message': 'hidden', | ||||||
| 			'topic_row_size': 'col-md-12', | 			'topic_row_size': 'col-md-12', | ||||||
| 			'topics' : [] | 			'topics': [] | ||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
| 		function noUnreadTopics() { | 		function noUnreadTopics() { | ||||||
| @@ -185,9 +187,9 @@ var	RDB = require('./redis.js') | |||||||
| 			Topics.getTopicsByTids(topicIds, uid, function(topicData) { | 			Topics.getTopicsByTids(topicIds, uid, function(topicData) { | ||||||
| 				unreadTopics.topics = topicData; | 				unreadTopics.topics = topicData; | ||||||
| 				unreadTopics.nextStart = start + topicIds.length; | 				unreadTopics.nextStart = start + topicIds.length; | ||||||
| 				if(!topicData || topicData.length === 0) | 				if (!topicData || topicData.length === 0) | ||||||
| 					unreadTopics.no_topics_message = 'show'; | 					unreadTopics.no_topics_message = 'show'; | ||||||
| 				if(uid === 0 || topicData.length === 0) | 				if (uid === 0 || topicData.length === 0) | ||||||
| 					unreadTopics.show_markallread_button = 'hidden'; | 					unreadTopics.show_markallread_button = 'hidden'; | ||||||
| 				callback(unreadTopics); | 				callback(unreadTopics); | ||||||
| 			}); | 			}); | ||||||
| @@ -197,18 +199,20 @@ var	RDB = require('./redis.js') | |||||||
| 			done = false; | 			done = false; | ||||||
|  |  | ||||||
| 		async.whilst( | 		async.whilst( | ||||||
| 			function () { return unreadTids.length < 20 && !done; }, | 			function() { | ||||||
| 			function (callback) { | 				return unreadTids.length < 20 && !done; | ||||||
|  | 			}, | ||||||
|  | 			function(callback) { | ||||||
| 				RDB.zrevrange('topics:recent', start, stop, function(err, tids) { | 				RDB.zrevrange('topics:recent', start, stop, function(err, tids) { | ||||||
| 					if(err) | 					if (err) | ||||||
| 						return callback(err); | 						return callback(err); | ||||||
|  |  | ||||||
| 					if(tids && !tids.length) { | 					if (tids && !tids.length) { | ||||||
| 						done = true; | 						done = true; | ||||||
| 						return callback(null); | 						return callback(null); | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					if(uid === 0) { | 					if (uid === 0) { | ||||||
| 						unreadTids.push.apply(unreadTids, tids); | 						unreadTids.push.apply(unreadTids, tids); | ||||||
| 						callback(null); | 						callback(null); | ||||||
| 					} else { | 					} else { | ||||||
| @@ -226,10 +230,10 @@ var	RDB = require('./redis.js') | |||||||
| 					} | 					} | ||||||
| 				}); | 				}); | ||||||
| 			}, | 			}, | ||||||
| 			function (err) { | 			function(err) { | ||||||
| 				if(err) | 				if (err) | ||||||
| 					return callback([]); | 					return callback([]); | ||||||
| 				if(unreadTids.length) | 				if (unreadTids.length) | ||||||
| 					sendUnreadTopics(unreadTids); | 					sendUnreadTopics(unreadTids); | ||||||
| 				else | 				else | ||||||
| 					noUnreadTopics(); | 					noUnreadTopics(); | ||||||
| @@ -242,7 +246,7 @@ var	RDB = require('./redis.js') | |||||||
|  |  | ||||||
| 		var retrieved_topics = []; | 		var retrieved_topics = []; | ||||||
|  |  | ||||||
| 		if(!Array.isArray(tids) || tids.length === 0) { | 		if (!Array.isArray(tids) || tids.length === 0) { | ||||||
| 			callback(retrieved_topics); | 			callback(retrieved_topics); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| @@ -266,6 +270,7 @@ var	RDB = require('./redis.js') | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			// temporary. I don't think this call should belong here | 			// temporary. I don't think this call should belong here | ||||||
|  |  | ||||||
| 			function getPrivileges(next) { | 			function getPrivileges(next) { | ||||||
| 				categories.privileges(category_id, current_user, function(user_privs) { | 				categories.privileges(category_id, current_user, function(user_privs) { | ||||||
| 					next(null, user_privs); | 					next(null, user_privs); | ||||||
| @@ -290,7 +295,7 @@ var	RDB = require('./redis.js') | |||||||
|  |  | ||||||
| 		function loadTopic(tid, callback) { | 		function loadTopic(tid, callback) { | ||||||
| 			Topics.getTopicData(tid, function(topicData) { | 			Topics.getTopicData(tid, function(topicData) { | ||||||
| 				if(!topicData) { | 				if (!topicData) { | ||||||
| 					return callback(null); | 					return callback(null); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| @@ -318,7 +323,7 @@ var	RDB = require('./redis.js') | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		async.eachSeries(tids, loadTopic, function(err) { | 		async.eachSeries(tids, loadTopic, function(err) { | ||||||
| 			if(!err) { | 			if (!err) { | ||||||
| 				callback(retrieved_topics); | 				callback(retrieved_topics); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| @@ -369,14 +374,14 @@ var	RDB = require('./redis.js') | |||||||
| 				var main_posts = topicPosts.splice(0, 1); | 				var main_posts = topicPosts.splice(0, 1); | ||||||
|  |  | ||||||
| 				callback(null, { | 				callback(null, { | ||||||
| 					'topic_name':topicData.title, | 					'topic_name': topicData.title, | ||||||
| 					'category_name':categoryData.name, | 					'category_name': categoryData.name, | ||||||
| 					'category_slug':categoryData.slug, | 					'category_slug': categoryData.slug, | ||||||
| 					'locked': topicData.locked, | 					'locked': topicData.locked, | ||||||
| 					'deleted': topicData.deleted, | 					'deleted': topicData.deleted, | ||||||
| 					'pinned': topicData.pinned, | 					'pinned': topicData.pinned, | ||||||
| 					'slug': topicData.slug, | 					'slug': topicData.slug, | ||||||
| 					'postcount' : topicData.postcount, | 					'postcount': topicData.postcount, | ||||||
| 					'topic_id': tid, | 					'topic_id': tid, | ||||||
| 					'expose_tools': privileges.editable ? 1 : 0, | 					'expose_tools': privileges.editable ? 1 : 0, | ||||||
| 					'posts': topicPosts, | 					'posts': topicPosts, | ||||||
| @@ -438,11 +443,13 @@ var	RDB = require('./redis.js') | |||||||
| 				numTids, x; | 				numTids, x; | ||||||
|  |  | ||||||
| 			// Sort into ascending order | 			// Sort into ascending order | ||||||
| 			tids.sort(function(a, b) { return a - b; }); | 			tids.sort(function(a, b) { | ||||||
|  | 				return a - b; | ||||||
|  | 			}); | ||||||
|  |  | ||||||
| 			// Eliminate everything after the "after" tid | 			// Eliminate everything after the "after" tid | ||||||
| 			if (after) { | 			if (after) { | ||||||
| 				for(x=0,numTids=tids.length;x<numTids;x++) { | 				for (x = 0, numTids = tids.length; x < numTids; x++) { | ||||||
| 					if (tids[x] >= after) { | 					if (tids[x] >= after) { | ||||||
| 						tids = tids.slice(0, x); | 						tids = tids.slice(0, x); | ||||||
| 						break; | 						break; | ||||||
| @@ -457,7 +464,9 @@ var	RDB = require('./redis.js') | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			// Sort into descending order | 			// Sort into descending order | ||||||
| 			tids.sort(function(a, b) { return b - a; }); | 			tids.sort(function(a, b) { | ||||||
|  | 				return b - a; | ||||||
|  | 			}); | ||||||
|  |  | ||||||
| 			async.each(tids, function(tid, next) { | 			async.each(tids, function(tid, next) { | ||||||
| 				Topics.getTopicDataWithUsername(tid, function(topicData) { | 				Topics.getTopicDataWithUsername(tid, function(topicData) { | ||||||
| @@ -472,14 +481,14 @@ var	RDB = require('./redis.js') | |||||||
|  |  | ||||||
| 	Topics.markAllRead = function(uid, callback) { | 	Topics.markAllRead = function(uid, callback) { | ||||||
| 		RDB.smembers('topics:tid', function(err, tids) { | 		RDB.smembers('topics:tid', function(err, tids) { | ||||||
| 			if(err) { | 			if (err) { | ||||||
| 				console.log(err); | 				console.log(err); | ||||||
| 				callback(err, null); | 				callback(err, null); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if(tids && tids.length) { | 			if (tids && tids.length) { | ||||||
| 				for(var i=0; i<tids.length; ++i) { | 				for (var i = 0; i < tids.length; ++i) { | ||||||
| 					Topics.markAsRead(tids[i], uid); | 					Topics.markAsRead(tids[i], uid); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| @@ -507,7 +516,7 @@ var	RDB = require('./redis.js') | |||||||
| 		Topics.getTopicField(tid, 'cid', function(err, cid) { | 		Topics.getTopicField(tid, 'cid', function(err, cid) { | ||||||
|  |  | ||||||
| 			categories.isTopicsRead(cid, uid, function(read) { | 			categories.isTopicsRead(cid, uid, function(read) { | ||||||
| 				if(read) { | 				if (read) { | ||||||
| 					categories.markAsRead(cid, uid); | 					categories.markAsRead(cid, uid); | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
| @@ -525,7 +534,7 @@ var	RDB = require('./redis.js') | |||||||
| 	Topics.hasReadTopics = function(tids, uid, callback) { | 	Topics.hasReadTopics = function(tids, uid, callback) { | ||||||
| 		var batch = RDB.multi(); | 		var batch = RDB.multi(); | ||||||
|  |  | ||||||
| 		for (var i=0, ii=tids.length; i<ii; i++) { | 		for (var i = 0, ii = tids.length; i < ii; i++) { | ||||||
| 			batch.sismember(schema.topics(tids[i]).read_by_uid, uid); | 			batch.sismember(schema.topics(tids[i]).read_by_uid, uid); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -537,7 +546,7 @@ var	RDB = require('./redis.js') | |||||||
| 	Topics.hasReadTopic = function(tid, uid, callback) { | 	Topics.hasReadTopic = function(tid, uid, callback) { | ||||||
| 		RDB.sismember(schema.topics(tid).read_by_uid, uid, function(err, hasRead) { | 		RDB.sismember(schema.topics(tid).read_by_uid, uid, function(err, hasRead) { | ||||||
|  |  | ||||||
| 			if(err === null) { | 			if (err === null) { | ||||||
| 				callback(hasRead); | 				callback(hasRead); | ||||||
| 			} else { | 			} else { | ||||||
| 				console.log(err); | 				console.log(err); | ||||||
| @@ -567,7 +576,7 @@ var	RDB = require('./redis.js') | |||||||
| 				posts.getPostFields(pid, ['content', 'uid', 'timestamp'], function(postData) { | 				posts.getPostFields(pid, ['content', 'uid', 'timestamp'], function(postData) { | ||||||
|  |  | ||||||
| 					user.getUserFields(postData.uid, ['username', 'picture'], function(err, userData) { | 					user.getUserFields(postData.uid, ['username', 'picture'], function(err, userData) { | ||||||
| 						if(err) | 						if (err) | ||||||
| 							return callback(err, null); | 							return callback(err, null); | ||||||
|  |  | ||||||
| 						var stripped = postData.content, | 						var stripped = postData.content, | ||||||
| @@ -575,7 +584,7 @@ var	RDB = require('./redis.js') | |||||||
| 							returnObj = { | 							returnObj = { | ||||||
| 								"username": userData.username, | 								"username": userData.username, | ||||||
| 								"picture": userData.picture, | 								"picture": userData.picture, | ||||||
| 								"timestamp" : timestamp | 								"timestamp": timestamp | ||||||
| 							}; | 							}; | ||||||
|  |  | ||||||
| 						if (postData.content) { | 						if (postData.content) { | ||||||
| @@ -596,27 +605,27 @@ var	RDB = require('./redis.js') | |||||||
|  |  | ||||||
| 	Topics.emitTitleTooShortAlert = function(socket) { | 	Topics.emitTitleTooShortAlert = function(socket) { | ||||||
| 		socket.emit('event:alert', { | 		socket.emit('event:alert', { | ||||||
| 				type: 'danger', | 			type: 'danger', | ||||||
| 				timeout: 2000, | 			timeout: 2000, | ||||||
| 				title: 'Title too short', | 			title: 'Title too short', | ||||||
| 				message: "Please enter a longer title. At least " + meta.config.minimumTitleLength + " characters.", | 			message: "Please enter a longer title. At least " + meta.config.minimumTitleLength + " characters.", | ||||||
| 				alert_id: 'post_error' | 			alert_id: 'post_error' | ||||||
| 			}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Topics.post = function(uid, title, content, category_id, callback) { | 	Topics.post = function(uid, title, content, category_id, callback) { | ||||||
| 		if (!category_id) | 		if (!category_id) | ||||||
| 			throw new Error('Attempted to post without a category_id'); | 			throw new Error('Attempted to post without a category_id'); | ||||||
|  |  | ||||||
| 		if(content) | 		if (content) | ||||||
| 			content = content.trim(); | 			content = content.trim(); | ||||||
| 		if(title) | 		if (title) | ||||||
| 			title = title.trim(); | 			title = title.trim(); | ||||||
|  |  | ||||||
| 		if (uid === 0) { | 		if (uid === 0) { | ||||||
| 			callback(new Error('not-logged-in'), null); | 			callback(new Error('not-logged-in'), null); | ||||||
| 			return; | 			return; | ||||||
| 		} else if(!title || title.length < meta.config.minimumTitleLength) { | 		} else if (!title || title.length < meta.config.minimumTitleLength) { | ||||||
| 			callback(new Error('title-too-short'), null); | 			callback(new Error('title-too-short'), null); | ||||||
| 			return; | 			return; | ||||||
| 		} else if (!content || content.length < meta.config.miminumPostLength) { | 		} else if (!content || content.length < meta.config.miminumPostLength) { | ||||||
| @@ -626,7 +635,7 @@ var	RDB = require('./redis.js') | |||||||
|  |  | ||||||
| 		user.getUserField(uid, 'lastposttime', function(err, lastposttime) { | 		user.getUserField(uid, 'lastposttime', function(err, lastposttime) { | ||||||
| 			if (err) lastposttime = 0; | 			if (err) lastposttime = 0; | ||||||
| 			if(Date.now() - lastposttime < meta.config.postDelay) { | 			if (Date.now() - lastposttime < meta.config.postDelay) { | ||||||
| 				callback(new Error('too-many-posts'), null); | 				callback(new Error('too-many-posts'), null); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| @@ -686,9 +695,11 @@ var	RDB = require('./redis.js') | |||||||
|  |  | ||||||
| 						// Notify any users looking at the category that a new topic has arrived | 						// Notify any users looking at the category that a new topic has arrived | ||||||
| 						Topics.getTopicForCategoryView(tid, uid, function(topicData) { | 						Topics.getTopicForCategoryView(tid, uid, function(topicData) { | ||||||
| 							io.sockets.in('category_' + category_id).emit('event:new_topic', topicData); | 							io.sockets. in ('category_' + category_id).emit('event:new_topic', topicData); | ||||||
| 							io.sockets.in('recent_posts').emit('event:new_topic', topicData); | 							io.sockets. in ('recent_posts').emit('event:new_topic', topicData); | ||||||
| 							io.sockets.in('users/' + uid).emit('event:new_post', {posts:postData}); | 							io.sockets. in ('users/' + uid).emit('event:new_post', { | ||||||
|  | 								posts: postData | ||||||
|  | 							}); | ||||||
| 						}); | 						}); | ||||||
|  |  | ||||||
| 						callback(null, postData); | 						callback(null, postData); | ||||||
| @@ -739,7 +750,7 @@ var	RDB = require('./redis.js') | |||||||
|  |  | ||||||
| 			function getUid(pid, next) { | 			function getUid(pid, next) { | ||||||
| 				posts.getPostField(pid, 'uid', function(uid) { | 				posts.getPostField(pid, 'uid', function(uid) { | ||||||
| 					if(err) | 					if (err) | ||||||
| 						return next(err); | 						return next(err); | ||||||
| 					uids[uid] = 1; | 					uids[uid] = 1; | ||||||
| 					next(null); | 					next(null); | ||||||
| @@ -747,7 +758,7 @@ var	RDB = require('./redis.js') | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			async.each(pids, getUid, function(err) { | 			async.each(pids, getUid, function(err) { | ||||||
| 				if(err) | 				if (err) | ||||||
| 					return callback(err, null); | 					return callback(err, null); | ||||||
|  |  | ||||||
| 				callback(null, Object.keys(uids)); | 				callback(null, Object.keys(uids)); | ||||||
| @@ -777,11 +788,11 @@ var	RDB = require('./redis.js') | |||||||
|  |  | ||||||
| 	Topics.reIndexTopic = function(tid, callback) { | 	Topics.reIndexTopic = function(tid, callback) { | ||||||
| 		Topics.getPids(tid, function(err, pids) { | 		Topics.getPids(tid, function(err, pids) { | ||||||
| 			if(err) { | 			if (err) { | ||||||
| 				callback(err); | 				callback(err); | ||||||
| 			} else { | 			} else { | ||||||
| 				posts.reIndexPids(pids, function(err) { | 				posts.reIndexPids(pids, function(err) { | ||||||
| 					if(err) { | 					if (err) { | ||||||
| 						callback(err); | 						callback(err); | ||||||
| 					} else { | 					} else { | ||||||
| 						callback(null); | 						callback(null); | ||||||
| @@ -793,12 +804,12 @@ var	RDB = require('./redis.js') | |||||||
|  |  | ||||||
| 	Topics.reIndexAll = function(callback) { | 	Topics.reIndexAll = function(callback) { | ||||||
| 		RDB.smembers('topics:tid', function(err, tids) { | 		RDB.smembers('topics:tid', function(err, tids) { | ||||||
| 			if(err) { | 			if (err) { | ||||||
| 				callback(err, null); | 				callback(err, null); | ||||||
| 			} else { | 			} else { | ||||||
|  |  | ||||||
| 				async.each(tids, Topics.reIndexTopic, function(err) { | 				async.each(tids, Topics.reIndexTopic, function(err) { | ||||||
| 					if(err) { | 					if (err) { | ||||||
| 						callback(err, null); | 						callback(err, null); | ||||||
| 					} else { | 					} else { | ||||||
| 						callback(null, 'All topics reindexed.'); | 						callback(null, 'All topics reindexed.'); | ||||||
|   | |||||||
| @@ -6,32 +6,31 @@ var RDB = require('./redis.js'), | |||||||
|  |  | ||||||
|  |  | ||||||
| function upgradeCategory(cid, callback) { | function upgradeCategory(cid, callback) { | ||||||
| 	RDB.type('categories:'+ cid +':tid', function(err, type) { | 	RDB.type('categories:' + cid + ':tid', function(err, type) { | ||||||
| 		if (type === 'set') { | 		if (type === 'set') { | ||||||
| 			RDB.smembers('categories:' + cid + ':tid', function(err, tids) { | 			RDB.smembers('categories:' + cid + ':tid', function(err, tids) { | ||||||
|  |  | ||||||
| 				function moveTopic(tid, callback) { | 				function moveTopic(tid, callback) { | ||||||
| 					RDB.hget('topic:' + tid, 'timestamp', function(err, timestamp) { | 					RDB.hget('topic:' + tid, 'timestamp', function(err, timestamp) { | ||||||
| 						if(err) | 						if (err) | ||||||
| 							return callback(err); | 							return callback(err); | ||||||
|  |  | ||||||
| 						RDB.zadd('temp_categories:'+ cid + ':tid', timestamp, tid); | 						RDB.zadd('temp_categories:' + cid + ':tid', timestamp, tid); | ||||||
| 						callback(null); | 						callback(null); | ||||||
| 					}); | 					}); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				async.each(tids, moveTopic, function(err) { | 				async.each(tids, moveTopic, function(err) { | ||||||
| 					if(!err) { | 					if (!err) { | ||||||
| 						RDB.rename('temp_categories:' + cid + ':tid', 'categories:' + cid + ':tid'); | 						RDB.rename('temp_categories:' + cid + ':tid', 'categories:' + cid + ':tid'); | ||||||
| 						callback(null); | 						callback(null); | ||||||
| 					} | 					} else | ||||||
| 					else |  | ||||||
| 						callback(err); | 						callback(err); | ||||||
| 				}); | 				}); | ||||||
|  |  | ||||||
| 			}); | 			}); | ||||||
| 		} else { | 		} else { | ||||||
| 			winston.info('category already upgraded '+ cid); | 			winston.info('category already upgraded ' + cid); | ||||||
| 			callback(null); | 			callback(null); | ||||||
| 		} | 		} | ||||||
| 	}); | 	}); | ||||||
| @@ -39,24 +38,24 @@ function upgradeCategory(cid, callback) { | |||||||
|  |  | ||||||
| function upgradeUser(uid, callback) { | function upgradeUser(uid, callback) { | ||||||
| 	user.getUserFields(uid, ['joindate', 'postcount', 'reputation'], function(err, userData) { | 	user.getUserFields(uid, ['joindate', 'postcount', 'reputation'], function(err, userData) { | ||||||
| 		if(err) | 		if (err) | ||||||
| 			return callback(err); | 			return callback(err); | ||||||
|  |  | ||||||
| 		async.parallel([ | 		async.parallel([ | ||||||
| 			function(next) { | 			function(next) { | ||||||
| 				if(userData.joindate) | 				if (userData.joindate) | ||||||
| 					RDB.zadd('users:joindate', userData.joindate, uid, next); | 					RDB.zadd('users:joindate', userData.joindate, uid, next); | ||||||
| 				else | 				else | ||||||
| 					next(null); | 					next(null); | ||||||
| 			}, | 			}, | ||||||
| 			function(next) { | 			function(next) { | ||||||
| 				if(userData.postcount)			 | 				if (userData.postcount) | ||||||
| 					RDB.zadd('users:postcount', userData.postcount, uid, next); | 					RDB.zadd('users:postcount', userData.postcount, uid, next); | ||||||
| 				else | 				else | ||||||
| 					next(null); | 					next(null); | ||||||
| 			}, | 			}, | ||||||
| 			function(next) { | 			function(next) { | ||||||
| 				if(userData.reputation) | 				if (userData.reputation) | ||||||
| 					RDB.zadd('users:reputation', userData.reputation, uid, next); | 					RDB.zadd('users:reputation', userData.reputation, uid, next); | ||||||
| 				else | 				else | ||||||
| 					next(null); | 					next(null); | ||||||
| @@ -69,24 +68,24 @@ function upgradeUser(uid, callback) { | |||||||
|  |  | ||||||
| function upgradeUserHash(uid, callback) { | function upgradeUserHash(uid, callback) { | ||||||
| 	user.getUserFields(uid, ['username', 'userslug', 'email'], function(err, userData) { | 	user.getUserFields(uid, ['username', 'userslug', 'email'], function(err, userData) { | ||||||
| 		if(err) | 		if (err) | ||||||
| 			return callback(err); | 			return callback(err); | ||||||
|  |  | ||||||
| 		async.parallel([ | 		async.parallel([ | ||||||
| 			function(next) { | 			function(next) { | ||||||
| 				if(userData.username) | 				if (userData.username) | ||||||
| 					RDB.hset('username:uid', userData.username, uid, next); | 					RDB.hset('username:uid', userData.username, uid, next); | ||||||
| 				else | 				else | ||||||
| 					next(null); | 					next(null); | ||||||
| 			}, | 			}, | ||||||
| 			function(next) { | 			function(next) { | ||||||
| 				if(userData.userslug) | 				if (userData.userslug) | ||||||
| 					RDB.hset('userslug:uid', userData.userslug, uid, next); | 					RDB.hset('userslug:uid', userData.userslug, uid, next); | ||||||
| 				else | 				else | ||||||
| 					next(null); | 					next(null); | ||||||
| 			}, | 			}, | ||||||
| 			function(next) { | 			function(next) { | ||||||
| 				if(userData.email) | 				if (userData.email) | ||||||
| 					RDB.hset('email:uid', userData.email, uid, next); | 					RDB.hset('email:uid', userData.email, uid, next); | ||||||
| 				else | 				else | ||||||
| 					next(null); | 					next(null); | ||||||
| @@ -135,7 +134,7 @@ exports.upgrade = function() { | |||||||
| 			RDB.lrange('categories:cid', 0, -1, function(err, cids) { | 			RDB.lrange('categories:cid', 0, -1, function(err, cids) { | ||||||
|  |  | ||||||
| 				async.each(cids, upgradeCategory, function(err) { | 				async.each(cids, upgradeCategory, function(err) { | ||||||
| 					if(!err) { | 					if (!err) { | ||||||
| 						winston.info('upgraded categories'); | 						winston.info('upgraded categories'); | ||||||
| 						next(null, null); | 						next(null, null); | ||||||
| 					} else { | 					} else { | ||||||
| @@ -151,7 +150,7 @@ exports.upgrade = function() { | |||||||
| 			RDB.lrange('userlist', 0, -1, function(err, uids) { | 			RDB.lrange('userlist', 0, -1, function(err, uids) { | ||||||
|  |  | ||||||
| 				async.each(uids, upgradeUser, function(err) { | 				async.each(uids, upgradeUser, function(err) { | ||||||
| 					if(!err) { | 					if (!err) { | ||||||
| 						winston.info('upgraded users'); | 						winston.info('upgraded users'); | ||||||
| 						next(null, null); | 						next(null, null); | ||||||
| 					} else { | 					} else { | ||||||
| @@ -165,11 +164,11 @@ exports.upgrade = function() { | |||||||
| 		function upgradeUserHashes(next) { | 		function upgradeUserHashes(next) { | ||||||
| 			winston.info('upgrading user hashes'); | 			winston.info('upgrading user hashes'); | ||||||
| 			RDB.zrange('users:joindate', 0, -1, function(err, uids) { | 			RDB.zrange('users:joindate', 0, -1, function(err, uids) { | ||||||
| 				if(err) | 				if (err) | ||||||
| 					return next(err); | 					return next(err); | ||||||
|  |  | ||||||
| 				async.each(uids, upgradeUserHash, function(err) { | 				async.each(uids, upgradeUserHash, function(err) { | ||||||
| 					if(!err) { | 					if (!err) { | ||||||
| 						winston.info('upgraded user hashes'); | 						winston.info('upgraded user hashes'); | ||||||
| 						next(null, null); | 						next(null, null); | ||||||
| 					} else { | 					} else { | ||||||
| @@ -183,7 +182,7 @@ exports.upgrade = function() { | |||||||
| 	]; | 	]; | ||||||
|  |  | ||||||
| 	async.series(schema, function(err, results) { | 	async.series(schema, function(err, results) { | ||||||
| 		if(!err) | 		if (!err) | ||||||
| 			winston.info('upgrade complete'); | 			winston.info('upgrade complete'); | ||||||
| 		else | 		else | ||||||
| 			winston.err(err); | 			winston.err(err); | ||||||
|   | |||||||
							
								
								
									
										238
									
								
								src/user.js
									
									
									
									
									
								
							
							
						
						
									
										238
									
								
								src/user.js
									
									
									
									
									
								
							| @@ -38,7 +38,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 			function(next) { | 			function(next) { | ||||||
| 				if (email !== undefined) { | 				if (email !== undefined) { | ||||||
| 					User.isEmailAvailable(email, function(err, available) { | 					User.isEmailAvailable(email, function(err, available) { | ||||||
| 						if(err) | 						if (err) | ||||||
| 							return next(err); | 							return next(err); | ||||||
| 						next(!available ? new Error('Email taken!') : null); | 						next(!available ? new Error('Email taken!') : null); | ||||||
| 					}); | 					}); | ||||||
| @@ -53,19 +53,19 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 				var gravatar = User.createGravatarURLFromEmail(email); | 				var gravatar = User.createGravatarURLFromEmail(email); | ||||||
| 				var timestamp = Date.now(); | 				var timestamp = Date.now(); | ||||||
|  |  | ||||||
| 				RDB.hmset('user:'+uid, { | 				RDB.hmset('user:' + uid, { | ||||||
| 					'uid': uid, | 					'uid': uid, | ||||||
| 					'username' : username, | 					'username': username, | ||||||
| 					'userslug' : userslug, | 					'userslug': userslug, | ||||||
| 					'fullname': '', | 					'fullname': '', | ||||||
| 					'location':'', | 					'location': '', | ||||||
| 					'birthday':'', | 					'birthday': '', | ||||||
| 					'website':'', | 					'website': '', | ||||||
| 					'email' : email || '', | 					'email': email || '', | ||||||
| 					'signature':'', | 					'signature': '', | ||||||
| 					'joindate' : timestamp, | 					'joindate': timestamp, | ||||||
| 					'picture': gravatar, | 					'picture': gravatar, | ||||||
| 					'gravatarpicture' : gravatar, | 					'gravatarpicture': gravatar, | ||||||
| 					'uploadedpicture': '', | 					'uploadedpicture': '', | ||||||
| 					'profileviews': 0, | 					'profileviews': 0, | ||||||
| 					'reputation': 0, | 					'reputation': 0, | ||||||
| @@ -87,7 +87,9 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 				RDB.incr('usercount', function(err, count) { | 				RDB.incr('usercount', function(err, count) { | ||||||
| 					RDB.handle(err); | 					RDB.handle(err); | ||||||
|  |  | ||||||
| 					if (typeof io !== 'undefined') io.sockets.emit('user.count', {count: count}); | 					if (typeof io !== 'undefined') io.sockets.emit('user.count', { | ||||||
|  | 						count: count | ||||||
|  | 					}); | ||||||
| 				}); | 				}); | ||||||
|  |  | ||||||
| 				RDB.zadd('users:joindate', timestamp, uid); | 				RDB.zadd('users:joindate', timestamp, uid); | ||||||
| @@ -96,7 +98,10 @@ var utils = require('./../public/src/utils.js'), | |||||||
|  |  | ||||||
| 				userSearch.index(username, uid); | 				userSearch.index(username, uid); | ||||||
|  |  | ||||||
| 				if (typeof io !== 'undefined') io.sockets.emit('user.latest', {userslug: userslug, username: username}); | 				if (typeof io !== 'undefined') io.sockets.emit('user.latest', { | ||||||
|  | 					userslug: userslug, | ||||||
|  | 					username: username | ||||||
|  | 				}); | ||||||
|  |  | ||||||
| 				if (password !== undefined) { | 				if (password !== undefined) { | ||||||
| 					User.hashPassword(password, function(err, hash) { | 					User.hashPassword(password, function(err, hash) { | ||||||
| @@ -109,8 +114,8 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	User.delete = function(uid, callback) { | 	User.delete = function(uid, callback) { | ||||||
| 		RDB.exists('user:'+uid, function(err, exists) { | 		RDB.exists('user:' + uid, function(err, exists) { | ||||||
| 			if(exists === 1) { | 			if (exists === 1) { | ||||||
| 				console.log('deleting uid ' + uid); | 				console.log('deleting uid ' + uid); | ||||||
|  |  | ||||||
| 				User.getUserData(uid, function(err, data) { | 				User.getUserData(uid, function(err, data) { | ||||||
| @@ -152,7 +157,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	User.getMultipleUserFields = function(uids, fields, callback) { | 	User.getMultipleUserFields = function(uids, fields, callback) { | ||||||
| 		if(uids.length === 0) { | 		if (uids.length === 0) { | ||||||
| 			return callback(null, []); | 			return callback(null, []); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -164,7 +169,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
|  |  | ||||||
| 		function iterator(uid, next) { | 		function iterator(uid, next) { | ||||||
| 			User.getUserFields(uid, fields, function(err, userData) { | 			User.getUserFields(uid, fields, function(err, userData) { | ||||||
| 				if(err) | 				if (err) | ||||||
| 					return next(err); | 					return next(err); | ||||||
| 				returnData.push(userData); | 				returnData.push(userData); | ||||||
| 				next(null); | 				next(null); | ||||||
| @@ -179,7 +184,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 	User.getUserData = function(uid, callback) { | 	User.getUserData = function(uid, callback) { | ||||||
| 		RDB.hgetall('user:' + uid, function(err, data) { | 		RDB.hgetall('user:' + uid, function(err, data) { | ||||||
|  |  | ||||||
| 			if(data && data['password']) { | 			if (data && data['password']) { | ||||||
| 				delete data['password']; | 				delete data['password']; | ||||||
| 			} | 			} | ||||||
| 			callback(err, data); | 			callback(err, data); | ||||||
| @@ -195,28 +200,34 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 	User.updateProfile = function(uid, data, callback) { | 	User.updateProfile = function(uid, data, callback) { | ||||||
|  |  | ||||||
| 		var fields = ['email', 'fullname', 'website', 'location', 'birthday', 'signature']; | 		var fields = ['email', 'fullname', 'website', 'location', 'birthday', 'signature']; | ||||||
| 		var returnData = {success:false}; | 		var returnData = { | ||||||
|  | 			success: false | ||||||
|  | 		}; | ||||||
|  |  | ||||||
| 		function isSignatureValid(next) { | 		function isSignatureValid(next) { | ||||||
| 			if(data['signature'] !== undefined && data['signature'].length > 150) { | 			if (data['signature'] !== undefined && data['signature'].length > 150) { | ||||||
| 				next({error:'Signature can\'t be longer than 150 characters!'}, false); | 				next({ | ||||||
|  | 					error: 'Signature can\'t be longer than 150 characters!' | ||||||
|  | 				}, false); | ||||||
| 			} else { | 			} else { | ||||||
| 				next(null, true); | 				next(null, true); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		function isEmailAvailable(next) { | 		function isEmailAvailable(next) { | ||||||
| 			if(!data['email']) { | 			if (!data['email']) { | ||||||
| 				return next(null, true); | 				return next(null, true); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			User.getUserField(uid, 'email', function(err, email) { | 			User.getUserField(uid, 'email', function(err, email) { | ||||||
| 				if(email !== data['email']) { | 				if (email !== data['email']) { | ||||||
| 					User.isEmailAvailable(data['email'], function(err, available) { | 					User.isEmailAvailable(data['email'], function(err, available) { | ||||||
| 						if(err) | 						if (err) | ||||||
| 							return next(err, null); | 							return next(err, null); | ||||||
| 						if(!available) { | 						if (!available) { | ||||||
| 							next({error:'Email not available!'}, false); | 							next({ | ||||||
|  | 								error: 'Email not available!' | ||||||
|  | 							}, false); | ||||||
| 						} else { | 						} else { | ||||||
| 							next(null, true); | 							next(null, true); | ||||||
| 						} | 						} | ||||||
| @@ -228,11 +239,11 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		async.series([isSignatureValid, isEmailAvailable], function(err, results) { | 		async.series([isSignatureValid, isEmailAvailable], function(err, results) { | ||||||
| 			if(err) { | 			if (err) { | ||||||
| 				callback(err, returnData); | 				callback(err, returnData); | ||||||
| 			} else { | 			} else { | ||||||
| 				async.each(fields, updateField, function(err) { | 				async.each(fields, updateField, function(err) { | ||||||
| 					if(err) { | 					if (err) { | ||||||
| 						callback(err, returnData); | 						callback(err, returnData); | ||||||
| 					} else { | 					} else { | ||||||
| 						returnData.success = true; | 						returnData.success = true; | ||||||
| @@ -243,18 +254,18 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		function updateField(field, next) { | 		function updateField(field, next) { | ||||||
| 			if(data[field] !== undefined) { | 			if (data[field] !== undefined) { | ||||||
| 				if(field === 'email') { | 				if (field === 'email') { | ||||||
| 					var gravatarpicture = User.createGravatarURLFromEmail(data[field]); | 					var gravatarpicture = User.createGravatarURLFromEmail(data[field]); | ||||||
| 					User.setUserField(uid, 'gravatarpicture', gravatarpicture); | 					User.setUserField(uid, 'gravatarpicture', gravatarpicture); | ||||||
| 					User.getUserFields(uid, ['email', 'picture', 'uploadedpicture'], function(err, userData) { | 					User.getUserFields(uid, ['email', 'picture', 'uploadedpicture'], function(err, userData) { | ||||||
| 						if(err) | 						if (err) | ||||||
| 							return next(err); | 							return next(err); | ||||||
|  |  | ||||||
| 						RDB.hdel('email:uid', userData['email']); | 						RDB.hdel('email:uid', userData['email']); | ||||||
| 						RDB.hset('email:uid', data['email'], uid); | 						RDB.hset('email:uid', data['email'], uid); | ||||||
| 						User.setUserField(uid, field, data[field]); | 						User.setUserField(uid, field, data[field]); | ||||||
| 						if(userData.picture !== userData.uploadedpicture) { | 						if (userData.picture !== userData.uploadedpicture) { | ||||||
| 							returnData.picture = gravatarpicture; | 							returnData.picture = gravatarpicture; | ||||||
| 							User.setUserField(uid, 'picture', gravatarpicture); | 							User.setUserField(uid, 'picture', gravatarpicture); | ||||||
| 						} | 						} | ||||||
| @@ -262,7 +273,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 						next(null); | 						next(null); | ||||||
| 					}); | 					}); | ||||||
| 					return; | 					return; | ||||||
| 				} else if(field === 'signature') { | 				} else if (field === 'signature') { | ||||||
| 					data[field] = utils.strip_tags(data[field]); | 					data[field] = utils.strip_tags(data[field]); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| @@ -282,13 +293,15 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	User.changePassword = function(uid, data, callback) { | 	User.changePassword = function(uid, data, callback) { | ||||||
| 		if(!utils.isPasswordValid(data.newPassword)) { | 		if (!utils.isPasswordValid(data.newPassword)) { | ||||||
| 			return callback({error:'Invalid password!'}); | 			return callback({ | ||||||
|  | 				error: 'Invalid password!' | ||||||
|  | 			}); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		User.getUserField(uid, 'password', function(err, user_password) { | 		User.getUserField(uid, 'password', function(err, user_password) { | ||||||
| 			bcrypt.compare(data.currentPassword, user_password, function(err, res) { | 			bcrypt.compare(data.currentPassword, user_password, function(err, res) { | ||||||
| 				if(err) { | 				if (err) { | ||||||
| 					return callback(err); | 					return callback(err); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| @@ -299,7 +312,9 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 						callback(null); | 						callback(null); | ||||||
| 					}); | 					}); | ||||||
| 				} else { | 				} else { | ||||||
| 					callback({error:'Your current password is not correct!'}); | 					callback({ | ||||||
|  | 						error: 'Your current password is not correct!' | ||||||
|  | 					}); | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| @@ -325,13 +340,13 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 		var data = []; | 		var data = []; | ||||||
|  |  | ||||||
| 		RDB.zrevrange(set, start, stop, function(err, uids) { | 		RDB.zrevrange(set, start, stop, function(err, uids) { | ||||||
| 			if(err) { | 			if (err) { | ||||||
| 				return callback(err, null); | 				return callback(err, null); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			function iterator(uid, callback) { | 			function iterator(uid, callback) { | ||||||
| 				User.getUserData(uid, function(err, userData) { | 				User.getUserData(uid, function(err, userData) { | ||||||
| 					if(userData) { | 					if (userData) { | ||||||
| 						data.push(userData); | 						data.push(userData); | ||||||
| 					} | 					} | ||||||
| 					callback(null); | 					callback(null); | ||||||
| @@ -356,11 +371,11 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 			options.forcedefault = 'y'; | 			options.forcedefault = 'y'; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return require('gravatar').url(email, options, https=nconf.get('https')); | 		return require('gravatar').url(email, options, https = nconf.get('https')); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	User.hashPassword = function(password, callback) { | 	User.hashPassword = function(password, callback) { | ||||||
| 		if(!password) { | 		if (!password) { | ||||||
| 			callback(password); | 			callback(password); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| @@ -372,17 +387,17 @@ var utils = require('./../public/src/utils.js'), | |||||||
|  |  | ||||||
| 	User.reIndexAll = function(callback) { | 	User.reIndexAll = function(callback) { | ||||||
| 		User.getUsers('users:joindate', 0, -1, function(err, usersData) { | 		User.getUsers('users:joindate', 0, -1, function(err, usersData) { | ||||||
| 			if(err) { | 			if (err) { | ||||||
| 				return callback(err, null); | 				return callback(err, null); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			function reIndexUser(uid, username) { | 			function reIndexUser(uid, username) { | ||||||
| 				userSearch.remove(uid, function(){ | 				userSearch.remove(uid, function() { | ||||||
| 					userSearch.index(username, uid); | 					userSearch.index(username, uid); | ||||||
| 				}) | 				}) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			for(var i=0; i<usersData.length; ++i) { | 			for (var i = 0; i < usersData.length; ++i) { | ||||||
| 				reIndexUser(usersData[i].uid, usersData[i].username); | 				reIndexUser(usersData[i].uid, usersData[i].username); | ||||||
| 			} | 			} | ||||||
| 			callback(null, 1); | 			callback(null, 1); | ||||||
| @@ -390,17 +405,17 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	User.search = function(username, callback) { | 	User.search = function(username, callback) { | ||||||
| 		if(!username) { | 		if (!username) { | ||||||
| 			callback([]); | 			callback([]); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		userSearch.query(query = username).type('or').end(function(err, uids) { | 		userSearch.query(query = username).type('or').end(function(err, uids) { | ||||||
| 			if(err) { | 			if (err) { | ||||||
| 				console.log(err); | 				console.log(err); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 			if(uids && uids.length) { | 			if (uids && uids.length) { | ||||||
| 				User.getDataForUsers(uids, function(userdata) { | 				User.getDataForUsers(uids, function(userdata) { | ||||||
| 					callback(userdata); | 					callback(userdata); | ||||||
| 				}); | 				}); | ||||||
| @@ -432,8 +447,8 @@ var utils = require('./../public/src/utils.js'), | |||||||
|  |  | ||||||
| 	User.getPostIds = function(uid, start, end, callback) { | 	User.getPostIds = function(uid, start, end, callback) { | ||||||
| 		RDB.lrange('uid:' + uid + ':posts', start, end, function(err, pids) { | 		RDB.lrange('uid:' + uid + ':posts', start, end, function(err, pids) { | ||||||
| 			if(!err) { | 			if (!err) { | ||||||
| 				if(pids && pids.length) | 				if (pids && pids.length) | ||||||
| 					callback(pids); | 					callback(pids); | ||||||
| 				else | 				else | ||||||
| 					callback([]); | 					callback([]); | ||||||
| @@ -444,15 +459,19 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	User.sendConfirmationEmail = function (email) { | 	User.sendConfirmationEmail = function(email) { | ||||||
| 		if (meta.config['email:host'] && meta.config['email:port'] && meta.config['email:from']) { | 		if (meta.config['email:host'] && meta.config['email:port'] && meta.config['email:from']) { | ||||||
| 			var confirm_code = utils.generateUUID(), | 			var confirm_code = utils.generateUUID(), | ||||||
| 				confirm_link = nconf.get('url') + 'confirm/' + confirm_code, | 				confirm_link = nconf.get('url') + 'confirm/' + confirm_code, | ||||||
| 				confirm_email = global.templates['emails/header'] + global.templates['emails/email_confirm'].parse({'CONFIRM_LINK': confirm_link}) + global.templates['emails/footer'], | 				confirm_email = global.templates['emails/header'] + global.templates['emails/email_confirm'].parse({ | ||||||
| 				confirm_email_plaintext = global.templates['emails/email_confirm_plaintext'].parse({ 'CONFIRM_LINK': confirm_link }); | 					'CONFIRM_LINK': confirm_link | ||||||
|  | 				}) + global.templates['emails/footer'], | ||||||
|  | 				confirm_email_plaintext = global.templates['emails/email_confirm_plaintext'].parse({ | ||||||
|  | 					'CONFIRM_LINK': confirm_link | ||||||
|  | 				}); | ||||||
|  |  | ||||||
| 			// Email confirmation code | 			// Email confirmation code | ||||||
| 			var expiry_time = 60*60*2,	// Expire after 2 hours | 			var expiry_time = 60 * 60 * 2, // Expire after 2 hours | ||||||
| 				email_key = 'email:' + email + ':confirm', | 				email_key = 'email:' + email + ':confirm', | ||||||
| 				confirm_key = 'confirm:' + confirm_code + ':email'; | 				confirm_key = 'confirm:' + confirm_code + ':email'; | ||||||
|  |  | ||||||
| @@ -467,12 +486,10 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 				from: meta.config.mailer.from, | 				from: meta.config.mailer.from, | ||||||
| 				to: email, | 				to: email, | ||||||
| 				subject: '[NodeBB] Registration Email Verification', | 				subject: '[NodeBB] Registration Email Verification', | ||||||
| 				attachment: [ | 				attachment: [{ | ||||||
| 					{ | 					data: confirm_email, | ||||||
| 						data: confirm_email, | 					alternative: true | ||||||
| 						alternative: true | 				}] | ||||||
| 					} |  | ||||||
| 				] |  | ||||||
| 			}); | 			}); | ||||||
|  |  | ||||||
| 			emailjsServer.send(message, function(err, success) { | 			emailjsServer.send(message, function(err, success) { | ||||||
| @@ -485,9 +502,9 @@ var utils = require('./../public/src/utils.js'), | |||||||
|  |  | ||||||
| 	User.follow = function(uid, followid, callback) { | 	User.follow = function(uid, followid, callback) { | ||||||
| 		RDB.sadd('following:' + uid, followid, function(err, data) { | 		RDB.sadd('following:' + uid, followid, function(err, data) { | ||||||
| 			if(!err) { | 			if (!err) { | ||||||
| 				RDB.sadd('followers:' + followid, uid, function(err, data) { | 				RDB.sadd('followers:' + followid, uid, function(err, data) { | ||||||
| 					if(!err) { | 					if (!err) { | ||||||
| 						callback(true); | 						callback(true); | ||||||
| 					} else { | 					} else { | ||||||
| 						console.log(err); | 						console.log(err); | ||||||
| @@ -502,9 +519,9 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	User.unfollow = function(uid, unfollowid, callback) { | 	User.unfollow = function(uid, unfollowid, callback) { | ||||||
| 		RDB.srem('following:' + uid, unfollowid, function(err, data){ | 		RDB.srem('following:' + uid, unfollowid, function(err, data) { | ||||||
| 			if(!err) { | 			if (!err) { | ||||||
| 				RDB.srem('followers:' + unfollowid, uid, function(err, data){ | 				RDB.srem('followers:' + unfollowid, uid, function(err, data) { | ||||||
| 					callback(data); | 					callback(data); | ||||||
| 				}); | 				}); | ||||||
| 			} else { | 			} else { | ||||||
| @@ -515,7 +532,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
|  |  | ||||||
| 	User.getFollowing = function(uid, callback) { | 	User.getFollowing = function(uid, callback) { | ||||||
| 		RDB.smembers('following:' + uid, function(err, userIds) { | 		RDB.smembers('following:' + uid, function(err, userIds) { | ||||||
| 			if(!err) { | 			if (!err) { | ||||||
| 				User.getDataForUsers(userIds, callback); | 				User.getDataForUsers(userIds, callback); | ||||||
| 			} else { | 			} else { | ||||||
| 				console.log(err); | 				console.log(err); | ||||||
| @@ -525,7 +542,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
|  |  | ||||||
| 	User.getFollowers = function(uid, callback) { | 	User.getFollowers = function(uid, callback) { | ||||||
| 		RDB.smembers('followers:' + uid, function(err, userIds) { | 		RDB.smembers('followers:' + uid, function(err, userIds) { | ||||||
| 			if(!err) { | 			if (!err) { | ||||||
| 				User.getDataForUsers(userIds, callback); | 				User.getDataForUsers(userIds, callback); | ||||||
| 			} else { | 			} else { | ||||||
| 				console.log(err); | 				console.log(err); | ||||||
| @@ -535,7 +552,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
|  |  | ||||||
| 	User.getFollowingCount = function(uid, callback) { | 	User.getFollowingCount = function(uid, callback) { | ||||||
| 		RDB.smembers('following:' + uid, function(err, userIds) { | 		RDB.smembers('following:' + uid, function(err, userIds) { | ||||||
| 			if(!err) { | 			if (!err) { | ||||||
| 				callback(userIds.length); | 				callback(userIds.length); | ||||||
| 			} else { | 			} else { | ||||||
| 				console.log(err); | 				console.log(err); | ||||||
| @@ -549,7 +566,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 			// either go with not-error-dosomething-else-dosomethingelse, or | 			// either go with not-error-dosomething-else-dosomethingelse, or | ||||||
| 			// go with if-error-dosomething-return | 			// go with if-error-dosomething-return | ||||||
| 			// also why is console.log(err) being used when below we're using RDB.handle()? | 			// also why is console.log(err) being used when below we're using RDB.handle()? | ||||||
| 			if(!err) { | 			if (!err) { | ||||||
| 				callback(userIds.length); | 				callback(userIds.length); | ||||||
| 			} else { | 			} else { | ||||||
| 				console.log(err); | 				console.log(err); | ||||||
| @@ -560,7 +577,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 	User.getDataForUsers = function(uids, callback) { | 	User.getDataForUsers = function(uids, callback) { | ||||||
| 		var returnData = []; | 		var returnData = []; | ||||||
|  |  | ||||||
| 		if(!uids || !Array.isArray(uids) || uids.length === 0) { | 		if (!uids || !Array.isArray(uids) || uids.length === 0) { | ||||||
| 			callback(returnData); | 			callback(returnData); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| @@ -584,8 +601,8 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 				topics.getTopicField(tid, 'slug', function(err, slug) { | 				topics.getTopicField(tid, 'slug', function(err, slug) { | ||||||
| 					var message = '<strong>' + username + '</strong> made a new post'; | 					var message = '<strong>' + username + '</strong> made a new post'; | ||||||
|  |  | ||||||
| 					notifications.create(message, 5, nconf.get('relative_path') + '/topic/' + slug + '#' + pid, 'topic:'+ tid, function(nid) { | 					notifications.create(message, 5, nconf.get('relative_path') + '/topic/' + slug + '#' + pid, 'topic:' + tid, function(nid) { | ||||||
| 		 				notifications.push(nid, followers); | 						notifications.push(nid, followers); | ||||||
| 					}); | 					}); | ||||||
| 				}); | 				}); | ||||||
| 			}); | 			}); | ||||||
| @@ -594,7 +611,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
|  |  | ||||||
| 	User.isFollowing = function(uid, theirid, callback) { | 	User.isFollowing = function(uid, theirid, callback) { | ||||||
| 		RDB.sismember('following:' + uid, theirid, function(err, data) { | 		RDB.sismember('following:' + uid, theirid, function(err, data) { | ||||||
| 			if(!err) { | 			if (!err) { | ||||||
| 				callback(data === 1); | 				callback(data === 1); | ||||||
| 			} else { | 			} else { | ||||||
| 				console.log(err); | 				console.log(err); | ||||||
| @@ -604,7 +621,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
|  |  | ||||||
| 	User.exists = function(userslug, callback) { | 	User.exists = function(userslug, callback) { | ||||||
| 		User.get_uid_by_userslug(userslug, function(err, exists) { | 		User.get_uid_by_userslug(userslug, function(err, exists) { | ||||||
| 			callback(!!exists); | 			callback( !! exists); | ||||||
| 		}); | 		}); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| @@ -612,7 +629,9 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 		RDB.get('usercount', function(err, count) { | 		RDB.get('usercount', function(err, count) { | ||||||
| 			RDB.handle(err); | 			RDB.handle(err); | ||||||
|  |  | ||||||
| 			socket.emit('user.count', { count: count ? count : 0 }); | 			socket.emit('user.count', { | ||||||
|  | 				count: count ? count : 0 | ||||||
|  | 			}); | ||||||
| 		}); | 		}); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| @@ -621,8 +640,11 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 			RDB.handle(err); | 			RDB.handle(err); | ||||||
|  |  | ||||||
| 			User.getUserFields(uid, ['username', 'userslug'], function(err, userData) { | 			User.getUserFields(uid, ['username', 'userslug'], function(err, userData) { | ||||||
| 				if(!err && userData) | 				if (!err && userData) | ||||||
| 					socket.emit('user.latest', {userslug: userData.userslug, username: userData.username}); | 					socket.emit('user.latest', { | ||||||
|  | 						userslug: userData.userslug, | ||||||
|  | 						username: userData.username | ||||||
|  | 					}); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| @@ -725,7 +747,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 				RDB.handle(err); | 				RDB.handle(err); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			var expiry = 60*60*24*14, // Login valid for two weeks | 			var expiry = 60 * 60 * 24 * 14, // Login valid for two weeks | ||||||
| 				sess_key = 'sess:' + sessionID + ':uid', | 				sess_key = 'sess:' + sessionID + ':uid', | ||||||
| 				uid_key = 'uid:' + uid + ':session'; | 				uid_key = 'uid:' + uid + ':session'; | ||||||
|  |  | ||||||
| @@ -739,14 +761,14 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 	User.isModerator = function(uid, cid, callback) { | 	User.isModerator = function(uid, cid, callback) { | ||||||
| 		RDB.sismember('cid:' + cid + ':moderators', uid, function(err, exists) { | 		RDB.sismember('cid:' + cid + ':moderators', uid, function(err, exists) { | ||||||
| 			RDB.handle(err); | 			RDB.handle(err); | ||||||
| 			callback(!!exists); | 			callback( !! exists); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	User.isAdministrator = function(uid, callback) { | 	User.isAdministrator = function(uid, callback) { | ||||||
| 		Groups.getGidFromName('Administrators', function(err, gid) { | 		Groups.getGidFromName('Administrators', function(err, gid) { | ||||||
| 			Groups.isMember(uid, gid, function(err, isAdmin) { | 			Groups.isMember(uid, gid, function(err, isAdmin) { | ||||||
| 				callback(!!isAdmin); | 				callback( !! isAdmin); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| @@ -769,9 +791,11 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 							RDB.handle(err); | 							RDB.handle(err); | ||||||
| 						} | 						} | ||||||
|  |  | ||||||
| 						if (expiry >= +Date.now()/1000|0) { | 						if (expiry >= +Date.now() / 1000 | 0) { | ||||||
| 							if (!callback) { | 							if (!callback) { | ||||||
| 								socket.emit('user:reset.valid', { valid: true }); | 								socket.emit('user:reset.valid', { | ||||||
|  | 									valid: true | ||||||
|  | 								}); | ||||||
| 							} else { | 							} else { | ||||||
| 								callback(true); | 								callback(true); | ||||||
| 							} | 							} | ||||||
| @@ -780,7 +804,9 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 							RDB.del('reset:' + code + ':uid'); | 							RDB.del('reset:' + code + ':uid'); | ||||||
| 							RDB.del('reset:' + code + ':expiry'); | 							RDB.del('reset:' + code + ':expiry'); | ||||||
| 							if (!callback) { | 							if (!callback) { | ||||||
| 								socket.emit('user:reset.valid', { valid: false }); | 								socket.emit('user:reset.valid', { | ||||||
|  | 									valid: false | ||||||
|  | 								}); | ||||||
| 							} else { | 							} else { | ||||||
| 								callback(false); | 								callback(false); | ||||||
| 							} | 							} | ||||||
| @@ -788,7 +814,9 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 					}); | 					}); | ||||||
| 				} else { | 				} else { | ||||||
| 					if (!callback) { | 					if (!callback) { | ||||||
| 						socket.emit('user:reset.valid', { valid: false }); | 						socket.emit('user:reset.valid', { | ||||||
|  | 							valid: false | ||||||
|  | 						}); | ||||||
| 					} else { | 					} else { | ||||||
| 						callback(false); | 						callback(false); | ||||||
| 					} | 					} | ||||||
| @@ -801,23 +829,25 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 					// Generate a new reset code | 					// Generate a new reset code | ||||||
| 					var reset_code = utils.generateUUID(); | 					var reset_code = utils.generateUUID(); | ||||||
| 					RDB.set('reset:' + reset_code + ':uid', uid); | 					RDB.set('reset:' + reset_code + ':uid', uid); | ||||||
| 					RDB.set('reset:' + reset_code + ':expiry', (60*60)+new Date()/1000|0);	// Active for one hour | 					RDB.set('reset:' + reset_code + ':expiry', (60 * 60) + new Date() / 1000 | 0); // Active for one hour | ||||||
|  |  | ||||||
| 					var reset_link = nconf.get('url') + 'reset/' + reset_code, | 					var reset_link = nconf.get('url') + 'reset/' + reset_code, | ||||||
| 						reset_email = global.templates['emails/reset'].parse({'RESET_LINK': reset_link}), | 						reset_email = global.templates['emails/reset'].parse({ | ||||||
| 						reset_email_plaintext = global.templates['emails/reset_plaintext'].parse({ 'RESET_LINK': reset_link }); | 							'RESET_LINK': reset_link | ||||||
|  | 						}), | ||||||
|  | 						reset_email_plaintext = global.templates['emails/reset_plaintext'].parse({ | ||||||
|  | 							'RESET_LINK': reset_link | ||||||
|  | 						}); | ||||||
|  |  | ||||||
| 					var message = emailjs.message.create({ | 					var message = emailjs.message.create({ | ||||||
| 						text: reset_email_plaintext, | 						text: reset_email_plaintext, | ||||||
| 						from: meta.config.mailer?meta.config.mailer.from:'localhost@example.org', | 						from: meta.config.mailer ? meta.config.mailer.from : 'localhost@example.org', | ||||||
| 						to: email, | 						to: email, | ||||||
| 						subject: 'Password Reset Requested', | 						subject: 'Password Reset Requested', | ||||||
| 						attachment: [ | 						attachment: [{ | ||||||
| 							{ | 							data: reset_email, | ||||||
| 								data: reset_email, | 							alternative: true | ||||||
| 								alternative: true | 						}] | ||||||
| 							} |  | ||||||
| 						] |  | ||||||
| 					}); | 					}); | ||||||
|  |  | ||||||
| 					emailjsServer.send(message, function(err, success) { | 					emailjsServer.send(message, function(err, success) { | ||||||
| @@ -860,7 +890,9 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 						RDB.del('reset:' + code + ':uid'); | 						RDB.del('reset:' + code + ':uid'); | ||||||
| 						RDB.del('reset:' + code + ':expiry'); | 						RDB.del('reset:' + code + ':expiry'); | ||||||
|  |  | ||||||
| 						socket.emit('user:reset.commit', { status: 'ok' }); | 						socket.emit('user:reset.commit', { | ||||||
|  | 							status: 'ok' | ||||||
|  | 						}); | ||||||
| 					}); | 					}); | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
| @@ -870,9 +902,11 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 	User.email = { | 	User.email = { | ||||||
| 		exists: function(socket, email, callback) { | 		exists: function(socket, email, callback) { | ||||||
| 			User.get_uid_by_email(email, function(exists) { | 			User.get_uid_by_email(email, function(exists) { | ||||||
| 				exists = !!exists; | 				exists = !! exists; | ||||||
| 				if (typeof callback !== 'function') { | 				if (typeof callback !== 'function') { | ||||||
| 					socket.emit('user.email.exists', { exists: exists }); | 					socket.emit('user.email.exists', { | ||||||
|  | 						exists: exists | ||||||
|  | 					}); | ||||||
| 				} else { | 				} else { | ||||||
| 					callback(exists); | 					callback(exists); | ||||||
| 				} | 				} | ||||||
| @@ -887,9 +921,13 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 				if (email !== null) { | 				if (email !== null) { | ||||||
| 					RDB.set('email:' + email + ':confirm', true); | 					RDB.set('email:' + email + ':confirm', true); | ||||||
| 					RDB.del('confirm:' + code + ':email'); | 					RDB.del('confirm:' + code + ':email'); | ||||||
| 					callback({ status: 'ok' }); | 					callback({ | ||||||
|  | 						status: 'ok' | ||||||
|  | 					}); | ||||||
| 				} else { | 				} else { | ||||||
| 					callback({ status: 'not_ok' }); | 					callback({ | ||||||
|  | 						status: 'not_ok' | ||||||
|  | 					}); | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
| @@ -897,7 +935,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
|  |  | ||||||
| 	User.notifications = { | 	User.notifications = { | ||||||
| 		get: function(uid, callback) { | 		get: function(uid, callback) { | ||||||
| 			var	maxNotifs = 15; | 			var maxNotifs = 15; | ||||||
|  |  | ||||||
| 			async.parallel({ | 			async.parallel({ | ||||||
| 				unread: function(next) { | 				unread: function(next) { | ||||||
| @@ -946,7 +984,7 @@ var utils = require('./../public/src/utils.js'), | |||||||
| 				} | 				} | ||||||
| 			}, function(err, notifications) { | 			}, function(err, notifications) { | ||||||
| 				// While maintaining score sorting, sort by time | 				// While maintaining score sorting, sort by time | ||||||
| 				var	readCount = notifications.read.length, | 				var readCount = notifications.read.length, | ||||||
| 					unreadCount = notifications.unread.length; | 					unreadCount = notifications.unread.length; | ||||||
|  |  | ||||||
| 				notifications.read.sort(function(a, b) { | 				notifications.read.sort(function(a, b) { | ||||||
|   | |||||||
							
								
								
									
										190
									
								
								src/webserver.js
									
									
									
									
									
								
							
							
						
						
									
										190
									
								
								src/webserver.js
									
									
									
									
									
								
							| @@ -31,12 +31,19 @@ var express = require('express'), | |||||||
| 	 *						accepts:	metaTags | 	 *						accepts:	metaTags | ||||||
| 	 */ | 	 */ | ||||||
| 	app.build_header = function(options, callback) { | 	app.build_header = function(options, callback) { | ||||||
| 		var	defaultMetaTags = [ | 		var defaultMetaTags = [{ | ||||||
| 				{ name: 'viewport', content: 'width=device-width, initial-scale=1.0' }, | 			name: 'viewport', | ||||||
| 				{ name: 'content-type', content: 'text/html; charset=UTF-8' }, | 			content: 'width=device-width, initial-scale=1.0' | ||||||
| 				{ name: 'apple-mobile-web-app-capable', content: 'yes' }, | 		}, { | ||||||
| 				{ property: 'og:site_name', content: meta.config.title || 'NodeBB' }, | 			name: 'content-type', | ||||||
| 			], | 			content: 'text/html; charset=UTF-8' | ||||||
|  | 		}, { | ||||||
|  | 			name: 'apple-mobile-web-app-capable', | ||||||
|  | 			content: 'yes' | ||||||
|  | 		}, { | ||||||
|  | 			property: 'og:site_name', | ||||||
|  | 			content: meta.config.title || 'NodeBB' | ||||||
|  | 		}, ], | ||||||
| 			metaString = utils.buildMetaTags(defaultMetaTags.concat(options.metaTags || [])), | 			metaString = utils.buildMetaTags(defaultMetaTags.concat(options.metaTags || [])), | ||||||
| 			templateValues = { | 			templateValues = { | ||||||
| 				cssSrc: meta.config['theme:src'] || nconf.get('relative_path') + '/vendor/bootstrap/css/bootstrap.min.css', | 				cssSrc: meta.config['theme:src'] || nconf.get('relative_path') + '/vendor/bootstrap/css/bootstrap.min.css', | ||||||
| @@ -58,21 +65,24 @@ var express = require('express'), | |||||||
|  |  | ||||||
| 	// Middlewares | 	// Middlewares | ||||||
| 	app.use(express.favicon(path.join(__dirname, '../', 'public', 'favicon.ico'))); | 	app.use(express.favicon(path.join(__dirname, '../', 'public', 'favicon.ico'))); | ||||||
| 	app.use(require('less-middleware')({ src: path.join(__dirname, '../', 'public'), prefix:nconf.get('relative_path') })); | 	app.use(require('less-middleware')({ | ||||||
|  | 		src: path.join(__dirname, '../', 'public'), | ||||||
|  | 		prefix: nconf.get('relative_path') | ||||||
|  | 	})); | ||||||
| 	app.use(nconf.get('relative_path'), express.static(path.join(__dirname, '../', 'public'))); | 	app.use(nconf.get('relative_path'), express.static(path.join(__dirname, '../', 'public'))); | ||||||
| 	app.use(express.bodyParser());	// Puts POST vars in request.body | 	app.use(express.bodyParser()); // Puts POST vars in request.body | ||||||
|  |  | ||||||
| 	app.use(express.cookieParser());	// If you want to parse cookies (res.cookies) | 	app.use(express.cookieParser()); // If you want to parse cookies (res.cookies) | ||||||
| 	app.use(express.compress()); | 	app.use(express.compress()); | ||||||
| 	app.use(express.session({ | 	app.use(express.session({ | ||||||
| 		store: new RedisStore({ | 		store: new RedisStore({ | ||||||
| 			client: RDB, | 			client: RDB, | ||||||
| 			ttl: 60*60*24*30 | 			ttl: 60 * 60 * 24 * 30 | ||||||
| 		}), | 		}), | ||||||
| 		secret: nconf.get('secret'), | 		secret: nconf.get('secret'), | ||||||
| 		key: 'express.sid', | 		key: 'express.sid', | ||||||
| 		cookie: { | 		cookie: { | ||||||
| 			maxAge: 60*60*24*30*1000	// 30 days | 			maxAge: 60 * 60 * 24 * 30 * 1000 // 30 days | ||||||
| 		} | 		} | ||||||
| 	})); | 	})); | ||||||
| 	app.use(express.csrf()); | 	app.use(express.csrf()); | ||||||
| @@ -83,7 +93,7 @@ var express = require('express'), | |||||||
|  |  | ||||||
| 	// Static Directories for NodeBB Plugins | 	// Static Directories for NodeBB Plugins | ||||||
| 	app.configure(function() { | 	app.configure(function() { | ||||||
| 		var	tailMiddlewares = []; | 		var tailMiddlewares = []; | ||||||
|  |  | ||||||
| 		plugins.ready(function() { | 		plugins.ready(function() { | ||||||
| 			// Remove some middlewares until the router is gone | 			// Remove some middlewares until the router is gone | ||||||
| @@ -92,7 +102,7 @@ var express = require('express'), | |||||||
| 			tailMiddlewares.push(app.stack.pop()); | 			tailMiddlewares.push(app.stack.pop()); | ||||||
| 			tailMiddlewares.push(app.stack.pop()); | 			tailMiddlewares.push(app.stack.pop()); | ||||||
| 			tailMiddlewares.push(app.stack.pop()); | 			tailMiddlewares.push(app.stack.pop()); | ||||||
| 			for(d in plugins.staticDirs) { | 			for (d in plugins.staticDirs) { | ||||||
| 				app.use(nconf.get('relative_path') + '/plugins/' + d, express.static(plugins.staticDirs[d])); | 				app.use(nconf.get('relative_path') + '/plugins/' + d, express.static(plugins.staticDirs[d])); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -138,7 +148,9 @@ var express = require('express'), | |||||||
|  |  | ||||||
| 		// respond with json | 		// respond with json | ||||||
| 		if (req.accepts('json')) { | 		if (req.accepts('json')) { | ||||||
| 			res.send({ error: 'Not found' }); | 			res.send({ | ||||||
|  | 				error: 'Not found' | ||||||
|  | 			}); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -155,7 +167,9 @@ var express = require('express'), | |||||||
|  |  | ||||||
| 		res.status(err.status || 500); | 		res.status(err.status || 500); | ||||||
|  |  | ||||||
| 		res.json('500', { error: err.message }); | 		res.json('500', { | ||||||
|  | 			error: err.message | ||||||
|  | 		}); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -177,19 +191,22 @@ var express = require('express'), | |||||||
| 		(function() { | 		(function() { | ||||||
| 			var routes = ['login', 'register', 'account', 'recent', 'unread', 'popular', 'active', '403', '404']; | 			var routes = ['login', 'register', 'account', 'recent', 'unread', 'popular', 'active', '403', '404']; | ||||||
|  |  | ||||||
| 			for (var i=0, ii=routes.length; i<ii; i++) { | 			for (var i = 0, ii = routes.length; i < ii; i++) { | ||||||
| 				(function(route) { | 				(function(route) { | ||||||
|  |  | ||||||
| 					app.get('/' + route, function(req, res) { | 					app.get('/' + route, function(req, res) { | ||||||
| 						if ((route === 'login' || route ==='register') && (req.user && req.user.uid > 0)) { | 						if ((route === 'login' || route === 'register') && (req.user && req.user.uid > 0)) { | ||||||
|  |  | ||||||
| 							user.getUserField(req.user.uid, 'userslug', function(err, userslug) { | 							user.getUserField(req.user.uid, 'userslug', function(err, userslug) { | ||||||
| 								res.redirect('/users/'+userslug); | 								res.redirect('/users/' + userslug); | ||||||
| 							}); | 							}); | ||||||
| 							return; | 							return; | ||||||
| 						} | 						} | ||||||
|  |  | ||||||
| 						app.build_header({ req: req, res: res }, function(err, header) { | 						app.build_header({ | ||||||
|  | 							req: req, | ||||||
|  | 							res: res | ||||||
|  | 						}, function(err, header) { | ||||||
| 							res.send(header + app.create_route(route) + templates['footer']); | 							res.send(header + app.create_route(route) + templates['footer']); | ||||||
| 						}); | 						}); | ||||||
| 					}); | 					}); | ||||||
| @@ -204,12 +221,19 @@ var express = require('express'), | |||||||
| 					app.build_header({ | 					app.build_header({ | ||||||
| 						req: req, | 						req: req, | ||||||
| 						res: res, | 						res: res, | ||||||
| 						metaTags: [ | 						metaTags: [{ | ||||||
| 							{ name: "title", content: meta.config.title || 'NodeBB' }, | 							name: "title", | ||||||
| 							{ name: "description", content: meta.config.description || '' }, | 							content: meta.config.title || 'NodeBB' | ||||||
| 							{ property: 'og:title', content: 'Index | ' + (meta.config.title || 'NodeBB') }, | 						}, { | ||||||
| 							{ property: "og:type", content: 'website' } | 							name: "description", | ||||||
| 						] | 							content: meta.config.description || '' | ||||||
|  | 						}, { | ||||||
|  | 							property: 'og:title', | ||||||
|  | 							content: 'Index | ' + (meta.config.title || 'NodeBB') | ||||||
|  | 						}, { | ||||||
|  | 							property: "og:type", | ||||||
|  | 							content: 'website' | ||||||
|  | 						}] | ||||||
| 					}, next); | 					}, next); | ||||||
| 				}, | 				}, | ||||||
| 				"categories": function(next) { | 				"categories": function(next) { | ||||||
| @@ -233,9 +257,9 @@ var express = require('express'), | |||||||
|  |  | ||||||
| 			if (tid.match(/^\d+\.rss$/)) { | 			if (tid.match(/^\d+\.rss$/)) { | ||||||
| 				tid = tid.slice(0, -4); | 				tid = tid.slice(0, -4); | ||||||
| 				var	rssPath = path.join(__dirname, '../', 'feeds/topics', tid + '.rss'), | 				var rssPath = path.join(__dirname, '../', 'feeds/topics', tid + '.rss'), | ||||||
| 					loadFeed = function() { | 					loadFeed = function() { | ||||||
| 						fs.readFile(rssPath, function (err, data) { | 						fs.readFile(rssPath, function(err, data) { | ||||||
| 							if (err) res.type('text').send(404, "Unable to locate an rss feed at this location."); | 							if (err) res.type('text').send(404, "Unable to locate an rss feed at this location."); | ||||||
| 							else res.type('xml').set('Content-Length', data.length).send(data); | 							else res.type('xml').set('Content-Length', data.length).send(data); | ||||||
| 						}); | 						}); | ||||||
| @@ -255,8 +279,8 @@ var express = require('express'), | |||||||
| 			async.waterfall([ | 			async.waterfall([ | ||||||
| 				function(next) { | 				function(next) { | ||||||
| 					topics.getTopicWithPosts(tid, ((req.user) ? req.user.uid : 0), 0, -1, function(err, topicData) { | 					topics.getTopicWithPosts(tid, ((req.user) ? req.user.uid : 0), 0, -1, function(err, topicData) { | ||||||
| 						if(topicData) { | 						if (topicData) { | ||||||
| 							if(topicData.deleted === '1' && topicData.expose_tools === 0) | 							if (topicData.deleted === '1' && topicData.expose_tools === 0) | ||||||
| 								return next(new Error('Topic deleted'), null); | 								return next(new Error('Topic deleted'), null); | ||||||
| 						} | 						} | ||||||
|  |  | ||||||
| @@ -267,7 +291,7 @@ var express = require('express'), | |||||||
| 					var lastMod = 0, | 					var lastMod = 0, | ||||||
| 						timestamp; | 						timestamp; | ||||||
|  |  | ||||||
| 					for(var x=0,numPosts=topicData.posts.length;x<numPosts;x++) { | 					for (var x = 0, numPosts = topicData.posts.length; x < numPosts; x++) { | ||||||
| 						timestamp = parseInt(topicData.posts[x].timestamp, 10); | 						timestamp = parseInt(topicData.posts[x].timestamp, 10); | ||||||
| 						if (timestamp > lastMod) lastMod = timestamp; | 						if (timestamp > lastMod) lastMod = timestamp; | ||||||
| 					} | 					} | ||||||
| @@ -275,16 +299,31 @@ var express = require('express'), | |||||||
| 					app.build_header({ | 					app.build_header({ | ||||||
| 						req: req, | 						req: req, | ||||||
| 						res: res, | 						res: res, | ||||||
| 						metaTags: [ | 						metaTags: [{ | ||||||
| 							{ name: "title", content: topicData.topic_name }, | 							name: "title", | ||||||
| 							{ property: 'og:title', content: topicData.topic_name + ' | ' + (meta.config.title || 'NodeBB') }, | 							content: topicData.topic_name | ||||||
| 							{ property: "og:type", content: 'article' }, | 						}, { | ||||||
| 							{ property: "og:url", content: nconf.get('url') + 'topic/' + topicData.slug }, | 							property: 'og:title', | ||||||
| 							{ property: 'og:image', content: topicData.main_posts[0].picture }, | 							content: topicData.topic_name + ' | ' + (meta.config.title || 'NodeBB') | ||||||
| 							{ property: "article:published_time", content: new Date(parseInt(topicData.main_posts[0].timestamp, 10)).toISOString() }, | 						}, { | ||||||
| 							{ property: 'article:modified_time', content: new Date(lastMod).toISOString() }, | 							property: "og:type", | ||||||
| 							{ property: 'article:section', content: topicData.category_name } | 							content: 'article' | ||||||
| 						] | 						}, { | ||||||
|  | 							property: "og:url", | ||||||
|  | 							content: nconf.get('url') + 'topic/' + topicData.slug | ||||||
|  | 						}, { | ||||||
|  | 							property: 'og:image', | ||||||
|  | 							content: topicData.main_posts[0].picture | ||||||
|  | 						}, { | ||||||
|  | 							property: "article:published_time", | ||||||
|  | 							content: new Date(parseInt(topicData.main_posts[0].timestamp, 10)).toISOString() | ||||||
|  | 						}, { | ||||||
|  | 							property: 'article:modified_time', | ||||||
|  | 							content: new Date(lastMod).toISOString() | ||||||
|  | 						}, { | ||||||
|  | 							property: 'article:section', | ||||||
|  | 							content: topicData.category_name | ||||||
|  | 						}] | ||||||
| 					}, function(err, header) { | 					}, function(err, header) { | ||||||
| 						next(err, { | 						next(err, { | ||||||
| 							header: header, | 							header: header, | ||||||
| @@ -310,9 +349,9 @@ var express = require('express'), | |||||||
|  |  | ||||||
| 			if (cid.match(/^\d+\.rss$/)) { | 			if (cid.match(/^\d+\.rss$/)) { | ||||||
| 				cid = cid.slice(0, -4); | 				cid = cid.slice(0, -4); | ||||||
| 				var	rssPath = path.join(__dirname, '../', 'feeds/categories', cid + '.rss'), | 				var rssPath = path.join(__dirname, '../', 'feeds/categories', cid + '.rss'), | ||||||
| 					loadFeed = function() { | 					loadFeed = function() { | ||||||
| 						fs.readFile(rssPath, function (err, data) { | 						fs.readFile(rssPath, function(err, data) { | ||||||
| 							if (err) res.type('text').send(404, "Unable to locate an rss feed at this location."); | 							if (err) res.type('text').send(404, "Unable to locate an rss feed at this location."); | ||||||
| 							else res.type('xml').set('Content-Length', data.length).send(data); | 							else res.type('xml').set('Content-Length', data.length).send(data); | ||||||
| 						}); | 						}); | ||||||
| @@ -333,8 +372,8 @@ var express = require('express'), | |||||||
| 				function(next) { | 				function(next) { | ||||||
| 					categories.getCategoryById(cid, 0, function(err, categoryData) { | 					categories.getCategoryById(cid, 0, function(err, categoryData) { | ||||||
|  |  | ||||||
| 						if(categoryData) { | 						if (categoryData) { | ||||||
| 							if(categoryData.disabled === '1') | 							if (categoryData.disabled === '1') | ||||||
| 								return next(new Error('Category disabled'), null); | 								return next(new Error('Category disabled'), null); | ||||||
| 						} | 						} | ||||||
| 						next(err, categoryData); | 						next(err, categoryData); | ||||||
| @@ -344,11 +383,16 @@ var express = require('express'), | |||||||
| 					app.build_header({ | 					app.build_header({ | ||||||
| 						req: req, | 						req: req, | ||||||
| 						res: res, | 						res: res, | ||||||
| 						metaTags: [ | 						metaTags: [{ | ||||||
| 							{ name: 'title', content: categoryData.category_name }, | 							name: 'title', | ||||||
| 							{ name: 'description', content: categoryData.category_description }, | 							content: categoryData.category_name | ||||||
| 							{ property: "og:type", content: 'website' } | 						}, { | ||||||
| 						] | 							name: 'description', | ||||||
|  | 							content: categoryData.category_description | ||||||
|  | 						}, { | ||||||
|  | 							property: "og:type", | ||||||
|  | 							content: 'website' | ||||||
|  | 						}] | ||||||
| 					}, function(err, header) { | 					}, function(err, header) { | ||||||
| 						next(err, { | 						next(err, { | ||||||
| 							header: header, | 							header: header, | ||||||
| @@ -357,7 +401,7 @@ var express = require('express'), | |||||||
| 					}); | 					}); | ||||||
| 				} | 				} | ||||||
| 			], function(err, data) { | 			], function(err, data) { | ||||||
| 				if(err) return res.redirect('404'); | 				if (err) return res.redirect('404'); | ||||||
| 				var category_url = cid + (req.params.slug ? '/' + req.params.slug : ''); | 				var category_url = cid + (req.params.slug ? '/' + req.params.slug : ''); | ||||||
|  |  | ||||||
| 				res.send( | 				res.send( | ||||||
| @@ -370,13 +414,16 @@ var express = require('express'), | |||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/confirm/:code', function(req, res) { | 		app.get('/confirm/:code', function(req, res) { | ||||||
| 			app.build_header({ req: req, res: res }, function(err, header) { | 			app.build_header({ | ||||||
|  | 				req: req, | ||||||
|  | 				res: res | ||||||
|  | 			}, function(err, header) { | ||||||
| 				res.send(header + '<script>templates.ready(function(){ajaxify.go("confirm/' + req.params.code + '");});</script>' + templates['footer']); | 				res.send(header + '<script>templates.ready(function(){ajaxify.go("confirm/' + req.params.code + '");});</script>' + templates['footer']); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/sitemap.xml', function(req, res) { | 		app.get('/sitemap.xml', function(req, res) { | ||||||
| 			var	sitemap = require('./sitemap.js'); | 			var sitemap = require('./sitemap.js'); | ||||||
|  |  | ||||||
| 			sitemap.render(function(xml) { | 			sitemap.render(function(xml) { | ||||||
| 				res.type('xml').set('Content-Length', xml.length).send(xml); | 				res.type('xml').set('Content-Length', xml.length).send(xml); | ||||||
| @@ -385,15 +432,15 @@ var express = require('express'), | |||||||
|  |  | ||||||
| 		app.get('/robots.txt', function(req, res) { | 		app.get('/robots.txt', function(req, res) { | ||||||
| 			res.set('Content-Type', 'text/plain'); | 			res.set('Content-Type', 'text/plain'); | ||||||
| 			res.send(	"User-agent: *\n" + | 			res.send("User-agent: *\n" + | ||||||
| 						"Disallow: \n" + | 				"Disallow: \n" + | ||||||
| 						"Disallow: /admin/\n" + | 				"Disallow: /admin/\n" + | ||||||
| 						"Sitemap: " + nconf.get('url') + "sitemap.xml"); | 				"Sitemap: " + nconf.get('url') + "sitemap.xml"); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/cid/:cid', function(req, res) { | 		app.get('/cid/:cid', function(req, res) { | ||||||
| 			categories.getCategoryData(req.params.cid, function(err, data) { | 			categories.getCategoryData(req.params.cid, function(err, data) { | ||||||
| 				if(data) | 				if (data) | ||||||
| 					res.send(data); | 					res.send(data); | ||||||
| 				else | 				else | ||||||
| 					res.send(404, "Category doesn't exist!"); | 					res.send(404, "Category doesn't exist!"); | ||||||
| @@ -401,8 +448,8 @@ var express = require('express'), | |||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/tid/:tid', function(req, res) { | 		app.get('/tid/:tid', function(req, res) { | ||||||
| 			topics.getTopicData(req.params.tid, function(data){ | 			topics.getTopicData(req.params.tid, function(data) { | ||||||
| 				if(data) | 				if (data) | ||||||
| 					res.send(data); | 					res.send(data); | ||||||
| 				else | 				else | ||||||
| 					res.send(404, "Topic doesn't exist!"); | 					res.send(404, "Topic doesn't exist!"); | ||||||
| @@ -410,8 +457,8 @@ var express = require('express'), | |||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/pid/:pid', function(req, res) { | 		app.get('/pid/:pid', function(req, res) { | ||||||
| 			posts.getPostData(req.params.pid, function(data){ | 			posts.getPostData(req.params.pid, function(data) { | ||||||
| 				if(data) | 				if (data) | ||||||
| 					res.send(data); | 					res.send(data); | ||||||
| 				else | 				else | ||||||
| 					res.send(404, "Post doesn't exist!"); | 					res.send(404, "Post doesn't exist!"); | ||||||
| @@ -421,7 +468,10 @@ var express = require('express'), | |||||||
| 		app.get('/outgoing', function(req, res) { | 		app.get('/outgoing', function(req, res) { | ||||||
| 			if (!req.query.url) return res.redirect('/404'); | 			if (!req.query.url) return res.redirect('/404'); | ||||||
|  |  | ||||||
| 			app.build_header({ req: req, res: res }, function(err, header) { | 			app.build_header({ | ||||||
|  | 				req: req, | ||||||
|  | 				res: res | ||||||
|  | 			}, function(err, header) { | ||||||
| 				res.send( | 				res.send( | ||||||
| 					header + | 					header + | ||||||
| 					'\n\t<script>templates.ready(function(){ajaxify.go("outgoing?url=' + encodeURIComponent(req.query.url) + '", null, null, true);});</script>' + | 					'\n\t<script>templates.ready(function(){ajaxify.go("outgoing?url=' + encodeURIComponent(req.query.url) + '", null, null, true);});</script>' + | ||||||
| @@ -431,25 +481,31 @@ var express = require('express'), | |||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/search', function(req, res) { | 		app.get('/search', function(req, res) { | ||||||
| 			app.build_header({ req: req, res: res }, function(err, header) { | 			app.build_header({ | ||||||
|  | 				req: req, | ||||||
|  | 				res: res | ||||||
|  | 			}, function(err, header) { | ||||||
| 				res.send(header + app.create_route("search", null, "search") + templates['footer']); | 				res.send(header + app.create_route("search", null, "search") + templates['footer']); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/search/:term', function(req, res) { | 		app.get('/search/:term', function(req, res) { | ||||||
| 			app.build_header({ req: req, res: res }, function(err, header) { | 			app.build_header({ | ||||||
| 				res.send(header + app.create_route("search/"+req.params.term, null, "search") + templates['footer']); | 				req: req, | ||||||
|  | 				res: res | ||||||
|  | 			}, function(err, header) { | ||||||
|  | 				res.send(header + app.create_route("search/" + req.params.term, null, "search") + templates['footer']); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		app.get('/reindex', function(req, res) { | 		app.get('/reindex', function(req, res) { | ||||||
| 			topics.reIndexAll(function(err) { | 			topics.reIndexAll(function(err) { | ||||||
| 				if(err) { | 				if (err) { | ||||||
| 					return res.json(err); | 					return res.json(err); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				user.reIndexAll(function(err) { | 				user.reIndexAll(function(err) { | ||||||
| 					if(err) { | 					if (err) { | ||||||
| 						return res.json(err); | 						return res.json(err); | ||||||
| 					} else { | 					} else { | ||||||
| 						res.send('Topics and users reindexed'); | 						res.send('Topics and users reindexed'); | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
|  |  | ||||||
| var SocketIO = require('socket.io').listen(global.server, { | var SocketIO = require('socket.io').listen(global.server, { | ||||||
| 		log: false, | 	log: false, | ||||||
| 		transports: ['websocket', 'xhr-polling', 'jsonp-polling', 'flashsocket'] | 	transports: ['websocket', 'xhr-polling', 'jsonp-polling', 'flashsocket'] | ||||||
| 	}), | }), | ||||||
| 	cookie = require('cookie'), | 	cookie = require('cookie'), | ||||||
| 	express = require('express'), | 	express = require('express'), | ||||||
| 	user = require('./user.js'), | 	user = require('./user.js'), | ||||||
| @@ -22,7 +21,7 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 	RDB = require('./redis'), | 	RDB = require('./redis'), | ||||||
| 	RedisStore = new RedisStoreLib({ | 	RedisStore = new RedisStoreLib({ | ||||||
| 		client: RDB, | 		client: RDB, | ||||||
| 		ttl: 60*60*24*14 | 		ttl: 60 * 60 * 24 * 14 | ||||||
| 	}), | 	}), | ||||||
| 	socketCookieParser = express.cookieParser(nconf.get('secret')), | 	socketCookieParser = express.cookieParser(nconf.get('secret')), | ||||||
| 	admin = { | 	admin = { | ||||||
| @@ -40,7 +39,7 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 	global.io = io; | 	global.io = io; | ||||||
|  |  | ||||||
| 	io.sockets.on('connection', function(socket) { | 	io.sockets.on('connection', function(socket) { | ||||||
| 		var	hs = socket.handshake, | 		var hs = socket.handshake, | ||||||
| 			sessionID, uid; | 			sessionID, uid; | ||||||
|  |  | ||||||
| 		// Validate the session, if present | 		// Validate the session, if present | ||||||
| @@ -53,12 +52,16 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 				userSockets[uid] = userSockets[uid] || []; | 				userSockets[uid] = userSockets[uid] || []; | ||||||
| 				userSockets[uid].push(socket); | 				userSockets[uid].push(socket); | ||||||
|  |  | ||||||
| 				if(uid) { | 				if (uid) { | ||||||
| 					socket.join('uid_' + uid); | 					socket.join('uid_' + uid); | ||||||
| 					io.sockets.in('global').emit('api:user.isOnline', isUserOnline(uid)); | 					io.sockets. in ('global').emit('api:user.isOnline', isUserOnline(uid)); | ||||||
|  |  | ||||||
| 					user.getUserField(uid, 'username', function(err, username) { | 					user.getUserField(uid, 'username', function(err, username) { | ||||||
| 						socket.emit('event:connect', {status: 1, username:username, uid:uid}); | 						socket.emit('event:connect', { | ||||||
|  | 							status: 1, | ||||||
|  | 							username: username, | ||||||
|  | 							uid: uid | ||||||
|  | 						}); | ||||||
| 					}); | 					}); | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
| @@ -69,25 +72,25 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 		socket.on('disconnect', function() { | 		socket.on('disconnect', function() { | ||||||
|  |  | ||||||
| 			var index = userSockets[uid].indexOf(socket); | 			var index = userSockets[uid].indexOf(socket); | ||||||
| 			if(index !== -1) { | 			if (index !== -1) { | ||||||
| 				userSockets[uid].splice(index, 1); | 				userSockets[uid].splice(index, 1); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if(userSockets[uid].length === 0) { | 			if (userSockets[uid].length === 0) { | ||||||
| 				delete users[sessionID]; | 				delete users[sessionID]; | ||||||
| 				delete userSockets[uid]; | 				delete userSockets[uid]; | ||||||
| 				if(uid) { | 				if (uid) { | ||||||
| 					io.sockets.in('global').emit('api:user.isOnline', isUserOnline(uid)); | 					io.sockets. in ('global').emit('api:user.isOnline', isUserOnline(uid)); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			emitOnlineUserCount(); | 			emitOnlineUserCount(); | ||||||
|  |  | ||||||
| 			for(var roomName in rooms) { | 			for (var roomName in rooms) { | ||||||
|  |  | ||||||
| 				socket.leave(roomName); | 				socket.leave(roomName); | ||||||
|  |  | ||||||
| 				if(rooms[roomName][socket.id]) { | 				if (rooms[roomName][socket.id]) { | ||||||
| 					delete rooms[roomName][socket.id]; | 					delete rooms[roomName][socket.id]; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| @@ -103,8 +106,8 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
|  |  | ||||||
| 			function getUidsInRoom(room) { | 			function getUidsInRoom(room) { | ||||||
| 				var uids = []; | 				var uids = []; | ||||||
| 				for(var socketId in room) { | 				for (var socketId in room) { | ||||||
| 					if(uids.indexOf(room[socketId]) === -1) | 					if (uids.indexOf(room[socketId]) === -1) | ||||||
| 						uids.push(room[socketId]); | 						uids.push(room[socketId]); | ||||||
| 				} | 				} | ||||||
| 				return uids; | 				return uids; | ||||||
| @@ -114,10 +117,10 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 				var clients = io.sockets.clients(roomName); | 				var clients = io.sockets.clients(roomName); | ||||||
| 				var anonCount = 0; | 				var anonCount = 0; | ||||||
|  |  | ||||||
| 				for(var i=0; i<clients.length; ++i) { | 				for (var i = 0; i < clients.length; ++i) { | ||||||
| 					var hs = clients[i].handshake; | 					var hs = clients[i].handshake; | ||||||
|  |  | ||||||
| 					if(hs && !users[sessionID]) { | 					if (hs && !users[sessionID]) { | ||||||
| 						++anonCount; | 						++anonCount; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| @@ -131,24 +134,24 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 			function userList(users, anonymousCount, userCount) { | 			function userList(users, anonymousCount, userCount) { | ||||||
| 				var usernames = []; | 				var usernames = []; | ||||||
|  |  | ||||||
| 				for (var i = 0, ii=users.length; i<ii; ++i) { | 				for (var i = 0, ii = users.length; i < ii; ++i) { | ||||||
| 					usernames[i] = '<strong>' + '<a href="/users/'+users[i].userslug+'">' + users[i].username + '</a></strong>'; | 					usernames[i] = '<strong>' + '<a href="/users/' + users[i].userslug + '">' + users[i].username + '</a></strong>'; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				var joiner = anonymousCount + userCount == 1 ? 'is' : 'are', | 				var joiner = anonymousCount + userCount == 1 ? 'is' : 'are', | ||||||
| 				userList = anonymousCount > 0 ? usernames.concat(util.format('%d guest%s', anonymousCount, anonymousCount > 1 ? 's' : '')) : usernames, | 					userList = anonymousCount > 0 ? usernames.concat(util.format('%d guest%s', anonymousCount, anonymousCount > 1 ? 's' : '')) : usernames, | ||||||
| 				lastUser = userList.length > 1 ? ' and ' + userList.pop() : ''; | 					lastUser = userList.length > 1 ? ' and ' + userList.pop() : ''; | ||||||
|  |  | ||||||
| 				return util.format('%s%s %s browsing this thread', userList.join(', '), lastUser, joiner); | 				return util.format('%s%s %s browsing this thread', userList.join(', '), lastUser, joiner); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  |  | ||||||
| 			if (uids.length === 0) { | 			if (uids.length === 0) { | ||||||
| 				io.sockets.in(roomName).emit('api:get_users_in_room', userList([], anonymousCount, 0)); | 				io.sockets. in (roomName).emit('api:get_users_in_room', userList([], anonymousCount, 0)); | ||||||
| 			} else { | 			} else { | ||||||
| 				user.getMultipleUserFields(uids, ['username', 'userslug'], function(err, users) { | 				user.getMultipleUserFields(uids, ['username', 'userslug'], function(err, users) { | ||||||
| 					if(!err) | 					if (!err) | ||||||
| 						io.sockets.in(roomName).emit('api:get_users_in_room', userList(users, anonymousCount, users.length)); | 						io.sockets. in (roomName).emit('api:get_users_in_room', userList(users, anonymousCount, users.length)); | ||||||
| 				}); | 				}); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @@ -171,42 +174,45 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if(data.leave) | 			if (data.leave) | ||||||
| 				updateRoomBrowsingText(data.leave); | 				updateRoomBrowsingText(data.leave); | ||||||
|  |  | ||||||
| 			updateRoomBrowsingText(data.enter); | 			updateRoomBrowsingText(data.enter); | ||||||
|  |  | ||||||
| 			if (data.enter != 'admin') | 			if (data.enter != 'admin') | ||||||
| 				io.sockets.in('admin').emit('api:get_all_rooms', io.sockets.manager.rooms); | 				io.sockets. in ('admin').emit('api:get_all_rooms', io.sockets.manager.rooms); | ||||||
|  |  | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		// BEGIN: API calls (todo: organize) | 		// BEGIN: API calls (todo: organize) | ||||||
|  |  | ||||||
| 		socket.on('api:updateHeader', function(data) { | 		socket.on('api:updateHeader', function(data) { | ||||||
| 			if(uid) { | 			if (uid) { | ||||||
| 				user.getUserFields(uid, data.fields, function(err, fields) { | 				user.getUserFields(uid, data.fields, function(err, fields) { | ||||||
| 					if(!err && fields) { | 					if (!err && fields) { | ||||||
| 						fields.uid = uid; | 						fields.uid = uid; | ||||||
| 						socket.emit('api:updateHeader', fields); | 						socket.emit('api:updateHeader', fields); | ||||||
| 					} | 					} | ||||||
| 				}); | 				}); | ||||||
| 			} | 			} else { | ||||||
| 			else { |  | ||||||
| 				socket.emit('api:updateHeader', { | 				socket.emit('api:updateHeader', { | ||||||
| 					uid:0, | 					uid: 0, | ||||||
| 					username: "Anonymous User", | 					username: "Anonymous User", | ||||||
| 					email: '', | 					email: '', | ||||||
| 					picture: require('gravatar').url('', {s:'24'}, https=nconf.get('https')) | 					picture: require('gravatar').url('', { | ||||||
|  | 						s: '24' | ||||||
|  | 					}, https = nconf.get('https')) | ||||||
| 				}); | 				}); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('user.exists', function(data) { | 		socket.on('user.exists', function(data) { | ||||||
| 			if(data.username) { | 			if (data.username) { | ||||||
| 				user.exists(utils.slugify(data.username), function(exists){ | 				user.exists(utils.slugify(data.username), function(exists) { | ||||||
| 					socket.emit('user.exists', {exists: exists}); | 					socket.emit('user.exists', { | ||||||
|  | 						exists: exists | ||||||
|  | 					}); | ||||||
| 				}); | 				}); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| @@ -246,9 +252,9 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 		socket.on('api:user.get_online_users', function(data) { | 		socket.on('api:user.get_online_users', function(data) { | ||||||
| 			var returnData = []; | 			var returnData = []; | ||||||
|  |  | ||||||
| 			for(var i=0; i<data.length; ++i) { | 			for (var i = 0; i < data.length; ++i) { | ||||||
| 				var uid = data[i]; | 				var uid = data[i]; | ||||||
| 				if(isUserOnline(uid)) | 				if (isUserOnline(uid)) | ||||||
| 					returnData.push(uid); | 					returnData.push(uid); | ||||||
| 				else | 				else | ||||||
| 					returnData.push(0); | 					returnData.push(0); | ||||||
| @@ -257,7 +263,10 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('api:user.isOnline', function(uid, callback) { | 		socket.on('api:user.isOnline', function(uid, callback) { | ||||||
| 			callback({online:isUserOnline(uid), timestamp:Date.now()}); | 			callback({ | ||||||
|  | 				online: isUserOnline(uid), | ||||||
|  | 				timestamp: Date.now() | ||||||
|  | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('api:user.changePassword', function(data, callback) { | 		socket.on('api:user.changePassword', function(data, callback) { | ||||||
| @@ -274,7 +283,7 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
|  |  | ||||||
| 			function updateHeader() { | 			function updateHeader() { | ||||||
| 				user.getUserFields(uid, ['picture'], function(err, fields) { | 				user.getUserFields(uid, ['picture'], function(err, fields) { | ||||||
| 					if(!err && fields) { | 					if (!err && fields) { | ||||||
| 						fields.uid = uid; | 						fields.uid = uid; | ||||||
| 						socket.emit('api:updateHeader', fields); | 						socket.emit('api:updateHeader', fields); | ||||||
| 						callback(true); | 						callback(true); | ||||||
| @@ -284,12 +293,12 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 				}); | 				}); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if(type === 'gravatar') { | 			if (type === 'gravatar') { | ||||||
| 				user.getUserField(uid, 'gravatarpicture', function(err, gravatar) { | 				user.getUserField(uid, 'gravatarpicture', function(err, gravatar) { | ||||||
| 					user.setUserField(uid, 'picture', gravatar); | 					user.setUserField(uid, 'picture', gravatar); | ||||||
| 					updateHeader(); | 					updateHeader(); | ||||||
| 				}); | 				}); | ||||||
| 			} else if(type === 'uploaded') { | 			} else if (type === 'uploaded') { | ||||||
| 				user.getUserField(uid, 'uploadedpicture', function(err, uploadedpicture) { | 				user.getUserField(uid, 'uploadedpicture', function(err, uploadedpicture) { | ||||||
| 					user.setUserField(uid, 'picture', uploadedpicture); | 					user.setUserField(uid, 'picture', uploadedpicture); | ||||||
| 					updateHeader(); | 					updateHeader(); | ||||||
| @@ -300,21 +309,21 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('api:user.follow', function(data, callback) { | 		socket.on('api:user.follow', function(data, callback) { | ||||||
| 			if(uid) { | 			if (uid) { | ||||||
| 				user.follow(uid, data.uid, callback); | 				user.follow(uid, data.uid, callback); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('api:user.unfollow', function(data, callback) { | 		socket.on('api:user.unfollow', function(data, callback) { | ||||||
| 			if(uid) { | 			if (uid) { | ||||||
| 				user.unfollow(uid, data.uid, callback); | 				user.unfollow(uid, data.uid, callback); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('api:user.saveSettings', function(data, callback) { | 		socket.on('api:user.saveSettings', function(data, callback) { | ||||||
| 			if(uid) { | 			if (uid) { | ||||||
| 				user.setUserFields(uid, { | 				user.setUserFields(uid, { | ||||||
| 					showemail:data.showemail | 					showemail: data.showemail | ||||||
| 				}); | 				}); | ||||||
| 				callback(true); | 				callback(true); | ||||||
| 			} | 			} | ||||||
| @@ -334,9 +343,9 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 								ajaxify.go('register'); | 								ajaxify.go('register'); | ||||||
| 							} | 							} | ||||||
| 						}); | 						}); | ||||||
| 					} else if(err.message === 'title-too-short') { | 					} else if (err.message === 'title-too-short') { | ||||||
| 						topics.emitTitleTooShortAlert(socket); | 						topics.emitTitleTooShortAlert(socket); | ||||||
| 					} else if(err.message === 'content-too-short') { | 					} else if (err.message === 'content-too-short') { | ||||||
| 						posts.emitContentTooShortAlert(socket); | 						posts.emitContentTooShortAlert(socket); | ||||||
| 					} else if (err.message === 'too-many-posts') { | 					} else if (err.message === 'too-many-posts') { | ||||||
| 						posts.emitTooManyPostsAlert(socket); | 						posts.emitTooManyPostsAlert(socket); | ||||||
| @@ -344,7 +353,7 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				if(result) { | 				if (result) { | ||||||
| 					posts.getTopicPostStats(socket); | 					posts.getTopicPostStats(socket); | ||||||
|  |  | ||||||
| 					socket.emit('event:alert', { | 					socket.emit('event:alert', { | ||||||
| @@ -360,7 +369,7 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
|  |  | ||||||
| 		socket.on('api:topics.markAllRead', function(data, callback) { | 		socket.on('api:topics.markAllRead', function(data, callback) { | ||||||
| 			topics.markAllRead(uid, function(err, success) { | 			topics.markAllRead(uid, function(err, success) { | ||||||
| 				if(!err && success)	{ | 				if (!err && success) { | ||||||
| 					callback(true); | 					callback(true); | ||||||
| 				} else { | 				} else { | ||||||
| 					callback(false); | 					callback(false); | ||||||
| @@ -369,7 +378,7 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('api:posts.reply', function(data) { | 		socket.on('api:posts.reply', function(data) { | ||||||
| 			if(uid < 1) { | 			if (uid < 1) { | ||||||
| 				socket.emit('event:alert', { | 				socket.emit('event:alert', { | ||||||
| 					title: 'Reply Unsuccessful', | 					title: 'Reply Unsuccessful', | ||||||
| 					message: 'You don't seem to be logged in, so you cannot reply.', | 					message: 'You don't seem to be logged in, so you cannot reply.', | ||||||
| @@ -383,9 +392,9 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 				if(err) { | 				if(err) { | ||||||
| 					if(err.message === 'content-too-short') { | 					if(err.message === 'content-too-short') { | ||||||
| 						posts.emitContentTooShortAlert(socket); | 						posts.emitContentTooShortAlert(socket); | ||||||
| 					} else if(err.message === 'too-many-posts') { | 					} else if (err.message === 'too-many-posts') { | ||||||
| 						posts.emitTooManyPostsAlert(socket); | 						posts.emitTooManyPostsAlert(socket); | ||||||
| 					} else if(err.message === 'reply-error') { | 					} else if (err.message === 'reply-error') { | ||||||
| 						socket.emit('event:alert', { | 						socket.emit('event:alert', { | ||||||
| 							title: 'Reply Unsuccessful', | 							title: 'Reply Unsuccessful', | ||||||
| 							message: 'Your reply could not be posted at this time. Please try again later.', | 							message: 'Your reply could not be posted at this time. Please try again later.', | ||||||
| @@ -396,7 +405,7 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				if(result) { | 				if (result) { | ||||||
|  |  | ||||||
| 					posts.getTopicPostStats(socket); | 					posts.getTopicPostStats(socket); | ||||||
|  |  | ||||||
| @@ -415,7 +424,7 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 		function emitOnlineUserCount() { | 		function emitOnlineUserCount() { | ||||||
| 			var anon = userSockets[0] ? userSockets[0].length : 0; | 			var anon = userSockets[0] ? userSockets[0].length : 0; | ||||||
| 			var registered = Object.keys(userSockets).length; | 			var registered = Object.keys(userSockets).length; | ||||||
| 			if(anon) | 			if (anon) | ||||||
| 				registered = registered - 1; | 				registered = registered - 1; | ||||||
|  |  | ||||||
| 			var returnObj = { | 			var returnObj = { | ||||||
| @@ -483,12 +492,14 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
|  |  | ||||||
| 		socket.on('api:posts.getRawPost', function(data) { | 		socket.on('api:posts.getRawPost', function(data) { | ||||||
| 			posts.getPostField(data.pid, 'content', function(raw) { | 			posts.getPostField(data.pid, 'content', function(raw) { | ||||||
| 				socket.emit('api:posts.getRawPost', { post: raw }); | 				socket.emit('api:posts.getRawPost', { | ||||||
|  | 					post: raw | ||||||
|  | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('api:posts.edit', function(data) { | 		socket.on('api:posts.edit', function(data) { | ||||||
| 			if(!data.title || data.title.length < topics.minimumTitleLength) { | 			if (!data.title || data.title.length < topics.minimumTitleLength) { | ||||||
| 				topics.emitTitleTooShortAlert(socket); | 				topics.emitTitleTooShortAlert(socket); | ||||||
| 				return; | 				return; | ||||||
| 			} else if (!data.content || data.content.length < require('../public/config.json').minimumPostLength) { | 			} else if (!data.content || data.content.length < require('../public/config.json').minimumPostLength) { | ||||||
| @@ -531,7 +542,7 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 		socket.on('getChatMessages', function(data, callback) { | 		socket.on('getChatMessages', function(data, callback) { | ||||||
| 			var touid = data.touid; | 			var touid = data.touid; | ||||||
| 			require('./messaging').getMessages(uid, touid, function(err, messages) { | 			require('./messaging').getMessages(uid, touid, function(err, messages) { | ||||||
| 				if(err) | 				if (err) | ||||||
| 					return callback(null); | 					return callback(null); | ||||||
|  |  | ||||||
| 				callback(messages); | 				callback(messages); | ||||||
| @@ -541,7 +552,7 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 		socket.on('sendChatMessage', function(data) { | 		socket.on('sendChatMessage', function(data) { | ||||||
|  |  | ||||||
| 			var touid = data.touid; | 			var touid = data.touid; | ||||||
| 			if(touid === uid || uid === 0) { | 			if (touid === uid || uid === 0) { | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -551,8 +562,8 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 				var finalMessage = username + ' : ' + msg, | 				var finalMessage = username + ' : ' + msg, | ||||||
| 					notifText = 'New message from <strong>' + username + '</strong>'; | 					notifText = 'New message from <strong>' + username + '</strong>'; | ||||||
|  |  | ||||||
| 				if(!isUserOnline(touid)) { | 				if (!isUserOnline(touid)) { | ||||||
| 					notifications.create(notifText, 5, 'javascript:app.openChat(''+username+'', '+uid+');', 'notification_' + uid + '_' + touid, function(nid) { | 					notifications.create(notifText, 5, 'javascript:app.openChat('' + username + '', ' + uid + ');', 'notification_' + uid + '_' + touid, function(nid) { | ||||||
| 						notifications.push(nid, [touid], function(success) { | 						notifications.push(nid, [touid], function(success) { | ||||||
|  |  | ||||||
| 						}); | 						}); | ||||||
| @@ -562,20 +573,30 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 				require('./messaging').addMessage(uid, touid, msg, function(err, message) { | 				require('./messaging').addMessage(uid, touid, msg, function(err, message) { | ||||||
| 					var numSockets = 0; | 					var numSockets = 0; | ||||||
|  |  | ||||||
| 					if(userSockets[touid]) { | 					if (userSockets[touid]) { | ||||||
| 						numSockets = userSockets[touid].length; | 						numSockets = userSockets[touid].length; | ||||||
|  |  | ||||||
| 						for(var x=0; x<numSockets; ++x) { | 						for (var x = 0; x < numSockets; ++x) { | ||||||
| 							userSockets[touid][x].emit('chatMessage', {fromuid:uid, username:username, message: finalMessage, timestamp: Date.now()}); | 							userSockets[touid][x].emit('chatMessage', { | ||||||
|  | 								fromuid: uid, | ||||||
|  | 								username: username, | ||||||
|  | 								message: finalMessage, | ||||||
|  | 								timestamp: Date.now() | ||||||
|  | 							}); | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					if(userSockets[uid]) { | 					if (userSockets[uid]) { | ||||||
|  |  | ||||||
| 						numSockets = userSockets[uid].length; | 						numSockets = userSockets[uid].length; | ||||||
|  |  | ||||||
| 						for(var x=0; x<numSockets; ++x) { | 						for (var x = 0; x < numSockets; ++x) { | ||||||
| 							userSockets[uid][x].emit('chatMessage', {fromuid:touid, username:username, message:'You : ' + msg, timestamp: Date.now()}); | 							userSockets[uid][x].emit('chatMessage', { | ||||||
|  | 								fromuid: touid, | ||||||
|  | 								username: username, | ||||||
|  | 								message: 'You : ' + msg, | ||||||
|  | 								timestamp: Date.now() | ||||||
|  | 							}); | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				}); | 				}); | ||||||
| @@ -590,7 +611,9 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
|  |  | ||||||
| 		socket.on('api:config.set', function(data) { | 		socket.on('api:config.set', function(data) { | ||||||
| 			meta.configs.set(data.key, data.value, function(err) { | 			meta.configs.set(data.key, data.value, function(err) { | ||||||
| 				if (!err) socket.emit('api:config.set', { status: 'ok' }); | 				if (!err) socket.emit('api:config.set', { | ||||||
|  | 					status: 'ok' | ||||||
|  | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| @@ -613,7 +636,7 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 					}); | 					}); | ||||||
| 				} else if (parseInt(data.cid) > 0) { | 				} else if (parseInt(data.cid) > 0) { | ||||||
| 					user.getUserFields(uid, ['username', 'picture'], function(err, userData) { | 					user.getUserFields(uid, ['username', 'picture'], function(err, userData) { | ||||||
| 						if(!err && userData) { | 						if (!err && userData) { | ||||||
| 							socket.emit('api:composer.push', { | 							socket.emit('api:composer.push', { | ||||||
| 								tid: 0, | 								tid: 0, | ||||||
| 								cid: data.cid, | 								cid: data.cid, | ||||||
| @@ -692,7 +715,9 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 				end = start + 9; | 				end = start + 9; | ||||||
|  |  | ||||||
| 			topics.getTopicPosts(data.tid, start, end, uid, function(posts) { | 			topics.getTopicPosts(data.tid, start, end, uid, function(posts) { | ||||||
| 				callback({posts:posts}); | 				callback({ | ||||||
|  | 					posts: posts | ||||||
|  | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| @@ -701,7 +726,9 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 				end = start + 9; | 				end = start + 9; | ||||||
|  |  | ||||||
| 			categories.getCategoryTopics(data.cid, start, end, uid, function(topics) { | 			categories.getCategoryTopics(data.cid, start, end, uid, function(topics) { | ||||||
| 				callback({topics:topics}); | 				callback({ | ||||||
|  | 					topics: topics | ||||||
|  | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| @@ -728,10 +755,12 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 				end = start + 19; | 				end = start + 19; | ||||||
|  |  | ||||||
| 			user.getUsers(data.set, start, end, function(err, data) { | 			user.getUsers(data.set, start, end, function(err, data) { | ||||||
| 				if(err) { | 				if (err) { | ||||||
| 					winston.err(err); | 					winston.err(err); | ||||||
| 				} else { | 				} else { | ||||||
| 					callback({users:data}); | 					callback({ | ||||||
|  | 						users: data | ||||||
|  | 					}); | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| @@ -753,37 +782,37 @@ var SocketIO = require('socket.io').listen(global.server, { | |||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('api:admin.user.makeAdmin', function(theirid) { | 		socket.on('api:admin.user.makeAdmin', function(theirid) { | ||||||
| 			if(uid && uid > 0) { | 			if (uid && uid > 0) { | ||||||
| 				admin.user.makeAdmin(uid, theirid, socket); | 				admin.user.makeAdmin(uid, theirid, socket); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('api:admin.user.removeAdmin', function(theirid) { | 		socket.on('api:admin.user.removeAdmin', function(theirid) { | ||||||
| 			if(uid && uid > 0) { | 			if (uid && uid > 0) { | ||||||
| 				admin.user.removeAdmin(uid, theirid, socket); | 				admin.user.removeAdmin(uid, theirid, socket); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('api:admin.user.deleteUser', function(theirid) { | 		socket.on('api:admin.user.deleteUser', function(theirid) { | ||||||
| 			if(uid && uid > 0) { | 			if (uid && uid > 0) { | ||||||
| 				admin.user.deleteUser(uid, theirid, socket); | 				admin.user.deleteUser(uid, theirid, socket); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('api:admin.user.banUser', function(theirid) { | 		socket.on('api:admin.user.banUser', function(theirid) { | ||||||
| 			if(uid && uid > 0) { | 			if (uid && uid > 0) { | ||||||
| 				admin.user.banUser(uid, theirid, socket); | 				admin.user.banUser(uid, theirid, socket); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('api:admin.user.unbanUser', function(theirid) { | 		socket.on('api:admin.user.unbanUser', function(theirid) { | ||||||
| 			if(uid && uid > 0) { | 			if (uid && uid > 0) { | ||||||
| 				admin.user.unbanUser(uid, theirid, socket); | 				admin.user.unbanUser(uid, theirid, socket); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		socket.on('api:admin.user.search', function(username, callback) { | 		socket.on('api:admin.user.search', function(username, callback) { | ||||||
| 			if(uid && uid > 0) { | 			if (uid && uid > 0) { | ||||||
| 				user.search(username, function(data) { | 				user.search(username, function(data) { | ||||||
| 					if (!callback) socket.emit('api:admin.user.search', data); | 					if (!callback) socket.emit('api:admin.user.search', data); | ||||||
| 					else callback(null, data); | 					else callback(null, data); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user