8c1e593686
- Introduced a new customer management domain, including entities, services, handlers, and forms for customer operations. - Added JWT-based user authorization settings in the configuration file for both user and customer management. - Updated API endpoints to reflect the new structure, including changes to health check and user management routes. - Enhanced Swagger documentation to include new customer-related endpoints and authorization details. - Refactored the Makefile to include a target for generating API documentation. - Removed obsolete documentation files to streamline the project structure.
85 lines
2.6 KiB
Go
85 lines
2.6 KiB
Go
package customer
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
"tm/pkg/response"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/labstack/echo/v4"
|
|
)
|
|
|
|
// AuthMiddleware validates JWT access tokens and extracts customer information
|
|
func (h *Handler) AuthMiddleware() echo.MiddlewareFunc {
|
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
|
return func(c echo.Context) error {
|
|
// Extract token from Authorization header
|
|
authHeader := c.Request().Header.Get("Authorization")
|
|
if authHeader == "" {
|
|
return response.Unauthorized(c, "Authorization header required")
|
|
}
|
|
|
|
// Check if it's a Bearer token
|
|
if !strings.HasPrefix(authHeader, "Bearer ") {
|
|
return response.Unauthorized(c, "Invalid authorization format. Use 'Bearer <token>'")
|
|
}
|
|
|
|
// Extract the token
|
|
tokenString := strings.TrimPrefix(authHeader, "Bearer ")
|
|
|
|
// Validate the access token using authorization service
|
|
validationResult, err := h.authService.ValidateAccessToken(tokenString)
|
|
if err != nil {
|
|
h.logger.Error("Token validation error", map[string]interface{}{
|
|
"error": err.Error(),
|
|
})
|
|
return response.Unauthorized(c, "Invalid token")
|
|
}
|
|
|
|
if !validationResult.Valid {
|
|
if validationResult.Expired {
|
|
return response.Unauthorized(c, "Token expired")
|
|
}
|
|
return response.Unauthorized(c, validationResult.Error)
|
|
}
|
|
|
|
// Extract customer information from token
|
|
customerID, err := uuid.Parse(validationResult.Claims.UserID)
|
|
if err != nil {
|
|
h.logger.Error("Failed to parse customer ID from token", map[string]interface{}{
|
|
"error": err.Error(),
|
|
})
|
|
return response.Unauthorized(c, "Invalid token format")
|
|
}
|
|
|
|
// Store customer information in context for handlers to use
|
|
c.Set("customer_id", customerID)
|
|
c.Set("customer_email", validationResult.Claims.Email)
|
|
c.Set("customer_role", validationResult.Claims.Role)
|
|
c.Set("company_id", validationResult.Claims.CompanyID)
|
|
c.Set("access_token", tokenString)
|
|
|
|
// Continue to next handler
|
|
return next(c)
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetCustomerIDFromContext extracts customer ID from Echo context
|
|
func GetCustomerIDFromContext(c echo.Context) (uuid.UUID, error) {
|
|
customerID, ok := c.Get("customer_id").(uuid.UUID)
|
|
if !ok {
|
|
return uuid.Nil, echo.NewHTTPError(http.StatusUnauthorized, "Customer ID not found in context")
|
|
}
|
|
return customerID, nil
|
|
}
|
|
|
|
// GetAccessTokenFromContext extracts access token from Echo context
|
|
func GetAccessTokenFromContext(c echo.Context) (string, error) {
|
|
accessToken, ok := c.Get("access_token").(string)
|
|
if !ok {
|
|
return "", echo.NewHTTPError(http.StatusUnauthorized, "Access token not found in context")
|
|
}
|
|
return accessToken, nil
|
|
}
|