added logout

This commit is contained in:
Mephimeow
2026-06-12 10:18:04 +00:00
parent 130d5d5e3d
commit a26cd891e4
11 changed files with 244 additions and 5 deletions
+22 -1
View File
@@ -7,6 +7,8 @@ import (
"encoding/base64"
"errors"
"fmt"
"log"
"strings"
"time"
"go.mongodb.org/mongo-driver/v2/bson"
@@ -21,6 +23,7 @@ var (
ErrInvalidUserID = errors.New("invalid user ID")
ErrInvalidRefresh = errors.New("invalid refresh token")
ErrRefreshExpired = errors.New("refresh token expired")
ErrLogoutInvalid = errors.New("refresh token not found or already used")
)
type Service struct {
@@ -81,6 +84,7 @@ func (s *Service) issueTokenPair(ctx context.Context, user *User) (*AuthResponse
}
func (s *Service) Register(ctx context.Context, req RegisterRequest) (*UserPublic, error) {
req.Email = strings.ToLower(req.Email)
existing, err := s.repo.FindByEmail(ctx, req.Email)
if err != nil && !errors.Is(err, mongo.ErrNoDocuments) {
return nil, fmt.Errorf("failed to check existing user: %w", err)
@@ -109,6 +113,7 @@ func (s *Service) Register(ctx context.Context, req RegisterRequest) (*UserPubli
}
func (s *Service) Login(ctx context.Context, req LoginRequest) (*AuthResponse, error) {
req.Email = strings.ToLower(req.Email)
user, err := s.repo.FindByEmail(ctx, req.Email)
if err != nil {
if errors.Is(err, mongo.ErrNoDocuments) {
@@ -136,7 +141,9 @@ func (s *Service) Refresh(ctx context.Context, rawRefresh string) (*AuthResponse
}
if time.Now().UTC().After(doc.ExpiresAt) {
s.repo.DeleteRefreshToken(ctx, doc.ID)
if err := s.repo.DeleteRefreshToken(ctx, doc.ID); err != nil {
log.Printf("failed to cleanup expired refresh token: %v", err)
}
return nil, ErrRefreshExpired
}
@@ -152,6 +159,20 @@ func (s *Service) Refresh(ctx context.Context, rawRefresh string) (*AuthResponse
return s.issueTokenPair(ctx, user)
}
func (s *Service) Logout(ctx context.Context, rawRefresh string) error {
hash := sha256Hex(rawRefresh)
found, err := s.repo.DeleteRefreshTokenByHash(ctx, hash)
if err != nil {
return fmt.Errorf("failed to delete refresh token: %w", err)
}
if !found {
return ErrLogoutInvalid
}
return nil
}
func (s *Service) GetUserByID(ctx context.Context, userID string) (*UserPublic, error) {
id, err := bson.ObjectIDFromHex(userID)
if err != nil {