fix(workbench): complete profile and channel flows
This commit is contained in:
@@ -21,6 +21,12 @@ type Service struct {
|
||||
sessionTTL time.Duration
|
||||
}
|
||||
|
||||
var (
|
||||
ErrProfileNameRequired = errors.New("display name is required")
|
||||
ErrCurrentPassword = errors.New("current password is incorrect")
|
||||
ErrPasswordTooShort = errors.New("new password must be at least 8 characters")
|
||||
)
|
||||
|
||||
func NewService(secret string) *Service {
|
||||
return &Service{secret: secret, inviteTokenTTL: 7 * 24 * time.Hour, sessionTTL: 24 * time.Hour}
|
||||
}
|
||||
@@ -86,6 +92,46 @@ func (s *Service) VerifySession(token string) (uint, error) {
|
||||
return userID, nil
|
||||
}
|
||||
|
||||
// CurrentUser returns the authenticated user's profile without exposing password hashes.
|
||||
func (s *Service) CurrentUser(userID uint) (*models.SaUser, error) {
|
||||
var user models.SaUser
|
||||
if err := models.DBService.Where("id = ?", userID).First(&user).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
// UpdateCurrentUser updates the small MVP profile surface. A password change always
|
||||
// requires the current password so a stolen unlocked session cannot silently rotate it.
|
||||
func (s *Service) UpdateCurrentUser(userID uint, displayName, currentPassword, newPassword string) (*models.SaUser, error) {
|
||||
user, err := s.CurrentUser(userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
name := strings.TrimSpace(displayName)
|
||||
if name == "" {
|
||||
return nil, ErrProfileNameRequired
|
||||
}
|
||||
updates := map[string]any{"display_name": name}
|
||||
if strings.TrimSpace(newPassword) != "" {
|
||||
if len(newPassword) < 8 {
|
||||
return nil, ErrPasswordTooShort
|
||||
}
|
||||
if bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(currentPassword)) != nil {
|
||||
return nil, ErrCurrentPassword
|
||||
}
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
updates["password_hash"] = string(hash)
|
||||
}
|
||||
if err := models.DBService.Model(user).Updates(updates).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s.CurrentUser(userID)
|
||||
}
|
||||
|
||||
type tokenPayload struct {
|
||||
Type string `json:"type"`
|
||||
Subject string `json:"subject"`
|
||||
|
||||
Reference in New Issue
Block a user