128 lines
3.7 KiB
Go
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
|
|
}
|