first commit
This commit is contained in:
@@ -0,0 +1,353 @@
|
||||
package db
|
||||
|
||||
import "time"
|
||||
|
||||
// ── Tenants & domains ──────────────────────────────────────────────────────────
|
||||
|
||||
type Tenant struct {
|
||||
ID string
|
||||
Name string
|
||||
DisplayName string
|
||||
DigestIntervalMins int
|
||||
MaxAccounts int // 0 = unlimited
|
||||
QuotaMBPerUser int
|
||||
SettingsJSON string // pipeline thresholds, check toggles (parsed by pipeline pkg)
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type Domain struct {
|
||||
ID string
|
||||
TenantID string
|
||||
Domain string
|
||||
Active bool
|
||||
DKIMSelector string
|
||||
DKIMPrivateKeyEnc []byte // AES-256-GCM encrypted PEM
|
||||
AcceptAll bool
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
// ── Users & auth ──────────────────────────────────────────────────────────────
|
||||
|
||||
type UserRole string
|
||||
|
||||
const (
|
||||
RoleUser UserRole = "user"
|
||||
RoleTenantAdmin UserRole = "tenant_admin"
|
||||
RoleGlobalAdmin UserRole = "global_admin"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID string
|
||||
TenantID string
|
||||
DomainID string
|
||||
Email string
|
||||
PasswordHash string
|
||||
DisplayName string
|
||||
Role UserRole
|
||||
Active bool
|
||||
MFAEnabled bool
|
||||
TOTPSecretEnc []byte // AES-256-GCM encrypted
|
||||
PasskeyCredentialsJSON string // JSON array of WebAuthn credentials
|
||||
RecoveryEmail string // external address for password-reset delivery (see Phase 12 notes)
|
||||
QuotaMB int
|
||||
UsedBytes int64
|
||||
DigestEnabled bool
|
||||
DigestIntervalMins int // 0 = use tenant default
|
||||
LastDigestAt *time.Time
|
||||
LastLoginAt *time.Time
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type AppPassword struct {
|
||||
ID string
|
||||
UserID string
|
||||
Label string
|
||||
PasswordHash string // bcrypt of a 32-char random token
|
||||
Scopes string // comma-separated: smtp,imap,caldav,carddav,pop3
|
||||
LastUsedAt *time.Time
|
||||
ExpiresAt *time.Time // nil = never expires
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type Session struct {
|
||||
ID string
|
||||
UserID string
|
||||
JTI string // JWT ID, for revocation lookups
|
||||
UserAgent string
|
||||
IP string
|
||||
ExpiresAt time.Time
|
||||
RevokedAt *time.Time
|
||||
}
|
||||
|
||||
type Alias struct {
|
||||
ID string
|
||||
TenantID string
|
||||
FromAddress string
|
||||
ToUserID *string // nil if forwarding externally
|
||||
ToExternal *string // nil if local
|
||||
Active bool
|
||||
}
|
||||
|
||||
// ── List rules (allow/block, per tenant) ───────────────────────────────────────
|
||||
|
||||
type ListRuleAction string
|
||||
|
||||
const (
|
||||
ListActionAllow ListRuleAction = "allow"
|
||||
ListActionBlock ListRuleAction = "block"
|
||||
)
|
||||
|
||||
type ListRule struct {
|
||||
ID string
|
||||
TenantID string
|
||||
ListType ListRuleAction // allow | block
|
||||
MatchType string // email | domain
|
||||
Value string
|
||||
Note string
|
||||
Active bool
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
// ── Messages (audit log) & mailbox index ────────────────────────────────────────
|
||||
|
||||
type MessageVerdict string
|
||||
|
||||
const (
|
||||
VerdictClean MessageVerdict = "clean"
|
||||
VerdictFlagged MessageVerdict = "flagged"
|
||||
VerdictQuarantine MessageVerdict = "quarantine"
|
||||
VerdictBlocked MessageVerdict = "blocked"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
ID string
|
||||
TenantID string
|
||||
FromAddress string
|
||||
ToAddress string
|
||||
Subject string
|
||||
MessageIDHdr string
|
||||
SizeBytes int64
|
||||
Verdict MessageVerdict
|
||||
TotalScore float64
|
||||
SenderIP string
|
||||
RelayedAt *time.Time
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type MailboxEntry struct {
|
||||
ID string
|
||||
UserID string
|
||||
Mailbox string // INBOX, Sent, Trash, Junk, custom...
|
||||
UID int
|
||||
EMLPath string // path to encrypted .eml.enc on disk
|
||||
Flags string // \Seen \Flagged \Answered \Deleted \Draft
|
||||
SizeBytes int64
|
||||
ReceivedAt time.Time
|
||||
InternalDate time.Time
|
||||
}
|
||||
|
||||
// ── Outbound queue ───────────────────────────────────────────────────────────
|
||||
|
||||
type OutboundQueueEntry struct {
|
||||
ID string
|
||||
UserID string
|
||||
FromAddress string
|
||||
ToAddress string
|
||||
EMLPath string
|
||||
Priority int
|
||||
Attempts int
|
||||
LastError string
|
||||
NextAttemptAt time.Time
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
// ── Pipeline check results ──────────────────────────────────────────────────────
|
||||
|
||||
// CheckResult is the outcome of a single pipeline stage (SPF, DKIM, etc.).
|
||||
type CheckResult string
|
||||
|
||||
const (
|
||||
CheckPass CheckResult = "pass"
|
||||
CheckWarn CheckResult = "warn"
|
||||
CheckFail CheckResult = "fail"
|
||||
CheckSkipped CheckResult = "skipped"
|
||||
CheckError CheckResult = "error"
|
||||
)
|
||||
|
||||
type MessageCheck struct {
|
||||
ID string
|
||||
MessageID string
|
||||
Stage string
|
||||
Result CheckResult
|
||||
Score float64
|
||||
Detail string
|
||||
DurationMs int64
|
||||
}
|
||||
|
||||
// ── Quarantine ────────────────────────────────────────────────────────────────
|
||||
|
||||
type QuarantineStatus string
|
||||
|
||||
const (
|
||||
QuarantineHeld QuarantineStatus = "held"
|
||||
QuarantineReleased QuarantineStatus = "released"
|
||||
QuarantineDeleted QuarantineStatus = "deleted"
|
||||
)
|
||||
|
||||
type QuarantineEntry struct {
|
||||
ID string
|
||||
MessageID string
|
||||
EMLPath string
|
||||
Status QuarantineStatus
|
||||
Reason string
|
||||
ReleasedBy string
|
||||
ReleasedAt *time.Time
|
||||
ExpiresAt time.Time
|
||||
NotifiedAt *time.Time
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type ReleaseToken struct {
|
||||
ID string
|
||||
QuarantineID string
|
||||
Token string
|
||||
Email string
|
||||
UsedAt *time.Time
|
||||
ExpiresAt time.Time
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
// ── Linked accounts (multi-account webmail — Part B of the plan) ──────────────
|
||||
|
||||
type LinkedAccountProvider string
|
||||
|
||||
const (
|
||||
ProviderGoMail LinkedAccountProvider = "gomail"
|
||||
ProviderIMAP LinkedAccountProvider = "imap"
|
||||
ProviderGmail LinkedAccountProvider = "gmail" // Phase 10
|
||||
ProviderM365 LinkedAccountProvider = "m365" // Phase 10
|
||||
)
|
||||
|
||||
type LinkedAccountAuthType string
|
||||
|
||||
const (
|
||||
AuthTypeSession LinkedAccountAuthType = "session" // gomail local account, already logged in
|
||||
AuthTypePassword LinkedAccountAuthType = "password" // generic IMAP/SMTP
|
||||
AuthTypeOAuth2 LinkedAccountAuthType = "oauth2" // Phase 10
|
||||
)
|
||||
|
||||
type LinkedAccount struct {
|
||||
ID string
|
||||
UserID string
|
||||
Provider LinkedAccountProvider
|
||||
DisplayName string
|
||||
EmailAddress string
|
||||
AuthType LinkedAccountAuthType
|
||||
IMAPHost string
|
||||
IMAPPort int
|
||||
IMAPTLS string // "starttls" | "implicit" | "off"
|
||||
SMTPHost string
|
||||
SMTPPort int
|
||||
SMTPTLS string
|
||||
CredentialEnc []byte // encrypted password or OAuth2 tokens (JSON)
|
||||
OAuthExpiresAt *time.Time
|
||||
SyncState string
|
||||
CacheRetentionDays int // 0 = use instance default
|
||||
LastSyncAt *time.Time
|
||||
LastSyncError string
|
||||
Active bool
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
// ── CalDAV / CardDAV ────────────────────────────────────────────────────────────
|
||||
|
||||
// OwnerType distinguishes a personal (per-user) collection from a shared
|
||||
// tenant-wide one — both addressbooks and calendars support both scopes per
|
||||
// the plan (tenant addressbook + per-user addressbook, same for calendars).
|
||||
type OwnerType string
|
||||
|
||||
const (
|
||||
OwnerUser OwnerType = "user"
|
||||
OwnerTenant OwnerType = "tenant"
|
||||
)
|
||||
|
||||
type Addressbook struct {
|
||||
ID string
|
||||
OwnerType OwnerType
|
||||
OwnerID string
|
||||
DisplayName string
|
||||
Description string
|
||||
SyncToken string
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type Contact struct {
|
||||
ID string
|
||||
AddressbookID string
|
||||
UID string
|
||||
VCardEnc []byte // AES-256-GCM encrypted vCard text
|
||||
ETag string
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
type Calendar struct {
|
||||
ID string
|
||||
OwnerType OwnerType
|
||||
OwnerID string
|
||||
DisplayName string
|
||||
Description string
|
||||
Color string
|
||||
Timezone string
|
||||
SyncToken string
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type CalendarObject struct {
|
||||
ID string
|
||||
CalendarID string
|
||||
UID string
|
||||
ICalEnc []byte // AES-256-GCM encrypted iCal text
|
||||
ComponentType string // VEVENT | VTODO | VJOURNAL
|
||||
Summary string
|
||||
DTStart *time.Time
|
||||
DTEnd *time.Time
|
||||
ETag string
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
// ── ManageSieve ───────────────────────────────────────────────────────────────
|
||||
|
||||
type SieveScript struct {
|
||||
ID string
|
||||
UserID string
|
||||
Name string
|
||||
ScriptText string
|
||||
Active bool
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
// ── TLS certs (ACME) ────────────────────────────────────────────────────────────
|
||||
|
||||
type TLSCert struct {
|
||||
ID string
|
||||
Domain string
|
||||
CertPEMEnc []byte
|
||||
KeyPEMEnc []byte
|
||||
ExpiresAt *time.Time
|
||||
ACMEAccountKeyEnc []byte
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
// ── MFA ───────────────────────────────────────────────────────────────────────
|
||||
|
||||
type MFABackupCode struct {
|
||||
ID string
|
||||
UserID string
|
||||
CodeHash string
|
||||
UsedAt *time.Time
|
||||
CreatedAt time.Time
|
||||
}
|
||||
Reference in New Issue
Block a user