Skip to content

Commit

Permalink
add subfolder push
Browse files Browse the repository at this point in the history
  • Loading branch information
Frederik Schwan authored and freswa committed Oct 13, 2024
1 parent 00c564c commit e4ba0d1
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 14 deletions.
61 changes: 55 additions & 6 deletions internal/apns.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package internal

import (
"crypto/md5"
"crypto/tls"
"crypto/x509"
"encoding/hex"
"encoding/json"
"errors"
"github.com/freswa/dovecot-xaps-daemon/internal/config"
"github.com/freswa/dovecot-xaps-daemon/internal/database"
Expand All @@ -11,6 +14,7 @@ import (
log "github.com/sirupsen/logrus"
"golang.org/x/net/http2"
"net/http"
"strings"
"sync"
"time"
)
Expand All @@ -34,16 +38,23 @@ type Apns struct {
db *database.Database
mapMutex sync.Mutex
delayedApns map[database.Registration]time.Time
delayedMailboxes map[database.Registration]PushedMailboxes
RenewTimer *time.Timer
}

type PushedMailboxes struct {
mailboxes []string
registration database.Registration
}

func NewApns(cfg *config.Config, db *database.Database) (apns *Apns) {
apns = &Apns{
DelayTime: cfg.Delay,
CheckDelayedInterval: cfg.CheckInterval,
db: db,
mapMutex: sync.Mutex{},
delayedApns: make(map[database.Registration]time.Time),
delayedMailboxes: make(map[database.Registration]PushedMailboxes),
}
log.Debugln("APNS for non NewMessage events will be delayed for", time.Second*time.Duration(apns.DelayTime))
log.Debugln("Trying to get existing certs from the DB")
Expand Down Expand Up @@ -136,18 +147,25 @@ func (apns *Apns) checkDelayed() {
}
apns.mapMutex.Unlock()
for _, reg := range sendNow {
apns.SendNotification(reg, false)
apns.mapMutex.Lock()
mbox := apns.delayedMailboxes[reg]
apns.mapMutex.Unlock()
apns.SendNotification(reg, mbox, false)
}
}

func (apns *Apns) SendNotification(registration database.Registration, delayed bool) {
func (apns *Apns) SendNotification(registration database.Registration, mailboxes PushedMailboxes, delayed bool) {
apns.mapMutex.Lock()
if delayed {
log.Debugln("Delaying notification for", registration.AccountId, "/", registration.DeviceToken, "for mailboxes", mailboxes.toString())
apns.delayedApns[registration] = time.Now()
apns.delayedMailboxes[registration] = mailboxes.merge(apns.delayedMailboxes[registration])
apns.mapMutex.Unlock()
return
} else {
delete(apns.delayedApns, registration)
mailboxes = mailboxes.merge(apns.delayedMailboxes[registration])
delete(apns.delayedMailboxes, registration)
apns.mapMutex.Unlock()
}
log.Debugln("Sending notification to", registration.AccountId, "/", registration.DeviceToken)
Expand All @@ -157,17 +175,16 @@ func (apns *Apns) SendNotification(registration database.Registration, delayed b
notification.Topic = apns.Topic
composedPayload := []byte(`{"aps":{`)
composedPayload = append(composedPayload, []byte(`"account-id":"`+registration.AccountId+`"`)...)
composedPayload = append(composedPayload, []byte(`,"m":`)...)
m, _ := json.Marshal(mailboxes.toHashes())
composedPayload = append(composedPayload, m...)
composedPayload = append(composedPayload, []byte(`}}`)...)
notification.Payload = composedPayload
notification.PushType = apns2.PushTypeBackground
notification.Expiration = time.Now().Add(24 * time.Hour)
// set the apns-priority
//notification.Priority = apns2.PriorityLow

if log.IsLevelEnabled(log.DebugLevel) {
dbgstr, _ := notification.MarshalJSON()
log.Debugf("Sending: %s", dbgstr)
}
res, err := apns.client.Push(notification)

if err != nil {
Expand Down Expand Up @@ -220,3 +237,35 @@ func certificateNotValidAfter(certificate *tls.Certificate) time.Time {
}
return cert.NotAfter
}

func (pm *PushedMailboxes) AddMailbox(mailbox string) {
present := false
for _, mb := range pm.mailboxes {
if mb == mailbox {
present = true
}
}
if !present {
pm.mailboxes = append(pm.mailboxes, mailbox)
}
}

func (pm *PushedMailboxes) toHashes() []string {
var mbh = make([]string, 0)
for _, m := range pm.mailboxes {
md5sum := md5.Sum([]byte(m))
mbh = append(mbh, hex.EncodeToString(md5sum[:]))
}
return mbh
}

func (pm *PushedMailboxes) toString() string {
return strings.Join(pm.mailboxes, ", ")
}

func (pm *PushedMailboxes) merge(anotherPm PushedMailboxes) PushedMailboxes {
for _, mb := range anotherPm.mailboxes {
pm.AddMailbox(mb)
}
return *pm
}
11 changes: 3 additions & 8 deletions internal/socket.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,6 @@ func (httpHandler *httpHandler) handleNotify(writer http.ResponseWriter, request
}
}

// we don't know how to handle other mailboxes other than INBOX, so ignore them
if notify.Mailbox != "INBOX" {
log.Debugln("Ignoring non INBOX event for:", notify.Mailbox)
writer.WriteHeader(http.StatusOK)
return
}

// Find all the devices registered for this mailbox event
registrations, err := httpHandler.db.FindRegistrations(notify.Username, notify.Mailbox)
if err != nil {
Expand All @@ -179,7 +172,9 @@ func (httpHandler *httpHandler) handleNotify(writer http.ResponseWriter, request
// Send a notification to all registered devices. We ignore failures
// because there is not a lot we can do.
for _, registration := range registrations {
httpHandler.apns.SendNotification(registration, !isMessageNew)
pm := PushedMailboxes{}
pm.AddMailbox(notify.Mailbox)
httpHandler.apns.SendNotification(registration, pm, !isMessageNew)
}

writer.WriteHeader(http.StatusOK)
Expand Down

0 comments on commit e4ba0d1

Please sign in to comment.