forked from othman.suseno/Mail-Migrator
fix and recompile
This commit is contained in:
51
imap.go
51
imap.go
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/emersion/go-imap"
|
||||
"github.com/emersion/go-imap/client"
|
||||
"github.com/emersion/go-sasl"
|
||||
"github.com/sirupsen/logrus"
|
||||
bolt "go.etcd.io/bbolt"
|
||||
)
|
||||
@@ -43,20 +44,37 @@ func parseIMAPURL(rawURL string) (*IMAPConfig, error) {
|
||||
}
|
||||
|
||||
password, _ := u.User.Password()
|
||||
// URL decode the password to handle special characters
|
||||
if password != "" {
|
||||
if decodedPassword, err := url.QueryUnescape(password); err == nil {
|
||||
password = decodedPassword
|
||||
}
|
||||
}
|
||||
|
||||
username := u.User.Username()
|
||||
// URL decode the username to handle special characters
|
||||
if username != "" {
|
||||
if decodedUsername, err := url.QueryUnescape(username); err == nil {
|
||||
username = decodedUsername
|
||||
}
|
||||
}
|
||||
|
||||
return &IMAPConfig{
|
||||
Host: u.Hostname(),
|
||||
Port: port,
|
||||
Username: u.User.Username(),
|
||||
Username: username,
|
||||
Password: password,
|
||||
UseTLS: port == 993 || u.Scheme == "imaps",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// connectIMAP creates IMAP client connection
|
||||
func connectIMAP(cfg *IMAPConfig, insecure bool) (*client.Client, error) {
|
||||
addr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
|
||||
|
||||
// Debug logging (mask password for security)
|
||||
maskedPassword := strings.Repeat("*", len(cfg.Password))
|
||||
logrus.Debugf("Connecting to %s with username: %s, password: %s", addr, cfg.Username, maskedPassword)
|
||||
|
||||
var c *client.Client
|
||||
var err error
|
||||
|
||||
@@ -74,9 +92,34 @@ func connectIMAP(cfg *IMAPConfig, insecure bool) (*client.Client, error) {
|
||||
return nil, fmt.Errorf("dial failed: %w", err)
|
||||
}
|
||||
|
||||
// Check server capabilities first
|
||||
caps, errCaps := c.Capability()
|
||||
if errCaps != nil {
|
||||
logrus.Debugf("Failed to get capabilities: %v", errCaps)
|
||||
caps = make(map[string]bool) // fallback to empty map
|
||||
} else {
|
||||
logrus.Debugf("Server capabilities: %v", caps)
|
||||
}
|
||||
|
||||
// Try LOGIN first
|
||||
if err := c.Login(cfg.Username, cfg.Password); err != nil {
|
||||
c.Close()
|
||||
return nil, fmt.Errorf("login failed: %w", err)
|
||||
logrus.Debugf("LOGIN failed: %v", err)
|
||||
|
||||
// Try AUTHENTICATE PLAIN as fallback
|
||||
if caps["AUTH=PLAIN"] || caps["AUTH=PLAIN-CLIENT-FIRST"] {
|
||||
logrus.Debugf("Trying AUTHENTICATE PLAIN")
|
||||
auth := sasl.NewPlainClient("", cfg.Username, cfg.Password)
|
||||
if authErr := c.Authenticate(auth); authErr != nil {
|
||||
c.Close()
|
||||
return nil, fmt.Errorf("login failed: %w (also tried AUTHENTICATE PLAIN: %v)", err, authErr)
|
||||
}
|
||||
logrus.Debugf("AUTHENTICATE PLAIN succeeded")
|
||||
} else {
|
||||
c.Close()
|
||||
return nil, fmt.Errorf("login failed: %w", err)
|
||||
}
|
||||
} else {
|
||||
logrus.Debugf("LOGIN succeeded")
|
||||
}
|
||||
|
||||
logrus.Infof("Connected to %s as %s", addr, cfg.Username)
|
||||
|
||||
Reference in New Issue
Block a user