From fc102dddf0d14560290791d8d3bd6cdc7244797d Mon Sep 17 00:00:00 2001
From: localhost_frssoft <userquicker@disroot.org>
Date: Wed, 27 Sep 2023 19:47:29 +0000
Subject: [PATCH] prevent flooding codes and mention spam

---
 functions.lua |  5 +++++
 join.lua      | 24 ++++++++++++++++++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/functions.lua b/functions.lua
index dffaffb..3cfbc60 100644
--- a/functions.lua
+++ b/functions.lua
@@ -227,3 +227,8 @@ function fediauth.give_code(secret_b32, time)
     end
     return codeseq
 end
+
+function fediauth.str_repeats(s,c)
+    local _,n = s:gsub(c,"")
+    return n
+end
diff --git a/join.lua b/join.lua
index fbedf40..9ffe209 100644
--- a/join.lua
+++ b/join.lua
@@ -14,6 +14,7 @@ local formspecfediadd = "size[9,10]" ..
             		"button[5,8.7;3,1;submit;Send code]"
 
 local feditempstore = {}
+local failed_counter = {}
 
 minetest.register_entity("fediauth:checkmark", {
 	initial_properties = {
@@ -75,6 +76,23 @@ minetest.register_on_joinplayer(function(player)
     end
 end)
 
+-- prevent flooding codes
+minetest.register_on_prejoinplayer(function(name, ip)
+    if (failed_counter[name] or 0) >= 2 then
+	return "Please try later, your attempts has expired"
+    end
+end)
+
+local function attempts_cleanup(name)
+    for k, v in pairs(failed_counter) do
+	if v >= 2 then
+		failed_counter[k] = nil
+	end
+    end
+    minetest.after(120, attempts_cleanup)
+end
+minetest.after(120, attempts_cleanup)
+
 -- clear fediauth session on leave
 minetest.register_on_leaveplayer(function(player)
     local playername = player:get_player_name()
@@ -105,7 +123,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 
     -- check for new player or doesn't have fedi account
     if fields.fediverse_account_url then
-	if not string.starts(fields.fediverse_account_url, "@") or string.len(fields.fediverse_account_url) < 3 or string.len(fields.fediverse_account_url) > 100 then
+	-- basic prevent mention spam and limit length
+	if not string.starts(fields.fediverse_account_url, "@") or string.len(fields.fediverse_account_url) < 3 or string.len(fields.fediverse_account_url) > 100 or fediauth.str_repeats(fields.fediverse_account_url, "@") > 2 then
 		minetest.chat_send_player(playername, minetest.colorize("#ff0000", "Try again, your input is incorrect"))
 		minetest.show_formspec(playername, FORMNAMEFEDI, formspecfediadd)
 		return
@@ -129,7 +148,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
     if fediauth.check_code(secret_b32, fields.code) then
 	local fedi_account = fediauth.storage:get_string(playername .. "_fedi")
 
-	-- for account without fediverse (for prevent write account if code incorrect
+	-- if player without fediverse (for prevent write account handle if code incorrect)
 	if fedi_account == "" and feditempstore[playername] then
 		fediauth.storage:set_string(playername .. "_fedi", feditempstore[playername])
 		fedi_account = feditempstore[playername]
@@ -143,5 +162,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
     else
         minetest.kick_player(playername, "fediauth code validation failed")
         fediauth.regrant_privs(playername)
+	failed_counter[playername] = (failed_counter[playername] or 0) + 1
     end
 end)