fix(GODT-3122): use display name as 'Email Account Name' in macOS profile.

This commit is contained in:
Xavier Michelon
2023-11-15 16:51:41 +01:00
parent 5a434fafbc
commit 36c5c37dac
3 changed files with 56 additions and 19 deletions

View File

@ -19,19 +19,22 @@ package bridge
import ( import (
"context" "context"
"errors"
"strings" "strings"
"github.com/ProtonMail/proton-bridge/v3/internal/clientconfig" "github.com/ProtonMail/proton-bridge/v3/internal/clientconfig"
"github.com/ProtonMail/proton-bridge/v3/internal/constants" "github.com/ProtonMail/proton-bridge/v3/internal/constants"
"github.com/ProtonMail/proton-bridge/v3/internal/logging" "github.com/ProtonMail/proton-bridge/v3/internal/logging"
"github.com/ProtonMail/proton-bridge/v3/internal/safe" "github.com/ProtonMail/proton-bridge/v3/internal/safe"
userpkg "github.com/ProtonMail/proton-bridge/v3/internal/user"
"github.com/ProtonMail/proton-bridge/v3/internal/useragent" "github.com/ProtonMail/proton-bridge/v3/internal/useragent"
"github.com/ProtonMail/proton-bridge/v3/internal/vault" "github.com/ProtonMail/proton-bridge/v3/internal/vault"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/exp/slices"
) )
// ConfigureAppleMail configures apple mail for the given userID and address. // ConfigureAppleMail configures Apple Mail for the given userID and address.
// If configuring apple mail for Catalina or newer, it ensures Bridge is using SSL. // If configuring Apple Mail for Catalina or newer, it ensures Bridge is using SSL.
func (bridge *Bridge) ConfigureAppleMail(ctx context.Context, userID, address string) error { func (bridge *Bridge) ConfigureAppleMail(ctx context.Context, userID, address string) error {
logrus.WithFields(logrus.Fields{ logrus.WithFields(logrus.Fields{
"userID": userID, "userID": userID,
@ -44,16 +47,31 @@ func (bridge *Bridge) ConfigureAppleMail(ctx context.Context, userID, address st
return ErrNoSuchUser return ErrNoSuchUser
} }
if address == "" { identities := user.Identities()
address = user.Emails()[0] if len(identities) == 0 {
return errors.New("could not retrieve user identities")
} }
username := address if address == "" {
addresses := address address = identities[0].Email
}
var username, displayName, addresses string
if user.GetAddressMode() == vault.CombinedMode { if user.GetAddressMode() == vault.CombinedMode {
username = user.Emails()[0] username = identities[0].Email
displayName = identities[0].DisplayName
addresses = strings.Join(user.Emails(), ",") addresses = strings.Join(user.Emails(), ",")
} else {
username = address
addresses = address
index := slices.IndexFunc(identities, func(identity userpkg.Identity) bool {
return strings.EqualFold(identity.Email, address)
})
if index >= 0 {
displayName = identities[index].DisplayName
} else {
displayName = address
}
} }
if useragent.IsCatalinaOrNewer() && !bridge.vault.GetSMTPSSL() { if useragent.IsCatalinaOrNewer() && !bridge.vault.GetSMTPSSL() {
@ -69,6 +87,7 @@ func (bridge *Bridge) ConfigureAppleMail(ctx context.Context, userID, address st
bridge.vault.GetIMAPSSL(), bridge.vault.GetIMAPSSL(),
bridge.vault.GetSMTPSSL(), bridge.vault.GetSMTPSSL(),
username, username,
displayName,
addresses, addresses,
user.BridgePass(), user.BridgePass(),
) )

View File

@ -39,10 +39,10 @@ func (c *AppleMail) Configure(
hostname string, hostname string,
imapPort, smtpPort int, imapPort, smtpPort int,
imapSSL, smtpSSL bool, imapSSL, smtpSSL bool,
username, addresses string, username, displayName, addresses string,
password []byte, password []byte,
) error { ) error {
mc := prepareMobileConfig(hostname, imapPort, smtpPort, imapSSL, smtpSSL, username, addresses, password) mc := prepareMobileConfig(hostname, imapPort, smtpPort, imapSSL, smtpSSL, username, displayName, addresses, password)
confPath, err := saveConfigTemporarily(mc) confPath, err := saveConfigTemporarily(mc)
if err != nil { if err != nil {
@ -66,13 +66,13 @@ func prepareMobileConfig(
hostname string, hostname string,
imapPort, smtpPort int, imapPort, smtpPort int,
imapSSL, smtpSSL bool, imapSSL, smtpSSL bool,
username, addresses string, username, displayName, addresses string,
password []byte, password []byte,
) *mobileconfig.Config { ) *mobileconfig.Config {
return &mobileconfig.Config{ return &mobileconfig.Config{
DisplayName: username, DisplayName: username,
EmailAddress: addresses, EmailAddress: addresses,
AccountName: username, AccountName: displayName,
AccountDescription: username, AccountDescription: username,
Identifier: "protonmail " + username + strconv.FormatInt(time.Now().Unix(), 10), Identifier: "protonmail " + username + strconv.FormatInt(time.Now().Unix(), 10),
IMAP: &mobileconfig.IMAP{ IMAP: &mobileconfig.IMAP{

View File

@ -58,6 +58,11 @@ const (
SyncRetryCooldown = 20 * time.Second SyncRetryCooldown = 20 * time.Second
) )
type Identity struct {
DisplayName string
Email string
}
type User struct { type User struct {
id string id string
log *logrus.Entry log *logrus.Entry
@ -378,19 +383,16 @@ func (user *User) Match(query string) bool {
return false return false
} }
func (user *User) Identities() []Identity {
// Emails returns all the user's active email addresses.
// It returns them in sorted order; the user's primary address is first.
func (user *User) Emails() []string {
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Minute)) ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Minute))
defer cancel() defer cancel()
apiAddrs, err := user.identityService.GetAddresses(ctx) apiAddresses, err := user.identityService.GetAddresses(ctx)
if err != nil { if err != nil {
return nil return nil
} }
addresses := xslices.Filter(maps.Values(apiAddrs), func(addr proton.Address) bool { addresses := xslices.Filter(maps.Values(apiAddresses), func(addr proton.Address) bool {
return addr.Status == proton.AddressStatusEnabled && addr.Type != proton.AddressTypeExternal return addr.Status == proton.AddressStatusEnabled && addr.Type != proton.AddressTypeExternal
}) })
@ -398,8 +400,24 @@ func (user *User) Emails() []string {
return a.Order < b.Order return a.Order < b.Order
}) })
return xslices.Map(addresses, func(addr proton.Address) string { return xslices.Map(addresses, func(addr proton.Address) Identity {
return addr.Email return Identity{
DisplayName: addr.DisplayName,
Email: addr.Email,
}
})
}
// Emails returns all the user's active email addresses.
// It returns them in sorted order; the user's primary address is first.
func (user *User) Emails() []string {
identities := user.Identities()
if identities == nil {
return nil
}
return xslices.Map(identities, func(identity Identity) string {
return identity.Email
}) })
} }