Documentation
¶
Overview ¶
Package postgres implements the panel's persistence layer on top of pgx.
Index ¶
- Variables
- type Attention
- type HostInput
- type NodeConnectedInfo
- type NodeHeartbeat
- type NodeInput
- type NodeSeries
- type Overview
- type PendingWarning
- type ProviderSpend
- type ProvisionedUser
- type ResponseRule
- type Session
- type Snapshot
- type SpendSummary
- type Store
- func (s *Store) APITokenByHash(ctx context.Context, hash string) (*domain.APIToken, error)
- func (s *Store) AddAllUsersToSquad(ctx context.Context, squadID string) (int64, error)
- func (s *Store) AddNodeTraffic(ctx context.Context, id string, bytes int64) error
- func (s *Store) AddUserTraffic(ctx context.Context, userID string, bytes int64) (used, limit int64, status domain.UserStatus, err error)
- func (s *Store) AdminByUUID(ctx context.Context, id string) (*domain.Admin, error)
- func (s *Store) AdminByUsername(ctx context.Context, username string) (*domain.Admin, error)
- func (s *Store) AllDevices(ctx context.Context, search string, limit int) ([]domain.Device, error)
- func (s *Store) ApplyNodeHeartbeat(ctx context.Context, id string, hb NodeHeartbeat) error
- func (s *Store) Attention(ctx context.Context, expiryDays, quotaPercent int) (*Attention, error)
- func (s *Store) Channel(ctx context.Context, id string) (*domain.NotificationChannel, error)
- func (s *Store) ChannelDeliveries(ctx context.Context, id string, limit int) ([]domain.NotificationDelivery, error)
- func (s *Store) ClaimExpiryWarnings(ctx context.Context, within time.Duration) ([]PendingWarning, error)
- func (s *Store) ClaimQuotaWarnings(ctx context.Context, percent int) ([]PendingWarning, error)
- func (s *Store) ClaimTOTPStep(ctx context.Context, id string, step int64) (bool, error)
- func (s *Store) Close()
- func (s *Store) ConfirmTOTP(ctx context.Context, id string, step int64, recoveryHashes []string) error
- func (s *Store) ConsumeRecoveryCode(ctx context.Context, id, digest string) (bool, error)
- func (s *Store) CountAdmins(ctx context.Context) (int, error)
- func (s *Store) CreateAPIToken(ctx context.Context, name, hash, preview, createdBy string, ...) (*domain.APIToken, error)
- func (s *Store) CreateAdmin(ctx context.Context, username, passwordHash string, role domain.AdminRole) (*domain.Admin, error)
- func (s *Store) CreateAnnouncement(ctx context.Context, a domain.Announcement) (*domain.Announcement, error)
- func (s *Store) CreateChannel(ctx context.Context, c domain.NotificationChannel) (*domain.NotificationChannel, error)
- func (s *Store) CreateHost(ctx context.Context, in HostInput) (*domain.Host, error)
- func (s *Store) CreateNode(ctx context.Context, in NodeInput, tokenHash, tokenPreview string) (*domain.Node, error)
- func (s *Store) CreateProfile(ctx context.Context, name string, kind domain.ProfileKind, ...) (*domain.ConfigProfile, error)
- func (s *Store) CreateRule(ctx context.Context, r ResponseRule) (*ResponseRule, error)
- func (s *Store) CreateSquad(ctx context.Context, name, info string, inboundIDs []string) (*domain.Squad, error)
- func (s *Store) CreateUser(ctx context.Context, in UserInput, sec UserSecrets) (*domain.User, error)
- func (s *Store) DeleteAPIToken(ctx context.Context, id string) error
- func (s *Store) DeleteAdmin(ctx context.Context, id string) error
- func (s *Store) DeleteAnnouncement(ctx context.Context, id string) error
- func (s *Store) DeleteChannel(ctx context.Context, id string) error
- func (s *Store) DeleteDevice(ctx context.Context, userID, hwid string) error
- func (s *Store) DeleteHost(ctx context.Context, id string) error
- func (s *Store) DeleteNode(ctx context.Context, id string) error
- func (s *Store) DeleteProfile(ctx context.Context, id string) error
- func (s *Store) DeleteRule(ctx context.Context, id string) error
- func (s *Store) DeleteSquad(ctx context.Context, id string) error
- func (s *Store) DeleteUser(ctx context.Context, id string) error
- func (s *Store) DisableTOTP(ctx context.Context, id string) error
- func (s *Store) EnabledChannels(ctx context.Context) ([]domain.NotificationChannel, error)
- func (s *Store) ExpireUsers(ctx context.Context) (int64, error)
- func (s *Store) ExportSnapshot(ctx context.Context) (*Snapshot, error)
- func (s *Store) Host(ctx context.Context, id string) (*domain.Host, error)
- func (s *Store) HostsForInbounds(ctx context.Context, inboundIDs []string) ([]domain.Host, error)
- func (s *Store) ImportSnapshot(ctx context.Context, snap *Snapshot, currentSchema string) error
- func (s *Store) Inbound(ctx context.Context, id string) (*domain.ConfigProfileInbound, error)
- func (s *Store) ListAPITokens(ctx context.Context) ([]domain.APIToken, error)
- func (s *Store) ListAdmins(ctx context.Context) ([]domain.Admin, error)
- func (s *Store) ListAnnouncements(ctx context.Context) ([]domain.Announcement, error)
- func (s *Store) ListChannels(ctx context.Context) ([]domain.NotificationChannel, error)
- func (s *Store) ListEvents(ctx context.Context, limit int, kind string) ([]domain.Event, error)
- func (s *Store) ListHosts(ctx context.Context) ([]domain.Host, error)
- func (s *Store) ListNodes(ctx context.Context) ([]domain.Node, error)
- func (s *Store) ListProfiles(ctx context.Context) ([]domain.ConfigProfile, error)
- func (s *Store) ListRules(ctx context.Context) ([]ResponseRule, error)
- func (s *Store) ListSquads(ctx context.Context) ([]domain.Squad, error)
- func (s *Store) ListUsers(ctx context.Context, f UserFilter) ([]domain.User, int, error)
- func (s *Store) LiveAnnouncements(ctx context.Context) ([]domain.Announcement, error)
- func (s *Store) LogEvent(ctx context.Context, kind domain.EventKind, actor, subject, message string, ...)
- func (s *Store) MarkAllNodesDisconnected(ctx context.Context) error
- func (s *Store) MarkNodeConnected(ctx context.Context, id string, info NodeConnectedInfo) error
- func (s *Store) MarkNodeDisconnected(ctx context.Context, id, reason string) error
- func (s *Store) MarkUserOnline(ctx context.Context, userID string)
- func (s *Store) MatchRule(ctx context.Context, userAgent string) (string, bool)
- func (s *Store) Migrate(ctx context.Context) error
- func (s *Store) Node(ctx context.Context, id string) (*domain.Node, error)
- func (s *Store) NodeMetrics(ctx context.Context, nodeID string, since time.Duration) ([]domain.NodeMetric, error)
- func (s *Store) NodeTrafficSeries(ctx context.Context, since time.Time, interval string) ([]NodeSeries, error)
- func (s *Store) NodesUsingProfile(ctx context.Context, profileID string) ([]domain.Node, error)
- func (s *Store) OnEvent(fn func(domain.Event))
- func (s *Store) Overview(ctx context.Context) (*Overview, error)
- func (s *Store) Pool() *pgxpool.Pool
- func (s *Store) PreviewRule(ctx context.Context, userAgent string) (string, bool)
- func (s *Store) Profile(ctx context.Context, id string) (*domain.ConfigProfile, error)
- func (s *Store) ProfileInbounds(ctx context.Context, profileID string) ([]domain.ConfigProfileInbound, error)
- func (s *Store) PruneDeliveries(ctx context.Context, keepFor time.Duration) error
- func (s *Store) PruneNodeMetrics(ctx context.Context, keepFor time.Duration) error
- func (s *Store) PruneSubscriptionRequests(ctx context.Context, keepFor time.Duration) error
- func (s *Store) PruneUsage(ctx context.Context, retention time.Duration) error
- func (s *Store) RecordDelivery(ctx context.Context, d domain.NotificationDelivery) error
- func (s *Store) RecordNodeMetric(ctx context.Context, nodeID string, m domain.NodeMetric) error
- func (s *Store) RecordNodeUsage(ctx context.Context, nodeID string, at time.Time, bytes int64) error
- func (s *Store) RecordSubscriptionRequest(ctx context.Context, r SubscriptionRequest)
- func (s *Store) RecordUserUsage(ctx context.Context, userID, nodeID string, at time.Time, bytes int64) error
- func (s *Store) RemoveAllUsersFromSquad(ctx context.Context, squadID string) (int64, error)
- func (s *Store) ReorderHosts(ctx context.Context, order []string) error
- func (s *Store) ReplaceRecoveryCodes(ctx context.Context, id string, hashes []string) error
- func (s *Store) ResetDevices(ctx context.Context, userID string) error
- func (s *Store) ResetDueUserTraffic(ctx context.Context) (int64, error)
- func (s *Store) ResetNodeTraffic(ctx context.Context, id string) error
- func (s *Store) ResetUserTraffic(ctx context.Context, id string) error
- func (s *Store) RevokeUserSubscription(ctx context.Context, ...) (*domain.User, error)
- func (s *Store) RollDuePayments(ctx context.Context) ([]domain.Node, error)
- func (s *Store) RotateNodeToken(ctx context.Context, id, tokenHash, tokenPreview string) error
- func (s *Store) SchemaVersion(ctx context.Context) (string, error)
- func (s *Store) Sessions(ctx context.Context, within time.Duration, limit int) ([]Session, error)
- func (s *Store) SetNodeConfigHash(ctx context.Context, id, hash string) error
- func (s *Store) SetNodeDisabled(ctx context.Context, id string, disabled bool) error
- func (s *Store) SetNodeHealth(ctx context.Context, id string, health domain.NodeHealth, message string) error
- func (s *Store) SetUserStatus(ctx context.Context, id string, status domain.UserStatus) error
- func (s *Store) SetWireGuardKeys(ctx context.Context, id, private, public string) error
- func (s *Store) Settings(ctx context.Context) (*domain.Settings, error)
- func (s *Store) Spend(ctx context.Context, defaultCurrency string) (*SpendSummary, error)
- func (s *Store) Squad(ctx context.Context, id string) (*domain.Squad, error)
- func (s *Store) StageTOTPSecret(ctx context.Context, id, secret string) error
- func (s *Store) SubscriptionRequests(ctx context.Context, userID string, failedOnly bool, limit int) ([]SubscriptionRequest, error)
- func (s *Store) TopUsers(ctx context.Context, since time.Time, limit int) ([]TopUser, error)
- func (s *Store) TotalTrafficSeries(ctx context.Context, since time.Time, interval string) ([]TrafficPoint, error)
- func (s *Store) TouchAdminLogin(ctx context.Context, id string)
- func (s *Store) TouchDevice(ctx context.Context, userID, hwid, userAgent, platform string, limit int) (allowed bool, count int, err error)
- func (s *Store) TouchSubscriptionOpen(ctx context.Context, id, userAgent string)
- func (s *Store) UpdateAdmin(ctx context.Context, id string, role domain.AdminRole, disabled bool) (*domain.Admin, error)
- func (s *Store) UpdateAdminPassword(ctx context.Context, id, passwordHash string) error
- func (s *Store) UpdateAnnouncement(ctx context.Context, id string, a domain.Announcement) (*domain.Announcement, error)
- func (s *Store) UpdateChannel(ctx context.Context, id string, c domain.NotificationChannel) (*domain.NotificationChannel, error)
- func (s *Store) UpdateHost(ctx context.Context, id string, in HostInput) (*domain.Host, error)
- func (s *Store) UpdateNode(ctx context.Context, id string, in NodeInput) (*domain.Node, error)
- func (s *Store) UpdateProfile(ctx context.Context, id, name string, kind domain.ProfileKind, ...) (*domain.ConfigProfile, error)
- func (s *Store) UpdateRule(ctx context.Context, id string, r ResponseRule) (*ResponseRule, error)
- func (s *Store) UpdateSettings(ctx context.Context, in domain.Settings) (*domain.Settings, error)
- func (s *Store) UpdateSquad(ctx context.Context, id, name, info string, inboundIDs []string) (*domain.Squad, error)
- func (s *Store) UpdateUser(ctx context.Context, id string, in UserInput) (*domain.User, error)
- func (s *Store) User(ctx context.Context, id string) (*domain.User, error)
- func (s *Store) UserByShortUUID(ctx context.Context, short string) (*domain.User, error)
- func (s *Store) UserBySubscription(ctx context.Context, subUUID string) (*domain.User, error)
- func (s *Store) UserDevices(ctx context.Context, userID string) ([]domain.Device, error)
- func (s *Store) UserInboundIDs(ctx context.Context, userID string) ([]string, error)
- func (s *Store) UserTags(ctx context.Context) ([]string, error)
- func (s *Store) UserTrafficSeries(ctx context.Context, userID string, since time.Time) ([]TrafficPoint, error)
- func (s *Store) UsersForNode(ctx context.Context, profileID string, inboundTags []string) ([]ProvisionedUser, error)
- func (s *Store) UsersForProfile(ctx context.Context, profileID string) ([]domain.User, error)
- func (s *Store) UsersMissingWireGuardKeys(ctx context.Context, limit int) ([]string, error)
- type SubscriptionRequest
- type TopUser
- type TrafficPoint
- type UpcomingBill
- type UserFilter
- type UserInput
- type UserSecrets
Constants ¶
This section is empty.
Variables ¶
var ErrConflict = errors.New("already exists")
ErrConflict is returned when a unique constraint rejects a write.
var ErrNotFound = errors.New("not found")
ErrNotFound is returned when a lookup by identity yields no row.
Functions ¶
This section is empty.
Types ¶
type Attention ¶ added in v0.9.0
type Attention struct {
NodesOffline int `json:"nodesOffline"`
NodesDegraded int `json:"nodesDegraded"`
NodesOverQuota int `json:"nodesOverQuota"`
UsersExpiring int `json:"usersExpiring"`
UsersNearQuota int `json:"usersNearQuota"`
UsersLimited int `json:"usersLimited"`
PaymentsDueSoon int `json:"paymentsDueSoon"`
Expiring []PendingWarning `json:"expiring"`
NearQuota []PendingWarning `json:"nearQuota"`
}
Attention is the short answer to "what needs me right now". Every figure is a count the dashboard can show without the operator opening four pages.
type NodeConnectedInfo ¶
type NodeConnectedInfo struct {
AgentVersion string
XrayVersion string
Hostname string
OS string
Arch string
Kernel string
CPUCount int
CPUModel string
TotalRAMBytes int64
ConfigHash string
}
NodeConnectedInfo is written when an agent completes its handshake.
type NodeHeartbeat ¶
type NodeInput ¶
type NodeInput struct {
Name string
Address string
CountryCode string
Description string
IsDisabled bool
ConfigProfileID *string
ActiveInboundTags []string
Consumption float64
TrafficLimitBytes int64
TrafficReset domain.TrafficResetStrategy
NotifyPercent int
ViewPosition int
Provider string
ProviderURL string
CostAmount float64
CostCurrency string
BillingCycle domain.BillingCycle
NextPaymentAt *time.Time
BillingNotes string
Tags []string
}
type NodeSeries ¶
type NodeSeries struct {
NodeID string `json:"nodeUuid"`
NodeName string `json:"nodeName"`
Points []TrafficPoint `json:"points"`
Total int64 `json:"totalBytes"`
}
NodeSeries is per-node traffic over a window, grouped for stacked charts.
type Overview ¶
type Overview struct {
UsersTotal int `json:"usersTotal"`
UsersActive int `json:"usersActive"`
UsersDisabled int `json:"usersDisabled"`
UsersLimited int `json:"usersLimited"`
UsersExpired int `json:"usersExpired"`
UsersOnline int `json:"usersOnline"`
NodesTotal int `json:"nodesTotal"`
NodesOnline int `json:"nodesOnline"`
NodesDisabled int `json:"nodesDisabled"`
HostsTotal int `json:"hostsTotal"`
SquadsTotal int `json:"squadsTotal"`
ProfilesTotal int `json:"profilesTotal"`
TrafficDay int64 `json:"trafficLast24hBytes"`
TrafficWeek int64 `json:"trafficLast7dBytes"`
TrafficMonth int64 `json:"trafficLast30dBytes"`
TrafficTotal int64 `json:"trafficTotalBytes"`
}
Overview is the aggregate shown on the dashboard landing page.
type PendingWarning ¶ added in v0.9.0
type PendingWarning struct {
UserID string `json:"userUuid"`
Username string `json:"username"`
// Days until expiry, for an expiry warning.
DaysLeft int `json:"daysLeft,omitempty"`
// Percent of quota used, for a quota warning.
Percent int `json:"percent,omitempty"`
// The figures behind the percent, so a message can name them.
UsedBytes int64 `json:"usedBytes,omitempty"`
LimitBytes int64 `json:"limitBytes,omitempty"`
}
PendingWarning is one subscriber the operator should hear about before the thing happens, rather than after.
type ProviderSpend ¶
type ProvisionedUser ¶
type ProvisionedUser struct {
UUID string
Username string
VlessUUID string
TrojanPassword string
SSPassword string
InboundTag string
WGPublicKey string
WGIndex int64
}
ProvisionedUser is the minimal projection the orchestrator needs to inject a client into an xray inbound.
type ResponseRule ¶ added in v0.5.0
type ResponseRule struct {
UUID string `json:"uuid"`
Name string `json:"name"`
MatchUA string `json:"matchUserAgent"`
Format string `json:"format"`
IsEnabled bool `json:"isEnabled"`
Priority int `json:"priority"`
Hits int64 `json:"hits"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
ResponseRule maps a client to the format it should be served.
type Session ¶ added in v0.6.0
type Session struct {
UserID string `json:"userUuid"`
Username string `json:"username"`
Status string `json:"status"`
NodeID string `json:"nodeUuid"`
NodeName string `json:"nodeName"`
Country string `json:"countryCode"`
Bytes int64 `json:"bytes"`
LastSeen time.Time `json:"lastSeen"`
OnlineAt *time.Time `json:"onlineAt"`
}
Session is a subscriber currently carrying traffic, and where.
This is assembled from what the panel already collects rather than from a per-connection feed: xray reports usage per user per node, and a user that moved bytes in the last few minutes is, for an operator's purposes, online there. It cannot show individual connections or their addresses — that would need the agent to report them — and the UI says so rather than implying a precision it does not have.
type Snapshot ¶ added in v0.3.0
type Snapshot struct {
// Schema is the last applied migration. A snapshot taken on a newer schema
// cannot be trusted to load into an older one: a column that did not exist
// yet would be dropped in silence, and the operator would find out when the
// feature that used it stopped working.
Schema string `json:"schema"`
TakenAt string `json:"takenAt"`
// Tables maps a table name to its rows, each row a column→value object.
// Column-keyed rather than positional so a snapshot stays readable, and so
// a reordered column list cannot silently shift values into wrong fields.
Tables map[string][]map[string]any `json:"tables"`
Counts map[string]int `json:"counts"`
// Types records each column's Postgres type, because JSON cannot tell a
// text[] from a jsonb array once both are a list of strings — and binding
// one as the other is rejected. Without this, restore guesses and fails on
// the first node row.
Types map[string]map[string]string `json:"types"`
}
Snapshot is a portable copy of a panel's configuration.
type SpendSummary ¶
type SpendSummary struct {
Currency string `json:"currency"`
MonthlyTotal float64 `json:"monthlyTotal"`
YearlyTotal float64 `json:"yearlyTotal"`
BilledNodes int `json:"billedNodes"`
CostPerTB float64 `json:"costPerTb"`
TrafficMonthTB float64 `json:"trafficThisMonthTb"`
ByProvider []ProviderSpend `json:"byProvider"`
Upcoming []UpcomingBill `json:"upcoming"`
Overdue int `json:"overdue"`
}
SpendSummary is the infrastructure cost picture shown on the dashboard.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
func (*Store) APITokenByHash ¶
APITokenByHash resolves a presented token and rejects expired ones.
func (*Store) AddAllUsersToSquad ¶
AddAllUsersToSquad and RemoveAllUsersFromSquad back the bulk membership actions offered on the squad page.
func (*Store) AddNodeTraffic ¶
func (*Store) AddUserTraffic ¶
func (s *Store) AddUserTraffic(ctx context.Context, userID string, bytes int64) (used, limit int64, status domain.UserStatus, err error)
AddUserTraffic charges usage to a user and returns the user's post-update state so the caller can enforce limits.
func (*Store) AdminByUUID ¶
func (*Store) AdminByUsername ¶
func (*Store) AllDevices ¶ added in v0.4.0
AllDevices powers the hardware-id inspector: every known device across every subscriber, rather than one user at a time.
func (*Store) ApplyNodeHeartbeat ¶
func (*Store) Attention ¶ added in v0.9.0
Attention counts without claiming anything — it is a read, and reading the dashboard must never consume a warning that has not been sent yet.
func (*Store) ChannelDeliveries ¶ added in v0.2.0
func (*Store) ClaimExpiryWarnings ¶ added in v0.9.0
func (s *Store) ClaimExpiryWarnings(ctx context.Context, within time.Duration) ([]PendingWarning, error)
ClaimExpiryWarnings returns the active users expiring within the window and marks them, so the caller can send one warning each.
The claim and the read are one statement: the maintenance loop runs every minute, and a select-then-update would send the same warning again on the next tick if anything failed in between. Marking by the expiry timestamp rather than a boolean means a rescheduled expiry earns a fresh warning, which is what an operator extending a subscription expects.
func (*Store) ClaimQuotaWarnings ¶ added in v0.9.0
ClaimQuotaWarnings returns the active users past the threshold and marks them at their current usage.
Marking with the usage figure rather than a flag is what makes a reset clear the warning: after a monthly rollover used_traffic drops below the mark, the condition `used > quota_warned_at` is true again on the next crossing, and the subscriber is warned once per cycle rather than once ever.
func (*Store) ClaimTOTPStep ¶ added in v0.7.0
ClaimTOTPStep records a time step as used, and reports whether it was still unused. The comparison and the write are one statement so two requests racing with the same code cannot both win.
func (*Store) ConfirmTOTP ¶ added in v0.7.0
func (s *Store) ConfirmTOTP(ctx context.Context, id string, step int64, recoveryHashes []string) error
ConfirmTOTP turns a staged secret on, once a code proved the app has it.
func (*Store) ConsumeRecoveryCode ¶ added in v0.7.0
ConsumeRecoveryCode removes one digest, and reports whether it was there. Removal is what makes a recovery code single-use.
func (*Store) CreateAPIToken ¶
func (*Store) CreateAdmin ¶
func (*Store) CreateAnnouncement ¶ added in v0.2.0
func (s *Store) CreateAnnouncement(ctx context.Context, a domain.Announcement) (*domain.Announcement, error)
func (*Store) CreateChannel ¶ added in v0.2.0
func (s *Store) CreateChannel(ctx context.Context, c domain.NotificationChannel) (*domain.NotificationChannel, error)
func (*Store) CreateHost ¶
func (*Store) CreateNode ¶
func (*Store) CreateProfile ¶
func (s *Store) CreateProfile(ctx context.Context, name string, kind domain.ProfileKind, config json.RawMessage, inbounds []domain.ConfigProfileInbound) (*domain.ConfigProfile, error)
func (*Store) CreateRule ¶ added in v0.5.0
func (s *Store) CreateRule(ctx context.Context, r ResponseRule) (*ResponseRule, error)
func (*Store) CreateSquad ¶
func (*Store) CreateUser ¶
func (*Store) DeleteAnnouncement ¶ added in v0.2.0
func (*Store) DeleteChannel ¶ added in v0.2.0
func (*Store) DeleteDevice ¶
func (*Store) DeleteRule ¶ added in v0.5.0
func (*Store) DisableTOTP ¶ added in v0.7.0
DisableTOTP clears the second factor and every recovery code with it, so a re-enrolment cannot be unlocked by a code from the previous one.
func (*Store) EnabledChannels ¶ added in v0.2.0
EnabledChannels is the dispatcher's read path, kept separate so a disabled channel costs nothing at delivery time.
func (*Store) ExpireUsers ¶
ExpireUsers flips past-due active users to EXPIRED and returns how many changed.
func (*Store) ExportSnapshot ¶ added in v0.3.0
ExportSnapshot reads every configuration table in one transaction, so the snapshot is a single consistent moment rather than a smear across the time it took to read.
func (*Store) HostsForInbounds ¶
HostsForInbounds returns the enabled hosts published by any of the inbounds, which is how a user's subscription is assembled from their squads.
func (*Store) ImportSnapshot ¶ added in v0.3.0
ImportSnapshot replaces the current configuration with the snapshot's.
This is destructive by design — a restore that merged would leave a panel in a state that is neither the backup nor what was there before, which is the worst outcome of the three. It runs in one transaction: either the whole snapshot lands or the database is untouched.
func (*Store) ListAPITokens ¶
func (*Store) ListAnnouncements ¶ added in v0.2.0
func (*Store) ListChannels ¶ added in v0.2.0
func (*Store) ListEvents ¶
func (*Store) ListProfiles ¶
func (*Store) ListRules ¶ added in v0.5.0
func (s *Store) ListRules(ctx context.Context) ([]ResponseRule, error)
func (*Store) LiveAnnouncements ¶ added in v0.2.0
LiveAnnouncements is what a subscriber sees. The window is filtered in SQL so the subscription path stays one query regardless of how many notices have accumulated over the life of the deployment.
func (*Store) MarkAllNodesDisconnected ¶
MarkAllNodesDisconnected resets liveness state on panel start, since no agent stream survives a restart.
func (*Store) MarkNodeConnected ¶
func (*Store) MarkNodeDisconnected ¶
func (*Store) MatchRule ¶ added in v0.5.0
MatchRule finds the first enabled rule whose pattern appears in the user agent, and counts the hit. Matching happens in SQL so the subscription path stays one round trip no matter how many rules exist.
func (*Store) NodeMetrics ¶ added in v0.2.0
func (*Store) NodeTrafficSeries ¶
func (*Store) NodesUsingProfile ¶
NodesUsingProfile lists the nodes bound to a profile, used to fan out config changes after the profile document is edited.
func (*Store) OnEvent ¶ added in v0.2.0
OnEvent registers the hook LogEvent calls. Passing nil detaches it.
func (*Store) PreviewRule ¶ added in v0.5.0
PreviewRule answers the same question as MatchRule without recording a hit, for the log line and for the operator's "what would this client get" probe.
func (*Store) ProfileInbounds ¶
func (s *Store) ProfileInbounds(ctx context.Context, profileID string) ([]domain.ConfigProfileInbound, error)
ProfileInbounds returns the inbounds of one profile, or of every profile when profileID is empty.
func (*Store) PruneDeliveries ¶ added in v0.2.0
PruneDeliveries keeps the log from growing without bound. A panel that notifies on every user update produces a lot of rows, and none of them are interesting a week later.
func (*Store) PruneNodeMetrics ¶ added in v0.2.0
func (*Store) PruneSubscriptionRequests ¶ added in v0.4.0
func (*Store) PruneUsage ¶
PruneUsage drops history older than the retention window.
func (*Store) RecordDelivery ¶ added in v0.2.0
RecordDelivery appends to the delivery log and rolls the denormalised health fields on the channel in the same statement pair, so the list view and the log can never disagree about the last outcome.
func (*Store) RecordNodeMetric ¶ added in v0.2.0
RecordNodeMetric stores one heartbeat sample. Samples are keyed by minute so a chatty agent cannot flood the table — a node heartbeating every few seconds would otherwise write tens of thousands of rows a day for a chart that is read at minute resolution anyway.
func (*Store) RecordNodeUsage ¶
func (*Store) RecordSubscriptionRequest ¶ added in v0.4.0
func (s *Store) RecordSubscriptionRequest(ctx context.Context, r SubscriptionRequest)
RecordSubscriptionRequest is fire-and-forget: a subscriber fetching their configuration must never fail because the audit write did.
func (*Store) RecordUserUsage ¶
func (*Store) RemoveAllUsersFromSquad ¶
func (*Store) ReorderHosts ¶
func (*Store) ReplaceRecoveryCodes ¶ added in v0.7.0
ReplaceRecoveryCodes swaps the whole set, for regenerating them.
func (*Store) ResetDueUserTraffic ¶
ResetDueUserTraffic applies the per-user reset strategy and returns how many counters were rolled over.
func (*Store) ResetNodeTraffic ¶
func (*Store) ResetUserTraffic ¶
func (*Store) RevokeUserSubscription ¶
func (*Store) RollDuePayments ¶
RollDuePayments moves past-due nodes onto their next billing date and reports which ones rolled over, so the operator gets one notice per cycle.
func (*Store) RotateNodeToken ¶
func (*Store) SchemaVersion ¶ added in v0.3.0
SchemaVersion is the last applied migration, used to stamp and to check snapshots.
func (*Store) Sessions ¶ added in v0.6.0
Sessions lists who has moved traffic within the window, newest first.
func (*Store) SetNodeConfigHash ¶
func (*Store) SetNodeDisabled ¶
func (*Store) SetNodeHealth ¶
func (*Store) SetUserStatus ¶
func (*Store) SetWireGuardKeys ¶ added in v0.10.0
SetWireGuardKeys fills in a key pair, but only where one is not already set — so two panels racing on the same database cannot hand the same subscriber two different keys, one of which would silently never connect.
func (*Store) Settings ¶
Settings returns the singleton settings row, creating it if a very old installation somehow lacks one.
func (*Store) Spend ¶
Spend aggregates node costs. Amounts are normalised to a monthly figure so nodes on different billing cycles can be compared and summed.
func (*Store) StageTOTPSecret ¶ added in v0.7.0
StageTOTPSecret stores a secret that is not in force yet. Enrolment is two steps on purpose: a secret written straight to the account would lock an operator out if they scanned the QR into an app that never actually worked.
func (*Store) SubscriptionRequests ¶ added in v0.4.0
func (s *Store) SubscriptionRequests(ctx context.Context, userID string, failedOnly bool, limit int) ([]SubscriptionRequest, error)
SubscriptionRequests lists recent fetches, newest first. userID narrows it to one subscriber; failed lists only the ones that did not resolve, which is where a revoked link still being polled shows up.
func (*Store) TotalTrafficSeries ¶
func (*Store) TouchDevice ¶
func (s *Store) TouchDevice(ctx context.Context, userID, hwid, userAgent, platform string, limit int) (allowed bool, count int, err error)
TouchDevice records a device against a subscription and reports whether the user is over their limit. A device already known never counts as new, so a returning client is not locked out by its own history.
func (*Store) TouchSubscriptionOpen ¶
func (*Store) UpdateAdmin ¶
func (*Store) UpdateAdminPassword ¶
func (*Store) UpdateAnnouncement ¶ added in v0.2.0
func (s *Store) UpdateAnnouncement(ctx context.Context, id string, a domain.Announcement) (*domain.Announcement, error)
func (*Store) UpdateChannel ¶ added in v0.2.0
func (s *Store) UpdateChannel(ctx context.Context, id string, c domain.NotificationChannel) (*domain.NotificationChannel, error)
func (*Store) UpdateHost ¶
func (*Store) UpdateNode ¶
func (*Store) UpdateProfile ¶
func (s *Store) UpdateProfile(ctx context.Context, id, name string, kind domain.ProfileKind, config json.RawMessage, inbounds []domain.ConfigProfileInbound) (*domain.ConfigProfile, error)
UpdateProfile rewrites the document and reconciles the extracted inbound rows. Inbounds are matched by tag so hosts and squads keep pointing at the same inbound identity across edits.
func (*Store) UpdateRule ¶ added in v0.5.0
func (s *Store) UpdateRule(ctx context.Context, id string, r ResponseRule) (*ResponseRule, error)
func (*Store) UpdateSettings ¶
func (*Store) UpdateSquad ¶
func (*Store) UpdateUser ¶
func (*Store) UserByShortUUID ¶
func (*Store) UserBySubscription ¶
func (*Store) UserDevices ¶
func (*Store) UserInboundIDs ¶
UserInboundIDs lists the inbound identities a user can reach through their squads.
func (*Store) UserTrafficSeries ¶
func (*Store) UsersForNode ¶
func (s *Store) UsersForNode(ctx context.Context, profileID string, inboundTags []string) ([]ProvisionedUser, error)
UsersForNode returns every (user, inbound tag) pair that should be present in the config of the given node: active users, in a squad, whose squad grants an inbound of the node's profile that the node actually serves.
func (*Store) UsersForProfile ¶ added in v0.11.0
func (*Store) UsersMissingWireGuardKeys ¶ added in v0.10.0
UsersMissingWireGuardKeys returns the users created before WireGuard existed, so the panel can give them a key pair without an operator touching anything.
type SubscriptionRequest ¶ added in v0.4.0
type SubscriptionRequest struct {
ID int64 `json:"id"`
UserID *string `json:"userUuid"`
Username string `json:"username"`
Token string `json:"token"`
IP string `json:"ip"`
UserAgent string `json:"userAgent"`
Format string `json:"format"`
Status int `json:"status"`
HWID string `json:"hwid"`
At time.Time `json:"at"`
}
SubscriptionRequest is one fetch of a subscription link.
type TopUser ¶
type TopUser struct {
UserID string `json:"uuid"`
Username string `json:"username"`
Bytes int64 `json:"bytes"`
}
TopUser is an entry of the "biggest consumers" dashboard widget.
type TrafficPoint ¶
TrafficPoint is one row of a time series returned to the dashboard.