Files
xiaolajiaoyyds 6f71df4849 Initial open-source release
多平台账号批量注册系统,支持 OpenAI / Grok / Kiro / Gemini 平台的全自动注册。

Features:
- 用户名/密码注册登录(首个用户自动管理员)
- JWT 认证 + bcrypt 密码加密
- 积分系统与多用户管理
- HuggingFace Space 弹性 Worker 节点管理
- Cloudflare Worker 负载均衡
- 实时日志推送(SSE/WebSocket)
- 管理后台(用户管理、系统设置、代理池、卡池)

Tech Stack: Go 1.25 / Gin / GORM / PostgreSQL / Vue 3 / Vite / TailwindCSS
2026-03-22 03:44:42 +08:00

148 lines
3.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package tempmail
import (
"bytes"
"io"
"mime/quotedprintable"
"regexp"
"strings"
)
// 验证码提取正则(所有 provider 共用)
var (
// 策略 1a: subject 以验证码开头(Grok 格式 "ABC123-DEF456")
reSubjectCodeDash = regexp.MustCompile(`^([A-Z0-9]+-[A-Z0-9]+)`)
// 策略 1b: subject 末尾的 6-8 位数字验证码(OpenAI 格式 "Your ChatGPT code is 798357")
reSubjectCodeTail = regexp.MustCompile(`\b(\d{6,8})\s*$`)
// 策略 1c: 显式提示 verification code 的 6 位数字
reKeywordDigits = regexp.MustCompile(`(?i)(?:verification code|verify|code)[^0-9]{0,30}(\d{6})`)
// 策略 1d: 显式提示 verification code 的 6 位字母数字混合码
reKeywordAlphaNum = regexp.MustCompile(`(?i)(?:verification code|verify|code)\s*[::\s]*\b([A-Z0-9]{6})\b`)
// 策略 1e: HTML 中 verification-code 样式块
reHTMLSpanCode = regexp.MustCompile(`(?i)<span[^>]*class="[^"]*verification-code[^"]*"[^>]*>\s*([A-Z0-9]{6,8})\s*</span>`)
// 策略 2: 任意位置的 6-8 位大写字母+数字兜底
reInlineCode = regexp.MustCompile(`\b([A-Z0-9]{6,8})\b`)
)
var verificationCodeBlacklist = map[string]struct{}{
"GOOGLE": {},
"GEMINI": {},
"VERIFY": {},
"SIGNIN": {},
"PLEASE": {},
"CHANGE": {},
"ACCEPT": {},
"CANCEL": {},
"SUBMIT": {},
}
// ExtractVerificationCode 从邮件 subject/body 中提取验证码。
// 先走显式模式,再走 HTML 和 quoted-printable 解码,最后才用通用兜底规则。
func ExtractVerificationCode(subject, body string) string {
if subject != "" {
// Grok 的 subject 常见为 "ABC123-DEF456" 这种前缀格式。
if m := reSubjectCodeDash.FindStringSubmatch(strings.ToUpper(subject)); len(m) > 1 {
return strings.ReplaceAll(m[1], "-", "")
}
// OpenAI 常见 "Your ChatGPT code is 798357"。
if m := reSubjectCodeTail.FindStringSubmatch(subject); len(m) > 1 {
return m[1]
}
if code := extractCodeFromText(subject, true); code != "" {
return code
}
}
if body != "" {
if code := extractCodeFromText(body, true); code != "" {
return code
}
}
return ""
}
func extractCodeFromText(text string, allowPlainDigits bool) string {
if text == "" {
return ""
}
upperText := strings.ToUpper(text)
if m := reHTMLSpanCode.FindStringSubmatch(upperText); len(m) > 1 && isPlausibleVerificationCode(m[1], false) {
return m[1]
}
if m := reKeywordDigits.FindStringSubmatch(text); len(m) > 1 && isPlausibleVerificationCode(m[1], true) {
return m[1]
}
if m := reKeywordAlphaNum.FindStringSubmatch(upperText); len(m) > 1 && isPlausibleVerificationCode(m[1], false) {
return m[1]
}
if decoded := decodeQuotedPrintable(text); decoded != "" && decoded != text {
if code := extractCodeFromText(decoded, allowPlainDigits); code != "" {
return code
}
}
for _, candidate := range reInlineCode.FindAllString(upperText, -1) {
if isPlausibleVerificationCode(candidate, allowPlainDigits) {
return candidate
}
}
return ""
}
func isPlausibleVerificationCode(code string, allowPlainDigits bool) bool {
if code == "" {
return false
}
code = strings.ToUpper(strings.TrimSpace(code))
if _, blocked := verificationCodeBlacklist[code]; blocked {
return false
}
if isAllDigits(code) {
if !allowPlainDigits {
return false
}
if strings.Trim(code, "0") == "" {
return false
}
if len(code) == 6 && (strings.HasPrefix(code, "19") || strings.HasPrefix(code, "20")) {
return false
}
return true
}
return containsDigit(code)
}
func decodeQuotedPrintable(text string) string {
reader := quotedprintable.NewReader(strings.NewReader(text))
decoded, err := io.ReadAll(reader)
if err != nil {
return ""
}
return strings.TrimSpace(string(bytes.TrimSpace(decoded)))
}
func isAllDigits(text string) bool {
if text == "" {
return false
}
for _, ch := range text {
if ch < '0' || ch > '9' {
return false
}
}
return true
}
func containsDigit(text string) bool {
for _, ch := range text {
if ch >= '0' && ch <= '9' {
return true
}
}
return false
}