apikit

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Nov 11, 2026 License: AGPL-3.0 Imports: 25 Imported by: 0

Documentation

Index

Constants

View Source
const (
	SignatureHeader = "X-Webhook-Signature"
	TimestampHeader = "X-Webhook-Timestamp"
	EventIDHeader   = "X-Webhook-Id"
	EventTypeHeader = "X-Webhook-Event"
)
View Source
const MaxBodyBytes = 2 << 20

Variables

This section is empty.

Functions

func BearerToken

func BearerToken(r *http.Request) string

func DecodeCursor

func DecodeCursor(s string) (int64, error)

func DecodeJSON

func DecodeJSON(w http.ResponseWriter, r *http.Request, dst any) bool

func EncodeCursor

func EncodeCursor(id int64) string

func EnsureSQLiteSchema

func EnsureSQLiteSchema(db *sql.DB) error

func HashToken

func HashToken(raw string) string

func NewEventID

func NewEventID() (string, error)

func NewSafeClient

func NewSafeClient(allowHost func(host string) error) *http.Client

func NewSecret

func NewSecret() (string, error)

func NewToken

func NewToken(tokenPrefix string) (raw, hash, display string, err error)

func NormalizeScopes

func NormalizeScopes(requested []string, allowed []string) ([]string, error)

func ScopesInclude

func ScopesInclude(granted []string, want string) bool

func Sign

func Sign(secret string, ts int64, body []byte) string

func ValidateWebhookURL

func ValidateWebhookURL(raw string) error

func VerifySignature

func VerifySignature(secret, header string, ts int64, body []byte, tolerance time.Duration, now time.Time) bool

func WriteError

func WriteError(w http.ResponseWriter, status int, code, message string)

func WriteInternal

func WriteInternal(w http.ResponseWriter, what string, err error)

func WriteJSON

func WriteJSON(w http.ResponseWriter, status int, v any)

func WriteList

func WriteList(w http.ResponseWriter, data any, nextID int64)

Types

type Admin

type Admin struct {
	Keys          Store
	Hooks         WebhookStore
	Emitter       *Emitter
	AllowedScopes func() []string
	Events        []string
	TokenPrefix   string
	Owner         func(r *http.Request) int64
	Actor         func(r *http.Request) int64
	Audit         func(r *http.Request, action, detail string)
	Seal          func(string) (string, error)
	BaseURL       func(r *http.Request) string
	MaxKeys       int
	MaxHooks      int
}

func (*Admin) CreateKey

func (a *Admin) CreateKey(w http.ResponseWriter, r *http.Request)

func (*Admin) CreateWebhook

func (a *Admin) CreateWebhook(w http.ResponseWriter, r *http.Request)

func (*Admin) DeleteWebhook

func (a *Admin) DeleteWebhook(w http.ResponseWriter, r *http.Request)

func (*Admin) Deliveries

func (a *Admin) Deliveries(w http.ResponseWriter, r *http.Request)

func (*Admin) Overview

func (a *Admin) Overview(w http.ResponseWriter, r *http.Request)

func (*Admin) RevokeKey

func (a *Admin) RevokeKey(w http.ResponseWriter, r *http.Request)

func (*Admin) TestWebhook

func (a *Admin) TestWebhook(w http.ResponseWriter, r *http.Request)

func (*Admin) ToggleWebhook

func (a *Admin) ToggleWebhook(w http.ResponseWriter, r *http.Request)

type Authenticator

type Authenticator struct {
	// contains filtered or unexported fields
}

func New

func New(cfg Config) *Authenticator

func (*Authenticator) NewRegistry

func (a *Authenticator) NewRegistry(mount func(method, path string, h http.Handler)) *Registry

func (*Authenticator) Wrap

func (a *Authenticator) Wrap(scope string, h HandlerFunc) http.Handler

type Config

type Config struct {
	Store            Store
	Enabled          func() bool
	ClientIP         func(*http.Request) string
	OnWrite          func(k *Key, r *http.Request, status int)
	DefaultRateLimit int
	RateWindow       time.Duration
	FailLimit        int
	FailWindow       time.Duration
}

type Delivery

type Delivery struct {
	ID         int64
	WebhookID  int64
	EventID    string
	EventType  string
	Attempt    int
	StatusCode int
	OK         bool
	Error      string
	DurationMS int
	CreatedAt  time.Time
}

type DeliveryView

type DeliveryView struct {
	ID         int64     `json:"id"`
	EventID    string    `json:"event_id"`
	EventType  string    `json:"event_type"`
	Attempt    int       `json:"attempt"`
	StatusCode int       `json:"status_code"`
	OK         bool      `json:"ok"`
	Error      string    `json:"error"`
	DurationMS int       `json:"duration_ms"`
	CreatedAt  time.Time `json:"created_at"`
}

type Emitter

type Emitter struct {
	Hooks        WebhookStore
	Open         func(sealed string) (string, error)
	Client       *http.Client
	Queue        string
	DisableAfter int
	RetryDelays  []time.Duration
}

func (*Emitter) Emit

func (e *Emitter) Emit(owner int64, eventType string, data any)

func (*Emitter) Run

func (e *Emitter) Run(ctx context.Context)

func (*Emitter) SendTest

func (e *Emitter) SendTest(ctx context.Context, hook *Webhook) (Delivery, error)

type ErrorBody

type ErrorBody struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

type Event

type Event struct {
	ID        string    `json:"id"`
	Type      string    `json:"type"`
	CreatedAt time.Time `json:"created_at"`
	Data      any       `json:"data"`
}

type HandlerFunc

type HandlerFunc func(w http.ResponseWriter, r *http.Request, k *Key)

func Idempotent

func Idempotent(h HandlerFunc) HandlerFunc

type HookView

type HookView struct {
	ID        int64     `json:"id"`
	URL       string    `json:"url"`
	Events    []string  `json:"events"`
	Enabled   bool      `json:"enabled"`
	FailCount int       `json:"fail_count"`
	CreatedAt time.Time `json:"created_at"`
}

type Key

type Key struct {
	ID         int64
	Label      string
	Prefix     string
	Scopes     []string
	RateLimit  int
	CreatedBy  int64
	CreatedAt  time.Time
	LastUsedAt *time.Time
	LastUsedIP string
	ExpiresAt  *time.Time
	RevokedAt  *time.Time
}

func FromContext

func FromContext(ctx context.Context) (*Key, bool)

func (*Key) Expired

func (k *Key) Expired(now time.Time) bool

func (*Key) HasScope

func (k *Key) HasScope(scope string) bool

func (*Key) Revoked

func (k *Key) Revoked() bool

type KeyView

type KeyView struct {
	ID         int64      `json:"id"`
	Label      string     `json:"label"`
	Prefix     string     `json:"prefix"`
	Scopes     []string   `json:"scopes"`
	CreatedAt  time.Time  `json:"created_at"`
	LastUsedAt *time.Time `json:"last_used_at"`
	LastUsedIP string     `json:"last_used_ip"`
	ExpiresAt  *time.Time `json:"expires_at"`
	Revoked    bool       `json:"revoked"`
	Expired    bool       `json:"expired"`
}

type List

type List struct {
	Data       any    `json:"data"`
	NextCursor string `json:"next_cursor,omitempty"`
}

type Op

type Op struct {
	Method     string
	Path       string
	Scope      string
	Summary    string
	Tag        string
	Params     []Param
	Request    any
	Response   any
	Status     int
	List       bool
	Idempotent bool
}

type OverviewView

type OverviewView struct {
	Keys     []KeyView  `json:"keys"`
	Webhooks []HookView `json:"webhooks"`
	Scopes   []string   `json:"scopes"`
	Events   []string   `json:"events"`
	BaseURL  string     `json:"base_url"`
}

type Page

type Page struct {
	Limit  int
	Cursor int64
}

func ParsePage

func ParsePage(w http.ResponseWriter, r *http.Request, defaultLimit, maxLimit int) (Page, bool)

type Param

type Param struct {
	Name        string
	In          string
	Description string
	Required    bool
}

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

func (*Registry) Handle

func (g *Registry) Handle(op Op, h HandlerFunc)

func (*Registry) Scopes

func (g *Registry) Scopes() []string

func (*Registry) Spec

func (g *Registry) Spec(title, version string) ([]byte, error)

func (*Registry) SpecHandler

func (g *Registry) SpecHandler(title, version string) http.Handler

type SQLStore

type SQLStore struct {
	DB *sql.DB
}

func (*SQLStore) Insert

func (s *SQLStore) Insert(ctx context.Context, k Key, hash string) (int64, error)

func (*SQLStore) List

func (s *SQLStore) List(ctx context.Context, owner int64) ([]Key, error)

func (*SQLStore) Lookup

func (s *SQLStore) Lookup(ctx context.Context, hash string) (*Key, error)

func (*SQLStore) Revoke

func (s *SQLStore) Revoke(ctx context.Context, id int64, owner int64, now time.Time) (bool, error)

func (*SQLStore) Touch

func (s *SQLStore) Touch(ctx context.Context, id int64, ip string, now time.Time) error

type SQLWebhookStore

type SQLWebhookStore struct {
	DB *sql.DB
}

func (*SQLWebhookStore) AddDelivery

func (s *SQLWebhookStore) AddDelivery(ctx context.Context, d Delivery) error

func (*SQLWebhookStore) Create

func (s *SQLWebhookStore) Create(ctx context.Context, w Webhook) (int64, error)

func (*SQLWebhookStore) Delete

func (s *SQLWebhookStore) Delete(ctx context.Context, id, owner int64) (bool, error)

func (*SQLWebhookStore) Deliveries

func (s *SQLWebhookStore) Deliveries(ctx context.Context, webhookID, owner int64, limit int) ([]Delivery, error)

func (*SQLWebhookStore) Get

func (s *SQLWebhookStore) Get(ctx context.Context, id int64) (*Webhook, error)

func (*SQLWebhookStore) List

func (s *SQLWebhookStore) List(ctx context.Context, owner int64) ([]Webhook, error)

func (*SQLWebhookStore) ListFor

func (s *SQLWebhookStore) ListFor(ctx context.Context, owner int64, eventType string) ([]Webhook, error)

func (*SQLWebhookStore) Prune

func (s *SQLWebhookStore) Prune(ctx context.Context, olderThan time.Time) error

func (*SQLWebhookStore) RecordResult

func (s *SQLWebhookStore) RecordResult(ctx context.Context, id int64, ok bool, disableAfter int) (bool, error)

func (*SQLWebhookStore) SetEnabled

func (s *SQLWebhookStore) SetEnabled(ctx context.Context, id, owner int64, enabled bool) (bool, error)

type SendResult

type SendResult struct {
	StatusCode int
	OK         bool
	Error      string
	Duration   time.Duration
}

func Send

func Send(ctx context.Context, client *http.Client, target, secret, eventID, eventType string, body []byte) SendResult

type Store

type Store interface {
	Insert(ctx context.Context, k Key, hash string) (int64, error)
	Lookup(ctx context.Context, hash string) (*Key, error)
	Touch(ctx context.Context, id int64, ip string, now time.Time) error
	List(ctx context.Context, owner int64) ([]Key, error)
	Revoke(ctx context.Context, id int64, owner int64, now time.Time) (bool, error)
}

type Webhook

type Webhook struct {
	ID        int64
	OwnerID   int64
	URL       string
	SecretEnc string
	Events    []string
	Enabled   bool
	FailCount int
	CreatedAt time.Time
}

func (*Webhook) Wants

func (w *Webhook) Wants(eventType string) bool

type WebhookStore

type WebhookStore interface {
	Create(ctx context.Context, w Webhook) (int64, error)
	Get(ctx context.Context, id int64) (*Webhook, error)
	List(ctx context.Context, owner int64) ([]Webhook, error)
	ListFor(ctx context.Context, owner int64, eventType string) ([]Webhook, error)
	Delete(ctx context.Context, id, owner int64) (bool, error)
	SetEnabled(ctx context.Context, id, owner int64, enabled bool) (bool, error)
	RecordResult(ctx context.Context, id int64, ok bool, disableAfter int) (bool, error)
	AddDelivery(ctx context.Context, d Delivery) error
	Deliveries(ctx context.Context, webhookID, owner int64, limit int) ([]Delivery, error)
	Prune(ctx context.Context, olderThan time.Time) error
}

Jump to

Keyboard shortcuts

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