package api import ( "errors" "net/http" "strings" "time" db "github.com/FernandoJVideira/simple_bank/internal/db/sqlc" "github.com/FernandoJVideira/simple_bank/internal/handlers/http/response" "github.com/FernandoJVideira/simple_bank/internal/service" "github.com/gin-gonic/gin" ) type renewAccessTokenRequest struct { RefreshToken string `json:"refresh_token" binding:"required"` } type renewAccessTokenResponse struct { AccessToken string `json:"access_token"` AccessTokenExpiresAt time.Time `json:"access_token_expires_at"` } func (s *Server) renewAccessToken(ctx *gin.Context) { var req renewAccessTokenRequest var resp response.JSONResponse if err := ctx.ShouldBindJSON(&req); err != nil { resp = response.JSONResponse{ Success: false, Error: err.Error(), } ctx.JSON(http.StatusBadRequest, resp) return } // Call auth service - all business logic moved there result, err := s.authService.RenewAccessToken(ctx, service.TokenRenewalRequest{ RefreshToken: req.RefreshToken, }) if err != nil { statusCode := http.StatusInternalServerError errMsg := err.Error() // Map service errors to HTTP codes if errors.Is(err, db.ErrRecordNotFound) || strings.Contains(errMsg, "session not found") { statusCode = http.StatusNotFound } else if strings.Contains(errMsg, "invalid") || strings.Contains(errMsg, "blocked") || strings.Contains(errMsg, "expired") || strings.Contains(errMsg, "mismatched") { statusCode = http.StatusUnauthorized } resp = response.JSONResponse{ Success: false, Error: errMsg, } ctx.JSON(statusCode, resp) return } resp = response.JSONResponse{ Success: true, Message: "Access token renewed successfully", Data: renewAccessTokenResponse{ AccessToken: result.AccessToken, AccessTokenExpiresAt: result.AccessTokenExpiresAt, }, } ctx.JSON(http.StatusOK, resp) }