Documentation
¶
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrSessionNotFound = errors.New("session not found")
ErrSessionNotFound is returned when a session token is not found in the store.
Functions ¶
func NewHandler ¶
func NewHandler(opts HandlerOpts) (http.Handler, error)
NewHandler creates an http.Handler that serves the REST API and embedded SPA. The handler should be mounted at the configured prefix in the user's HTTP mux.
Example:
h, err := ui.NewHandler(ui.HandlerOpts{
Pool: db,
Prefix: "/asynqpg",
})
mux.Handle("/asynqpg/", h)
Example ¶
package main
import (
"log"
"net/http"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
"github.com/yakser/asynqpg/ui"
)
func main() {
db, err := sqlx.Connect("postgres", "postgres://postgres:password@localhost:5432/asynqpg?sslmode=disable")
if err != nil {
log.Fatal(err)
}
handler, err := ui.NewHandler(ui.HandlerOpts{
Pool: db,
Prefix: "/asynqpg",
})
if err != nil {
log.Fatal(err)
}
http.Handle("/asynqpg/", handler)
}
Example (BasicAuth) ¶
package main
import (
"log"
"net/http"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
"github.com/yakser/asynqpg/ui"
)
func main() {
db, err := sqlx.Connect("postgres", "postgres://postgres:password@localhost:5432/asynqpg?sslmode=disable")
if err != nil {
log.Fatal(err)
}
handler, err := ui.NewHandler(ui.HandlerOpts{
Pool: db,
Prefix: "/asynqpg",
BasicAuth: &ui.BasicAuth{Username: "admin", Password: "secret"},
})
if err != nil {
log.Fatal(err)
}
http.Handle("/asynqpg/", handler)
}
Types ¶
type AuthProvider ¶
type AuthProvider interface {
// ID returns a unique identifier for this provider (e.g. "github", "google", "okta").
ID() string
// DisplayName returns a human-readable name shown on the login button.
DisplayName() string
// IconURL returns an optional URL/path for the provider icon. Empty string means no icon.
IconURL() string
// BeginAuth starts the OAuth flow by redirecting the user to the provider's authorization page.
// callbackURL is the full URL the provider should redirect back to after authorization.
// state is the CSRF token that must be included in the authorization request.
BeginAuth(w http.ResponseWriter, r *http.Request, callbackURL string, state string)
// CompleteAuth handles the OAuth callback. It exchanges the authorization code for tokens,
// fetches user information, and returns the authenticated user.
CompleteAuth(w http.ResponseWriter, r *http.Request) (*User, error)
}
AuthProvider defines the interface for OAuth/SSO authentication providers. Implementations handle the specific OAuth flow for a given identity provider.
type HandlerOpts ¶
type HandlerOpts struct {
// Pool is a database connection pool (required).
Pool asynqpg.Pool
// Prefix is the URL prefix for the handler (e.g. "/asynqpg").
// Defaults to "/".
Prefix string
// Logger is used for logging. If nil, slog.Default() is used.
Logger *slog.Logger
// BasicAuth enables optional HTTP Basic Authentication.
// If nil, no built-in authentication is applied.
// Mutually exclusive with AuthProviders.
BasicAuth *BasicAuth
// AuthProviders configures OAuth/SSO authentication providers.
// When set, session-based authentication is enabled and a login page is shown.
// Mutually exclusive with BasicAuth.
AuthProviders []AuthProvider
// SessionStore manages user sessions when AuthProviders is set.
// If nil and AuthProviders is non-empty, an in-memory store is used.
SessionStore SessionStore
// SessionMaxAge controls the maximum session duration.
// Defaults to 24 hours.
SessionMaxAge time.Duration
// SecureCookies controls the Secure flag on session cookies.
// Should be true in production (HTTPS). Defaults to false.
SecureCookies bool
// HidePayloadByDefault controls whether task payloads are hidden
// in list and detail responses. Users can still fetch payloads
// via the dedicated payload endpoint.
HidePayloadByDefault bool
// AllowedOrigins configures CORS allowed origins.
// If empty, only same-origin requests are allowed.
AllowedOrigins []string
}
HandlerOpts configures the UI handler.
type ListTasksParams ¶
type ListTasksParams struct {
Statuses []string
Types []string
IDs []int64
CreatedAfter *time.Time
CreatedBefore *time.Time
Limit int
Offset int
OrderBy string
OrderDir string
}
ListTasksParams contains parameters for listing tasks.
type MemorySessionStore ¶
type MemorySessionStore struct {
// contains filtered or unexported fields
}
MemorySessionStore is an in-memory SessionStore implementation. Sessions are lost on server restart. For production multi-server deployments, use a shared store.
func NewMemorySessionStore ¶
func NewMemorySessionStore() *MemorySessionStore
NewMemorySessionStore creates a new in-memory session store with a background cleanup goroutine that removes expired sessions.
func (*MemorySessionStore) Close ¶
func (s *MemorySessionStore) Close()
Close stops the background cleanup goroutine. Safe to call multiple times.
func (*MemorySessionStore) Delete ¶
func (s *MemorySessionStore) Delete(_ context.Context, token string) error
Delete removes a session by token. No error is returned if the token doesn't exist.
type SessionStore ¶
type SessionStore interface {
Get(ctx context.Context, token string) (*Session, error)
Save(ctx context.Context, session *Session) error
Delete(ctx context.Context, token string) error
}
SessionStore manages user sessions. The default in-memory implementation is suitable for single-server deployments. For multi-server setups, provide a shared store (e.g. PostgreSQL, Redis).
type TaskListItem ¶
type TaskListItem struct {
ID int64 `db:"id" json:"id"`
Type string `db:"type" json:"type"`
Status string `db:"status" json:"status"`
IdempotencyToken *string `db:"idempotency_token" json:"idempotency_token"`
Messages pq.StringArray `db:"messages" json:"messages"`
BlockedTill time.Time `db:"blocked_till" json:"blocked_till"`
AttemptsLeft int `db:"attempts_left" json:"attempts_left"`
AttemptsElapsed int `db:"attempts_elapsed" json:"attempts_elapsed"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
FinalizedAt *time.Time `db:"finalized_at" json:"finalized_at"`
AttemptedAt *time.Time `db:"attempted_at" json:"attempted_at"`
PayloadSize int64 `db:"payload_size" json:"payload_size"`
}
TaskListItem represents a task in the list view (without payload, with payload_size).
type TaskListResult ¶
type TaskListResult struct {
Tasks []TaskListItem `json:"tasks"`
Total int `json:"total"`
}
TaskListResult contains the list of tasks and total count matching filters.
type TaskTypeStat ¶
type TaskTypeStat struct {
Type string `db:"type" json:"type"`
Status string `db:"status" json:"status"`
Count int64 `db:"count" json:"count"`
}
TaskTypeStat represents a count of tasks grouped by type and status.
type User ¶
type User struct {
ID string `json:"id"`
Provider string `json:"provider"`
Name string `json:"name"`
AvatarURL string `json:"avatar_url"`
Email string `json:"email"`
}
User represents an authenticated user from any OAuth/SSO provider.
func UserFromContext ¶
UserFromContext returns the authenticated user from the request context, or nil if the request is not authenticated.