Files
WarpBox/lib/metastore/sessions.go

80 lines
1.7 KiB
Go
Raw Normal View History

package metastore
import (
"errors"
"fmt"
"strings"
"time"
"github.com/dgraph-io/badger/v4"
"warpbox/lib/helpers"
)
func (store *Store) CreateSession(userID string, ttl time.Duration) (Session, error) {
userID = strings.TrimSpace(userID)
if userID == "" {
return Session{}, fmt.Errorf("%w: user id cannot be empty", ErrInvalid)
}
if ttl <= 0 {
return Session{}, fmt.Errorf("%w: session ttl must be positive", ErrInvalid)
}
token, err := helpers.RandomHexID(32)
if err != nil {
return Session{}, err
}
csrfToken, err := helpers.RandomHexID(32)
if err != nil {
return Session{}, err
}
now := time.Now().UTC()
session := Session{
Token: token,
CSRFToken: csrfToken,
UserID: userID,
CreatedAt: now,
ExpiresAt: now.Add(ttl),
}
err = store.db.Update(func(txn *badger.Txn) error {
return putJSON(txn, sessionKey(token), session)
})
return session, err
}
func (store *Store) GetSession(token string) (Session, bool, error) {
token = strings.TrimSpace(token)
if token == "" {
return Session{}, false, nil
}
var session Session
err := store.db.View(func(txn *badger.Txn) error {
return getJSON(txn, sessionKey(token), &session)
})
if errors.Is(err, ErrNotFound) {
return Session{}, false, nil
}
if err != nil {
return Session{}, false, err
}
if time.Now().UTC().After(session.ExpiresAt) {
_ = store.DeleteSession(token)
return Session{}, false, nil
}
return session, true, nil
}
func (store *Store) DeleteSession(token string) error {
return store.db.Update(func(txn *badger.Txn) error {
err := txn.Delete(sessionKey(token))
if errors.Is(err, badger.ErrKeyNotFound) {
return nil
}
return err
})
}
func sessionKey(token string) []byte {
return []byte("session/" + strings.TrimSpace(token))
}