mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 02:55:58 +01:00 
			
		
		
		
	refactored the entire privileges stack. .editable() is now deprecated, use
.privileges instead. Privileges now are inherited, so querying a topic's privileges will automatically query it's parent category's privileges as well, etc.
This commit is contained in:
		| @@ -164,6 +164,10 @@ footer.footer { | |||||||
| 			margin-bottom: 10px; | 			margin-bottom: 10px; | ||||||
| 			padding-bottom: 10px; | 			padding-bottom: 10px; | ||||||
|  |  | ||||||
|  | 			&.deleted { | ||||||
|  | 				-moz-opacity: 0.30; | ||||||
|  | 				opacity: 0.30; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		&:last-child li { | 		&:last-child li { | ||||||
| @@ -300,7 +304,7 @@ footer.footer { | |||||||
|  |  | ||||||
| 		&.deleted { | 		&.deleted { | ||||||
| 			-moz-opacity: 0.30; | 			-moz-opacity: 0.30; | ||||||
| 			opacity: 0.30;			 | 			opacity: 0.30; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ | |||||||
| 	<div class="span9"> | 	<div class="span9"> | ||||||
| 		<ul id="topics-container"> | 		<ul id="topics-container"> | ||||||
| 		<!-- BEGIN topics --> | 		<!-- BEGIN topics --> | ||||||
| 		<a href="../../topic/{topics.slug}"><li> | 		<a href="../../topic/{topics.slug}"><li class="{topics.deleted-class}"> | ||||||
| 			<div class="row-fluid"> | 			<div class="row-fluid"> | ||||||
| 				<div class="span1 thread-rating hidden-phone hidden-tablet"> | 				<div class="span1 thread-rating hidden-phone hidden-tablet"> | ||||||
| 					<span> | 					<span> | ||||||
|   | |||||||
| @@ -1,7 +1,8 @@ | |||||||
| var	RDB = require('./redis.js'), | var	RDB = require('./redis.js'), | ||||||
| 	posts = require('./posts.js'), | 	posts = require('./posts.js'), | ||||||
| 	utils = require('./utils.js'), | 	utils = require('./utils.js'), | ||||||
| 	user = require('./user.js'); | 	user = require('./user.js'), | ||||||
|  | 	async = require('async'); | ||||||
|  |  | ||||||
| (function(Categories) { | (function(Categories) { | ||||||
|  |  | ||||||
| @@ -27,6 +28,30 @@ var	RDB = require('./redis.js'), | |||||||
| 		}); | 		}); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	Categories.privileges = function(cid, uid, callback) { | ||||||
|  | 		async.parallel([ | ||||||
|  | 			// function(next) { | ||||||
|  | 			// 	user.getUserField(uid, 'reputation', function(reputation) { | ||||||
|  | 			// 		next(null, reputation >= config.privilege_thresholds.manage_category); | ||||||
|  | 			// 	}); | ||||||
|  | 			// }, | ||||||
|  | 			function(next) { | ||||||
|  | 				user.isModerator(uid, cid, function(isMod) { | ||||||
|  | 					next(null, isMod); | ||||||
|  | 				}); | ||||||
|  | 			}, function(next) { | ||||||
|  | 				user.isAdministrator(uid, function(isAdmin) { | ||||||
|  | 					next(null, isAdmin); | ||||||
|  | 				}); | ||||||
|  | 			} | ||||||
|  | 		], function(err, results) { | ||||||
|  | 			callback({ | ||||||
|  | 				editable: results.indexOf(true) !== -1 ? true : false, | ||||||
|  | 				view_deleted: results.indexOf(true) !== -1 ? true : false | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	Categories.edit = function(data, callback) { | 	Categories.edit = function(data, callback) { | ||||||
| 		// just a reminder to self that name + slugs are stored into topics data as well. | 		// just a reminder to self that name + slugs are stored into topics data as well. | ||||||
| 	}; | 	}; | ||||||
|   | |||||||
							
								
								
									
										92
									
								
								src/posts.js
									
									
									
									
									
								
							
							
						
						
									
										92
									
								
								src/posts.js
									
									
									
									
									
								
							| @@ -13,34 +13,28 @@ marked.setOptions({ | |||||||
| (function(Posts) { | (function(Posts) { | ||||||
|  |  | ||||||
| 	Posts.get = function(callback, tid, current_user, start, end) { | 	Posts.get = function(callback, tid, current_user, start, end) { | ||||||
|  |  | ||||||
| 		if (start == null) start = 0; | 		if (start == null) start = 0; | ||||||
| 		if (end == null) end = -1;//start + 10; | 		if (end == null) end = -1;//start + 10; | ||||||
|  |  | ||||||
| 		var post_data, user_data, thread_data, vote_data, viewer_data; | 		var post_data, user_data, thread_data, vote_data, privileges; | ||||||
|  |  | ||||||
| 		getTopicPosts(); | 		getTopicPosts(); | ||||||
|  |  | ||||||
| 		getViewerData(); | 		getPrivileges(); | ||||||
| 		 | 		 | ||||||
|  |  | ||||||
| 		//compile thread after all data is asynchronously called | 		//compile thread after all data is asynchronously called | ||||||
| 		function generateThread() { | 		function generateThread() { | ||||||
| 			if (!post_data || !user_data || !thread_data || !vote_data || !viewer_data) return; | 			if (!post_data || !user_data || !thread_data || !vote_data || !privileges) return; | ||||||
|  |  | ||||||
| 			var	posts = [], | 			var	posts = [], | ||||||
| 				main_posts = [], | 				main_posts = []; | ||||||
| 				manage_content = ( |  | ||||||
| 					viewer_data.reputation >= config.privilege_thresholds.manage_content || |  | ||||||
| 					viewer_data.isModerator || |  | ||||||
| 					viewer_data.isAdministrator |  | ||||||
| 				); |  | ||||||
|  |  | ||||||
| 			for (var i=0, ii= post_data.pid.length; i<ii; i++) { | 			for (var i=0, ii= post_data.pid.length; i<ii; i++) { | ||||||
| 				var uid = post_data.uid[i], | 				var uid = post_data.uid[i], | ||||||
| 					pid = post_data.pid[i]; | 					pid = post_data.pid[i]; | ||||||
| 					 | 					 | ||||||
| 				if (post_data.deleted[i] === null || (post_data.deleted[i] === '1' && manage_content) || current_user === uid) { | 				if (post_data.deleted[i] === null || (post_data.deleted[i] === '1' && privileges.view_deleted) || current_user === uid) { | ||||||
| 					var post_obj = { | 					var post_obj = { | ||||||
| 						'pid' : pid, | 						'pid' : pid, | ||||||
| 						'uid' : uid, | 						'uid' : uid, | ||||||
| @@ -53,7 +47,7 @@ marked.setOptions({ | |||||||
| 						'gravatar' : user_data[uid].picture || 'http://www.gravatar.com/avatar/d41d8cd98f00b204e9800998ecf8427e', | 						'gravatar' : user_data[uid].picture || 'http://www.gravatar.com/avatar/d41d8cd98f00b204e9800998ecf8427e', | ||||||
| 						'signature' : user_data[uid].signature, | 						'signature' : user_data[uid].signature, | ||||||
| 						'fav_star_class' : vote_data[pid] ? 'icon-star' : 'icon-star-empty', | 						'fav_star_class' : vote_data[pid] ? 'icon-star' : 'icon-star-empty', | ||||||
| 						'display_moderator_tools': (uid == current_user || manage_content || viewer_data.isModerator) ? 'show' : 'none', | 						'display_moderator_tools': (uid == current_user || privileges.editable) ? 'show' : 'none', | ||||||
| 						'edited-class': post_data.editor[i] !== null ? '' : 'none', | 						'edited-class': post_data.editor[i] !== null ? '' : 'none', | ||||||
| 						'editor': post_data.editor[i] !== null ? user_data[post_data.editor[i]].username : '', | 						'editor': post_data.editor[i] !== null ? user_data[post_data.editor[i]].username : '', | ||||||
| 						'relativeEditTime': post_data.editTime !== null ? utils.relativeTime(post_data.editTime[i]) : '', | 						'relativeEditTime': post_data.editTime !== null ? utils.relativeTime(post_data.editTime[i]) : '', | ||||||
| @@ -73,7 +67,7 @@ marked.setOptions({ | |||||||
| 				'deleted': parseInt(thread_data.deleted) || 0, | 				'deleted': parseInt(thread_data.deleted) || 0, | ||||||
| 				'pinned': parseInt(thread_data.pinned) || 0, | 				'pinned': parseInt(thread_data.pinned) || 0, | ||||||
| 				'topic_id': tid, | 				'topic_id': tid, | ||||||
| 				'expose_tools': manage_content ? 1 : 0, | 				'expose_tools': privileges.editable ? 1 : 0, | ||||||
| 				'posts': posts, | 				'posts': posts, | ||||||
| 				'main_posts': main_posts | 				'main_posts': main_posts | ||||||
| 			}); | 			}); | ||||||
| @@ -159,40 +153,23 @@ marked.setOptions({ | |||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		function getViewerData() { | 		function getPrivileges() { | ||||||
| 			async.parallel([ | 			topics.privileges(tid, current_user, function(user_privs) { | ||||||
| 				function(callback) { | 				privileges = user_privs; | ||||||
| 					user.getUserField(current_user, 'reputation', function(reputation){ | 				generateThread(); | ||||||
| 						viewer_data = viewer_data || {}; |  | ||||||
| 						viewer_data.reputation = reputation; |  | ||||||
|  |  | ||||||
| 						callback(null); |  | ||||||
| 					}); |  | ||||||
| 				}, |  | ||||||
| 				function(callback) { |  | ||||||
| 					RDB.get('tid:' + tid + ':cid', function(err, cid) { |  | ||||||
| 						user.isModerator(current_user, cid, function(isMod) { |  | ||||||
| 							viewer_data = viewer_data || {}; |  | ||||||
| 							viewer_data.isModerator = isMod; |  | ||||||
| 							callback(null); |  | ||||||
| 						}); |  | ||||||
| 					}) |  | ||||||
| 				}, |  | ||||||
| 				function(callback) { |  | ||||||
| 					user.isAdministrator(current_user, function(isAdmin) { |  | ||||||
| 						viewer_data = viewer_data || {}; |  | ||||||
| 						viewer_data.isAdministrator = isAdmin; |  | ||||||
| 						callback(null); |  | ||||||
| 					}); |  | ||||||
| 				} |  | ||||||
| 			], function(err) { |  | ||||||
| 					generateThread(); |  | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Posts.editable = function(uid, pid, callback) { | 	Posts.privileges = function(pid, uid, callback) { | ||||||
| 		async.parallel([ | 		async.parallel([ | ||||||
|  | 			function(next) { | ||||||
|  | 				Posts.get_tid_by_pid(pid, function(tid) { | ||||||
|  | 					topics.privileges(tid, uid, function(privileges) { | ||||||
|  | 						next(null, privileges); | ||||||
|  | 					}); | ||||||
|  | 				}); | ||||||
|  | 			}, | ||||||
| 			function(next) { | 			function(next) { | ||||||
| 				RDB.get('pid:' + pid + ':uid', function(err, author) { | 				RDB.get('pid:' + pid + ':uid', function(err, author) { | ||||||
| 					if (author && parseInt(author) > 0) next(null, author === uid); | 					if (author && parseInt(author) > 0) next(null, author === uid); | ||||||
| @@ -202,23 +179,12 @@ marked.setOptions({ | |||||||
| 				user.getUserField(uid, 'reputation', function(reputation) { | 				user.getUserField(uid, 'reputation', function(reputation) { | ||||||
| 					next(null, reputation >= config.privilege_thresholds.manage_content); | 					next(null, reputation >= config.privilege_thresholds.manage_content); | ||||||
| 				}); | 				}); | ||||||
| 			}, |  | ||||||
| 			function(next) { |  | ||||||
| 				Posts.get_tid_by_pid(pid, function(tid) { |  | ||||||
| 					RDB.get('tid:' + tid + ':cid', function(err, cid) { |  | ||||||
| 						user.isModerator(uid, cid, function(isMod) { |  | ||||||
| 							next(null, isMod); |  | ||||||
| 						}); |  | ||||||
| 					}); |  | ||||||
| 				}); |  | ||||||
| 			}, function(next) { |  | ||||||
| 				user.isAdministrator(uid, function(isAdmin) { |  | ||||||
| 					next(null, isAdmin); |  | ||||||
| 				}); |  | ||||||
| 			} | 			} | ||||||
| 		], function(err, results) { | 		], function(err, results) { | ||||||
| 			// If any return true, allow the edit | 			callback({ | ||||||
| 			if (results.indexOf(true) !== -1) callback(true); | 				editable: results[0].editable || (results.slice(1).indexOf(true) !== -1 ? true : false), | ||||||
|  | 				view_deleted: results[0].view_deleted || (results.slice(1).indexOf(true) !== -1 ? true : false) | ||||||
|  | 			}); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -462,8 +428,8 @@ marked.setOptions({ | |||||||
| 				}); | 				}); | ||||||
| 			}; | 			}; | ||||||
|  |  | ||||||
| 		Posts.editable(uid, pid, function(editable) { | 		Posts.privileges(pid, uid, function(privileges) { | ||||||
| 			if (editable) success(); | 			if (privileges.editable) success(); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -476,8 +442,8 @@ marked.setOptions({ | |||||||
| 				}); | 				}); | ||||||
| 			}; | 			}; | ||||||
|  |  | ||||||
| 		Posts.editable(uid, pid, function(editable) { | 		Posts.privileges(pid, uid, function(privileges) { | ||||||
| 			if (editable) success(); | 			if (privileges.editable) success(); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -490,8 +456,8 @@ marked.setOptions({ | |||||||
| 				}); | 				}); | ||||||
| 			}; | 			}; | ||||||
|  |  | ||||||
| 		Posts.editable(uid, pid, function(editable) { | 		Posts.privileges(pid, uid, function(privileges) { | ||||||
| 			if (editable) success(); | 			if (privileges.editable) success(); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| }(exports)); | }(exports)); | ||||||
							
								
								
									
										102
									
								
								src/topics.js
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								src/topics.js
									
									
									
									
									
								
							| @@ -87,29 +87,33 @@ marked.setOptions({ | |||||||
| 				var usernames, | 				var usernames, | ||||||
| 					has_read, | 					has_read, | ||||||
| 					moderators, | 					moderators, | ||||||
| 					teaser_info; | 					teaser_info, | ||||||
|  | 					privileges; | ||||||
|  |  | ||||||
| 				function generate_topic() { | 				function generate_topic() { | ||||||
| 					if (!usernames || !has_read || !moderators || !teaser_info) return; | 					if (!usernames || !has_read || !moderators || !teaser_info || !privileges) return; | ||||||
|  |  | ||||||
| 					if (tids.length > 0) { | 					if (tids.length > 0) { | ||||||
| 						for (var i=0, ii=title.length; i<ii; i++) { | 						for (var i=0, ii=title.length; i<ii; i++) { | ||||||
| 							topics.push({ | 							if (!deleted[i] || (deleted[i] && privileges.view_deleted) || uid[i] === current_user) { | ||||||
| 								'title' : title[i], | 								topics.push({ | ||||||
| 								'uid' : uid[i], | 									'title' : title[i], | ||||||
| 								'username': usernames[i], | 									'uid' : uid[i], | ||||||
| 								'timestamp' : timestamp[i], | 									'username': usernames[i], | ||||||
| 								'relativeTime': utils.relativeTime(timestamp[i]), | 									'timestamp' : timestamp[i], | ||||||
| 								'slug' : slug[i], | 									'relativeTime': utils.relativeTime(timestamp[i]), | ||||||
| 								'post_count' : postcount[i], | 									'slug' : slug[i], | ||||||
| 								'lock-icon': locked[i] === '1' ? 'icon-lock' : 'none', | 									'post_count' : postcount[i], | ||||||
| 								'deleted': deleted[i], | 									'lock-icon': locked[i] === '1' ? 'icon-lock' : 'none', | ||||||
| 								'pinned': parseInt(pinned[i] || 0),	// For sorting purposes | 									'deleted': deleted[i], | ||||||
| 								'pin-icon': pinned[i] === '1' ? 'icon-pushpin' : 'none', | 									'deleted-class': deleted[i] ? 'deleted' : '', | ||||||
| 								'badgeclass' : (has_read[i] && current_user !=0) ? '' : 'badge-important', | 									'pinned': parseInt(pinned[i] || 0),	// For sorting purposes | ||||||
| 								'teaser_text': teaser_info[i].text, | 									'pin-icon': pinned[i] === '1' ? 'icon-pushpin' : 'none', | ||||||
| 								'teaser_username': teaser_info[i].username | 									'badgeclass' : (has_read[i] && current_user !=0) ? '' : 'badge-important', | ||||||
| 							}); | 									'teaser_text': teaser_info[i].text, | ||||||
|  | 									'teaser_username': teaser_info[i].username | ||||||
|  | 								}); | ||||||
|  | 							} | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| @@ -157,39 +161,33 @@ marked.setOptions({ | |||||||
| 					teaser_info = teasers; | 					teaser_info = teasers; | ||||||
| 					generate_topic(); | 					generate_topic(); | ||||||
| 				}); | 				}); | ||||||
| 				// else { |  | ||||||
| 				// 	callback({ | 				categories.privileges(category_id, current_user, function(user_privs) { | ||||||
| 				// 		'category_name' : category_id ? category_name : 'Recent', | 					privileges = user_privs; | ||||||
| 				// 		'show_topic_button' : category_id ? 'show' : 'hidden', | 				}); | ||||||
| 				// 		'category_id': category_id || 0, |  | ||||||
| 				// 		'topics': [] |  | ||||||
| 				// 	}); |  | ||||||
| 				// } |  | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Topics.editable = function(tid, uid, callback) { | 	Topics.privileges = function(tid, uid, callback) { | ||||||
| 		async.parallel([ | 		async.parallel([ | ||||||
|  | 			function(next) { | ||||||
|  | 				Topics.get_cid_by_tid(tid, function(cid) { | ||||||
|  | 					categories.privileges(cid, uid, function(privileges) { | ||||||
|  | 						next(null, privileges); | ||||||
|  | 					}); | ||||||
|  | 				}); | ||||||
|  | 			}, | ||||||
| 			function(next) { | 			function(next) { | ||||||
| 				user.getUserField(uid, 'reputation', function(reputation) { | 				user.getUserField(uid, 'reputation', function(reputation) { | ||||||
| 					next(null, reputation >= config.privilege_thresholds.manage_thread); | 					next(null, reputation >= config.privilege_thresholds.manage_thread); | ||||||
| 				}); | 				}); | ||||||
| 			}, |  | ||||||
| 			function(next) { |  | ||||||
| 				Topics.get_cid_by_tid(tid, function(cid) { |  | ||||||
| 					user.isModerator(uid, cid, function(isMod) { |  | ||||||
| 						next(null, isMod); |  | ||||||
| 					}); |  | ||||||
| 				}); |  | ||||||
| 			}, function(next) { |  | ||||||
| 				user.isAdministrator(uid, function(isAdmin) { |  | ||||||
| 					next(null, isAdmin); |  | ||||||
| 				}); |  | ||||||
| 			} | 			} | ||||||
| 		], function(err, results) { | 		], function(err, results) { | ||||||
| 			// If any return true, allow the edit | 			callback({ | ||||||
| 			if (results.indexOf(true) !== -1) callback(true); | 				editable: results[0].editable || (results.slice(1).indexOf(true) !== -1 ? true : false), | ||||||
|  | 				view_deleted: results[0].view_deleted || (results.slice(1).indexOf(true) !== -1 ? true : false) | ||||||
|  | 			}); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -383,8 +381,8 @@ marked.setOptions({ | |||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	Topics.lock = function(tid, uid, socket) { | 	Topics.lock = function(tid, uid, socket) { | ||||||
| 		Topics.editable(tid, uid, function(editable) { | 		Topics.privileges(tid, uid, function(privileges) { | ||||||
| 			if (editable) { | 			if (privileges.editable) { | ||||||
| 				// Mark thread as locked | 				// Mark thread as locked | ||||||
| 				RDB.set('tid:' + tid + ':locked', 1); | 				RDB.set('tid:' + tid + ':locked', 1); | ||||||
|  |  | ||||||
| @@ -399,8 +397,8 @@ marked.setOptions({ | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Topics.unlock = function(tid, uid, socket) { | 	Topics.unlock = function(tid, uid, socket) { | ||||||
| 		Topics.editable(tid, uid, function(editable) { | 		Topics.privileges(tid, uid, function(privileges) { | ||||||
| 			if (editable) { | 			if (privileges.editable) { | ||||||
| 				// Mark thread as unlocked | 				// Mark thread as unlocked | ||||||
| 				RDB.del('tid:' + tid + ':locked'); | 				RDB.del('tid:' + tid + ':locked'); | ||||||
|  |  | ||||||
| @@ -415,8 +413,8 @@ marked.setOptions({ | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Topics.delete = function(tid, uid, socket) { | 	Topics.delete = function(tid, uid, socket) { | ||||||
| 		Topics.editable(tid, uid, function(editable) { | 		Topics.privileges(tid, uid, function(privileges) { | ||||||
| 			if (editable) { | 			if (privileges.editable) { | ||||||
| 				// Mark thread as deleted | 				// Mark thread as deleted | ||||||
| 				RDB.set('tid:' + tid + ':deleted', 1); | 				RDB.set('tid:' + tid + ':deleted', 1); | ||||||
| 				Topics.lock(tid, uid); | 				Topics.lock(tid, uid); | ||||||
| @@ -432,8 +430,8 @@ marked.setOptions({ | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Topics.restore = function(tid, uid, socket) { | 	Topics.restore = function(tid, uid, socket) { | ||||||
| 		Topics.editable(tid, uid, function(editable) { | 		Topics.privileges(tid, uid, function(privileges) { | ||||||
| 			if (editable) { | 			if (privileges.editable) { | ||||||
| 				// Mark thread as restored | 				// Mark thread as restored | ||||||
| 				RDB.del('tid:' + tid + ':deleted'); | 				RDB.del('tid:' + tid + ':deleted'); | ||||||
| 				Topics.unlock(tid, uid); | 				Topics.unlock(tid, uid); | ||||||
| @@ -449,8 +447,8 @@ marked.setOptions({ | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Topics.pin = function(tid, uid, socket) { | 	Topics.pin = function(tid, uid, socket) { | ||||||
| 		Topics.editable(tid, uid, function(editable) { | 		Topics.privileges(tid, uid, function(privileges) { | ||||||
| 			if (editable) { | 			if (privileges.editable) { | ||||||
| 				// Mark thread as pinned | 				// Mark thread as pinned | ||||||
| 				RDB.set('tid:' + tid + ':pinned', 1); | 				RDB.set('tid:' + tid + ':pinned', 1); | ||||||
|  |  | ||||||
| @@ -465,8 +463,8 @@ marked.setOptions({ | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Topics.unpin = function(tid, uid, socket) { | 	Topics.unpin = function(tid, uid, socket) { | ||||||
| 		Topics.editable(tid, uid, function(editable) { | 		Topics.privileges(tid, uid, function(privileges) { | ||||||
| 			if (editable) { | 			if (privileges.editable) { | ||||||
| 				// Mark thread as unpinned | 				// Mark thread as unpinned | ||||||
| 				RDB.del('tid:' + tid + ':pinned'); | 				RDB.del('tid:' + tid + ':pinned'); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user