all repos

onasty @ 5829b75f12cc97ef4168ea070d1c81a6e2f1dccc

a one-time notes service

onasty/internal/store/psql/sessionrepo/sessionrepo.go (view raw)

Smirnov Oleksandr Smirnov Oleksandr
ss2316544@gmail.com
chore(golangci-lint): upgrade config (#14)..., 1 year ago
1
package sessionrepo
2
3
import (
4
	"context"
5
	"errors"
6
	"time"
7
8
	"github.com/gofrs/uuid/v5"
9
	"github.com/henvic/pgq"
10
	"github.com/jackc/pgx/v5"
11
	"github.com/olexsmir/onasty/internal/models"
12
	"github.com/olexsmir/onasty/internal/store/psqlutil"
13
)
14
15
type SessionStorer interface {
16
	Set(ctx context.Context, usedID uuid.UUID, refreshToken string, expiresAt time.Time) error
17
	GetUserIDByRefreshToken(ctx context.Context, refreshToken string) (uuid.UUID, error)
18
	Update(ctx context.Context, userID uuid.UUID, refreshToken string, newRefreshToken string) error
19
	Delete(ctx context.Context, userID uuid.UUID) error
20
}
21
22
var _ SessionStorer = (*SessionRepo)(nil)
23
24
type SessionRepo struct {
25
	db *psqlutil.DB
26
}
27
28
func New(db *psqlutil.DB) *SessionRepo {
29
	return &SessionRepo{
30
		db: db,
31
	}
32
}
33
34
func (s *SessionRepo) Set(
35
	ctx context.Context,
36
	userID uuid.UUID,
37
	refreshToken string,
38
	expiresAt time.Time,
39
) error {
40
	query, args, err := pgq.
41
		Insert("sessions").
42
		Columns("user_id", "refresh_token", "expires_at").
43
		Values(userID, refreshToken, expiresAt).
44
		SQL()
45
	if err != nil {
46
		return err
47
	}
48
49
	_, err = s.db.Exec(ctx, query, args...)
50
	return err
51
}
52
53
func (s *SessionRepo) Update(
54
	ctx context.Context,
55
	userID uuid.UUID,
56
	refreshToken string,
57
	newRefreshToken string,
58
) error {
59
	query := `--sql
60
update sessions
61
set refresh_token = $1
62
where
63
  user_id = $2
64
  and refresh_token = $3
65
  -- and expires_at < now()
66
`
67
68
	res, err := s.db.Exec(ctx, query, newRefreshToken, userID, refreshToken)
69
	if res.RowsAffected() != 1 {
70
		return models.ErrSessionNotFound
71
	}
72
73
	return err
74
}
75
76
func (s *SessionRepo) GetUserIDByRefreshToken(
77
	ctx context.Context,
78
	refreshToken string,
79
) (uuid.UUID, error) {
80
	query, args, err := pgq.
81
		Select("user_id").
82
		From("sessions").
83
		Where(pgq.Eq{"refresh_token": refreshToken}).
84
		SQL()
85
	if err != nil {
86
		return uuid.UUID{}, err
87
	}
88
89
	var userID uuid.UUID
90
	err = s.db.QueryRow(ctx, query, args...).Scan(&userID)
91
	if errors.Is(err, pgx.ErrNoRows) {
92
		return uuid.UUID{}, models.ErrUserNotFound
93
	}
94
95
	return userID, err
96
}
97
98
func (s *SessionRepo) Delete(ctx context.Context, userID uuid.UUID) error {
99
	query := `--sql
100
DELETE FROM sessions
101
WHERE user_id = $1
102
`
103
104
	_, err := s.db.Exec(ctx, query, userID)
105
	return err
106
}