fix: backfill email identities on successful login
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user