models

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Jun 26, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package models defines the GORM persistence schema for led.

Every user-facing entity (Link, Mailbox, Domain) carries a Note field — a free-text remark that upstream wr.do does not support. DNS records get their note through the provider's native comment field (see dnsprovider).

All tables carry an OwnerID (constant 1 in single-user mode) so the move to multi-tenant later needs no schema migration.

Index

Constants

View Source
const SingleUserID uint = 1

Variables

This section is empty.

Functions

func AllModels

func AllModels() []any

AllModels lists every model for AutoMigrate.

func HashToken

func HashToken(raw string) string

HashToken returns the SHA-256 hex digest of a raw API token. The stored hash is what bearer requests are matched against.

Types

type Domain

type Domain struct {
	ID                uint   `gorm:"primaryKey" json:"id"`
	OwnerID           uint   `gorm:"index;default:1" json:"-"`
	Name              string `gorm:"uniqueIndex;size:255" json:"name"`
	ProviderAccountID uint   `gorm:"index" json:"providerAccountId"`
	ZoneID            string `gorm:"size:64" json:"zoneId"`
	Note              string `gorm:"type:text" json:"note"`
	ForMail           bool   `json:"forMail"` // accept inbound email for this domain
	ForLink           bool   `json:"forLink"` // serve short links on this domain
	// LinkHosts are the hostnames short links are served on for this zone — one
	// or more, typically subdomains like "go.example.com", "s.example.com".
	// MailHosts are the hostnames mailboxes live under (e.g. "example.com",
	// "mail.example.com"). An empty list with the matching toggle on falls back
	// to the apex Name.
	LinkHosts HostList  `gorm:"type:text" json:"linkHosts"`
	MailHosts HostList  `gorm:"type:text" json:"mailHosts"`
	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
}

Domain is a domain managed by led, tied to a DNS provider account.

func (Domain) EffectiveLinkHosts

func (d Domain) EffectiveLinkHosts() []string

EffectiveLinkHosts returns the enabled hostnames short links are served on.

func (Domain) EffectiveMailHosts

func (d Domain) EffectiveMailHosts() []string

EffectiveMailHosts returns the enabled hostnames mailboxes live under.

type Email

type Email struct {
	ID          uint      `gorm:"primaryKey" json:"id"`
	MailboxID   uint      `gorm:"index" json:"mailboxId"`
	MessageID   string    `gorm:"size:512;index" json:"messageId"`
	FromAddr    string    `gorm:"size:320" json:"from"`
	ToAddr      string    `gorm:"size:320" json:"to"`
	Subject     string    `gorm:"type:text" json:"subject"`
	Text        string    `gorm:"type:text" json:"text"`
	HTML        string    `gorm:"type:text" json:"html"`
	Raw         []byte    `json:"-"` // GORM maps []byte to blob (sqlite) / bytea (postgres)
	Read        bool      `gorm:"default:false" json:"read"`
	Note        string    `gorm:"type:text" json:"note"`
	Attachments string    `gorm:"type:text" json:"attachments"` // JSON array of {filename,contentType,size}
	ReceivedAt  time.Time `gorm:"index" json:"receivedAt"`
}

Email is a received message stored for a mailbox.

type Host

type Host struct {
	Host    string `json:"host"`
	Enabled bool   `json:"enabled"`
}

Host is a single hostname with an enable flag, so a host can be temporarily disabled without losing its configuration.

type HostList

type HostList []Host

HostList is a []Host persisted as a JSON text column. Scan is backward compatible with the older format that stored a plain []string (each such host is treated as enabled).

func (HostList) Blocks

func (l HostList) Blocks(host string) bool

Blocks reports whether host is listed but every listing is disabled — i.e. traffic to it should be dropped. An unlisted host is not blocked.

func (HostList) Enabled

func (l HostList) Enabled() []string

Enabled returns only the hostnames that are currently enabled.

func (*HostList) Scan

func (l *HostList) Scan(v any) error

func (HostList) Value

func (l HostList) Value() (driver.Value, error)
type Link struct {
	ID           uint         `gorm:"primaryKey" json:"id"`
	OwnerID      uint         `gorm:"index;default:1" json:"-"`
	Host         string       `gorm:"size:255;index:idx_host_slug,unique" json:"host"` // empty = default/any host
	Slug         string       `gorm:"size:255;index:idx_host_slug,unique" json:"slug"`
	Target       string       `gorm:"type:text" json:"target"`
	Password     string       `gorm:"size:255" json:"-"` // optional; presence exposed via HasPassword
	Note         string       `gorm:"type:text" json:"note"`
	Title        string       `gorm:"size:255" json:"title"`
	Tags         string       `gorm:"size:512" json:"tags"` // comma-separated tags
	ExpiresAt    *time.Time   `json:"expiresAt"`
	ExpiredURL   string       `gorm:"type:text" json:"expiredUrl"` // redirect here once expired / over limit (dub-style)
	ClickLimit   int64        `gorm:"default:0" json:"clickLimit"` // 0 = unlimited
	Archived     bool         `gorm:"default:false;index" json:"archived"`
	Enabled      bool         `gorm:"default:true" json:"enabled"`
	RoutingRules RoutingRules `gorm:"type:text" json:"routingRules"`
	Clicks       int64        `gorm:"default:0" json:"clicks"`
	CreatedAt    time.Time    `json:"createdAt"`
	UpdatedAt    time.Time    `json:"updatedAt"`
}

Link is a short link. (Host, Slug) is unique.

type LinkEvent

type LinkEvent struct {
	ID        uint      `gorm:"primaryKey" json:"id"`
	LinkID    uint      `gorm:"index" json:"linkId"`
	CreatedAt time.Time `gorm:"index" json:"createdAt"`
	IP        string    `gorm:"size:64" json:"ip"`
	Country   string    `gorm:"size:64" json:"country"`
	Region    string    `gorm:"size:128" json:"region"`
	City      string    `gorm:"size:128" json:"city"`
	Device    string    `gorm:"size:32" json:"device"`
	Browser   string    `gorm:"size:64" json:"browser"`
	OS        string    `gorm:"size:64" json:"os"`
	Referer   string    `gorm:"type:text" json:"referer"`
	UA        string    `gorm:"type:text" json:"ua"`
	IsBot     bool      `gorm:"default:false;index" json:"isBot"`
}

LinkEvent is a single click, recorded asynchronously for basic analytics.

type Mailbox

type Mailbox struct {
	ID        uint      `gorm:"primaryKey" json:"id"`
	OwnerID   uint      `gorm:"index;default:1" json:"-"`
	Address   string    `gorm:"uniqueIndex;size:320" json:"address"`
	Note      string    `gorm:"type:text" json:"note"`
	Enabled   bool      `gorm:"default:true" json:"enabled"`
	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
	Unread    int64     `gorm:"-" json:"unread"` // computed, not persisted
}

Mailbox is an address that can receive mail (prefix@domain).

type NotificationChannel

type NotificationChannel struct {
	ID        uint      `json:"id" gorm:"primaryKey"`
	OwnerID   uint      `json:"-" gorm:"index"`
	Name      string    `json:"name"`
	Type      string    `json:"type"`                    // e.g. "telegram", "webhook"
	Config    string    `json:"config" gorm:"type:text"` // JSON object
	Enabled   bool      `json:"enabled" gorm:"default:true"`
	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
}

type ProviderAccount

type ProviderAccount struct {
	ID        uint      `gorm:"primaryKey" json:"id"`
	OwnerID   uint      `gorm:"index;default:1" json:"-"`
	Name      string    `gorm:"size:255" json:"name"` // e.g. "Personal Cloudflare"
	Type      string    `gorm:"size:32" json:"type"`  // e.g. "cloudflare", "dnspod"
	Config    string    `gorm:"type:text" json:"-"`   // AES-GCM encrypted credentials JSON
	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
}

ProviderAccount represents a DNS provider configuration (e.g. Cloudflare) containing the credentials needed to manage zones.

type RoutingRule

type RoutingRule struct {
	Type   string `json:"type"`   // "geo", "device", "os", "language"
	Match  string `json:"match"`  // e.g. "US", "Mobile", "iOS", "zh-CN"
	Target string `json:"target"` // redirect URL if matched
}

type RoutingRules

type RoutingRules []RoutingRule

func (*RoutingRules) Scan

func (r *RoutingRules) Scan(v any) error

func (RoutingRules) Value

func (r RoutingRules) Value() (driver.Value, error)

type SMTPSender

type SMTPSender struct {
	ID        uint      `json:"id" gorm:"primaryKey"`
	OwnerID   uint      `json:"-" gorm:"index"`
	Name      string    `json:"name"`
	Host      string    `json:"host"`
	Port      int       `json:"port"`
	User      string    `json:"user"`
	Pass      string    `json:"-"`
	FromEmail string    `json:"fromEmail"`
	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
}

type SSHKey

type SSHKey struct {
	ID        uint      `json:"id" gorm:"primaryKey"`
	OwnerID   uint      `json:"-" gorm:"index;default:1"`
	Name      string    `json:"name" gorm:"size:255"`
	Type      string    `json:"type" gorm:"size:32"` // e.g. "rsa", "ed25519", "imported"
	Key       string    `json:"-" gorm:"type:text"`  // AES-GCM encrypted private key
	PubKey    string    `json:"pubKey" gorm:"type:text"`
	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
}

type Setting

type Setting struct {
	Key   string `gorm:"primaryKey;size:64" json:"key"`
	Value string `gorm:"type:text" json:"value"`
}

Setting is a single key/value runtime configuration entry (reserved slugs, reserved mailbox prefixes, a global Cloudflare token, …).

type StringList

type StringList []string

StringList is a []string persisted as a JSON text column, portable across SQLite and Postgres.

func (*StringList) Scan

func (s *StringList) Scan(v any) error

func (StringList) Value

func (s StringList) Value() (driver.Value, error)

type Token

type Token struct {
	ID         uint       `gorm:"primaryKey" json:"id"`
	OwnerID    uint       `gorm:"index;default:1" json:"-"`
	Name       string     `gorm:"size:255" json:"name"`
	Hash       string     `gorm:"uniqueIndex;size:64" json:"-"` // SHA-256 hex of the raw token
	Prefix     string     `gorm:"size:32" json:"prefix"`        // e.g. "led_abcd" for identification
	Note       string     `gorm:"type:text" json:"note"`
	LastUsedAt *time.Time `json:"lastUsedAt"`
	CreatedAt  time.Time  `json:"createdAt"`
}

Token is an API token for the open API. Only the SHA-256 hash of the raw token is stored; the raw token is shown once at creation time. Prefix keeps a short, non-secret identifier for the dashboard list.

type VPS

type VPS struct {
	ID          uint       `json:"id" gorm:"primaryKey"`
	OwnerID     uint       `json:"-" gorm:"index;default:1"`
	Name        string     `json:"name" gorm:"size:255"`
	IP          string     `json:"ip" gorm:"size:64"`
	Port        int        `json:"port" gorm:"default:22"`
	User        string     `json:"user" gorm:"size:64;default:'root'"`
	SSHKeyID    uint       `json:"sshKeyId" gorm:"index"`
	Status      string     `json:"status" gorm:"size:32;default:'unknown'"` // "online", "offline", "unknown"
	FailCount   int        `json:"failCount" gorm:"default:0"`
	LastChecked *time.Time `json:"lastChecked"`
	CreatedAt   time.Time  `json:"createdAt"`
	UpdatedAt   time.Time  `json:"updatedAt"`
}

Jump to

Keyboard shortcuts

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