mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-17 15:46:44 +00:00
Merge branch 'release/congo' into devel
This commit is contained in:
@ -95,6 +95,15 @@ func (l AddressList) ByID(id string) *Address {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AllEmails returns all emails.
|
||||
func (l AddressList) AllEmails() (addresses []string) {
|
||||
for _, a := range l {
|
||||
addresses = append(addresses, a.Email)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ActiveEmails returns only active emails.
|
||||
func (l AddressList) ActiveEmails() (addresses []string) {
|
||||
for _, a := range l {
|
||||
if a.Receive == CanReceive {
|
||||
|
||||
@ -173,26 +173,6 @@ func (c *client) Report(rep ReportReq) (err error) {
|
||||
return res.Err()
|
||||
}
|
||||
|
||||
// ReportBug is old. Use Report instead.
|
||||
func (c *client) ReportBug(os, osVersion, title, description, username, email string) (err error) {
|
||||
return c.ReportBugWithEmailClient(os, osVersion, title, description, username, email, "")
|
||||
}
|
||||
|
||||
// ReportBugWithEmailClient is old. Use Report instead.
|
||||
func (c *client) ReportBugWithEmailClient(os, osVersion, title, description, username, email, emailClient string) (err error) {
|
||||
bugReq := ReportReq{
|
||||
OS: os,
|
||||
OSVersion: osVersion,
|
||||
Browser: emailClient,
|
||||
Title: title,
|
||||
Description: description,
|
||||
Username: username,
|
||||
Email: email,
|
||||
}
|
||||
|
||||
return c.Report(bugReq)
|
||||
}
|
||||
|
||||
// ReportCrash is old. Use sentry instead.
|
||||
func (c *client) ReportCrash(stacktrace string) (err error) {
|
||||
crashReq := ReportReq{
|
||||
|
||||
@ -27,19 +27,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var testBugsReportReq = ReportReq{
|
||||
OS: "Mac OSX",
|
||||
OSVersion: "10.11.6",
|
||||
Client: "demoapp",
|
||||
ClientVersion: "GoPMAPI_1.0.14",
|
||||
ClientType: 1,
|
||||
Title: "Big Bug",
|
||||
Description: "Cannot fetch new messages",
|
||||
Username: "apple",
|
||||
Email: "apple@gmail.com",
|
||||
}
|
||||
|
||||
var testBugsReportReqWithEmailClient = ReportReq{
|
||||
var testBugReportReq = ReportReq{
|
||||
OS: "Mac OSX",
|
||||
OSVersion: "10.11.6",
|
||||
Browser: "AppleMail",
|
||||
@ -67,31 +55,6 @@ const testBugsBody = `{
|
||||
|
||||
const testAttachmentJSONZipped = "PK\x03\x04\x14\x00\b\x00\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00last.log\\Rَ\xaaH\x00}ﯨ\xf8r\x1f\xeeܖED;\xe9\ap\x03\x11\x11\x97\x0e8\x99L\xb0(\xa1\xa0\x16\x85b\x91I\xff\xfbD{\x99\xc9}\xab:K\x9d\xa4\xce\xf9\xe7\t\x00\x00z\xf6\xb4\xf7\x02z\xb7a\xe5\xd8\x04*V̭\x8d\xd1lvE}\xd6\xe3\x80\x1f\xd7nX\x9bI[\xa6\xe1a=\xd4a\xa8M\x97\xd9J\xf1F\xeb\x105U\xbd\xb0`XO\xce\xf1hu\x99q\xc3\xfe{\x11ߨ'-\v\x89Z\xa4\x9c5\xaf\xaf\xbd?>R\xd6\x11E\xf7\x1cX\xf0JpF#L\x9eE+\xbe\xe8\x1d\xee\ued2e\u007f\xde]\u06dd\xedo\x97\x87E\xa0V\xf4/$\xc2\xecK\xed\xa0\xdb&\x829\x12\xe5\x9do\xa0\xe9\x1a\xd2\x19\x1e\xf5`\x95гb\xf8\x89\x81\xb7\xa5G\x18\x95\xf3\x9d9\xe8\x93B\x17!\x1a^\xccr\xbb`\xb2\xb4\xb86\x87\xb4h\x0e\xda\xc6u<+\x9e$̓\x95\xccSo\xea\xa4\xdbH!\xe9g\x8b\xd4\b\xb3hܬ\xa6Wk\x14He\xae\x8aPU\xaa\xc1\xee$\xfbH\xb3\xab.I\f<\x89\x06q\xe3-3-\x99\xcdݽ\xe5v\x99\xedn\xac\xadn\xe8Rp=\xb4nJ\xed\xd5\r\x8d\xde\x06Ζ\xf6\xb3\x01\x94\xcb\xf6\xd4\x19r\xe1\xaa$4+\xeaW\xa6F\xfa0\x97\x9cD\f\x8e\xd7\xd6z\v,G\xf3e2\xd4\xe6V\xba\v\xb6\xd9\xe8\xca*\x16\x95V\xa4J\xfbp\xddmF\x8c\x9a\xc6\xc8Č-\xdb\v\xf6\xf5\xf9\x02*\x15e\x874\xc9\xe7\"\xa3\x1an\xabq}ˊq\x957\xd3\xfd\xa91\x82\xe0Lß\\\x17\x8e\x9e_\xed`\t\xe9~5̕\x03\x9a\f\xddN6\xa2\xc4\x17\xdb\xc9V\x1c~\x9e\xea\xbe\xda-xv\xed\x8b\xe2\xc8DŽS\x95E6\xf2\xc3H\x1d:HPx\xc9\x14\xbfɒ\xff\xea\xb4P\x14\xa3\xe2\xfe\xfd\x1f+z\x80\x903\x81\x98\xf8\x15\xa3\x12\x16\xf8\"0g\xf7~B^\xfd \x040T\xa3\x02\x9c\x10\xc1\xa8F\xa0I#\xf1\xa3\x04\x98\x01\x91\xe2\x12\xdc;\x06gL\xd0g\xc0\xe3\xbd\xf6\xd7}&\xa8轀?\xbfяy`X\xf0\x92\x9f\x05\xf0*A8ρ\xac=K\xff\xf3\xfe\xa6Z\xe1\x1a\x017\xc2\x04\f\x94g\xa9\xf7-\xfb\xebqz\u007fz\u007f\xfa7\x00\x00\xff\xffPK\a\b\xf5\\\v\xe5I\x02\x00\x00\r\x03\x00\x00PK\x01\x02\x14\x00\x14\x00\b\x00\b\x00\x00\x00\x00\x00\xf5\\\v\xe5I\x02\x00\x00\r\x03\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00last.logPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x006\x00\x00\x00\u007f\x02\x00\x00\x00\x00" //nolint[misspell]
|
||||
|
||||
func TestClient_BugReport(t *testing.T) {
|
||||
s, c := newTestServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
Ok(t, checkMethodAndPath(r, "POST", "/reports/bug"))
|
||||
Ok(t, isAuthReq(r, testUID, testAccessToken))
|
||||
|
||||
var bugsReportReq ReportReq
|
||||
Ok(t, json.NewDecoder(r.Body).Decode(&bugsReportReq))
|
||||
Equals(t, testBugsReportReq, bugsReportReq)
|
||||
|
||||
fmt.Fprint(w, testBugsBody)
|
||||
}))
|
||||
defer s.Close()
|
||||
c.uid = testUID
|
||||
c.accessToken = testAccessToken
|
||||
|
||||
Ok(t, c.ReportBug(
|
||||
testBugsReportReq.OS,
|
||||
testBugsReportReq.OSVersion,
|
||||
testBugsReportReq.Title,
|
||||
testBugsReportReq.Description,
|
||||
testBugsReportReq.Username,
|
||||
testBugsReportReq.Email,
|
||||
))
|
||||
}
|
||||
|
||||
func TestClient_BugReportWithAttachment(t *testing.T) {
|
||||
s, c := newTestServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
Ok(t, checkMethodAndPath(r, "POST", "/reports/bug"))
|
||||
@ -100,15 +63,15 @@ func TestClient_BugReportWithAttachment(t *testing.T) {
|
||||
Ok(t, r.ParseMultipartForm(10*1024))
|
||||
|
||||
for field, expected := range map[string]string{
|
||||
"OS": testBugsReportReq.OS,
|
||||
"OSVersion": testBugsReportReq.OSVersion,
|
||||
"Client": testBugsReportReq.Client,
|
||||
"ClientVersion": testBugsReportReq.ClientVersion,
|
||||
"ClientType": fmt.Sprintf("%d", testBugsReportReq.ClientType),
|
||||
"Title": testBugsReportReq.Title,
|
||||
"Description": testBugsReportReq.Description,
|
||||
"Username": testBugsReportReq.Username,
|
||||
"Email": testBugsReportReq.Email,
|
||||
"OS": testBugReportReq.OS,
|
||||
"OSVersion": testBugReportReq.OSVersion,
|
||||
"Client": testBugReportReq.Client,
|
||||
"ClientVersion": testBugReportReq.ClientVersion,
|
||||
"ClientType": fmt.Sprintf("%d", testBugReportReq.ClientType),
|
||||
"Title": testBugReportReq.Title,
|
||||
"Description": testBugReportReq.Description,
|
||||
"Username": testBugReportReq.Username,
|
||||
"Email": testBugReportReq.Email,
|
||||
} {
|
||||
if r.PostFormValue(field) != expected {
|
||||
t.Errorf("Field %q has %q but expected %q", field, r.PostFormValue(field), expected)
|
||||
@ -129,20 +92,20 @@ func TestClient_BugReportWithAttachment(t *testing.T) {
|
||||
c.uid = testUID
|
||||
c.accessToken = testAccessToken
|
||||
|
||||
rep := testBugsReportReq
|
||||
rep := testBugReportReq
|
||||
rep.AddAttachment("log", "last.log", strings.NewReader(testAttachmentJSON))
|
||||
|
||||
Ok(t, c.Report(rep))
|
||||
}
|
||||
|
||||
func TestClient_BugReportWithEmailClient(t *testing.T) {
|
||||
func TestClient_BugReport(t *testing.T) {
|
||||
s, c := newTestServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
Ok(t, checkMethodAndPath(r, "POST", "/reports/bug"))
|
||||
Ok(t, isAuthReq(r, testUID, testAccessToken))
|
||||
|
||||
var bugsReportReq ReportReq
|
||||
Ok(t, json.NewDecoder(r.Body).Decode(&bugsReportReq))
|
||||
Equals(t, testBugsReportReqWithEmailClient, bugsReportReq)
|
||||
Equals(t, testBugReportReq, bugsReportReq)
|
||||
|
||||
fmt.Fprint(w, testBugsBody)
|
||||
}))
|
||||
@ -150,15 +113,17 @@ func TestClient_BugReportWithEmailClient(t *testing.T) {
|
||||
c.uid = testUID
|
||||
c.accessToken = testAccessToken
|
||||
|
||||
Ok(t, c.ReportBugWithEmailClient(
|
||||
testBugsReportReqWithEmailClient.OS,
|
||||
testBugsReportReqWithEmailClient.OSVersion,
|
||||
testBugsReportReqWithEmailClient.Title,
|
||||
testBugsReportReqWithEmailClient.Description,
|
||||
testBugsReportReqWithEmailClient.Username,
|
||||
testBugsReportReqWithEmailClient.Email,
|
||||
testBugsReportReqWithEmailClient.Browser,
|
||||
))
|
||||
r := ReportReq{
|
||||
OS: testBugReportReq.OS,
|
||||
OSVersion: testBugReportReq.OSVersion,
|
||||
Browser: testBugReportReq.Browser,
|
||||
Title: testBugReportReq.Title,
|
||||
Description: testBugReportReq.Description,
|
||||
Username: testBugReportReq.Username,
|
||||
Email: testBugReportReq.Email,
|
||||
}
|
||||
|
||||
Ok(t, c.Report(r))
|
||||
}
|
||||
|
||||
func TestClient_BugsCrash(t *testing.T) {
|
||||
|
||||
@ -67,7 +67,7 @@ type Client interface {
|
||||
DeleteLabel(labelID string) error
|
||||
EmptyFolder(labelID string, addressID string) error
|
||||
|
||||
ReportBugWithEmailClient(os, osVersion, title, description, username, email, emailClient string) error
|
||||
Report(report ReportReq) error
|
||||
SendSimpleMetric(category, action, label string) error
|
||||
|
||||
GetMailSettings() (MailSettings, error)
|
||||
|
||||
@ -317,9 +317,8 @@ func (cm *ClientManager) CheckConnection() error {
|
||||
retStatus := make(chan error)
|
||||
retAPI := make(chan error)
|
||||
|
||||
// Check protonstatus.com without SSL for performance reasons. vpn_status endpoint is fast and
|
||||
// returns only OK; this endpoint is not known by the public. We check the connection only.
|
||||
go checkConnection(client, "http://protonstatus.com/vpn_status", retStatus)
|
||||
// vpn_status endpoint is fast and returns only OK. We check the connection only.
|
||||
go checkConnection(client, "https://protonstatus.com/vpn_status", retStatus)
|
||||
|
||||
// Check of API reachability also uses a fast endpoint.
|
||||
go checkConnection(client, cm.GetRootURL()+"/tests/ping", retAPI)
|
||||
@ -347,6 +346,14 @@ func (cm *ClientManager) CheckConnection() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckConnection returns an error if there is no internet connection.
|
||||
func CheckConnection() error {
|
||||
client := &http.Client{Timeout: time.Second * 10}
|
||||
retStatus := make(chan error)
|
||||
go checkConnection(client, "https://protonstatus.com/vpn_status", retStatus)
|
||||
return <-retStatus
|
||||
}
|
||||
|
||||
func checkConnection(client *http.Client, url string, errorChannel chan error) {
|
||||
resp, err := client.Get(url)
|
||||
if err != nil {
|
||||
@ -445,11 +452,10 @@ func (cm *ClientManager) HandleAuth(ca ClientAuth) {
|
||||
if ca.Auth == nil {
|
||||
cm.clearToken(ca.UserID)
|
||||
go cm.LogoutClient(ca.UserID)
|
||||
return
|
||||
} else {
|
||||
cm.setToken(ca.UserID, ca.Auth.GenToken(), time.Duration(ca.Auth.ExpiresIn)*time.Second)
|
||||
}
|
||||
|
||||
cm.setToken(ca.UserID, ca.Auth.GenToken(), time.Duration(ca.Auth.ExpiresIn)*time.Second)
|
||||
|
||||
logrus.Debug("ClientManager is forwarding auth update...")
|
||||
cm.authUpdates <- ca
|
||||
logrus.Debug("Auth update was forwarded")
|
||||
|
||||
@ -95,6 +95,11 @@ type ImportMsgReq struct {
|
||||
LabelIDs []string
|
||||
}
|
||||
|
||||
func (req ImportMsgReq) String() string {
|
||||
data, _ := json.Marshal(req)
|
||||
return string(data)
|
||||
}
|
||||
|
||||
// ImportRes is a response to an import request.
|
||||
type ImportRes struct {
|
||||
Res
|
||||
|
||||
@ -175,3 +175,21 @@ func (c *client) DeleteLabel(id string) (err error) {
|
||||
err = res.Err()
|
||||
return
|
||||
}
|
||||
|
||||
// LeastUsedColor is intended to return color for creating a new inbox or label
|
||||
func LeastUsedColor(colors []string) (color string) {
|
||||
color = LabelColors[0]
|
||||
frequency := map[string]int{}
|
||||
|
||||
for _, c := range colors {
|
||||
frequency[c]++
|
||||
}
|
||||
|
||||
for _, c := range LabelColors {
|
||||
if frequency[color] > frequency[c] {
|
||||
color = c
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -24,6 +24,8 @@ import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
r "github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const testLabelsBody = `{
|
||||
@ -184,3 +186,17 @@ func TestClient_DeleteLabel(t *testing.T) {
|
||||
t.Fatal("Expected no error while deleting label, got:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLeastUsedColor(t *testing.T) {
|
||||
// No colors at all, should use first available color
|
||||
colors := []string{}
|
||||
r.Equal(t, "#7272a7", LeastUsedColor(colors))
|
||||
|
||||
// All colors have same frequency, should use first available color
|
||||
colors = []string{"#7272a7", "#cf5858", "#c26cc7", "#7569d1", "#69a9d1", "#5ec7b7", "#72bb75", "#c3d261", "#e6c04c", "#e6984c", "#8989ac", "#cf7e7e", "#c793ca", "#9b94d1", "#a8c4d5", "#97c9c1", "#9db99f", "#c6cd97", "#e7d292", "#dfb286"}
|
||||
r.Equal(t, "#7272a7", LeastUsedColor(colors))
|
||||
|
||||
// First three colors already used, but others wasn't. Should use first non-used one.
|
||||
colors = []string{"#7272a7", "#cf5858", "#c26cc7"}
|
||||
r.Equal(t, "#7569d1", LeastUsedColor(colors))
|
||||
}
|
||||
|
||||
@ -5,12 +5,11 @@
|
||||
package mocks
|
||||
|
||||
import (
|
||||
io "io"
|
||||
reflect "reflect"
|
||||
|
||||
crypto "github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||
pmapi "github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
io "io"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockClient is a mock of Client interface
|
||||
@ -601,18 +600,18 @@ func (mr *MockClientMockRecorder) ReorderAddresses(arg0 interface{}) *gomock.Cal
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReorderAddresses", reflect.TypeOf((*MockClient)(nil).ReorderAddresses), arg0)
|
||||
}
|
||||
|
||||
// ReportBugWithEmailClient mocks base method
|
||||
func (m *MockClient) ReportBugWithEmailClient(arg0, arg1, arg2, arg3, arg4, arg5, arg6 string) error {
|
||||
// Report mocks base method
|
||||
func (m *MockClient) Report(arg0 pmapi.ReportReq) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ReportBugWithEmailClient", arg0, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||
ret := m.ctrl.Call(m, "Report", arg0)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ReportBugWithEmailClient indicates an expected call of ReportBugWithEmailClient
|
||||
func (mr *MockClientMockRecorder) ReportBugWithEmailClient(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call {
|
||||
// Report indicates an expected call of Report
|
||||
func (mr *MockClientMockRecorder) Report(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReportBugWithEmailClient", reflect.TypeOf((*MockClient)(nil).ReportBugWithEmailClient), arg0, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Report", reflect.TypeOf((*MockClient)(nil).Report), arg0)
|
||||
}
|
||||
|
||||
// SendMessage mocks base method
|
||||
|
||||
Reference in New Issue
Block a user