backend barebone done, big chunk of work done
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgconn"
|
||||
"github.com/jackc/pgerrcode"
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
// 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
|
||||
}
|
||||
Reference in New Issue
Block a user