From 40e840b237fb5cc9f62c81589a2a8eddc000ce8b Mon Sep 17 00:00:00 2001 From: pplulee <46434255+pplulee@users.noreply.github.com> Date: Mon, 26 Feb 2024 21:52:28 +0000 Subject: [PATCH] feat: add frequency limit on requesting email per IP --- .../Controllers/V1/Passport/CommController.php | 17 ++++++++++++++++- app/Http/Requests/Admin/ConfigSave.php | 3 +++ app/Services/ConfigService.php | 3 +++ app/Utils/CacheKey.php | 1 + resources/lang/en-US.json | 1 + resources/lang/zh-CN.json | 1 + 6 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/V1/Passport/CommController.php b/app/Http/Controllers/V1/Passport/CommController.php index 14019db7..4cc4880a 100644 --- a/app/Http/Controllers/V1/Passport/CommController.php +++ b/app/Http/Controllers/V1/Passport/CommController.php @@ -26,6 +26,15 @@ class CommController extends Controller public function sendEmailVerify(CommSendEmailVerify $request) { + if ((int)config('v2board.email_limit_by_ip_enable', 1)) { + $emailCountByIP = Cache::get(CacheKey::get('EMAIL_IP_RATE_LIMIT', $request->ip())) ?? 0; + if ((int)$emailCountByIP >= (int)config('v2board.email_limit_count', 3)) { + abort(500, __('Requesting emails too frequently, please try again after :minute minute', [ + 'minute' => config('v2board.email_limit_expire', 30) + ])); + } + } + if ((int)config('v2board.recaptcha_enable', 0)) { $recaptcha = new ReCaptcha(config('v2board.recaptcha_key')); $recaptchaResp = $recaptcha->verify($request->input('recaptcha_data')); @@ -50,7 +59,13 @@ class CommController extends Controller 'url' => config('v2board.app_url') ] ]); - + if ((int)config('v2board.email_limit_by_ip_enable', 1)) { + Cache::put( + CacheKey::get('EMAIL_IP_RATE_LIMIT', $request->ip()), + (int)$emailCountByIP + 1, + (int)config('v2board.email_limit_expire', 30) * 60 + ); + } Cache::put(CacheKey::get('EMAIL_VERIFY_CODE', $email), $code, 300); Cache::put(CacheKey::get('LAST_SEND_EMAIL_VERIFY_TIMESTAMP', $email), time(), 60); return response([ diff --git a/app/Http/Requests/Admin/ConfigSave.php b/app/Http/Requests/Admin/ConfigSave.php index 09d105d1..02d85409 100755 --- a/app/Http/Requests/Admin/ConfigSave.php +++ b/app/Http/Requests/Admin/ConfigSave.php @@ -86,6 +86,9 @@ class ConfigSave extends FormRequest 'register_limit_by_ip_enable' => 'in:0,1', 'register_limit_count' => 'integer', 'register_limit_expire' => 'integer', + 'email_limit_by_ip_enable' => 'in:0,1', + 'email_limit_count' => 'integer', + 'email_limit_expire' => 'integer', 'secure_path' => 'min:8|regex:/^[\w-]*$/', 'password_limit_enable' => 'in:0,1', 'password_limit_count' => 'integer', diff --git a/app/Services/ConfigService.php b/app/Services/ConfigService.php index e7ba8879..9e073daf 100644 --- a/app/Services/ConfigService.php +++ b/app/Services/ConfigService.php @@ -96,6 +96,9 @@ class ConfigService { 'register_limit_by_ip_enable' => (int)config('v2board.register_limit_by_ip_enable', 0), 'register_limit_count' => config('v2board.register_limit_count', 3), 'register_limit_expire' => config('v2board.register_limit_expire', 60), + 'email_limit_by_ip_enable' => (int)config('v2board.email_limit_by_ip_enable', 1), + 'email_limit_count' => config('v2board.email_limit_count', 3), + 'email_limit_expire' => config('v2board.email_limit_expire', 30), 'password_limit_enable' => (int)config('v2board.password_limit_enable', 1), 'password_limit_count' => config('v2board.password_limit_count', 5), 'password_limit_expire' => config('v2board.password_limit_expire', 60) diff --git a/app/Utils/CacheKey.php b/app/Utils/CacheKey.php index 7b5d0e4c..ede6f66f 100644 --- a/app/Utils/CacheKey.php +++ b/app/Utils/CacheKey.php @@ -26,6 +26,7 @@ class CacheKey 'LAST_SEND_EMAIL_REMIND_TRAFFIC' => '最后发送流量邮件提醒', 'SCHEDULE_LAST_CHECK_AT' => '计划任务最后检查时间', 'REGISTER_IP_RATE_LIMIT' => '注册频率限制', + 'EMAIL_IP_RATE_LIMIT' => 'IP请求邮件频率限制', 'LAST_SEND_LOGIN_WITH_MAIL_LINK_TIMESTAMP' => '最后一次发送登入链接时间', 'PASSWORD_ERROR_LIMIT' => '密码错误次数限制', 'USER_SESSIONS' => '用户session', diff --git a/resources/lang/en-US.json b/resources/lang/en-US.json index 3007aa98..971133ec 100644 --- a/resources/lang/en-US.json +++ b/resources/lang/en-US.json @@ -89,6 +89,7 @@ "The coupon code cannot be used for this period": "The coupon code cannot be used for this period", "Request failed, please try again later": "Request failed, please try again later", "Register frequently, please try again after :minute minute": "Register frequently, please try again after :minute minute", + "Requesting emails too frequently, please try again after :minute minute": "Requesting emails too frequently, please try again after :minute minute", "Uh-oh, we've had some problems, we're working on it.": "Uh-oh, we've had some problems, we're working on it", "This subscription reset package does not apply to your subscription": "This subscription reset package does not apply to your subscription", "Login to :name": "Login to :name", diff --git a/resources/lang/zh-CN.json b/resources/lang/zh-CN.json index 6d11779f..b8d69d38 100644 --- a/resources/lang/zh-CN.json +++ b/resources/lang/zh-CN.json @@ -89,6 +89,7 @@ "The coupon code cannot be used for this period": "此优惠券无法用于该付款周期", "Request failed, please try again later": "请求失败,请稍后再试", "Register frequently, please try again after :minute minute": "注册频繁,请等待 :minute 分钟后再次尝试", + "Requesting emails too frequently, please try again after :minute minute": "请求邮件过于频繁,请等待 :minute 分钟后再次尝试", "Uh-oh, we've had some problems, we're working on it.": "遇到了些问题,我们正在进行处理", "This subscription reset package does not apply to your subscription": "该订阅重置包不适用于你的订阅", "Login to :name": "登入到 :name",