chore: refacto
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"database/sql"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"gestion/models"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MigrateAddTelegramColumns ajoute les colonnes telegram_chat_id si elles n'existent pas
|
||||
func (d *Database) MigrateAddTelegramColumns() {
|
||||
migrations := []string{
|
||||
`ALTER TABLE clients ADD COLUMN IF NOT EXISTS telegram_chat_id BIGINT`,
|
||||
`ALTER TABLE users ADD COLUMN IF NOT EXISTS telegram_chat_id BIGINT`,
|
||||
}
|
||||
for _, q := range migrations {
|
||||
if _, err := d.Exec(q); err != nil {
|
||||
log.Printf("⚠️ [TELEGRAM_MIGRATION] %v", err)
|
||||
}
|
||||
}
|
||||
log.Println("✅ [TELEGRAM] Colonnes telegram_chat_id vérifiées")
|
||||
}
|
||||
|
||||
const linkTokenTTL = 10 * time.Minute
|
||||
|
||||
// GenerateLinkToken crée un token aléatoire sécurisé et le stocke dans Redis (10 min)
|
||||
func GenerateLinkToken(username, role string) (string, error) {
|
||||
raw := make([]byte, 16)
|
||||
if _, err := rand.Read(raw); err != nil {
|
||||
return "", fmt.Errorf("génération token: %w", err)
|
||||
}
|
||||
token := hex.EncodeToString(raw)
|
||||
|
||||
data := models.TelegramLinkData{Username: username, Role: role}
|
||||
val, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
key := fmt.Sprintf("telegram:link:%s", token)
|
||||
if err := Redis.Set(RedisCtx, key, val, linkTokenTTL).Err(); err != nil {
|
||||
return "", fmt.Errorf("Redis SET: %w", err)
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
// ValidateAndConsumeLinkToken valide le token, retourne les données, puis le supprime
|
||||
func ValidateAndConsumeLinkToken(token string) (username, role string, err error) {
|
||||
key := fmt.Sprintf("telegram:link:%s", token)
|
||||
|
||||
val, err := Redis.Get(RedisCtx, key).Bytes()
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("token invalide ou expiré")
|
||||
}
|
||||
|
||||
var data models.TelegramLinkData
|
||||
if err := json.Unmarshal(val, &data); err != nil {
|
||||
return "", "", fmt.Errorf("données corrompues")
|
||||
}
|
||||
|
||||
Redis.Del(RedisCtx, key)
|
||||
|
||||
return data.Username, data.Role, nil
|
||||
}
|
||||
|
||||
func (d *Database) SaveClientTelegramChatID(username string, chatID int64) error {
|
||||
_, err := d.Exec(`UPDATE clients SET telegram_chat_id = $1 WHERE username = $2`, chatID, username)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Database) GetClientTelegramChatID(username string) (int64, bool, error) {
|
||||
var chatID sql.NullInt64
|
||||
err := d.QueryRow(`SELECT telegram_chat_id FROM clients WHERE username = $1`, username).Scan(&chatID)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
return chatID.Int64, chatID.Valid, nil
|
||||
}
|
||||
|
||||
func (d *Database) DeleteClientTelegramChatID(username string) error {
|
||||
_, err := d.Exec(`UPDATE clients SET telegram_chat_id = NULL WHERE username = $1`, username)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Database) SaveUserTelegramChatID(username string, chatID int64) error {
|
||||
_, err := d.Exec(`UPDATE users SET telegram_chat_id = $1 WHERE username = $2`, chatID, username)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Database) GetUserTelegramChatID(username string) (int64, bool, error) {
|
||||
var chatID sql.NullInt64
|
||||
err := d.QueryRow(`SELECT telegram_chat_id FROM users WHERE username = $1`, username).Scan(&chatID)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
return chatID.Int64, chatID.Valid, nil
|
||||
}
|
||||
|
||||
func (d *Database) DeleteUserTelegramChatID(username string) error {
|
||||
_, err := d.Exec(`UPDATE users SET telegram_chat_id = NULL WHERE username = $1`, username)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetUserByTelegramChatID retrouve un utilisateur (clients + users) par chat_id
|
||||
func (d *Database) GetUserByTelegramChatID(chatID int64) (username, role string, err error) {
|
||||
err = d.QueryRow(`SELECT username FROM clients WHERE telegram_chat_id = $1`, chatID).Scan(&username)
|
||||
if err == nil {
|
||||
return username, "client", nil
|
||||
}
|
||||
|
||||
err = d.QueryRow(`SELECT username, role FROM users WHERE telegram_chat_id = $1`, chatID).Scan(&username, &role)
|
||||
if err == nil {
|
||||
return username, role, nil
|
||||
}
|
||||
|
||||
return "", "", fmt.Errorf("aucun compte lié à ce chat_id")
|
||||
}
|
||||
Reference in New Issue
Block a user