Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 0 additions & 98 deletions cmd/entire/cli/api/auth_tokens.go

This file was deleted.

26 changes: 11 additions & 15 deletions cmd/entire/cli/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,20 @@ type Client struct {
httpClient *http.Client
baseURL string

// authTokensPath is the base path for the auth-tokens management
// endpoints (list / revoke). Set via WithAuthTokensPath when the
// client targets the auth host. Empty for data-API-only clients;
// auth-tokens methods error out if called against an empty path.
authTokensPath string
// sessionsPath is the base path for entire-core's login-session
// endpoints (list / revoke / current). Set via WithSessionsPath when the
// client targets the auth host; empty otherwise, and the session methods
// error out if called against an empty path.
sessionsPath string
}

// WithAuthTokensPath sets the base path used by ListTokens,
// RevokeCurrentToken, and RevokeToken. The path is supplied by the
// auth shim from auth.CurrentProvider().AuthTokensPath, which is the
// single source of truth for provider-version routing — the api
// package no longer reads ENTIRE_AUTH_PROVIDER_VERSION itself.
// WithSessionsPath sets the base path used by ListSessions,
// RevokeCurrentSession, and RevokeSession. Returns the receiver for chaining
// at construction:
//
// Returns the receiver for chaining at construction:
//
// c := api.NewClientWithBaseURL(token, base).WithAuthTokensPath(p)
func (c *Client) WithAuthTokensPath(path string) *Client {
c.authTokensPath = path
// c := api.NewClientWithBaseURL(token, base).WithSessionsPath(p)
func (c *Client) WithSessionsPath(path string) *Client {
c.sessionsPath = path
return c
}

Expand Down
100 changes: 100 additions & 0 deletions cmd/entire/cli/api/sessions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package api

import (
"context"
"errors"
"fmt"
"net/url"
)

// Session is a single active login session — an OAuth refresh-token family —
// returned by entire-core's session endpoint. One is created per
// `entire login`, across all of a user's devices. Plaintext token values are
// never returned by the server, only metadata. (The list envelope's wire key
// is "tokens"; the rows are sessions.)
type Session struct {
ID string `json:"id"`
UserID string `json:"user_id"`
Name string `json:"name"`
Scope string `json:"scope"`
ExpiresAt string `json:"expires_at"`
LastUsedAt *string `json:"last_used_at"`
CreatedAt string `json:"created_at"`
}

// SessionsResponse is the envelope returned by the list endpoint.
type SessionsResponse struct {
Sessions []Session `json:"tokens"`
}

// errSessionsPathUnset surfaces when a session method is called on a Client
// that wasn't given a base path. Construct via
// NewClientWithBaseURL(...).WithSessionsPath(...).
var errSessionsPathUnset = errors.New("api: sessions path is unset (call (*Client).WithSessionsPath before list/revoke)")

func (c *Client) sessionsBasePath() (string, error) {
if c.sessionsPath == "" {
return "", errSessionsPathUnset
}
return c.sessionsPath, nil
}

// ListSessions returns the authenticated user's active login sessions.
func (c *Client) ListSessions(ctx context.Context) ([]Session, error) {
base, err := c.sessionsBasePath()
if err != nil {
return nil, fmt.Errorf("list sessions: %w", err)
}
resp, err := c.Get(ctx, base)
if err != nil {
return nil, fmt.Errorf("list sessions: %w", err)
}
defer resp.Body.Close()

if err := CheckResponse(resp); err != nil {
return nil, fmt.Errorf("list sessions: %w", err)
}

var out SessionsResponse
if err := DecodeJSON(resp, &out); err != nil {
return nil, fmt.Errorf("list sessions: %w", err)
}
return out.Sessions, nil
}

// RevokeCurrentSession revokes the login session this client is authenticating
// with (the family the current bearer belongs to).
func (c *Client) RevokeCurrentSession(ctx context.Context) error {
base, err := c.sessionsBasePath()
if err != nil {
return fmt.Errorf("revoke current session: %w", err)
}
resp, err := c.Delete(ctx, base+"/current")
if err != nil {
return fmt.Errorf("revoke current session: %w", err)
}
defer resp.Body.Close()

if err := CheckResponse(resp); err != nil {
return fmt.Errorf("revoke current session: %w", err)
}
return nil
}

// RevokeSession revokes the login session with the given id.
func (c *Client) RevokeSession(ctx context.Context, id string) error {
base, err := c.sessionsBasePath()
if err != nil {
return fmt.Errorf("revoke session %s: %w", id, err)
}
resp, err := c.Delete(ctx, base+"/"+url.PathEscape(id))
if err != nil {
return fmt.Errorf("revoke session %s: %w", id, err)
}
defer resp.Body.Close()

if err := CheckResponse(resp); err != nil {
return fmt.Errorf("revoke session %s: %w", id, err)
}
return nil
}
Loading
Loading