Documentation
¶
Overview ¶
Package store is AgentTransfer's persistence layer: one SQLite database plus a sha256-addressed, refcounted blob directory. It also owns the instance ed25519 identity and writes the signed receipt chain.
Index ¶
- Variables
- func NewID(prefix string) string
- func NewLinkToken() string
- func VolumeStats(path string) (free, total int64, err error)
- type Agent
- type Attachment
- type ConnectInstance
- type ConnectMail
- type File
- type Link
- type Message
- type StorageConsumer
- type Store
- func (s *Store) AddFile(agentID, sha, name, mime string, size int64, source string, claimed bool, ...) (File, error)
- func (s *Store) AddMessage(m Message) (Message, error)
- func (s *Store) AgentByID(id string) (Agent, error)
- func (s *Store) AgentByKey(key string) (Agent, error)
- func (s *Store) AgentByName(name string) (Agent, error)
- func (s *Store) AgentHasFile(agentID, sha, name string) bool
- func (s *Store) AppendReceipt(actor, action, sha string, size int64, target, messageID string) (receipt.Receipt, error)
- func (s *Store) BurnLink(token string) (Link, error)
- func (s *Store) CheckUnsubscribeToken(addr, tok string) bool
- func (s *Store) ClaimHumanRecipients(agentID string, addrs []string, max int64) (newly []string, err error)
- func (s *Store) Close() error
- func (s *Store) ConnectInstanceByName(name string) (ConnectInstance, error)
- func (s *Store) ConnectInstanceByToken(token string) (ConnectInstance, error)
- func (s *Store) ConsumeVerifyToken(tok string) (string, error)
- func (s *Store) CountAgentsByOwner(owner string) (int64, error)
- func (s *Store) CountDownload(token string) error
- func (s *Store) CountHumanRecipients(agentID string) (int64, error)
- func (s *Store) CreateAgent(name, ownerEmail string, verified bool) (Agent, string, error)
- func (s *Store) CreateConnectInstance(name string) (string, error)
- func (s *Store) CreateLink(agentID, sha, name, mime string, size int64, once bool, ttl time.Duration) (Link, error)
- func (s *Store) CreateUploadRequest(agentID, note string, ttl time.Duration) (UploadRequest, error)
- func (s *Store) CreateVerifyToken(agentID string) (string, error)
- func (s *Store) DeleteAgent(agentID string) (Agent, []string, error)
- func (s *Store) DeleteConnectMail(name, id string) error
- func (s *Store) DeleteFile(agentID, sha string) ([]File, error)
- func (s *Store) DeleteOrphanBlobs() (int, error)
- func (s *Store) DiskFull() bool
- func (s *Store) DiskStats() (free, total, reserve int64)
- func (s *Store) EnqueueConnectMail(name string, rcpts []string, raw []byte, maxMsgs, maxBytes int64) error
- func (s *Store) ExpireFiles(cutoff int64) ([]File, error)
- func (s *Store) ExpireLinks(cutoff int64) ([]Link, error)
- func (s *Store) FileByName(agentID, name string) (File, error)
- func (s *Store) FileBySHA(agentID, sha string) (File, error)
- func (s *Store) GetIdempotent(agentID, key string) (string, error)
- func (s *Store) GetLink(token string) (Link, error)
- func (s *Store) GetMessage(agentID, id string) (Message, error)
- func (s *Store) GetSetting(k string) (string, error)
- func (s *Store) GetUploadRequest(token string) (UploadRequest, error)
- func (s *Store) HasMessageID(agentID, messageID string) bool
- func (s *Store) IncrCounter(agentID, kind string) (int64, error)
- func (s *Store) IncrCounterN(agentID, kind string, n int64) (int64, error)
- func (s *Store) Instance() string
- func (s *Store) IsAdmin(tok string) bool
- func (s *Store) IsSuppressed(addr string) bool
- func (s *Store) KeepFile(agentID, sha string, expiresAt int64) (File, error)
- func (s *Store) ListConnectMail(name string, limit int) ([]ConnectMail, error)
- func (s *Store) ListFiles(agentID string) ([]File, error)
- func (s *Store) ListInbox(agentID string, unreadOnly bool, thread string, limit int) ([]Message, error)
- func (s *Store) ListLinks(agentID string) ([]Link, error)
- func (s *Store) ListReceipts(actor string, limit int) ([]receipt.Receipt, error)
- func (s *Store) MarkOwnerVerified(agentID string) error
- func (s *Store) MarkRead(agentID, id string) error
- func (s *Store) OpenBlob(sha string) (*os.File, error)
- func (s *Store) PeekVerifyToken(tok string) (string, error)
- func (s *Store) Prune() error
- func (s *Store) PublicKey() ed25519.PublicKey
- func (s *Store) PutBlob(r io.Reader, limit int64) (sha string, size int64, err error)
- func (s *Store) PutIdempotent(agentID, key, response string) error
- func (s *Store) ReapConnectInstances(graceNew, graceIdle time.Duration) ([]string, error)
- func (s *Store) ReleaseHumanRecipients(agentID string, addrs []string) error
- func (s *Store) RenameInstance(domain string) error
- func (s *Store) RevokeLink(token string) (Link, error)
- func (s *Store) RevokeLinksForSHA(agentID, sha string) ([]Link, error)
- func (s *Store) RotateKey(agentID string) (string, error)
- func (s *Store) SetAlwaysCC(agentID string, v bool) error
- func (s *Store) SetConnectSuspended(name string, v bool) error
- func (s *Store) SetConnectVerified(name, ownerEmail string) error
- func (s *Store) SetDiskReserve(bytes int64)
- func (s *Store) SetHumanRecipientsMax(agentID string, n int64) error
- func (s *Store) SetInstance(domain string)
- func (s *Store) SetSetting(k, v string) error
- func (s *Store) StorageUsed(agentID string) (int64, error)
- func (s *Store) StoredBytes() (int64, error)
- func (s *Store) Suppress(addr string) error
- func (s *Store) TopStorageConsumers(limit int) ([]StorageConsumer, error)
- func (s *Store) TouchConnectInstance(name string) error
- func (s *Store) UnsubscribeToken(addr string) string
- func (s *Store) UseUploadRequest(token string) (bool, error)
- type UploadRequest
Constants ¶
This section is empty.
Variables ¶
var ErrCircleFull = errors.New("recipient circle full")
ErrCircleFull is returned when a send would add more unique remote recipients than the agent's circle allows.
var ErrNameTaken = errors.New("name taken")
ErrNameTaken is returned when an agent name is already registered.
var ErrNotFound = errors.New("not found")
ErrNotFound is returned when a row does not exist.
var ErrQueueFull = errors.New("mail queue full")
ErrQueueFull is returned when an instance's mail queue is at capacity, so the SMTP path can answer a retryable 452 rather than a permanent reject.
var ErrQuota = errors.New("storage quota exceeded")
ErrQuota is returned when an upload would exceed the agent's storage quota or the max file size.
Functions ¶
func VolumeStats ¶
VolumeStats returns the free (available to unprivileged users) and total bytes of the filesystem holding path.
Types ¶
type Agent ¶
type Agent struct {
ID string `json:"agent_id"`
Name string `json:"name"`
Email string `json:"email"`
OwnerEmail string `json:"owner_email,omitempty"`
OwnerVerified bool `json:"owner_verified"`
AlwaysCCOwner bool `json:"always_cc_owner"`
// HumanRecipientsMax overrides the instance-wide cap on unique remote
// recipients for this agent: 0 = instance default, <0 = unlimited.
HumanRecipientsMax int64 `json:"-"`
CreatedAt int64 `json:"created_at"`
}
Agent is one identity: an email address plus an API key.
type Attachment ¶
type Attachment struct {
SHA256 string `json:"sha256"`
Name string `json:"name"`
MIME string `json:"mime"`
Size int64 `json:"size"`
}
Attachment describes an inbound email attachment ingested into the folder.
type ConnectInstance ¶
ConnectInstance is one tunneled instance in the host registry. Only the fields the server actually reads are surfaced; created_at / last_seen / owner_email live in the table and are used by reaping and verification via SQL, not through this struct.
type ConnectMail ¶
ConnectMail is one queued inbound email for a tunneled instance.
type File ¶
type File struct {
ID string `json:"id"`
AgentID string `json:"-"`
SHA256 string `json:"sha256"`
Name string `json:"name"`
MIME string `json:"mime"`
Size int64 `json:"size"`
Source string `json:"source"` // upload | inbound | request
Claimed bool `json:"claimed"`
ExpiresAt int64 `json:"expires_at,omitempty"` // unix; 0 = never
CreatedAt int64 `json:"created_at"`
}
File is one entry in an agent's folder. Claimed means the agent owns it (its own upload, or an arrival it kept); unclaimed files (inbound attachments, upload-request drops) await a keep. ExpiresAt > 0 makes a file mortal regardless of claiming — the unverified-owner tier uploads with an expiry that verification later lifts.
type Link ¶
type Link struct {
Token string `json:"token"`
AgentID string `json:"-"`
SHA256 string `json:"sha256"`
Name string `json:"name"`
MIME string `json:"mime"`
Size int64 `json:"size"`
Once bool `json:"once"`
Downloads int64 `json:"downloads"`
Status string `json:"status"` // active | revoked | burned | expired
ExpiresAt int64 `json:"expires_at"`
CreatedAt int64 `json:"created_at"`
}
Link is an ephemeral, unguessable share link over a blob.
type Message ¶
type Message struct {
ID string `json:"id"`
AgentID string `json:"-"`
From string `json:"from"`
To []string `json:"to"`
Subject string `json:"subject"`
Text string `json:"text"`
MessageID string `json:"message_id"`
InReplyTo string `json:"in_reply_to,omitempty"`
References string `json:"references,omitempty"`
Manifest string `json:"-"` // raw manifest JSON, if any
Attachments []Attachment `json:"attachments"`
DKIM string `json:"dkim"`
SPF string `json:"spf"`
Read bool `json:"read"`
ReceivedAt int64 `json:"received_at"`
}
Message is one inbox entry.
type StorageConsumer ¶
type StorageConsumer struct {
AgentID string `json:"agent_id"`
Name string `json:"name"`
Email string `json:"email"`
OwnerEmail string `json:"owner_email"`
OwnerVerified bool `json:"owner_verified"`
Files int64 `json:"files"`
Bytes int64 `json:"bytes"`
}
StorageConsumer is one row of the admin "top storage consumers" view.
type Store ¶
Store wraps the database, blob directory, and instance identity.
func Open ¶
Open opens (creating if needed) the store at dataDir. adminToken, if non-empty, becomes the admin token; otherwise one is generated on first boot and returned in firstBootAdminToken exactly once.
func (*Store) AddFile ¶
func (s *Store) AddFile(agentID, sha, name, mime string, size int64, source string, claimed bool, expiresAt int64) (File, error)
AddFile records a folder entry over an existing blob and takes a blob reference. Re-adding the same (name, sha) refreshes the row instead.
func (*Store) AddMessage ¶
AddMessage inserts an inbox row for an agent.
func (*Store) AgentByKey ¶
AgentByKey resolves an API key to its agent.
func (*Store) AgentByName ¶
AgentByName resolves an agent by name (the address localpart).
func (*Store) AgentHasFile ¶
AgentHasFile reports whether the agent's folder already holds this exact (name, sha) entry — used to waive quota on idempotent re-uploads.
func (*Store) AppendReceipt ¶
func (s *Store) AppendReceipt(actor, action, sha string, size int64, target, messageID string) (receipt.Receipt, error)
AppendReceipt signs and appends one receipt to the instance chain.
func (*Store) CheckUnsubscribeToken ¶
CheckUnsubscribeToken verifies an unsubscribe token for addr.
func (*Store) ClaimHumanRecipients ¶
func (s *Store) ClaimHumanRecipients(agentID string, addrs []string, max int64) (newly []string, err error)
ClaimHumanRecipients records addrs in the agent's recipient circle, enforcing max (<0 = unlimited) atomically. It returns the addresses this call newly claimed, so a failed send can release exactly those.
func (*Store) ConnectInstanceByName ¶
func (s *Store) ConnectInstanceByName(name string) (ConnectInstance, error)
ConnectInstanceByName fetches a registered instance.
func (*Store) ConnectInstanceByToken ¶
func (s *Store) ConnectInstanceByToken(token string) (ConnectInstance, error)
ConnectInstanceByToken resolves an instance token.
func (*Store) ConsumeVerifyToken ¶
ConsumeVerifyToken redeems a verification token for its agent id.
func (*Store) CountAgentsByOwner ¶
CountAgentsByOwner counts agents registered to an owner address (case-insensitive) — open signup caps this so identities aren't free in bulk.
func (*Store) CountDownload ¶
CountDownload bumps a link's download counter.
func (*Store) CountHumanRecipients ¶
CountHumanRecipients returns the number of unique remote recipients the agent has claimed.
func (*Store) CreateAgent ¶
CreateAgent mints an agent and returns it with the plaintext API key (stored only as a hash).
func (*Store) CreateConnectInstance ¶
CreateConnectInstance registers a tunneled instance and returns its plaintext token (stored hashed).
func (*Store) CreateLink ¶
func (s *Store) CreateLink(agentID, sha, name, mime string, size int64, once bool, ttl time.Duration) (Link, error)
CreateLink mints an ephemeral share link over a blob and takes a blob ref.
func (*Store) CreateUploadRequest ¶
CreateUploadRequest mints a one-time human upload page token.
func (*Store) CreateVerifyToken ¶
CreateVerifyToken mints an owner-verification token.
func (*Store) DeleteAgent ¶
DeleteAgent removes an agent and everything it owns — files, links, inbox, recipient circle, upload requests, counters, idempotency + verify tokens — EXCEPT its receipts: the signed chain is append-only and must outlive the account, or it stops being deletion-evident. Blob refs held by the agent's files and active links are released (only this agent's contribution, so content deduped with another agent survives), and the active link tokens are returned so the caller can sever any in-flight downloads. All in one transaction: a partial cascade would leave dangling refs or FK orphans.
func (*Store) DeleteConnectMail ¶
DeleteConnectMail acknowledges (removes) one queued message.
func (*Store) DeleteFile ¶
DeleteFile removes folder entries for a hash and drops their blob refs. It returns the removed entries.
func (*Store) DeleteOrphanBlobs ¶
DeleteOrphanBlobs removes blobs with zero references from db and disk.
Safety has three layers. The grace period skips young rows entirely — PutBlob creates (or refreshes) the row at refs=0 and the first reference lands moments later. The row DELETE re-checks refs AND age, so a blob re-referenced or re-put since the scan is left alone. And each delete + unlink pair runs under blobMu so it can't interleave with PutBlob's row-write + byte-write pair — without the lock, a dedup upload could see the bytes on disk, skip writing them, and then lose them to the unlink.
func (*Store) DiskFull ¶
DiskFull reports whether the volume holding the data dir is below the configured free-space reserve — the global backstop that keeps the disk from ever reaching 100% (where SQLite writes start failing and the whole instance falls over). Callers refuse new uploads while it holds.
func (*Store) DiskStats ¶
DiskStats returns the data-dir volume's free and total bytes plus the configured reserve (0 = guard disabled). free/total are 0 when the platform can't report them.
func (*Store) EnqueueConnectMail ¶
func (s *Store) EnqueueConnectMail(name string, rcpts []string, raw []byte, maxMsgs, maxBytes int64) error
EnqueueConnectMail stores one inbound email for an instance, enforcing per-instance count and byte caps.
func (*Store) ExpireFiles ¶
ExpireFiles removes folder entries past their expiry — unclaimed arrivals and unverified-tier uploads alike (expires_at=0 means immortal). It returns the expired entries (for receipts).
func (*Store) ExpireLinks ¶
ExpireLinks closes active links past expiry and returns them.
func (*Store) FileByName ¶
FileByName fetches an agent's folder entry by filename.
func (*Store) GetIdempotent ¶
GetIdempotent returns a stored response for (agent, key), or "".
func (*Store) GetMessage ¶
GetMessage fetches one inbox message owned by the agent.
func (*Store) GetSetting ¶
GetSetting returns a persisted setting ("" if unset).
func (*Store) GetUploadRequest ¶
func (s *Store) GetUploadRequest(token string) (UploadRequest, error)
GetUploadRequest fetches a live (unused, unexpired) upload request.
func (*Store) HasMessageID ¶
HasMessageID reports whether the agent already has a message with this RFC Message-ID — used to make at-least-once inbound delivery (connect store-and-forward, retried drains) idempotent instead of duplicating.
func (*Store) IncrCounter ¶
IncrCounter bumps and returns today's counter of a kind for an agent.
func (*Store) IncrCounterN ¶
IncrCounterN bumps today's counter by n and returns the new total. n=0 reads the current value; a negative n refunds a charge.
func (*Store) IsSuppressed ¶
IsSuppressed reports whether addr has unsubscribed from this instance.
func (*Store) KeepFile ¶
KeepFile claims a file. expiresAt caps its remaining lifetime: 0 makes it persistent (verified owners); unverified agents pass their tier's ceiling — keeping must not grant an immortality their own uploads don't get.
func (*Store) ListConnectMail ¶
func (s *Store) ListConnectMail(name string, limit int) ([]ConnectMail, error)
ListConnectMail returns queued mail for an instance, oldest first.
func (*Store) ListInbox ¶
func (s *Store) ListInbox(agentID string, unreadOnly bool, thread string, limit int) ([]Message, error)
ListInbox returns inbox messages, oldest first. thread filters by an AgentTransfer message id (matches the message or replies to it).
func (*Store) ListReceipts ¶
ListReceipts returns receipts, oldest first. actor "" means all (admin).
func (*Store) MarkOwnerVerified ¶
MarkOwnerVerified flips owner verification on and lifts the unverified storage tier: the agent's claimed files stop expiring. (Unclaimed arrivals stay mortal until kept — that guard is about strangers, not the owner.)
func (*Store) PeekVerifyToken ¶
PeekVerifyToken resolves a verification token WITHOUT consuming it — the GET landing page must be side-effect-free so link prefetchers and mail scanners can't verify on the owner's behalf; only the explicit confirm POST consumes.
func (*Store) Prune ¶
Prune clears expired idempotency keys, verify tokens, upload requests and stale counters.
func (*Store) PutBlob ¶
PutBlob streams r to disk while hashing, capped at limit bytes. Identical content is stored once (content addressing); re-putting an existing blob just refreshes its row.
func (*Store) PutIdempotent ¶
PutIdempotent stores a response for (agent, key).
func (*Store) ReapConnectInstances ¶
ReapConnectInstances removes registrations that never connected within graceNew, or have been idle longer than graceIdle, along with their queued mail. Returns the reaped names.
func (*Store) ReleaseHumanRecipients ¶
ReleaseHumanRecipients removes addresses from the agent's circle — used to refund slots claimed for a send that then failed at the relay.
func (*Store) RenameInstance ¶
RenameInstance changes the instance domain and rewrites agent addresses to the new domain (agent emails are stored denormalized at creation time). Historical receipts keep the addresses that were true when they were signed — rewriting them would break the chain.
func (*Store) RevokeLink ¶
RevokeLink kills a link now.
func (*Store) RevokeLinksForSHA ¶
RevokeLinksForSHA revokes all of an agent's active links over a hash.
func (*Store) SetAlwaysCC ¶
SetAlwaysCC sets the per-agent "always CC my owner" flag.
func (*Store) SetConnectSuspended ¶
SetConnectSuspended flips the kill switch for an instance.
func (*Store) SetConnectVerified ¶
SetConnectVerified marks an instance's owner verified (unlocks outbound email through the host).
func (*Store) SetDiskReserve ¶
SetDiskReserve sets the free-space floor (bytes) below which DiskFull reports true. 0 disables the guard.
func (*Store) SetHumanRecipientsMax ¶
SetHumanRecipientsMax sets the per-agent recipient-circle override (0 = instance default, <0 = unlimited).
func (*Store) SetInstance ¶
SetInstance sets the domain recorded on receipts and used in addresses.
func (*Store) SetSetting ¶
SetSetting persists a setting.
func (*Store) StorageUsed ¶
StorageUsed sums the agent's folder bytes (each entry counted once).
func (*Store) StoredBytes ¶
StoredBytes is the physical footprint: the sum of all blob sizes (dedup means this is ≤ the sum of folder entries).
func (*Store) Suppress ¶
Suppress records that addr never wants agent mail from this instance again.
func (*Store) TopStorageConsumers ¶
func (s *Store) TopStorageConsumers(limit int) ([]StorageConsumer, error)
TopStorageConsumers returns agents ordered by folder bytes, biggest first — abuse cleanup starts with being able to SEE who holds the disk.
func (*Store) TouchConnectInstance ¶
TouchConnectInstance records tunnel activity.
func (*Store) UnsubscribeToken ¶
UnsubscribeToken returns a stateless HMAC token binding addr to this instance's key, so unsubscribe links can't be forged to suppress a victim.