feat: show activity center notification if user must reveal addressed to join/rejoin the community (#4373)
- show activity center notification if user must reveal addressed to join/rejoin the community - fixed unit test, added validation that ex-owner receive AC notification
This commit is contained in:
parent
8641ec5dd5
commit
19464eb345
|
@ -34,6 +34,7 @@ const (
|
||||||
ActivityCenterNotificationTypeOwnershipLost
|
ActivityCenterNotificationTypeOwnershipLost
|
||||||
ActivityCenterNotificationTypeSetSignerFailed
|
ActivityCenterNotificationTypeSetSignerFailed
|
||||||
ActivityCenterNotificationTypeSetSignerDeclined
|
ActivityCenterNotificationTypeSetSignerDeclined
|
||||||
|
ActivityCenterNotificationTypeShareAccounts
|
||||||
)
|
)
|
||||||
|
|
||||||
type ActivityCenterMembershipStatus int
|
type ActivityCenterMembershipStatus int
|
||||||
|
|
|
@ -41,3 +41,5 @@ var ErrNotEnoughPermissions = errors.New("not enough permissions for this commun
|
||||||
var ErrCannotRemoveOwnerOrAdmin = errors.New("not allowed to remove admin or owner")
|
var ErrCannotRemoveOwnerOrAdmin = errors.New("not allowed to remove admin or owner")
|
||||||
var ErrCannotBanOwnerOrAdmin = errors.New("not allowed to ban admin or owner")
|
var ErrCannotBanOwnerOrAdmin = errors.New("not allowed to ban admin or owner")
|
||||||
var ErrInvalidManageTokensPermission = errors.New("no privileges to manage tokens")
|
var ErrInvalidManageTokensPermission = errors.New("no privileges to manage tokens")
|
||||||
|
var ErrRevealedAccountsAbsent = errors.New("revealed accounts is absent")
|
||||||
|
var ErrNoRevealedAccountsSignature = errors.New("revealed accounts without the signature")
|
||||||
|
|
|
@ -666,3 +666,56 @@ func (s *PersistenceSuite) TestCuratedCommunities() {
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().True(reflect.DeepEqual(communities, setCommunities))
|
s.Require().True(reflect.DeepEqual(communities, setCommunities))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *PersistenceSuite) TestGetCommunityRequestToJoinWithRevealedAddresses() {
|
||||||
|
identity, err := crypto.GenerateKey()
|
||||||
|
s.Require().NoError(err, "crypto.GenerateKey shouldn't give any error")
|
||||||
|
|
||||||
|
clock := uint64(time.Now().Unix())
|
||||||
|
communityID := types.HexBytes{7, 7, 7, 7, 7, 7, 7, 7}
|
||||||
|
revealedAddresses := []string{"address1", "address2", "address3"}
|
||||||
|
chainIds := []uint64{1, 2}
|
||||||
|
publicKey := common.PubkeyToHex(&identity.PublicKey)
|
||||||
|
signature := []byte("test")
|
||||||
|
|
||||||
|
// No data in database
|
||||||
|
_, err = s.db.GetCommunityRequestToJoinWithRevealedAddresses(publicKey, communityID)
|
||||||
|
s.Require().ErrorIs(err, sql.ErrNoRows)
|
||||||
|
|
||||||
|
// RTJ with 2 withoutRevealed Addresses
|
||||||
|
expectedRtj := &RequestToJoin{
|
||||||
|
ID: types.HexBytes{1, 2, 3, 4, 5, 6, 7, 8},
|
||||||
|
PublicKey: publicKey,
|
||||||
|
Clock: clock,
|
||||||
|
CommunityID: communityID,
|
||||||
|
State: RequestToJoinStateAccepted,
|
||||||
|
RevealedAccounts: []*protobuf.RevealedAccount{
|
||||||
|
{
|
||||||
|
Address: revealedAddresses[2],
|
||||||
|
ChainIds: chainIds,
|
||||||
|
IsAirdropAddress: true,
|
||||||
|
Signature: signature,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err = s.db.SaveRequestToJoin(expectedRtj)
|
||||||
|
s.Require().NoError(err, "SaveRequestToJoin shouldn't give any error")
|
||||||
|
|
||||||
|
// check that there will be no error if revealed account is absent
|
||||||
|
rtjResult, err := s.db.GetCommunityRequestToJoinWithRevealedAddresses(publicKey, communityID)
|
||||||
|
s.Require().NoError(err, "RevealedAccounts empty, shouldn't give any error")
|
||||||
|
|
||||||
|
s.Require().Len(rtjResult.RevealedAccounts, 0)
|
||||||
|
|
||||||
|
// save revealed accounts for previous request to join
|
||||||
|
err = s.db.SaveRequestToJoinRevealedAddresses(expectedRtj.ID, expectedRtj.RevealedAccounts)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
rtjResult, err = s.db.GetCommunityRequestToJoinWithRevealedAddresses(publicKey, communityID)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Equal(expectedRtj.ID, rtjResult.ID)
|
||||||
|
s.Require().Equal(expectedRtj.PublicKey, rtjResult.PublicKey)
|
||||||
|
s.Require().Equal(expectedRtj.Clock, rtjResult.Clock)
|
||||||
|
s.Require().Equal(expectedRtj.CommunityID, rtjResult.CommunityID)
|
||||||
|
s.Require().Len(rtjResult.RevealedAccounts, 1)
|
||||||
|
}
|
||||||
|
|
|
@ -2,13 +2,15 @@ package protocol
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
gethcommon "github.com/ethereum/go-ethereum/common"
|
||||||
|
hexutil "github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
|
||||||
gethbridge "github.com/status-im/status-go/eth-node/bridge/geth"
|
gethbridge "github.com/status-im/status-go/eth-node/bridge/geth"
|
||||||
"github.com/status-im/status-go/eth-node/crypto"
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
"github.com/status-im/status-go/eth-node/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
|
@ -37,6 +39,10 @@ type MessengerCommunitiesSignersSuite struct {
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
|
|
||||||
collectiblesServiceMock *CollectiblesServiceMock
|
collectiblesServiceMock *CollectiblesServiceMock
|
||||||
|
|
||||||
|
accountsTestData map[string]string
|
||||||
|
|
||||||
|
mockedBalances map[uint64]map[gethcommon.Address]map[gethcommon.Address]*hexutil.Big // chainID, account, token, balance
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MessengerCommunitiesSignersSuite) SetupTest() {
|
func (s *MessengerCommunitiesSignersSuite) SetupTest() {
|
||||||
|
@ -53,15 +59,23 @@ func (s *MessengerCommunitiesSignersSuite) SetupTest() {
|
||||||
s.shh = gethbridge.NewGethWakuWrapper(shh)
|
s.shh = gethbridge.NewGethWakuWrapper(shh)
|
||||||
s.Require().NoError(shh.Start())
|
s.Require().NoError(shh.Start())
|
||||||
|
|
||||||
s.john = s.newMessenger()
|
aliceAccountAddress := "0x0777100000000000000000000000000000000000"
|
||||||
s.bob = s.newMessenger()
|
bobAccountAddress := "0x0330000000000000000000000000000000000000"
|
||||||
s.alice = s.newMessenger()
|
accountPassword := "QWERTY"
|
||||||
|
|
||||||
|
s.john = s.newMessenger("", []string{})
|
||||||
|
s.bob = s.newMessenger(accountPassword, []string{aliceAccountAddress})
|
||||||
|
s.alice = s.newMessenger(accountPassword, []string{bobAccountAddress})
|
||||||
_, err := s.john.Start()
|
_, err := s.john.Start()
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
_, err = s.bob.Start()
|
_, err = s.bob.Start()
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
_, err = s.alice.Start()
|
_, err = s.alice.Start()
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
s.accountsTestData = make(map[string]string)
|
||||||
|
s.accountsTestData[common.PubkeyToHex(&s.bob.identity.PublicKey)] = bobAccountAddress
|
||||||
|
s.accountsTestData[common.PubkeyToHex(&s.alice.identity.PublicKey)] = aliceAccountAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MessengerCommunitiesSignersSuite) TearDownTest() {
|
func (s *MessengerCommunitiesSignersSuite) TearDownTest() {
|
||||||
|
@ -71,18 +85,25 @@ func (s *MessengerCommunitiesSignersSuite) TearDownTest() {
|
||||||
_ = s.logger.Sync()
|
_ = s.logger.Sync()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MessengerCommunitiesSignersSuite) newMessengerWithKey(privateKey *ecdsa.PrivateKey) *Messenger {
|
func (s *MessengerCommunitiesSignersSuite) newMessenger(password string, walletAddresses []string) *Messenger {
|
||||||
messenger, err := newCommunitiesTestMessenger(s.shh, privateKey, s.logger, nil, nil, s.collectiblesServiceMock)
|
|
||||||
s.Require().NoError(err)
|
|
||||||
|
|
||||||
return messenger
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *MessengerCommunitiesSignersSuite) newMessenger() *Messenger {
|
|
||||||
privateKey, err := crypto.GenerateKey()
|
privateKey, err := crypto.GenerateKey()
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
return s.newMessengerWithKey(privateKey)
|
accountsManagerMock := &AccountManagerMock{}
|
||||||
|
accountsManagerMock.AccountsMap = make(map[string]string)
|
||||||
|
|
||||||
|
for _, walletAddress := range walletAddresses {
|
||||||
|
accountsManagerMock.AccountsMap[walletAddress] = types.EncodeHex(crypto.Keccak256([]byte(password)))
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenManagerMock := &TokenManagerMock{
|
||||||
|
Balances: &s.mockedBalances,
|
||||||
|
}
|
||||||
|
|
||||||
|
messenger, err := newCommunitiesTestMessenger(s.shh, privateKey, s.logger, accountsManagerMock, tokenManagerMock, s.collectiblesServiceMock)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
return messenger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MessengerCommunitiesSignersSuite) createCommunity(controlNode *Messenger) *communities.Community {
|
func (s *MessengerCommunitiesSignersSuite) createCommunity(controlNode *Messenger) *communities.Community {
|
||||||
|
@ -95,18 +116,40 @@ func (s *MessengerCommunitiesSignersSuite) advertiseCommunityTo(controlNode *Mes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MessengerCommunitiesSignersSuite) joinCommunity(controlNode *Messenger, community *communities.Community, user *Messenger) {
|
func (s *MessengerCommunitiesSignersSuite) joinCommunity(controlNode *Messenger, community *communities.Community, user *Messenger) {
|
||||||
request := &requests.RequestToJoinCommunity{CommunityID: community.ID()}
|
accTestData := s.accountsTestData[common.PubkeyToHex(&s.alice.identity.PublicKey)]
|
||||||
|
array64Bytes := common.HashPublicKey(&s.alice.identity.PublicKey)
|
||||||
|
signature := append([]byte{0}, array64Bytes...)
|
||||||
|
|
||||||
|
request := &requests.RequestToJoinCommunity{
|
||||||
|
CommunityID: community.ID(),
|
||||||
|
AddressesToReveal: []string{accTestData},
|
||||||
|
AirdropAddress: accTestData,
|
||||||
|
Signatures: []types.HexBytes{signature},
|
||||||
|
}
|
||||||
|
|
||||||
joinCommunity(&s.Suite, community, controlNode, user, request, "")
|
joinCommunity(&s.Suite, community, controlNode, user, request, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MessengerCommunitiesSignersSuite) joinOnRequestCommunity(controlNode *Messenger, community *communities.Community, user *Messenger) {
|
func (s *MessengerCommunitiesSignersSuite) joinOnRequestCommunity(controlNode *Messenger, community *communities.Community, user *Messenger) {
|
||||||
request := &requests.RequestToJoinCommunity{CommunityID: community.ID()}
|
accTestData := s.accountsTestData[common.PubkeyToHex(&s.alice.identity.PublicKey)]
|
||||||
|
array64Bytes := common.HashPublicKey(&s.alice.identity.PublicKey)
|
||||||
|
signature := append([]byte{0}, array64Bytes...)
|
||||||
|
|
||||||
|
request := &requests.RequestToJoinCommunity{
|
||||||
|
CommunityID: community.ID(),
|
||||||
|
AddressesToReveal: []string{accTestData},
|
||||||
|
AirdropAddress: accTestData,
|
||||||
|
Signatures: []types.HexBytes{signature},
|
||||||
|
}
|
||||||
|
|
||||||
joinOnRequestCommunity(&s.Suite, community, controlNode, user, request)
|
joinOnRequestCommunity(&s.Suite, community, controlNode, user, request)
|
||||||
}
|
}
|
||||||
|
|
||||||
// John crates a community
|
// John crates a community
|
||||||
// Ownership is transferred to Alice
|
// Ownership is transferred to Alice
|
||||||
// Alice kick all members Bob and John rejoins
|
// Alice kick all members Bob and John
|
||||||
|
// Bob automatically rejoin
|
||||||
|
// John receive AC notification to share the address and join to the community
|
||||||
// Bob and John accepts the changes
|
// Bob and John accepts the changes
|
||||||
|
|
||||||
func (s *MessengerCommunitiesSignersSuite) TestControlNodeUpdateSigner() {
|
func (s *MessengerCommunitiesSignersSuite) TestControlNodeUpdateSigner() {
|
||||||
|
@ -193,19 +236,26 @@ func (s *MessengerCommunitiesSignersSuite) TestControlNodeUpdateSigner() {
|
||||||
)
|
)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
// check that John received kick event, also he will receive
|
// check that John received kick event, and AC notification msg created
|
||||||
// request to share RevealedAddresses and send request to join to the control node
|
// John, as ex-owner must manually join the community
|
||||||
_, err = WaitOnSignaledMessengerResponse(
|
_, err = WaitOnSignaledMessengerResponse(
|
||||||
s.john,
|
s.john,
|
||||||
func(r *MessengerResponse) bool {
|
func(r *MessengerResponse) bool {
|
||||||
return len(r.Communities()) > 0 && !r.Communities()[0].HasMember(&s.john.identity.PublicKey)
|
wasKicked := len(r.Communities()) > 0 && !r.Communities()[0].HasMember(&s.john.identity.PublicKey)
|
||||||
|
sharedNotificationExist := false
|
||||||
|
for _, acNotification := range r.ActivityCenterNotifications() {
|
||||||
|
if acNotification.Type == ActivityCenterNotificationTypeShareAccounts {
|
||||||
|
sharedNotificationExist = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wasKicked && sharedNotificationExist
|
||||||
},
|
},
|
||||||
"John was not kicked from the community",
|
"John was not kicked from the community",
|
||||||
)
|
)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
// Alice auto-accept requests to join with RevealedAddresses
|
// Alice auto-accept requests to join with RevealedAddresses
|
||||||
// TODO: please, check TODO's in this test and uncomment them if Members() == 3
|
|
||||||
_, err = WaitOnMessengerResponse(
|
_, err = WaitOnMessengerResponse(
|
||||||
s.alice,
|
s.alice,
|
||||||
func(r *MessengerResponse) bool {
|
func(r *MessengerResponse) bool {
|
||||||
|
@ -243,20 +293,8 @@ func (s *MessengerCommunitiesSignersSuite) TestControlNodeUpdateSigner() {
|
||||||
s.Require().False(community.IsControlNode())
|
s.Require().False(community.IsControlNode())
|
||||||
s.Require().False(community.IsOwner())
|
s.Require().False(community.IsOwner())
|
||||||
|
|
||||||
// TODO: uncomment when ex-owner will start sharing request to join with revealed address
|
// John manually joins the community
|
||||||
// // Jonh is a community member again
|
s.joinCommunity(s.alice, community, s.john)
|
||||||
// _, err = WaitOnMessengerResponse(
|
|
||||||
// s.bob,
|
|
||||||
// func(r *MessengerResponse) bool {
|
|
||||||
// return len(r.Communities()) > 0 && r.Communities()[0].HasMember(&s.bob.identity.PublicKey)
|
|
||||||
// },
|
|
||||||
// "John was auto-accepted",
|
|
||||||
// )
|
|
||||||
// s.Require().NoError(err)
|
|
||||||
|
|
||||||
// community = validateResults(s.john)
|
|
||||||
// s.Require().False(community.IsControlNode())
|
|
||||||
// s.Require().False(community.IsOwner())
|
|
||||||
|
|
||||||
// Alice change community name
|
// Alice change community name
|
||||||
|
|
||||||
|
@ -290,15 +328,14 @@ func (s *MessengerCommunitiesSignersSuite) TestControlNodeUpdateSigner() {
|
||||||
|
|
||||||
validateNameInDB(s.alice)
|
validateNameInDB(s.alice)
|
||||||
|
|
||||||
// TODO: uncomment when ex-owner will start sharing request to join with revealed address
|
|
||||||
// john accepts community update from alice (new control node)
|
// john accepts community update from alice (new control node)
|
||||||
// _, err = WaitOnMessengerResponse(
|
_, err = WaitOnMessengerResponse(
|
||||||
// s.john,
|
s.john,
|
||||||
// validateNameInResponse,
|
validateNameInResponse,
|
||||||
// "john did not receive community name update",
|
"john did not receive community name update",
|
||||||
// )
|
)
|
||||||
// s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
// validateNameInDB(s.john)
|
validateNameInDB(s.john)
|
||||||
|
|
||||||
// bob accepts community update from alice (new control node)
|
// bob accepts community update from alice (new control node)
|
||||||
_, err = WaitOnMessengerResponse(
|
_, err = WaitOnMessengerResponse(
|
||||||
|
@ -394,14 +431,21 @@ func (s *MessengerCommunitiesSignersSuite) TestAutoAcceptOnOwnershipChangeReques
|
||||||
_, err = WaitOnSignaledMessengerResponse(
|
_, err = WaitOnSignaledMessengerResponse(
|
||||||
s.john,
|
s.john,
|
||||||
func(r *MessengerResponse) bool {
|
func(r *MessengerResponse) bool {
|
||||||
return len(r.Communities()) > 0 && !r.Communities()[0].HasMember(&s.john.identity.PublicKey)
|
wasKicked := len(r.Communities()) > 0 && !r.Communities()[0].HasMember(&s.john.identity.PublicKey)
|
||||||
|
sharedNotificationExist := false
|
||||||
|
for _, acNotification := range r.ActivityCenterNotifications() {
|
||||||
|
if acNotification.Type == ActivityCenterNotificationTypeShareAccounts {
|
||||||
|
sharedNotificationExist = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wasKicked && sharedNotificationExist
|
||||||
},
|
},
|
||||||
"John was not kicked from the community",
|
"John was not kicked from the community",
|
||||||
)
|
)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
// Alice auto-accept requests to join with RevealedAddresses
|
// Alice auto-accept requests to join with RevealedAddresses
|
||||||
// TODO: please, check TODO's in this test and uncomment them if Members() == 3
|
|
||||||
_, err = WaitOnMessengerResponse(
|
_, err = WaitOnMessengerResponse(
|
||||||
s.alice,
|
s.alice,
|
||||||
func(r *MessengerResponse) bool {
|
func(r *MessengerResponse) bool {
|
||||||
|
@ -437,20 +481,6 @@ func (s *MessengerCommunitiesSignersSuite) TestAutoAcceptOnOwnershipChangeReques
|
||||||
community = validateResults(s.bob)
|
community = validateResults(s.bob)
|
||||||
s.Require().False(community.IsControlNode())
|
s.Require().False(community.IsControlNode())
|
||||||
s.Require().False(community.IsOwner())
|
s.Require().False(community.IsOwner())
|
||||||
|
|
||||||
// TODO: uncomment when ex-owner will start sharing request to join with revealed address
|
|
||||||
// _, err = WaitOnMessengerResponse(
|
|
||||||
// s.john,
|
|
||||||
// func(r *MessengerResponse) bool {
|
|
||||||
// return len(r.Communities()) > 0 && r.Communities()[0].HasMember(&s.bob.identity.PublicKey)
|
|
||||||
// },
|
|
||||||
// "John was auto-accepted",
|
|
||||||
// )
|
|
||||||
// s.Require().NoError(err)
|
|
||||||
|
|
||||||
// community = validateResults(s.john)
|
|
||||||
// s.Require().False(community.IsControlNode())
|
|
||||||
// s.Require().False(community.IsOwner())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MessengerCommunitiesSignersSuite) TestNewOwnerAcceptRequestToJoin() {
|
func (s *MessengerCommunitiesSignersSuite) TestNewOwnerAcceptRequestToJoin() {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package protocol
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
@ -392,8 +393,13 @@ func (m *Messenger) handleCommunitiesSubscription(c chan *communities.Subscripti
|
||||||
// control node changed and we were kicked out. It now awaits our addresses
|
// control node changed and we were kicked out. It now awaits our addresses
|
||||||
if communityResponse.Changes.ControlNodeChanged != nil && communityResponse.Changes.MemberKicked {
|
if communityResponse.Changes.ControlNodeChanged != nil && communityResponse.Changes.MemberKicked {
|
||||||
requestToJoin, err := m.sendSharedAddressToControlNode(communityResponse.Community.ControlNode(), communityResponse.Community)
|
requestToJoin, err := m.sendSharedAddressToControlNode(communityResponse.Community.ControlNode(), communityResponse.Community)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
m.logger.Error("share address to control node failed", zap.String("id", types.EncodeHex(communityResponse.Community.ID())), zap.Error(err))
|
m.logger.Error("share address to control node failed", zap.String("id", types.EncodeHex(communityResponse.Community.ID())), zap.Error(err))
|
||||||
|
|
||||||
|
if err == communities.ErrRevealedAccountsAbsent || err == communities.ErrNoRevealedAccountsSignature {
|
||||||
|
m.AddActivityCenterNotificationToResponse(communityResponse.Community.IDString(), ActivityCenterNotificationTypeShareAccounts, response)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
state.Response.RequestsToJoinCommunity = append(state.Response.RequestsToJoinCommunity, requestToJoin)
|
state.Response.RequestsToJoinCommunity = append(state.Response.RequestsToJoinCommunity, requestToJoin)
|
||||||
}
|
}
|
||||||
|
@ -3105,9 +3111,30 @@ func (m *Messenger) sendSharedAddressToControlNode(receiver *ecdsa.PublicKey, co
|
||||||
|
|
||||||
requestToJoin, err := m.communitiesManager.GetCommunityRequestToJoinWithRevealedAddresses(pk, community.ID())
|
requestToJoin, err := m.communitiesManager.GetCommunityRequestToJoinWithRevealedAddresses(pk, community.ID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return nil, communities.ErrRevealedAccountsAbsent
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(requestToJoin.RevealedAccounts) == 0 {
|
||||||
|
return nil, communities.ErrRevealedAccountsAbsent
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if at least one account is signed
|
||||||
|
// old community users can not keep locally the signature of their revealed accounts in the DB
|
||||||
|
revealedAccountSigned := false
|
||||||
|
for _, account := range requestToJoin.RevealedAccounts {
|
||||||
|
revealedAccountSigned = len(account.Signature) > 0
|
||||||
|
if revealedAccountSigned {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !revealedAccountSigned {
|
||||||
|
return nil, communities.ErrNoRevealedAccountsSignature
|
||||||
|
}
|
||||||
|
|
||||||
requestToJoin.Clock = uint64(time.Now().Unix())
|
requestToJoin.Clock = uint64(time.Now().Unix())
|
||||||
requestToJoin.State = communities.RequestToJoinStateAwaitingAddresses
|
requestToJoin.State = communities.RequestToJoinStateAwaitingAddresses
|
||||||
payload, err := proto.Marshal(requestToJoin.ToCommunityRequestToJoinProtobuf())
|
payload, err := proto.Marshal(requestToJoin.ToCommunityRequestToJoinProtobuf())
|
||||||
|
@ -4217,3 +4244,21 @@ func (m *Messenger) SendMessageToControlNode(community *communities.Community, r
|
||||||
|
|
||||||
return m.sender.SendCommunityMessage(context.Background(), rawMessage)
|
return m.sender.SendCommunityMessage(context.Background(), rawMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Messenger) AddActivityCenterNotificationToResponse(communityID string, acType ActivityCenterType, response *MessengerResponse) {
|
||||||
|
// Activity Center notification
|
||||||
|
notification := &ActivityCenterNotification{
|
||||||
|
ID: types.FromHex(uuid.New().String()),
|
||||||
|
Type: acType,
|
||||||
|
Timestamp: m.getTimesource().GetCurrentTime(),
|
||||||
|
CommunityID: communityID,
|
||||||
|
Read: false,
|
||||||
|
Deleted: false,
|
||||||
|
UpdatedAt: m.GetCurrentTimeInMillis(),
|
||||||
|
}
|
||||||
|
|
||||||
|
err := m.addActivityCenterNotification(response, notification, nil)
|
||||||
|
if err != nil {
|
||||||
|
m.logger.Error("failed to save notification", zap.Error(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue