Files
Messenger/server/internal/store/sessions.go
T
vantablackTea f381b4cd14
CI / Go (build + vet + test) (push) Canceled after 0s
CI / Web (build + lint) (push) Canceled after 0s
fix: дубликат username теперь дает 500
2026-09-27 20:19:26 +03:00

68 lines
2.1 KiB
Go

package store
import (
"context"
"errors"
"time"
"github.com/jackc/pgerrcode"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"
)
// CreateSession adds a new session record.
func (s *Store) CreateSession(ctx context.Context, userID int64, refreshHash, userAgent, ip string, expiresAt time.Time) (*Session, error) {
var sess Session
err := s.pool.QueryRow(ctx, `
INSERT INTO sessions(user_id, refresh_hash, user_agent, ip, expires_at)
VALUES($1, $2, $3, $4, $5)
RETURNING id, user_id, refresh_hash, expires_at, revoked_at, created_at, user_agent, ip
`, userID, refreshHash, userAgent, ip, expiresAt).Scan(
&sess.ID, &sess.UserID, &sess.RefreshHash, &sess.ExpiresAt,
&sess.RevokedAt, &sess.CreatedAt, &sess.UserAgent, &sess.IP,
)
if err != nil {
var pgErr *pgconn.PgError
if errors.As(err, &pgErr) && pgErr.Code == pgerrcode.UniqueViolation {
return nil, ErrDuplicate
}
return nil, err
}
return &sess, nil
}
// GetSessionByRefreshHash returns a session by its refresh hash or ErrNotFound.
func (s *Store) GetSessionByRefreshHash(ctx context.Context, hash string) (*Session, error) {
var sess Session
err := s.pool.QueryRow(ctx, `
SELECT id, user_id, refresh_hash, expires_at, revoked_at, created_at, user_agent, ip
FROM sessions WHERE refresh_hash=$1
`, hash).Scan(
&sess.ID, &sess.UserID, &sess.RefreshHash, &sess.ExpiresAt,
&sess.RevokedAt, &sess.CreatedAt, &sess.UserAgent, &sess.IP,
)
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return nil, ErrNotFound
}
return nil, err
}
return &sess, nil
}
// RevokeSession sets revoked_at to now() for the given session ID.
func (s *Store) RevokeSession(ctx context.Context, id int64) error {
_, err := s.pool.Exec(ctx, `
UPDATE sessions SET revoked_at = now() WHERE id = $1
`, id)
return err
}
// RevokeAllSessions revokes all sessions for a given user.
func (s *Store) RevokeAllSessions(ctx context.Context, userID int64) error {
_, err := s.pool.Exec(ctx, `
UPDATE sessions SET revoked_at = now() WHERE user_id = $1
`, userID)
return err
}