mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-10 04:36:43 +00:00
feat(BRIDGE-348): display BYOE addresses in Bridge
This commit is contained in:
2
go.mod
2
go.mod
@ -9,7 +9,7 @@ require (
|
|||||||
github.com/Masterminds/semver/v3 v3.2.0
|
github.com/Masterminds/semver/v3 v3.2.0
|
||||||
github.com/ProtonMail/gluon v0.17.1-0.20250324123053-2abce471ad71
|
github.com/ProtonMail/gluon v0.17.1-0.20250324123053-2abce471ad71
|
||||||
github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a
|
github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a
|
||||||
github.com/ProtonMail/go-proton-api v0.4.1-0.20250217140732-2e531f21de4c
|
github.com/ProtonMail/go-proton-api v0.4.1-0.20250410050801-92de6e7c8517
|
||||||
github.com/ProtonMail/gopenpgp/v2 v2.8.2-proton
|
github.com/ProtonMail/gopenpgp/v2 v2.8.2-proton
|
||||||
github.com/PuerkitoBio/goquery v1.8.1
|
github.com/PuerkitoBio/goquery v1.8.1
|
||||||
github.com/abiosoft/ishell v2.0.0+incompatible
|
github.com/abiosoft/ishell v2.0.0+incompatible
|
||||||
|
|||||||
6
go.sum
6
go.sum
@ -47,6 +47,12 @@ github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ek
|
|||||||
github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw=
|
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.20250217140732-2e531f21de4c h1:dxnbB+ov77BDj1LC35fKZ14hLoTpU6OTpZySwxarVx0=
|
github.com/ProtonMail/go-proton-api v0.4.1-0.20250217140732-2e531f21de4c h1:dxnbB+ov77BDj1LC35fKZ14hLoTpU6OTpZySwxarVx0=
|
||||||
github.com/ProtonMail/go-proton-api v0.4.1-0.20250217140732-2e531f21de4c/go.mod h1:RYgagBFkA3zFrSt7/vviFFwjZxBo6pGzcTwFsLwsnyc=
|
github.com/ProtonMail/go-proton-api v0.4.1-0.20250217140732-2e531f21de4c/go.mod h1:RYgagBFkA3zFrSt7/vviFFwjZxBo6pGzcTwFsLwsnyc=
|
||||||
|
github.com/ProtonMail/go-proton-api v0.4.1-0.20250409092940-13ddc20a05a1 h1:u3G9UB8prOnzOneOf0JFCIVnMRLiK4QgEpPQVu9Y8Q4=
|
||||||
|
github.com/ProtonMail/go-proton-api v0.4.1-0.20250409092940-13ddc20a05a1/go.mod h1:RYgagBFkA3zFrSt7/vviFFwjZxBo6pGzcTwFsLwsnyc=
|
||||||
|
github.com/ProtonMail/go-proton-api v0.4.1-0.20250409131808-0bbc8e7c32db h1:mOtbY5BB2eNr2QmbZhFn5EnsJcimTntPB6akN2r+AuE=
|
||||||
|
github.com/ProtonMail/go-proton-api v0.4.1-0.20250409131808-0bbc8e7c32db/go.mod h1:RYgagBFkA3zFrSt7/vviFFwjZxBo6pGzcTwFsLwsnyc=
|
||||||
|
github.com/ProtonMail/go-proton-api v0.4.1-0.20250410050801-92de6e7c8517 h1:70JoDgXxfil4hbDoYGF98rMd47Rld6wXWyFAw4uFOTY=
|
||||||
|
github.com/ProtonMail/go-proton-api v0.4.1-0.20250410050801-92de6e7c8517/go.mod h1:RYgagBFkA3zFrSt7/vviFFwjZxBo6pGzcTwFsLwsnyc=
|
||||||
github.com/ProtonMail/go-smtp v0.0.0-20231109081432-2b3d50599865 h1:EP1gnxLL5Z7xBSymE9nSTM27nRYINuvssAtDmG0suD8=
|
github.com/ProtonMail/go-smtp v0.0.0-20231109081432-2b3d50599865 h1:EP1gnxLL5Z7xBSymE9nSTM27nRYINuvssAtDmG0suD8=
|
||||||
github.com/ProtonMail/go-smtp v0.0.0-20231109081432-2b3d50599865/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ=
|
github.com/ProtonMail/go-smtp v0.0.0-20231109081432-2b3d50599865/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ=
|
||||||
github.com/ProtonMail/go-srp v0.0.7 h1:Sos3Qk+th4tQR64vsxGIxYpN3rdnG9Wf9K4ZloC1JrI=
|
github.com/ProtonMail/go-srp v0.0.7 h1:Sos3Qk+th4tQR64vsxGIxYpN3rdnG9Wf9K4ZloC1JrI=
|
||||||
|
|||||||
@ -618,7 +618,7 @@ func TestBridge_AddressWithoutKeys(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Create an additional address for the user; it will not have keys.
|
// Create an additional address for the user; it will not have keys.
|
||||||
aliasAddrID, err := s.CreateAddress(userID, "alias@pm.me", []byte("password"))
|
aliasAddrID, err := s.CreateAddress(userID, "alias@pm.me", []byte("password"), true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Create an API client so we can remove the address keys.
|
// Create an API client so we can remove the address keys.
|
||||||
@ -785,7 +785,7 @@ func TestBridge_ChangeAddressOrder(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Create a second address for the user.
|
// Create a second address for the user.
|
||||||
aliasID, err := s.CreateAddress(userID, "alias@"+s.GetDomain(), password)
|
aliasID, err := s.CreateAddress(userID, "alias@"+s.GetDomain(), password, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Create 10 messages for the user.
|
// Create 10 messages for the user.
|
||||||
|
|||||||
@ -355,7 +355,7 @@ func TestBridge_CanProcessEventsDuringSync(t *testing.T) {
|
|||||||
|
|
||||||
// Create a new address
|
// Create a new address
|
||||||
newAddress := "foo@proton.ch"
|
newAddress := "foo@proton.ch"
|
||||||
addrID, err := s.CreateAddress(userID, newAddress, password)
|
addrID, err := s.CreateAddress(userID, newAddress, password, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
event := <-addressCreatedCh
|
event := <-addressCreatedCh
|
||||||
@ -430,7 +430,7 @@ func TestBridge_EventReplayAfterSyncHasFinished(t *testing.T) {
|
|||||||
createNumMessages(ctx, t, c, addrID, labelID, numMsg)
|
createNumMessages(ctx, t, c, addrID, labelID, numMsg)
|
||||||
})
|
})
|
||||||
|
|
||||||
addrID1, err := s.CreateAddress(userID, "foo@proton.ch", password)
|
addrID1, err := s.CreateAddress(userID, "foo@proton.ch", password, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var allowSyncToProgress atomic.Bool
|
var allowSyncToProgress atomic.Bool
|
||||||
@ -469,7 +469,7 @@ func TestBridge_EventReplayAfterSyncHasFinished(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// User AddrID2 event as a check point to see when the new address was created.
|
// User AddrID2 event as a check point to see when the new address was created.
|
||||||
addrID2, err := s.CreateAddress(userID, "bar@proton.ch", password)
|
addrID2, err := s.CreateAddress(userID, "bar@proton.ch", password, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
allowSyncToProgress.Store(true)
|
allowSyncToProgress.Store(true)
|
||||||
@ -552,7 +552,7 @@ func TestBridge_MessageCreateDuringSync(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// User AddrID2 event as a check point to see when the new address was created.
|
// User AddrID2 event as a check point to see when the new address was created.
|
||||||
addrID, err := s.CreateAddress(userID, "bar@proton.ch", password)
|
addrID, err := s.CreateAddress(userID, "bar@proton.ch", password, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// At most two events can be published, one for the first address, then for the second.
|
// At most two events can be published, one for the first address, then for the second.
|
||||||
@ -663,7 +663,7 @@ func TestBridge_AddressOrderChangeDuringSyncInCombinedModeDoesNotTriggerBadEvent
|
|||||||
require.Equal(t, 1, len(info.Addresses))
|
require.Equal(t, 1, len(info.Addresses))
|
||||||
require.Equal(t, info.Addresses[0], "user@proton.local")
|
require.Equal(t, info.Addresses[0], "user@proton.local")
|
||||||
|
|
||||||
addrID2, err := s.CreateAddress(userID, "foo@"+s.GetDomain(), password)
|
addrID2, err := s.CreateAddress(userID, "foo@"+s.GetDomain(), password, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.NoError(t, s.SetAddressOrder(userID, []string{addrID2, addrID}))
|
require.NoError(t, s.SetAddressOrder(userID, []string{addrID2, addrID}))
|
||||||
|
|||||||
@ -304,7 +304,7 @@ func TestBridge_User_AddressEvents_NoBadEvent(t *testing.T) {
|
|||||||
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, _ *bridge.Mocks) {
|
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, _ *bridge.Mocks) {
|
||||||
userLoginAndSync(ctx, t, bridge, "user", password)
|
userLoginAndSync(ctx, t, bridge, "user", password)
|
||||||
|
|
||||||
addrID, err = s.CreateAddress(userID, "other@pm.me", password)
|
addrID, err = s.CreateAddress(userID, "other@pm.me", password, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
userContinueEventProcess(ctx, t, s, bridge)
|
userContinueEventProcess(ctx, t, s, bridge)
|
||||||
|
|
||||||
@ -312,7 +312,7 @@ func TestBridge_User_AddressEvents_NoBadEvent(t *testing.T) {
|
|||||||
userContinueEventProcess(ctx, t, s, bridge)
|
userContinueEventProcess(ctx, t, s, bridge)
|
||||||
})
|
})
|
||||||
|
|
||||||
otherID, err := s.CreateAddress(userID, "another@pm.me", password)
|
otherID, err := s.CreateAddress(userID, "another@pm.me", password, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, s.RemoveAddress(userID, otherID))
|
require.NoError(t, s.RemoveAddress(userID, otherID))
|
||||||
|
|
||||||
@ -328,6 +328,87 @@ func TestBridge_User_AddressEvents_NoBadEvent(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBridge_User_AddressEvents_BYOEAddressAdded(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) {
|
||||||
|
userLoginAndSync(ctx, t, bridge, "user", password)
|
||||||
|
|
||||||
|
// Create an additional proton address
|
||||||
|
addrID, err = s.CreateAddress(userID, "other@pm.me", password, true)
|
||||||
|
require.NoError(t, err)
|
||||||
|
userContinueEventProcess(ctx, t, s, bridge)
|
||||||
|
require.NoError(t, s.AddAddressCreatedEvent(userID, addrID))
|
||||||
|
userContinueEventProcess(ctx, t, s, bridge)
|
||||||
|
|
||||||
|
userInfo, err := bridge.GetUserInfo(userID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 2, len(userInfo.Addresses))
|
||||||
|
|
||||||
|
// Create an external address with sending disabled.
|
||||||
|
externalID, err := s.CreateExternalAddress(userID, "another@yahoo.com", password, false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
userContinueEventProcess(ctx, t, s, bridge)
|
||||||
|
require.NoError(t, s.AddAddressCreatedEvent(userID, externalID))
|
||||||
|
userContinueEventProcess(ctx, t, s, bridge)
|
||||||
|
|
||||||
|
// User addresses should still return 2, as we ignore the external address.
|
||||||
|
userInfo, err = bridge.GetUserInfo(userID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 2, len(userInfo.Addresses))
|
||||||
|
|
||||||
|
// Create an external address w. sending enabled. This is considered a BYOE address.
|
||||||
|
BYOEAddrID, err := s.CreateExternalAddress(userID, "other@yahoo.com", password, true)
|
||||||
|
require.NoError(t, err)
|
||||||
|
userContinueEventProcess(ctx, t, s, bridge)
|
||||||
|
require.NoError(t, s.AddAddressCreatedEvent(userID, BYOEAddrID))
|
||||||
|
userContinueEventProcess(ctx, t, s, bridge)
|
||||||
|
|
||||||
|
userInfo, err = bridge.GetUserInfo(userID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 3, len(userInfo.Addresses))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBridge_User_AddressEvents_ExternalAddressSendChanged(t *testing.T) {
|
||||||
|
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
|
||||||
|
userID, _, err := s.CreateUser("user", password)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, _ *bridge.Mocks) {
|
||||||
|
userLoginAndSync(ctx, t, bridge, "user", password)
|
||||||
|
|
||||||
|
// Create an additional external address.
|
||||||
|
externalID, err := s.CreateExternalAddress(userID, "other@yahoo.me", password, false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
userContinueEventProcess(ctx, t, s, bridge)
|
||||||
|
require.NoError(t, s.AddAddressCreatedEvent(userID, externalID))
|
||||||
|
userContinueEventProcess(ctx, t, s, bridge)
|
||||||
|
|
||||||
|
// We expect only one address, the external one without sending should not be considered a valid address.
|
||||||
|
userInfo, err := bridge.GetUserInfo(userID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 1, len(userInfo.Addresses))
|
||||||
|
|
||||||
|
// Change it to allow sending such that it becomes a BYOE address.
|
||||||
|
err = s.ChangeAddressAllowSend(userID, externalID, true)
|
||||||
|
require.NoError(t, err)
|
||||||
|
userContinueEventProcess(ctx, t, s, bridge)
|
||||||
|
require.NoError(t, s.AddAddressUpdatedEvent(userID, externalID))
|
||||||
|
userContinueEventProcess(ctx, t, s, bridge)
|
||||||
|
|
||||||
|
// We should now have 2 usable addresses listed.
|
||||||
|
userInfo, err = bridge.GetUserInfo(userID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 2, len(userInfo.Addresses))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestBridge_User_AddressEventUpdatedForAddressThatDoesNotExist_NoBadEvent(t *testing.T) {
|
func TestBridge_User_AddressEventUpdatedForAddressThatDoesNotExist_NoBadEvent(t *testing.T) {
|
||||||
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
|
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
|
||||||
// Create a user.
|
// Create a user.
|
||||||
@ -694,7 +775,7 @@ func TestBridge_User_DisableEnableAddress(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Create an additional address for the user.
|
// Create an additional address for the user.
|
||||||
aliasID, err := s.CreateAddress(userID, "alias@"+s.GetDomain(), password)
|
aliasID, err := s.CreateAddress(userID, "alias@"+s.GetDomain(), password, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, _ *bridge.Mocks) {
|
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, _ *bridge.Mocks) {
|
||||||
@ -745,7 +826,7 @@ func TestBridge_User_CreateDisabledAddress(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Create an additional address for the user.
|
// Create an additional address for the user.
|
||||||
aliasID, err := s.CreateAddress(userID, "alias@"+s.GetDomain(), password)
|
aliasID, err := s.CreateAddress(userID, "alias@"+s.GetDomain(), password, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Immediately disable the address.
|
// Immediately disable the address.
|
||||||
|
|||||||
@ -658,7 +658,7 @@ func TestBridge_UserInfo_Alias(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Give the new user an alias.
|
// Give the new user an alias.
|
||||||
require.NoError(t, getErr(s.CreateAddress(userID, "alias@pm.me", []byte("password"))))
|
require.NoError(t, getErr(s.CreateAddress(userID, "alias@pm.me", []byte("password"), true)))
|
||||||
|
|
||||||
// Login the user.
|
// Login the user.
|
||||||
require.NoError(t, getErr(bridge.LoginFull(ctx, "primary", []byte("password"), nil, nil)))
|
require.NoError(t, getErr(bridge.LoginFull(ctx, "primary", []byte("password"), nil, nil)))
|
||||||
@ -706,7 +706,7 @@ func TestBridge_User_GetAddresses(t *testing.T) {
|
|||||||
// Create a user.
|
// Create a user.
|
||||||
userID, _, err := s.CreateUser("user", password)
|
userID, _, err := s.CreateUser("user", password)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
addrID2, err := s.CreateAddress(userID, "user@external.com", []byte("password"))
|
addrID2, err := s.CreateAddress(userID, "user@external.com", password, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, s.ChangeAddressType(userID, addrID2, proton.AddressTypeExternal))
|
require.NoError(t, s.ChangeAddressType(userID, addrID2, proton.AddressTypeExternal))
|
||||||
|
|
||||||
@ -720,6 +720,29 @@ func TestBridge_User_GetAddresses(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBridge_User_GetAddresses_BYOE(t *testing.T) {
|
||||||
|
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
|
||||||
|
// Create a user.
|
||||||
|
userID, _, err := s.CreateUser("user", password)
|
||||||
|
require.NoError(t, err)
|
||||||
|
// Add a non-sending external address.
|
||||||
|
_, err = s.CreateExternalAddress(userID, "user@external.com", password, false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
// Add a BYOE address.
|
||||||
|
_, err = s.CreateExternalAddress(userID, "user2@external.com", password, true)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, _ *bridge.Mocks) {
|
||||||
|
userLoginAndSync(ctx, t, bridge, "user", password)
|
||||||
|
info, err := bridge.GetUserInfo(userID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 2, len(info.Addresses))
|
||||||
|
require.Equal(t, info.Addresses[0], "user@proton.local")
|
||||||
|
require.Equal(t, info.Addresses[1], "user2@external.com")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// getErr returns the error that was passed to it.
|
// getErr returns the error that was passed to it.
|
||||||
func getErr[T any](_ T, err error) error {
|
func getErr[T any](_ T, err error) error {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@ -739,7 +739,7 @@ func (user *User) protonAddresses() []proton.Address {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addresses := xslices.Filter(maps.Values(apiAddrs), func(addr proton.Address) bool {
|
addresses := xslices.Filter(maps.Values(apiAddrs), func(addr proton.Address) bool {
|
||||||
return addr.Status == proton.AddressStatusEnabled && addr.Type != proton.AddressTypeExternal
|
return addr.Status == proton.AddressStatusEnabled && (addr.IsBYOEAddress() || addr.Type != proton.AddressTypeExternal)
|
||||||
})
|
})
|
||||||
|
|
||||||
slices.SortFunc(addresses, func(a, b proton.Address) bool {
|
slices.SortFunc(addresses, func(a, b proton.Address) bool {
|
||||||
|
|||||||
@ -110,7 +110,7 @@ func withAccount(tb testing.TB, s *server.Server, username, password string, ali
|
|||||||
addrIDs := []string{addrID}
|
addrIDs := []string{addrID}
|
||||||
|
|
||||||
for _, email := range aliases {
|
for _, email := range aliases {
|
||||||
addrID, err := s.CreateAddress(userID, email, []byte(password))
|
addrID, err := s.CreateAddress(userID, email, []byte(password), true)
|
||||||
require.NoError(tb, err)
|
require.NoError(tb, err)
|
||||||
require.NoError(tb, s.ChangeAddressDisplayName(userID, addrID, email+" (Display Name)"))
|
require.NoError(tb, s.ChangeAddressDisplayName(userID, addrID, email+" (Display Name)"))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user