1package backend23import (4 "context"5 "errors"6 "time"78 "github.com/charmbracelet/soft-serve/pkg/db"9 "github.com/charmbracelet/soft-serve/pkg/proto"10)1112// CreateAccessToken creates an access token for user.13func (b *Backend) CreateAccessToken(ctx context.Context, user proto.User, name string, expiresAt time.Time) (string, error) {14 token := GenerateToken()15 tokenHash := HashToken(token)1617 if err := b.db.TransactionContext(ctx, func(tx *db.Tx) error {18 _, err := b.store.CreateAccessToken(ctx, tx, name, user.ID(), tokenHash, expiresAt)19 if err != nil {20 return db.WrapError(err)21 }2223 return nil24 }); err != nil {25 return "", err26 }2728 return token, nil29}3031// DeleteAccessToken deletes an access token for a user.32func (b *Backend) DeleteAccessToken(ctx context.Context, user proto.User, id int64) error {33 err := b.db.TransactionContext(ctx, func(tx *db.Tx) error {34 _, err := b.store.GetAccessToken(ctx, tx, id)35 if err != nil {36 return db.WrapError(err)37 }3839 if err := b.store.DeleteAccessTokenForUser(ctx, tx, user.ID(), id); err != nil {40 return db.WrapError(err)41 }42 return nil43 })44 if err != nil {45 if errors.Is(err, db.ErrRecordNotFound) {46 return proto.ErrTokenNotFound47 }48 return err49 }5051 return nil52}5354// ListAccessTokens lists access tokens for a user.55func (b *Backend) ListAccessTokens(ctx context.Context, user proto.User) ([]proto.AccessToken, error) {56 accessTokens, err := b.store.GetAccessTokensByUserID(ctx, b.db, user.ID())57 if err != nil {58 return nil, db.WrapError(err)59 }6061 var tokens []proto.AccessToken62 for _, t := range accessTokens {63 token := proto.AccessToken{64 ID: t.ID,65 Name: t.Name,66 TokenHash: t.Token,67 UserID: t.UserID,68 CreatedAt: t.CreatedAt,69 }70 if t.ExpiresAt.Valid {71 token.ExpiresAt = t.ExpiresAt.Time72 }7374 tokens = append(tokens, token)75 }7677 return tokens, nil78}