77 lines
1.7 KiB
Go

package authmiddleware
import (
"context"
"fmt"
"net/http"
"time"
redisaccessor "legalgo-BE-go/internal/accessor/redis"
"legalgo-BE-go/internal/utilities/response"
"legalgo-BE-go/internal/utilities/utils"
"github.com/golang-jwt/jwt/v5"
)
const SessionHeader = "Authorization"
func Authorize() func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
tokenString, err := utils.GetToken(r)
if err != nil {
response.RespondWithError(w, r, err, "Invalid auth header")
return
}
spec, err := utils.GetTokenDetail(r)
token, err := ValidateToken(ctx, spec.Email)
if err != nil {
response.RespondWithError(w, r, err, err.Error())
return
}
isValid := token == tokenString
if !isValid {
response.RespondWithError(w, r, err, "invalid token")
return
}
next.ServeHTTP(w, r.WithContext(ctx))
})
}
}
func ValidateToken(ctx context.Context, id string) (string, error) {
redisClient := redisaccessor.Get()
redisToken, err := utils.GetTokenRedis(ctx, redisClient, id)
if err != nil {
return "", err
}
token, err := utils.ParseToken(redisToken)
if err != nil {
return "", fmt.Errorf("invalid token: %w", err)
}
// Check if the token is valid
if !token.Valid {
return "", fmt.Errorf("invalid token: token is not valid")
}
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
expirationTime := claims["exp"].(float64) // Expiration time in Unix timestamp format
if time.Unix(int64(expirationTime), 0).Before(time.Now()) {
return "", fmt.Errorf("token has expired")
}
}
return redisToken, nil
}