Merge branch 'master' into imap

This commit is contained in:
emersion 2018-01-09 22:59:01 +01:00
commit fc7e906d1b
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
3 changed files with 36 additions and 14 deletions

View File

@ -5,6 +5,7 @@ import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"os"
@ -97,15 +98,29 @@ func EncryptAndSave(auth *CachedAuth, username string, secretKey *[32]byte) erro
return saveAuths(auths)
}
func authenticate(c *protonmail.Client, CachedAuth *CachedAuth) (openpgp.EntityList, error) {
auth, err := c.AuthRefresh(&CachedAuth.Auth)
func authenticate(c *protonmail.Client, cachedAuth *CachedAuth, username string) (openpgp.EntityList, error) {
auth, err := c.AuthRefresh(&cachedAuth.Auth)
if apiErr, ok := err.(*protonmail.ApiError); ok && apiErr.Code == 10013 {
// Invalid refresh token, re-authenticate
authInfo, err := c.AuthInfo(username)
if err != nil {
// TODO: handle expired token, re-authenticate
return nil, fmt.Errorf("cannot re-authenticate: failed to get auth info: %v", err)
}
if authInfo.TwoFactor == 1 {
return nil, fmt.Errorf("cannot re-authenticate: two factor authentication enabled, please login manually")
}
auth, err = c.Auth(username, cachedAuth.LoginPassword, "", authInfo)
if err != nil {
return nil, fmt.Errorf("cannot re-authenticate: %v", err)
}
} else if err != nil {
return nil, err
}
CachedAuth.Auth = *auth
cachedAuth.Auth = *auth
return c.Unlock(auth, CachedAuth.MailboxPassword)
return c.Unlock(auth, cachedAuth.MailboxPassword)
}
func GeneratePassword() (secretKey *[32]byte, password string, err error) {
@ -168,14 +183,14 @@ func (m *Manager) Auth(username, password string) (*protonmail.Client, openpgp.E
c := m.newClient()
c.ReAuth = func() error {
if _, err := authenticate(c, &cachedAuth); err != nil {
if _, err := authenticate(c, &cachedAuth, username); err != nil {
return err
}
return EncryptAndSave(&cachedAuth, username, &secretKey)
}
// authenticate updates cachedAuth with the new refresh token
privateKeys, err := authenticate(c, &cachedAuth)
privateKeys, err := authenticate(c, &cachedAuth, username)
if err != nil {
return nil, nil, err
}

View File

@ -24,8 +24,10 @@ type resp struct {
func (r *resp) Err() error {
if err := r.apiError; err != nil {
err.code = r.Code
return err
return &ApiError{
Code: r.Code,
Message: err.Message,
}
}
return nil
}
@ -35,12 +37,16 @@ type maybeError interface {
}
type apiError struct {
code int // populated by resp
Message string `json:"Error"`
}
func (err apiError) Error() string {
return fmt.Sprintf("[%v] %v", err.code, err.Message)
type ApiError struct {
Code int
Message string
}
func (err *ApiError) Error() string {
return fmt.Sprintf("[%v] %v", err.Code, err.Message)
}
// Client is a ProtonMail API client.

View File

@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"io"
"strings"
"github.com/emersion/go-message/mail"
"github.com/emersion/go-smtp"
@ -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 {
if addr.Email == fromAddrStr {
if strings.EqualFold(addr.Email, fromAddrStr) {
fromAddr = addr
break
}