feat: fully implemented Refresh method;

fix: Improve error handling in Refresh method for token validation;
fix: Update Refresh route to use correct request model;
fix: Correct request model for password reset complete route;
fix: Redis pipeline error handling in AuthService constructor;
fix: Refresh method wanted access token;
refactor: Enhance error handling for unexpected token validation errors;
refactor: Simplify claims extraction in ValidateToken method;
fix: Ensure session termination state is correctly dereferenced;
refactor: Return structured session info in ValidateToken method;
feat: New util method to check if an error is one of multiple given ones;
This commit is contained in:
2025-07-15 23:32:25 +03:00
parent e465da6854
commit 8b558eaf5f
3 changed files with 70 additions and 11 deletions

View File

@@ -71,8 +71,8 @@ func NewAuthService(_log *zap.Logger, _dbctx database.DbContext, _redis *redis.C
// FIXME: review possible problems due to a large pipeline request
pipe := _redis.Pipeline()
for _, guid := range guids {
if err := pipe.Set(ctx, fmt.Sprintf("session::%s::is_terminated", guid), true, 0); err != nil {
panic("Failed to cache terminated session: " + err.Err().Error())
if err := pipe.Set(ctx, fmt.Sprintf("session::%s::is_terminated", guid), true, 0).Err(); err != nil {
panic("Failed to cache terminated session: " + err.Error())
}
}
_log.Info("Cached terminated sessions' GUIDs in Redis", zap.Int("amount", len(guids)))
@@ -509,8 +509,23 @@ func (a *authServiceImpl) Login(request models.LoginRequest) (*models.LoginRespo
func (a *authServiceImpl) Refresh(request models.RefreshRequest) (*models.RefreshResponse, error) {
sessionInfo, err := a.ValidateToken(request.RefreshToken, enums.JwtAccessTokenType); if err != nil {
return nil, err
sessionInfo, err := a.ValidateToken(request.RefreshToken, enums.JwtRefreshTokenType); if err != nil {
if utils.ErrorIsOneOf(
err,
errs.ErrInvalidToken,
errs.ErrTokenExpired,
errs.ErrWrongTokenType,
errs.ErrSessionNotFound,
errs.ErrSessionTerminated,
) {
return nil, err
} else {
a.log.Error(
"Encountered an unexpected error while validating token",
zap.Error(err))
return nil, errs.ErrServerError
}
}
accessToken, refreshToken, err := utils.GenerateTokens(
@@ -558,7 +573,7 @@ func (a *authServiceImpl) ValidateToken(jwtToken string, tokenType enums.JwtToke
return nil, errs.ErrInvalidToken
}
if claims, ok := token.Claims.(*dto.UserClaims); ok && token.Valid {
claims, ok := token.Claims.(*dto.UserClaims); if ok && token.Valid {
if claims.Type != tokenType {
return nil, errs.ErrWrongTokenType
@@ -597,7 +612,7 @@ func (a *authServiceImpl) ValidateToken(jwtToken string, tokenType enums.JwtToke
if err := a.redis.Set(
ctx,
fmt.Sprintf("session::%s::is_terminated", claims.Session),
session.Terminated,
*session.Terminated,
time.Duration(8 * time.Hour), // XXX: magic number
).Err(); err != nil {
a.log.Error(
@@ -615,7 +630,14 @@ func (a *authServiceImpl) ValidateToken(jwtToken string, tokenType enums.JwtToke
return nil, errs.ErrSessionTerminated
}
}
return nil, errs.ErrNotImplemented
sessionInfo := dto.SessionInfo{
Username: claims.Username,
Session: claims.Session,
Role: claims.Role,
}
return &sessionInfo, nil
}
func (a *authServiceImpl) PasswordResetBegin(request models.PasswordResetBeginRequest) (bool, error) {