379 lines
8.9 KiB
Go
379 lines
8.9 KiB
Go
// Package models defines all shared data structures.
|
|
package models
|
|
|
|
import "time"
|
|
|
|
// ---- Domain & User ----
|
|
|
|
type Domain struct {
|
|
ID int64
|
|
Name string
|
|
Enabled bool
|
|
DKIMPrivateEnc []byte // AES-256-GCM encrypted PEM private key
|
|
DKIMPublic string // PEM public key (not secret)
|
|
DKIMSelector string
|
|
DKIMAlgo string // rsa2048 | ed25519
|
|
SPFPolicy string // stored for reference
|
|
DMARCPolicy string // stored for reference
|
|
MaxUsers int
|
|
MaxQuotaBytes int64
|
|
CreatedAt time.Time
|
|
DMARCRua string // monitoring address e.g. dmarc-abc123@domain.com; empty = disabled
|
|
}
|
|
|
|
// ---- DMARC aggregate reports ----
|
|
|
|
// DMARCReport is a parsed RFC 7489 aggregate report received at the monitoring address.
|
|
type DMARCReport struct {
|
|
ID int64
|
|
DomainID int64
|
|
OrgName string
|
|
OrgEmail string
|
|
ReportID string
|
|
DateBegin int64 // unix timestamp
|
|
DateEnd int64 // unix timestamp
|
|
PolicyDomain string
|
|
PolicyADKIM string
|
|
PolicyASPF string
|
|
PolicyP string
|
|
PolicyPct int
|
|
ReceivedAt time.Time
|
|
Records []DMARCRecord
|
|
}
|
|
|
|
// DMARCRecord is one IP-level row within a DMARCReport.
|
|
type DMARCRecord struct {
|
|
ID int64
|
|
ReportID int64
|
|
SourceIP string
|
|
Count int
|
|
Disposition string // none | quarantine | reject
|
|
DKIMResult string // pass | fail | none
|
|
SPFResult string // pass | fail | none
|
|
HeaderFrom string
|
|
EnvelopeFrom string
|
|
DKIMDomain string
|
|
DKIMSelector string
|
|
SPFDomain string
|
|
}
|
|
|
|
type User struct {
|
|
ID int64
|
|
DomainID int64
|
|
Username string // local part (before @)
|
|
Email string // full address
|
|
PasswordHash string // bcrypt
|
|
DisplayName string
|
|
QuotaBytes int64
|
|
UsedBytes int64
|
|
Enabled bool
|
|
Admin bool // global admin
|
|
DomainAdmin bool // admin of own domain only
|
|
MFASecretEnc []byte // encrypted TOTP secret; nil = MFA disabled
|
|
MFAEnabled bool
|
|
RecoveryCodesEnc []byte // encrypted JSON array of one-time codes
|
|
CreatedAt time.Time
|
|
LastLogin time.Time
|
|
}
|
|
|
|
type UserAlias struct {
|
|
ID int64
|
|
UserID int64
|
|
AliasEmail string
|
|
}
|
|
|
|
// ---- Mail storage ----
|
|
|
|
// MailboxType canonical values.
|
|
const (
|
|
MailboxInbox = "inbox"
|
|
MailboxSent = "sent"
|
|
MailboxDrafts = "drafts"
|
|
MailboxTrash = "trash"
|
|
MailboxSpam = "spam"
|
|
MailboxArchive = "archive"
|
|
MailboxCustom = "custom"
|
|
)
|
|
|
|
type Mailbox struct {
|
|
ID int64
|
|
UserID int64
|
|
Name string // IMAP mailbox name (e.g. "INBOX", "Sent", "Folder/Sub")
|
|
Type string // MailboxInbox … MailboxCustom
|
|
ParentID *int64
|
|
UIDValidity uint32
|
|
UIDNext uint32
|
|
Subscribed bool
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
type Message struct {
|
|
ID int64
|
|
MailboxID int64
|
|
UID uint32
|
|
MessageID string // RFC 2822 Message-ID header (not encrypted — needed for threading)
|
|
Subject string // plaintext for list/search (consider sensitivity vs usability)
|
|
FromEmail string
|
|
FromName string
|
|
ToList string // comma-separated
|
|
CCList string
|
|
BCCList string
|
|
ReplyTo string
|
|
Date time.Time
|
|
BodyTextEnc []byte // AES-256-GCM encrypted text/plain
|
|
BodyHTMLEnc []byte // AES-256-GCM encrypted text/html
|
|
RawEnc []byte // AES-256-GCM encrypted full RFC822 message
|
|
SizeBytes int64
|
|
HasAttachment bool
|
|
IsRead bool
|
|
IsStarred bool
|
|
IsDraft bool
|
|
Flags string // raw IMAP flags string
|
|
SpamScore int
|
|
ReceivedAt time.Time
|
|
DeletedAt *time.Time // soft delete; nil = not deleted
|
|
}
|
|
|
|
type Attachment struct {
|
|
ID int64
|
|
MessageID int64
|
|
Filename string
|
|
ContentType string
|
|
SizeBytes int64
|
|
DataEnc []byte // AES-256-GCM encrypted bytes (or nil if fs-backed)
|
|
DataPath string // filesystem path (if STORAGE_BACKEND=fs)
|
|
ContentID string // MIME Content-ID for inline images
|
|
Inline bool
|
|
MIMEPath string // dot-separated MIME section path e.g. "1.2"
|
|
}
|
|
|
|
// ---- Delivery queue ----
|
|
|
|
const (
|
|
QueuePending = "pending"
|
|
QueueSending = "sending"
|
|
QueueDelivered = "delivered"
|
|
QueueFailed = "failed"
|
|
QueueBounced = "bounced"
|
|
)
|
|
|
|
type QueueEntry struct {
|
|
ID int64
|
|
DomainID int64
|
|
FromAddr string
|
|
ToAddr string
|
|
RawEnc []byte // encrypted RFC822
|
|
MessageID string
|
|
Status string // QueuePending … QueueBounced
|
|
Attempts int
|
|
LastAttempt *time.Time
|
|
NextAttempt time.Time
|
|
ErrorLog string
|
|
CreatedAt time.Time
|
|
ExpiresAt time.Time
|
|
}
|
|
|
|
type DeliveryLog struct {
|
|
ID int64
|
|
QueueID int64
|
|
FromAddr string
|
|
ToAddr string
|
|
Status string
|
|
SMTPCode int
|
|
SMTPMessage string
|
|
MXHost string
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
// ---- Sessions & Security ----
|
|
|
|
type Session struct {
|
|
ID int64
|
|
UserID int64
|
|
TokenHash string // SHA-256 hex of the raw bearer token
|
|
IP string
|
|
UserAgent string
|
|
CreatedAt time.Time
|
|
ExpiresAt time.Time
|
|
}
|
|
|
|
type IPBan struct {
|
|
ID int64
|
|
IP string
|
|
Reason string
|
|
BannedAt time.Time
|
|
ExpiresAt *time.Time // nil = permanent
|
|
ReleasedBy string
|
|
}
|
|
|
|
type LoginAttempt struct {
|
|
ID int64
|
|
IP string
|
|
UserEmail string
|
|
Success bool
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
type SecurityEvent struct {
|
|
ID int64
|
|
Type string // brute_ban | auth_fail | relay_attempt | etc.
|
|
IP string
|
|
UserID *int64
|
|
Detail string
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
// ---- External accounts (Gmail / Outlook / custom IMAP) ----
|
|
|
|
const (
|
|
ProviderGmail = "gmail"
|
|
ProviderOutlook = "outlook"
|
|
ProviderCustom = "custom"
|
|
)
|
|
|
|
type ExternalAccount struct {
|
|
ID int64
|
|
UserID int64
|
|
Provider string // ProviderGmail | ProviderOutlook | ProviderCustom
|
|
EmailAddress string
|
|
DisplayName string
|
|
AccessTokenEnc []byte // encrypted OAuth2 or password
|
|
RefreshTokenEnc []byte // encrypted OAuth2 refresh token
|
|
TokenExpiry time.Time
|
|
IMAPHost string
|
|
IMAPPort int
|
|
SMTPHost string
|
|
SMTPPort int
|
|
Enabled bool
|
|
SyncEnabled bool
|
|
LastSync time.Time
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
// ---- Contacts (CardDAV) ----
|
|
|
|
type AddressBook struct {
|
|
ID int64
|
|
UserID int64
|
|
Name string
|
|
Description string
|
|
Color string
|
|
SyncToken int64
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
type Contact struct {
|
|
ID int64
|
|
AddressBookID int64
|
|
UID string
|
|
VCardEnc []byte // AES-256-GCM encrypted vCard 3.0/4.0
|
|
ETag string // hex(sha256(raw vcard)) — for sync
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
}
|
|
|
|
// ---- Calendar (CalDAV) ----
|
|
|
|
type Calendar struct {
|
|
ID int64
|
|
UserID int64
|
|
Name string
|
|
Description string
|
|
Color string
|
|
Timezone string
|
|
SyncToken int64
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
type CalendarEvent struct {
|
|
ID int64
|
|
CalendarID int64
|
|
UID string
|
|
ICalEnc []byte // AES-256-GCM encrypted iCalendar data
|
|
ETag string // hex(sha256(raw ical))
|
|
DTStart time.Time
|
|
DTEnd time.Time
|
|
Summary string // plaintext for calendar grid display
|
|
Recurring bool
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
}
|
|
|
|
// ---- Spam / Bayesian ----
|
|
|
|
type SpamToken struct {
|
|
ID int64
|
|
UserID int64
|
|
Token string
|
|
SpamCount int64
|
|
HamCount int64
|
|
}
|
|
|
|
// ---- Relay ----
|
|
|
|
// RelayAccount is a domain-level SMTP-only account used for relay purposes.
|
|
// It has no mailbox or IMAP access.
|
|
type RelayAccount struct {
|
|
ID int64
|
|
DomainID int64
|
|
Username string // may be email or arbitrary string up to 240 chars
|
|
PasswordHash string
|
|
DisplayName string
|
|
Enabled bool
|
|
Description string
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
// RelaySendAs is a permitted sender pattern for a relay account.
|
|
// Pattern may be an exact address or a wildcard (*@domain.com).
|
|
type RelaySendAs struct {
|
|
ID int64
|
|
RelayAccountID int64
|
|
Pattern string
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
// RelayIPRule allows unauthenticated SMTP relay from a specific IP/CIDR
|
|
// for a given sender pattern, per domain.
|
|
type RelayIPRule struct {
|
|
ID int64
|
|
DomainID int64
|
|
CIDR string // IP or CIDR notation
|
|
SenderPattern string // exact email or *@domain.com
|
|
Description string
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
// RelayAccountIP whitelists an IP/CIDR for a relay account.
|
|
// Connections from the IP may send as any address permitted by the account's
|
|
// send-as patterns without SMTP AUTH.
|
|
type RelayAccountIP struct {
|
|
ID int64
|
|
RelayAccountID int64
|
|
CIDR string
|
|
Description string
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
// ---- Compose helpers (not persisted directly) ----
|
|
|
|
type Attachment_Upload struct {
|
|
Filename string
|
|
ContentType string
|
|
Data []byte
|
|
}
|
|
|
|
type ComposeRequest struct {
|
|
AccountID int64 // 0 = local account, >0 = external account ID
|
|
FromEmail string
|
|
To []string
|
|
CC []string
|
|
BCC []string
|
|
Subject string
|
|
BodyText string
|
|
BodyHTML string
|
|
Attachments []Attachment_Upload
|
|
InReplyTo string
|
|
References string
|
|
}
|