From 6647231278824fe889390a56546f4ab989e598cf Mon Sep 17 00:00:00 2001 From: Atanas Janeshliev Date: Wed, 30 Oct 2024 11:45:50 +0100 Subject: [PATCH] chore: (BRIDGE-253) removing unused telemetry (activation and troubleshooting) --- internal/bridge/bug_report.go | 7 - internal/bridge/config_status.go | 46 ---- internal/bridge/settings.go | 3 +- internal/bridge/types.go | 1 - internal/bridge/user.go | 19 +- internal/bridge/user_events.go | 3 +- internal/configstatus/config_status.go | 228 ---------------- internal/configstatus/config_status_test.go | 252 ------------------ internal/configstatus/configuration_abort.go | 59 ---- .../configstatus/configuration_abort_test.go | 75 ------ .../configstatus/configuration_progress.go | 60 ----- .../configuration_progress_test.go | 100 ------- .../configstatus/configuration_recovery.go | 63 ----- .../configuration_recovery_test.go | 79 ------ .../configstatus/configuration_success.go | 61 ----- .../configuration_success_test.go | 77 ------ internal/configstatus/types_config_status.go | 56 ---- .../bridge-gui-tester/GRPCService.cpp | 26 -- .../bridge-gui-tester/GRPCService.h | 3 - .../bridge-gui/bridge-gui/QMLBackend.cpp | 28 -- .../bridge-gui/bridge-gui/QMLBackend.h | 3 - .../bridge-gui/bridge-gui/qml/HelpView.qml | 1 - .../bridgepp/bridgepp/GRPC/GRPCClient.cpp | 26 -- .../bridgepp/bridgepp/GRPC/GRPCClient.h | 5 - internal/frontend/grpc/bridge.pb.go | 216 +++++++-------- internal/frontend/grpc/bridge.proto | 5 - internal/frontend/grpc/bridge_grpc.pb.go | 113 -------- internal/frontend/grpc/service_telemetry.go | 44 --- internal/locations/locations.go | 14 - internal/services/imapservice/connector.go | 8 +- internal/services/imapservice/service.go | 11 - .../imapservice/service_address_events.go | 1 - internal/services/smtp/accounts.go | 5 - internal/services/smtp/service.go | 9 - internal/services/useridentity/mocks/mocks.go | 35 --- internal/services/useridentity/service.go | 3 - .../services/useridentity/service_test.go | 3 +- internal/services/useridentity/telemetry.go | 22 -- internal/user/config_status.go | 219 --------------- internal/user/user.go | 38 +-- internal/user/user_test.go | 1 - tests/config_status_test.go | 187 ------------- tests/features/bridge/config_status.feature | 79 ------ tests/steps_test.go | 7 - 44 files changed, 107 insertions(+), 2194 deletions(-) delete mode 100644 internal/bridge/config_status.go delete mode 100644 internal/configstatus/config_status.go delete mode 100644 internal/configstatus/config_status_test.go delete mode 100644 internal/configstatus/configuration_abort.go delete mode 100644 internal/configstatus/configuration_abort_test.go delete mode 100644 internal/configstatus/configuration_progress.go delete mode 100644 internal/configstatus/configuration_progress_test.go delete mode 100644 internal/configstatus/configuration_recovery.go delete mode 100644 internal/configstatus/configuration_recovery_test.go delete mode 100644 internal/configstatus/configuration_success.go delete mode 100644 internal/configstatus/configuration_success_test.go delete mode 100644 internal/configstatus/types_config_status.go delete mode 100644 internal/frontend/grpc/service_telemetry.go delete mode 100644 internal/services/useridentity/telemetry.go delete mode 100644 internal/user/config_status.go delete mode 100644 tests/config_status_test.go delete mode 100644 tests/features/bridge/config_status.feature diff --git a/internal/bridge/bug_report.go b/internal/bridge/bug_report.go index e43c89be..a33219bd 100644 --- a/internal/bridge/bug_report.go +++ b/internal/bridge/bug_report.go @@ -25,7 +25,6 @@ import ( "github.com/ProtonMail/go-proton-api" "github.com/ProtonMail/proton-bridge/v3/internal/constants" "github.com/ProtonMail/proton-bridge/v3/internal/logging" - "github.com/ProtonMail/proton-bridge/v3/internal/safe" "github.com/ProtonMail/proton-bridge/v3/internal/vault" ) @@ -80,12 +79,6 @@ func (bridge *Bridge) ReportBug(ctx context.Context, report *ReportBugReq) error return err } - safe.RLock(func() { - for _, user := range bridge.users { - user.ReportBugSent() - } - }, bridge.usersLock) - // if we have a token we can append more attachment to the bugReport for i, att := range attachments { if i == 0 && report.IncludeLogs { diff --git a/internal/bridge/config_status.go b/internal/bridge/config_status.go deleted file mode 100644 index 5b17bc85..00000000 --- a/internal/bridge/config_status.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2024 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -package bridge - -import ( - "github.com/ProtonMail/proton-bridge/v3/internal/safe" -) - -func (bridge *Bridge) ReportBugClicked() { - safe.RLock(func() { - for _, user := range bridge.users { - user.ReportBugClicked() - } - }, bridge.usersLock) -} - -func (bridge *Bridge) AutoconfigUsed(client string) { - safe.RLock(func() { - for _, user := range bridge.users { - user.AutoconfigUsed(client) - } - }, bridge.usersLock) -} - -func (bridge *Bridge) ExternalLinkClicked(article string) { - safe.RLock(func() { - for _, user := range bridge.users { - user.ExternalLinkClicked(article) - } - }, bridge.usersLock) -} diff --git a/internal/bridge/settings.go b/internal/bridge/settings.go index 1cfee6e0..7478fabf 100644 --- a/internal/bridge/settings.go +++ b/internal/bridge/settings.go @@ -318,11 +318,10 @@ func (bridge *Bridge) GetKnowledgeBaseSuggestions(userInput string) (kb.ArticleL // Note: it does not clear the keychain. The only entry in the keychain is the vault password, // which we need at next startup to decrypt the vault. func (bridge *Bridge) FactoryReset(ctx context.Context) { - useTelemetry := !bridge.GetTelemetryDisabled() // Delete all the users. safe.Lock(func() { for _, user := range bridge.users { - bridge.logoutUser(ctx, user, true, true, useTelemetry) + bridge.logoutUser(ctx, user, true, true) } }, bridge.usersLock) diff --git a/internal/bridge/types.go b/internal/bridge/types.go index e3516809..e9b6978d 100644 --- a/internal/bridge/types.go +++ b/internal/bridge/types.go @@ -28,7 +28,6 @@ type Locator interface { ProvideLogsPath() (string, error) ProvideGluonCachePath() (string, error) ProvideGluonDataPath() (string, error) - ProvideStatsPath() (string, error) GetLicenseFilePath() string GetDependencyLicensesLink() string Clear(...string) error diff --git a/internal/bridge/user.go b/internal/bridge/user.go index fe87ae20..efde55f4 100644 --- a/internal/bridge/user.go +++ b/internal/bridge/user.go @@ -255,7 +255,7 @@ func (bridge *Bridge) LogoutUser(ctx context.Context, userID string) error { return ErrNoSuchUser } - bridge.logoutUser(ctx, user, true, false, false) + bridge.logoutUser(ctx, user, true, false) bridge.publish(events.UserLoggedOut{ UserID: userID, @@ -280,7 +280,7 @@ func (bridge *Bridge) DeleteUser(ctx context.Context, userID string) error { } if user, ok := bridge.users[userID]; ok { - bridge.logoutUser(ctx, user, true, true, !bridge.GetTelemetryDisabled()) + bridge.logoutUser(ctx, user, true, true) } if err := imapservice.DeleteSyncState(syncConfigDir, userID); err != nil { @@ -358,7 +358,7 @@ func (bridge *Bridge) SendBadEventUserFeedback(_ context.Context, userID string, return user.BadEventFeedbackResync(ctx) } - bridge.logoutUser(ctx, user, true, false, false) + bridge.logoutUser(ctx, user, true, false) bridge.publish(events.UserLoggedOut{ UserID: userID, @@ -527,11 +527,6 @@ func (bridge *Bridge) addUserWithVault( vault *vault.User, isNew bool, ) error { - statsPath, err := bridge.locator.ProvideStatsPath() - if err != nil { - return fmt.Errorf("failed to get Statistics directory: %w", err) - } - syncSettingsPath, err := bridge.locator.ProvideIMAPSyncConfigPath() if err != nil { return fmt.Errorf("failed to get IMAP sync config path: %w", err) @@ -546,7 +541,6 @@ func (bridge *Bridge) addUserWithVault( bridge.panicHandler, bridge.vault.GetShowAllMail(), bridge.vault.GetMaxSyncMemory(), - statsPath, bridge, bridge.serverManager, bridge.serverManager, @@ -611,14 +605,9 @@ func (bridge *Bridge) newVaultUser( } // logout logs out the given user, optionally logging them out from the API too. -func (bridge *Bridge) logoutUser(ctx context.Context, user *user.User, withAPI, withData, withTelemetry bool) { +func (bridge *Bridge) logoutUser(ctx context.Context, user *user.User, withAPI, withData bool) { defer delete(bridge.users, user.ID()) - // if this is actually a remove account - if withData && withAPI { - user.SendConfigStatusAbort(ctx, withTelemetry) - } - logUser.WithFields(logrus.Fields{ "userID": user.ID(), "withAPI": withAPI, diff --git a/internal/bridge/user_events.go b/internal/bridge/user_events.go index c41f771c..f9069ce2 100644 --- a/internal/bridge/user_events.go +++ b/internal/bridge/user_events.go @@ -43,8 +43,7 @@ func (bridge *Bridge) handleUserEvent(ctx context.Context, user *user.User, even func (bridge *Bridge) handleUserDeauth(ctx context.Context, user *user.User) { safe.Lock(func() { - bridge.logoutUser(ctx, user, false, false, false) - user.ReportConfigStatusFailure("User deauth.") + bridge.logoutUser(ctx, user, false, false) }, bridge.usersLock) } diff --git a/internal/configstatus/config_status.go b/internal/configstatus/config_status.go deleted file mode 100644 index a8ec2e71..00000000 --- a/internal/configstatus/config_status.go +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright (c) 2024 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -package configstatus - -import ( - "encoding/json" - "fmt" - "os" - "strconv" - "time" - - "github.com/ProtonMail/proton-bridge/v3/internal/safe" - "github.com/sirupsen/logrus" -) - -const version = "1.0.0" - -func LoadConfigurationStatus(filepath string) (*ConfigurationStatus, error) { - status := ConfigurationStatus{ - FilePath: filepath, - DataLock: safe.NewRWMutex(), - Data: &ConfigurationStatusData{}, - } - - if _, err := os.Stat(filepath); err == nil { - if err := status.Load(); err == nil { - return &status, nil - } - logrus.WithError(err).Warn("Cannot load configuration status file. Reset it.") - } - - status.Data.init() - if err := status.Save(); err != nil { - return &status, err - } - return &status, nil -} - -func (status *ConfigurationStatus) Load() error { - bytes, err := os.ReadFile(status.FilePath) - if err != nil { - return err - } - - var metadata MetadataOnly - if err := json.Unmarshal(bytes, &metadata); err != nil { - return err - } - - if metadata.Metadata.Version != version { - return fmt.Errorf("unsupported configstatus file version %s", metadata.Metadata.Version) - } - - return json.Unmarshal(bytes, status.Data) -} - -func (status *ConfigurationStatus) Save() error { - temp := status.FilePath + "_temp" - f, err := os.Create(temp) //nolint:gosec - if err != nil { - return err - } - enc := json.NewEncoder(f) - enc.SetIndent("", " ") - err = enc.Encode(status.Data) - if err := f.Close(); err != nil { - logrus.WithError(err).Error("Error while closing configstatus file.") - } - if err != nil { - return err - } - - return os.Rename(temp, status.FilePath) -} - -func (status *ConfigurationStatus) IsPending() bool { - status.DataLock.RLock() - defer status.DataLock.RUnlock() - - return !status.Data.DataV1.PendingSince.IsZero() -} - -func (status *ConfigurationStatus) isPendingSinceMin() int { - if min := int(time.Since(status.Data.DataV1.PendingSince).Minutes()); min > 0 { //nolint:predeclared - return min - } - return 0 -} - -func (status *ConfigurationStatus) IsFromFailure() bool { - status.DataLock.RLock() - defer status.DataLock.RUnlock() - - return status.Data.DataV1.FailureDetails != "" -} - -func (status *ConfigurationStatus) ApplySuccess() error { - status.DataLock.Lock() - defer status.DataLock.Unlock() - - status.Data.init() - status.Data.DataV1.PendingSince = time.Time{} - return status.Save() -} - -func (status *ConfigurationStatus) ApplyFailure(err string) error { - status.DataLock.Lock() - defer status.DataLock.Unlock() - - status.Data.init() - status.Data.DataV1.FailureDetails = err - return status.Save() -} - -func (status *ConfigurationStatus) ApplyProgress() error { - status.DataLock.Lock() - defer status.DataLock.Unlock() - - status.Data.DataV1.LastProgress = time.Now() - return status.Save() -} - -func (status *ConfigurationStatus) RecordLinkClicked(link uint64) error { - status.DataLock.Lock() - defer status.DataLock.Unlock() - - if !status.Data.hasLinkClicked(link) { - status.Data.setClickedLink(link) - return status.Save() - } - return nil -} - -func (status *ConfigurationStatus) ReportClicked() error { - status.DataLock.Lock() - defer status.DataLock.Unlock() - - if !status.Data.DataV1.ReportClick { - status.Data.DataV1.ReportClick = true - return status.Save() - } - return nil -} - -func (status *ConfigurationStatus) ReportSent() error { - status.DataLock.Lock() - defer status.DataLock.Unlock() - - if !status.Data.DataV1.ReportSent { - status.Data.DataV1.ReportSent = true - return status.Save() - } - return nil -} - -func (status *ConfigurationStatus) AutoconfigUsed(client string) error { - status.DataLock.Lock() - defer status.DataLock.Unlock() - - if client != status.Data.DataV1.Autoconf { - status.Data.DataV1.Autoconf = client - return status.Save() - } - return nil -} - -func (status *ConfigurationStatus) Remove() error { - status.DataLock.Lock() - defer status.DataLock.Unlock() - return os.Remove(status.FilePath) -} - -func (data *ConfigurationStatusData) init() { - data.Metadata = Metadata{ - Version: version, - } - data.DataV1.PendingSince = time.Now() - data.DataV1.LastProgress = time.Time{} - data.DataV1.Autoconf = "" - data.DataV1.ClickedLink = 0 - data.DataV1.ReportSent = false - data.DataV1.ReportClick = false - data.DataV1.FailureDetails = "" -} - -func (data *ConfigurationStatusData) setClickedLink(pos uint64) { - data.DataV1.ClickedLink |= 1 << pos -} - -func (data *ConfigurationStatusData) hasLinkClicked(pos uint64) bool { - val := data.DataV1.ClickedLink & (1 << pos) - return val > 0 -} - -func (data *ConfigurationStatusData) clickedLinkToString() string { - var str = "" - var first = true - for i := 0; i < 64; i++ { - if data.hasLinkClicked(uint64(i)) { //nolint:gosec // disable G115 - if !first { - str += "," - } else { - first = false - str += "[" - } - str += strconv.Itoa(i) - } - } - if str != "" { - str += "]" - } - return str -} diff --git a/internal/configstatus/config_status_test.go b/internal/configstatus/config_status_test.go deleted file mode 100644 index 746b22f3..00000000 --- a/internal/configstatus/config_status_test.go +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright (c) 2024 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -package configstatus_test - -import ( - "encoding/json" - "os" - "path/filepath" - "testing" - "time" - - "github.com/ProtonMail/proton-bridge/v3/internal/configstatus" - "github.com/stretchr/testify/require" -) - -func TestConfigStatus_init_virgin(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - require.Equal(t, "1.0.0", config.Data.Metadata.Version) - - require.Equal(t, false, config.Data.DataV1.PendingSince.IsZero()) - require.Equal(t, true, config.Data.DataV1.LastProgress.IsZero()) - - require.Equal(t, "", config.Data.DataV1.Autoconf) - require.Equal(t, uint64(0), config.Data.DataV1.ClickedLink) - require.Equal(t, false, config.Data.DataV1.ReportSent) - require.Equal(t, false, config.Data.DataV1.ReportClick) - require.Equal(t, "", config.Data.DataV1.FailureDetails) -} - -func TestConfigStatus_init_existing(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - var data = configstatus.ConfigurationStatusData{ - Metadata: configstatus.Metadata{Version: "1.0.0"}, - DataV1: configstatus.DataV1{Autoconf: "Mr TBird"}, - } - require.NoError(t, dumpConfigStatusInFile(&data, file)) - - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - require.Equal(t, "1.0.0", config.Data.Metadata.Version) - require.Equal(t, "Mr TBird", config.Data.DataV1.Autoconf) -} - -func TestConfigStatus_init_bad_version(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - var data = configstatus.ConfigurationStatusData{ - Metadata: configstatus.Metadata{Version: "2.0.0"}, - DataV1: configstatus.DataV1{Autoconf: "Mr TBird"}, - } - require.NoError(t, dumpConfigStatusInFile(&data, file)) - - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - require.Equal(t, "1.0.0", config.Data.Metadata.Version) - require.Equal(t, "", config.Data.DataV1.Autoconf) -} - -func TestConfigStatus_IsPending(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - require.Equal(t, true, config.IsPending()) - config.Data.DataV1.PendingSince = time.Time{} - require.Equal(t, false, config.IsPending()) -} - -func TestConfigStatus_IsFromFailure(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - require.Equal(t, false, config.IsFromFailure()) - config.Data.DataV1.FailureDetails = "test" - require.Equal(t, true, config.IsFromFailure()) -} - -func TestConfigStatus_ApplySuccess(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - require.Equal(t, true, config.IsPending()) - require.NoError(t, config.ApplySuccess()) - require.Equal(t, false, config.IsPending()) - - config2, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - require.Equal(t, "1.0.0", config2.Data.Metadata.Version) - require.Equal(t, true, config2.Data.DataV1.PendingSince.IsZero()) - require.Equal(t, true, config2.Data.DataV1.LastProgress.IsZero()) - require.Equal(t, "", config2.Data.DataV1.Autoconf) - require.Equal(t, uint64(0), config2.Data.DataV1.ClickedLink) - require.Equal(t, false, config2.Data.DataV1.ReportSent) - require.Equal(t, false, config2.Data.DataV1.ReportClick) - require.Equal(t, "", config2.Data.DataV1.FailureDetails) -} - -func TestConfigStatus_ApplyFailure(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - require.NoError(t, config.ApplySuccess()) - - require.NoError(t, config.ApplyFailure("Big Failure")) - require.Equal(t, true, config.IsFromFailure()) - require.Equal(t, true, config.IsPending()) - - config2, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - require.Equal(t, "1.0.0", config2.Data.Metadata.Version) - require.Equal(t, false, config2.Data.DataV1.PendingSince.IsZero()) - require.Equal(t, true, config2.Data.DataV1.LastProgress.IsZero()) - require.Equal(t, "", config2.Data.DataV1.Autoconf) - require.Equal(t, uint64(0), config2.Data.DataV1.ClickedLink) - require.Equal(t, false, config2.Data.DataV1.ReportSent) - require.Equal(t, false, config2.Data.DataV1.ReportClick) - require.Equal(t, "Big Failure", config2.Data.DataV1.FailureDetails) -} - -func TestConfigStatus_ApplyProgress(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - require.Equal(t, true, config.IsPending()) - require.Equal(t, true, config.Data.DataV1.LastProgress.IsZero()) - - require.NoError(t, config.ApplyProgress()) - - config2, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - require.Equal(t, "1.0.0", config2.Data.Metadata.Version) - require.Equal(t, false, config2.Data.DataV1.PendingSince.IsZero()) - require.Equal(t, false, config2.Data.DataV1.LastProgress.IsZero()) - require.Equal(t, "", config2.Data.DataV1.Autoconf) - require.Equal(t, uint64(0), config2.Data.DataV1.ClickedLink) - require.Equal(t, false, config2.Data.DataV1.ReportSent) - require.Equal(t, false, config2.Data.DataV1.ReportClick) - require.Equal(t, "", config2.Data.DataV1.FailureDetails) -} - -func TestConfigStatus_RecordLinkClicked(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - require.Equal(t, uint64(0), config.Data.DataV1.ClickedLink) - require.NoError(t, config.RecordLinkClicked(0)) - require.Equal(t, uint64(1), config.Data.DataV1.ClickedLink) - require.NoError(t, config.RecordLinkClicked(1)) - require.Equal(t, uint64(3), config.Data.DataV1.ClickedLink) - - config2, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - require.Equal(t, "1.0.0", config2.Data.Metadata.Version) - require.Equal(t, false, config2.Data.DataV1.PendingSince.IsZero()) - require.Equal(t, true, config2.Data.DataV1.LastProgress.IsZero()) - require.Equal(t, "", config2.Data.DataV1.Autoconf) - require.Equal(t, uint64(3), config2.Data.DataV1.ClickedLink) - require.Equal(t, false, config2.Data.DataV1.ReportSent) - require.Equal(t, false, config2.Data.DataV1.ReportClick) - require.Equal(t, "", config2.Data.DataV1.FailureDetails) -} - -func TestConfigStatus_ReportClicked(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - require.Equal(t, false, config.Data.DataV1.ReportClick) - require.NoError(t, config.ReportClicked()) - require.Equal(t, true, config.Data.DataV1.ReportClick) - - config2, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - require.Equal(t, "1.0.0", config2.Data.Metadata.Version) - require.Equal(t, false, config2.Data.DataV1.PendingSince.IsZero()) - require.Equal(t, true, config2.Data.DataV1.LastProgress.IsZero()) - require.Equal(t, "", config2.Data.DataV1.Autoconf) - require.Equal(t, uint64(0), config2.Data.DataV1.ClickedLink) - require.Equal(t, false, config2.Data.DataV1.ReportSent) - require.Equal(t, true, config2.Data.DataV1.ReportClick) - require.Equal(t, "", config2.Data.DataV1.FailureDetails) -} - -func TestConfigStatus_ReportSent(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - require.Equal(t, false, config.Data.DataV1.ReportSent) - require.NoError(t, config.ReportSent()) - require.Equal(t, true, config.Data.DataV1.ReportSent) - - config2, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - require.Equal(t, "1.0.0", config2.Data.Metadata.Version) - require.Equal(t, false, config2.Data.DataV1.PendingSince.IsZero()) - require.Equal(t, true, config2.Data.DataV1.LastProgress.IsZero()) - require.Equal(t, "", config2.Data.DataV1.Autoconf) - require.Equal(t, uint64(0), config2.Data.DataV1.ClickedLink) - require.Equal(t, true, config2.Data.DataV1.ReportSent) - require.Equal(t, false, config2.Data.DataV1.ReportClick) - require.Equal(t, "", config2.Data.DataV1.FailureDetails) -} - -func dumpConfigStatusInFile(data *configstatus.ConfigurationStatusData, file string) error { - f, err := os.Create(file) - if err != nil { - return err - } - defer func() { _ = f.Close() }() - - return json.NewEncoder(f).Encode(data) -} diff --git a/internal/configstatus/configuration_abort.go b/internal/configstatus/configuration_abort.go deleted file mode 100644 index d3cba23c..00000000 --- a/internal/configstatus/configuration_abort.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2024 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -package configstatus - -import ( - "strconv" -) - -type ConfigAbortValues struct { - Duration int `json:"duration"` -} - -type ConfigAbortDimensions struct { - ReportClick string `json:"report_click"` - ReportSent string `json:"report_sent"` - ClickedLink string `json:"clicked_link"` -} - -type ConfigAbortData struct { - MeasurementGroup string - Event string - Values ConfigSuccessValues - Dimensions ConfigSuccessDimensions -} - -type ConfigAbortBuilder struct{} - -func (*ConfigAbortBuilder) New(config *ConfigurationStatus) ConfigAbortData { - config.DataLock.RLock() - defer config.DataLock.RUnlock() - - return ConfigAbortData{ - MeasurementGroup: "bridge.any.configuration", - Event: "bridge_config_abort", - Values: ConfigSuccessValues{ - Duration: config.isPendingSinceMin(), - }, - Dimensions: ConfigSuccessDimensions{ - ReportClick: strconv.FormatBool(config.Data.DataV1.ReportClick), - ReportSent: strconv.FormatBool(config.Data.DataV1.ReportSent), - ClickedLink: config.Data.clickedLinkToString(), - }, - } -} diff --git a/internal/configstatus/configuration_abort_test.go b/internal/configstatus/configuration_abort_test.go deleted file mode 100644 index 688f68a1..00000000 --- a/internal/configstatus/configuration_abort_test.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2024 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -package configstatus_test - -import ( - "path/filepath" - "testing" - "time" - - "github.com/ProtonMail/proton-bridge/v3/internal/configstatus" - "github.com/stretchr/testify/require" -) - -func TestConfigurationAbort_default(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - var builder = configstatus.ConfigAbortBuilder{} - req := builder.New(config) - - require.Equal(t, "bridge.any.configuration", req.MeasurementGroup) - require.Equal(t, "bridge_config_abort", req.Event) - require.Equal(t, 0, req.Values.Duration) - require.Equal(t, "false", req.Dimensions.ReportClick) - require.Equal(t, "false", req.Dimensions.ReportSent) - require.Equal(t, "", req.Dimensions.ClickedLink) -} - -func TestConfigurationAbort_fed(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - var data = configstatus.ConfigurationStatusData{ - Metadata: configstatus.Metadata{Version: "1.0.0"}, - DataV1: configstatus.DataV1{ - PendingSince: time.Now().Add(-10 * time.Minute), - LastProgress: time.Time{}, - Autoconf: "Mr TBird", - ClickedLink: 42, - ReportSent: false, - ReportClick: true, - FailureDetails: "Not an error", - }, - } - require.NoError(t, dumpConfigStatusInFile(&data, file)) - - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - var builder = configstatus.ConfigAbortBuilder{} - req := builder.New(config) - - require.Equal(t, "bridge.any.configuration", req.MeasurementGroup) - require.Equal(t, "bridge_config_abort", req.Event) - require.Equal(t, 10, req.Values.Duration) - require.Equal(t, "true", req.Dimensions.ReportClick) - require.Equal(t, "false", req.Dimensions.ReportSent) - require.Equal(t, "[1,3,5]", req.Dimensions.ClickedLink) -} diff --git a/internal/configstatus/configuration_progress.go b/internal/configstatus/configuration_progress.go deleted file mode 100644 index e8d15bf0..00000000 --- a/internal/configstatus/configuration_progress.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2024 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -package configstatus - -import "time" - -type ConfigProgressValues struct { - NbDay int `json:"nb_day"` - NbDaySinceLast int `json:"nb_day_since_last"` -} - -type ConfigProgressData struct { - MeasurementGroup string - Event string - Values ConfigProgressValues - Dimensions struct{} -} - -type ConfigProgressBuilder struct{} - -func (*ConfigProgressBuilder) New(config *ConfigurationStatus) ConfigProgressData { - config.DataLock.RLock() - defer config.DataLock.RUnlock() - - return ConfigProgressData{ - MeasurementGroup: "bridge.any.configuration", - Event: "bridge_config_progress", - Values: ConfigProgressValues{ - NbDay: numberOfDay(time.Now(), config.Data.DataV1.PendingSince), - NbDaySinceLast: numberOfDay(time.Now(), config.Data.DataV1.LastProgress), - }, - } -} - -func numberOfDay(now, prev time.Time) int { - if now.IsZero() || prev.IsZero() { - return 1 - } - if now.Year() > prev.Year() { - return (365 * (now.Year() - prev.Year())) + now.YearDay() - prev.YearDay() - } else if now.YearDay() > prev.YearDay() { - return now.YearDay() - prev.YearDay() - } - return 0 -} diff --git a/internal/configstatus/configuration_progress_test.go b/internal/configstatus/configuration_progress_test.go deleted file mode 100644 index 8d9b5f1e..00000000 --- a/internal/configstatus/configuration_progress_test.go +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) 2024 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -package configstatus_test - -import ( - "path/filepath" - "testing" - "time" - - "github.com/ProtonMail/proton-bridge/v3/internal/configstatus" - "github.com/stretchr/testify/require" -) - -func TestConfigurationProgress_default(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - var builder = configstatus.ConfigProgressBuilder{} - req := builder.New(config) - - require.Equal(t, "bridge.any.configuration", req.MeasurementGroup) - require.Equal(t, "bridge_config_progress", req.Event) - require.Equal(t, 0, req.Values.NbDay) - require.Equal(t, 1, req.Values.NbDaySinceLast) -} - -func TestConfigurationProgress_fed(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - var data = configstatus.ConfigurationStatusData{ - Metadata: configstatus.Metadata{Version: "1.0.0"}, - DataV1: configstatus.DataV1{ - PendingSince: time.Now().AddDate(0, 0, -5), - LastProgress: time.Now().AddDate(0, 0, -2), - Autoconf: "Mr TBird", - ClickedLink: 42, - ReportSent: false, - ReportClick: true, - FailureDetails: "Not an error", - }, - } - require.NoError(t, dumpConfigStatusInFile(&data, file)) - - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - var builder = configstatus.ConfigProgressBuilder{} - req := builder.New(config) - - require.Equal(t, "bridge.any.configuration", req.MeasurementGroup) - require.Equal(t, "bridge_config_progress", req.Event) - require.Equal(t, 5, req.Values.NbDay) - require.Equal(t, 2, req.Values.NbDaySinceLast) -} - -func TestConfigurationProgress_fed_year_change(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - var data = configstatus.ConfigurationStatusData{ - Metadata: configstatus.Metadata{Version: "1.0.0"}, - DataV1: configstatus.DataV1{ - PendingSince: time.Now().AddDate(-1, 0, -5), - LastProgress: time.Now().AddDate(0, 0, -2), - Autoconf: "Mr TBird", - ClickedLink: 42, - ReportSent: false, - ReportClick: true, - FailureDetails: "Not an error", - }, - } - require.NoError(t, dumpConfigStatusInFile(&data, file)) - - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - var builder = configstatus.ConfigProgressBuilder{} - req := builder.New(config) - - require.Equal(t, "bridge.any.configuration", req.MeasurementGroup) - require.Equal(t, "bridge_config_progress", req.Event) - require.True(t, (req.Values.NbDay == 370) || (req.Values.NbDay == 371)) // leap year is accounted for in the simplest manner. - require.Equal(t, 2, req.Values.NbDaySinceLast) -} diff --git a/internal/configstatus/configuration_recovery.go b/internal/configstatus/configuration_recovery.go deleted file mode 100644 index f0907821..00000000 --- a/internal/configstatus/configuration_recovery.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) 2024 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -package configstatus - -import ( - "strconv" -) - -type ConfigRecoveryValues struct { - Duration int `json:"duration"` -} - -type ConfigRecoveryDimensions struct { - Autoconf string `json:"autoconf"` - ReportClick string `json:"report_click"` - ReportSent string `json:"report_sent"` - ClickedLink string `json:"clicked_link"` - FailureDetails string `json:"failure_details"` -} - -type ConfigRecoveryData struct { - MeasurementGroup string - Event string - Values ConfigRecoveryValues - Dimensions ConfigRecoveryDimensions -} - -type ConfigRecoveryBuilder struct{} - -func (*ConfigRecoveryBuilder) New(config *ConfigurationStatus) ConfigRecoveryData { - config.DataLock.RLock() - defer config.DataLock.RUnlock() - - return ConfigRecoveryData{ - MeasurementGroup: "bridge.any.configuration", - Event: "bridge_config_recovery", - Values: ConfigRecoveryValues{ - Duration: config.isPendingSinceMin(), - }, - Dimensions: ConfigRecoveryDimensions{ - Autoconf: config.Data.DataV1.Autoconf, - ReportClick: strconv.FormatBool(config.Data.DataV1.ReportClick), - ReportSent: strconv.FormatBool(config.Data.DataV1.ReportSent), - ClickedLink: config.Data.clickedLinkToString(), - FailureDetails: config.Data.DataV1.FailureDetails, - }, - } -} diff --git a/internal/configstatus/configuration_recovery_test.go b/internal/configstatus/configuration_recovery_test.go deleted file mode 100644 index 16266667..00000000 --- a/internal/configstatus/configuration_recovery_test.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2024 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -package configstatus_test - -import ( - "path/filepath" - "testing" - "time" - - "github.com/ProtonMail/proton-bridge/v3/internal/configstatus" - "github.com/stretchr/testify/require" -) - -func TestConfigurationRecovery_default(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - var builder = configstatus.ConfigRecoveryBuilder{} - req := builder.New(config) - - require.Equal(t, "bridge.any.configuration", req.MeasurementGroup) - require.Equal(t, "bridge_config_recovery", req.Event) - require.Equal(t, 0, req.Values.Duration) - require.Equal(t, "", req.Dimensions.Autoconf) - require.Equal(t, "false", req.Dimensions.ReportClick) - require.Equal(t, "false", req.Dimensions.ReportSent) - require.Equal(t, "", req.Dimensions.ClickedLink) - require.Equal(t, "", req.Dimensions.FailureDetails) -} - -func TestConfigurationRecovery_fed(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - var data = configstatus.ConfigurationStatusData{ - Metadata: configstatus.Metadata{Version: "1.0.0"}, - DataV1: configstatus.DataV1{ - PendingSince: time.Now().Add(-10 * time.Minute), - LastProgress: time.Time{}, - Autoconf: "Mr TBird", - ClickedLink: 42, - ReportSent: false, - ReportClick: true, - FailureDetails: "Not an error", - }, - } - require.NoError(t, dumpConfigStatusInFile(&data, file)) - - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - var builder = configstatus.ConfigRecoveryBuilder{} - req := builder.New(config) - - require.Equal(t, "bridge.any.configuration", req.MeasurementGroup) - require.Equal(t, "bridge_config_recovery", req.Event) - require.Equal(t, 10, req.Values.Duration) - require.Equal(t, "Mr TBird", req.Dimensions.Autoconf) - require.Equal(t, "true", req.Dimensions.ReportClick) - require.Equal(t, "false", req.Dimensions.ReportSent) - require.Equal(t, "[1,3,5]", req.Dimensions.ClickedLink) - require.Equal(t, "Not an error", req.Dimensions.FailureDetails) -} diff --git a/internal/configstatus/configuration_success.go b/internal/configstatus/configuration_success.go deleted file mode 100644 index 86b3de34..00000000 --- a/internal/configstatus/configuration_success.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2024 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -package configstatus - -import ( - "strconv" -) - -type ConfigSuccessValues struct { - Duration int `json:"duration"` -} - -type ConfigSuccessDimensions struct { - Autoconf string `json:"autoconf"` - ReportClick string `json:"report_click"` - ReportSent string `json:"report_sent"` - ClickedLink string `json:"clicked_link"` -} - -type ConfigSuccessData struct { - MeasurementGroup string - Event string - Values ConfigSuccessValues - Dimensions ConfigSuccessDimensions -} - -type ConfigSuccessBuilder struct{} - -func (*ConfigSuccessBuilder) New(config *ConfigurationStatus) ConfigSuccessData { - config.DataLock.RLock() - defer config.DataLock.RUnlock() - - return ConfigSuccessData{ - MeasurementGroup: "bridge.any.configuration", - Event: "bridge_config_success", - Values: ConfigSuccessValues{ - Duration: config.isPendingSinceMin(), - }, - Dimensions: ConfigSuccessDimensions{ - Autoconf: config.Data.DataV1.Autoconf, - ReportClick: strconv.FormatBool(config.Data.DataV1.ReportClick), - ReportSent: strconv.FormatBool(config.Data.DataV1.ReportSent), - ClickedLink: config.Data.clickedLinkToString(), - }, - } -} diff --git a/internal/configstatus/configuration_success_test.go b/internal/configstatus/configuration_success_test.go deleted file mode 100644 index 332d8f45..00000000 --- a/internal/configstatus/configuration_success_test.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) 2024 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -package configstatus_test - -import ( - "path/filepath" - "testing" - "time" - - "github.com/ProtonMail/proton-bridge/v3/internal/configstatus" - "github.com/stretchr/testify/require" -) - -func TestConfigurationSuccess_default(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - var builder = configstatus.ConfigSuccessBuilder{} - req := builder.New(config) - - require.Equal(t, "bridge.any.configuration", req.MeasurementGroup) - require.Equal(t, "bridge_config_success", req.Event) - require.Equal(t, 0, req.Values.Duration) - require.Equal(t, "", req.Dimensions.Autoconf) - require.Equal(t, "false", req.Dimensions.ReportClick) - require.Equal(t, "false", req.Dimensions.ReportSent) - require.Equal(t, "", req.Dimensions.ClickedLink) -} - -func TestConfigurationSuccess_fed(t *testing.T) { - dir := t.TempDir() - file := filepath.Join(dir, "dummy.json") - var data = configstatus.ConfigurationStatusData{ - Metadata: configstatus.Metadata{Version: "1.0.0"}, - DataV1: configstatus.DataV1{ - PendingSince: time.Now().Add(-10 * time.Minute), - LastProgress: time.Time{}, - Autoconf: "Mr TBird", - ClickedLink: 42, - ReportSent: false, - ReportClick: true, - FailureDetails: "Not an error", - }, - } - require.NoError(t, dumpConfigStatusInFile(&data, file)) - - config, err := configstatus.LoadConfigurationStatus(file) - require.NoError(t, err) - - var builder = configstatus.ConfigSuccessBuilder{} - req := builder.New(config) - - require.Equal(t, "bridge.any.configuration", req.MeasurementGroup) - require.Equal(t, "bridge_config_success", req.Event) - require.Equal(t, 10, req.Values.Duration) - require.Equal(t, "Mr TBird", req.Dimensions.Autoconf) - require.Equal(t, "true", req.Dimensions.ReportClick) - require.Equal(t, "false", req.Dimensions.ReportSent) - require.Equal(t, "[1,3,5]", req.Dimensions.ClickedLink) -} diff --git a/internal/configstatus/types_config_status.go b/internal/configstatus/types_config_status.go deleted file mode 100644 index a5474574..00000000 --- a/internal/configstatus/types_config_status.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2024 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -package configstatus - -import ( - "time" - - "github.com/ProtonMail/proton-bridge/v3/internal/safe" -) - -const ProgressCheckInterval = time.Hour - -type Metadata struct { - Version string `json:"version"` -} - -type MetadataOnly struct { - Metadata Metadata `json:"metadata"` -} - -type DataV1 struct { - PendingSince time.Time `json:"pending_since"` - LastProgress time.Time `json:"last_progress"` - Autoconf string `json:"auto_conf"` - ClickedLink uint64 `json:"clicked_link"` - ReportSent bool `json:"report_sent"` - ReportClick bool `json:"report_click"` - FailureDetails string `json:"failure_details"` -} - -type ConfigurationStatusData struct { - Metadata Metadata `json:"metadata"` - DataV1 DataV1 `json:"dataV1"` -} - -type ConfigurationStatus struct { - FilePath string - DataLock safe.RWMutex - - Data *ConfigurationStatusData -} diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp index 917129a1..9eb0fac2 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp +++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp @@ -846,32 +846,6 @@ Status GRPCService::InstallTLSCertificate(ServerContext *, Empty const *, Empty } -//**************************************************************************************************************************************************** -/// \param[in] request The request. -//**************************************************************************************************************************************************** -Status GRPCService::ExternalLinkClicked(::grpc::ServerContext *, ::google::protobuf::StringValue const *request, ::google::protobuf::Empty *) { - app().log().debug(QString("%1 - URL = %2").arg(__FUNCTION__, QString::fromStdString(request->value()))); - return Status::OK; -} - -//**************************************************************************************************************************************************** -// -//**************************************************************************************************************************************************** -Status GRPCService::ReportBugClicked(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::Empty *) { - app().log().debug(__FUNCTION__); - return Status::OK; -} - - -//**************************************************************************************************************************************************** -/// \param[in] request The request. -//**************************************************************************************************************************************************** -Status GRPCService::AutoconfigClicked(::grpc::ServerContext *, ::google::protobuf::StringValue const *request, ::google::protobuf::Empty *response) { - app().log().debug(QString("%1 - Client = %2").arg(__FUNCTION__, QString::fromStdString(request->value()))); - return Status::OK; -} - - //**************************************************************************************************************************************************** /// \param[in] request The request /// \param[in] writer The writer diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.h b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.h index 60490971..9222952e 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.h +++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.h @@ -97,9 +97,6 @@ public: // member functions. grpc::Status IsTLSCertificateInstalled(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::BoolValue *response) override; grpc::Status InstallTLSCertificate(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::Empty *) override; grpc::Status ExportTLSCertificates(::grpc::ServerContext *, ::google::protobuf::StringValue const *request, ::google::protobuf::Empty *) override; - grpc::Status ReportBugClicked(::grpc::ServerContext *context, ::google::protobuf::Empty const *request, ::google::protobuf::Empty *) override; - grpc::Status AutoconfigClicked(::grpc::ServerContext *context, ::google::protobuf::StringValue const *request, ::google::protobuf::Empty *) override; - grpc::Status ExternalLinkClicked(::grpc::ServerContext *, ::google::protobuf::StringValue const *request, ::google::protobuf::Empty *) override; grpc::Status RunEventStream(::grpc::ServerContext *ctx, ::grpc::EventStreamRequest const *request, ::grpc::ServerWriter<::grpc::StreamEvent> *writer) override; grpc::Status StopEventStream(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::Empty *) override; bool sendEvent(bridgepp::SPStreamEvent const &event); ///< Queue an event for sending through the event stream. diff --git a/internal/frontend/bridge-gui/bridge-gui/QMLBackend.cpp b/internal/frontend/bridge-gui/bridge-gui/QMLBackend.cpp index 06a0d673..962fb664 100644 --- a/internal/frontend/bridge-gui/bridge-gui/QMLBackend.cpp +++ b/internal/frontend/bridge-gui/bridge-gui/QMLBackend.cpp @@ -303,7 +303,6 @@ void QMLBackend::openExternalLink(QString const &url) { HANDLE_EXCEPTION( QString const u = url.isEmpty() ? bridgeKBUrl : url; QDesktopServices::openUrl(u); - emit notifyExternalLinkClicked(u); ) } @@ -1095,33 +1094,6 @@ void QMLBackend::sendBadEventUserFeedback(QString const &userID, bool doResync) ) } -//**************************************************************************************************************************************************** -/// -//**************************************************************************************************************************************************** -void QMLBackend::notifyReportBugClicked() const { - HANDLE_EXCEPTION( - app().grpc().reportBugClicked(); - ) -} -//**************************************************************************************************************************************************** -/// \param[in] client The selected Mail client for autoconfig. -//**************************************************************************************************************************************************** -void QMLBackend::notifyAutoconfigClicked(QString const &client) const { - HANDLE_EXCEPTION( - app().grpc().autoconfigClicked(client); - ) -} - -//**************************************************************************************************************************************************** -/// \param[in] article The url of the KB article. -//**************************************************************************************************************************************************** -void QMLBackend::notifyExternalLinkClicked(QString const &article) const { - HANDLE_EXCEPTION( - app().grpc().externalLinkClicked(article); - ) -} - - //**************************************************************************************************************************************************** // //**************************************************************************************************************************************************** diff --git a/internal/frontend/bridge-gui/bridge-gui/QMLBackend.h b/internal/frontend/bridge-gui/bridge-gui/QMLBackend.h index 55ad0e8f..2519d7f2 100644 --- a/internal/frontend/bridge-gui/bridge-gui/QMLBackend.h +++ b/internal/frontend/bridge-gui/bridge-gui/QMLBackend.h @@ -213,9 +213,6 @@ public slots: // slot for signals received from QML -> To be forwarded to Bridge void onVersionChanged(); ///< Slot for the version change signal. void setMailServerSettings(int imapPort, int smtpPort, bool useSSLForIMAP, bool useSSLForSMTP) const; ///< Forwards a connection mode change request from QML to gRPC void sendBadEventUserFeedback(QString const &userID, bool doResync); ///< Slot the providing user feedback for a bad event. - void notifyReportBugClicked() const; ///< Slot for the ReportBugClicked gRPC event. - void notifyAutoconfigClicked(QString const &client) const; ///< Slot for gAutoconfigClicked gRPC event. - void notifyExternalLinkClicked(QString const &article) const; ///< Slot for KBArticleClicked gRPC event. void triggerRepair() const; ///< Slot for the triggering of the bridge repair function i.e. 'resync'. void userNotificationDismissed(); ///< Slot to pop the notification from the stack and display the rest. diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/HelpView.qml b/internal/frontend/bridge-gui/bridge-gui/qml/HelpView.qml index ac2704f0..59e2159e 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/HelpView.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/HelpView.qml @@ -83,7 +83,6 @@ SettingsView { onClicked: { Backend.updateCurrentMailClient(); - Backend.notifyReportBugClicked(); root.parent.showBugReport(); } } diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.cpp b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.cpp index 48aafca3..304bba78 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.cpp +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.cpp @@ -1572,32 +1572,6 @@ UPClientContext GRPCClient::clientContext() const { return ctx; } -//**************************************************************************************************************************************************** -/// \return the status for the gRPC call. -//**************************************************************************************************************************************************** -grpc::Status GRPCClient::reportBugClicked() { - return this->logGRPCCallStatus(stub_->ReportBugClicked(this->clientContext().get(), empty, &empty), __FUNCTION__); -} - -//**************************************************************************************************************************************************** -/// \param[in] client The client string. -/// \return the status for the gRPC call. -//**************************************************************************************************************************************************** -grpc::Status GRPCClient::autoconfigClicked(QString const &client) { - StringValue s; - s.set_value(client.toStdString()); - return this->logGRPCCallStatus(stub_->AutoconfigClicked(this->clientContext().get(), s, &empty), __FUNCTION__); -} - -//**************************************************************************************************************************************************** -/// \param[in] link The clicked link. -/// \return the status for the gRPC call. -//**************************************************************************************************************************************************** -grpc::Status GRPCClient::externalLinkClicked(QString const &link) { - StringValue s; - s.set_value(link.toStdString()); - return this->logGRPCCallStatus(stub_->ExternalLinkClicked(this->clientContext().get(), s, &empty), __FUNCTION__); -} //**************************************************************************************************************************************************** // diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.h b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.h index b5120792..992b2ea9 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.h +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.h @@ -232,11 +232,6 @@ signals: void syncFinished(QString const &userID); void syncProgress(QString const &userID, double progress, qint64 elapsedMs, qint64 remainingMs); -public: // telemetry related calls - grpc::Status reportBugClicked(); ///< Performs the 'reportBugClicked' call. - grpc::Status autoconfigClicked(QString const &userID); ///< Performs the 'AutoconfigClicked' call. - grpc::Status externalLinkClicked(QString const &userID); ///< Performs the 'KBArticleClicked' call. - public: // keychain related calls grpc::Status availableKeychains(QStringList &outKeychains); grpc::Status currentKeychain(QString &outKeychain); diff --git a/internal/frontend/grpc/bridge.pb.go b/internal/frontend/grpc/bridge.pb.go index 87fd8764..c1cb6498 100644 --- a/internal/frontend/grpc/bridge.pb.go +++ b/internal/frontend/grpc/bridge.pb.go @@ -5425,7 +5425,7 @@ var file_bridge_proto_rawDesc = []byte{ 0x4c, 0x53, 0x5f, 0x43, 0x45, 0x52, 0x54, 0x5f, 0x45, 0x58, 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x4c, 0x53, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x45, 0x58, 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, - 0x32, 0x99, 0x23, 0x0a, 0x06, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x12, 0x49, 0x0a, 0x0b, 0x43, + 0x32, 0xbd, 0x21, 0x0a, 0x06, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x12, 0x49, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, @@ -5666,51 +5666,37 @@ var file_bridge_proto_rawDesc = []byte{ 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x4d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x12, 0x42, 0x0a, 0x10, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x43, - 0x6c, 0x69, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x49, 0x0a, 0x11, 0x41, 0x75, 0x74, 0x6f, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x1c, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x12, 0x4b, 0x0a, 0x13, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4c, 0x69, 0x6e, - 0x6b, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4f, - 0x0a, 0x19, 0x49, 0x73, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, - 0x47, 0x0a, 0x15, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4d, 0x0a, 0x15, 0x45, 0x78, 0x70, 0x6f, - 0x72, 0x74, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x73, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, + 0x74, 0x79, 0x12, 0x4f, 0x0a, 0x19, 0x49, 0x73, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0e, 0x52, 0x75, 0x6e, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x18, 0x2e, 0x67, 0x72, 0x70, 0x63, - 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0f, 0x53, 0x74, 0x6f, 0x70, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0d, 0x54, - 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x70, 0x61, 0x69, 0x72, 0x12, 0x16, 0x2e, 0x67, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x47, 0x0a, 0x15, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x54, 0x4c, + 0x53, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x36, 0x5a, 0x34, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x6e, 0x4d, 0x61, 0x69, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2d, 0x62, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x2f, 0x76, 0x33, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, - 0x67, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4d, 0x0a, 0x15, + 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0e, 0x52, + 0x75, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x18, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0f, + 0x53, 0x74, 0x6f, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, + 0x3f, 0x0a, 0x0d, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x70, 0x61, 0x69, 0x72, + 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x4d, 0x61, 0x69, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, + 0x2d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2f, 0x76, 0x33, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -5938,81 +5924,75 @@ var file_bridge_proto_depIdxs = []int32{ 80, // 121: grpc.Bridge.LogoutUser:input_type -> google.protobuf.StringValue 80, // 122: grpc.Bridge.RemoveUser:input_type -> google.protobuf.StringValue 18, // 123: grpc.Bridge.ConfigureUserAppleMail:input_type -> grpc.ConfigureAppleMailRequest - 81, // 124: grpc.Bridge.ReportBugClicked:input_type -> google.protobuf.Empty - 80, // 125: grpc.Bridge.AutoconfigClicked:input_type -> google.protobuf.StringValue - 80, // 126: grpc.Bridge.ExternalLinkClicked:input_type -> google.protobuf.StringValue - 81, // 127: grpc.Bridge.IsTLSCertificateInstalled:input_type -> google.protobuf.Empty - 81, // 128: grpc.Bridge.InstallTLSCertificate:input_type -> google.protobuf.Empty - 80, // 129: grpc.Bridge.ExportTLSCertificates:input_type -> google.protobuf.StringValue - 19, // 130: grpc.Bridge.RunEventStream:input_type -> grpc.EventStreamRequest - 81, // 131: grpc.Bridge.StopEventStream:input_type -> google.protobuf.Empty - 81, // 132: grpc.Bridge.TriggerRepair:input_type -> google.protobuf.Empty - 80, // 133: grpc.Bridge.CheckTokens:output_type -> google.protobuf.StringValue - 81, // 134: grpc.Bridge.AddLogEntry:output_type -> google.protobuf.Empty - 8, // 135: grpc.Bridge.GuiReady:output_type -> grpc.GuiReadyResponse - 81, // 136: grpc.Bridge.Quit:output_type -> google.protobuf.Empty - 81, // 137: grpc.Bridge.Restart:output_type -> google.protobuf.Empty - 82, // 138: grpc.Bridge.ShowOnStartup:output_type -> google.protobuf.BoolValue - 81, // 139: grpc.Bridge.SetIsAutostartOn:output_type -> google.protobuf.Empty - 82, // 140: grpc.Bridge.IsAutostartOn:output_type -> google.protobuf.BoolValue - 81, // 141: grpc.Bridge.SetIsBetaEnabled:output_type -> google.protobuf.Empty - 82, // 142: grpc.Bridge.IsBetaEnabled:output_type -> google.protobuf.BoolValue - 81, // 143: grpc.Bridge.SetIsAllMailVisible:output_type -> google.protobuf.Empty - 82, // 144: grpc.Bridge.IsAllMailVisible:output_type -> google.protobuf.BoolValue - 81, // 145: grpc.Bridge.SetIsTelemetryDisabled:output_type -> google.protobuf.Empty - 82, // 146: grpc.Bridge.IsTelemetryDisabled:output_type -> google.protobuf.BoolValue - 80, // 147: grpc.Bridge.GoOs:output_type -> google.protobuf.StringValue - 81, // 148: grpc.Bridge.TriggerReset:output_type -> google.protobuf.Empty - 80, // 149: grpc.Bridge.Version:output_type -> google.protobuf.StringValue - 80, // 150: grpc.Bridge.LogsPath:output_type -> google.protobuf.StringValue - 80, // 151: grpc.Bridge.LicensePath:output_type -> google.protobuf.StringValue - 80, // 152: grpc.Bridge.ReleaseNotesPageLink:output_type -> google.protobuf.StringValue - 80, // 153: grpc.Bridge.DependencyLicensesLink:output_type -> google.protobuf.StringValue - 80, // 154: grpc.Bridge.LandingPageLink:output_type -> google.protobuf.StringValue - 81, // 155: grpc.Bridge.SetColorSchemeName:output_type -> google.protobuf.Empty - 80, // 156: grpc.Bridge.ColorSchemeName:output_type -> google.protobuf.StringValue - 80, // 157: grpc.Bridge.CurrentEmailClient:output_type -> google.protobuf.StringValue - 81, // 158: grpc.Bridge.ReportBug:output_type -> google.protobuf.Empty - 81, // 159: grpc.Bridge.ForceLauncher:output_type -> google.protobuf.Empty - 81, // 160: grpc.Bridge.SetMainExecutable:output_type -> google.protobuf.Empty - 81, // 161: grpc.Bridge.RequestKnowledgeBaseSuggestions:output_type -> google.protobuf.Empty - 81, // 162: grpc.Bridge.Login:output_type -> google.protobuf.Empty - 81, // 163: grpc.Bridge.Login2FA:output_type -> google.protobuf.Empty - 81, // 164: grpc.Bridge.Login2Passwords:output_type -> google.protobuf.Empty - 81, // 165: grpc.Bridge.LoginAbort:output_type -> google.protobuf.Empty - 81, // 166: grpc.Bridge.CheckUpdate:output_type -> google.protobuf.Empty - 81, // 167: grpc.Bridge.InstallUpdate:output_type -> google.protobuf.Empty - 81, // 168: grpc.Bridge.SetIsAutomaticUpdateOn:output_type -> google.protobuf.Empty - 82, // 169: grpc.Bridge.IsAutomaticUpdateOn:output_type -> google.protobuf.BoolValue - 80, // 170: grpc.Bridge.DiskCachePath:output_type -> google.protobuf.StringValue - 81, // 171: grpc.Bridge.SetDiskCachePath:output_type -> google.protobuf.Empty - 81, // 172: grpc.Bridge.SetIsDoHEnabled:output_type -> google.protobuf.Empty - 82, // 173: grpc.Bridge.IsDoHEnabled:output_type -> google.protobuf.BoolValue - 12, // 174: grpc.Bridge.MailServerSettings:output_type -> grpc.ImapSmtpSettings - 81, // 175: grpc.Bridge.SetMailServerSettings:output_type -> google.protobuf.Empty - 80, // 176: grpc.Bridge.Hostname:output_type -> google.protobuf.StringValue - 82, // 177: grpc.Bridge.IsPortFree:output_type -> google.protobuf.BoolValue - 13, // 178: grpc.Bridge.AvailableKeychains:output_type -> grpc.AvailableKeychainsResponse - 81, // 179: grpc.Bridge.SetCurrentKeychain:output_type -> google.protobuf.Empty - 80, // 180: grpc.Bridge.CurrentKeychain:output_type -> google.protobuf.StringValue - 17, // 181: grpc.Bridge.GetUserList:output_type -> grpc.UserListResponse - 14, // 182: grpc.Bridge.GetUser:output_type -> grpc.User - 81, // 183: grpc.Bridge.SetUserSplitMode:output_type -> google.protobuf.Empty - 81, // 184: grpc.Bridge.SendBadEventUserFeedback:output_type -> google.protobuf.Empty - 81, // 185: grpc.Bridge.LogoutUser:output_type -> google.protobuf.Empty - 81, // 186: grpc.Bridge.RemoveUser:output_type -> google.protobuf.Empty - 81, // 187: grpc.Bridge.ConfigureUserAppleMail:output_type -> google.protobuf.Empty - 81, // 188: grpc.Bridge.ReportBugClicked:output_type -> google.protobuf.Empty - 81, // 189: grpc.Bridge.AutoconfigClicked:output_type -> google.protobuf.Empty - 81, // 190: grpc.Bridge.ExternalLinkClicked:output_type -> google.protobuf.Empty - 82, // 191: grpc.Bridge.IsTLSCertificateInstalled:output_type -> google.protobuf.BoolValue - 81, // 192: grpc.Bridge.InstallTLSCertificate:output_type -> google.protobuf.Empty - 81, // 193: grpc.Bridge.ExportTLSCertificates:output_type -> google.protobuf.Empty - 20, // 194: grpc.Bridge.RunEventStream:output_type -> grpc.StreamEvent - 81, // 195: grpc.Bridge.StopEventStream:output_type -> google.protobuf.Empty - 81, // 196: grpc.Bridge.TriggerRepair:output_type -> google.protobuf.Empty - 133, // [133:197] is the sub-list for method output_type - 69, // [69:133] is the sub-list for method input_type + 81, // 124: grpc.Bridge.IsTLSCertificateInstalled:input_type -> google.protobuf.Empty + 81, // 125: grpc.Bridge.InstallTLSCertificate:input_type -> google.protobuf.Empty + 80, // 126: grpc.Bridge.ExportTLSCertificates:input_type -> google.protobuf.StringValue + 19, // 127: grpc.Bridge.RunEventStream:input_type -> grpc.EventStreamRequest + 81, // 128: grpc.Bridge.StopEventStream:input_type -> google.protobuf.Empty + 81, // 129: grpc.Bridge.TriggerRepair:input_type -> google.protobuf.Empty + 80, // 130: grpc.Bridge.CheckTokens:output_type -> google.protobuf.StringValue + 81, // 131: grpc.Bridge.AddLogEntry:output_type -> google.protobuf.Empty + 8, // 132: grpc.Bridge.GuiReady:output_type -> grpc.GuiReadyResponse + 81, // 133: grpc.Bridge.Quit:output_type -> google.protobuf.Empty + 81, // 134: grpc.Bridge.Restart:output_type -> google.protobuf.Empty + 82, // 135: grpc.Bridge.ShowOnStartup:output_type -> google.protobuf.BoolValue + 81, // 136: grpc.Bridge.SetIsAutostartOn:output_type -> google.protobuf.Empty + 82, // 137: grpc.Bridge.IsAutostartOn:output_type -> google.protobuf.BoolValue + 81, // 138: grpc.Bridge.SetIsBetaEnabled:output_type -> google.protobuf.Empty + 82, // 139: grpc.Bridge.IsBetaEnabled:output_type -> google.protobuf.BoolValue + 81, // 140: grpc.Bridge.SetIsAllMailVisible:output_type -> google.protobuf.Empty + 82, // 141: grpc.Bridge.IsAllMailVisible:output_type -> google.protobuf.BoolValue + 81, // 142: grpc.Bridge.SetIsTelemetryDisabled:output_type -> google.protobuf.Empty + 82, // 143: grpc.Bridge.IsTelemetryDisabled:output_type -> google.protobuf.BoolValue + 80, // 144: grpc.Bridge.GoOs:output_type -> google.protobuf.StringValue + 81, // 145: grpc.Bridge.TriggerReset:output_type -> google.protobuf.Empty + 80, // 146: grpc.Bridge.Version:output_type -> google.protobuf.StringValue + 80, // 147: grpc.Bridge.LogsPath:output_type -> google.protobuf.StringValue + 80, // 148: grpc.Bridge.LicensePath:output_type -> google.protobuf.StringValue + 80, // 149: grpc.Bridge.ReleaseNotesPageLink:output_type -> google.protobuf.StringValue + 80, // 150: grpc.Bridge.DependencyLicensesLink:output_type -> google.protobuf.StringValue + 80, // 151: grpc.Bridge.LandingPageLink:output_type -> google.protobuf.StringValue + 81, // 152: grpc.Bridge.SetColorSchemeName:output_type -> google.protobuf.Empty + 80, // 153: grpc.Bridge.ColorSchemeName:output_type -> google.protobuf.StringValue + 80, // 154: grpc.Bridge.CurrentEmailClient:output_type -> google.protobuf.StringValue + 81, // 155: grpc.Bridge.ReportBug:output_type -> google.protobuf.Empty + 81, // 156: grpc.Bridge.ForceLauncher:output_type -> google.protobuf.Empty + 81, // 157: grpc.Bridge.SetMainExecutable:output_type -> google.protobuf.Empty + 81, // 158: grpc.Bridge.RequestKnowledgeBaseSuggestions:output_type -> google.protobuf.Empty + 81, // 159: grpc.Bridge.Login:output_type -> google.protobuf.Empty + 81, // 160: grpc.Bridge.Login2FA:output_type -> google.protobuf.Empty + 81, // 161: grpc.Bridge.Login2Passwords:output_type -> google.protobuf.Empty + 81, // 162: grpc.Bridge.LoginAbort:output_type -> google.protobuf.Empty + 81, // 163: grpc.Bridge.CheckUpdate:output_type -> google.protobuf.Empty + 81, // 164: grpc.Bridge.InstallUpdate:output_type -> google.protobuf.Empty + 81, // 165: grpc.Bridge.SetIsAutomaticUpdateOn:output_type -> google.protobuf.Empty + 82, // 166: grpc.Bridge.IsAutomaticUpdateOn:output_type -> google.protobuf.BoolValue + 80, // 167: grpc.Bridge.DiskCachePath:output_type -> google.protobuf.StringValue + 81, // 168: grpc.Bridge.SetDiskCachePath:output_type -> google.protobuf.Empty + 81, // 169: grpc.Bridge.SetIsDoHEnabled:output_type -> google.protobuf.Empty + 82, // 170: grpc.Bridge.IsDoHEnabled:output_type -> google.protobuf.BoolValue + 12, // 171: grpc.Bridge.MailServerSettings:output_type -> grpc.ImapSmtpSettings + 81, // 172: grpc.Bridge.SetMailServerSettings:output_type -> google.protobuf.Empty + 80, // 173: grpc.Bridge.Hostname:output_type -> google.protobuf.StringValue + 82, // 174: grpc.Bridge.IsPortFree:output_type -> google.protobuf.BoolValue + 13, // 175: grpc.Bridge.AvailableKeychains:output_type -> grpc.AvailableKeychainsResponse + 81, // 176: grpc.Bridge.SetCurrentKeychain:output_type -> google.protobuf.Empty + 80, // 177: grpc.Bridge.CurrentKeychain:output_type -> google.protobuf.StringValue + 17, // 178: grpc.Bridge.GetUserList:output_type -> grpc.UserListResponse + 14, // 179: grpc.Bridge.GetUser:output_type -> grpc.User + 81, // 180: grpc.Bridge.SetUserSplitMode:output_type -> google.protobuf.Empty + 81, // 181: grpc.Bridge.SendBadEventUserFeedback:output_type -> google.protobuf.Empty + 81, // 182: grpc.Bridge.LogoutUser:output_type -> google.protobuf.Empty + 81, // 183: grpc.Bridge.RemoveUser:output_type -> google.protobuf.Empty + 81, // 184: grpc.Bridge.ConfigureUserAppleMail:output_type -> google.protobuf.Empty + 82, // 185: grpc.Bridge.IsTLSCertificateInstalled:output_type -> google.protobuf.BoolValue + 81, // 186: grpc.Bridge.InstallTLSCertificate:output_type -> google.protobuf.Empty + 81, // 187: grpc.Bridge.ExportTLSCertificates:output_type -> google.protobuf.Empty + 20, // 188: grpc.Bridge.RunEventStream:output_type -> grpc.StreamEvent + 81, // 189: grpc.Bridge.StopEventStream:output_type -> google.protobuf.Empty + 81, // 190: grpc.Bridge.TriggerRepair:output_type -> google.protobuf.Empty + 130, // [130:191] is the sub-list for method output_type + 69, // [69:130] is the sub-list for method input_type 69, // [69:69] is the sub-list for extension type_name 69, // [69:69] is the sub-list for extension extendee 0, // [0:69] is the sub-list for field type_name diff --git a/internal/frontend/grpc/bridge.proto b/internal/frontend/grpc/bridge.proto index 369aebf5..2161487f 100644 --- a/internal/frontend/grpc/bridge.proto +++ b/internal/frontend/grpc/bridge.proto @@ -98,11 +98,6 @@ service Bridge { rpc RemoveUser(google.protobuf.StringValue) returns (google.protobuf.Empty); rpc ConfigureUserAppleMail(ConfigureAppleMailRequest) returns (google.protobuf.Empty); - // Telemetry - rpc ReportBugClicked(google.protobuf.Empty) returns (google.protobuf.Empty); - rpc AutoconfigClicked(google.protobuf.StringValue) returns (google.protobuf.Empty); - rpc ExternalLinkClicked(google.protobuf.StringValue) returns (google.protobuf.Empty); - // TLS certificate related calls rpc IsTLSCertificateInstalled(google.protobuf.Empty) returns (google.protobuf.BoolValue); rpc InstallTLSCertificate(google.protobuf.Empty) returns (google.protobuf.Empty); diff --git a/internal/frontend/grpc/bridge_grpc.pb.go b/internal/frontend/grpc/bridge_grpc.pb.go index 7b55d529..8573e9d5 100644 --- a/internal/frontend/grpc/bridge_grpc.pb.go +++ b/internal/frontend/grpc/bridge_grpc.pb.go @@ -93,9 +93,6 @@ const ( Bridge_LogoutUser_FullMethodName = "/grpc.Bridge/LogoutUser" Bridge_RemoveUser_FullMethodName = "/grpc.Bridge/RemoveUser" Bridge_ConfigureUserAppleMail_FullMethodName = "/grpc.Bridge/ConfigureUserAppleMail" - Bridge_ReportBugClicked_FullMethodName = "/grpc.Bridge/ReportBugClicked" - Bridge_AutoconfigClicked_FullMethodName = "/grpc.Bridge/AutoconfigClicked" - Bridge_ExternalLinkClicked_FullMethodName = "/grpc.Bridge/ExternalLinkClicked" Bridge_IsTLSCertificateInstalled_FullMethodName = "/grpc.Bridge/IsTLSCertificateInstalled" Bridge_InstallTLSCertificate_FullMethodName = "/grpc.Bridge/InstallTLSCertificate" Bridge_ExportTLSCertificates_FullMethodName = "/grpc.Bridge/ExportTLSCertificates" @@ -170,10 +167,6 @@ type BridgeClient interface { LogoutUser(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) RemoveUser(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) ConfigureUserAppleMail(ctx context.Context, in *ConfigureAppleMailRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) - // Telemetry - ReportBugClicked(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) - AutoconfigClicked(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) - ExternalLinkClicked(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) // TLS certificate related calls IsTLSCertificateInstalled(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) InstallTLSCertificate(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) @@ -688,33 +681,6 @@ func (c *bridgeClient) ConfigureUserAppleMail(ctx context.Context, in *Configure return out, nil } -func (c *bridgeClient) ReportBugClicked(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_ReportBugClicked_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *bridgeClient) AutoconfigClicked(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_AutoconfigClicked_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *bridgeClient) ExternalLinkClicked(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_ExternalLinkClicked_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *bridgeClient) IsTLSCertificateInstalled(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { out := new(wrapperspb.BoolValue) err := c.cc.Invoke(ctx, Bridge_IsTLSCertificateInstalled_FullMethodName, in, out, opts...) @@ -858,10 +824,6 @@ type BridgeServer interface { LogoutUser(context.Context, *wrapperspb.StringValue) (*emptypb.Empty, error) RemoveUser(context.Context, *wrapperspb.StringValue) (*emptypb.Empty, error) ConfigureUserAppleMail(context.Context, *ConfigureAppleMailRequest) (*emptypb.Empty, error) - // Telemetry - ReportBugClicked(context.Context, *emptypb.Empty) (*emptypb.Empty, error) - AutoconfigClicked(context.Context, *wrapperspb.StringValue) (*emptypb.Empty, error) - ExternalLinkClicked(context.Context, *wrapperspb.StringValue) (*emptypb.Empty, error) // TLS certificate related calls IsTLSCertificateInstalled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) InstallTLSCertificate(context.Context, *emptypb.Empty) (*emptypb.Empty, error) @@ -1043,15 +1005,6 @@ func (UnimplementedBridgeServer) RemoveUser(context.Context, *wrapperspb.StringV func (UnimplementedBridgeServer) ConfigureUserAppleMail(context.Context, *ConfigureAppleMailRequest) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method ConfigureUserAppleMail not implemented") } -func (UnimplementedBridgeServer) ReportBugClicked(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method ReportBugClicked not implemented") -} -func (UnimplementedBridgeServer) AutoconfigClicked(context.Context, *wrapperspb.StringValue) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method AutoconfigClicked not implemented") -} -func (UnimplementedBridgeServer) ExternalLinkClicked(context.Context, *wrapperspb.StringValue) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method ExternalLinkClicked not implemented") -} func (UnimplementedBridgeServer) IsTLSCertificateInstalled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { return nil, status.Errorf(codes.Unimplemented, "method IsTLSCertificateInstalled not implemented") } @@ -2073,60 +2026,6 @@ func _Bridge_ConfigureUserAppleMail_Handler(srv interface{}, ctx context.Context return interceptor(ctx, in, info, handler) } -func _Bridge_ReportBugClicked_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(emptypb.Empty) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(BridgeServer).ReportBugClicked(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Bridge_ReportBugClicked_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BridgeServer).ReportBugClicked(ctx, req.(*emptypb.Empty)) - } - return interceptor(ctx, in, info, handler) -} - -func _Bridge_AutoconfigClicked_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(wrapperspb.StringValue) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(BridgeServer).AutoconfigClicked(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Bridge_AutoconfigClicked_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BridgeServer).AutoconfigClicked(ctx, req.(*wrapperspb.StringValue)) - } - return interceptor(ctx, in, info, handler) -} - -func _Bridge_ExternalLinkClicked_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(wrapperspb.StringValue) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(BridgeServer).ExternalLinkClicked(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Bridge_ExternalLinkClicked_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BridgeServer).ExternalLinkClicked(ctx, req.(*wrapperspb.StringValue)) - } - return interceptor(ctx, in, info, handler) -} - func _Bridge_IsTLSCertificateInstalled_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(emptypb.Empty) if err := dec(in); err != nil { @@ -2465,18 +2364,6 @@ var Bridge_ServiceDesc = grpc.ServiceDesc{ MethodName: "ConfigureUserAppleMail", Handler: _Bridge_ConfigureUserAppleMail_Handler, }, - { - MethodName: "ReportBugClicked", - Handler: _Bridge_ReportBugClicked_Handler, - }, - { - MethodName: "AutoconfigClicked", - Handler: _Bridge_AutoconfigClicked_Handler, - }, - { - MethodName: "ExternalLinkClicked", - Handler: _Bridge_ExternalLinkClicked_Handler, - }, { MethodName: "IsTLSCertificateInstalled", Handler: _Bridge_IsTLSCertificateInstalled_Handler, diff --git a/internal/frontend/grpc/service_telemetry.go b/internal/frontend/grpc/service_telemetry.go deleted file mode 100644 index d81107e9..00000000 --- a/internal/frontend/grpc/service_telemetry.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2024 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -package grpc - -import ( - "context" - - "github.com/ProtonMail/gluon/async" - "google.golang.org/protobuf/types/known/emptypb" - "google.golang.org/protobuf/types/known/wrapperspb" -) - -func (s *Service) ReportBugClicked(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { - defer async.HandlePanic(s.panicHandler) - s.bridge.ReportBugClicked() - return &emptypb.Empty{}, nil -} - -func (s *Service) AutoconfigClicked(_ context.Context, client *wrapperspb.StringValue) (*emptypb.Empty, error) { - defer async.HandlePanic(s.panicHandler) - s.bridge.AutoconfigUsed(client.Value) - return &emptypb.Empty{}, nil -} - -func (s *Service) ExternalLinkClicked(_ context.Context, article *wrapperspb.StringValue) (*emptypb.Empty, error) { - defer async.HandlePanic(s.panicHandler) - s.bridge.ExternalLinkClicked(article.Value) - return &emptypb.Empty{}, nil -} diff --git a/internal/locations/locations.go b/internal/locations/locations.go index f59f0ec0..1c49bb1a 100644 --- a/internal/locations/locations.go +++ b/internal/locations/locations.go @@ -188,16 +188,6 @@ func (l *Locations) ProvideUpdatesPath() (string, error) { return l.getUpdatesPath(), nil } -// ProvideStatsPath returns a location for statistics files (e.g. ~/.local/share///stats). -// It creates it if it doesn't already exist. -func (l *Locations) ProvideStatsPath() (string, error) { - if err := os.MkdirAll(l.getStatsPath(), 0o700); err != nil { - return "", err - } - - return l.getStatsPath(), nil -} - func (l *Locations) ProvideIMAPSyncConfigPath() (string, error) { if err := os.MkdirAll(l.getIMAPSyncConfigPath(), 0o700); err != nil { return "", err @@ -252,10 +242,6 @@ func (l *Locations) getNotificationsCachePath() string { return filepath.Join(l.userCache, "notifications") } -func (l *Locations) getStatsPath() string { - return filepath.Join(l.userData, "stats") -} - func (l *Locations) getUnleashCachePath() string { return filepath.Join(l.userCache, "unleash_cache") } // Clear removes everything except the lock and update files. diff --git a/internal/services/imapservice/connector.go b/internal/services/imapservice/connector.go index 04cc5aea..31ab8df4 100644 --- a/internal/services/imapservice/connector.go +++ b/internal/services/imapservice/connector.go @@ -56,7 +56,6 @@ type Connector struct { identityState sharedIdentity client APIClient - telemetry Telemetry reporter reporter.Reporter panicHandler async.PanicHandler sendRecorder *sendrecorder.SendRecorder @@ -80,7 +79,6 @@ func NewConnector( addressMode usertypes.AddressMode, sendRecorder *sendrecorder.SendRecorder, panicHandler async.PanicHandler, - telemetry Telemetry, reporter reporter.Reporter, showAllMail bool, syncState *SyncState, @@ -96,7 +94,6 @@ func NewConnector( attrs: defaultMailboxAttributes(), client: apiClient, - telemetry: telemetry, reporter: reporter, panicHandler: panicHandler, sendRecorder: sendRecorder, @@ -169,10 +166,9 @@ func (s *Connector) Init(ctx context.Context, cache connector.IMAPState) error { }) } -func (s *Connector) Authorize(ctx context.Context, username string, password []byte) bool { +func (s *Connector) Authorize(_ context.Context, username string, password []byte) bool { addrID, err := s.identityState.CheckAuth(username, password) if err != nil { - s.telemetry.ReportConfigStatusFailure("IMAP " + err.Error()) return false } @@ -180,8 +176,6 @@ func (s *Connector) Authorize(ctx context.Context, username string, password []b return false } - s.telemetry.SendConfigStatusSuccess(ctx) - return true } diff --git a/internal/services/imapservice/service.go b/internal/services/imapservice/service.go index 3ce0d63e..989b78fb 100644 --- a/internal/services/imapservice/service.go +++ b/internal/services/imapservice/service.go @@ -47,12 +47,6 @@ type EventProvider interface { RewindEventID(ctx context.Context, eventID string) error } -type Telemetry interface { - useridentity.Telemetry - SendConfigStatusSuccess(ctx context.Context) - ReportConfigStatusFailure(errDetails string) -} - type GluonIDProvider interface { GetGluonID(addrID string) (string, bool) GetGluonIDs() map[string]string @@ -77,7 +71,6 @@ type Service struct { serverManager IMAPServerManager eventPublisher events.EventPublisher - telemetry Telemetry panicHandler async.PanicHandler sendRecorder *sendrecorder.SendRecorder reporter reporter.Reporter @@ -112,7 +105,6 @@ func NewService( keyPassProvider useridentity.KeyPassProvider, panicHandler async.PanicHandler, sendRecorder *sendrecorder.SendRecorder, - telemetry Telemetry, reporter reporter.Reporter, addressMode usertypes.AddressMode, subscription events.Subscription, @@ -150,7 +142,6 @@ func NewService( panicHandler: panicHandler, sendRecorder: sendRecorder, - telemetry: telemetry, reporter: reporter, connectors: make(map[string]*Connector), @@ -513,7 +504,6 @@ func (s *Service) buildConnectors() (map[string]*Connector, error) { s.addressMode, s.sendRecorder, s.panicHandler, - s.telemetry, s.reporter, s.showAllMail, s.syncStateProvider, @@ -531,7 +521,6 @@ func (s *Service) buildConnectors() (map[string]*Connector, error) { s.addressMode, s.sendRecorder, s.panicHandler, - s.telemetry, s.reporter, s.showAllMail, s.syncStateProvider, diff --git a/internal/services/imapservice/service_address_events.go b/internal/services/imapservice/service_address_events.go index 6dfa8b94..163c5b65 100644 --- a/internal/services/imapservice/service_address_events.go +++ b/internal/services/imapservice/service_address_events.go @@ -154,7 +154,6 @@ func addNewAddressSplitMode(ctx context.Context, s *Service, addrID string) erro s.addressMode, s.sendRecorder, s.panicHandler, - s.telemetry, s.reporter, s.showAllMail, s.syncStateProvider, diff --git a/internal/services/smtp/accounts.go b/internal/services/smtp/accounts.go index f98d1d01..6a985053 100644 --- a/internal/services/smtp/accounts.go +++ b/internal/services/smtp/accounts.go @@ -66,14 +66,9 @@ func (s *Accounts) CheckAuth(user string, password []byte) (string, string, erro continue } - account.service.telemetry.ReportSMTPAuthSuccess(context.Background()) return id, addrID, nil } - for _, service := range s.accounts { - service.service.telemetry.ReportSMTPAuthFailed(user) - } - return "", "", ErrNoSuchUser } diff --git a/internal/services/smtp/service.go b/internal/services/smtp/service.go index e2f10649..be969201 100644 --- a/internal/services/smtp/service.go +++ b/internal/services/smtp/service.go @@ -39,12 +39,6 @@ import ( "github.com/sirupsen/logrus" ) -type Telemetry interface { - useridentity.Telemetry - ReportSMTPAuthSuccess(context.Context) - ReportSMTPAuthFailed(username string) -} - type Service struct { userID string panicHandler async.PanicHandler @@ -57,7 +51,6 @@ type Service struct { bridgePassProvider useridentity.BridgePassProvider keyPassProvider useridentity.KeyPassProvider identityState *useridentity.State - telemetry Telemetry eventService userevents.Subscribable subscription *userevents.EventChanneledSubscriber @@ -76,7 +69,6 @@ func NewService( reporter reporter.Reporter, bridgePassProvider useridentity.BridgePassProvider, keyPassProvider useridentity.KeyPassProvider, - telemetry Telemetry, eventService userevents.Subscribable, mode usertypes.AddressMode, identityState *useridentity.State, @@ -99,7 +91,6 @@ func NewService( bridgePassProvider: bridgePassProvider, keyPassProvider: keyPassProvider, - telemetry: telemetry, identityState: identityState, eventService: eventService, diff --git a/internal/services/useridentity/mocks/mocks.go b/internal/services/useridentity/mocks/mocks.go index 7c342639..a4655013 100644 --- a/internal/services/useridentity/mocks/mocks.go +++ b/internal/services/useridentity/mocks/mocks.go @@ -64,38 +64,3 @@ func (mr *MockIdentityProviderMockRecorder) GetUser(arg0 interface{}) *gomock.Ca mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUser", reflect.TypeOf((*MockIdentityProvider)(nil).GetUser), arg0) } - -// MockTelemetry is a mock of Telemetry interface. -type MockTelemetry struct { - ctrl *gomock.Controller - recorder *MockTelemetryMockRecorder -} - -// MockTelemetryMockRecorder is the mock recorder for MockTelemetry. -type MockTelemetryMockRecorder struct { - mock *MockTelemetry -} - -// NewMockTelemetry creates a new mock instance. -func NewMockTelemetry(ctrl *gomock.Controller) *MockTelemetry { - mock := &MockTelemetry{ctrl: ctrl} - mock.recorder = &MockTelemetryMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockTelemetry) EXPECT() *MockTelemetryMockRecorder { - return m.recorder -} - -// ReportConfigStatusFailure mocks base method. -func (m *MockTelemetry) ReportConfigStatusFailure(arg0 string) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "ReportConfigStatusFailure", arg0) -} - -// ReportConfigStatusFailure indicates an expected call of ReportConfigStatusFailure. -func (mr *MockTelemetryMockRecorder) ReportConfigStatusFailure(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReportConfigStatusFailure", reflect.TypeOf((*MockTelemetry)(nil).ReportConfigStatusFailure), arg0) -} diff --git a/internal/services/useridentity/service.go b/internal/services/useridentity/service.go index 7e916da8..b6f4e693 100644 --- a/internal/services/useridentity/service.go +++ b/internal/services/useridentity/service.go @@ -50,7 +50,6 @@ type Service struct { subscription *userevents.EventChanneledSubscriber bridgePassProvider BridgePassProvider - telemetry Telemetry } func NewService( @@ -58,7 +57,6 @@ func NewService( eventPublisher events.EventPublisher, state *State, bridgePassProvider BridgePassProvider, - telemetry Telemetry, ) *Service { subscriberName := fmt.Sprintf("identity-%v", state.User.ID) @@ -73,7 +71,6 @@ func NewService( }), subscription: userevents.NewEventSubscriber(subscriberName), bridgePassProvider: bridgePassProvider, - telemetry: telemetry, } } diff --git a/internal/services/useridentity/service_test.go b/internal/services/useridentity/service_test.go index c2b43df3..bfbdcca0 100644 --- a/internal/services/useridentity/service_test.go +++ b/internal/services/useridentity/service_test.go @@ -361,10 +361,9 @@ func newTestService(_ *testing.T, mockCtrl *gomock.Controller) (*Service, *mocks eventPublisher := mocks2.NewMockEventPublisher(mockCtrl) provider := mocks.NewMockIdentityProvider(mockCtrl) user := newTestUser() - telemetry := mocks.NewMockTelemetry(mockCtrl) bridgePassProvider := NewFixedBridgePassProvider([]byte("hello")) - service := NewService(subscribable, eventPublisher, NewState(*user, newTestAddresses(), provider), bridgePassProvider, telemetry) + service := NewService(subscribable, eventPublisher, NewState(*user, newTestAddresses(), provider), bridgePassProvider) return service, eventPublisher, provider } diff --git a/internal/services/useridentity/telemetry.go b/internal/services/useridentity/telemetry.go deleted file mode 100644 index 06f1fcc8..00000000 --- a/internal/services/useridentity/telemetry.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2024 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -package useridentity - -type Telemetry interface { - ReportConfigStatusFailure(errDetails string) -} diff --git a/internal/user/config_status.go b/internal/user/config_status.go deleted file mode 100644 index b5b7164c..00000000 --- a/internal/user/config_status.go +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright (c) 2024 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -package user - -import ( - "context" - "encoding/json" - "errors" - - "github.com/ProtonMail/gluon/reporter" - "github.com/ProtonMail/proton-bridge/v3/internal/configstatus" - "github.com/ProtonMail/proton-bridge/v3/internal/kb" -) - -func (user *User) SendConfigStatusSuccess(ctx context.Context) { - if user.configStatus.IsFromFailure() { - user.SendConfigStatusRecovery(ctx) - return - } - if !user.IsTelemetryEnabled(ctx) { - return - } - if !user.configStatus.IsPending() { - return - } - - var builder configstatus.ConfigSuccessBuilder - success := builder.New(user.configStatus) - data, err := json.Marshal(success) - if err != nil { - if err := user.reporter.ReportMessageWithContext("Cannot parse config_success data.", reporter.Context{ - "error": err, - }); err != nil { - user.log.WithError(err).Error("Failed to report config_success data parsing error.") - } - return - } - - if err := user.SendTelemetry(ctx, data); err == nil { - user.log.Info("Configuration Status Success event sent.") - if err := user.configStatus.ApplySuccess(); err != nil { - user.log.WithError(err).Error("Failed to ApplySuccess on config_status.") - } - } -} - -func (user *User) SendConfigStatusAbort(ctx context.Context, withTelemetry bool) { - if err := user.configStatus.Remove(); err != nil { - user.log.WithError(err).Error("Failed to remove config_status file.") - } - - if !user.configStatus.IsPending() { - return - } - if !withTelemetry || !user.IsTelemetryEnabled(ctx) { - return - } - var builder configstatus.ConfigAbortBuilder - abort := builder.New(user.configStatus) - data, err := json.Marshal(abort) - if err != nil { - if err := user.reporter.ReportMessageWithContext("Cannot parse config_abort data.", reporter.Context{ - "error": err, - }); err != nil { - user.log.WithError(err).Error("Failed to report config_abort data parsing error.") - } - return - } - - if err := user.SendTelemetry(ctx, data); err == nil { - user.log.Info("Configuration Status Abort event sent.") - } -} - -func (user *User) SendConfigStatusRecovery(ctx context.Context) { - if !user.configStatus.IsFromFailure() { - user.SendConfigStatusSuccess(ctx) - return - } - if !user.IsTelemetryEnabled(ctx) { - return - } - if !user.configStatus.IsPending() { - return - } - - var builder configstatus.ConfigRecoveryBuilder - success := builder.New(user.configStatus) - data, err := json.Marshal(success) - if err != nil { - if err := user.reporter.ReportMessageWithContext("Cannot parse config_recovery data.", reporter.Context{ - "error": err, - }); err != nil { - user.log.WithError(err).Error("Failed to report config_recovery data parsing error.") - } - return - } - - if err := user.SendTelemetry(ctx, data); err == nil { - user.log.Info("Configuration Status Recovery event sent.") - if err := user.configStatus.ApplySuccess(); err != nil { - user.log.WithError(err).Error("Failed to ApplySuccess on config_status.") - } - } -} - -func (user *User) SendConfigStatusProgress(ctx context.Context) { - if !user.IsTelemetryEnabled(ctx) { - return - } - if !user.configStatus.IsPending() { - return - } - var builder configstatus.ConfigProgressBuilder - progress := builder.New(user.configStatus) - if progress.Values.NbDay == 0 { - return - } - if progress.Values.NbDaySinceLast == 0 { - return - } - - data, err := json.Marshal(progress) - if err != nil { - if err := user.reporter.ReportMessageWithContext("Cannot parse config_progress data.", reporter.Context{ - "error": err, - }); err != nil { - user.log.WithError(err).Error("Failed to report config_progress data parsing error.") - } - return - } - - if err := user.SendTelemetry(ctx, data); err == nil { - user.log.Info("Configuration Status Progress event sent.") - if err := user.configStatus.ApplyProgress(); err != nil { - user.log.WithError(err).Error("Failed to ApplyProgress on config_status.") - } - } -} - -func (user *User) ReportConfigStatusFailure(errDetails string) { - if user.configStatus.IsPending() { - return - } - - if err := user.configStatus.ApplyFailure(errDetails); err != nil { - user.log.WithError(err).Error("Failed to ApplyFailure on config_status.") - } else { - user.log.Info("Configuration Status is back to Pending due to Failure.") - } -} - -func (user *User) ReportBugClicked() { - if !user.configStatus.IsPending() { - return - } - - if err := user.configStatus.ReportClicked(); err != nil { - user.log.WithError(err).Error("Failed to log ReportClicked in config_status.") - } -} - -func (user *User) ReportBugSent() { - if !user.configStatus.IsPending() { - return - } - - if err := user.configStatus.ReportSent(); err != nil { - user.log.WithError(err).Error("Failed to log ReportSent in config_status.") - } -} - -func (user *User) AutoconfigUsed(client string) { - if !user.configStatus.IsPending() { - return - } - - if err := user.configStatus.AutoconfigUsed(client); err != nil { - user.log.WithError(err).Error("Failed to log Autoconf in config_status.") - } -} - -func (user *User) ExternalLinkClicked(url string) { - if !user.configStatus.IsPending() { - return - } - - const externalLinkWasClicked = "External link was clicked." - index, err := kb.GetArticleIndex(url) - if err != nil { - if errors.Is(err, kb.ErrArticleNotFound) { - user.log.WithField("report", false).WithField("url", url).Debug(externalLinkWasClicked) - } else { - user.log.WithError(err).Error("Failed to retrieve list of KB articles.") - } - return - } - - if err := user.configStatus.RecordLinkClicked(index); err != nil { - user.log.WithError(err).Error("Failed to log LinkClicked in config_status.") - } else { - user.log.WithField("report", true).WithField("url", url).Debug(externalLinkWasClicked) - } -} diff --git a/internal/user/user.go b/internal/user/user.go index 6e1ce73f..b9c1170c 100644 --- a/internal/user/user.go +++ b/internal/user/user.go @@ -21,13 +21,11 @@ import ( "context" "encoding/json" "fmt" - "path/filepath" "time" "github.com/ProtonMail/gluon/async" "github.com/ProtonMail/gluon/reporter" "github.com/ProtonMail/go-proton-api" - "github.com/ProtonMail/proton-bridge/v3/internal/configstatus" "github.com/ProtonMail/proton-bridge/v3/internal/events" "github.com/ProtonMail/proton-bridge/v3/internal/safe" "github.com/ProtonMail/proton-bridge/v3/internal/services/imapservice" @@ -78,10 +76,7 @@ type User struct { maxSyncMemory uint64 panicHandler async.PanicHandler - configStatus *configstatus.ConfigurationStatus telemetryManager telemetry.Availability - // goStatusProgress triggers a check/sending if progress is needed. - goStatusProgress func() eventService *userevents.Service identityService *useridentity.Service @@ -104,7 +99,6 @@ func New( crashHandler async.PanicHandler, showAllMail bool, maxSyncMemory uint64, - statsDir string, telemetryManager telemetry.Availability, imapServerManager imapservice.IMAPServerManager, smtpServerManager smtp.ServerManager, @@ -125,7 +119,6 @@ func New( crashHandler, showAllMail, maxSyncMemory, - statsDir, telemetryManager, imapServerManager, smtpServerManager, @@ -159,7 +152,6 @@ func newImpl( crashHandler async.PanicHandler, showAllMail bool, maxSyncMemory uint64, - statsDir string, telemetryManager telemetry.Availability, imapServerManager imapservice.IMAPServerManager, smtpServerManager smtp.ServerManager, @@ -198,12 +190,6 @@ func newImpl( "numLabels": len(apiLabels), }).Info("Creating user object") - configStatusFile := filepath.Join(statsDir, apiUser.ID+".json") - configStatus, err := configstatus.LoadConfigurationStatus(configStatusFile) - if err != nil { - return nil, fmt.Errorf("failed to init configuration status file: %w", err) - } - sendRecorder := sendrecorder.NewSendRecorder(sendrecorder.SendEntryExpiry) // Create the user object. @@ -225,7 +211,6 @@ func newImpl( panicHandler: crashHandler, - configStatus: configStatus, telemetryManager: telemetryManager, serviceGroup: orderedtasks.NewOrderedCancelGroup(crashHandler), @@ -248,7 +233,7 @@ func newImpl( addressMode := usertypes.VaultToAddressMode(encVault.AddressMode()) - user.identityService = useridentity.NewService(user.eventService, user, identityState, encVault, user) + user.identityService = useridentity.NewService(user.eventService, user, identityState, encVault) user.telemetryService = telemetryservice.NewService(apiUser.ID, client, user.eventService) @@ -260,7 +245,6 @@ func newImpl( reporter, encVault, encVault, - user, user.eventService, addressMode, identityState.Clone(), @@ -279,7 +263,6 @@ func newImpl( encVault, crashHandler, sendRecorder, - user, reporter, addressMode, eventSubscription, @@ -291,12 +274,6 @@ func newImpl( user.notificationService = notifications.NewService(user.id, user.eventService, user, notificationStore, getFlagValueFn, observabilityService) - // Check for status_progress when triggered. - user.goStatusProgress = user.tasks.PeriodicOrTrigger(configstatus.ProgressCheckInterval, 0, func(ctx context.Context) { - user.SendConfigStatusProgress(ctx) - }) - defer user.goStatusProgress() - // When we receive an auth object, we update it in the vault. // This will be used to authorize the user on the next run. user.client.AddAuthHandler(func(auth proton.Auth) { @@ -698,19 +675,6 @@ func (user *User) SendTelemetry(ctx context.Context, data []byte) error { return nil } -func (user *User) ReportSMTPAuthFailed(username string) { - emails := user.Emails() - for _, mail := range emails { - if mail == username { - user.ReportConfigStatusFailure("SMTP invalid username or password") - } - } -} - -func (user *User) ReportSMTPAuthSuccess(ctx context.Context) { - user.SendConfigStatusSuccess(ctx) -} - func (user *User) GetSMTPService() *smtp.Service { return user.smtpService } diff --git a/internal/user/user_test.go b/internal/user/user_test.go index 64ccab9b..5cbc265a 100644 --- a/internal/user/user_test.go +++ b/internal/user/user_test.go @@ -160,7 +160,6 @@ func withUser(tb testing.TB, ctx context.Context, _ *server.Server, m *proton.Ma nil, true, vault.DefaultMaxSyncMemory, - tb.TempDir(), manager, nullIMAPServerManager, nullSMTPServerManager, diff --git a/tests/config_status_test.go b/tests/config_status_test.go deleted file mode 100644 index fef673e9..00000000 --- a/tests/config_status_test.go +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright (c) 2024 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -package tests - -import ( - "encoding/json" - "fmt" - "os" - "path/filepath" - "time" - - "github.com/ProtonMail/go-proton-api" - "github.com/ProtonMail/go-proton-api/server" - "github.com/ProtonMail/proton-bridge/v3/internal/configstatus" - "github.com/sirupsen/logrus" -) - -func (s *scenario) configStatusFileExistForUser(username string) error { - configStatusFile, err := getConfigStatusFile(s.t, username) - if err != nil { - return err - } - if _, err := os.Stat(configStatusFile); err != nil { - return err - } - return nil -} - -func (s *scenario) configStatusIsPendingForUser(username string) error { - data, err := loadConfigStatusFile(s.t, username) - if err != nil { - return err - } - - if data.DataV1.PendingSince.IsZero() { - return fmt.Errorf("expected ConfigStatus pending but got success instead") - } - - return nil -} - -func (s *scenario) configStatusIsPendingWithFailureForUser(username string) error { - data, err := loadConfigStatusFile(s.t, username) - if err != nil { - return err - } - - if data.DataV1.PendingSince.IsZero() { - return fmt.Errorf("expected ConfigStatus pending but got success instead") - } - if data.DataV1.FailureDetails == "" { - return fmt.Errorf("expected ConfigStatus pending with failure but got no failure instead") - } - - return nil -} - -func (s *scenario) configStatusSucceedForUser(username string) error { - data, err := loadConfigStatusFile(s.t, username) - if err != nil { - return err - } - - if !data.DataV1.PendingSince.IsZero() { - return fmt.Errorf("expected ConfigStatus success but got pending since %s", data.DataV1.PendingSince) - } - - return nil -} - -func (s *scenario) configStatusEventIsEventuallySendXTime(event string, number int) error { - return eventually(func() error { - err := s.checkEventSentForUser(event, number) - logrus.WithError(err).Trace("Matching eventually") - return err - }) -} - -func (s *scenario) configStatusEventIsNotSendMoreThanXTime(event string, number int) error { - if err := eventually(func() error { - err := s.checkEventSentForUser(event, number+1) - logrus.WithError(err).Trace("Matching eventually") - return err - }); err == nil { - return fmt.Errorf("expected %s to be sent %d but catch %d", event, number, number+1) - } - return nil -} - -func (s *scenario) forceConfigStatusProgressToBeSentForUser(username string) error { - configStatusFile, err := getConfigStatusFile(s.t, username) - if err != nil { - return err - } - - data, err := loadConfigStatusFile(s.t, username) - if err != nil { - return err - } - data.DataV1.PendingSince = time.Now().AddDate(0, 0, -2) - data.DataV1.LastProgress = time.Now().AddDate(0, 0, -1) - - f, err := os.Create(configStatusFile) - if err != nil { - return err - } - defer func() { _ = f.Close() }() - - return json.NewEncoder(f).Encode(data) -} - -func (s *scenario) checkEventSentForUser(event string, number int) error { - calls, err := getLastTelemetryEventSent(s.t, event) - if err != nil { - return err - } - if len(calls) != number { - return fmt.Errorf("expected %s to be sent %d but catch %d", event, number, len(calls)) - } - return nil -} - -func getConfigStatusFile(t *testCtx, username string) (string, error) { - userID := t.getUserByName(username).getUserID() - statsDir, err := t.locator.ProvideStatsPath() - if err != nil { - return "", fmt.Errorf("failed to get Statistics directory: %w", err) - } - return filepath.Join(statsDir, userID+".json"), nil -} - -func loadConfigStatusFile(t *testCtx, username string) (configstatus.ConfigurationStatusData, error) { - data := configstatus.ConfigurationStatusData{} - - configStatusFile, err := getConfigStatusFile(t, username) - if err != nil { - return data, err - } - - if _, err := os.Stat(configStatusFile); err != nil { - return data, err - } - - f, err := os.Open(configStatusFile) - if err != nil { - return data, err - } - defer func() { _ = f.Close() }() - - err = json.NewDecoder(f).Decode(&data) - return data, err -} - -func getLastTelemetryEventSent(t *testCtx, event string) ([]server.Call, error) { - var matches []server.Call - - calls, err := t.getAllCalls("POST", "/data/v1/stats") - if err != nil { - return matches, err - } - - for _, call := range calls { - var req proton.SendStatsReq - if err := json.Unmarshal(call.RequestBody, &req); err != nil { - continue - } - if req.Event == event { - matches = append(matches, call) - } - } - return matches, err -} diff --git a/tests/features/bridge/config_status.feature b/tests/features/bridge/config_status.feature deleted file mode 100644 index 85e7b5bd..00000000 --- a/tests/features/bridge/config_status.feature +++ /dev/null @@ -1,79 +0,0 @@ -Feature: Configuration Status Telemetry - Background: - Given there exists an account with username "[user:user]" and password "password" - Then it succeeds - When bridge starts - Then it succeeds - - - Scenario: Init config status on user addition - Then bridge telemetry feature is enabled - When the user logs in with username "[user:user]" and password "password" - Then config status file exist for user "[user:user]" - And config status is pending for user "[user:user]" - - - Scenario: Config Status Success on IMAP - Then bridge telemetry feature is enabled - When the user logs in with username "[user:user]" and password "password" - Then config status file exist for user "[user:user]" - And config status is pending for user "[user:user]" - When user "[user:user]" connects and authenticates IMAP client "1" - Then config status succeed for user "[user:user]" - And config status event "bridge_config_success" is eventually send 1 time - - - Scenario: Config Status Success on SMTP - Then bridge telemetry feature is enabled - When the user logs in with username "[user:user]" and password "password" - Then config status file exist for user "[user:user]" - And config status is pending for user "[user:user]" - When user "[user:user]" connects and authenticates SMTP client "1" - Then config status succeed for user "[user:user]" - And config status event "bridge_config_success" is eventually send 1 time - - - Scenario: Config Status Success send only once - Then bridge telemetry feature is enabled - When the user logs in with username "[user:user]" and password "password" - Then config status file exist for user "[user:user]" - And config status is pending for user "[user:user]" - When user "[user:user]" connects and authenticates IMAP client "1" - Then config status succeed for user "[user:user]" - And config status event "bridge_config_success" is eventually send 1 time - When user "[user:user]" connects and authenticates IMAP client "2" - Then config status event "bridge_config_success" is not send more than 1 time - - - Scenario: Config Status Abort - Then bridge telemetry feature is enabled - When the user logs in with username "[user:user]" and password "password" - And user "[user:user]" finishes syncing - Then config status file exist for user "[user:user]" - And config status is pending for user "[user:user]" - When user "[user:user]" is deleted - Then config status event "bridge_config_abort" is eventually send 1 time - - - Scenario: Config Status Recovery from deauth - Then bridge telemetry feature is enabled - When the user logs in with username "[user:user]" and password "password" - And user "[user:user]" connects and authenticates IMAP client "1" - Then config status succeed for user "[user:user]" - When the auth of user "[user:user]" is revoked - Then bridge sends a deauth event for user "[user:user]" - Then config status is pending with failure for user "[user:user]" - When the user logs in with username "[user:user]" and password "password" - And user "[user:user]" connects and authenticates IMAP client "1" - Then config status succeed for user "[user:user]" - And config status event "bridge_config_recovery" is eventually send 1 time - - - Scenario: Config Status Progress - Then bridge telemetry feature is enabled - When the user logs in with username "[user:user]" and password "password" - And config status is pending for user "[user:user]" - And bridge stops - And force config status progress to be sent for user"[user:user]" - And bridge starts - Then config status event "bridge_config_progress" is eventually send 1 time diff --git a/tests/steps_test.go b/tests/steps_test.go index 58bf1358..470a2a0e 100644 --- a/tests/steps_test.go +++ b/tests/steps_test.go @@ -203,13 +203,6 @@ func (s *scenario) steps(ctx *godog.ScenarioContext) { ctx.Step(`^bridge needs to send heartbeat`, s.bridgeNeedsToSendHeartbeat) ctx.Step(`^bridge do not need to send heartbeat`, s.bridgeDoNotNeedToSendHeartbeat) ctx.Step(`^heartbeat is not whitelisted`, s.heartbeatIsNotwhitelisted) - ctx.Step(`^config status file exist for user "([^"]*)"$`, s.configStatusFileExistForUser) - ctx.Step(`^config status is pending for user "([^"]*)"$`, s.configStatusIsPendingForUser) - ctx.Step(`^config status is pending with failure for user "([^"]*)"$`, s.configStatusIsPendingWithFailureForUser) - ctx.Step(`^config status succeed for user "([^"]*)"$`, s.configStatusSucceedForUser) - ctx.Step(`^config status event "([^"]*)" is eventually send (\d+) time`, s.configStatusEventIsEventuallySendXTime) - ctx.Step(`^config status event "([^"]*)" is not send more than (\d+) time`, s.configStatusEventIsNotSendMoreThanXTime) - ctx.Step(`^force config status progress to be sent for user"([^"]*)"$`, s.forceConfigStatusProgressToBeSentForUser) // ==== CONTACT ==== ctx.Step(`^user "([^"]*)" has contact "([^"]*)" with name "([^"]*)"$`, s.userHasContactWithName)