commit 9af4c893d44d7d4d5ca87748cd06048f6ae46ee3
parent e00d4011db81cba7e9acd5ba0c462df1220efb2c
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date: Wed, 17 Dec 2025 23:26:37 +0900
add possibility of paid messages back (API only)
Diffstat:
4 files changed, 147 insertions(+), 61 deletions(-)
diff --git a/cmd/mailbox-server/main.go b/cmd/mailbox-server/main.go
@@ -101,7 +101,7 @@ func main() {
LibtoolVersion: ltversion,
Version: version,
Datahome: mailboxdatahome,
- Db: db,
+ DB: db,
Ini: iniCfg,
Merchant: merch,
Loglevel: loglevel,
diff --git a/cmd/mailbox-server/main_test.go b/cmd/mailbox-server/main_test.go
@@ -119,7 +119,7 @@ func TestMain(m *testing.M) {
merch := merchant.NewMerchant(merchServer.URL, "supersecret")
a.Initialize(mailbox.MailboxConfig{
Version: "testing",
- Db: db,
+ DB: db,
Merchant: merch,
Ini: cfg})
testAliceSigningKey, testAliceSigningKeyPriv, _ = ed25519.GenerateKey(nil)
@@ -131,12 +131,12 @@ func TestMain(m *testing.M) {
code := m.Run()
// Purge DB
- a.Db.Where("1 = 1").Delete(&mailbox.InboxEntry{})
+ a.DB.Where("1 = 1").Delete(&mailbox.InboxEntry{})
os.Exit(code)
}
func TestEmptyMailbox(t *testing.T) {
- a.Db.Where("1 = 1").Delete(&mailbox.InboxEntry{})
+ a.DB.Where("1 = 1").Delete(&mailbox.InboxEntry{})
req, _ := http.NewRequest("GET", "/"+testAliceHashedSigningKeyString, nil)
response := executeRequest(req)
@@ -148,9 +148,9 @@ func TestEmptyMailbox(t *testing.T) {
}
}
-func TestPostMessage(t *testing.T) {
+func TestSendMessage(t *testing.T) {
testMessage := make([]byte, 256)
- a.Db.Where("1 = 1").Delete(&mailbox.InboxEntry{})
+ a.DB.Where("1 = 1").Delete(&mailbox.InboxEntry{})
req, _ := http.NewRequest("POST", "/"+testAliceHashedSigningKeyString, bytes.NewReader(testMessage))
response := executeRequest(req)
@@ -162,6 +162,50 @@ func TestPostMessage(t *testing.T) {
}
}
+func setMailboxPaid(isPaid bool) {
+ var messageFee talerutil.Amount
+ if isPaid {
+ messageFee = talerutil.NewAmount("KUDOS", 1, 0)
+ } else {
+ messageFee = talerutil.NewAmount("KUDOS", 0, 0)
+ }
+ a.MessageFee = &messageFee
+ a.FreeMessageQuota = 1
+}
+
+func TestSendMessagePaid(t *testing.T) {
+
+ // Make paid
+ setMailboxPaid(true)
+
+ // Cleanup
+ a.DB.Where("1 = 1").Delete(&mailbox.InboxEntry{})
+
+ testMessage := make([]byte, 256)
+ rand.Read(testMessage)
+ req, _ := http.NewRequest("POST", "/"+testAliceHashedSigningKeyString, bytes.NewReader(testMessage))
+ response := executeRequest(req)
+
+ checkResponseCode(t, http.StatusNoContent, response.Code)
+
+ body := response.Body.String()
+ if body != "" {
+ t.Errorf("Expected empty response, Got %s", body)
+ }
+ testMessage2 := make([]byte, 256)
+ rand.Read(testMessage2)
+ req, _ = http.NewRequest("POST", "/"+testAliceHashedSigningKeyString, bytes.NewReader(testMessage2))
+ response = executeRequest(req)
+
+ checkResponseCode(t, http.StatusPaymentRequired, response.Code)
+
+ body = response.Body.String()
+ if body != "" {
+ t.Errorf("Expected empty response, Got %s", body)
+ }
+ setMailboxPaid(false)
+}
+
func TestGetKeysEmpty(t *testing.T) {
req, _ := http.NewRequest("GET", "/info/"+testAliceHashedSigningKeyString, nil)
response := executeRequest(req)
@@ -175,11 +219,11 @@ func TestMailboxRegistration(t *testing.T) {
aliceSigningKey := util.Base32CrockfordEncode(testAliceSigningKey)
msg.MailboxMetadata.EncryptionKey = util.Base32CrockfordEncode(encKey)
msg.MailboxMetadata.EncryptionKeyType = "X25519"
- msg.MailboxMetadata.Expiration = mailbox.Timestamp{T_s: uint64(time.Now().Add(time.Hour*24*365).UnixMilli() / 1000)}
+ msg.MailboxMetadata.Expiration = mailbox.Timestamp{Seconds: uint64(time.Now().Add(time.Hour*24*365).UnixMilli() / 1000)}
msg.MailboxMetadata.SigningKey = aliceSigningKey
msg.MailboxMetadata.SigningKeyType = "EdDSA"
expNbo := make([]byte, 8)
- binary.BigEndian.PutUint64(expNbo, msg.MailboxMetadata.Expiration.T_s)
+ binary.BigEndian.PutUint64(expNbo, msg.MailboxMetadata.Expiration.Seconds)
h := sha512.New()
h.Write([]byte(msg.MailboxMetadata.EncryptionKeyType))
h.Write(encKey)
@@ -218,8 +262,8 @@ func TestMailboxRegistration(t *testing.T) {
if respMsg.EncryptionKey != msg.MailboxMetadata.EncryptionKey {
fmt.Printf("Keys mismatch! %v %v\n", respMsg, msg.MailboxMetadata)
}
- a.Db.Where("1 = 1").Delete(&mailbox.MailboxMetadata{})
- a.Db.Where("1 = 1").Delete(&mailbox.PendingMailboxRegistration{})
+ a.DB.Where("1 = 1").Delete(&mailbox.MailboxMetadata{})
+ a.DB.Where("1 = 1").Delete(&mailbox.PendingMailboxRegistration{})
}
func TestMailboxRegistrationPaid(t *testing.T) {
@@ -236,11 +280,11 @@ func TestMailboxRegistrationPaid(t *testing.T) {
aliceSigningKey := util.Base32CrockfordEncode(testAliceSigningKey)
msg.MailboxMetadata.EncryptionKey = util.Base32CrockfordEncode(encKey)
msg.MailboxMetadata.EncryptionKeyType = "X25519"
- msg.MailboxMetadata.Expiration = mailbox.Timestamp{T_s: uint64(time.Now().Add(time.Hour * 24 * 365).UnixMicro())}
+ msg.MailboxMetadata.Expiration = mailbox.Timestamp{Seconds: uint64(time.Now().Add(time.Hour * 24 * 365).UnixMicro())}
msg.MailboxMetadata.SigningKey = aliceSigningKey
msg.MailboxMetadata.SigningKeyType = "EdDSA"
expNbo := make([]byte, 8)
- binary.BigEndian.PutUint64(expNbo, msg.MailboxMetadata.Expiration.T_s)
+ binary.BigEndian.PutUint64(expNbo, msg.MailboxMetadata.Expiration.Seconds)
h := sha512.New()
h.Write([]byte(msg.MailboxMetadata.EncryptionKeyType))
h.Write(encKey)
@@ -290,11 +334,12 @@ func TestMailboxRegistrationPaid(t *testing.T) {
}
func TestPostThenDeleteMessage(t *testing.T) {
- // testMessage := make([]byte, 256)
+
+ // make not paid
numMessagesToPost := (a.MessageResponseLimit + 7)
testMessages := make([]byte, 256*numMessagesToPost)
_, _ = rand.Read(testMessages)
- a.Db.Where("1 = 1").Delete(&mailbox.InboxEntry{})
+ a.DB.Where("1 = 1").Delete(&mailbox.InboxEntry{})
for i := 0; i < int(numMessagesToPost); i++ {
testMessage := testMessages[i*256 : (i+1)*256]
diff --git a/mailbox.conf.example b/mailbox.conf.example
@@ -5,6 +5,8 @@ production = false
message_body_bytes = 256
message_response_limit = 50
monthly_fee = KUDOS:0
+message_fee = KUDOS:0
+free_message_quota = 0
[mailbox-pq]
host = localhost
diff --git a/pkg/rest/mailbox.go b/pkg/rest/mailbox.go
@@ -16,6 +16,7 @@
//
// SPDX-License-Identifier: AGPL3.0-or-later
+// Package mailbox is a GNU Taler service. See https://docs.taler.net/core/api-mailbox.html
package mailbox
import (
@@ -76,7 +77,7 @@ type MailboxConfig struct {
Ini *ini.File
// DB connection
- Db gorm.Dialector
+ DB gorm.Dialector
// Merchant connection
Merchant merchant.Merchant
@@ -92,7 +93,7 @@ type Mailbox struct {
Router *mux.Router
// The main DB handle
- Db *gorm.DB
+ DB *gorm.DB
// Our configuration from the ini
Cfg MailboxConfig
@@ -104,7 +105,7 @@ type Mailbox struct {
Merchant merchant.Merchant
// Base URL
- BaseUrl string
+ BaseURL string
// Registration fee for each validity month mailbox
MonthlyFee *talerutil.Amount
@@ -112,6 +113,12 @@ type Mailbox struct {
// Registration fee for registering or modifying mailbox
RegistrationUpdateFee *talerutil.Amount
+ // Message fee for receiving a message
+ MessageFee *talerutil.Amount
+
+ // The free message quota
+ FreeMessageQuota uint64
+
// How many messages will a single response
// contain at maximum.
MessageResponseLimit uint64
@@ -124,11 +131,11 @@ type Mailbox struct {
}
type RelativeTime struct {
- D_us uint64 `json:"d_us"`
+ Microseconds uint64 `json:"d_us"`
}
type Timestamp struct {
- T_s uint64 `json:"t_s"`
+ Seconds uint64 `json:"t_s"`
}
// 1 Month as Go duration
@@ -164,6 +171,18 @@ type VersionResponse struct {
// registration period (30 days) of a mailbox
// May be 0 for a free registration.
MonthlyFee string `json:"monthly_fee"`
+
+ // How much is the cost to send a single
+ // message to a mailbox.
+ // May be 0 for free message sending.
+ MessageFee string `json:"message_fee"`
+
+ // How many messages can be send and
+ // are stored by the service for free.
+ // After the quota is reached, the
+ // regular message_fee applies.
+ // May be 0 for no free quota.
+ FreeMessageQuota string `json:"free_message_quota"`
}
type MailboxMetadata struct {
@@ -263,7 +282,7 @@ func (m *Mailbox) configResponse(w http.ResponseWriter, r *http.Request) {
MessageResponseLimit: m.MessageResponseLimit,
MonthlyFee: m.MonthlyFee.String(),
RegistrationUpdateFee: m.RegistrationUpdateFee.String(),
- DeliveryPeriod: RelativeTime{D_us: uint64(dp.Microseconds())},
+ DeliveryPeriod: RelativeTime{Microseconds: uint64(dp.Microseconds())},
}
w.Header().Set("Content-Type", "application/json")
response, _ := json.Marshal(cfg)
@@ -278,7 +297,7 @@ func (m *Mailbox) getMessagesResponse(w http.ResponseWriter, r *http.Request) {
// FIXME timeout
// FIXME possibly limit results here
m.checkPendingRegistrationUpdates(vars["h_mailbox"])
- err := m.Db.Where("hashed_signing_key = ?", vars["h_mailbox"]).Limit(int(m.MessageResponseLimit)).Find(&entries).Error
+ err := m.DB.Where("hashed_signing_key = ?", vars["h_mailbox"]).Limit(int(m.MessageResponseLimit)).Find(&entries).Error
if err != nil {
log.Printf("%v", err)
w.WriteHeader(http.StatusNotFound)
@@ -299,7 +318,6 @@ func (m *Mailbox) getMessagesResponse(w http.ResponseWriter, r *http.Request) {
func (m *Mailbox) sendMessageResponse(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var entry InboxEntry
- //var body = make([]byte, m.MessageBodyBytes)
if r.Body == nil {
http.Error(w, "No request body", http.StatusBadRequest)
return
@@ -308,21 +326,35 @@ func (m *Mailbox) sendMessageResponse(w http.ResponseWriter, r *http.Request) {
http.Error(w, "Wrong message size", http.StatusBadRequest)
return
}
- body, err := io.ReadAll(r.Body) //.Read(body)
+ body, err := io.ReadAll(r.Body)
if err != nil {
log.Printf("%v", err)
http.Error(w, "Cannot read body", http.StatusBadRequest)
return
}
+ if !m.MessageFee.IsZero() {
+ var count int64
+ err = m.DB.Model(&InboxEntry{}).Where("hashed_signing_key = ?", vars["h_mailbox"]).Count(&count).Error
+ if nil != err {
+ m.Logf(LogError, "%v", err)
+ http.Error(w, "Cannot look for entries", http.StatusBadRequest)
+ return
+ }
+ if count >= int64(m.FreeMessageQuota) {
+ w.WriteHeader(http.StatusPaymentRequired)
+ //w.Header().Set("Taler", payto) FIXME generate payto
+ return
+ }
+ }
m.checkPendingRegistrationUpdates(vars["h_mailbox"])
- err = m.Db.First(&entry, "hashed_signing_key = ? AND body = ?", vars["h_mailbox"], body, true).Error
+ err = m.DB.First(&entry, "hashed_signing_key = ? AND body = ?", vars["h_mailbox"], body, true).Error
if err == nil {
w.WriteHeader(http.StatusNotModified)
return
}
entry.HashedSigningKey = vars["h_mailbox"]
entry.Body = body
- m.Db.Save(&entry)
+ m.DB.Save(&entry)
w.WriteHeader(http.StatusNoContent)
}
@@ -330,13 +362,13 @@ func (m *Mailbox) getKeysResponse(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var keyEntry MailboxMetadata
m.checkPendingRegistrationUpdates(vars["h_mailbox"])
- err := m.Db.First(&keyEntry, "hashed_signing_key = ?", vars["h_mailbox"]).Error
+ err := m.DB.First(&keyEntry, "hashed_signing_key = ?", vars["h_mailbox"]).Error
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
}
- m.Logf(LogDebug, "entry expires at %d, have %d", keyEntry.Expiration.T_s, time.Now().Unix())
- if keyEntry.Expiration.T_s < uint64(time.Now().Unix()) {
+ m.Logf(LogDebug, "entry expires at %d, have %d", keyEntry.Expiration.Seconds, time.Now().Unix())
+ if keyEntry.Expiration.Seconds < uint64(time.Now().Unix()) {
w.WriteHeader(http.StatusNotFound)
return
}
@@ -360,7 +392,7 @@ func (m *Mailbox) validateRegistrationSignature(msg MailboxRegistrationRequest)
if nil != err {
return fmt.Errorf("unable to decode signature")
}
- binary.BigEndian.PutUint64(expNbo[:], msg.MailboxMetadata.Expiration.T_s)
+ binary.BigEndian.PutUint64(expNbo[:], msg.MailboxMetadata.Expiration.Seconds)
size := signedMsg[0:4]
binary.BigEndian.PutUint32(size, 64+4+4)
purp := signedMsg[4:8]
@@ -392,7 +424,7 @@ func calculateCost(sliceCostAmount string, fixedCostAmount string, howLong time.
Value: 0,
Fraction: 0,
}
- for i := 0; i < sliceCount; i++ {
+ for range sliceCount {
sum, err = sum.Add(*sliceCost)
if nil != err {
return nil, err
@@ -435,10 +467,10 @@ func (m *Mailbox) registerMailboxResponse(w http.ResponseWriter, r *http.Request
hMailbox := util.Base32CrockfordEncode(h.Sum(nil))
pendingRegistration.HashedSigningKey = hMailbox
// Round to the nearest multiple of a month
- reqExpiration := time.Unix(int64(msg.MailboxMetadata.Expiration.T_s), 0)
+ reqExpiration := time.Unix(int64(msg.MailboxMetadata.Expiration.Seconds), 0)
now := time.Now()
reqDuration := reqExpiration.Sub(now).Round(monthDuration)
- err = m.Db.First(®istrationEntry, "hashed_signing_key = ?", hMailbox).Error
+ err = m.DB.First(®istrationEntry, "hashed_signing_key = ?", hMailbox).Error
if err == nil {
// This probably meansthe registration is modified or extended or both
entryModified := (registrationEntry.EncryptionKey != msg.MailboxMetadata.EncryptionKey)
@@ -451,17 +483,17 @@ func (m *Mailbox) registerMailboxResponse(w http.ResponseWriter, r *http.Request
} else {
// Entry does not yet exist, add but immediately expire it
registrationEntry = msg.MailboxMetadata
- registrationEntry.Expiration.T_s = uint64(time.Now().Unix() - 1)
+ registrationEntry.Expiration.Seconds = uint64(time.Now().Unix() - 1)
hAddr := sha512.New()
hAddr.Write(pk)
registrationEntry.HashedSigningKey = util.Base32CrockfordEncode(hAddr.Sum(nil))
- err = m.Db.Create(®istrationEntry).Error
+ err = m.DB.Create(®istrationEntry).Error
if nil != err {
w.WriteHeader(http.StatusInternalServerError)
return
}
}
- err = m.Db.First(&pendingRegistration, "hashed_signing_key = ?", hMailbox).Error
+ err = m.DB.First(&pendingRegistration, "hashed_signing_key = ?", hMailbox).Error
pendingRegistrationExists := (nil == err)
if !pendingRegistrationExists {
pendingRegistration.HashedSigningKey = hMailbox
@@ -480,7 +512,7 @@ func (m *Mailbox) registerMailboxResponse(w http.ResponseWriter, r *http.Request
if !cost.IsZero() {
if len(pendingRegistration.OrderID) == 0 {
// Add new order
- orderID, newOrderErr := m.Merchant.AddNewOrder(*cost, "Mailbox registration", m.BaseUrl)
+ orderID, newOrderErr := m.Merchant.AddNewOrder(*cost, "Mailbox registration", m.BaseURL)
if newOrderErr != nil {
m.Logf(LogError, "%v", newOrderErr)
w.WriteHeader(http.StatusInternalServerError)
@@ -496,20 +528,20 @@ func (m *Mailbox) registerMailboxResponse(w http.ResponseWriter, r *http.Request
if paytoErr != nil {
fmt.Println(paytoErr)
w.WriteHeader(http.StatusInternalServerError)
- m.Logf(LogError, paytoErr.Error()+"\n")
+ m.Logf(LogError, "%s\n", paytoErr.Error())
return
}
if len(payto) != 0 {
- m.Db.Save(&pendingRegistration)
+ m.DB.Save(&pendingRegistration)
w.WriteHeader(http.StatusPaymentRequired)
- w.Header().Set("Taler", payto) // FIXME no idea what to do with this.
+ w.Header().Set("Taler", payto)
return
}
}
// Update expiration time of registration.
- registrationEntry.Expiration.T_s += uint64(reqDuration.Seconds())
- m.Db.Delete(pendingRegistration)
- err = m.Db.Save(®istrationEntry).Error
+ registrationEntry.Expiration.Seconds += uint64(reqDuration.Seconds())
+ m.DB.Delete(pendingRegistration)
+ err = m.DB.Save(®istrationEntry).Error
if nil != err {
w.WriteHeader(http.StatusInternalServerError)
return
@@ -520,7 +552,7 @@ func (m *Mailbox) registerMailboxResponse(w http.ResponseWriter, r *http.Request
func (m *Mailbox) checkPendingRegistrationUpdates(hMailbox string) {
var pendingEntry PendingMailboxRegistration
var registrationEntry MailboxMetadata
- err := m.Db.First(&pendingEntry, "hashed_signing_key = ?", hMailbox).Error
+ err := m.DB.First(&pendingEntry, "hashed_signing_key = ?", hMailbox).Error
if err != nil {
return
}
@@ -530,7 +562,7 @@ func (m *Mailbox) checkPendingRegistrationUpdates(hMailbox string) {
if rc == http.StatusNotFound {
m.Logf(LogInfo, "Registration order for `%s' not found, removing\n", hMailbox)
}
- err := m.Db.Delete(&pendingEntry)
+ err := m.DB.Delete(&pendingEntry)
if nil != err {
m.Logf(LogInfo, "%v\n", err)
}
@@ -539,12 +571,12 @@ func (m *Mailbox) checkPendingRegistrationUpdates(hMailbox string) {
m.Logf(LogDebug, "Order status for %s is %s", pendingEntry.HashedSigningKey, orderStatus)
if merchant.OrderPaid == orderStatus {
m.Logf(LogDebug, "Order for %v appears to be paid", pendingEntry)
- err = m.Db.First(®istrationEntry, "hashed_signing_key = ?", hMailbox).Error
+ err = m.DB.First(®istrationEntry, "hashed_signing_key = ?", hMailbox).Error
if err == nil {
m.Logf(LogDebug, "Adding %d seconds to entry expiration", uint64(pendingEntry.Duration.Seconds()))
- registrationEntry.Expiration.T_s += uint64(pendingEntry.Duration.Seconds())
- m.Db.Save(®istrationEntry)
- err := m.Db.Delete(&pendingEntry)
+ registrationEntry.Expiration.Seconds += uint64(pendingEntry.Duration.Seconds())
+ m.DB.Save(®istrationEntry)
+ err := m.DB.Delete(&pendingEntry)
if nil != err {
m.Logf(LogInfo, "%v\n", err)
}
@@ -609,20 +641,20 @@ func (m *Mailbox) deleteMessagesResponse(w http.ResponseWriter, r *http.Request)
return
}
// Check that expectedETag actually exists
- err = m.Db.Where("hashed_signing_key = ? AND id = ?", hHailbox, expectedETag).Find(&InboxEntry{}).Error
+ err = m.DB.Where("hashed_signing_key = ? AND id = ?", hHailbox, expectedETag).Find(&InboxEntry{}).Error
if err != nil {
m.Logf(LogDebug, "Message to delete not found with ID %d", expectedETag)
w.WriteHeader(http.StatusNotFound)
return
}
var entries []InboxEntry
- err = m.Db.Where("hashed_signing_key = ? AND id >= ?", hHailbox, expectedETag).Limit(count).Find(&entries).Error
+ err = m.DB.Where("hashed_signing_key = ? AND id >= ?", hHailbox, expectedETag).Limit(count).Find(&entries).Error
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
m.Logf(LogDebug, "Found matching ID, deleting %d messages", len(entries))
- m.Db.Delete(entries)
+ m.DB.Delete(entries)
w.WriteHeader(http.StatusNoContent)
}
@@ -692,42 +724,49 @@ func (m *Mailbox) Initialize(cfg MailboxConfig) {
if cfg.Ini.Section("mailbox").Key("production").MustBool(false) {
fmt.Println("Production mode enabled")
}
- m.BaseUrl = cfg.Ini.Section("mailbox").Key("base_url").MustString("https://example.com")
+ m.BaseURL = cfg.Ini.Section("mailbox").Key("base_url").MustString("https://example.com")
m.MessageBodyBytes = cfg.Ini.Section("mailbox").Key("message_body_bytes").MustInt64(256)
m.MessageResponseLimit = cfg.Ini.Section("mailbox").Key("message_response_limit").MustUint64(50)
monthlyFee, err := talerutil.ParseAmount(cfg.Ini.Section("mailbox").Key("monthly_fee").MustString("KUDOS:0"))
if err != nil {
- fmt.Printf("Failed to parse cost: %v", err)
+ fmt.Printf("Failed to parse monthly fee: %v", err)
os.Exit(1)
}
m.MonthlyFee = monthlyFee
updateFee, err := talerutil.ParseAmount(cfg.Ini.Section("mailbox").Key("registration_update_fee").MustString("KUDOS:0"))
if err != nil {
- fmt.Printf("Failed to parse cost: %v", err)
+ fmt.Printf("Failed to parse update fee: %v", err)
os.Exit(1)
}
m.RegistrationUpdateFee = updateFee
- _db, err := gorm.Open(cfg.Db, &gorm.Config{
+ messageFee, err := talerutil.ParseAmount(cfg.Ini.Section("mailbox").Key("message_fee").MustString("KUDOS:0"))
+ if err != nil {
+ fmt.Printf("Failed to parse message fee: %v", err)
+ os.Exit(1)
+ }
+ m.MessageFee = messageFee
+ m.FreeMessageQuota = cfg.Ini.Section("mailbox").Key("free_message_quota").MustUint64(0)
+ _db, err := gorm.Open(cfg.DB, &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent),
})
if err != nil {
panic(err)
}
- m.Db = _db
- if err := m.Db.AutoMigrate(&InboxEntry{}); err != nil {
+ m.DB = _db
+ if err := m.DB.AutoMigrate(&InboxEntry{}); err != nil {
panic(err)
}
- if err := m.Db.AutoMigrate(&MailboxMetadata{}); err != nil {
+ if err := m.DB.AutoMigrate(&MailboxMetadata{}); err != nil {
panic(err)
}
go func() {
for {
- tx := m.Db.Where("expiration < ?", time.Now()).Delete(&MailboxMetadata{})
+ tx := m.DB.Where("expiration < ?", time.Now()).Delete(&MailboxMetadata{})
m.Logf(LogInfo, "Cleaned up %d stale registrations.\n", tx.RowsAffected)
time.Sleep(time.Hour * 24)
}
}()
- if err := m.Db.AutoMigrate(&PendingMailboxRegistration{}); err != nil {
+ if err := m.DB.AutoMigrate(&PendingMailboxRegistration{}); err != nil {
panic(err)
}
// Clean up pending
@@ -739,7 +778,7 @@ func (m *Mailbox) Initialize(cfg MailboxConfig) {
}
go func() {
for {
- tx := m.Db.Where("created_at < ?", time.Now().Add(-pendingExp)).Delete(&PendingMailboxRegistration{})
+ tx := m.DB.Where("created_at < ?", time.Now().Add(-pendingExp)).Delete(&PendingMailboxRegistration{})
m.Logf(LogInfo, "Cleaned up %d stale pending registrations.\n", tx.RowsAffected)
time.Sleep(pendingExp)
}