fix(auth): synchronize need_change_password across login, user-info and repositories

This commit is contained in:
ryan
2026-08-29 11:49:14 +08:00
parent 107251891f
commit d3d7c783a9
4 changed files with 32 additions and 6 deletions
+1 -1
View File
@@ -440,7 +440,7 @@ func handleCallbackRegister(ctx context.Context, c *gin.Context, source *AuthSou
func UserInfo(c *gin.Context) {
user, _ := ginutil.GetFromContext[*contracts.UserDTO](c, contracts.AuthUserObjKey)
session := sessions.Default(c)
needChange := session.Get("need_change_password") == true
needChange := session.Get("need_change_password") == true || (user != nil && user.NeedChangePassword)
c.JSON(
http.StatusOK,
+1 -1
View File
@@ -172,7 +172,7 @@ func BuildBasicUserInfo(user *contracts.UserDTO, needChange bool) BasicUserInfo
Email: user.Email,
AvatarURL: user.AvatarURL,
IsAdmin: user.IsAdmin,
NeedChangePassword: needChange,
NeedChangePassword: needChange || user.NeedChangePassword,
Bio: user.Bio,
Phone: user.Phone,
Gender: user.Gender,
+27 -4
View File
@@ -8,6 +8,7 @@ import (
"Wavelet/core/contracts"
"Wavelet/pkg/util"
"context"
"strings"
"sync"
"time"
@@ -79,19 +80,41 @@ func GetAccessTokenByHash(ctx context.Context, tokenHash string) (*CachedToken,
// GetActiveUserByID 读取仍处于启用状态的用户
func GetActiveUserByID(ctx context.Context, userID uint64) (*contracts.UserDTO, error) {
var user contracts.UserDTO
if err := getDB(ctx).Table("w_users").Where("id = ? AND is_active = ?", userID, true).First(&user).Error; err != nil {
var row struct {
contracts.UserDTO
Password string `gorm:"column:password"`
}
if err := getDB(ctx).Table("w_users").Where("id = ? AND is_active = ?", userID, true).First(&row).Error; err != nil {
return nil, err
}
user := row.UserDTO
if row.Password != "" &&
!strings.HasPrefix(row.Password, "$2a$") &&
!strings.HasPrefix(row.Password, "$2b$") &&
!strings.HasPrefix(row.Password, "$2y$") &&
!strings.HasPrefix(row.Password, "$2x$") {
user.NeedChangePassword = true
}
return &user, nil
}
// GetUserByID 按 ID 读取用户(不限制启用状态)
func GetUserByID(ctx context.Context, userID uint64) (*contracts.UserDTO, error) {
var user contracts.UserDTO
if err := getDB(ctx).Table("w_users").Where("id = ?", userID).First(&user).Error; err != nil {
var row struct {
contracts.UserDTO
Password string `gorm:"column:password"`
}
if err := getDB(ctx).Table("w_users").Where("id = ?", userID).First(&row).Error; err != nil {
return nil, err
}
user := row.UserDTO
if row.Password != "" &&
!strings.HasPrefix(row.Password, "$2a$") &&
!strings.HasPrefix(row.Password, "$2b$") &&
!strings.HasPrefix(row.Password, "$2y$") &&
!strings.HasPrefix(row.Password, "$2x$") {
user.NeedChangePassword = true
}
return &user, nil
}
+3
View File
@@ -79,6 +79,9 @@ func Login(c *gin.Context) {
sess := sessions.Default(c)
sess.Set(contracts.AuthUserIDKey, user.ID)
sess.Set(contracts.AuthUserNameKey, user.Username)
needChange := user.NeedChangePassword || user.IsPlaintextPassword()
user.NeedChangePassword = needChange
sess.Set("need_change_password", needChange)
if err := sess.Save(); err != nil {
logger.ErrorF(c.Request.Context(), "save session failed on login: %v", err)
}