auth

package
v0.1.10 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 24, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrNoRefresh = errors.New("no refresh token; sign in via `codag auth login`")

ErrNoRefresh signals that no refresh credential is available — caller should surface a "run `codag auth login`" message instead of retrying.

Functions

func ClearTokens

func ClearTokens() error

ClearTokens wipes only the auth-related fields, preserving server URL and provider auth.

func EnsureFreshToken

func EnsureFreshToken() (string, error)

EnsureFreshToken returns a usable access token, refreshing if the current one is expired or unset. Cheap when nothing's expired: returns the cached token without any network I/O.

Callers (api.Client.do) invoke this both proactively (before sending, when ExpiresAt is in the past) and reactively (on a 401 response). The single-flight ensures a thundering-herd of MCP tool calls collapses to one refresh request.

func ForceRefresh

func ForceRefresh() (string, error)

ForceRefresh ignores the cached token and demands a fresh one. Used by api.Client when the server returns 401 for a token that *was* non-expired locally (e.g. clock skew, or server-side revocation).

func OpenBrowser

func OpenBrowser(url string)

OpenBrowser tries to launch the user's default browser. Returns no error if launch wasn't attempted (e.g. headless env) — callers always also print the URL so the user can paste it manually.

func SaveTokens

func SaveTokens(tr *TokenResponse) error

SaveTokens persists a TokenResponse into the on-disk config. Wraps config.Save so we don't lose other fields on disk.

func SetEndpoints

func SetEndpoints(e Endpoints)

SetEndpoints rewires the global refresher (for tests + for callers that want to point at a non-default API server at runtime).

func VerificationURL added in v0.1.6

func VerificationURL(dc *DeviceCode) string

Types

type DeviceCode

type DeviceCode struct {
	DeviceCode              string `json:"device_code"`
	UserCode                string `json:"user_code"`
	VerificationURI         string `json:"verification_uri"`                    // base
	VerificationURIComplete string `json:"verification_uri_complete,omitempty"` // with user_code prefilled
	ExpiresIn               int    `json:"expires_in"`
	Interval                int    `json:"interval"`
}

DeviceCode is the response from POST /oauth/device/code.

type Endpoints

type Endpoints struct {
	Server  string // e.g. https://api.codag.ai
	Console string // e.g. https://console.codag.ai
	HTTP    *http.Client
}

Endpoints centralizes the URLs we hit so tests can override.

func DefaultEndpoints

func DefaultEndpoints() Endpoints

DefaultEndpoints reads from config / env so callers don't have to.

func (Endpoints) PollToken

func (e Endpoints) PollToken(dc *DeviceCode) (*TokenResponse, error)

PollToken loops POST /oauth/token until the user completes the browser login (server returns 200) or `expires_in` seconds elapse.

The IETF device-flow spec defines two non-fatal "still pending" error codes: `authorization_pending` (keep polling) and `slow_down` (increase interval by 5s and keep polling). Anything else is fatal.

func (Endpoints) Refresh

func (e Endpoints) Refresh(refreshToken string) (*TokenResponse, error)

Refresh exchanges a refresh_token for a fresh access_token. Used both by the explicit `codag auth refresh` command and by the api.Client's transparent 401 retry.

func (Endpoints) RequestDeviceCode

func (e Endpoints) RequestDeviceCode() (*DeviceCode, error)

RequestDeviceCode kicks off a device-flow handshake.

func (Endpoints) Whoami

func (e Endpoints) Whoami(accessToken string) (map[string]any, error)

Whoami calls the authenticated /v1/whoami endpoint. Used to validate a freshly-issued token AND to power `codag whoami`.

type TokenResponse

type TokenResponse struct {
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
	TokenType    string `json:"token_type"`
	ExpiresIn    int    `json:"expires_in"` // seconds from now
	// Identity convenience fields the server may include so we can echo
	// "logged in as foo@bar / org=baz" without a separate /v1/whoami call.
	User string `json:"user,omitempty"`
	Org  string `json:"org,omitempty"`
	Role string `json:"role,omitempty"`
}

TokenResponse is the success response from POST /oauth/token.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL