168 lines
4.4 KiB
Go
168 lines
4.4 KiB
Go
package db
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"log"
|
|
"time"
|
|
)
|
|
|
|
func (d *Database) SaveToken(userID int, userType string, token string, expiresAt time.Time) error {
|
|
// Valider le user_type
|
|
validTypes := map[string]bool{
|
|
"client": true,
|
|
"admin": true,
|
|
"cabine": true,
|
|
"livreur": true,
|
|
}
|
|
|
|
if !validTypes[userType] {
|
|
return fmt.Errorf("type d'utilisateur invalide: %s", userType)
|
|
}
|
|
|
|
query := `INSERT INTO jwt_tokens (user_id, user_type, token, date_save, date_fin)
|
|
VALUES ($1, $2, $3, CURRENT_TIMESTAMP, $4)`
|
|
|
|
_, err := d.Exec(query, userID, userType, token, expiresAt)
|
|
if 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
|
|
}
|
|
|
|
// IsTokenValid vérifie si un token existe et n'est pas expiré
|
|
func (d *Database) IsTokenValid(token string) (bool, error) {
|
|
query := `SELECT COUNT(*) FROM jwt_tokens
|
|
WHERE token = $1 AND date_fin > $2`
|
|
|
|
var count int
|
|
err := d.QueryRow(query, token, time.Now()).Scan(&count)
|
|
if err != nil {
|
|
return false, fmt.Errorf("erreur lors de la vérification du token: %w", err)
|
|
}
|
|
|
|
return count > 0, nil
|
|
}
|
|
|
|
// RevokeToken révoque un token (le supprime de la base)
|
|
func (d *Database) RevokeToken(token string) error {
|
|
query := `DELETE FROM jwt_tokens WHERE token = $1`
|
|
|
|
result, err := d.Exec(query, token)
|
|
if err != nil {
|
|
return fmt.Errorf("erreur lors de la révocation du token: %w", err)
|
|
}
|
|
|
|
rowsAffected, _ := result.RowsAffected()
|
|
if rowsAffected > 0 {
|
|
log.Printf("✅ Token révoqué avec succès")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RevokeAllUserTokens révoque tous les tokens d'un utilisateur
|
|
func (d *Database) RevokeAllUserTokens(userID int, userType string) error {
|
|
query := `DELETE FROM jwt_tokens WHERE user_id = $1 AND user_type = $2`
|
|
|
|
result, err := d.Exec(query, userID, userType)
|
|
if err != nil {
|
|
return fmt.Errorf("erreur lors de la révocation des tokens: %w", err)
|
|
}
|
|
|
|
rowsAffected, _ := result.RowsAffected()
|
|
log.Printf("✅ %d token(s) révoqué(s) pour %s ID: %d", rowsAffected, userType, userID)
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetUserActiveTokens récupère tous les tokens actifs d'un utilisateur
|
|
func (d *Database) GetUserActiveTokens(userID int, userType string) ([]map[string]interface{}, error) {
|
|
query := `SELECT id, token, date_save, date_fin
|
|
FROM jwt_tokens
|
|
WHERE user_id = $1 AND user_type = $2 AND date_fin > $3
|
|
ORDER BY date_save DESC`
|
|
|
|
rows, err := d.Query(query, userID, userType, time.Now())
|
|
if err != nil {
|
|
return nil, fmt.Errorf("erreur lors de la récupération des tokens: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
var tokens []map[string]interface{}
|
|
for rows.Next() {
|
|
var id int
|
|
var token string
|
|
var dateSave, dateFin time.Time
|
|
|
|
err := rows.Scan(&id, &token, &dateSave, &dateFin)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("erreur lors du scan: %w", err)
|
|
}
|
|
|
|
tokens = append(tokens, map[string]interface{}{
|
|
"id": id,
|
|
"token": token[:20] + "...", // Tronquer pour la sécurité
|
|
"date_save": dateSave,
|
|
"date_fin": dateFin,
|
|
"user_type": userType,
|
|
})
|
|
}
|
|
|
|
return tokens, nil
|
|
}
|
|
|
|
func (d *Database) GetTokenInfo(token string) (map[string]interface{}, error) {
|
|
query := `SELECT user_id, user_type, date_save, date_fin
|
|
FROM jwt_tokens
|
|
WHERE token = $1 AND date_fin > $2`
|
|
|
|
var userID int
|
|
var userType string
|
|
var dateSave, dateFin time.Time
|
|
|
|
err := d.QueryRow(query, token, time.Now()).Scan(&userID, &userType, &dateSave, &dateFin)
|
|
if err == sql.ErrNoRows {
|
|
return nil, fmt.Errorf("token non trouvé ou expiré")
|
|
}
|
|
if err != nil {
|
|
return nil, fmt.Errorf("erreur lors de la récupération des infos du token: %w", err)
|
|
}
|
|
|
|
tokenInfo := map[string]interface{}{
|
|
"user_id": userID,
|
|
"user_type": userType,
|
|
"date_save": dateSave,
|
|
"date_fin": dateFin,
|
|
}
|
|
|
|
return tokenInfo, nil
|
|
}
|
|
|
|
func (d *Database) CountActiveTokensByType() (map[string]int, error) {
|
|
query := `SELECT user_type, COUNT(*) as count
|
|
FROM jwt_tokens
|
|
WHERE date_fin > $1
|
|
GROUP BY user_type`
|
|
|
|
rows, err := d.Query(query, time.Now())
|
|
if err != nil {
|
|
return nil, fmt.Errorf("erreur lors du comptage des tokens: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
counts := make(map[string]int)
|
|
for rows.Next() {
|
|
var userType string
|
|
var count int
|
|
if err := rows.Scan(&userType, &count); err != nil {
|
|
return nil, err
|
|
}
|
|
counts[userType] = count
|
|
}
|
|
|
|
return counts, nil
|
|
}
|