fix: backfill email identities on successful login

This commit is contained in:
IanShaw027
2026-04-20 20:58:19 +08:00
parent 9bebf1c1a6
commit 32059ae9d5
3 changed files with 51 additions and 0 deletions

View File

@@ -147,5 +147,11 @@ func (s *AuthService) ValidatePasswordCredentials(ctx context.Context, email, pa
// RecordSuccessfulLogin updates last-login activity after a non-standard login
// flow finishes with a real session.
func (s *AuthService) RecordSuccessfulLogin(ctx context.Context, userID int64) {
if s != nil && s.userRepo != nil && userID > 0 {
user, err := s.userRepo.GetByID(ctx, userID)
if err == nil {
s.backfillEmailIdentityOnSuccessfulLogin(ctx, user)
}
}
s.touchUserLogin(ctx, userID)
}

View File

@@ -430,6 +430,7 @@ func (s *AuthService) Login(ctx context.Context, email, password string) (string
if !user.IsActive() {
return "", nil, ErrUserNotActive
}
s.backfillEmailIdentityOnSuccessfulLogin(ctx, user)
s.touchUserLogin(ctx, user.ID)
// 生成JWT token
@@ -802,6 +803,13 @@ func (s *AuthService) touchUserLogin(ctx context.Context, userID int64) {
}
}
func (s *AuthService) backfillEmailIdentityOnSuccessfulLogin(ctx context.Context, user *User) {
if s == nil || user == nil || user.ID <= 0 {
return
}
s.ensureEmailAuthIdentity(ctx, user)
}
func (s *AuthService) ensureEmailAuthIdentity(ctx context.Context, user *User) {
if s == nil || s.entClient == nil || user == nil || user.ID <= 0 {
return

View File

@@ -150,4 +150,41 @@ func TestAuthServiceLoginTouchesLastLoginAt(t *testing.T) {
require.NotNil(t, storedUser.LastActiveAt)
require.True(t, storedUser.LastLoginAt.After(old))
require.True(t, storedUser.LastActiveAt.After(old))
identity, err := client.AuthIdentity.Query().
Where(
authidentity.ProviderTypeEQ("email"),
authidentity.ProviderKeyEQ("email"),
authidentity.ProviderSubjectEQ("login@example.com"),
).
Only(ctx)
require.NoError(t, err)
require.Equal(t, user.ID, identity.UserID)
}
func TestAuthServiceRecordSuccessfulLoginBackfillsEmailIdentity(t *testing.T) {
svc, repo, client := newAuthServiceWithEnt(t)
ctx := context.Background()
user := &service.User{
Email: "record@example.com",
Role: service.RoleUser,
Status: service.StatusActive,
Balance: 1,
Concurrency: 1,
}
require.NoError(t, user.SetPassword("password"))
require.NoError(t, repo.Create(ctx, user))
svc.RecordSuccessfulLogin(ctx, user.ID)
identity, err := client.AuthIdentity.Query().
Where(
authidentity.ProviderTypeEQ("email"),
authidentity.ProviderKeyEQ("email"),
authidentity.ProviderSubjectEQ("record@example.com"),
).
Only(ctx)
require.NoError(t, err)
require.Equal(t, user.ID, identity.UserID)
}