How to protect my forum from Auto Liker?


(Ultra Noob) #1

Below script is annoying. Is there no way to protect forum from it?

Some user are using it do mass-likes in one click.

I don’t own below script.

// ==UserScript==
// @name        One Click Love-Script
// @namespace   discourse-autolove
// @include     https://help.gulshankumar.net/*
// @version     2017.04.11
// @grant       none
// ==/UserScript==

/*
* Patch for GM_getValue and GM_SetValue support for chrome
* credits to: www.devign.me/greasemonkey-gm_getvaluegm_setvalue-functions-for-google-chrome/
*/
if (!this.GM_getValue || (this.GM_getValue.toString && this.GM_getValue.toString().indexOf("not supported")>-1)) {
    this.GM_getValue=function (key,def) {
        return localStorage[key] || def;
    };
    this.GM_setValue=function (key,value) {
        return localStorage[key]=value;
    };
    this.GM_deleteValue=function (key) {
        return delete localStorage[key];
    };
}


$('body').ready(function(){
	var GR_COOKIE_NAME = 'discourse-autolove';
	var hide_ids = $.parseJSON(GM_getValue(GR_COOKIE_NAME, '{}'));

	function handle_post_node(node){
		var tid = node.getAttribute('data-user-id');
		function love_foo(){
			this.innerHTML = "Unlove";
//			$(node).find('.contents').hide();
			$(this).unbind('click', love_foo);
			$(this).click(ulove_foo);
			hide_ids[tid] = 1;
			GM_setValue(GR_COOKIE_NAME, JSON.stringify(hide_ids));
			$('[data-user-id="'+tid+'"]').find('.love_btn').remove();
			$('[data-user-id="'+tid+'"]').each(function(){ handle_post_node(this) });
		}
		function ulove_foo(){
			this.innerHTML = "love";
//			$(node).find('.contents').show();
			$(this).unbind('click', ulove_foo);
			$(this).click(love_foo);
			delete hide_ids[tid];
			GM_setValue(GR_COOKIE_NAME, JSON.stringify(hide_ids));
			$('[data-user-id="'+tid+'"]').find('.ulove_btn').remove();
			$('[data-user-id="'+tid+'"]').each(function(){ $(this).find('.contents').show(); handle_post_node(this) });
		}
		// execute on finding loved one
		if(hide_ids[tid]){			
//			$(node).find('.contents').hide();
			$(node).find('.contents').show();
			if($(node).find('.ulove_btn').length > 0) return;
			var btn = $('<button class="ulove_btn" title="Unsupport this user." style="background-color: Transparent; background-repeat:no-repeat; border: none; cursor:pointer; overflow: hidden; outline:none; margin-left: 3px; "><i class="fa fa-toggle-on"></i></button>');
			$(node).find('.post-info').first().prepend(btn);
			btn.click(ulove_foo);
			$('[data-user-id="'+tid+'"]').find("like").click();
			$('[data-user-id="'+tid+'"]').find(".like").click();
		}
// end execute
			else{
			if($(node).find('.love_btn').length > 0) return;
			var btn = $('<button title="Support this user." style="background: none;" class="love_btn"><i class="fa fa-toggle-off"></i></button>');
			btn.insertBefore($(node).find('.create').last());
			btn.click(love_foo);
		}
	}
	
	$('article').each(function(){handle_post_node(this)});
	var observer = new MutationObserver(function(mutations) {
		for(var i=0; i < mutations.length; ++i){
			var mutation = mutations[i];
			for(var j=0; j < mutation.addedNodes.length; ++j){
				if(mutation.addedNodes[j].nodeName == "#text") continue;
				var node = mutation.addedNodes[j];
				//console.log(node);
				if(node.className == 'container posts'){
					$(node).find('article').each(function(){handle_post_node(this)});
					continue;
				}
				// just to be sure (TODO: sometimes when jumping to a thread via notification the posts aren't handled.
				// This "hack" (should) ensure that all posts are handled )
				if(node.className == 'topic-link'){
					$(window.document).find('article').each(function(){handle_post_node(this)});
					continue;
				}
				if(node.className == 'ember-view post-cloak'){
					node = $(node).find('article').get(0);
				}
				if(node.nodeName == "ARTICLE" && node.getAttribute('data-user-id')){
					handle_post_node(node);	
				}
			}
		}
	});
observer.observe(document, { subtree: true, childList: true});
	});


(Ultra Noob) #2

How to use it?

  • Go to any Topic with large number of replies
  • Enter above script in the Browser Console > press enter key
  • Click on show support icon for any user. Booom! Flood of :heart: notifications.

(Jeff Atwood) #3

Turn down the number of likes per day per user in your site settings. This is already rate limited.


(Ultra Noob) #4

I did turned from 50 to 20. Unfortunately, that raised complaint against me why I did. :expressionless:

Because sometimes there may be really need of large numbers.


(Bhanu Sharma) #5

There is no real solution or method to block such a script. The rate limiter is already available. If your forum members are complaining against it, educate them as to why you have reduced the limit.


(Jay Pfaffman) #6

It’s a problem with your users. You should ban users who use such a script.


(Colin Marshall) #7

I agree with this. Make a rule that the script is not allowed, give users one warning for using it and then ban them if they do it a second time.


(Biscuit) #8

If you want to stop people using this script, maybe don’t post it in the Discourse forum, with instructions about how to use it. :joy:


(Ultra Noob) #9

Thanks to all for the valuable suggestions. I will make restrict the use by guiding users.


(Ultra Noob) #10

I shared it here as a method to reproduce the issue. To confirm what’s happening.


(Colin Marshall) #11

Did you write the script yourself? I see a link to your website in the comments at the top.


(Ultra Noob) #12

No. I have no idea why it is there. I got this script from a user who uses it.


(Colin Marshall) #13

Oh ok. I was just going to say that’s kind of hilarious that you wrote it and it came back to haunt you, but never mind.


#14

Mmm :thinking:

Maybe you (or we) should add some script to warning if the “console” is open.

For example: devtools-detect • Detect if DevTools is open
Other example: javascript - Find out whether Chrome console is open - Stack Overflow

Maybe some dev-guru can make a modal-popup that warns to reader about executing scripts or auto-likers. :+1:


(Jeff Wong) #15

Neat idea, but this won’t protect you from determined abusers - sticking the script in a javascript favorite, or browser plugin would skirt around that particular solution. You’d be caught up in an arms race that you can’t really win.

Rate limits and flagging/PMing the user to let him know that this isn’t acceptable behavior is still the only real method I can see of discouraging that sort of behavior.


(Ultra Noob) #16

Something like Facebook to prevent XSS attack.