fix: 完善邮箱快捷登录注册流程
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
dbent "github.com/Wei-Shaw/sub2api/ent"
|
||||
"github.com/Wei-Shaw/sub2api/ent/redeemcode"
|
||||
infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors"
|
||||
)
|
||||
|
||||
func normalizeOAuthSignupSource(signupSource string) string {
|
||||
@@ -168,6 +169,87 @@ func (s *AuthService) RegisterOAuthEmailAccount(
|
||||
return tokenPair, user, nil
|
||||
}
|
||||
|
||||
// RegisterVerifiedOAuthEmailAccount creates a local account from an OAuth
|
||||
// provider that has already returned a verified email address.
|
||||
func (s *AuthService) RegisterVerifiedOAuthEmailAccount(
|
||||
ctx context.Context,
|
||||
email string,
|
||||
password string,
|
||||
invitationCode string,
|
||||
signupSource string,
|
||||
) (*TokenPair, *User, error) {
|
||||
if s == nil {
|
||||
return nil, nil, ErrServiceUnavailable
|
||||
}
|
||||
if s.settingService == nil || !s.settingService.IsRegistrationEnabled(ctx) {
|
||||
return nil, nil, ErrRegDisabled
|
||||
}
|
||||
|
||||
email = strings.TrimSpace(strings.ToLower(email))
|
||||
if email == "" || len(email) > 255 {
|
||||
return nil, nil, ErrEmailVerifyRequired
|
||||
}
|
||||
if _, err := mail.ParseAddress(email); err != nil {
|
||||
return nil, nil, ErrEmailVerifyRequired
|
||||
}
|
||||
if isReservedEmail(email) {
|
||||
return nil, nil, ErrEmailReserved
|
||||
}
|
||||
if err := s.validateRegistrationEmailPolicy(ctx, email); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if strings.TrimSpace(password) == "" {
|
||||
return nil, nil, infraerrors.BadRequest("PASSWORD_REQUIRED", "password is required")
|
||||
}
|
||||
if _, err := s.validateOAuthRegistrationInvitation(ctx, invitationCode); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
existsEmail, err := s.userRepo.ExistsByEmail(ctx, email)
|
||||
if err != nil {
|
||||
return nil, nil, ErrServiceUnavailable
|
||||
}
|
||||
if existsEmail {
|
||||
return nil, nil, ErrEmailExists
|
||||
}
|
||||
|
||||
hashedPassword, err := s.HashPassword(password)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("hash password: %w", err)
|
||||
}
|
||||
|
||||
signupSource = normalizeOAuthSignupSource(signupSource)
|
||||
grantPlan := s.resolveSignupGrantPlan(ctx, signupSource)
|
||||
var defaultRPMLimit int
|
||||
if s.settingService != nil {
|
||||
defaultRPMLimit = s.settingService.GetDefaultUserRPMLimit(ctx)
|
||||
}
|
||||
user := &User{
|
||||
Email: email,
|
||||
PasswordHash: hashedPassword,
|
||||
Role: RoleUser,
|
||||
Balance: grantPlan.Balance,
|
||||
Concurrency: grantPlan.Concurrency,
|
||||
RPMLimit: defaultRPMLimit,
|
||||
Status: StatusActive,
|
||||
SignupSource: signupSource,
|
||||
}
|
||||
|
||||
if err := s.userRepo.Create(ctx, user); err != nil {
|
||||
if errors.Is(err, ErrEmailExists) {
|
||||
return nil, nil, ErrEmailExists
|
||||
}
|
||||
return nil, nil, ErrServiceUnavailable
|
||||
}
|
||||
|
||||
tokenPair, err := s.GenerateTokenPair(ctx, user, "")
|
||||
if err != nil {
|
||||
_ = s.RollbackOAuthEmailAccountCreation(ctx, user.ID, "")
|
||||
return nil, nil, fmt.Errorf("generate token pair: %w", err)
|
||||
}
|
||||
return tokenPair, user, nil
|
||||
}
|
||||
|
||||
// FinalizeOAuthEmailAccount applies invitation usage and normal signup bootstrap
|
||||
// only after the pending OAuth flow has fully reached its last reversible step.
|
||||
func (s *AuthService) FinalizeOAuthEmailAccount(
|
||||
|
||||
Reference in New Issue
Block a user