Files
2026-03-28 17:00:00 +01:00

128 lines
3.7 KiB
Go

package db
import (
"fmt"
"log"
"time"
"gorm.io/gorm"
)
type jwtToken struct {
ID int `gorm:"primaryKey;autoIncrement"`
UserID int `gorm:"column:user_id;index"`
UserType string `gorm:"column:user_type"`
Token string `gorm:"column:token;uniqueIndex"`
DateSave time.Time `gorm:"column:date_save;autoCreateTime"`
DateFin time.Time `gorm:"column:date_fin"`
}
func (jwtToken) TableName() string { return "jwt_tokens" }
var validTokenTypes = map[string]bool{
"client": true, "admin": true, "cabine": true, "livreur": true,
}
func (d *Database) SaveToken(userID int, userType string, token string, expiresAt time.Time) error {
if !validTokenTypes[userType] {
return fmt.Errorf("type d'utilisateur invalide: %s", userType)
}
t := jwtToken{UserID: userID, UserType: userType, Token: token, DateFin: expiresAt}
if err := d.GDB.Create(&t).Error; err != nil {
return fmt.Errorf("erreur lors de l'enregistrement du token: %w", err)
}
log.Printf("✅ Token enregistré pour %s ID: %d", userType, userID)
return nil
}
func (d *Database) IsTokenValid(token string) (bool, error) {
var count int64
err := d.GDB.Model(&jwtToken{}).
Where("token = ? AND date_fin > ?", token, time.Now()).
Count(&count).Error
return count > 0, err
}
func (d *Database) RevokeToken(token string) error {
result := d.GDB.Where("token = ?", token).Delete(&jwtToken{})
if result.Error != nil {
return fmt.Errorf("erreur lors de la révocation du token: %w", result.Error)
}
if result.RowsAffected > 0 {
log.Printf("✅ Token révoqué avec succès")
}
return nil
}
func (d *Database) RevokeAllUserTokens(userID int, userType string) error {
result := d.GDB.Where("user_id = ? AND user_type = ?", userID, userType).Delete(&jwtToken{})
if result.Error != nil {
return fmt.Errorf("erreur lors de la révocation des tokens: %w", result.Error)
}
log.Printf("✅ %d token(s) révoqué(s) pour %s ID: %d", result.RowsAffected, userType, userID)
return nil
}
func (d *Database) GetUserActiveTokens(userID int, userType string) ([]map[string]any, error) {
var tokens []jwtToken
err := d.GDB.Where("user_id = ? AND user_type = ? AND date_fin > ?", userID, userType, time.Now()).
Order("date_save DESC").Find(&tokens).Error
if err != nil {
return nil, fmt.Errorf("erreur lors de la récupération des tokens: %w", err)
}
result := make([]map[string]any, len(tokens))
for i, t := range tokens {
truncated := t.Token
if len(truncated) > 20 {
truncated = truncated[:20] + "..."
}
result[i] = map[string]any{
"id": t.ID,
"token": truncated,
"date_save": t.DateSave,
"date_fin": t.DateFin,
"user_type": t.UserType,
}
}
return result, nil
}
func (d *Database) GetTokenInfo(token string) (map[string]any, error) {
var t jwtToken
err := d.GDB.Where("token = ? AND date_fin > ?", token, time.Now()).First(&t).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, fmt.Errorf("token non trouvé ou expiré")
}
return nil, fmt.Errorf("erreur lors de la récupération des infos du token: %w", err)
}
return map[string]any{
"user_id": t.UserID,
"user_type": t.UserType,
"date_save": t.DateSave,
"date_fin": t.DateFin,
}, nil
}
func (d *Database) CountActiveTokensByType() (map[string]int, error) {
type row struct {
UserType string
Count int
}
var rows []row
err := d.GDB.Model(&jwtToken{}).
Select("user_type, COUNT(*) as count").
Where("date_fin > ?", time.Now()).
Group("user_type").
Scan(&rows).Error
if err != nil {
return nil, fmt.Errorf("erreur lors du comptage des tokens: %w", err)
}
counts := make(map[string]int, len(rows))
for _, r := range rows {
counts[r.UserType] = r.Count
}
return counts, nil
}