From 23a7a292efcad4c6d14776ca4d9b5a0656c1ce7e Mon Sep 17 00:00:00 2001 From: shanshanzhong Date: Tue, 21 Apr 2026 01:09:34 -0700 Subject: [PATCH] =?UTF-8?q?fix:=20Gmail=20=E6=B3=9B=E5=9F=9F=E5=90=8D?= =?UTF-8?q?=E9=82=AE=E7=AE=B1(=E5=90=AB=E7=82=B9=E5=8F=B7/+=E5=88=AB?= =?UTF-8?q?=E5=90=8D)=E7=9B=B4=E6=8E=A5=E6=8B=92=E7=BB=9D=E8=B5=A0?= =?UTF-8?q?=E9=80=81=E8=AF=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: claude-flow --- internal/logic/auth/trialEmailWhitelist.go | 30 +++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/internal/logic/auth/trialEmailWhitelist.go b/internal/logic/auth/trialEmailWhitelist.go index ae15855..de7b0c1 100644 --- a/internal/logic/auth/trialEmailWhitelist.go +++ b/internal/logic/auth/trialEmailWhitelist.go @@ -38,7 +38,35 @@ func ShouldGrantTrialForEmail(register config.RegisterConfig, email string) bool if register.TrialEmailDomainWhitelist == "" { return false } - return IsEmailDomainWhitelisted(email, register.TrialEmailDomainWhitelist) + if !IsEmailDomainWhitelisted(email, register.TrialEmailDomainWhitelist) { + return false + } + // Gmail 系域名:local part 含点号或 + 别名的视为泛域名,直接拒绝赠送 + if IsDisposableAlias(email) { + return false + } + return true +} + +// IsDisposableAlias detects Gmail dot trick and + alias abuse. +// For Gmail-like domains, local part containing "." or "+" is rejected. +// For all other domains, only "+" alias is rejected. +func IsDisposableAlias(email string) bool { + parts := strings.SplitN(strings.ToLower(strings.TrimSpace(email)), "@", 2) + if len(parts) != 2 { + return false + } + local, domain := parts[0], parts[1] + + // All domains: reject + alias + if strings.ContainsRune(local, '+') { + return true + } + // Gmail-like domains: reject dots in local part + if isGmailLikeDomain(domain) && strings.ContainsRune(local, '.') { + return true + } + return false } // NormalizeEmail returns a canonical form of the email for trial deduplication.