diff --git a/imap/backend.go b/imap/backend.go index 1d79550..35b8264 100644 --- a/imap/backend.go +++ b/imap/backend.go @@ -28,9 +28,12 @@ func (be *backend) Login(username, password string) (imapbackend.User, error) { return nil, err } - // TODO: decrypt private keys in u.Addresses + addrs, err := c.ListAddresses() + if err != nil { + return nil, err + } - return newUser(be, c, u, privateKeys) + return newUser(be, c, u, privateKeys, addrs) } func (be *backend) Updates() <-chan imapbackend.Update { diff --git a/imap/mailbox.go b/imap/mailbox.go index a413cf2..98d8e30 100644 --- a/imap/mailbox.go +++ b/imap/mailbox.go @@ -366,7 +366,7 @@ func (mbox *mailbox) CreateMessage(flags []string, date time.Time, body imap.Lit return err } - _, err := createMessage(mbox.u.c, mbox.u.u, mbox.u.privateKeys, body) + _, err := createMessage(mbox.u.c, mbox.u.u, mbox.u.privateKeys, mbox.u.addrs, body) if err != nil { return err } diff --git a/imap/message.go b/imap/message.go index 6cbb58d..5044dfd 100644 --- a/imap/message.go +++ b/imap/message.go @@ -376,7 +376,7 @@ func (mbox *mailbox) fetchBodySection(msg *protonmail.Message, section *imap.Bod return l, nil } -func createMessage(c *protonmail.Client, u *protonmail.User, privateKeys openpgp.EntityList, r io.Reader) (*protonmail.Message, error) { +func createMessage(c *protonmail.Client, u *protonmail.User, privateKeys openpgp.EntityList, addrs []*protonmail.Address, r io.Reader) (*protonmail.Message, error) { // Parse the incoming MIME message header mr, err := mail.CreateReader(r) if err != nil { @@ -398,7 +398,7 @@ func createMessage(c *protonmail.Client, u *protonmail.User, privateKeys openpgp fromAddrStr := fromList[0].Address var fromAddr *protonmail.Address - for _, addr := range u.Addresses { + for _, addr := range addrs { if strings.EqualFold(addr.Email, fromAddrStr) { fromAddr = addr break diff --git a/imap/user.go b/imap/user.go index 57993fa..630c6a5 100644 --- a/imap/user.go +++ b/imap/user.go @@ -33,6 +33,7 @@ type user struct { c *protonmail.Client u *protonmail.User privateKeys openpgp.EntityList + addrs []*protonmail.Address db *database.User eventsReceiver *events.Receiver @@ -44,11 +45,12 @@ type user struct { eventSent chan struct{} } -func newUser(be *backend, c *protonmail.Client, u *protonmail.User, privateKeys openpgp.EntityList) (*user, error) { +func newUser(be *backend, c *protonmail.Client, u *protonmail.User, privateKeys openpgp.EntityList, addrs []*protonmail.Address) (*user, error) { uu := &user{ c: c, u: u, privateKeys: privateKeys, + addrs: addrs, eventSent: make(chan struct{}), } diff --git a/protonmail/adresses.go b/protonmail/adresses.go index c4b48b2..8e18a05 100644 --- a/protonmail/adresses.go +++ b/protonmail/adresses.go @@ -1,5 +1,9 @@ package protonmail +import ( + "net/http" +) + type ( AddressSend int AddressStatus int @@ -37,3 +41,21 @@ type Address struct { HasKeys int Keys []*PrivateKey } + +func (c *Client) ListAddresses() ([]*Address, error) { + // TODO: Page, PageSize + req, err := c.newRequest(http.MethodGet, "/addresses", nil) + if err != nil { + return nil, err + } + + var respData struct { + resp + Addresses []*Address + } + if err := c.doJSON(req, &respData); err != nil { + return nil, err + } + + return respData.Addresses, nil +} diff --git a/protonmail/users.go b/protonmail/users.go index 426f677..a60fa01 100644 --- a/protonmail/users.go +++ b/protonmail/users.go @@ -15,53 +15,19 @@ type ( ) type User struct { - ID string - Name string - NotificationEmail string - Signature string // HTML - NumMessagePerPage int - UsedSpace int - Notify int - AutoSaveContacts int - Language string // e.g. en_US - LogAuth LogAuth - ComposerMode ComposerMode - MessageButtons MessageButtons - Images ImagesMode - Moved int - ShowImages int - ShowEmbedded int - ViewMode ViewMode - ViewLayout ViewLayout - SwipeLeft SwipeAction - SwipeRight SwipeAction - Theme string - Currency string // e.g. EUR - Credit int - InvoiceText string - AlsoArchive int - Hotkeys int - PMSignature int - TwoFactor int - PasswordReset int - PasswordMode PasswordMode - News int - AutoResponder interface{} // TODO - AutoWildcardSearch int - DraftMIMEType string - ReceiveMIMEType string - ImageProxy int - DisplayName string - MaxSpace int - MaxUpload int - Subscribed int // TODO - Services int // TODO - Role int // TODO - Private int - VPN interface{} // TODO - Delinquent int - Addresses []*Address - Keys []*PrivateKey + ID string + Name string + UsedSpace int + Currency string // e.g. EUR + Credit int + MaxSpace int + MaxUpload int + Role int // TODO + Private int + Subscribed int // TODO + Services int // TODO + Delinquent int + Keys []*PrivateKey } func (c *Client) GetCurrentUser() (*User, error) { @@ -70,28 +36,13 @@ func (c *Client) GetCurrentUser() (*User, error) { return nil, err } - var userData struct { + var respData struct { resp User *User } - if err := c.doJSON(req, &userData); err != nil { + if err := c.doJSON(req, &respData); err != nil { return nil, err } - req, err = c.newRequest(http.MethodGet, "/addresses", nil) - if err != nil { - return nil, err - } - - var addrData struct { - resp - Addresses []*Address - } - if err := c.doJSON(req, &addrData); err != nil { - return nil, err - } - - userData.User.Addresses = addrData.Addresses - - return userData.User, nil + return respData.User, nil } diff --git a/smtp/smtp.go b/smtp/smtp.go index f2fba5c..28b4510 100644 --- a/smtp/smtp.go +++ b/smtp/smtp.go @@ -41,6 +41,7 @@ type user struct { c *protonmail.Client u *protonmail.User privateKeys openpgp.EntityList + addrs []*protonmail.Address } func (u *user) Send(from string, to []string, r io.Reader) error { @@ -65,7 +66,7 @@ func (u *user) Send(from string, to []string, r io.Reader) error { fromAddrStr := fromList[0].Address var fromAddr *protonmail.Address - for _, addr := range u.u.Addresses { + for _, addr := range u.addrs { if strings.EqualFold(addr.Email, fromAddrStr) { fromAddr = addr break @@ -360,9 +361,14 @@ func (be *backend) Login(username, password string) (smtp.User, error) { return nil, err } + addrs, err := c.ListAddresses() + if err != nil { + return nil, err + } + // TODO: decrypt private keys in u.Addresses - return &user{c, u, privateKeys}, nil + return &user{c, u, privateKeys, addrs}, nil } func (be *backend) AnonymousLogin() (smtp.User, error) {