0302-добавил куки и сломал десктоп авторизацию.

сложно поддерживать однояйцевых близнецов - desktop и TMA, подготовил к рефакторингу структуры
This commit is contained in:
2026-02-03 09:32:02 +03:00
parent 88620f3fb6
commit ea1e5bbf6a
14 changed files with 547 additions and 86 deletions

View File

@@ -1,7 +1,10 @@
package auth
import (
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"time"
"rmser/internal/domain/account"
@@ -22,9 +25,9 @@ type Claims struct {
// Service представляет сервис авторизации для desktop auth
type Service struct {
accountRepo account.Repository
wsServer *ws.Server
secretKey string
accountRepo account.Repository
wsServer *ws.Server
secretKey string
}
// NewService создает новый экземпляр сервиса авторизации
@@ -105,3 +108,76 @@ func (s *Service) generateJWTToken(user *account.User) (string, error) {
return tokenString, nil
}
// generateRefreshToken генерирует безопасный refresh токен
func (s *Service) generateRefreshToken() (string, error) {
b := make([]byte, 32)
if _, err := rand.Read(b); err != nil {
return "", err
}
return hex.EncodeToString(b), nil
}
// CreateWebSession создает новую веб-сессию для пользователя
func (s *Service) CreateWebSession(userID uuid.UUID, userAgent, ip string) (*account.Session, error) {
token, err := s.generateRefreshToken()
if err != nil {
logger.Log.Error("failed to generate refresh token", zap.Error(err))
return nil, err
}
session := &account.Session{
UserID: userID,
RefreshToken: token,
UserAgent: userAgent,
IP: ip,
ExpiresAt: time.Now().Add(7 * 24 * time.Hour),
}
if err := s.accountRepo.CreateSession(session); err != nil {
logger.Log.Error("failed to create session", zap.Error(err))
return nil, err
}
return session, nil
}
// ValidateAndExtendSession проверяет и продлевает сессию (sliding window)
func (s *Service) ValidateAndExtendSession(token string) (*account.User, error) {
session, err := s.accountRepo.GetSessionByToken(token)
if err != nil {
logger.Log.Error("failed to get session", zap.Error(err))
return nil, err
}
if session == nil {
return nil, fmt.Errorf("session not found")
}
if time.Now().After(session.ExpiresAt) {
// Сессия истекла, удаляем её
s.accountRepo.DeleteSession(token)
return nil, fmt.Errorf("session expired")
}
// Sliding expiration: обновляем expiresAt на 7 дней от текущего момента
newExpiry := time.Now().Add(7 * 24 * time.Hour)
if err := s.accountRepo.UpdateSessionExpiry(session.ID, newExpiry); err != nil {
logger.Log.Error("failed to update session expiry", zap.Error(err))
// Не критичная ошибка, продолжаем
}
// Получаем пользователя
user, err := s.accountRepo.GetUserByID(session.UserID)
if err != nil {
logger.Log.Error("failed to get user", zap.Error(err))
return nil, err
}
return user, nil
}
// DeleteSession удаляет сессию пользователя
func (s *Service) DeleteSession(token string) error {
return s.accountRepo.DeleteSession(token)
}