mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-17 23:56:56 +00:00
fix(GODT-3129): Bad Event during after address order change
When syncing an account, if the user creates a new address and then changes it to be the default address in combined address mode we need to update the connector maps so that the new primary address ID can be found in that map. Includes https://github.com/ProtonMail/go-proton-api/pull/130
This commit is contained in:
@ -641,6 +641,55 @@ func TestBridge_CorruptedVaultClearsPreviousIMAPSyncState(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestBridge_AddressOrderChangeDuringSyncInCombinedModeDoesNotTriggerBadEventOnNewMessage(t *testing.T) {
|
||||
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
|
||||
// Create a user.
|
||||
userID, addrID, err := s.CreateUser("user", password)
|
||||
require.NoError(t, err)
|
||||
|
||||
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, _ *bridge.Mocks) {
|
||||
userInfoChanged, done := chToType[events.Event, events.UserChanged](bridge.GetEvents(events.UserChanged{}))
|
||||
defer done()
|
||||
|
||||
withClient(ctx, t, s, "user", password, func(ctx context.Context, c *proton.Client) {
|
||||
createNumMessages(ctx, t, c, addrID, proton.InboxLabel, 300)
|
||||
})
|
||||
|
||||
_, err := bridge.LoginFull(ctx, "user", password, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
info, err := bridge.GetUserInfo(userID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(info.Addresses))
|
||||
require.Equal(t, info.Addresses[0], "user@proton.local")
|
||||
|
||||
addrID2, err := s.CreateAddress(userID, "foo@"+s.GetDomain(), password)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, s.SetAddressOrder(userID, []string{addrID2, addrID}))
|
||||
|
||||
withClient(ctx, t, s, "user", password, func(ctx context.Context, c *proton.Client) {
|
||||
createNumMessages(ctx, t, c, addrID2, proton.InboxLabel, 1)
|
||||
})
|
||||
|
||||
// Since we can't intercept events at this time, we sleep for a bit to make sure the
|
||||
// new message does not get combined into the event below. This ensures the newly created
|
||||
// goes through the full code flow which triggered the original bad event.
|
||||
time.Sleep(time.Second)
|
||||
require.NoError(t, s.SetAddressOrder(userID, []string{addrID, addrID2}))
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case e := <-userInfoChanged:
|
||||
require.Equal(t, userID, e.UserID)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
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()),
|
||||
|
||||
@ -274,6 +274,10 @@ func (s *Service) HandleRefreshEvent(ctx context.Context, _ proton.RefreshFlag)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.rebuildConnectors(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.syncStateProvider.ClearSyncStatus(ctx); err != nil {
|
||||
return fmt.Errorf("failed to clear sync status:%w", err)
|
||||
}
|
||||
@ -292,6 +296,7 @@ func (s *Service) HandleUserEvent(_ context.Context, user *proton.User) error {
|
||||
|
||||
return s.identityState.Write(func(identity *useridentity.State) error {
|
||||
identity.OnUserEvent(*user)
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@ -24,12 +24,18 @@ import (
|
||||
"github.com/ProtonMail/go-proton-api"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/services/useridentity"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/usertypes"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func (s *Service) HandleAddressEvents(ctx context.Context, events []proton.AddressEvent) error {
|
||||
s.log.Debug("handling address event")
|
||||
|
||||
if s.addressMode == usertypes.AddressModeCombined {
|
||||
oldPrimaryAddr, err := s.identityState.GetPrimaryAddress()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get primary addr: %w", err)
|
||||
}
|
||||
|
||||
if err := s.identityState.Write(func(identity *useridentity.State) error {
|
||||
identity.OnAddressEvents(events)
|
||||
return nil
|
||||
@ -38,6 +44,28 @@ func (s *Service) HandleAddressEvents(ctx context.Context, events []proton.Addre
|
||||
return err
|
||||
}
|
||||
|
||||
newPrimaryAddr, err := s.identityState.GetPrimaryAddress()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get primary addr after update: %w", err)
|
||||
}
|
||||
|
||||
if oldPrimaryAddr.ID == newPrimaryAddr.ID {
|
||||
return nil
|
||||
}
|
||||
|
||||
connector, ok := s.connectors[oldPrimaryAddr.ID]
|
||||
if !ok {
|
||||
return fmt.Errorf("could not find old primary addr conncetor after default address change")
|
||||
}
|
||||
|
||||
s.connectors[newPrimaryAddr.ID] = connector
|
||||
delete(s.connectors, oldPrimaryAddr.ID)
|
||||
|
||||
s.log.WithFields(logrus.Fields{
|
||||
"old": oldPrimaryAddr.Email,
|
||||
"new": newPrimaryAddr.Email,
|
||||
}).Debug("Primary address changed")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user