Documentation
¶
Index ¶
- Constants
- Variables
- func ParseAuthPayload(data []byte) (cursor_account_sdk.Credentials, error)
- func PublicAccountID(a *cursor_account_sdk.Account) string
- type Attempt
- type LoginAttempts
- type SessionRecord
- type Store
- func (s *Store) Add(account *cursor_account_sdk.Account) error
- func (s *Store) CheckAccess(ctx context.Context, id string) (*cursor_account_sdk.Account, error)
- func (s *Store) EnsureAccess(ctx context.Context, id string) (*cursor_account_sdk.Account, error)
- func (s *Store) Find(id string) (*cursor_account_sdk.Account, error)
- func (s *Store) Get(id string) (*cursor_account_sdk.Account, error)
- func (s *Store) ImportAuthFile(path string) (*cursor_account_sdk.Account, error)
- func (s *Store) List() []*cursor_account_sdk.Account
- func (s *Store) LoginInteractive(ctx context.Context) (*cursor_account_sdk.Account, error)
- func (s *Store) Path() string
- func (s *Store) Remove(id string) (removed int, err error)
- func (s *Store) RemoveMatch(id string) (removed int, err error)
- func (s *Store) StartRefreshLoops(ctx context.Context, log *slog.Logger)
- func (s *Store) TestAndStore(ctx context.Context, creds cursor_account_sdk.Credentials) (*cursor_account_sdk.Account, bool, error)
- func (s *Store) Update(account *cursor_account_sdk.Account) error
- func (s *Store) UpsertBySubject(account *cursor_account_sdk.Account) (merged bool, err error)
- type StoreFile
Constants ¶
const ( AttemptPending = "pending" AttemptSucceeded = "succeeded" AttemptFailed = "failed" AttemptExpired = "expired" )
Variables ¶
var ( ErrMaxLoginAttempts = errors.New("too many open login attempts") ErrAttemptNotFound = errors.New("login attempt not found") )
Functions ¶
func ParseAuthPayload ¶ added in v1.4.0
func ParseAuthPayload(data []byte) (cursor_account_sdk.Credentials, error)
ParseAuthPayload accepts Cursor-style token JSON (access/refresh variants).
func PublicAccountID ¶ added in v1.4.0
func PublicAccountID(a *cursor_account_sdk.Account) string
PublicAccountID is the Control API account id: JWT subject when present, else store id.
Types ¶
type Attempt ¶ added in v1.4.0
type Attempt struct {
ID string
URL string
State string
AccountID string
Error string
CreatedAt time.Time
ResolvedAt time.Time
}
Attempt is a public snapshot of one Control API login attempt.
type LoginAttempts ¶ added in v1.4.0
type LoginAttempts struct {
Store *Store
Client *cursor_account_sdk.Client
Log *slog.Logger
Parent context.Context
MaxOpen int
AttemptTimeout time.Duration
Keep time.Duration
Poll func(ctx context.Context, uuid, verifier string) (cursor_account_sdk.Credentials, error)
Now func() time.Time
// contains filtered or unexported fields
}
LoginAttempts owns in-memory PKCE attempts for the Control API.
func (*LoginAttempts) Create ¶ added in v1.4.0
func (a *LoginAttempts) Create() (Attempt, error)
Create starts a new PKCE attempt. It is not an account.
func (*LoginAttempts) Delete ¶ added in v1.4.0
func (a *LoginAttempts) Delete(id string) error
Delete closes and forgets an attempt.
func (*LoginAttempts) Get ¶ added in v1.4.0
func (a *LoginAttempts) Get(id string) (Attempt, error)
Get returns one attempt by PKCE uuid.
func (*LoginAttempts) List ¶ added in v1.4.0
func (a *LoginAttempts) List() []Attempt
List returns open attempts and resolved ones still in the keep window.
func (*LoginAttempts) OpenCount ¶ added in v1.4.0
func (a *LoginAttempts) OpenCount() int
OpenCount is the number of unanswered attempts after a sweep.
func (*LoginAttempts) Stop ¶ added in v1.4.0
func (a *LoginAttempts) Stop()
Stop cancels every open attempt (serve shutdown).
type SessionRecord ¶
type SessionRecord struct {
ID string `json:"id"`
Label string `json:"label,omitempty"`
Subject string `json:"subject,omitempty"`
Tier string `json:"tier,omitempty"`
Access string `json:"access"`
Refresh string `json:"refresh"`
ExpiresAt int64 `json:"expires"`
LastRefreshAt int64 `json:"last_refresh_at,omitempty"`
CreatedAt int64 `json:"created_at,omitempty"`
UpdatedAt int64 `json:"updated_at,omitempty"`
}
SessionRecord is the JSON shape for one gateway session.
type Store ¶
Store is a mutex-protected multi-account session file.
func NewStore ¶
func NewStore(path string, client *cursor_account_sdk.Client) (*Store, error)
NewStore loads path if it exists (or starts as empty {"sessions":[]}), then always writes via the normal tmp+rename save so permission errors like "write auth store tmp: ..." surface at startup, not on first mutation.
func (*Store) Add ¶
func (s *Store) Add(account *cursor_account_sdk.Account) error
Add persists a new account session.
func (*Store) CheckAccess ¶
CheckAccess always validates against Cursor by refreshing, then persists.
func (*Store) EnsureAccess ¶
EnsureAccess refreshes the account if needed and persists the result.
func (*Store) Find ¶ added in v1.4.0
func (s *Store) Find(id string) (*cursor_account_sdk.Account, error)
Find returns one session by store id or JWT subject.
func (*Store) Get ¶
func (s *Store) Get(id string) (*cursor_account_sdk.Account, error)
Get returns one session by id.
func (*Store) ImportAuthFile ¶
func (s *Store) ImportAuthFile(path string) (*cursor_account_sdk.Account, error)
ImportAuthFile reads a Cursor/OpenCode-style auth JSON and merges into the store. Supports:
- { "accessToken", "refreshToken" }
- { "access", "refresh", "expires"? }
- { "cursor": { ... one of the above ... } }
- { "type":"oauth", "access", "refresh", "expires" }
func (*Store) List ¶
func (s *Store) List() []*cursor_account_sdk.Account
List returns a copy of all sessions as accounts.
func (*Store) LoginInteractive ¶
LoginInteractive runs PKCE login and stores the new session (merge by subject).
func (*Store) RemoveMatch ¶ added in v1.4.0
RemoveMatch deletes the session whose store id or JWT subject equals id.
func (*Store) StartRefreshLoops ¶
StartRefreshLoops runs boot fast-refresh then a staggered background loop. It blocks until ctx is cancelled.
func (*Store) TestAndStore ¶ added in v1.4.0
func (s *Store) TestAndStore(ctx context.Context, creds cursor_account_sdk.Credentials) (*cursor_account_sdk.Account, bool, error)
TestAndStore refreshes creds against Cursor, then upserts by subject.
func (*Store) Update ¶
func (s *Store) Update(account *cursor_account_sdk.Account) error
Update writes an existing session back to disk.
func (*Store) UpsertBySubject ¶
func (s *Store) UpsertBySubject(account *cursor_account_sdk.Account) (merged bool, err error)
UpsertBySubject replaces an existing session with the same JWT subject, or adds.
type StoreFile ¶
type StoreFile struct {
Sessions []SessionRecord `json:"sessions"`
}
StoreFile is the on-disk multi-account session document.