邮箱正则判断
This commit is contained in:
parent
2e4b8cb673
commit
e1517d4243
@ -45,12 +45,14 @@ type EmailConfig struct {
|
|||||||
Enable bool `toml:"enable" comment:"注册验证邮件,且允许使用邮箱找回账号"`
|
Enable bool `toml:"enable" comment:"注册验证邮件,且允许使用邮箱找回账号"`
|
||||||
Smtp []SmtpUser `toml:"smtp"`
|
Smtp []SmtpUser `toml:"smtp"`
|
||||||
AllowDomain []string `toml:"allow_domain" comment:"允许用于注册的邮箱域名,留空则允许全部"`
|
AllowDomain []string `toml:"allow_domain" comment:"允许用于注册的邮箱域名,留空则允许全部"`
|
||||||
|
EmailReg string `toml:"email_reg" comment:"邮箱正则,留空则不处理,如 ^[0-9]+@qq.com$|^[^+\\.A-Z]+@gmail.com$"`
|
||||||
|
EmailRegMsg string `toml:"email_reg_msg" comment:"不满足要求时的提示信息"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SmtpUser struct {
|
type SmtpUser struct {
|
||||||
Host string `toml:"host"`
|
Host string `toml:"host"`
|
||||||
Port int `toml:"port"`
|
Port int `toml:"port"`
|
||||||
SSL bool `toml:"SSL"`
|
SSL bool `toml:"SSL" comment:"启用 ssl"`
|
||||||
Name string `toml:"name"`
|
Name string `toml:"name"`
|
||||||
Pass string `toml:"password"`
|
Pass string `toml:"password"`
|
||||||
}
|
}
|
||||||
@ -82,5 +84,9 @@ func Default() Config {
|
|||||||
WebBaseUrl: "",
|
WebBaseUrl: "",
|
||||||
ServerName: "没有设置名字",
|
ServerName: "没有设置名字",
|
||||||
Captcha: Captcha{},
|
Captcha: Captcha{},
|
||||||
|
Email: EmailConfig{
|
||||||
|
Smtp: []SmtpUser{},
|
||||||
|
AllowDomain: []string{},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,8 @@ export interface ApiConfig {
|
|||||||
serverName: string
|
serverName: string
|
||||||
NeedEmail: boolean
|
NeedEmail: boolean
|
||||||
AllowDomain: string[]
|
AllowDomain: string[]
|
||||||
|
EmailReg: string
|
||||||
|
EmailRegMsg: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UserInfo {
|
export interface UserInfo {
|
||||||
|
@ -77,6 +77,11 @@ export default function SendEmail({ title, anyEmail = false, sendService }: { ti
|
|||||||
setHelperText("邮箱格式错误")
|
setHelperText("邮箱格式错误")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (!anyEmail && server.data?.EmailReg && server.data?.EmailReg != ""
|
||||||
|
&& !new RegExp(server.data?.EmailReg).test(sendEmail)) {
|
||||||
|
setHelperText(server.data?.EmailRegMsg ?? "邮箱不满足正则要求")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (server.data?.captcha.type != "" && captchaToken == "") {
|
if (server.data?.captcha.type != "" && captchaToken == "") {
|
||||||
return
|
return
|
||||||
|
@ -3,11 +3,15 @@ package handle
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image/png"
|
"image/png"
|
||||||
"io"
|
"io"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
@ -25,10 +29,16 @@ type UserHandel struct {
|
|||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
textureService *service.TextureService
|
textureService *service.TextureService
|
||||||
config config.Config
|
config config.Config
|
||||||
|
|
||||||
|
emailReg func() (*regexp.Regexp, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserHandel(handleError *handelerror.HandleError, validate *validator.Validate,
|
func NewUserHandel(handleError *handelerror.HandleError, validate *validator.Validate,
|
||||||
userService *service.UserService, logger *slog.Logger, textureService *service.TextureService, config config.Config) *UserHandel {
|
userService *service.UserService, logger *slog.Logger, textureService *service.TextureService, config config.Config) *UserHandel {
|
||||||
|
emailReg := sync.OnceValues[*regexp.Regexp, error](func() (*regexp.Regexp, error) {
|
||||||
|
return regexp.Compile(config.Email.EmailReg)
|
||||||
|
})
|
||||||
|
|
||||||
return &UserHandel{
|
return &UserHandel{
|
||||||
handleError: handleError,
|
handleError: handleError,
|
||||||
validate: validate,
|
validate: validate,
|
||||||
@ -36,6 +46,8 @@ func NewUserHandel(handleError *handelerror.HandleError, validate *validator.Val
|
|||||||
logger: logger,
|
logger: logger,
|
||||||
textureService: textureService,
|
textureService: textureService,
|
||||||
config: config,
|
config: config,
|
||||||
|
|
||||||
|
emailReg: emailReg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,6 +239,8 @@ func (h *UserHandel) NeedEnableEmail(handle http.Handler) http.Handler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ErrNotAllowDomain = errors.New("不在允许域名列表内")
|
||||||
|
|
||||||
func (h *UserHandel) SendRegEmail() http.HandlerFunc {
|
func (h *UserHandel) SendRegEmail() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
@ -235,6 +249,31 @@ func (h *UserHandel) SendRegEmail() http.HandlerFunc {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(h.config.Email.AllowDomain) != 0 {
|
||||||
|
allow := false
|
||||||
|
for _, v := range h.config.Email.AllowDomain {
|
||||||
|
if strings.HasSuffix(c.Email, v) {
|
||||||
|
allow = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !allow {
|
||||||
|
h.handleError.Error(ctx, w, "不在允许邮箱域名内", model.ErrInput, 400, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if h.config.Email.EmailReg != "" {
|
||||||
|
r, err := h.emailReg()
|
||||||
|
if err != nil {
|
||||||
|
h.handleError.Error(ctx, w, "正则错误", model.ErrUnknown, 500, slog.LevelError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !r.MatchString(c.Email) {
|
||||||
|
h.handleError.Error(ctx, w, "邮箱不符合正则要求", model.ErrInput, 400, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err := h.userService.SendRegEmail(ctx, c.Email, c.CaptchaToken, r.Host, ip)
|
err := h.userService.SendRegEmail(ctx, c.Email, c.CaptchaToken, r.Host, ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError.Service(ctx, w, err)
|
h.handleError.Service(ctx, w, err)
|
||||||
|
@ -65,6 +65,8 @@ type Config struct {
|
|||||||
ServerName string `json:"serverName"`
|
ServerName string `json:"serverName"`
|
||||||
NeedEmail bool
|
NeedEmail bool
|
||||||
AllowDomain []string
|
AllowDomain []string
|
||||||
|
EmailReg string
|
||||||
|
EmailRegMsg string
|
||||||
}
|
}
|
||||||
|
|
||||||
type EditUser struct {
|
type EditUser struct {
|
||||||
|
@ -238,22 +238,7 @@ func (w *UserService) ChangeName(ctx context.Context, newName string, t *model.T
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var ErrNotAllowDomain = errors.New("不在允许域名列表内")
|
|
||||||
|
|
||||||
func (w *UserService) SendRegEmail(ctx context.Context, email, CaptchaToken, host, ip string) error {
|
func (w *UserService) SendRegEmail(ctx context.Context, email, CaptchaToken, host, ip string) error {
|
||||||
if len(w.config.Email.AllowDomain) != 0 {
|
|
||||||
allow := false
|
|
||||||
for _, v := range w.config.Email.AllowDomain {
|
|
||||||
if strings.HasSuffix(email, v) {
|
|
||||||
allow = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !allow {
|
|
||||||
return fmt.Errorf("SendRegEmail: %w", ErrNotAllowDomain)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err := w.captchaService.VerifyCaptcha(ctx, CaptchaToken, ip)
|
err := w.captchaService.VerifyCaptcha(ctx, CaptchaToken, ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("SendRegEmail: %w", err)
|
return fmt.Errorf("SendRegEmail: %w", err)
|
||||||
|
@ -37,5 +37,7 @@ func (w *WebService) GetConfig(ctx context.Context) model.Config {
|
|||||||
AllowChangeName: !w.config.OfflineUUID,
|
AllowChangeName: !w.config.OfflineUUID,
|
||||||
NeedEmail: w.config.Email.Enable,
|
NeedEmail: w.config.Email.Enable,
|
||||||
AllowDomain: w.config.Email.AllowDomain,
|
AllowDomain: w.config.Email.AllowDomain,
|
||||||
|
EmailReg: w.config.Email.EmailReg,
|
||||||
|
EmailRegMsg: w.config.Email.EmailRegMsg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user