refactor: restructure authentication components and routes
All checks were successful
Push to Helm Chart Repository / build (push) Successful in 13s

- Removed the old reset password form component and replaced it with a new implementation.
- Updated routing paths for login, registration, and reset password to be under a common auth path.
- Added new login and registration pages with corresponding forms.
- Introduced a common auth header component for consistent branding across auth pages.
- Implemented a current logged-in user display component.
- Enhanced the register form to include email verification and captcha.
- Updated translations for new and modified components.
- Refactored the navigation bar to include user avatar dropdown and improved menu structure.
This commit is contained in:
2025-09-23 02:21:03 +08:00
parent 0f7cbb385a
commit 349cf5a5b7
23 changed files with 380 additions and 112 deletions

View File

@ -52,6 +52,12 @@ func (u *UserController) Register(ctx context.Context, c *app.RequestContext) {
resps.BadRequest(c, resps.ErrParamInvalid)
return
}
email := strings.TrimSpace(string(c.GetHeader(constant.HeaderKeyEmail)))
if email == "" {
resps.BadRequest(c, "Email header is required")
return
}
userRegisterReq.Email = email
resp, err := u.service.UserRegister(&userRegisterReq)
if err != nil {
@ -97,7 +103,7 @@ func (u *UserController) OidcLogin(ctx context.Context, c *app.RequestContext) {
Code: code,
State: state,
}
resp, err := u.service.OidcLogin(oidcLoginReq)
resp, err := u.service.OidcLogin(ctx, oidcLoginReq)
if err != nil {
serviceErr := errs.AsServiceError(err)
resps.Custom(c, serviceErr.Code, serviceErr.Message, nil)

View File

@ -29,11 +29,10 @@ type UserLoginResp struct {
}
type UserRegisterReq struct {
Username string `json:"username"` // 用户名
Nickname string `json:"nickname"` // 昵称
Password string `json:"password"` // 密码
Email string `json:"email"` // 邮箱
VerificationCode string `json:"verification_code"` // 邮箱验证码
Username string `json:"username"` // 用户名
Nickname string `json:"nickname"` // 昵称
Password string `json:"password"` // 密码
Email string `json:"-" binding:"-"`
}
type UserRegisterResp struct {

View File

@ -2,6 +2,7 @@ package middleware
import (
"context"
"strings"
"github.com/cloudwego/hertz/pkg/app"
"github.com/snowykami/neo-blog/pkg/constant"
@ -12,8 +13,8 @@ import (
// UseEmailVerify 中间件函数,用于邮箱验证,使用前先调用请求发送邮件验证码函数
func UseEmailVerify() app.HandlerFunc {
return func(ctx context.Context, c *app.RequestContext) {
email := string(c.GetHeader(constant.HeaderKeyEmail))
verifyCode := string(c.GetHeader(constant.HeaderKeyVerifyCode))
email := strings.TrimSpace(string(c.GetHeader(constant.HeaderKeyEmail)))
verifyCode := strings.TrimSpace(string(c.GetHeader(constant.HeaderKeyVerifyCode)))
if !utils.Env.GetAsBool(constant.EnvKeyEnableEmailVerify, true) {
c.Next(ctx)
}

View File

@ -15,7 +15,7 @@ func registerUserRoutes(group *route.RouterGroup) {
{
userGroupWithoutAuthNeedsCaptcha.POST("/login", userController.Login)
userGroupWithoutAuthNeedsCaptcha.POST("/register", userController.Register)
userGroupWithoutAuthNeedsCaptcha.POST("/email/verify", userController.VerifyEmail) // Send email verification code
userGroupWithoutAuth.POST("/email/verify", userController.VerifyEmail) // Send email verification code
userGroupWithoutAuth.GET("/captcha", userController.GetCaptchaConfig)
userGroupWithoutAuth.GET("/oidc/list", userController.OidcList)
userGroupWithoutAuth.GET("/oidc/login/:name", userController.OidcLogin)

View File

@ -56,16 +56,9 @@ func (s *UserService) UserLogin(req *dto.UserLoginReq) (*dto.UserLoginResp, erro
}
func (s *UserService) UserRegister(req *dto.UserRegisterReq) (*dto.UserRegisterResp, error) {
// 验证邮箱验证码
if !utils.Env.GetAsBool(constant.EnvKeyEnableRegister, true) {
return nil, errs.ErrForbidden
}
if utils.Env.GetAsBool(constant.EnvKeyEnableEmailVerify, true) {
ok := utils.VerifyEmailCode(req.Email, req.VerificationCode)
if !ok {
return nil, errs.New(http.StatusForbidden, "Invalid email verification code", nil)
}
}
// 检查用户名或邮箱是否已存在
usernameExist, err := repo.User.CheckUsernameExists(req.Username)
if err != nil {
@ -185,7 +178,7 @@ func (s *UserService) ListOidcConfigs() ([]dto.UserOidcConfigDto, error) {
return oidcConfigsDtos, nil
}
func (s *UserService) OidcLogin(req *dto.OidcLoginReq) (*dto.OidcLoginResp, error) {
func (s *UserService) OidcLogin(ctx context.Context, req *dto.OidcLoginReq) (*dto.OidcLoginResp, error) {
// 验证state
kvStore := utils.KV.GetInstance()
storedName, ok := kvStore.Get(constant.KVKeyOidcState + req.State)