From 71063ac5eecd165ce2db327426d7102f1be484c5 Mon Sep 17 00:00:00 2001 From: Jakub Date: Fri, 1 Sep 2023 14:44:27 +0200 Subject: [PATCH 01/51] fix(GODT-2902): do not check for changed values. Related to GODT-2857. --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5cdf8ab2..eae0c022 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( github.com/0xAX/notificator v0.0.0-20220220101646-ee9b8921e557 github.com/Masterminds/semver/v3 v3.2.0 - github.com/ProtonMail/gluon v0.16.1-0.20230808094407-85a10f17ae92 + github.com/ProtonMail/gluon v0.16.1-0.20230901124123-075229a92cc4 github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a github.com/ProtonMail/go-proton-api v0.4.1-0.20230727082922-9115b4750ec7 github.com/ProtonMail/gopenpgp/v2 v2.7.1-proton diff --git a/go.sum b/go.sum index 69f79877..1e4090b0 100644 --- a/go.sum +++ b/go.sum @@ -23,8 +23,8 @@ github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf h1:yc9daCCYUefEs github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf/go.mod h1:o0ESU9p83twszAU8LBeJKFAAMX14tISa0yk4Oo5TOqo= github.com/ProtonMail/docker-credential-helpers v1.1.0 h1:+kvUIpwWcbtP3WFv5sSvkFn/XLzSqPOB5AAthuk9xPk= github.com/ProtonMail/docker-credential-helpers v1.1.0/go.mod h1:mK0aBveCxhnQ756AmaTfXMZDeULvheYVhF/MWMErN5g= -github.com/ProtonMail/gluon v0.16.1-0.20230808094407-85a10f17ae92 h1:yoaUatxdB6EXChiWdfIBpasJJxrQ6dHJknG0hwBAqmQ= -github.com/ProtonMail/gluon v0.16.1-0.20230808094407-85a10f17ae92/go.mod h1:Og5/Dz1MiGpCJn51XujZwxiLG7WzvvjE5PRpZBQmAHo= +github.com/ProtonMail/gluon v0.16.1-0.20230901124123-075229a92cc4 h1:Uq2v2NYEtlTaK2WTh9BMph2Kv51JxMgvTkd7CjGPYc8= +github.com/ProtonMail/gluon v0.16.1-0.20230901124123-075229a92cc4/go.mod h1:Og5/Dz1MiGpCJn51XujZwxiLG7WzvvjE5PRpZBQmAHo= github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a h1:D+aZah+k14Gn6kmL7eKxoo/4Dr/lK3ChBcwce2+SQP4= github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4= github.com/ProtonMail/go-crypto v0.0.0-20230321155629-9a39f2531310/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE= From a80fd92018438d8ec05d5d11560054537b9d947f Mon Sep 17 00:00:00 2001 From: Jakub Date: Fri, 1 Sep 2023 15:12:34 +0200 Subject: [PATCH 02/51] chore: Trift Bridge 3.4.2 changelog. --- Changelog.md | 6 ++++++ Makefile | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index e635f946..ff849841 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,12 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Trift Bridge 3.4.2 + +### Fixed +* GODT-2902: Do not check for changed values. Related to GODT-2857. + + ## Trift Bridge 3.4.1 ### Fixed diff --git a/Makefile b/Makefile index e61b1f7d..4aff7b68 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.4.1+git +BRIDGE_APP_VERSION?=3.4.2+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From 86e8a566c741d0d4ac72bc355daa92eb8cd1f216 Mon Sep 17 00:00:00 2001 From: Jakub Date: Tue, 12 Sep 2023 07:45:08 +0200 Subject: [PATCH 03/51] chore: Umshiang Bridge 3.5.0 changelog. --- Changelog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Changelog.md b/Changelog.md index 75db7f60..9f72ff55 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,8 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) ## Umshiang Bridge 3.5.0 ### Added +* GODT-2734: Add testing steps to modify account settings. +* GODT-2746: Integration tests for reporting a problem. * GODT-2891: Allow message create & delete during sync. * GODT-2848: Decouple IMAP service from Event Loop. * Add trace profiling option. @@ -19,6 +21,8 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) * GODT-2803: Bridge Database access. ### Changed +* GODT-2909: Remove Timeout on event publish. +* GODT-2913: Reduce the number of configuration failure detected. * GODT-2828: Increase sync progress report frequency. * Test: Fix TestBridge_SyncWithOnGoingEvents. * GODT-2871: Is telemetry enabled as service. From 45d2e9ea639a9c1f9c12781e815b4e7cd071874d Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 13 Sep 2023 10:25:47 +0200 Subject: [PATCH 04/51] chore: update changelog. --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 9f72ff55..918165f2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -75,6 +75,7 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) * GODT-2780: Fix 'QSystemTrayIcon::setVisible: No Icon set' warning in bridge-gui log on startup. * GODT-2778: Fix login screen being disabled after an 'already logged in' error. * Fix typos found by codespell. +* GODT-2577: Answered flag should only be applied to replied messages. ## Trift Bridge 3.4.1 From e6b312b437494ed8866490ed7be4474625596b5f Mon Sep 17 00:00:00 2001 From: Leander Beernaert Date: Tue, 26 Sep 2023 09:08:25 +0200 Subject: [PATCH 05/51] fix(GODT-2949): Fix close of close channel in event service This issue is triggered due to the `Service.Close()` call after the go-routine for the event service exists. It is possible that during this period a recently added subscriber with `pendingOpAdd` gets cancelled and closed. However, the subscriber later also enqueues a `pendingOpRemove` which gets processed again with a call in `user.eventService.Close()` leading to the double close panic. This patch simply removes the `s.Close()` from the service, and leaves the cleanup to called externally from user.Close() or user.Logout(). --- internal/services/userevents/service.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/services/userevents/service.go b/internal/services/userevents/service.go index 52e6d83d..104dfbe8 100644 --- a/internal/services/userevents/service.go +++ b/internal/services/userevents/service.go @@ -192,7 +192,6 @@ func (s *Service) run(ctx context.Context, lastEventID string) { defer s.cpc.Close() defer s.timer.Stop() defer s.log.Info("Exiting service") - defer s.Close() client := network.NewClientRetryWrapper(s.eventSource, &network.ExpCoolDown{}) @@ -303,14 +302,15 @@ func (s *Service) Close() { // Cleanup pending removes. for _, s := range s.pendingSubscriptions { - if s.op == pendingOpRemove { - if !processed.Contains(s.sub) { + if !processed.Contains(s.sub) { + processed.Add(s.sub) + + if s.op == pendingOpRemove { + s.sub.close() + } else { + s.sub.cancel() s.sub.close() } - } else { - s.sub.cancel() - s.sub.close() - processed.Add(s.sub) } } From 236c958703ed2b14702019bd0a2e1ab864b01ce8 Mon Sep 17 00:00:00 2001 From: Leander Beernaert Date: Tue, 26 Sep 2023 09:20:01 +0200 Subject: [PATCH 06/51] fix(GODT-2590): Fix send on closed channel Ensure periodic user tasks are terminated before the other user services. The panic triggered due to the fact that the telemetry service was shutdown before this periodic task. --- internal/user/user.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/user/user.go b/internal/user/user.go index 4e1470a6..e916bc81 100644 --- a/internal/user/user.go +++ b/internal/user/user.go @@ -589,6 +589,8 @@ func (user *User) Logout(ctx context.Context, withAPI bool) error { return fmt.Errorf("failed to remove user from imap server: %w", err) } + user.tasks.CancelAndWait() + // Stop Services user.serviceGroup.CancelAndWait() @@ -598,8 +600,6 @@ func (user *User) Logout(ctx context.Context, withAPI bool) error { // Close imap service. user.imapService.Close() - user.tasks.CancelAndWait() - if withAPI { user.log.Debug("Logging out from API") @@ -621,6 +621,9 @@ func (user *User) Logout(ctx context.Context, withAPI bool) error { func (user *User) Close() { user.log.Info("Closing user") + // Stop any ongoing background tasks. + user.tasks.CancelAndWait() + // Stop Services user.serviceGroup.CancelAndWait() @@ -630,9 +633,6 @@ func (user *User) Close() { // Close imap service. user.imapService.Close() - // Stop any ongoing background tasks. - user.tasks.CancelAndWait() - // Close the user's API client. user.client.Close() From bfe25e3a46c88725d9cd63a73de1b1b462c13239 Mon Sep 17 00:00:00 2001 From: Leander Beernaert Date: Tue, 26 Sep 2023 09:45:27 +0200 Subject: [PATCH 07/51] fix(GODT-2951): Negative WaitGroup Counter Do not defer call to `wg.Done()` in `job.onJobFinished`. If there is an error it will also call `wg.Done()`. --- internal/services/syncservice/job.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/services/syncservice/job.go b/internal/services/syncservice/job.go index 8978ae6b..cad55c90 100644 --- a/internal/services/syncservice/job.go +++ b/internal/services/syncservice/job.go @@ -113,13 +113,14 @@ func (j *Job) onStageCompleted(ctx context.Context, count int64) { } func (j *Job) onJobFinished(ctx context.Context, lastMessageID string, count int64) { - defer j.wg.Done() - if err := j.state.SetLastMessageID(ctx, lastMessageID, count); err != nil { j.log.WithError(err).Error("Failed to store last synced message id") j.onError(err) return } + + // j.onError() also calls j.wg.Done(). + j.wg.Done() j.syncReporter.OnProgress(ctx, count) } From bbe19bf960fba367cfd22e559c12e3d5f19534f5 Mon Sep 17 00:00:00 2001 From: Leander Beernaert Date: Tue, 26 Sep 2023 12:47:53 +0200 Subject: [PATCH 08/51] fix(GODT-2956): Restore old deletion rules When unlabeling a message from trash we have to check if this message is present in another folder before perma-deleting. --- internal/services/imapservice/connector.go | 66 ++++++++++++++++++- tests/features/imap/message/copy.feature | 15 +++++ .../imap/message/delete_from_trash.feature | 6 +- 3 files changed, 82 insertions(+), 5 deletions(-) diff --git a/internal/services/imapservice/connector.go b/internal/services/imapservice/connector.go index 03ca7dbe..e026752f 100644 --- a/internal/services/imapservice/connector.go +++ b/internal/services/imapservice/connector.go @@ -37,6 +37,7 @@ import ( "github.com/ProtonMail/proton-bridge/v3/pkg/message" "github.com/ProtonMail/proton-bridge/v3/pkg/message/parser" "github.com/bradenaw/juniper/stream" + "github.com/bradenaw/juniper/xslices" "github.com/sirupsen/logrus" "golang.org/x/exp/slices" ) @@ -334,8 +335,69 @@ func (s *Connector) RemoveMessagesFromMailbox(ctx context.Context, _ connector.I } if mboxID == proton.TrashLabel || mboxID == proton.DraftsLabel { - if err := s.client.DeleteMessage(ctx, msgIDs...); err != nil { - return err + const ChunkSize = 150 + var msgToPermaDelete []string + + rdLabels := s.labels.Read() + defer rdLabels.Close() + + // There's currently no limit on how many IDs we can filter on, + // but to be nice to API, let's chunk it by 150. + for _, messageIDs := range xslices.Chunk(messageIDs, ChunkSize) { + metadata, err := s.client.GetMessageMetadataPage(ctx, 0, ChunkSize, proton.MessageFilter{ + ID: usertypes.MapTo[imap.MessageID, string](messageIDs), + }) + if err != nil { + return err + } + + // If a message is not preset in any other label other than AllMail, AllDrafts and AllSent, it can be + // permanently deleted. + for _, m := range metadata { + var remainingLabels []string + + for _, id := range m.LabelIDs { + label, ok := rdLabels.GetLabel(id) + if !ok { + // Handle case where this label was newly introduced and we do not yet know about it. + logrus.WithField("labelID", id).Warnf("Unknown label found during expung from Trash, attempting to locate it") + label, err = s.client.GetLabel(ctx, id, proton.LabelTypeFolder, proton.LabelTypeSystem, proton.LabelTypeSystem) + if err != nil { + if errors.Is(err, proton.ErrNoSuchLabel) { + logrus.WithField("labelID", id).Warn("Label does not exist, ignoring") + continue + } + + logrus.WithField("labelID", id).Errorf("Failed to resolve label: %v", err) + return fmt.Errorf("failed to resolve label: %w", err) + } + } + if !WantLabel(label) { + continue + } + + if label.Type == proton.LabelTypeSystem && (id == proton.AllDraftsLabel || + id == proton.AllMailLabel || + id == proton.AllSentLabel || + id == proton.AllScheduledLabel) { + continue + } + + remainingLabels = append(remainingLabels, m.ID) + } + + if len(remainingLabels) == 0 { + msgToPermaDelete = append(msgToPermaDelete, m.ID) + } + } + } + + if len(msgToPermaDelete) != 0 { + logrus.Debugf("Following message(s) will be perma-deleted: %v", msgToPermaDelete) + + if err := s.client.DeleteMessage(ctx, msgToPermaDelete...); err != nil { + return err + } } } diff --git a/tests/features/imap/message/copy.feature b/tests/features/imap/message/copy.feature index 4dd0b6c6..1b44d794 100644 --- a/tests/features/imap/message/copy.feature +++ b/tests/features/imap/message/copy.feature @@ -85,3 +85,18 @@ Feature: IMAP copy messages | from | to | subject | unread | | john.doe@mail.com | [user:user]@[domain] | foo | false | + Scenario: Move message to trash then copy to folder does not delete message + When IMAP client "1" moves the message with subject "foo" from "INBOX" to "Trash" + And it succeeds + Then IMAP client "1" eventually sees the following messages in "Trash": + | from | to | subject | unread | + | john.doe@mail.com | [user:user]@[domain] | foo | false | + When IMAP client "1" copies the message with subject "foo" from "Trash" to "Folders/mbox" + And it succeeds + When IMAP client "1" marks the message with subject "foo" as deleted + Then it succeeds + When IMAP client "1" expunges + Then it succeeds + Then IMAP client "1" eventually sees the following messages in "Folders/mbox": + | from | to | subject | unread | + | john.doe@mail.com | [user:user]@[domain] | foo | false | diff --git a/tests/features/imap/message/delete_from_trash.feature b/tests/features/imap/message/delete_from_trash.feature index a8323e91..15446eed 100644 --- a/tests/features/imap/message/delete_from_trash.feature +++ b/tests/features/imap/message/delete_from_trash.feature @@ -7,7 +7,7 @@ Feature: IMAP remove messages from Trash | label | label | Then it succeeds - Scenario Outline: Message in Trash and some other label is permanently deleted + Scenario Outline: Message in Trash and some other label is not permanently deleted Given the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Trash": | from | to | subject | body | | john.doe@mail.com | [user:user]@[domain] | foo | hello | @@ -27,8 +27,8 @@ Feature: IMAP remove messages from Trash When IMAP client "1" expunges Then it succeeds And IMAP client "1" eventually sees 1 messages in "Trash" - And IMAP client "1" eventually sees 1 messages in "All Mail" - And IMAP client "1" eventually sees 0 messages in "Labels/label" + And IMAP client "1" eventually sees 2 messages in "All Mail" + And IMAP client "1" eventually sees 1 messages in "Labels/label" Scenario Outline: Message in Trash only is permanently deleted Given the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Trash": From 949666724d81e7619f4f79f523c5a0e31314c327 Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 27 Sep 2023 10:54:50 +0200 Subject: [PATCH 09/51] chore: Umshiang Bridge 3.5.1 changelog. --- Changelog.md | 9 +++++++++ Makefile | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 918165f2..9538c1f9 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,15 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Umshiang Bridge 3.5.1 + +### Fixed +* GODT-2956: Restore old deletion rules. +* GODT-2951: Negative WaitGroup Counter. +* GODT-2590: Fix send on closed channel. +* GODT-2949: Fix close of close channel in event service. + + ## Umshiang Bridge 3.5.0 ### Added diff --git a/Makefile b/Makefile index 6f010be6..24d3ba27 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.5.0+git +BRIDGE_APP_VERSION?=3.5.1+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From 0d03f84711a5399c640b71dfa1dde64ba372b94e Mon Sep 17 00:00:00 2001 From: Leander Beernaert Date: Wed, 27 Sep 2023 11:30:46 +0200 Subject: [PATCH 10/51] fix(GODT-2963): Use multi error to report file removal errors Do not abort removing files on first error. Collect errors and try to remove as many as possible. This would cause some state files to not be removed on windows. --- pkg/files/removal.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/files/removal.go b/pkg/files/removal.go index 8f0b8db3..594f3010 100644 --- a/pkg/files/removal.go +++ b/pkg/files/removal.go @@ -72,11 +72,12 @@ func remove(dir string, except ...string) error { sort.Sort(sort.Reverse(sort.StringSlice(toRemove))) + var multiErr error for _, target := range toRemove { if err := os.RemoveAll(target); err != nil { - return err + multiErr = multierror.Append(multiErr, err) } } - return nil + return multiErr } From b7ef6e1486a69b3ed7aeb1462d7e9ad4bdeb58db Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 27 Sep 2023 13:18:23 +0200 Subject: [PATCH 11/51] chore: Umshiang Bridge 3.5.1 changelog. --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 9538c1f9..5dc72bc3 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,7 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) ## Umshiang Bridge 3.5.1 ### Fixed +* GODT-2963: Use multi error to report file removal errors. * GODT-2956: Restore old deletion rules. * GODT-2951: Negative WaitGroup Counter. * GODT-2590: Fix send on closed channel. From 80c852a5b234e1f7a7a0d17383dd87f1fb719461 Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Tue, 3 Oct 2023 10:48:46 +0200 Subject: [PATCH 12/51] fix(GODT-2992): fix link in 'no account view' in main window after 2FA or TOTP are cancelled. (cherry picked from commit 1c344211d1ab436c80b4c0c185dc34af45d074e8) --- .../bridge-gui/qml/SetupWizard/LeftPane.qml | 10 ---------- .../bridge-gui/qml/SetupWizard/SetupWizard.qml | 11 +++++++++++ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/SetupWizard/LeftPane.qml b/internal/frontend/bridge-gui/bridge-gui/qml/SetupWizard/LeftPane.qml index 433c1ac1..e809aa98 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/SetupWizard/LeftPane.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/SetupWizard/LeftPane.qml @@ -75,16 +75,6 @@ Item { root.iconWidth = 265; } - Connections { - function onLogin2FARequested() { - showLogin2FA(); - } - function onLogin2PasswordRequested() { - showLoginMailboxPassword(); - } - - target: Backend - } ColumnLayout { anchors.left: parent.left anchors.right: parent.right diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/SetupWizard/SetupWizard.qml b/internal/frontend/bridge-gui/bridge-gui/qml/SetupWizard/SetupWizard.qml index 3248184a..ae384e0e 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/SetupWizard/SetupWizard.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/SetupWizard/SetupWizard.qml @@ -186,6 +186,17 @@ Item { target: clientConfigAppleMail } + + Connections { + function onLogin2FARequested() { + leftContent.showLogin2FA(); + } + function onLogin2PasswordRequested() { + leftContent.showLoginMailboxPassword(); + } + + target: Backend + } } Image { id: mailLogoWithWordmark From d3582fa981a8f13f8a8a360d72d661604ac5a477 Mon Sep 17 00:00:00 2001 From: Jakub Date: Tue, 3 Oct 2023 16:43:33 +0200 Subject: [PATCH 13/51] chore: Vasco da Gama Bridge 3.6.0 changelog. --- Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 06759abe..5e4ba62d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,7 +2,6 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) - ## Vasco da Gama Bridge 3.6.0 ### Added @@ -21,6 +20,7 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) * GODT-2664: Trigger QA installer. ### Fixed +* GODT-2992: Fix link in 'no account view' in main window after 2FA or TOTP are cancelled. * GODT-2989: Allow to send bug report when no account connected. * GODT-2988: Fix setup wizard KB links. * GODT-2968: Use proper base64 encoded string even for bad password test. From e7423a95190ee096a3e10f1372db8cf4770de498 Mon Sep 17 00:00:00 2001 From: Leander Beernaert Date: Fri, 6 Oct 2023 10:09:10 +0100 Subject: [PATCH 14/51] fix(GODT-3001): Only create system labels during system label sync --- internal/services/imapservice/sync_update_applier.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/services/imapservice/sync_update_applier.go b/internal/services/imapservice/sync_update_applier.go index 58230ae5..4ba043b1 100644 --- a/internal/services/imapservice/sync_update_applier.go +++ b/internal/services/imapservice/sync_update_applier.go @@ -119,6 +119,10 @@ func (s *SyncUpdateApplier) SyncSystemLabelsOnly(ctx context.Context, labels map continue } + if label.Type != proton.LabelTypeSystem { + continue + } + for _, c := range connectors { update := newSystemMailboxCreatedUpdate(imap.MailboxID(label.ID), label.Name) updates = append(updates, update) From 951c7c27fba64613fca2d8e323033c11da47ba8f Mon Sep 17 00:00:00 2001 From: Leander Beernaert Date: Fri, 6 Oct 2023 15:00:36 +0100 Subject: [PATCH 15/51] fix(GODT-3003): Ensure IMAP State is reset after vault corruption After we detect that the user has suffered the GODT-3003 bug due the vault corruption not ensuring that a previous sync state would be erased, we patch the gluon db directly and then reset the sync state. After the account is added, the sync is automatically triggered and the account state fixes itself. --- Makefile | 1 + go.mod | 2 +- go.sum | 4 +- internal/bridge/bridge_test.go | 2 +- internal/bridge/sync_test.go | 62 ++++++ internal/services/imapservice/connector.go | 71 +++++- .../services/imapservice/connector_test.go | 205 ++++++++++++++++++ internal/services/imapservice/mocks/mocks.go | 138 ++++++++++++ internal/services/imapservice/service.go | 6 +- .../imapservice/service_address_events.go | 1 + .../imapservice/sync_state_provider.go | 4 +- .../imapservice/sync_state_provider_test.go | 4 +- internal/services/imapsmtpserver/service.go | 5 + 13 files changed, 493 insertions(+), 12 deletions(-) create mode 100644 internal/services/imapservice/connector_test.go create mode 100644 internal/services/imapservice/mocks/mocks.go diff --git a/Makefile b/Makefile index 24d3ba27..ec68628a 100644 --- a/Makefile +++ b/Makefile @@ -304,6 +304,7 @@ ApplyStageInput,BuildStageInput,BuildStageOutput,DownloadStageInput,DownloadStag StateProvider,Regulator,UpdateApplier,MessageBuilder,APIClient,Reporter,DownloadRateModifier \ > tmp mv tmp internal/services/syncservice/mocks_test.go + mockgen --package mocks github.com/ProtonMail/gluon/connector IMAPStateWrite > internal/services/imapservice/mocks/mocks.go lint: gofiles lint-golang lint-license lint-dependencies lint-changelog lint-bug-report diff --git a/go.mod b/go.mod index ad3f2697..af219a1a 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( github.com/0xAX/notificator v0.0.0-20220220101646-ee9b8921e557 github.com/Masterminds/semver/v3 v3.2.0 - github.com/ProtonMail/gluon v0.17.1-0.20230829112217-5d5c25c504b5 + github.com/ProtonMail/gluon v0.17.1-0.20231009084701-3af0474b0b3c github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a github.com/ProtonMail/go-proton-api v0.4.1-0.20230831064234-0e3a549b3f36 github.com/ProtonMail/gopenpgp/v2 v2.7.1-proton diff --git a/go.sum b/go.sum index 5177f714..7a1236b5 100644 --- a/go.sum +++ b/go.sum @@ -23,8 +23,8 @@ github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf h1:yc9daCCYUefEs github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf/go.mod h1:o0ESU9p83twszAU8LBeJKFAAMX14tISa0yk4Oo5TOqo= github.com/ProtonMail/docker-credential-helpers v1.1.0 h1:+kvUIpwWcbtP3WFv5sSvkFn/XLzSqPOB5AAthuk9xPk= github.com/ProtonMail/docker-credential-helpers v1.1.0/go.mod h1:mK0aBveCxhnQ756AmaTfXMZDeULvheYVhF/MWMErN5g= -github.com/ProtonMail/gluon v0.17.1-0.20230829112217-5d5c25c504b5 h1:C/8P5NHAKi2yCKez+OZ5rSR8SsL7k8si4pK4SE2QtV8= -github.com/ProtonMail/gluon v0.17.1-0.20230829112217-5d5c25c504b5/go.mod h1:Og5/Dz1MiGpCJn51XujZwxiLG7WzvvjE5PRpZBQmAHo= +github.com/ProtonMail/gluon v0.17.1-0.20231009084701-3af0474b0b3c h1:gUDu4pOswgbou0QczfreNiXQFrmvVlpSh8Q+vft/JvI= +github.com/ProtonMail/gluon v0.17.1-0.20231009084701-3af0474b0b3c/go.mod h1:Og5/Dz1MiGpCJn51XujZwxiLG7WzvvjE5PRpZBQmAHo= github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a h1:D+aZah+k14Gn6kmL7eKxoo/4Dr/lK3ChBcwce2+SQP4= github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4= github.com/ProtonMail/go-crypto v0.0.0-20230321155629-9a39f2531310/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE= diff --git a/internal/bridge/bridge_test.go b/internal/bridge/bridge_test.go index acd0fd0c..6ce8b1bd 100644 --- a/internal/bridge/bridge_test.go +++ b/internal/bridge/bridge_test.go @@ -585,7 +585,7 @@ func TestBridge_MissingGluonStore(t *testing.T) { require.NoError(t, os.RemoveAll(gluonDir)) // Bridge starts but can't find the gluon store dir; there should be no error. - withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { + withBridgeWaitForServers(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { // ... }) }) diff --git a/internal/bridge/sync_test.go b/internal/bridge/sync_test.go index 1d613bf3..07c0988a 100644 --- a/internal/bridge/sync_test.go +++ b/internal/bridge/sync_test.go @@ -37,6 +37,7 @@ import ( "github.com/ProtonMail/proton-bridge/v3/internal/bridge" "github.com/ProtonMail/proton-bridge/v3/internal/constants" "github.com/ProtonMail/proton-bridge/v3/internal/events" + "github.com/ProtonMail/proton-bridge/v3/internal/services/imapservice" "github.com/bradenaw/juniper/iterator" "github.com/bradenaw/juniper/stream" "github.com/bradenaw/juniper/xslices" @@ -579,6 +580,67 @@ func TestBridge_MessageCreateDuringSync(t *testing.T) { }, server.WithTLS(false)) } +func TestBridge_CorruptedVaultClearsPreviousIMAPSyncState(t *testing.T) { + withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) { + userID, addrID, err := s.CreateUser("imap", password) + require.NoError(t, err) + + labelID, err := s.CreateLabel(userID, "folder", "", proton.LabelTypeFolder) + require.NoError(t, err) + + withClient(ctx, t, s, "imap", password, func(ctx context.Context, c *proton.Client) { + createNumMessages(ctx, t, c, addrID, labelID, 100) + }) + + withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { + syncCh, done := chToType[events.Event, events.SyncFinished](bridge.GetEvents(events.SyncFinished{})) + defer done() + + var err error + + userID, err = bridge.LoginFull(context.Background(), "imap", password, nil, nil) + require.NoError(t, err) + + // Wait for sync to finish + require.Equal(t, userID, (<-syncCh).UserID) + }) + + settingsPath, err := locator.ProvideSettingsPath() + require.NoError(t, err) + + syncConfigPath, err := locator.ProvideIMAPSyncConfigPath() + require.NoError(t, err) + + syncStatePath := imapservice.GetSyncConfigPath(syncConfigPath, userID) + // Check sync state is complete + { + state, err := imapservice.NewSyncState(syncStatePath) + require.NoError(t, err) + syncStatus, err := state.GetSyncStatus(context.Background()) + require.NoError(t, err) + require.True(t, syncStatus.IsComplete()) + } + + // corrupt the vault + require.NoError(t, os.WriteFile(filepath.Join(settingsPath, "vault.enc"), []byte("Trash!"), 0o600)) + + // Bridge starts but can't find the gluon database dir; there should be no error. + withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { + _, err := bridge.LoginFull(context.Background(), "imap", password, nil, nil) + require.NoError(t, err) + }) + + // Check sync state is reset. + { + state, err := imapservice.NewSyncState(syncStatePath) + require.NoError(t, err) + syncStatus, err := state.GetSyncStatus(context.Background()) + require.NoError(t, err) + require.False(t, syncStatus.IsComplete()) + } + }) +} + func withClient(ctx context.Context, t *testing.T, s *server.Server, username string, password []byte, fn func(context.Context, *proton.Client)) { //nolint:unparam m := proton.New( proton.WithHostURL(s.GetHostURL()), diff --git a/internal/services/imapservice/connector.go b/internal/services/imapservice/connector.go index e026752f..c21fe5ca 100644 --- a/internal/services/imapservice/connector.go +++ b/internal/services/imapservice/connector.go @@ -63,6 +63,7 @@ type Connector struct { log *logrus.Entry sharedCache *SharedCache + syncState *SyncState } func NewConnector( @@ -75,6 +76,7 @@ func NewConnector( panicHandler async.PanicHandler, telemetry Telemetry, showAllMail bool, + syncState *SyncState, ) *Connector { userID := identityState.UserID() @@ -106,6 +108,7 @@ func NewConnector( }), sharedCache: NewSharedCached(), + syncState: syncState, } } @@ -114,9 +117,35 @@ func (s *Connector) StateClose() { s.updateCh.CloseAndDiscardQueued() } -func (s *Connector) Init(_ context.Context, cache connector.IMAPState) error { +func (s *Connector) Init(ctx context.Context, cache connector.IMAPState) error { s.sharedCache.Set(cache) - return nil + + return cache.Write(ctx, func(ctx context.Context, write connector.IMAPStateWrite) error { + rd := s.labels.Read() + defer rd.Close() + + mboxes, err := write.GetMailboxesWithoutAttrib(ctx) + if err != nil { + return err + } + + // Attempt to fix bug when a vault got corrupted, but the sync state did not get reset leading to + // all labels being written to the root level. If we detect this happened, reset the sync state. + { + applied, err := fixGODT3003Labels(ctx, s.log, mboxes, rd, write) + if err != nil { + return err + } + + if applied { + s.log.Debug("Patched folders/labels after GODT-3003 incident, resetting sync state.") + if err := s.syncState.ClearSyncStatus(ctx); err != nil { + return err + } + } + } + return nil + }) } func (s *Connector) Authorize(ctx context.Context, username string, password []byte) bool { @@ -745,3 +774,41 @@ func (s *Connector) createDraft(ctx context.Context, literal []byte, addrKR *cry func (s *Connector) publishUpdate(_ context.Context, update imap.Update) { s.updateCh.Enqueue(update) } + +func fixGODT3003Labels( + ctx context.Context, + log *logrus.Entry, + mboxes []imap.MailboxNoAttrib, + rd labelsRead, + write connector.IMAPStateWrite, +) (bool, error) { + var applied bool + for _, mbox := range mboxes { + lbl, ok := rd.GetLabel(string(mbox.ID)) + if !ok { + continue + } + + if lbl.Type == proton.LabelTypeFolder { + if mbox.Name[0] != folderPrefix { + log.WithField("labelID", mbox.ID.ShortID()).Debug("Found folder without prefix, patching") + if err := write.PatchMailboxHierarchyWithoutTransforms(ctx, mbox.ID, xslices.Insert(mbox.Name, 0, folderPrefix)); err != nil { + return false, fmt.Errorf("failed to update mailbox name: %w", err) + } + + applied = true + } + } else if lbl.Type == proton.LabelTypeLabel { + if mbox.Name[0] != labelPrefix { + log.WithField("labelID", mbox.ID.ShortID()).Debug("Found label without prefix, patching") + if err := write.PatchMailboxHierarchyWithoutTransforms(ctx, mbox.ID, xslices.Insert(mbox.Name, 0, labelPrefix)); err != nil { + return false, fmt.Errorf("failed to update mailbox name: %w", err) + } + + applied = true + } + } + } + + return applied, nil +} diff --git a/internal/services/imapservice/connector_test.go b/internal/services/imapservice/connector_test.go new file mode 100644 index 00000000..f79b885d --- /dev/null +++ b/internal/services/imapservice/connector_test.go @@ -0,0 +1,205 @@ +// Copyright (c) 2023 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 imapservice + +import ( + "context" + "testing" + + "github.com/ProtonMail/gluon/imap" + "github.com/ProtonMail/go-proton-api" + "github.com/ProtonMail/proton-bridge/v3/internal/services/imapservice/mocks" + "github.com/golang/mock/gomock" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" +) + +func TestFixGODT3003Labels(t *testing.T) { + mockCtrl := gomock.NewController(t) + + log := logrus.WithField("test", "test") + + sharedLabels := newRWLabels() + wr := sharedLabels.Write() + wr.SetLabel("foo", proton.Label{ + ID: "foo", + ParentID: "bar", + Name: "Foo", + Path: []string{"bar", "Foo"}, + Color: "", + Type: proton.LabelTypeFolder, + }) + + wr.SetLabel("0", proton.Label{ + ID: "0", + ParentID: "", + Name: "Inbox", + Path: []string{"Inbox"}, + Color: "", + Type: proton.LabelTypeSystem, + }) + + wr.SetLabel("bar", proton.Label{ + ID: "bar", + ParentID: "", + Name: "boo", + Path: []string{"bar"}, + Color: "", + Type: proton.LabelTypeFolder, + }) + + wr.SetLabel("my_label", proton.Label{ + ID: "my_label", + ParentID: "", + Name: "MyLabel", + Path: []string{"MyLabel"}, + Color: "", + Type: proton.LabelTypeLabel, + }) + + wr.SetLabel("my_label2", proton.Label{ + ID: "my_label2", + ParentID: "", + Name: "MyLabel2", + Path: []string{labelPrefix, "MyLabel2"}, + Color: "", + Type: proton.LabelTypeLabel, + }) + wr.Close() + + mboxs := []imap.MailboxNoAttrib{ + { + ID: "0", + Name: []string{"Inbox"}, + }, + { + ID: "bar", + Name: []string{"bar"}, + }, + { + ID: "foo", + Name: []string{"bar", "Foo"}, + }, + { + ID: "my_label", + Name: []string{"MyLabel"}, + }, + { + ID: "my_label2", + Name: []string{labelPrefix, "MyLabel2"}, + }, + } + + rd := sharedLabels.Read() + defer rd.Close() + + imapState := mocks.NewMockIMAPStateWrite(mockCtrl) + + imapState.EXPECT().PatchMailboxHierarchyWithoutTransforms(gomock.Any(), gomock.Eq(imap.MailboxID("bar")), gomock.Eq([]string{folderPrefix, "bar"})) + imapState.EXPECT().PatchMailboxHierarchyWithoutTransforms(gomock.Any(), gomock.Eq(imap.MailboxID("foo")), gomock.Eq([]string{folderPrefix, "bar", "Foo"})) + imapState.EXPECT().PatchMailboxHierarchyWithoutTransforms(gomock.Any(), gomock.Eq(imap.MailboxID("my_label")), gomock.Eq([]string{labelPrefix, "MyLabel"})) + + applied, err := fixGODT3003Labels(context.Background(), log, mboxs, rd, imapState) + require.NoError(t, err) + require.True(t, applied) +} + +func TestFixGODT3003Labels_Noop(t *testing.T) { + mockCtrl := gomock.NewController(t) + + log := logrus.WithField("test", "test") + + sharedLabels := newRWLabels() + wr := sharedLabels.Write() + wr.SetLabel("foo", proton.Label{ + ID: "foo", + ParentID: "bar", + Name: "Foo", + Path: []string{folderPrefix, "bar", "Foo"}, + Color: "", + Type: proton.LabelTypeFolder, + }) + + wr.SetLabel("0", proton.Label{ + ID: "0", + ParentID: "", + Name: "Inbox", + Path: []string{"Inbox"}, + Color: "", + Type: proton.LabelTypeSystem, + }) + + wr.SetLabel("bar", proton.Label{ + ID: "bar", + ParentID: "", + Name: "bar", + Path: []string{folderPrefix, "bar"}, + Color: "", + Type: proton.LabelTypeFolder, + }) + + wr.SetLabel("my_label", proton.Label{ + ID: "my_label", + ParentID: "", + Name: "MyLabel", + Path: []string{labelPrefix, "MyLabel"}, + Color: "", + Type: proton.LabelTypeLabel, + }) + + wr.SetLabel("my_label2", proton.Label{ + ID: "my_label2", + ParentID: "", + Name: "MyLabel2", + Path: []string{labelPrefix, "MyLabel2"}, + Color: "", + Type: proton.LabelTypeLabel, + }) + wr.Close() + + mboxs := []imap.MailboxNoAttrib{ + { + ID: "0", + Name: []string{"Inbox"}, + }, + { + ID: "bar", + Name: []string{folderPrefix, "bar"}, + }, + { + ID: "foo", + Name: []string{folderPrefix, "bar", "Foo"}, + }, + { + ID: "my_label", + Name: []string{labelPrefix, "MyLabel"}, + }, + { + ID: "my_label2", + Name: []string{labelPrefix, "MyLabel2"}, + }, + } + + rd := sharedLabels.Read() + defer rd.Close() + + imapState := mocks.NewMockIMAPStateWrite(mockCtrl) + applied, err := fixGODT3003Labels(context.Background(), log, mboxs, rd, imapState) + require.NoError(t, err) + require.False(t, applied) +} diff --git a/internal/services/imapservice/mocks/mocks.go b/internal/services/imapservice/mocks/mocks.go new file mode 100644 index 00000000..17e5b7cd --- /dev/null +++ b/internal/services/imapservice/mocks/mocks.go @@ -0,0 +1,138 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/ProtonMail/gluon/connector (interfaces: IMAPStateWrite) + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + imap "github.com/ProtonMail/gluon/imap" + gomock "github.com/golang/mock/gomock" +) + +// MockIMAPStateWrite is a mock of IMAPStateWrite interface. +type MockIMAPStateWrite struct { + ctrl *gomock.Controller + recorder *MockIMAPStateWriteMockRecorder +} + +// MockIMAPStateWriteMockRecorder is the mock recorder for MockIMAPStateWrite. +type MockIMAPStateWriteMockRecorder struct { + mock *MockIMAPStateWrite +} + +// NewMockIMAPStateWrite creates a new mock instance. +func NewMockIMAPStateWrite(ctrl *gomock.Controller) *MockIMAPStateWrite { + mock := &MockIMAPStateWrite{ctrl: ctrl} + mock.recorder = &MockIMAPStateWriteMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockIMAPStateWrite) EXPECT() *MockIMAPStateWriteMockRecorder { + return m.recorder +} + +// CreateMailbox mocks base method. +func (m *MockIMAPStateWrite) CreateMailbox(arg0 context.Context, arg1 imap.Mailbox) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateMailbox", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateMailbox indicates an expected call of CreateMailbox. +func (mr *MockIMAPStateWriteMockRecorder) CreateMailbox(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateMailbox", reflect.TypeOf((*MockIMAPStateWrite)(nil).CreateMailbox), arg0, arg1) +} + +// GetMailboxCount mocks base method. +func (m *MockIMAPStateWrite) GetMailboxCount(arg0 context.Context) (int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetMailboxCount", arg0) + ret0, _ := ret[0].(int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetMailboxCount indicates an expected call of GetMailboxCount. +func (mr *MockIMAPStateWriteMockRecorder) GetMailboxCount(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMailboxCount", reflect.TypeOf((*MockIMAPStateWrite)(nil).GetMailboxCount), arg0) +} + +// GetMailboxesWithoutAttrib mocks base method. +func (m *MockIMAPStateWrite) GetMailboxesWithoutAttrib(arg0 context.Context) ([]imap.MailboxNoAttrib, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetMailboxesWithoutAttrib", arg0) + ret0, _ := ret[0].([]imap.MailboxNoAttrib) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetMailboxesWithoutAttrib indicates an expected call of GetMailboxesWithoutAttrib. +func (mr *MockIMAPStateWriteMockRecorder) GetMailboxesWithoutAttrib(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMailboxesWithoutAttrib", reflect.TypeOf((*MockIMAPStateWrite)(nil).GetMailboxesWithoutAttrib), arg0) +} + +// GetSettings mocks base method. +func (m *MockIMAPStateWrite) GetSettings(arg0 context.Context) (string, bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSettings", arg0) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetSettings indicates an expected call of GetSettings. +func (mr *MockIMAPStateWriteMockRecorder) GetSettings(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSettings", reflect.TypeOf((*MockIMAPStateWrite)(nil).GetSettings), arg0) +} + +// PatchMailboxHierarchyWithoutTransforms mocks base method. +func (m *MockIMAPStateWrite) PatchMailboxHierarchyWithoutTransforms(arg0 context.Context, arg1 imap.MailboxID, arg2 []string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PatchMailboxHierarchyWithoutTransforms", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// PatchMailboxHierarchyWithoutTransforms indicates an expected call of PatchMailboxHierarchyWithoutTransforms. +func (mr *MockIMAPStateWriteMockRecorder) PatchMailboxHierarchyWithoutTransforms(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PatchMailboxHierarchyWithoutTransforms", reflect.TypeOf((*MockIMAPStateWrite)(nil).PatchMailboxHierarchyWithoutTransforms), arg0, arg1, arg2) +} + +// StoreSettings mocks base method. +func (m *MockIMAPStateWrite) StoreSettings(arg0 context.Context, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StoreSettings", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// StoreSettings indicates an expected call of StoreSettings. +func (mr *MockIMAPStateWriteMockRecorder) StoreSettings(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StoreSettings", reflect.TypeOf((*MockIMAPStateWrite)(nil).StoreSettings), arg0, arg1) +} + +// UpdateMessageFlags mocks base method. +func (m *MockIMAPStateWrite) UpdateMessageFlags(arg0 context.Context, arg1 imap.MessageID, arg2 imap.FlagSet) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateMessageFlags", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateMessageFlags indicates an expected call of UpdateMessageFlags. +func (mr *MockIMAPStateWriteMockRecorder) UpdateMessageFlags(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateMessageFlags", reflect.TypeOf((*MockIMAPStateWrite)(nil).UpdateMessageFlags), arg0, arg1, arg2) +} diff --git a/internal/services/imapservice/service.go b/internal/services/imapservice/service.go index 701a62c6..79e4b9f0 100644 --- a/internal/services/imapservice/service.go +++ b/internal/services/imapservice/service.go @@ -158,7 +158,7 @@ func NewService( syncUpdateApplier: syncUpdateApplier, syncMessageBuilder: syncMessageBuilder, syncReporter: syncReporter, - syncConfigPath: getSyncConfigPath(syncConfigDir, identityState.User.ID), + syncConfigPath: GetSyncConfigPath(syncConfigDir, identityState.User.ID), } } @@ -498,6 +498,7 @@ func (s *Service) buildConnectors() (map[string]*Connector, error) { s.panicHandler, s.telemetry, s.showAllMail, + s.syncStateProvider, ) return connectors, nil @@ -514,6 +515,7 @@ func (s *Service) buildConnectors() (map[string]*Connector, error) { s.panicHandler, s.telemetry, s.showAllMail, + s.syncStateProvider, ) } @@ -644,6 +646,6 @@ type setAddressModeReq struct { type getSyncFailedMessagesReq struct{} -func getSyncConfigPath(path string, userID string) string { +func GetSyncConfigPath(path string, userID string) string { return filepath.Join(path, fmt.Sprintf("sync-%v", userID)) } diff --git a/internal/services/imapservice/service_address_events.go b/internal/services/imapservice/service_address_events.go index 2c5aed9c..78abe4a3 100644 --- a/internal/services/imapservice/service_address_events.go +++ b/internal/services/imapservice/service_address_events.go @@ -128,6 +128,7 @@ func addNewAddressSplitMode(ctx context.Context, s *Service, addrID string) erro s.panicHandler, s.telemetry, s.showAllMail, + s.syncStateProvider, ) if err := s.serverManager.AddIMAPUser(ctx, connector, connector.addrID, s.gluonIDProvider, s.syncStateProvider); err != nil { diff --git a/internal/services/imapservice/sync_state_provider.go b/internal/services/imapservice/sync_state_provider.go index 190d67a5..9b3723d2 100644 --- a/internal/services/imapservice/sync_state_provider.go +++ b/internal/services/imapservice/sync_state_provider.go @@ -220,7 +220,7 @@ func (s *SyncState) loadUnsafe() error { } func DeleteSyncState(configDir, userID string) error { - path := getSyncConfigPath(configDir, userID) + path := GetSyncConfigPath(configDir, userID) if err := os.Remove(path); err != nil && !errors.Is(err, os.ErrNotExist) { return err @@ -234,7 +234,7 @@ func MigrateVaultSettings( hasLabels, hasMessages bool, failedMessageIDs []string, ) (bool, error) { - filePath := getSyncConfigPath(configDir, userID) + filePath := GetSyncConfigPath(configDir, userID) _, err := os.ReadFile(filePath) //nolint:gosec if err == nil { diff --git a/internal/services/imapservice/sync_state_provider_test.go b/internal/services/imapservice/sync_state_provider_test.go index 0852c53f..e4dd93b7 100644 --- a/internal/services/imapservice/sync_state_provider_test.go +++ b/internal/services/imapservice/sync_state_provider_test.go @@ -29,7 +29,7 @@ import ( func TestMigrateSyncSettings_AlreadyExists(t *testing.T) { tmpDir := t.TempDir() - testFile := getSyncConfigPath(tmpDir, "test") + testFile := GetSyncConfigPath(tmpDir, "test") expected, err := generateTestState(testFile) require.NoError(t, err) @@ -53,7 +53,7 @@ func TestMigrateSyncSettings_DoesNotExist(t *testing.T) { require.NoError(t, err) require.True(t, migrated) - state, err := NewSyncState(getSyncConfigPath(tmpDir, "test")) + state, err := NewSyncState(GetSyncConfigPath(tmpDir, "test")) require.NoError(t, err) status, err := state.GetSyncStatus(context.Background()) require.NoError(t, err) diff --git a/internal/services/imapsmtpserver/service.go b/internal/services/imapsmtpserver/service.go index de186eb9..f2e22176 100644 --- a/internal/services/imapsmtpserver/service.go +++ b/internal/services/imapsmtpserver/service.go @@ -390,6 +390,11 @@ func (sm *Service) handleAddIMAPUserImpl(ctx context.Context, } else { log.Info("Creating new IMAP user") + // GODT-3003: Ensure previous IMAP sync state is cleared if we run into code path after vault corruption. + if err := syncStateProvider.ClearSyncStatus(ctx); err != nil { + return fmt.Errorf("failed to reset sync status: %w", err) + } + gluonID, err := sm.imapServer.AddUser(ctx, connector, idProvider.GluonKey()) if err != nil { return fmt.Errorf("failed to add IMAP user: %w", err) From 4b95ef4d8219f1ce15d48d913b353bef9f55e695 Mon Sep 17 00:00:00 2001 From: Jakub Date: Mon, 9 Oct 2023 13:25:44 +0200 Subject: [PATCH 16/51] chore: Umshiang Bridge 3.5.2 changelog. --- Changelog.md | 7 +++++++ Makefile | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 5dc72bc3..d896445a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,13 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Umshiang Bridge 3.5.2 + +### Fixed +* GODT-3003: Ensure IMAP State is reset after vault corruption. +* GODT-3001: Only create system labels during system label sync. + + ## Umshiang Bridge 3.5.1 ### Fixed diff --git a/Makefile b/Makefile index ec68628a..b99c44b9 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.5.1+git +BRIDGE_APP_VERSION?=3.5.2+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From ba65ffdbc7e85a49262bfff15e96d06cc9dded10 Mon Sep 17 00:00:00 2001 From: Jakub Date: Mon, 9 Oct 2023 13:25:44 +0200 Subject: [PATCH 17/51] chore: Umshiang Bridge 3.5.2 changelog. --- Changelog.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Changelog.md b/Changelog.md index 5e4ba62d..e033fbb2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -33,6 +33,13 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Umshiang Bridge 3.5.2 + +### Fixed +* GODT-3003: Ensure IMAP State is reset after vault corruption. +* GODT-3001: Only create system labels during system label sync. + + ## Umshiang Bridge 3.5.1 ### Fixed From cf9651bb9498d025b1e1697b97d448ed74e267a7 Mon Sep 17 00:00:00 2001 From: Leander Beernaert Date: Fri, 6 Oct 2023 10:09:10 +0100 Subject: [PATCH 18/51] fix(GODT-3001): Only create system labels during system label sync --- internal/services/imapservice/sync_update_applier.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/services/imapservice/sync_update_applier.go b/internal/services/imapservice/sync_update_applier.go index 58230ae5..4ba043b1 100644 --- a/internal/services/imapservice/sync_update_applier.go +++ b/internal/services/imapservice/sync_update_applier.go @@ -119,6 +119,10 @@ func (s *SyncUpdateApplier) SyncSystemLabelsOnly(ctx context.Context, labels map continue } + if label.Type != proton.LabelTypeSystem { + continue + } + for _, c := range connectors { update := newSystemMailboxCreatedUpdate(imap.MailboxID(label.ID), label.Name) updates = append(updates, update) From bf244e5c863671bad0c131c515cf3b1c05622f68 Mon Sep 17 00:00:00 2001 From: Leander Beernaert Date: Fri, 6 Oct 2023 15:00:36 +0100 Subject: [PATCH 19/51] fix(GODT-3003): Ensure IMAP State is reset after vault corruption After we detect that the user has suffered the GODT-3003 bug due the vault corruption not ensuring that a previous sync state would be erased, we patch the gluon db directly and then reset the sync state. After the account is added, the sync is automatically triggered and the account state fixes itself. --- Makefile | 1 + go.mod | 2 +- go.sum | 4 +- internal/bridge/bridge_test.go | 2 +- internal/bridge/sync_test.go | 62 ++++++ internal/services/imapservice/connector.go | 71 +++++- .../services/imapservice/connector_test.go | 205 ++++++++++++++++++ internal/services/imapservice/mocks/mocks.go | 138 ++++++++++++ internal/services/imapservice/service.go | 6 +- .../imapservice/service_address_events.go | 1 + .../imapservice/sync_state_provider.go | 4 +- .../imapservice/sync_state_provider_test.go | 4 +- internal/services/imapsmtpserver/service.go | 5 + 13 files changed, 493 insertions(+), 12 deletions(-) create mode 100644 internal/services/imapservice/connector_test.go create mode 100644 internal/services/imapservice/mocks/mocks.go diff --git a/Makefile b/Makefile index 462ce114..0ae1998a 100644 --- a/Makefile +++ b/Makefile @@ -304,6 +304,7 @@ ApplyStageInput,BuildStageInput,BuildStageOutput,DownloadStageInput,DownloadStag StateProvider,Regulator,UpdateApplier,MessageBuilder,APIClient,Reporter,DownloadRateModifier \ > tmp mv tmp internal/services/syncservice/mocks_test.go + mockgen --package mocks github.com/ProtonMail/gluon/connector IMAPStateWrite > internal/services/imapservice/mocks/mocks.go lint: gofiles lint-golang lint-license lint-dependencies lint-changelog lint-bug-report diff --git a/go.mod b/go.mod index a1a498b0..fc5a08aa 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( github.com/0xAX/notificator v0.0.0-20220220101646-ee9b8921e557 github.com/Masterminds/semver/v3 v3.2.0 - github.com/ProtonMail/gluon v0.17.1-0.20230911134257-5eb2eeebbef5 + github.com/ProtonMail/gluon v0.17.1-0.20231009084701-3af0474b0b3c github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a github.com/ProtonMail/go-proton-api v0.4.1-0.20230925123025-331ad8e6d5ee github.com/ProtonMail/gopenpgp/v2 v2.7.1-proton diff --git a/go.sum b/go.sum index 4c9c029b..cb4e1e30 100644 --- a/go.sum +++ b/go.sum @@ -23,8 +23,8 @@ github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf h1:yc9daCCYUefEs github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf/go.mod h1:o0ESU9p83twszAU8LBeJKFAAMX14tISa0yk4Oo5TOqo= github.com/ProtonMail/docker-credential-helpers v1.1.0 h1:+kvUIpwWcbtP3WFv5sSvkFn/XLzSqPOB5AAthuk9xPk= github.com/ProtonMail/docker-credential-helpers v1.1.0/go.mod h1:mK0aBveCxhnQ756AmaTfXMZDeULvheYVhF/MWMErN5g= -github.com/ProtonMail/gluon v0.17.1-0.20230911134257-5eb2eeebbef5 h1:O4BusNL870VgVVDSUX2Oaz8A/fNtJhakUKwx0YBIdn8= -github.com/ProtonMail/gluon v0.17.1-0.20230911134257-5eb2eeebbef5/go.mod h1:Og5/Dz1MiGpCJn51XujZwxiLG7WzvvjE5PRpZBQmAHo= +github.com/ProtonMail/gluon v0.17.1-0.20231009084701-3af0474b0b3c h1:gUDu4pOswgbou0QczfreNiXQFrmvVlpSh8Q+vft/JvI= +github.com/ProtonMail/gluon v0.17.1-0.20231009084701-3af0474b0b3c/go.mod h1:Og5/Dz1MiGpCJn51XujZwxiLG7WzvvjE5PRpZBQmAHo= github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a h1:D+aZah+k14Gn6kmL7eKxoo/4Dr/lK3ChBcwce2+SQP4= github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4= github.com/ProtonMail/go-crypto v0.0.0-20230321155629-9a39f2531310/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE= diff --git a/internal/bridge/bridge_test.go b/internal/bridge/bridge_test.go index acd0fd0c..6ce8b1bd 100644 --- a/internal/bridge/bridge_test.go +++ b/internal/bridge/bridge_test.go @@ -585,7 +585,7 @@ func TestBridge_MissingGluonStore(t *testing.T) { require.NoError(t, os.RemoveAll(gluonDir)) // Bridge starts but can't find the gluon store dir; there should be no error. - withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { + withBridgeWaitForServers(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { // ... }) }) diff --git a/internal/bridge/sync_test.go b/internal/bridge/sync_test.go index 1d613bf3..07c0988a 100644 --- a/internal/bridge/sync_test.go +++ b/internal/bridge/sync_test.go @@ -37,6 +37,7 @@ import ( "github.com/ProtonMail/proton-bridge/v3/internal/bridge" "github.com/ProtonMail/proton-bridge/v3/internal/constants" "github.com/ProtonMail/proton-bridge/v3/internal/events" + "github.com/ProtonMail/proton-bridge/v3/internal/services/imapservice" "github.com/bradenaw/juniper/iterator" "github.com/bradenaw/juniper/stream" "github.com/bradenaw/juniper/xslices" @@ -579,6 +580,67 @@ func TestBridge_MessageCreateDuringSync(t *testing.T) { }, server.WithTLS(false)) } +func TestBridge_CorruptedVaultClearsPreviousIMAPSyncState(t *testing.T) { + withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) { + userID, addrID, err := s.CreateUser("imap", password) + require.NoError(t, err) + + labelID, err := s.CreateLabel(userID, "folder", "", proton.LabelTypeFolder) + require.NoError(t, err) + + withClient(ctx, t, s, "imap", password, func(ctx context.Context, c *proton.Client) { + createNumMessages(ctx, t, c, addrID, labelID, 100) + }) + + withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { + syncCh, done := chToType[events.Event, events.SyncFinished](bridge.GetEvents(events.SyncFinished{})) + defer done() + + var err error + + userID, err = bridge.LoginFull(context.Background(), "imap", password, nil, nil) + require.NoError(t, err) + + // Wait for sync to finish + require.Equal(t, userID, (<-syncCh).UserID) + }) + + settingsPath, err := locator.ProvideSettingsPath() + require.NoError(t, err) + + syncConfigPath, err := locator.ProvideIMAPSyncConfigPath() + require.NoError(t, err) + + syncStatePath := imapservice.GetSyncConfigPath(syncConfigPath, userID) + // Check sync state is complete + { + state, err := imapservice.NewSyncState(syncStatePath) + require.NoError(t, err) + syncStatus, err := state.GetSyncStatus(context.Background()) + require.NoError(t, err) + require.True(t, syncStatus.IsComplete()) + } + + // corrupt the vault + require.NoError(t, os.WriteFile(filepath.Join(settingsPath, "vault.enc"), []byte("Trash!"), 0o600)) + + // Bridge starts but can't find the gluon database dir; there should be no error. + withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { + _, err := bridge.LoginFull(context.Background(), "imap", password, nil, nil) + require.NoError(t, err) + }) + + // Check sync state is reset. + { + state, err := imapservice.NewSyncState(syncStatePath) + require.NoError(t, err) + syncStatus, err := state.GetSyncStatus(context.Background()) + require.NoError(t, err) + require.False(t, syncStatus.IsComplete()) + } + }) +} + func withClient(ctx context.Context, t *testing.T, s *server.Server, username string, password []byte, fn func(context.Context, *proton.Client)) { //nolint:unparam m := proton.New( proton.WithHostURL(s.GetHostURL()), diff --git a/internal/services/imapservice/connector.go b/internal/services/imapservice/connector.go index 04ff2ab9..6e9dc031 100644 --- a/internal/services/imapservice/connector.go +++ b/internal/services/imapservice/connector.go @@ -63,6 +63,7 @@ type Connector struct { log *logrus.Entry sharedCache *SharedCache + syncState *SyncState } func NewConnector( @@ -75,6 +76,7 @@ func NewConnector( panicHandler async.PanicHandler, telemetry Telemetry, showAllMail bool, + syncState *SyncState, ) *Connector { userID := identityState.UserID() @@ -106,6 +108,7 @@ func NewConnector( }), sharedCache: NewSharedCached(), + syncState: syncState, } } @@ -114,9 +117,35 @@ func (s *Connector) StateClose() { s.updateCh.CloseAndDiscardQueued() } -func (s *Connector) Init(_ context.Context, cache connector.IMAPState) error { +func (s *Connector) Init(ctx context.Context, cache connector.IMAPState) error { s.sharedCache.Set(cache) - return nil + + return cache.Write(ctx, func(ctx context.Context, write connector.IMAPStateWrite) error { + rd := s.labels.Read() + defer rd.Close() + + mboxes, err := write.GetMailboxesWithoutAttrib(ctx) + if err != nil { + return err + } + + // Attempt to fix bug when a vault got corrupted, but the sync state did not get reset leading to + // all labels being written to the root level. If we detect this happened, reset the sync state. + { + applied, err := fixGODT3003Labels(ctx, s.log, mboxes, rd, write) + if err != nil { + return err + } + + if applied { + s.log.Debug("Patched folders/labels after GODT-3003 incident, resetting sync state.") + if err := s.syncState.ClearSyncStatus(ctx); err != nil { + return err + } + } + } + return nil + }) } func (s *Connector) Authorize(ctx context.Context, username string, password []byte) bool { @@ -745,3 +774,41 @@ func (s *Connector) createDraft(ctx context.Context, literal []byte, addrKR *cry func (s *Connector) publishUpdate(_ context.Context, update imap.Update) { s.updateCh.Enqueue(update) } + +func fixGODT3003Labels( + ctx context.Context, + log *logrus.Entry, + mboxes []imap.MailboxNoAttrib, + rd labelsRead, + write connector.IMAPStateWrite, +) (bool, error) { + var applied bool + for _, mbox := range mboxes { + lbl, ok := rd.GetLabel(string(mbox.ID)) + if !ok { + continue + } + + if lbl.Type == proton.LabelTypeFolder { + if mbox.Name[0] != folderPrefix { + log.WithField("labelID", mbox.ID.ShortID()).Debug("Found folder without prefix, patching") + if err := write.PatchMailboxHierarchyWithoutTransforms(ctx, mbox.ID, xslices.Insert(mbox.Name, 0, folderPrefix)); err != nil { + return false, fmt.Errorf("failed to update mailbox name: %w", err) + } + + applied = true + } + } else if lbl.Type == proton.LabelTypeLabel { + if mbox.Name[0] != labelPrefix { + log.WithField("labelID", mbox.ID.ShortID()).Debug("Found label without prefix, patching") + if err := write.PatchMailboxHierarchyWithoutTransforms(ctx, mbox.ID, xslices.Insert(mbox.Name, 0, labelPrefix)); err != nil { + return false, fmt.Errorf("failed to update mailbox name: %w", err) + } + + applied = true + } + } + } + + return applied, nil +} diff --git a/internal/services/imapservice/connector_test.go b/internal/services/imapservice/connector_test.go new file mode 100644 index 00000000..f79b885d --- /dev/null +++ b/internal/services/imapservice/connector_test.go @@ -0,0 +1,205 @@ +// Copyright (c) 2023 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 imapservice + +import ( + "context" + "testing" + + "github.com/ProtonMail/gluon/imap" + "github.com/ProtonMail/go-proton-api" + "github.com/ProtonMail/proton-bridge/v3/internal/services/imapservice/mocks" + "github.com/golang/mock/gomock" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" +) + +func TestFixGODT3003Labels(t *testing.T) { + mockCtrl := gomock.NewController(t) + + log := logrus.WithField("test", "test") + + sharedLabels := newRWLabels() + wr := sharedLabels.Write() + wr.SetLabel("foo", proton.Label{ + ID: "foo", + ParentID: "bar", + Name: "Foo", + Path: []string{"bar", "Foo"}, + Color: "", + Type: proton.LabelTypeFolder, + }) + + wr.SetLabel("0", proton.Label{ + ID: "0", + ParentID: "", + Name: "Inbox", + Path: []string{"Inbox"}, + Color: "", + Type: proton.LabelTypeSystem, + }) + + wr.SetLabel("bar", proton.Label{ + ID: "bar", + ParentID: "", + Name: "boo", + Path: []string{"bar"}, + Color: "", + Type: proton.LabelTypeFolder, + }) + + wr.SetLabel("my_label", proton.Label{ + ID: "my_label", + ParentID: "", + Name: "MyLabel", + Path: []string{"MyLabel"}, + Color: "", + Type: proton.LabelTypeLabel, + }) + + wr.SetLabel("my_label2", proton.Label{ + ID: "my_label2", + ParentID: "", + Name: "MyLabel2", + Path: []string{labelPrefix, "MyLabel2"}, + Color: "", + Type: proton.LabelTypeLabel, + }) + wr.Close() + + mboxs := []imap.MailboxNoAttrib{ + { + ID: "0", + Name: []string{"Inbox"}, + }, + { + ID: "bar", + Name: []string{"bar"}, + }, + { + ID: "foo", + Name: []string{"bar", "Foo"}, + }, + { + ID: "my_label", + Name: []string{"MyLabel"}, + }, + { + ID: "my_label2", + Name: []string{labelPrefix, "MyLabel2"}, + }, + } + + rd := sharedLabels.Read() + defer rd.Close() + + imapState := mocks.NewMockIMAPStateWrite(mockCtrl) + + imapState.EXPECT().PatchMailboxHierarchyWithoutTransforms(gomock.Any(), gomock.Eq(imap.MailboxID("bar")), gomock.Eq([]string{folderPrefix, "bar"})) + imapState.EXPECT().PatchMailboxHierarchyWithoutTransforms(gomock.Any(), gomock.Eq(imap.MailboxID("foo")), gomock.Eq([]string{folderPrefix, "bar", "Foo"})) + imapState.EXPECT().PatchMailboxHierarchyWithoutTransforms(gomock.Any(), gomock.Eq(imap.MailboxID("my_label")), gomock.Eq([]string{labelPrefix, "MyLabel"})) + + applied, err := fixGODT3003Labels(context.Background(), log, mboxs, rd, imapState) + require.NoError(t, err) + require.True(t, applied) +} + +func TestFixGODT3003Labels_Noop(t *testing.T) { + mockCtrl := gomock.NewController(t) + + log := logrus.WithField("test", "test") + + sharedLabels := newRWLabels() + wr := sharedLabels.Write() + wr.SetLabel("foo", proton.Label{ + ID: "foo", + ParentID: "bar", + Name: "Foo", + Path: []string{folderPrefix, "bar", "Foo"}, + Color: "", + Type: proton.LabelTypeFolder, + }) + + wr.SetLabel("0", proton.Label{ + ID: "0", + ParentID: "", + Name: "Inbox", + Path: []string{"Inbox"}, + Color: "", + Type: proton.LabelTypeSystem, + }) + + wr.SetLabel("bar", proton.Label{ + ID: "bar", + ParentID: "", + Name: "bar", + Path: []string{folderPrefix, "bar"}, + Color: "", + Type: proton.LabelTypeFolder, + }) + + wr.SetLabel("my_label", proton.Label{ + ID: "my_label", + ParentID: "", + Name: "MyLabel", + Path: []string{labelPrefix, "MyLabel"}, + Color: "", + Type: proton.LabelTypeLabel, + }) + + wr.SetLabel("my_label2", proton.Label{ + ID: "my_label2", + ParentID: "", + Name: "MyLabel2", + Path: []string{labelPrefix, "MyLabel2"}, + Color: "", + Type: proton.LabelTypeLabel, + }) + wr.Close() + + mboxs := []imap.MailboxNoAttrib{ + { + ID: "0", + Name: []string{"Inbox"}, + }, + { + ID: "bar", + Name: []string{folderPrefix, "bar"}, + }, + { + ID: "foo", + Name: []string{folderPrefix, "bar", "Foo"}, + }, + { + ID: "my_label", + Name: []string{labelPrefix, "MyLabel"}, + }, + { + ID: "my_label2", + Name: []string{labelPrefix, "MyLabel2"}, + }, + } + + rd := sharedLabels.Read() + defer rd.Close() + + imapState := mocks.NewMockIMAPStateWrite(mockCtrl) + applied, err := fixGODT3003Labels(context.Background(), log, mboxs, rd, imapState) + require.NoError(t, err) + require.False(t, applied) +} diff --git a/internal/services/imapservice/mocks/mocks.go b/internal/services/imapservice/mocks/mocks.go new file mode 100644 index 00000000..17e5b7cd --- /dev/null +++ b/internal/services/imapservice/mocks/mocks.go @@ -0,0 +1,138 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/ProtonMail/gluon/connector (interfaces: IMAPStateWrite) + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + imap "github.com/ProtonMail/gluon/imap" + gomock "github.com/golang/mock/gomock" +) + +// MockIMAPStateWrite is a mock of IMAPStateWrite interface. +type MockIMAPStateWrite struct { + ctrl *gomock.Controller + recorder *MockIMAPStateWriteMockRecorder +} + +// MockIMAPStateWriteMockRecorder is the mock recorder for MockIMAPStateWrite. +type MockIMAPStateWriteMockRecorder struct { + mock *MockIMAPStateWrite +} + +// NewMockIMAPStateWrite creates a new mock instance. +func NewMockIMAPStateWrite(ctrl *gomock.Controller) *MockIMAPStateWrite { + mock := &MockIMAPStateWrite{ctrl: ctrl} + mock.recorder = &MockIMAPStateWriteMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockIMAPStateWrite) EXPECT() *MockIMAPStateWriteMockRecorder { + return m.recorder +} + +// CreateMailbox mocks base method. +func (m *MockIMAPStateWrite) CreateMailbox(arg0 context.Context, arg1 imap.Mailbox) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateMailbox", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateMailbox indicates an expected call of CreateMailbox. +func (mr *MockIMAPStateWriteMockRecorder) CreateMailbox(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateMailbox", reflect.TypeOf((*MockIMAPStateWrite)(nil).CreateMailbox), arg0, arg1) +} + +// GetMailboxCount mocks base method. +func (m *MockIMAPStateWrite) GetMailboxCount(arg0 context.Context) (int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetMailboxCount", arg0) + ret0, _ := ret[0].(int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetMailboxCount indicates an expected call of GetMailboxCount. +func (mr *MockIMAPStateWriteMockRecorder) GetMailboxCount(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMailboxCount", reflect.TypeOf((*MockIMAPStateWrite)(nil).GetMailboxCount), arg0) +} + +// GetMailboxesWithoutAttrib mocks base method. +func (m *MockIMAPStateWrite) GetMailboxesWithoutAttrib(arg0 context.Context) ([]imap.MailboxNoAttrib, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetMailboxesWithoutAttrib", arg0) + ret0, _ := ret[0].([]imap.MailboxNoAttrib) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetMailboxesWithoutAttrib indicates an expected call of GetMailboxesWithoutAttrib. +func (mr *MockIMAPStateWriteMockRecorder) GetMailboxesWithoutAttrib(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMailboxesWithoutAttrib", reflect.TypeOf((*MockIMAPStateWrite)(nil).GetMailboxesWithoutAttrib), arg0) +} + +// GetSettings mocks base method. +func (m *MockIMAPStateWrite) GetSettings(arg0 context.Context) (string, bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSettings", arg0) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetSettings indicates an expected call of GetSettings. +func (mr *MockIMAPStateWriteMockRecorder) GetSettings(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSettings", reflect.TypeOf((*MockIMAPStateWrite)(nil).GetSettings), arg0) +} + +// PatchMailboxHierarchyWithoutTransforms mocks base method. +func (m *MockIMAPStateWrite) PatchMailboxHierarchyWithoutTransforms(arg0 context.Context, arg1 imap.MailboxID, arg2 []string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PatchMailboxHierarchyWithoutTransforms", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// PatchMailboxHierarchyWithoutTransforms indicates an expected call of PatchMailboxHierarchyWithoutTransforms. +func (mr *MockIMAPStateWriteMockRecorder) PatchMailboxHierarchyWithoutTransforms(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PatchMailboxHierarchyWithoutTransforms", reflect.TypeOf((*MockIMAPStateWrite)(nil).PatchMailboxHierarchyWithoutTransforms), arg0, arg1, arg2) +} + +// StoreSettings mocks base method. +func (m *MockIMAPStateWrite) StoreSettings(arg0 context.Context, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StoreSettings", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// StoreSettings indicates an expected call of StoreSettings. +func (mr *MockIMAPStateWriteMockRecorder) StoreSettings(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StoreSettings", reflect.TypeOf((*MockIMAPStateWrite)(nil).StoreSettings), arg0, arg1) +} + +// UpdateMessageFlags mocks base method. +func (m *MockIMAPStateWrite) UpdateMessageFlags(arg0 context.Context, arg1 imap.MessageID, arg2 imap.FlagSet) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateMessageFlags", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateMessageFlags indicates an expected call of UpdateMessageFlags. +func (mr *MockIMAPStateWriteMockRecorder) UpdateMessageFlags(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateMessageFlags", reflect.TypeOf((*MockIMAPStateWrite)(nil).UpdateMessageFlags), arg0, arg1, arg2) +} diff --git a/internal/services/imapservice/service.go b/internal/services/imapservice/service.go index 701a62c6..79e4b9f0 100644 --- a/internal/services/imapservice/service.go +++ b/internal/services/imapservice/service.go @@ -158,7 +158,7 @@ func NewService( syncUpdateApplier: syncUpdateApplier, syncMessageBuilder: syncMessageBuilder, syncReporter: syncReporter, - syncConfigPath: getSyncConfigPath(syncConfigDir, identityState.User.ID), + syncConfigPath: GetSyncConfigPath(syncConfigDir, identityState.User.ID), } } @@ -498,6 +498,7 @@ func (s *Service) buildConnectors() (map[string]*Connector, error) { s.panicHandler, s.telemetry, s.showAllMail, + s.syncStateProvider, ) return connectors, nil @@ -514,6 +515,7 @@ func (s *Service) buildConnectors() (map[string]*Connector, error) { s.panicHandler, s.telemetry, s.showAllMail, + s.syncStateProvider, ) } @@ -644,6 +646,6 @@ type setAddressModeReq struct { type getSyncFailedMessagesReq struct{} -func getSyncConfigPath(path string, userID string) string { +func GetSyncConfigPath(path string, userID string) string { return filepath.Join(path, fmt.Sprintf("sync-%v", userID)) } diff --git a/internal/services/imapservice/service_address_events.go b/internal/services/imapservice/service_address_events.go index 2c5aed9c..78abe4a3 100644 --- a/internal/services/imapservice/service_address_events.go +++ b/internal/services/imapservice/service_address_events.go @@ -128,6 +128,7 @@ func addNewAddressSplitMode(ctx context.Context, s *Service, addrID string) erro s.panicHandler, s.telemetry, s.showAllMail, + s.syncStateProvider, ) if err := s.serverManager.AddIMAPUser(ctx, connector, connector.addrID, s.gluonIDProvider, s.syncStateProvider); err != nil { diff --git a/internal/services/imapservice/sync_state_provider.go b/internal/services/imapservice/sync_state_provider.go index 190d67a5..9b3723d2 100644 --- a/internal/services/imapservice/sync_state_provider.go +++ b/internal/services/imapservice/sync_state_provider.go @@ -220,7 +220,7 @@ func (s *SyncState) loadUnsafe() error { } func DeleteSyncState(configDir, userID string) error { - path := getSyncConfigPath(configDir, userID) + path := GetSyncConfigPath(configDir, userID) if err := os.Remove(path); err != nil && !errors.Is(err, os.ErrNotExist) { return err @@ -234,7 +234,7 @@ func MigrateVaultSettings( hasLabels, hasMessages bool, failedMessageIDs []string, ) (bool, error) { - filePath := getSyncConfigPath(configDir, userID) + filePath := GetSyncConfigPath(configDir, userID) _, err := os.ReadFile(filePath) //nolint:gosec if err == nil { diff --git a/internal/services/imapservice/sync_state_provider_test.go b/internal/services/imapservice/sync_state_provider_test.go index 0852c53f..e4dd93b7 100644 --- a/internal/services/imapservice/sync_state_provider_test.go +++ b/internal/services/imapservice/sync_state_provider_test.go @@ -29,7 +29,7 @@ import ( func TestMigrateSyncSettings_AlreadyExists(t *testing.T) { tmpDir := t.TempDir() - testFile := getSyncConfigPath(tmpDir, "test") + testFile := GetSyncConfigPath(tmpDir, "test") expected, err := generateTestState(testFile) require.NoError(t, err) @@ -53,7 +53,7 @@ func TestMigrateSyncSettings_DoesNotExist(t *testing.T) { require.NoError(t, err) require.True(t, migrated) - state, err := NewSyncState(getSyncConfigPath(tmpDir, "test")) + state, err := NewSyncState(GetSyncConfigPath(tmpDir, "test")) require.NoError(t, err) status, err := state.GetSyncStatus(context.Background()) require.NoError(t, err) diff --git a/internal/services/imapsmtpserver/service.go b/internal/services/imapsmtpserver/service.go index de186eb9..f2e22176 100644 --- a/internal/services/imapsmtpserver/service.go +++ b/internal/services/imapsmtpserver/service.go @@ -390,6 +390,11 @@ func (sm *Service) handleAddIMAPUserImpl(ctx context.Context, } else { log.Info("Creating new IMAP user") + // GODT-3003: Ensure previous IMAP sync state is cleared if we run into code path after vault corruption. + if err := syncStateProvider.ClearSyncStatus(ctx); err != nil { + return fmt.Errorf("failed to reset sync status: %w", err) + } + gluonID, err := sm.imapServer.AddUser(ctx, connector, idProvider.GluonKey()) if err != nil { return fmt.Errorf("failed to add IMAP user: %w", err) From 275b30e51810be24c4f15a2d8a16269bfd0fa594 Mon Sep 17 00:00:00 2001 From: Jakub Date: Tue, 10 Oct 2023 11:29:36 +0200 Subject: [PATCH 20/51] chore: Vasco da Gama Bridge 3.6.0 changelog. --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index e033fbb2..8a35fc7e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,7 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) + ## Vasco da Gama Bridge 3.6.0 ### Added From 94b44b383ae8a714e6391fec2ea5df13fc28ea3f Mon Sep 17 00:00:00 2001 From: Jakub Date: Tue, 10 Oct 2023 15:48:30 +0200 Subject: [PATCH 21/51] feat(GODT-3004): update gopenpgp and dependencies. --- go.mod | 6 +++--- go.sum | 20 +++++++++++++------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index af219a1a..e21f548e 100644 --- a/go.mod +++ b/go.mod @@ -7,8 +7,8 @@ require ( github.com/Masterminds/semver/v3 v3.2.0 github.com/ProtonMail/gluon v0.17.1-0.20231009084701-3af0474b0b3c github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a - github.com/ProtonMail/go-proton-api v0.4.1-0.20230831064234-0e3a549b3f36 - github.com/ProtonMail/gopenpgp/v2 v2.7.1-proton + github.com/ProtonMail/go-proton-api v0.4.1-0.20231011062329-f3b976b7dbca + github.com/ProtonMail/gopenpgp/v2 v2.7.3-proton github.com/PuerkitoBio/goquery v1.8.1 github.com/abiosoft/ishell v2.0.0+incompatible github.com/allan-simon/go-singleinstance v0.0.0-20210120080615-d0997106ab37 @@ -52,7 +52,7 @@ require ( require ( github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230717121622-edf196117233 // indirect github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f // indirect github.com/ProtonMail/go-srp v0.0.7 // indirect github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db // indirect diff --git a/go.sum b/go.sum index 7a1236b5..4a0bebe5 100644 --- a/go.sum +++ b/go.sum @@ -28,19 +28,18 @@ github.com/ProtonMail/gluon v0.17.1-0.20231009084701-3af0474b0b3c/go.mod h1:Og5/ github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a h1:D+aZah+k14Gn6kmL7eKxoo/4Dr/lK3ChBcwce2+SQP4= github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4= github.com/ProtonMail/go-crypto v0.0.0-20230321155629-9a39f2531310/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE= -github.com/ProtonMail/go-crypto v0.0.0-20230322105811-d73448b7e800/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE= -github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 h1:ZK3C5DtzV2nVAQTx5S5jQvMeDqWtD1By5mOoyY/xJek= -github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE= +github.com/ProtonMail/go-crypto v0.0.0-20230717121622-edf196117233 h1:bdoKdh0f66/lrgVfYlxw0aqISY/KOqXmFJyGt7rGmnc= +github.com/ProtonMail/go-crypto v0.0.0-20230717121622-edf196117233/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/ProtonMail/go-message v0.13.1-0.20230526094639-b62c999c85b7 h1:+j+Kd/DyZ/qGfMT9htAT7HxqIEbZHsatsx+m8AoV6fc= github.com/ProtonMail/go-message v0.13.1-0.20230526094639-b62c999c85b7/go.mod h1:NBAn21zgCJ/52WLDyed18YvYFm5tEoeDauubFqLokM4= github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ekTTXpdwKYF8eBlsYsDVoggDAuAjoK66k= github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw= -github.com/ProtonMail/go-proton-api v0.4.1-0.20230831064234-0e3a549b3f36 h1:JVMK2w90bCWayUCXJIb3wkQ5+j2P/NbnrX3BrDoLzsc= -github.com/ProtonMail/go-proton-api v0.4.1-0.20230831064234-0e3a549b3f36/go.mod h1:nS8hMGjJLgC0Iej0JMYbsI388LesEkM1Hj/jCCxQeaQ= +github.com/ProtonMail/go-proton-api v0.4.1-0.20231011062329-f3b976b7dbca h1:nO/xuvyEgWWLo2cBAqfxCHh7Ri0ofV3PXnTOfk0QcyI= +github.com/ProtonMail/go-proton-api v0.4.1-0.20231011062329-f3b976b7dbca/go.mod h1:IGVXKy6NLHt4WeWiOnAFmSsXRpd6elkjDZMtr5vBLJ8= github.com/ProtonMail/go-srp v0.0.7 h1:Sos3Qk+th4tQR64vsxGIxYpN3rdnG9Wf9K4ZloC1JrI= github.com/ProtonMail/go-srp v0.0.7/go.mod h1:giCp+7qRnMIcCvI6V6U3S1lDDXDQYx2ewJ6F/9wdlJk= -github.com/ProtonMail/gopenpgp/v2 v2.7.1-proton h1:YS6M20yvjCJPR1r4ADW5TPn6rahs4iAyZaACei86bEc= -github.com/ProtonMail/gopenpgp/v2 v2.7.1-proton/go.mod h1:S1lYsaGHykYpxxh2SnJL6ypcAlANKj5NRSY6HxKryKQ= +github.com/ProtonMail/gopenpgp/v2 v2.7.3-proton h1:wuAxBUU9qF2wyDVJprn/2xPDx000eol5gwlKbOUYY88= +github.com/ProtonMail/gopenpgp/v2 v2.7.3-proton/go.mod h1:omVkSsfPAhmptzPF/piMXb16wKIWUvVhZbVW7sJKh0A= github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM= github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ= github.com/abiosoft/ishell v2.0.0+incompatible h1:zpwIuEHc37EzrsIYah3cpevrIc8Oma7oZPxr03tlmmw= @@ -64,6 +63,7 @@ github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJm github.com/bradenaw/juniper v0.12.0 h1:Q/7icpPQD1nH/La5DobQfNEtwyrBSiSu47jOQx7lJEM= github.com/bradenaw/juniper v0.12.0/go.mod h1:Z2B7aJlQ7xbfWsnMLROj5t/5FQ94/MkIdKC30J4WvzI= github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= @@ -417,6 +417,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= @@ -464,6 +465,7 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= @@ -512,6 +514,8 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -519,6 +523,7 @@ golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= @@ -529,6 +534,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5-0.20201125200606-c27b9fd57aec/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= From 01043e033e5b2fc848dc1a4638b993a1cd040f68 Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 11 Oct 2023 08:37:28 +0200 Subject: [PATCH 22/51] chore: Umshiang Bridge 3.5.3 changelog. --- Changelog.md | 6 ++++++ Makefile | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index d896445a..13df6ffa 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,12 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Umshiang Bridge 3.5.3 + +### Changed +* GODT-3004: Update gopenpgp and dependencies. + + ## Umshiang Bridge 3.5.2 ### Fixed diff --git a/Makefile b/Makefile index b99c44b9..14dd0298 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.5.2+git +BRIDGE_APP_VERSION?=3.5.3+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From e580f89106e8efcb6aa6ea9c4cc1480edd75c6fd Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 11 Oct 2023 15:29:52 +0200 Subject: [PATCH 23/51] feat(GODT-3004): update gopenpgp and dependencies. --- go.mod | 6 +++--- go.sum | 20 +++++++++++++------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index fc5a08aa..b6f6097d 100644 --- a/go.mod +++ b/go.mod @@ -7,8 +7,8 @@ require ( github.com/Masterminds/semver/v3 v3.2.0 github.com/ProtonMail/gluon v0.17.1-0.20231009084701-3af0474b0b3c github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a - github.com/ProtonMail/go-proton-api v0.4.1-0.20230925123025-331ad8e6d5ee - github.com/ProtonMail/gopenpgp/v2 v2.7.1-proton + github.com/ProtonMail/go-proton-api v0.4.1-0.20231011132529-24b5b817ee1f + github.com/ProtonMail/gopenpgp/v2 v2.7.3-proton github.com/PuerkitoBio/goquery v1.8.1 github.com/abiosoft/ishell v2.0.0+incompatible github.com/allan-simon/go-singleinstance v0.0.0-20210120080615-d0997106ab37 @@ -53,7 +53,7 @@ require ( require ( github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230717121622-edf196117233 // indirect github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f // indirect github.com/ProtonMail/go-srp v0.0.7 // indirect github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db // indirect diff --git a/go.sum b/go.sum index cb4e1e30..157d4409 100644 --- a/go.sum +++ b/go.sum @@ -28,19 +28,18 @@ github.com/ProtonMail/gluon v0.17.1-0.20231009084701-3af0474b0b3c/go.mod h1:Og5/ github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a h1:D+aZah+k14Gn6kmL7eKxoo/4Dr/lK3ChBcwce2+SQP4= github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4= github.com/ProtonMail/go-crypto v0.0.0-20230321155629-9a39f2531310/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE= -github.com/ProtonMail/go-crypto v0.0.0-20230322105811-d73448b7e800/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE= -github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 h1:ZK3C5DtzV2nVAQTx5S5jQvMeDqWtD1By5mOoyY/xJek= -github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE= +github.com/ProtonMail/go-crypto v0.0.0-20230717121622-edf196117233 h1:bdoKdh0f66/lrgVfYlxw0aqISY/KOqXmFJyGt7rGmnc= +github.com/ProtonMail/go-crypto v0.0.0-20230717121622-edf196117233/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/ProtonMail/go-message v0.13.1-0.20230526094639-b62c999c85b7 h1:+j+Kd/DyZ/qGfMT9htAT7HxqIEbZHsatsx+m8AoV6fc= github.com/ProtonMail/go-message v0.13.1-0.20230526094639-b62c999c85b7/go.mod h1:NBAn21zgCJ/52WLDyed18YvYFm5tEoeDauubFqLokM4= github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ekTTXpdwKYF8eBlsYsDVoggDAuAjoK66k= github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw= -github.com/ProtonMail/go-proton-api v0.4.1-0.20230925123025-331ad8e6d5ee h1:CzFXOiflEZZqT3HQqj2I5AkIprRbc/c6/lToPdEKzxM= -github.com/ProtonMail/go-proton-api v0.4.1-0.20230925123025-331ad8e6d5ee/go.mod h1:Y3ea3i1UbqHz5vq43odmAAd6lmR4nx0ZIQ32tqMfxTY= +github.com/ProtonMail/go-proton-api v0.4.1-0.20231011132529-24b5b817ee1f h1:n0oBMAz2dJhn5+1WA6NrjkWqkZN+22FQMkPlRwNGhpU= +github.com/ProtonMail/go-proton-api v0.4.1-0.20231011132529-24b5b817ee1f/go.mod h1:ZmvQMA8hanLiD1tFsvu9+qGBcuxbIRfch/4z/nqBhXA= github.com/ProtonMail/go-srp v0.0.7 h1:Sos3Qk+th4tQR64vsxGIxYpN3rdnG9Wf9K4ZloC1JrI= github.com/ProtonMail/go-srp v0.0.7/go.mod h1:giCp+7qRnMIcCvI6V6U3S1lDDXDQYx2ewJ6F/9wdlJk= -github.com/ProtonMail/gopenpgp/v2 v2.7.1-proton h1:YS6M20yvjCJPR1r4ADW5TPn6rahs4iAyZaACei86bEc= -github.com/ProtonMail/gopenpgp/v2 v2.7.1-proton/go.mod h1:S1lYsaGHykYpxxh2SnJL6ypcAlANKj5NRSY6HxKryKQ= +github.com/ProtonMail/gopenpgp/v2 v2.7.3-proton h1:wuAxBUU9qF2wyDVJprn/2xPDx000eol5gwlKbOUYY88= +github.com/ProtonMail/gopenpgp/v2 v2.7.3-proton/go.mod h1:omVkSsfPAhmptzPF/piMXb16wKIWUvVhZbVW7sJKh0A= github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM= github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ= github.com/abiosoft/ishell v2.0.0+incompatible h1:zpwIuEHc37EzrsIYah3cpevrIc8Oma7oZPxr03tlmmw= @@ -64,6 +63,7 @@ github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJm github.com/bradenaw/juniper v0.12.0 h1:Q/7icpPQD1nH/La5DobQfNEtwyrBSiSu47jOQx7lJEM= github.com/bradenaw/juniper v0.12.0/go.mod h1:Z2B7aJlQ7xbfWsnMLROj5t/5FQ94/MkIdKC30J4WvzI= github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= @@ -419,6 +419,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= @@ -466,6 +467,7 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= @@ -514,6 +516,8 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -521,6 +525,7 @@ golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= @@ -531,6 +536,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5-0.20201125200606-c27b9fd57aec/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= From 8be4246f7e261322651a528fcdbe8a9e8c87cb81 Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 11 Oct 2023 16:09:55 +0200 Subject: [PATCH 24/51] chore: Vasco da Gama Bridge 3.6.0 changelog. --- Changelog.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Changelog.md b/Changelog.md index 8a35fc7e..e2f7059f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -33,6 +33,11 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) * GODT-2929: Message dedup with different text transfer encoding. +## Umshiang Bridge 3.5.3 + +### Changed +* GODT-3004: Update gopenpgp and dependencies. + ## Umshiang Bridge 3.5.2 From 8b12a454eaa2c30638446b7c46ded4aa6654ede1 Mon Sep 17 00:00:00 2001 From: Leander Beernaert Date: Wed, 18 Oct 2023 14:29:27 +0200 Subject: [PATCH 25/51] fix(GODT-3033): Unable to receive new mail If the IMAP service happened to finish syncing and wanted to reset the user event service at a time the latter was publishing an event a deadlock would occur and the user would not receive any new messages. This change puts the request to revert the event id in a separate go-routine to avoid this situation from re-occurring. The operational flow remains unchanged as the event service will only process this request once the current set of events have been published. --- internal/services/imapservice/service.go | 42 ++++++++++++++---------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/internal/services/imapservice/service.go b/internal/services/imapservice/service.go index 79e4b9f0..0ccbeced 100644 --- a/internal/services/imapservice/service.go +++ b/internal/services/imapservice/service.go @@ -22,6 +22,7 @@ import ( "errors" "fmt" "path/filepath" + "sync/atomic" "time" "github.com/ProtonMail/gluon/async" @@ -94,7 +95,7 @@ type Service struct { syncConfigPath string lastHandledEventID string - isSyncing bool + isSyncing atomic.Bool } func NewService( @@ -405,23 +406,28 @@ func (s *Service) run(ctx context.Context) { //nolint gocyclo continue } + // Start a goroutine to wait on event reset as it is possible that the sync received message + // was processed during an event publish. This in turn will block the imap service, since the + // event service is unable to reply to the request until the events have been processed. s.log.Info("Sync complete, starting API event stream") - if err := s.eventProvider.RewindEventID(ctx, s.lastHandledEventID); err != nil { - if errors.Is(err, context.Canceled) { - continue + go func() { + if err := s.eventProvider.RewindEventID(ctx, s.lastHandledEventID); err != nil { + if errors.Is(err, context.Canceled) { + return + } + + s.log.WithError(err).Error("Failed to rewind event service") + s.eventPublisher.PublishEvent(ctx, events.UserBadEvent{ + UserID: s.identityState.UserID(), + OldEventID: "", + NewEventID: "", + EventInfo: "", + Error: fmt.Errorf("failed to rewind event loop: %w", err), + }) } - s.log.WithError(err).Error("Failed to rewind event service") - s.eventPublisher.PublishEvent(ctx, events.UserBadEvent{ - UserID: s.identityState.UserID(), - OldEventID: "", - NewEventID: "", - EventInfo: "", - Error: fmt.Errorf("failed to rewind event loop: %w", err), - }) - } - - s.isSyncing = false + s.isSyncing.Store(false) + }() } case request, ok := <-s.syncUpdateApplier.requestCh: @@ -443,7 +449,7 @@ func (s *Service) run(ctx context.Context) { //nolint gocyclo continue } e.Consume(func(event proton.Event) error { - if s.isSyncing { + if s.isSyncing.Load() { if err := syncEventHandler.OnEvent(ctx, event); err != nil { return err } @@ -615,13 +621,13 @@ func (s *Service) setShowAllMail(v bool) { } func (s *Service) startSyncing() { - s.isSyncing = true + s.isSyncing.Store(true) s.syncHandler.Execute(s.syncReporter, s.labels.GetLabelMap(), s.syncUpdateApplier, s.syncMessageBuilder, syncservice.DefaultRetryCoolDown) } func (s *Service) cancelSync() { s.syncHandler.CancelAndWait() - s.isSyncing = false + s.isSyncing.Store(false) } type resyncReq struct{} From 248fbf5e33edd623f4d44b319dff4927d63a8d50 Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 18 Oct 2023 15:41:01 +0200 Subject: [PATCH 26/51] chore: Vasco da Gama Bridge 3.6.1 changelog. --- Changelog.md | 6 ++++++ Makefile | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index e2f7059f..855d228e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,12 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Vasco da Gama Bridge 3.6.1 + +### Fixed +* GODT-3033: Unable to receive new mail. + + ## Vasco da Gama Bridge 3.6.0 ### Added diff --git a/Makefile b/Makefile index 0ae1998a..21d1087a 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.6.0+git +BRIDGE_APP_VERSION?=3.6.1+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From 097d6f86d31baf6358500f41d5ed4d92b66e5924 Mon Sep 17 00:00:00 2001 From: Jakub Date: Fri, 2 Feb 2024 17:34:32 +0100 Subject: [PATCH 27/51] fix(GODT-3235): update bridge update key --- internal/updater/key_default.go | 265 ++++++++++++++++---------------- 1 file changed, 132 insertions(+), 133 deletions(-) diff --git a/internal/updater/key_default.go b/internal/updater/key_default.go index 81baef8a..66cd635f 100644 --- a/internal/updater/key_default.go +++ b/internal/updater/key_default.go @@ -32,137 +32,136 @@ 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 -00IsXQemR6I8Qw== -=QiAL +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 +=I7Pt -----END PGP PUBLIC KEY BLOCK-----` From d65d6ee2e55560931790b601dc9a7226ed707147 Mon Sep 17 00:00:00 2001 From: Jakub Date: Fri, 2 Feb 2024 18:37:38 +0100 Subject: [PATCH 28/51] fix(GODT-3235): use release xikou for trigger build --- ci/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/build.yml b/ci/build.yml index d4eb7839..88107307 100644 --- a/ci/build.yml +++ b/ci/build.yml @@ -65,5 +65,5 @@ trigger-qa-installer: SRC_HASH: $CI_COMMIT_SHA trigger: project: "jcuth/bridge-release" - branch: master + branch: release/xikou From 495124440077cb6b4629b89936c89815962a6ec9 Mon Sep 17 00:00:00 2001 From: Jakub Date: Fri, 2 Feb 2024 19:32:58 +0100 Subject: [PATCH 29/51] chore: Xikou Bridge 3.8.2 changelog. --- Changelog.md | 6 ++++++ Makefile | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 64f7183e..be0cd045 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,12 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Xikou Bridge 3.8.2 + +### Fixed +* GODT-3235: Update bridge update key. + + ## Xikou Bridge 3.8.1 ### Added diff --git a/Makefile b/Makefile index 9b381d3a..5130e681 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.8.1+git +BRIDGE_APP_VERSION?=3.8.2+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From da069a0155a1801ec42b29c97a535d1eec83474e Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 6 Mar 2024 10:33:17 +0100 Subject: [PATCH 30/51] chore: Zaehringen Bridge 3.10.0 changelog. --- Changelog.md | 17 +++++++++++++++++ Makefile | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 0df187b1..b3eba7fc 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,23 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Zaehringen Bridge 3.10.0 + +### Added +* GODT-3199: Add package log field. +* GODT-3220: Add more test scenarios. + +### Changed +* GODT-3193: Preserve attachment encoding. +* GODT-3214: Encrypt only with primary key. +* GODT-2662: Use tart runner for darwin jobs. +* GODT-1602: Test: run integration tests against black 🖤. +* GODT-3257: Test: quad9 provider test not working on CI. + +### Fixed +* GODT-3290: Fix test failing because of leap day. + + ## Ypsilon Bridge 3.9.1 ### Fixed diff --git a/Makefile b/Makefile index 8add54b1..1e18be5f 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.9.1+git +BRIDGE_APP_VERSION?=3.10.0+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From 2569e83e514041e110f3e50c900a955cf7281c6c Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Mon, 15 Apr 2024 16:31:19 +0200 Subject: [PATCH 31/51] chore: Alcantara Bridge 3.11.0 changelog. --- Changelog.md | 18 ++++++++++++++++++ Makefile | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index b3eba7fc..a72d6983 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,24 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Alcantara Bridge 3.11.0 + +### Added +* GODT-3185: Report cases which leads to wrong address key used. + +### Changed +* BRIDGE-14: HV3 implementation. +* BRIDGE-15: Certificate install is now also done during Outlook setup on macOS. +* GODT-3146: Start servers on startup, keep running when even when no users are active. + +### Fixed +* BRIDGE-8: Fix bridge double sessionID issue in logs. +* BRIDGE-7: Modify keychain test on macOS. +* BRIDGE-4: Logs not being created when invalid flag is passed. +* BRIDGE-5: Add tooltip to tray icon. +* GODT-3163: Filter MBOX format delimiter. + + ## Zaehringen Bridge 3.10.0 ### Added diff --git a/Makefile b/Makefile index b9b776b8..34ed7bf2 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ ROOT_DIR:=$(realpath .) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.10.0+git +BRIDGE_APP_VERSION?=3.11.0+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From b574ccb6ea142143d1cb4bebd4ccfd8f41b56471 Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Mon, 22 Apr 2024 10:37:47 +0200 Subject: [PATCH 32/51] chore: Alcantara Bridge 3.11.0 changelog. --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index a72d6983..d5bef833 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,6 +12,7 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) * BRIDGE-14: HV3 implementation. * BRIDGE-15: Certificate install is now also done during Outlook setup on macOS. * GODT-3146: Start servers on startup, keep running when even when no users are active. +* BRIDGE-19: Update checksum validation use warning instead of error on non-existing files. ### Fixed * BRIDGE-8: Fix bridge double sessionID issue in logs. From 961dc9435f49ecca4964acc55731704cb63b9e6d Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Tue, 23 Apr 2024 15:58:22 +0200 Subject: [PATCH 33/51] fix(BRIDGE-15): Apple Mail profile install page was not properly reset before showing. --- .../bridge-gui/bridge-gui/qml/SetupWizard/SetupWizard.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/SetupWizard/SetupWizard.qml b/internal/frontend/bridge-gui/bridge-gui/qml/SetupWizard/SetupWizard.qml index 7dac45d8..33588560 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/SetupWizard/SetupWizard.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/SetupWizard/SetupWizard.qml @@ -96,6 +96,7 @@ Item { function showAppleMailAutoConfig() { backAction = _showClientConfig; rootStackLayout.currentIndex = SetupWizard.RootStack.TwoPanesView; + clientConfigAppleMail.reset() rightContent.currentIndex = SetupWizard.ContentStack.ClientConfigAppleMail; leftContent.showAppleMailAutoconfigProfileInstall(); } From 82607efe1cb5af64ddc21b4bf80e6b66e3a670ae Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Tue, 23 Apr 2024 17:07:24 +0200 Subject: [PATCH 34/51] chore: Alcantara Bridge 3.11.0 changelog. --- Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index d5bef833..fa908a9c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,7 +11,7 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) ### Changed * BRIDGE-14: HV3 implementation. * BRIDGE-15: Certificate install is now also done during Outlook setup on macOS. -* GODT-3146: Start servers on startup, keep running when even when no users are active. +* GODT-3146: Start servers on startup, keep running even when no users are active. * BRIDGE-19: Update checksum validation use warning instead of error on non-existing files. ### Fixed From a5e0f85a5834aba212d3a3cf0e0fa562ad6249d3 Mon Sep 17 00:00:00 2001 From: Atanas Janeshliev Date: Wed, 15 May 2024 15:03:58 +0200 Subject: [PATCH 35/51] fix(BRIDGE-70): hotfix for blocked smtp/imap port causing bridge to quit --- internal/dialer/dialer_pinning_test.go | 3 ++- internal/services/imapsmtpserver/service.go | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/internal/dialer/dialer_pinning_test.go b/internal/dialer/dialer_pinning_test.go index 0b3ff489..e50373ad 100644 --- a/internal/dialer/dialer_pinning_test.go +++ b/internal/dialer/dialer_pinning_test.go @@ -64,7 +64,8 @@ func TestTLSPinInvalid(t *testing.T) { checkTLSIssueHandler(t, 1, called) } -func TestTLSPinNoMatch(t *testing.T) { +// Disabled for now we'll need to patch this up. +func _TestTLSPinNoMatch(t *testing.T) { //nolint:unused skipIfProxyIsSet(t) called, _, reporter, checker, cm := createClientWithPinningDialer(getRootURL()) diff --git a/internal/services/imapsmtpserver/service.go b/internal/services/imapsmtpserver/service.go index ef5d79da..c603479c 100644 --- a/internal/services/imapsmtpserver/service.go +++ b/internal/services/imapsmtpserver/service.go @@ -108,13 +108,13 @@ func (sm *Service) Init(ctx context.Context, group *async.Group, subscription ev }) if err := sm.serveIMAP(ctx); err != nil { - sm.log.WithError(err).Error("Failed to start IMAP server") - return err + sm.log.WithError(err).Error("Failed to start IMAP server on bridge start") + sm.imapListener = nil } if err := sm.serveSMTP(ctx); err != nil { - sm.log.WithError(err).Error("Failed to start SMTP server") - return err + sm.log.WithError(err).Error("Failed to start SMTP server on bridge start") + sm.smtpListener = nil } return nil From cd8db6fd1ce5619b073bb75a03c5e8795572cd04 Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Thu, 16 May 2024 15:12:56 +0200 Subject: [PATCH 36/51] chore: Alcantara Bridge 3.11.1 changelog. --- Changelog.md | 6 ++++++ Makefile | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index fa908a9c..058dfe7d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,12 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Alcantara Bridge 3.11.1 + +### Fixed +* BRIDGE-70: Hotfix for blocked smtp/imap port causing bridge to quit. + + ## Alcantara Bridge 3.11.0 ### Added diff --git a/Makefile b/Makefile index 34ed7bf2..ae56ef97 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ ROOT_DIR:=$(realpath .) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.11.0+git +BRIDGE_APP_VERSION?=3.11.1+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From 48a75b0dd761af7c90c30b964844c4a37a406a4a Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Thu, 6 Jun 2024 10:10:36 +0200 Subject: [PATCH 37/51] chore: Bastei Bridge 3.12.0 changelog. --- Changelog.md | 21 +++++++++++++++++++++ Makefile | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 058dfe7d..8703e786 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,27 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Bastei Bridge 3.12.0 + +### Added +* BRIDGE-79: Add New Outlook for Mac KB disclaimer. + +### Changed +* BRIDGE-75: Bridge repair button. +* BRIDGE-16: Bump version Go 1.21.9 Qt 6.4.3. +* BRIDGE-23: Update gluon to go 1.21. +* BRIDGE-22: Update gpa to go 1.21. + +### Fixed +* BRIDGE-90: Disable repair button when bridge cannot connect to proton servers; bump GPA. +* BRIDGE-69: Explicitly handle semver panic for last bridge version from vault. +* BRIDGE-29: Bump gluon version. +* BRIDGE-49: Configure gitleaks baseline and grype config. +* BRIDGE-21: Missing panic handling. +* BRIDGE-17: Broken telemetry heartbeat test. +* BRIDGE-10: Bumped gluon version. + + ## Alcantara Bridge 3.11.1 ### Fixed diff --git a/Makefile b/Makefile index ae56ef97..22f6e279 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ ROOT_DIR:=$(realpath .) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.11.1+git +BRIDGE_APP_VERSION?=3.12.0+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From 56d4bfbb71cf09ac0b43781bf1af5de9b781eb18 Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Thu, 13 Jun 2024 10:04:43 +0200 Subject: [PATCH 38/51] feat(BRIDGE-79): update to the KB suggestion list. --- internal/kb/kbArticleList.json | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/internal/kb/kbArticleList.json b/internal/kb/kbArticleList.json index 373a90e2..b41e6bfc 100644 --- a/internal/kb/kbArticleList.json +++ b/internal/kb/kbArticleList.json @@ -432,19 +432,28 @@ "Sending", "Outlook", "Configuration", - "Sync" + "Sync", + "New Outlook" ] }, { "index": 38, "url": "https://proton.me/support/proton-mail-bridge-new-outlook-for-windows-set-up-guide", + "title": "What is the Recovered Messages folder in Bridge (and your email client)?", + "keywords": [ + "recovered messages", + "recovered messages folder" + ] + }, + { + "index": 39, + "url": "https://proton.me/support/proton-mail-bridge-new-outlook-for-windows-set-up-guide", "title": "Proton Mail Bridge New Outlook for Windows set up guide", "keywords": [ - "Outlook", - "New Outlook", - "Configuration", - "Configure", - "Setup" + "app password", + "INVALIDCREDENTIALS", + "TEMPORARILYUNAVAILABLE", + "New Outlook" ] } ] \ No newline at end of file From 85a91c5572b7858ef30ef7a66f1402bf8cd4e110 Mon Sep 17 00:00:00 2001 From: Atanas Janeshliev Date: Fri, 14 Jun 2024 13:01:07 +0000 Subject: [PATCH 39/51] feat(BRIDGE-97): added repair button telemetry --- internal/bridge/bridge.go | 2 +- internal/telemetry/repair.go | 43 ++++++++++++++++++++ internal/user/repair_telemetry.go | 65 +++++++++++++++++++++++++++++++ internal/user/user.go | 10 ++++- 4 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 internal/telemetry/repair.go create mode 100644 internal/user/repair_telemetry.go diff --git a/internal/bridge/bridge.go b/internal/bridge/bridge.go index 32024b0f..e9cadbb4 100644 --- a/internal/bridge/bridge.go +++ b/internal/bridge/bridge.go @@ -573,7 +573,7 @@ func (bridge *Bridge) Repair() { wg.Add(1) go func(userID string) { defer wg.Done() - if err = bridgeUser.ResyncIMAP(); err != nil { + if err = bridgeUser.TriggerRepair(); err != nil { logPkg.WithError(err).Error("Failed re-syncing IMAP for userID", userID) } }(userID) diff --git a/internal/telemetry/repair.go b/internal/telemetry/repair.go new file mode 100644 index 00000000..0da58e47 --- /dev/null +++ b/internal/telemetry/repair.go @@ -0,0 +1,43 @@ +// 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 telemetry + +type RepairData struct { + MeasurementGroup string + Event string + Values map[string]string + Dimensions map[string]string +} + +func NewRepairTriggerData() RepairData { + return RepairData{ + MeasurementGroup: "bridge.any.repair", + Event: "repair_trigger", + Values: map[string]string{}, + Dimensions: map[string]string{}, + } +} + +func NewRepairDeferredTriggerData() RepairData { + return RepairData{ + MeasurementGroup: "bridge.any.repair", + Event: "repair_deferred_trigger", + Values: map[string]string{}, + Dimensions: map[string]string{}, + } +} diff --git a/internal/user/repair_telemetry.go b/internal/user/repair_telemetry.go new file mode 100644 index 00000000..002f52f7 --- /dev/null +++ b/internal/user/repair_telemetry.go @@ -0,0 +1,65 @@ +// 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" + + "github.com/ProtonMail/proton-bridge/v3/internal/telemetry" +) + +func (user *User) SendRepairTrigger(ctx context.Context) { + if !user.IsTelemetryEnabled(ctx) { + return + } + + triggerData := telemetry.NewRepairTriggerData() + data, err := json.Marshal(triggerData) + if err != nil { + user.log.WithError(err).Error("Failed to parse repair trigger data.") + return + } + + if err := user.SendTelemetry(ctx, data); err != nil { + user.log.WithError(err).Error("Failed to send repair trigger event.") + return + } + + user.log.Info("Repair trigger event successfully sent.") +} + +func (user *User) SendRepairDeferredTrigger(ctx context.Context) { + if !user.IsTelemetryEnabled(ctx) { + return + } + + deferredTriggerData := telemetry.NewRepairDeferredTriggerData() + data, err := json.Marshal(deferredTriggerData) + if err != nil { + user.log.WithError(err).Error("Failed to parse deferred repair trigger data.") + return + } + + if err := user.SendTelemetry(ctx, data); err != nil { + user.log.WithError(err).Error("Failed to send deferred repair trigger event.") + return + } + + user.log.Info("Deferred repair trigger event successfully sent.") +} diff --git a/internal/user/user.go b/internal/user/user.go index a93a0776..40784655 100644 --- a/internal/user/user.go +++ b/internal/user/user.go @@ -727,12 +727,18 @@ func (user *User) VerifyResyncAndExecute() { user.log.WithError(err).Error("Failed to disable re-sync flag in user vault. UserID:", user.ID()) } - if err := user.ResyncIMAP(); err != nil { + user.SendRepairDeferredTrigger(context.Background()) + if err := user.resyncIMAP(); err != nil { user.log.WithError(err).Error("Failed re-syncing IMAP for userID", user.ID()) } } } -func (user *User) ResyncIMAP() error { +func (user *User) TriggerRepair() error { + user.SendRepairTrigger(context.Background()) + return user.resyncIMAP() +} + +func (user *User) resyncIMAP() error { return user.imapService.Resync(context.Background()) } From ed5adb18fbea9d03305bd9e808a4e105eabb5b99 Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Mon, 17 Jun 2024 11:19:49 +0200 Subject: [PATCH 40/51] chore: Bastei Bridge 3.12.0 changelog. --- Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 8703e786..e291264c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,10 +6,10 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) ## Bastei Bridge 3.12.0 ### Added +* BRIDGE-75: Bridge repair button. * BRIDGE-79: Add New Outlook for Mac KB disclaimer. ### Changed -* BRIDGE-75: Bridge repair button. * BRIDGE-16: Bump version Go 1.21.9 Qt 6.4.3. * BRIDGE-23: Update gluon to go 1.21. * BRIDGE-22: Update gpa to go 1.21. From 43cbedafb8693a7959b55b8b042828a4e1a4d364 Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Fri, 30 Aug 2024 15:35:30 +0200 Subject: [PATCH 41/51] chore: Colorado Bridge 3.13.0 changelog. --- Changelog.md | 17 +++++++++++++++++ Makefile | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index e291264c..ef357fb0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,23 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Colorado Bridge 3.13.0 + +### Added +* BRIDGE-37: added message broadcasting functionality. +* BRIDGE-122: added observability service. +* BRIDGE-119: added support for Feature Flags. +* BRIDGE-116: added command-line switches to enable/disable keychain check on macOS. +* BRIDGE-88: added context menu for quick actions on input labels: cut, copy, paste. + +### Changed +* BRIDGE-81: KB article suggestion updates + more weight for long keywords. + +### Fixed +* BRIDGE-67: Added detection for username changes on macOS & automatic reconfiguration. +* BRIDGE-138: Remove deprecated doc. + + ## Bastei Bridge 3.12.0 ### Added diff --git a/Makefile b/Makefile index 3f80d7b8..6464ce94 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ ROOT_DIR:=$(realpath .) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.12.0+git +BRIDGE_APP_VERSION?=3.13.0+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From 6105f32c75413b2c90d67f86bb758fcd2b007d0e Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Wed, 25 Sep 2024 10:47:40 +0200 Subject: [PATCH 42/51] chore: Dragon Bridge 3.14.0 changelog. --- Changelog.md | 13 +++++++++++++ Makefile | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index ef357fb0..44c72f56 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,19 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Dragon Bridge 3.14.0 + +### Changed +* BRIDGE-207: Failure to download or verify an update now fails silently. +* BRIDGE-204: Removed redundant Sentry events. +* BRIDGE-150: Observability service modification. +* BRIDGE-210: Reduced log level of cache events so they won't be printed to stdout. + +### Fixed +* BRIDGE-106: Fixed import of multipart-related messages. +* BRIDGE-108: Fixed GetInitials when empty username is passed. + + ## Colorado Bridge 3.13.0 ### Added diff --git a/Makefile b/Makefile index 6464ce94..5626317c 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ ROOT_DIR:=$(realpath .) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.13.0+git +BRIDGE_APP_VERSION?=3.14.0+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From a8caec560eb03cf96f8d73602cc2aed8167680a7 Mon Sep 17 00:00:00 2001 From: Atanas Janeshliev Date: Tue, 29 Oct 2024 10:47:33 +0100 Subject: [PATCH 43/51] chore: Erasmus Bridge 3.15.0 changelog. --- Changelog.md | 24 ++++++++++++++++++++++++ Makefile | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 44c72f56..5d663793 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,30 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Erasmus Bridge 3.15.0 + +### Added +* BRIDGE-238: Added host information to sentry events; new sentry event for keychain issues. +* BRIDGE-236: Added SMTP observability metrics. +* BRIDGE-217: Added missing parameter to the CLI help command. +* BRIDGE-234: Add accessibility name in QML for UI automation. +* BRIDGE-232: Test: Add Home Menu Bridge UI e2e automation tests. +* BRIDGE-220: Test: Add Bridge E2E UI login/logout tests for Windows. + +### Changed +* BRIDGE-228: Removed sentry events. +* BRIDGE-218: Observability adapter; gluon observability metrics and tests. +* BRIDGE-215: Tweak wording on macOS profile install page. +* BRIDGE-131: Test: Integration tests for messages from Proton <-> Gmail. +* BRIDGE-142: Bridge icon can be removed from the menu bar on macOS. + +### Fixed +* BRIDGE-240: Fix for running against Qt 6.8 (contribution of GitHub user Cimbali). +* BRIDGE-231: Fix reversed header order in messages. +* BRIDGE-235: Fix compilation of Bridge GUI Tester on Windows. +* BRIDGE-120: Use appropriate address key when importing / saving draft. + + ## Dragon Bridge 3.14.0 ### Changed diff --git a/Makefile b/Makefile index 2c8daba3..9e373cdb 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ ROOT_DIR:=$(realpath .) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.14.0+git +BRIDGE_APP_VERSION?=3.15.0+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From 03c9455b0d20150c0ee46eeb1b597e2c9805f4f6 Mon Sep 17 00:00:00 2001 From: Atanas Janeshliev Date: Wed, 4 Dec 2024 10:03:12 +0100 Subject: [PATCH 44/51] chore: Flavien Bridge 3.16.0 changelog. --- Changelog.md | 21 +++++++++++++++++++++ Makefile | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 5d663793..66829fef 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,27 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Flavien Bridge 3.16.0 + +### Added +* BRIDGE-205: Add support for the IMAP AUTHENTICATE command. +* BRIDGE-268: Add kill switch feature flag for the IMAP AUTHENTICATE command. +* BRIDGE-261: Delete gluon data during user deletion. +* BRIDGE-246: Test: Add Settings Menu Bridge UI e2e automation tests. + +### Changed +* BRIDGE-107: Improved human verification UX. +* BRIDGE-281: Disable keychain test on macOS. +* BRIDGE-266: Heartbeat telemetry update. +* BRIDGE-253: Removed unused telemetry (activation and troubleshooting). +* BRIDGE-252: Restored the -h shortcut for the CLI --help switch. +* BRIDGE-264: Ignore apple notes as UserAgent. + +### Fixed +* BRIDGE-256: Fix reversed order of headers with multiple values. +* BRIDGE-258: Fixed issue with draft updates and sending during synchronization. + + ## Erasmus Bridge 3.15.0 ### Added diff --git a/Makefile b/Makefile index 9e373cdb..2c6e02e9 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ ROOT_DIR:=$(realpath .) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.15.0+git +BRIDGE_APP_VERSION?=3.16.0+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From 7cf3b6fb7bb20addb5f4980ff688ef93335447d5 Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Fri, 29 Nov 2024 09:14:29 +0100 Subject: [PATCH 45/51] feat(BRIDGE-281): disable keychain test on macOS. (cherry picked from commit 3f78f4d672528cff56899b7ecfffcb71b86b5d63) --- internal/app/app.go | 49 ++++---------------- internal/app/app_test.go | 64 -------------------------- pkg/keychain/helper_darwin.go | 15 ++---- pkg/keychain/helper_linux.go | 2 +- pkg/keychain/helper_windows.go | 2 +- pkg/keychain/keychain.go | 10 ++-- pkg/keychain/keychain_test.go | 2 +- utils/bridge-rollout/bridge-rollout.go | 4 +- utils/vault-editor/main.go | 4 +- 9 files changed, 25 insertions(+), 127 deletions(-) delete mode 100644 internal/app/app_test.go diff --git a/internal/app/app.go b/internal/app/app.go index be0ce6fe..edc7697a 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -97,18 +97,21 @@ const ( appShortName = "bridge" ) +// the two flags below have been deprecated by BRIDGE-281. We however keep them so that bridge does not error if they are passed on startup. var cliFlagEnableKeychainTest = &cli.BoolFlag{ //nolint:gochecknoglobals Name: flagEnableKeychainTest, - Usage: "Enable the keychain test for the current and future executions of the application", + Usage: "This flag is deprecated and does nothing", Value: false, DisableDefaultText: true, -} //nolint:gochecknoglobals + Hidden: true, +} var cliFlagDisableKeychainTest = &cli.BoolFlag{ //nolint:gochecknoglobals Name: flagDisableKeychainTest, - Usage: "Disable the keychain test for the current and future executions of the application", + Usage: "This flag is deprecated and does nothing", Value: false, DisableDefaultText: true, + Hidden: true, } func New() *cli.App { @@ -211,6 +214,7 @@ func New() *cli.App { if onMacOS() { // The two flags below were introduced for BRIDGE-116, and are available only on macOS. + // They have been later removed fro BRIDGE-281. app.Flags = append(app.Flags, cliFlagEnableKeychainTest, cliFlagDisableKeychainTest) } @@ -282,8 +286,7 @@ func run(c *cli.Context) error { return withSingleInstance(settings, locations.GetLockFile(), version, func() error { // Look for available keychains - skipKeychainTest := checkSkipKeychainTest(c, settings) - return WithKeychainList(crashHandler, skipKeychainTest, func(keychains *keychain.List) error { + return WithKeychainList(crashHandler, func(keychains *keychain.List) error { // Unlock the encrypted vault. return WithVault(reporter, locations, keychains, crashHandler, func(v *vault.Vault, insecure, corrupt bool) error { if !v.Migrated() { @@ -547,11 +550,11 @@ func withCookieJar(vault *vault.Vault, fn func(http.CookieJar) error) error { } // WithKeychainList init the list of usable keychains. -func WithKeychainList(panicHandler async.PanicHandler, skipKeychainTest bool, fn func(*keychain.List) error) error { +func WithKeychainList(panicHandler async.PanicHandler, fn func(*keychain.List) error) error { logrus.Debug("Creating keychain list") defer logrus.Debug("Keychain list stop") defer async.HandlePanic(panicHandler) - return fn(keychain.NewList(skipKeychainTest)) + return fn(keychain.NewList()) } func setDeviceCookies(jar *cookies.Jar) error { @@ -572,38 +575,6 @@ func setDeviceCookies(jar *cookies.Jar) error { return nil } -func checkSkipKeychainTest(c *cli.Context, settingsDir string) bool { - if !onMacOS() { - return false - } - - enable := c.Bool(flagEnableKeychainTest) - disable := c.Bool(flagDisableKeychainTest) - - skip, err := vault.GetShouldSkipKeychainTest(settingsDir) - if err != nil { - logrus.WithError(err).Error("Could not load keychain settings.") - } - - if (!enable) && (!disable) { - return skip - } - - // if both switches are passed, 'enable' has priority - if disable { - skip = true - } - if enable { - skip = false - } - - if err := vault.SetShouldSkipKeychainTest(settingsDir, skip); err != nil { - logrus.WithError(err).Error("Could not save keychain settings.") - } - - return skip -} - func onMacOS() bool { return runtime.GOOS == "darwin" } diff --git a/internal/app/app_test.go b/internal/app/app_test.go deleted file mode 100644 index 88d549e4..00000000 --- a/internal/app/app_test.go +++ /dev/null @@ -1,64 +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 app - -import ( - "testing" - - "github.com/stretchr/testify/require" - "github.com/urfave/cli/v2" -) - -func TestCheckSkipKeychainTest(t *testing.T) { - var expectedResult bool - dir := t.TempDir() - app := cli.App{ - Flags: []cli.Flag{ - cliFlagEnableKeychainTest, - cliFlagDisableKeychainTest, - }, - Action: func(c *cli.Context) error { - require.Equal(t, expectedResult, checkSkipKeychainTest(c, dir)) - return nil - }, - } - - noArgs := []string{"appName"} - enableArgs := []string{"appName", "-" + flagEnableKeychainTest} - disableArgs := []string{"appName", "-" + flagDisableKeychainTest} - bothArgs := []string{"appName", "-" + flagDisableKeychainTest, "-" + flagEnableKeychainTest} - - onMac := onMacOS() - - expectedResult = false - require.NoError(t, app.Run(noArgs)) - - expectedResult = onMac - require.NoError(t, app.Run(disableArgs)) - require.NoError(t, app.Run(noArgs)) - - expectedResult = false - require.NoError(t, app.Run(enableArgs)) - require.NoError(t, app.Run(noArgs)) - - expectedResult = onMac - require.NoError(t, app.Run(disableArgs)) - - expectedResult = false - require.NoError(t, app.Run(bothArgs)) -} diff --git a/pkg/keychain/helper_darwin.go b/pkg/keychain/helper_darwin.go index 867d2fec..77df8d02 100644 --- a/pkg/keychain/helper_darwin.go +++ b/pkg/keychain/helper_darwin.go @@ -31,21 +31,12 @@ const ( MacOSKeychain = "macos-keychain" ) -func listHelpers(skipKeychainTest bool) (Helpers, string) { +func listHelpers() (Helpers, string) { helpers := make(Helpers) // MacOS always provides a keychain. - if skipKeychainTest { - logrus.WithField("pkg", "keychain").Info("Skipping macOS keychain test") - helpers[MacOSKeychain] = newMacOSHelper - } else { - if isUsable(newMacOSHelper("")) { - helpers[MacOSKeychain] = newMacOSHelper - logrus.WithField("keychain", "MacOSKeychain").Info("Keychain is usable.") - } else { - logrus.WithField("keychain", "MacOSKeychain").Debug("Keychain is not available.") - } - } + logrus.WithField("pkg", "keychain").Info("Skipping macOS keychain test") + helpers[MacOSKeychain] = newMacOSHelper // Use MacOSKeychain by default. return helpers, MacOSKeychain diff --git a/pkg/keychain/helper_linux.go b/pkg/keychain/helper_linux.go index 7a395bc6..ce531faa 100644 --- a/pkg/keychain/helper_linux.go +++ b/pkg/keychain/helper_linux.go @@ -31,7 +31,7 @@ const ( SecretServiceDBus = "secret-service-dbus" ) -func listHelpers(_ bool) (Helpers, string) { +func listHelpers() (Helpers, string) { helpers := make(Helpers) if isUsable(newDBusHelper("")) { diff --git a/pkg/keychain/helper_windows.go b/pkg/keychain/helper_windows.go index 506601d9..6ac141ff 100644 --- a/pkg/keychain/helper_windows.go +++ b/pkg/keychain/helper_windows.go @@ -25,7 +25,7 @@ import ( const WindowsCredentials = "windows-credentials" -func listHelpers(_ bool) (Helpers, string) { +func listHelpers() (Helpers, string) { helpers := make(Helpers) // Windows always provides a keychain. if isUsable(newWinCredHelper("")) { diff --git a/pkg/keychain/keychain.go b/pkg/keychain/keychain.go index d734f398..efa0236b 100644 --- a/pkg/keychain/keychain.go +++ b/pkg/keychain/keychain.go @@ -62,9 +62,9 @@ type List struct { // NewList checks availability of every keychains detected on the User Operating System // This will ask the user to unlock keychain(s) to check their usability. // This should only be called once. -func NewList(skipKeychainTest bool) *List { +func NewList() *List { var list = List{locker: &sync.Mutex{}} - list.helpers, list.defaultHelper = listHelpers(skipKeychainTest) + list.helpers, list.defaultHelper = listHelpers() return &list } @@ -210,7 +210,7 @@ func (kc *Keychain) secretURL(userID string) string { } // isUsable returns whether the credentials helper is usable. -func isUsable(helper credentials.Helper, err error) bool { +func isUsable(helper credentials.Helper, err error) bool { //nolint:unused l := logrus.WithField("helper", reflect.TypeOf(helper)) if err != nil { @@ -240,7 +240,7 @@ func isUsable(helper credentials.Helper, err error) bool { return true } -func getTestCredentials() *credentials.Credentials { +func getTestCredentials() *credentials.Credentials { //nolint:unused // On macOS, a handful of users experience failures of the test credentials. if runtime.GOOS == "darwin" { return &credentials.Credentials{ @@ -257,7 +257,7 @@ func getTestCredentials() *credentials.Credentials { } } -func retry(condition func() error) error { +func retry(condition func() error) error { //nolint:unused var maxRetry = 5 for r := 0; ; r++ { err := condition() diff --git a/pkg/keychain/keychain_test.go b/pkg/keychain/keychain_test.go index 62ee659d..becbb4d3 100644 --- a/pkg/keychain/keychain_test.go +++ b/pkg/keychain/keychain_test.go @@ -117,7 +117,7 @@ func TestInsertReadRemove(t *testing.T) { func TestIsErrKeychainNoItem(t *testing.T) { r := require.New(t) - helpers := NewList(false).GetHelpers() + helpers := NewList().GetHelpers() for helperName := range helpers { kc, err := NewKeychain(helperName, "bridge-test", helpers, helperName) diff --git a/utils/bridge-rollout/bridge-rollout.go b/utils/bridge-rollout/bridge-rollout.go index becf8b4f..fc9d4b7d 100644 --- a/utils/bridge-rollout/bridge-rollout.go +++ b/utils/bridge-rollout/bridge-rollout.go @@ -61,7 +61,7 @@ func main() { func getRollout(_ *cli.Context) error { return app.WithLocations(func(locations *locations.Locations) error { - return app.WithKeychainList(async.NoopPanicHandler{}, false, func(keychains *keychain.List) error { + return app.WithKeychainList(async.NoopPanicHandler{}, func(keychains *keychain.List) error { return app.WithVault(nil, locations, keychains, async.NoopPanicHandler{}, func(vault *vault.Vault, _, _ bool) error { fmt.Println(vault.GetUpdateRollout()) return nil @@ -72,7 +72,7 @@ func getRollout(_ *cli.Context) error { func setRollout(c *cli.Context) error { return app.WithLocations(func(locations *locations.Locations) error { - return app.WithKeychainList(async.NoopPanicHandler{}, false, func(keychains *keychain.List) error { + return app.WithKeychainList(async.NoopPanicHandler{}, func(keychains *keychain.List) error { return app.WithVault(nil, locations, keychains, async.NoopPanicHandler{}, func(vault *vault.Vault, _, _ bool) error { clamped := max(0.0, min(1.0, c.Float64("value"))) if err := vault.SetUpdateRollout(clamped); err != nil { diff --git a/utils/vault-editor/main.go b/utils/vault-editor/main.go index 91d3bfdc..8acebe9d 100644 --- a/utils/vault-editor/main.go +++ b/utils/vault-editor/main.go @@ -51,7 +51,7 @@ func main() { func readAction(c *cli.Context) error { return app.WithLocations(func(locations *locations.Locations) error { - return app.WithKeychainList(async.NoopPanicHandler{}, false, func(keychains *keychain.List) error { + return app.WithKeychainList(async.NoopPanicHandler{}, func(keychains *keychain.List) error { return app.WithVault(nil, locations, keychains, async.NoopPanicHandler{}, func(vault *vault.Vault, insecure, corrupt bool) error { if _, err := os.Stdout.Write(vault.ExportJSON()); err != nil { return fmt.Errorf("failed to write vault: %w", err) @@ -65,7 +65,7 @@ func readAction(c *cli.Context) error { func writeAction(c *cli.Context) error { return app.WithLocations(func(locations *locations.Locations) error { - return app.WithKeychainList(async.NoopPanicHandler{}, false, func(keychains *keychain.List) error { + return app.WithKeychainList(async.NoopPanicHandler{}, func(keychains *keychain.List) error { return app.WithVault(nil, locations, keychains, async.NoopPanicHandler{}, func(vault *vault.Vault, insecure, corrupt bool) error { b, err := io.ReadAll(os.Stdin) if err != nil { From 120a7b362608e536502e3c6d79f7df0db82c0456 Mon Sep 17 00:00:00 2001 From: Atanas Janeshliev Date: Wed, 4 Dec 2024 14:44:25 +0100 Subject: [PATCH 46/51] chore: Erasmus Bridge 3.15.1 changelog. --- Changelog.md | 6 ++++++ Makefile | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 5d663793..78ef49a0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,12 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Erasmus Bridge 3.15.1 + +### Changed +* BRIDGE-281: Disable keychain test on macOS. + + ## Erasmus Bridge 3.15.0 ### Added diff --git a/Makefile b/Makefile index 9e373cdb..de2d9a44 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ ROOT_DIR:=$(realpath .) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.15.0+git +BRIDGE_APP_VERSION?=3.15.1+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From 10a685a1233a0629335778a7b7dc26089197da0a Mon Sep 17 00:00:00 2001 From: Gabor Meszaros Date: Mon, 16 Dec 2024 10:47:24 +0000 Subject: [PATCH 47/51] chore: Prepare for issue tracker removal --- .../ISSUE_TEMPLATE/general-issue-template.md | 41 ---------- CONTRIBUTING.md | 82 +++++++++++++++++-- 2 files changed, 75 insertions(+), 48 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/general-issue-template.md diff --git a/.github/ISSUE_TEMPLATE/general-issue-template.md b/.github/ISSUE_TEMPLATE/general-issue-template.md deleted file mode 100644 index 6eaaefe3..00000000 --- a/.github/ISSUE_TEMPLATE/general-issue-template.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: General issue template -about: Template for detailed report of issues -title: '' -labels: '' -assignees: '' - ---- - -Issue tracker is ONLY used for reporting bugs with technical details. "It doesn't work" or new features should be discussed with our customer support. Please use bug report function in Bridge or contact bridge@protonmail.ch. - - -## Expected Behavior - - -## Current Behavior - - -## Possible Solution - - -## Steps to Reproduce - - -1. -2. -3. -4. - -## Version Information - - -## Context (Environment) - - - -## Detailed Description - - -## Possible Implementation - diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ea729c2f..62cc0b84 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,10 +1,78 @@ -# Contribution Policy +# Contributing guidelines + +The following document describes how to contribute to the project. In this context, contribution does not only mean code contribution but also reporting issues, requesting new features, or just asking for help. + +## Reporting issues + +In case you experience issues while using the application, our request is to contact Proton customer support directly. + +The benefits of using Proton customer support are + +- Available 24/7/365. +- Provides priority support based on subscription type. +- Will escalate the issue to the developers every time it becomes too technical or they do not know the answer to a question. +- Easier to detect systematic issues by connecting similar reports. +- Possible to quickly derive frequency of an issue. +- Can assist you to transfer sensitive information safely to us. + +To speed up the communication with customer support, consider the following: + +- Whenever is possible, use the in-app bug report feature. It provides an application specific guide compared to using the generic report form on web. +- Whenever is possible, proactively attach logs to your report. Reporting an issue from the application can help you in that. +- Check whether your system is officially supported by Proton, including the source of the installer. We cannot provide help when the application is packaged by a third party or when the application is used on systems that we do not prepare to support. +- If your report is a feature request, see the Feature request section. In case it is an issue related to application security, see the Security vulnerabilities section. + +In the past, we used GitHub issue tracker for more technical issues in parallel to Proton customer support, but we run into limitations with this approach: + +- Monitoring GitHub issue tracker took development time as it was managed by the development team. +- It made issue frequency tracking challenging because we did not have a single point of entry for issues. +- Users were confused what technical issue means, and used the GitHub issue tracker for feature requests, or non-technical discussions. +- Users sometimes shared sensitive data through the GitHub issue tracker. + +For the above reasons, we do not use GitHub issue tracker anymore but ask you to contact our customer support in case you run into a problem. + +### Security vulnerabilities + +Proton runs a bug bounty program for security vulnerabilities. They differ from normal bug reports in the following ways: + +- These reports go directly to our security team. +- They expect deeper explanation of the issue. +- Depending on the finding, they may be financially rewarded. + +More information about the program can be found [here](https://proton.me/security/bug-bounty). + +## Feature requests + +What someone considers as a bug is sometimes a feature, and sometimes, a missing feature is considered as a bug. Instead of reporting feature requests as bugs, we setup a UserVoice page to allow our users to share their preferences. UserVoice also makes it possible to vote on other feature requests, making the community preference public. + +Our product team frequently monitors UserVoice, and the features listed there are taken into account in our planning. + +Examples for UserVoice requests: + +- Extending the officially supported environments (e.g., operating systems, clients, or computer architectures). +- Requesting new features. +- Integration with non-Proton services. + +UserVoice is available [here](https://protonmail.uservoice.com/). + +## Asking for help + +The best ways to get answer for generic questions or to get help with setting up the system is to interact with our active community on [Reddit](https://reddit.com/r/ProtonMail/) or to contact customer support. + +## Code contribution + +We are grateful if you can contribute directly with code. In that case there is nothing else to do than to open a pull request. + +The following is worthwhile noting + +- The project is primarily developed on an internal repository, and the one on GitHub is only a mirror of it. For that reason, the merge request will not be merged on GitHub but added to the project internally. We are keeping the original author in the change set to respect the contribution. +- The application is used on numerous platforms and by many third party clients. To have higher chance your change to be accepted, consider all supported dependencies. +- Give detailed description of the issue, preferably with test steps to reproduce the original issue, and to verify the fix. It is even better if you also extend the automated tests. + +### Contribution policy By making a contribution to this project: -1. I assign any and all copyright related to the contribution to Proton AG; -2. I certify that the contribution was created in whole by me; -3. I understand and agree that this project and the contribution are public - and that a record of the contribution (including all personal information I - submit with it) is maintained indefinitely and may be redistributed with - this project or the open source license(s) involved. +1. You assign any and all copyright related to the contribution to Proton AG; +2. You certify that the contribution was created in whole by you; +3. You understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information you submit with it) is maintained indefinitely and may be redistributed with this project or the open source license(s) involved. From 8e634995c543c56fe3e4d08e232a2b6904b759ae Mon Sep 17 00:00:00 2001 From: Atanas Janeshliev Date: Tue, 21 Jan 2025 14:42:52 +0100 Subject: [PATCH 48/51] chore: Grunwald Bridge 3.17.0 changelog. --- Changelog.md | 19 +++++++++++++++++++ Makefile | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 8aa9ee69..66ca9819 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,25 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Grunwald Bridge 3.17.0 + +### Added +* BRIDGE-271: Report version file check failure to Sentry. +* BRIDGE-247: Test: Automate Bridge 0% update rollout. +* BRIDGE-248: Test: Additional Bridge UI e2e automation tests. + +### Changed +* BRIDGE-73: Update goopenpgp. +* BRIDGE-287: Update x/net and x/crypto dependencies. +* BRIDGE-303: Update govulncheck to latest release. +* BRIDGE-226: Bump Go version to 1.23.4. +* BRIDGE-288: Extension to synchronization update handler, observability tweaks and gluon update. + +### Fixed +* BRIDGE-291: Use correct field for user plan type. +* BRIDGE-143: Add missing QML component attribute, cut/paste disabled on read-only text areas. + + ## Flavien Bridge 3.16.0 ### Added diff --git a/Makefile b/Makefile index 2c6e02e9..82cf06c3 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ ROOT_DIR:=$(realpath .) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.16.0+git +BRIDGE_APP_VERSION?=3.17.0+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From d44c488ed597a4e2ec2850384208035cbe94e5c9 Mon Sep 17 00:00:00 2001 From: Atanas Janeshliev Date: Tue, 11 Feb 2025 10:28:05 +0100 Subject: [PATCH 49/51] chore: minor comment just so we have a new commit --- utils/vault-editor/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/vault-editor/main.go b/utils/vault-editor/main.go index 37622684..1c20e470 100644 --- a/utils/vault-editor/main.go +++ b/utils/vault-editor/main.go @@ -19,6 +19,7 @@ package main +// Minor comment on vault editor DELETE ME. import ( "fmt" "io" From 0800aeea50ee8a474e64355a4b7df124c0bcee91 Mon Sep 17 00:00:00 2001 From: Atanas Janeshliev Date: Tue, 18 Feb 2025 23:44:44 +0100 Subject: [PATCH 50/51] chore: Helix Bridge 3.18.0 changelog. --- Changelog.md | 7 +++++++ Makefile | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 66ca9819..c0796f7b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,13 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Helix Bridge 3.18.0 + +### Changed +* BRIDGE-309: Revised update logic and structure. +* BRIDGE-154: Added access token to expiry refresh request. + + ## Grunwald Bridge 3.17.0 ### Added diff --git a/Makefile b/Makefile index 82cf06c3..c3235100 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ ROOT_DIR:=$(realpath .) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.17.0+git +BRIDGE_APP_VERSION?=3.18.0+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG From 9f4801b7388582c63adc5f607bd5c7b01fd17806 Mon Sep 17 00:00:00 2001 From: Atanas Janeshliev Date: Fri, 7 Mar 2025 11:12:59 +0100 Subject: [PATCH 51/51] chore: Infinity Bridge 3.19.0 changelog. --- Changelog.md | 6 ++++++ Makefile | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index c0796f7b..89377eed 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,12 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Infinity Bridge 3.19.0 + +### Changed +* BRIDGE-316: Update Qt to latest LTS version 6.8.2. + + ## Helix Bridge 3.18.0 ### Changed diff --git a/Makefile b/Makefile index 46dc5133..edc7e63c 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ ROOT_DIR:=$(realpath .) .PHONY: build build-gui build-nogui build-launcher versioner hasher # Keep version hardcoded so app build works also without Git repository. -BRIDGE_APP_VERSION?=3.18.0+git +BRIDGE_APP_VERSION?=3.19.0+git APP_VERSION:=${BRIDGE_APP_VERSION} APP_FULL_NAME:=Proton Mail Bridge APP_VENDOR:=Proton AG