package service import ( "context" "strings" "time" "git.sundynix.cn/Blizzard/Veyra/internal/apperror" "golang.org/x/crypto/bcrypt" ) type DevelopmentUserCredentialRepository interface { ChangeDevelopmentUserCredential(context.Context, string, string, string, time.Time) (string, error) } type DevelopmentUserCredentialService struct { repo DevelopmentUserCredentialRepository development bool } func NewDevelopmentUserCredentialService(repo DevelopmentUserCredentialRepository, development bool) *DevelopmentUserCredentialService { return &DevelopmentUserCredentialService{repo: repo, development: development} } // Set is an explicit local/test maintenance operation for an existing active USER. // It preserves identity and account ownership and revokes previous sessions. func (s *DevelopmentUserCredentialService) Set(ctx context.Context, previousLogin, login, password string) (string, error) { if !s.development { return "", apperror.ErrForbidden } if s.repo == nil { return "", apperror.ErrUnavailable } previousLogin = strings.ToLower(strings.TrimSpace(previousLogin)) login = strings.ToLower(strings.TrimSpace(login)) if !loginPattern.MatchString(previousLogin) || !loginPattern.MatchString(login) || len(password) < 4 || len(password) > 72 { return "", apperror.ErrInvalidInput } hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { return "", apperror.ErrUnavailable } return s.repo.ChangeDevelopmentUserCredential(ctx, previousLogin, login, string(hash), time.Now().UTC()) }