Merge branch 'master' into imap
This commit is contained in:
commit
fc7e906d1b
31
auth/auth.go
31
auth/auth.go
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
@ -97,15 +98,29 @@ func EncryptAndSave(auth *CachedAuth, username string, secretKey *[32]byte) erro
|
||||||
return saveAuths(auths)
|
return saveAuths(auths)
|
||||||
}
|
}
|
||||||
|
|
||||||
func authenticate(c *protonmail.Client, CachedAuth *CachedAuth) (openpgp.EntityList, error) {
|
func authenticate(c *protonmail.Client, cachedAuth *CachedAuth, username string) (openpgp.EntityList, error) {
|
||||||
auth, err := c.AuthRefresh(&CachedAuth.Auth)
|
auth, err := c.AuthRefresh(&cachedAuth.Auth)
|
||||||
if err != nil {
|
if apiErr, ok := err.(*protonmail.ApiError); ok && apiErr.Code == 10013 {
|
||||||
// TODO: handle expired token, re-authenticate
|
// Invalid refresh token, re-authenticate
|
||||||
|
authInfo, err := c.AuthInfo(username)
|
||||||
|
if err != nil {
|
||||||
|
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
|
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) {
|
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 := m.newClient()
|
||||||
c.ReAuth = func() error {
|
c.ReAuth = func() error {
|
||||||
if _, err := authenticate(c, &cachedAuth); err != nil {
|
if _, err := authenticate(c, &cachedAuth, username); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return EncryptAndSave(&cachedAuth, username, &secretKey)
|
return EncryptAndSave(&cachedAuth, username, &secretKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// authenticate updates cachedAuth with the new refresh token
|
// authenticate updates cachedAuth with the new refresh token
|
||||||
privateKeys, err := authenticate(c, &cachedAuth)
|
privateKeys, err := authenticate(c, &cachedAuth, username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,10 @@ type resp struct {
|
||||||
|
|
||||||
func (r *resp) Err() error {
|
func (r *resp) Err() error {
|
||||||
if err := r.apiError; err != nil {
|
if err := r.apiError; err != nil {
|
||||||
err.code = r.Code
|
return &ApiError{
|
||||||
return err
|
Code: r.Code,
|
||||||
|
Message: err.Message,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -35,12 +37,16 @@ type maybeError interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiError struct {
|
type apiError struct {
|
||||||
code int // populated by resp
|
|
||||||
Message string `json:"Error"`
|
Message string `json:"Error"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (err apiError) Error() string {
|
type ApiError struct {
|
||||||
return fmt.Sprintf("[%v] %v", err.code, err.Message)
|
Code int
|
||||||
|
Message string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err *ApiError) Error() string {
|
||||||
|
return fmt.Sprintf("[%v] %v", err.Code, err.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client is a ProtonMail API client.
|
// Client is a ProtonMail API client.
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/emersion/go-message/mail"
|
"github.com/emersion/go-message/mail"
|
||||||
"github.com/emersion/go-smtp"
|
"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
|
fromAddrStr := fromList[0].Address
|
||||||
var fromAddr *protonmail.Address
|
var fromAddr *protonmail.Address
|
||||||
for _, addr := range u.u.Addresses {
|
for _, addr := range u.u.Addresses {
|
||||||
if addr.Email == fromAddrStr {
|
if strings.EqualFold(addr.Email, fromAddrStr) {
|
||||||
fromAddr = addr
|
fromAddr = addr
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue