mirror of
https://github.com/neilalexander/yggmail.git
synced 2026-05-09 05:06:28 +03:00
Very early NOTIFY support, hopefully fix -password on Windows
This commit is contained in:
@@ -16,6 +16,7 @@ type Backend struct {
|
||||
Config *config.Config
|
||||
Log *log.Logger
|
||||
Storage storage.Storage
|
||||
Server *IMAPServer
|
||||
}
|
||||
|
||||
func (b *Backend) Login(conn *imap.ConnInfo, username, password string) (backend.User, error) {
|
||||
@@ -38,6 +39,26 @@ func (b *Backend) Login(conn *imap.ConnInfo, username, password string) (backend
|
||||
user := &User{
|
||||
backend: b,
|
||||
username: username,
|
||||
conn: conn,
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
/*
|
||||
func (b *Backend) NotifyNew(id int) error {
|
||||
b.Server.server.ForEachConn(func(conn server.Conn) {
|
||||
notify := false
|
||||
for _, cap := range conn.Capabilities() {
|
||||
if cap == "NOTIFY" {
|
||||
notify = true
|
||||
}
|
||||
}
|
||||
if !notify {
|
||||
return
|
||||
}
|
||||
conn.WaitReady()
|
||||
conn.WriteResp()
|
||||
})
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
package imapserver
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
idle "github.com/emersion/go-imap-idle"
|
||||
"github.com/emersion/go-imap/server"
|
||||
"github.com/emersion/go-sasl"
|
||||
)
|
||||
|
||||
type IMAPServer struct {
|
||||
@@ -10,11 +14,27 @@ type IMAPServer struct {
|
||||
backend *Backend
|
||||
}
|
||||
|
||||
func NewIMAPServer(backend *Backend) (*IMAPServer, error) {
|
||||
func NewIMAPServer(backend *Backend, addr string, insecure bool) (*IMAPServer, *IMAPNotify, error) {
|
||||
s := &IMAPServer{
|
||||
server: server.New(backend),
|
||||
backend: backend,
|
||||
}
|
||||
notify := NewIMAPNotify(s.server, backend.Log)
|
||||
s.server.Addr = addr
|
||||
s.server.AllowInsecureAuth = insecure
|
||||
s.server.Debug = os.Stdout
|
||||
s.server.Enable(idle.NewExtension())
|
||||
return s, nil
|
||||
s.server.Enable(notify)
|
||||
s.server.EnableAuth(sasl.Login, func(conn server.Conn) sasl.Server {
|
||||
return sasl.NewLoginServer(func(username, password string) error {
|
||||
_, err := s.backend.Login(nil, username, password)
|
||||
return err
|
||||
})
|
||||
})
|
||||
go func() {
|
||||
if err := s.server.ListenAndServe(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}()
|
||||
return s, notify, nil
|
||||
}
|
||||
|
||||
65
internal/imapserver/notify.go
Normal file
65
internal/imapserver/notify.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package imapserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/emersion/go-imap"
|
||||
"github.com/emersion/go-imap/server"
|
||||
)
|
||||
|
||||
type IMAPNotifyHandler struct {
|
||||
imap.Command
|
||||
}
|
||||
|
||||
func (h *IMAPNotifyHandler) Handle(conn server.Conn) error {
|
||||
// TODO: Support setting NOTIFY subscriptions or not
|
||||
return nil
|
||||
}
|
||||
|
||||
type IMAPNotify struct {
|
||||
server *server.Server
|
||||
log *log.Logger
|
||||
}
|
||||
|
||||
func (ext *IMAPNotify) Capabilities(c server.Conn) []string {
|
||||
if c.Context().State&imap.AuthenticatedState != 0 {
|
||||
return []string{"NOTIFY"}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ext *IMAPNotify) Command(name string) server.HandlerFactory {
|
||||
if name != "NOTIFY" {
|
||||
return nil
|
||||
}
|
||||
return func() server.Handler {
|
||||
return &IMAPNotifyHandler{}
|
||||
}
|
||||
}
|
||||
|
||||
func (ext *IMAPNotify) NotifyNew(id, count int) error {
|
||||
ext.server.ForEachConn(func(c server.Conn) {
|
||||
var resptype imap.StatusRespType
|
||||
if mailbox := c.Context().Mailbox; mailbox != nil && mailbox.Name() == "INBOX" {
|
||||
resptype = imap.StatusRespType(
|
||||
fmt.Sprintf("EXISTS %d", id),
|
||||
)
|
||||
} else {
|
||||
resptype = imap.StatusRespType(
|
||||
fmt.Sprintf("STATUS INBOX (UIDNEXT %d MESSAGES %d)", id+1, count),
|
||||
)
|
||||
}
|
||||
_ = c.WriteResp(&imap.StatusResp{
|
||||
Type: resptype,
|
||||
})
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewIMAPNotify(s *server.Server, log *log.Logger) *IMAPNotify {
|
||||
return &IMAPNotify{
|
||||
server: s,
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,14 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/emersion/go-imap"
|
||||
"github.com/emersion/go-imap/backend"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
backend *Backend
|
||||
username string
|
||||
conn *imap.ConnInfo
|
||||
}
|
||||
|
||||
func (u *User) Username() string {
|
||||
|
||||
Reference in New Issue
Block a user