mirror of
https://github.com/status-im/status-go.git
synced 2025-01-29 16:06:47 +00:00
chore(community)_: serialise community jsons with image URLs
Fix status-im/status-desktop#15340
This commit is contained in:
parent
798877788c
commit
02b822802c
@ -3,6 +3,7 @@ package common
|
|||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"errors"
|
"errors"
|
||||||
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -72,3 +73,14 @@ func IsENSName(displayName string) bool {
|
|||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsNil(i interface{}) bool {
|
||||||
|
if i == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
switch reflect.TypeOf(i).Kind() {
|
||||||
|
case reflect.Ptr, reflect.Interface:
|
||||||
|
return reflect.ValueOf(i).IsNil()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
|
||||||
"github.com/status-im/status-go/api/multiformat"
|
"github.com/status-im/status-go/api/multiformat"
|
||||||
|
utils "github.com/status-im/status-go/common"
|
||||||
"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"
|
||||||
"github.com/status-im/status-go/images"
|
"github.com/status-im/status-go/images"
|
||||||
@ -65,13 +66,14 @@ type EventsData struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Community struct {
|
type Community struct {
|
||||||
config *Config
|
config *Config
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
timesource common.TimeSource
|
timesource common.TimeSource
|
||||||
encryptor DescriptionEncryptor
|
encryptor DescriptionEncryptor
|
||||||
|
mediaServer server.MediaServerInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(config Config, timesource common.TimeSource, encryptor DescriptionEncryptor) (*Community, error) {
|
func New(config Config, timesource common.TimeSource, encryptor DescriptionEncryptor, mediaServer server.MediaServerInterface) (*Community, error) {
|
||||||
if config.MemberIdentity == nil {
|
if config.MemberIdentity == nil {
|
||||||
return nil, errors.New("no member identity")
|
return nil, errors.New("no member identity")
|
||||||
}
|
}
|
||||||
@ -92,7 +94,12 @@ func New(config Config, timesource common.TimeSource, encryptor DescriptionEncry
|
|||||||
config.CommunityDescription = &protobuf.CommunityDescription{}
|
config.CommunityDescription = &protobuf.CommunityDescription{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Community{config: &config, timesource: timesource, encryptor: encryptor}, nil
|
return &Community{
|
||||||
|
config: &config,
|
||||||
|
timesource: timesource,
|
||||||
|
encryptor: encryptor,
|
||||||
|
mediaServer: mediaServer,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommunityAdminSettings struct {
|
type CommunityAdminSettings struct {
|
||||||
@ -257,7 +264,7 @@ func (o *Community) MarshalPublicAPIJSON() ([]byte, error) {
|
|||||||
return json.Marshal(communityItem)
|
return json.Marshal(communityItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Community) MarshalJSONWithMediaServer(mediaServer *server.MediaServer) ([]byte, error) {
|
func (o *Community) MarshalJSON() ([]byte, error) {
|
||||||
if o.config.MemberIdentity == nil {
|
if o.config.MemberIdentity == nil {
|
||||||
return nil, errors.New("member identity not set")
|
return nil, errors.New("member identity not set")
|
||||||
}
|
}
|
||||||
@ -353,159 +360,6 @@ func (o *Community) MarshalJSONWithMediaServer(mediaServer *server.MediaServer)
|
|||||||
}
|
}
|
||||||
canView := o.CanView(o.MemberIdentity(), id)
|
canView := o.CanView(o.MemberIdentity(), id)
|
||||||
|
|
||||||
chat := CommunityChat{
|
|
||||||
ID: id,
|
|
||||||
Name: c.Identity.DisplayName,
|
|
||||||
Emoji: c.Identity.Emoji,
|
|
||||||
Color: c.Identity.Color,
|
|
||||||
Description: c.Identity.Description,
|
|
||||||
Permissions: c.Permissions,
|
|
||||||
Members: c.Members,
|
|
||||||
CanPost: canPost,
|
|
||||||
CanView: canView,
|
|
||||||
CanPostReactions: canPostReactions,
|
|
||||||
ViewersCanPostReactions: c.ViewersCanPostReactions,
|
|
||||||
TokenGated: o.channelEncrypted(id),
|
|
||||||
CategoryID: c.CategoryId,
|
|
||||||
HideIfPermissionsNotMet: c.HideIfPermissionsNotMet,
|
|
||||||
Position: int(c.Position),
|
|
||||||
MissingEncryptionKey: !o.IsMemberInChat(o.MemberIdentity(), id) && o.IsMemberLikelyInChat(id),
|
|
||||||
}
|
|
||||||
communityItem.Chats[id] = chat
|
|
||||||
}
|
|
||||||
communityItem.TokenPermissions = o.tokenPermissions()
|
|
||||||
communityItem.PendingAndBannedMembers = o.PendingAndBannedMembers()
|
|
||||||
communityItem.Members = o.config.CommunityDescription.Members
|
|
||||||
communityItem.Permissions = o.config.CommunityDescription.Permissions
|
|
||||||
communityItem.IntroMessage = o.config.CommunityDescription.IntroMessage
|
|
||||||
communityItem.OutroMessage = o.config.CommunityDescription.OutroMessage
|
|
||||||
|
|
||||||
// update token meta image to url rather than base64 image
|
|
||||||
var tokenMetadata []*protobuf.CommunityTokenMetadata
|
|
||||||
for _, m := range o.config.CommunityDescription.CommunityTokensMetadata {
|
|
||||||
copyM := proto.Clone(m).(*protobuf.CommunityTokenMetadata)
|
|
||||||
copyM.Image = mediaServer.MakeCommunityDescriptionTokenImageURL(o.IDString(), copyM.GetSymbol())
|
|
||||||
tokenMetadata = append(tokenMetadata, copyM)
|
|
||||||
}
|
|
||||||
communityItem.CommunityTokensMetadata = tokenMetadata
|
|
||||||
|
|
||||||
communityItem.ActiveMembersCount = o.config.CommunityDescription.ActiveMembersCount
|
|
||||||
|
|
||||||
if o.config.CommunityDescription.Identity != nil {
|
|
||||||
communityItem.Name = o.Name()
|
|
||||||
communityItem.Color = o.config.CommunityDescription.Identity.Color
|
|
||||||
communityItem.Description = o.config.CommunityDescription.Identity.Description
|
|
||||||
for t := range o.config.CommunityDescription.Identity.Images {
|
|
||||||
if communityItem.Images == nil {
|
|
||||||
communityItem.Images = make(map[string]Image)
|
|
||||||
}
|
|
||||||
communityItem.Images[t] = Image{Uri: mediaServer.MakeCommunityImageURL(o.IDString(), t)}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
communityItem.CommunityAdminSettings = CommunityAdminSettings{
|
|
||||||
PinMessageAllMembersEnabled: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
if o.config.CommunityDescription.AdminSettings != nil {
|
|
||||||
communityItem.CommunityAdminSettings.PinMessageAllMembersEnabled = o.config.CommunityDescription.AdminSettings.PinMessageAllMembersEnabled
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return json.Marshal(communityItem)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *Community) MarshalJSON() ([]byte, error) {
|
|
||||||
if o.config.MemberIdentity == nil {
|
|
||||||
return nil, errors.New("member identity not set")
|
|
||||||
}
|
|
||||||
communityItem := struct {
|
|
||||||
ID types.HexBytes `json:"id"`
|
|
||||||
MemberRole protobuf.CommunityMember_Roles `json:"memberRole"`
|
|
||||||
IsControlNode bool `json:"isControlNode"`
|
|
||||||
Verified bool `json:"verified"`
|
|
||||||
Joined bool `json:"joined"`
|
|
||||||
JoinedAt int64 `json:"joinedAt"`
|
|
||||||
Spectated bool `json:"spectated"`
|
|
||||||
RequestedAccessAt int `json:"requestedAccessAt"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
IntroMessage string `json:"introMessage"`
|
|
||||||
OutroMessage string `json:"outroMessage"`
|
|
||||||
Tags []CommunityTag `json:"tags"`
|
|
||||||
Chats map[string]CommunityChat `json:"chats"`
|
|
||||||
Categories map[string]CommunityCategory `json:"categories"`
|
|
||||||
Images map[string]images.IdentityImage `json:"images"`
|
|
||||||
Permissions *protobuf.CommunityPermissions `json:"permissions"`
|
|
||||||
Members map[string]*protobuf.CommunityMember `json:"members"`
|
|
||||||
CanRequestAccess bool `json:"canRequestAccess"`
|
|
||||||
CanManageUsers bool `json:"canManageUsers"` //TODO: we can remove this
|
|
||||||
CanDeleteMessageForEveryone bool `json:"canDeleteMessageForEveryone"` //TODO: we can remove this
|
|
||||||
CanJoin bool `json:"canJoin"`
|
|
||||||
Color string `json:"color"`
|
|
||||||
RequestedToJoinAt uint64 `json:"requestedToJoinAt,omitempty"`
|
|
||||||
IsMember bool `json:"isMember"`
|
|
||||||
Muted bool `json:"muted"`
|
|
||||||
MuteTill time.Time `json:"muteTill,omitempty"`
|
|
||||||
CommunityAdminSettings CommunityAdminSettings `json:"adminSettings"`
|
|
||||||
Encrypted bool `json:"encrypted"`
|
|
||||||
PendingAndBannedMembers map[string]CommunityMemberState `json:"pendingAndBannedMembers"`
|
|
||||||
TokenPermissions map[string]*CommunityTokenPermission `json:"tokenPermissions"`
|
|
||||||
CommunityTokensMetadata []*protobuf.CommunityTokenMetadata `json:"communityTokensMetadata"`
|
|
||||||
ActiveMembersCount uint64 `json:"activeMembersCount"`
|
|
||||||
PubsubTopic string `json:"pubsubTopic"`
|
|
||||||
PubsubTopicKey string `json:"pubsubTopicKey"`
|
|
||||||
Shard *shard.Shard `json:"shard"`
|
|
||||||
LastOpenedAt int64 `json:"lastOpenedAt"`
|
|
||||||
Clock uint64 `json:"clock"`
|
|
||||||
}{
|
|
||||||
ID: o.ID(),
|
|
||||||
Clock: o.Clock(),
|
|
||||||
MemberRole: o.MemberRole(o.MemberIdentity()),
|
|
||||||
IsControlNode: o.IsControlNode(),
|
|
||||||
Verified: o.config.Verified,
|
|
||||||
Chats: make(map[string]CommunityChat),
|
|
||||||
Categories: make(map[string]CommunityCategory),
|
|
||||||
Joined: o.config.Joined,
|
|
||||||
JoinedAt: o.config.JoinedAt,
|
|
||||||
Spectated: o.config.Spectated,
|
|
||||||
CanRequestAccess: o.CanRequestAccess(o.MemberIdentity()),
|
|
||||||
CanJoin: o.canJoin(),
|
|
||||||
CanManageUsers: o.CanManageUsers(o.MemberIdentity()),
|
|
||||||
CanDeleteMessageForEveryone: o.CanDeleteMessageForEveryone(o.MemberIdentity()),
|
|
||||||
RequestedToJoinAt: o.RequestedToJoinAt(),
|
|
||||||
IsMember: o.isMember(),
|
|
||||||
Muted: o.config.Muted,
|
|
||||||
MuteTill: o.config.MuteTill,
|
|
||||||
Tags: o.Tags(),
|
|
||||||
Encrypted: o.Encrypted(),
|
|
||||||
PubsubTopic: o.PubsubTopic(),
|
|
||||||
PubsubTopicKey: o.PubsubTopicKey(),
|
|
||||||
Shard: o.Shard(),
|
|
||||||
LastOpenedAt: o.config.LastOpenedAt,
|
|
||||||
}
|
|
||||||
if o.config.CommunityDescription != nil {
|
|
||||||
for id, c := range o.config.CommunityDescription.Categories {
|
|
||||||
category := CommunityCategory{
|
|
||||||
ID: id,
|
|
||||||
Name: c.Name,
|
|
||||||
Position: int(c.Position),
|
|
||||||
}
|
|
||||||
communityItem.Encrypted = o.Encrypted()
|
|
||||||
communityItem.Categories[id] = category
|
|
||||||
}
|
|
||||||
for id, c := range o.config.CommunityDescription.Chats {
|
|
||||||
// NOTE: Here `CanPost` is only set for ChatMessage. But it can be different for reactions/pin/etc.
|
|
||||||
// Consider adding more properties to `CommunityChat` to reflect that.
|
|
||||||
canPost, err := o.CanPost(o.MemberIdentity(), id, protobuf.ApplicationMetadataMessage_CHAT_MESSAGE)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
canPostReactions, err := o.CanPost(o.MemberIdentity(), id, protobuf.ApplicationMetadataMessage_EMOJI_REACTION)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
canView := o.CanView(o.MemberIdentity(), id)
|
|
||||||
|
|
||||||
chat := CommunityChat{
|
chat := CommunityChat{
|
||||||
ID: id,
|
ID: id,
|
||||||
Name: c.Identity.DisplayName,
|
Name: c.Identity.DisplayName,
|
||||||
@ -535,18 +389,32 @@ func (o *Community) MarshalJSON() ([]byte, error) {
|
|||||||
communityItem.Permissions = o.config.CommunityDescription.Permissions
|
communityItem.Permissions = o.config.CommunityDescription.Permissions
|
||||||
communityItem.IntroMessage = o.config.CommunityDescription.IntroMessage
|
communityItem.IntroMessage = o.config.CommunityDescription.IntroMessage
|
||||||
communityItem.OutroMessage = o.config.CommunityDescription.OutroMessage
|
communityItem.OutroMessage = o.config.CommunityDescription.OutroMessage
|
||||||
communityItem.CommunityTokensMetadata = o.config.CommunityDescription.CommunityTokensMetadata
|
|
||||||
|
// update token meta image to url rather than base64 image
|
||||||
|
var tokenMetadata []*protobuf.CommunityTokenMetadata
|
||||||
|
|
||||||
|
if !utils.IsNil(o.mediaServer) {
|
||||||
|
for _, m := range o.config.CommunityDescription.CommunityTokensMetadata {
|
||||||
|
copyM := proto.Clone(m).(*protobuf.CommunityTokenMetadata)
|
||||||
|
copyM.Image = o.mediaServer.MakeCommunityDescriptionTokenImageURL(o.IDString(), copyM.GetSymbol())
|
||||||
|
tokenMetadata = append(tokenMetadata, copyM)
|
||||||
|
}
|
||||||
|
communityItem.CommunityTokensMetadata = tokenMetadata
|
||||||
|
}
|
||||||
communityItem.ActiveMembersCount = o.config.CommunityDescription.ActiveMembersCount
|
communityItem.ActiveMembersCount = o.config.CommunityDescription.ActiveMembersCount
|
||||||
|
|
||||||
if o.config.CommunityDescription.Identity != nil {
|
if o.config.CommunityDescription.Identity != nil {
|
||||||
communityItem.Name = o.Name()
|
communityItem.Name = o.Name()
|
||||||
communityItem.Color = o.config.CommunityDescription.Identity.Color
|
communityItem.Color = o.config.CommunityDescription.Identity.Color
|
||||||
communityItem.Description = o.config.CommunityDescription.Identity.Description
|
communityItem.Description = o.config.CommunityDescription.Identity.Description
|
||||||
for t, i := range o.config.CommunityDescription.Identity.Images {
|
|
||||||
if communityItem.Images == nil {
|
if !utils.IsNil(o.mediaServer) {
|
||||||
communityItem.Images = make(map[string]images.IdentityImage)
|
for t := range o.config.CommunityDescription.Identity.Images {
|
||||||
|
if communityItem.Images == nil {
|
||||||
|
communityItem.Images = make(map[string]Image)
|
||||||
|
}
|
||||||
|
communityItem.Images[t] = Image{Uri: o.mediaServer.MakeCommunityImageURL(o.IDString(), t)}
|
||||||
}
|
}
|
||||||
communityItem.Images[t] = images.IdentityImage{Name: t, Payload: i.Payload}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ func createTestCommunity(identity *ecdsa.PrivateKey) (*Community, error) {
|
|||||||
MemberIdentity: identity,
|
MemberIdentity: identity,
|
||||||
}
|
}
|
||||||
|
|
||||||
return New(config, &TimeSourceStub{}, &DescriptionEncryptorMock{})
|
return New(config, &TimeSourceStub{}, &DescriptionEncryptorMock{}, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCommunityEncryptionKeyActionSuite(t *testing.T) {
|
func TestCommunityEncryptionKeyActionSuite(t *testing.T) {
|
||||||
|
@ -444,7 +444,7 @@ func (s *CommunitySuite) TestValidateRequestToJoin() {
|
|||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
s.Run(tc.name, func() {
|
s.Run(tc.name, func() {
|
||||||
org, err := New(tc.config, &TimeSourceStub{}, &DescriptionEncryptorMock{})
|
org, err := New(tc.config, &TimeSourceStub{}, &DescriptionEncryptorMock{}, nil)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
err = org.ValidateRequestToJoin(tc.signer, tc.request)
|
err = org.ValidateRequestToJoin(tc.signer, tc.request)
|
||||||
s.Require().Equal(tc.err, err)
|
s.Require().Equal(tc.err, err)
|
||||||
@ -530,7 +530,7 @@ func (s *CommunitySuite) TestCanPost() {
|
|||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
s.Run(tc.name, func() {
|
s.Run(tc.name, func() {
|
||||||
var err error
|
var err error
|
||||||
org, err := New(tc.config, &TimeSourceStub{}, &DescriptionEncryptorMock{})
|
org, err := New(tc.config, &TimeSourceStub{}, &DescriptionEncryptorMock{}, nil)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
canPost, err := org.CanPost(tc.member, testChatID1, protobuf.ApplicationMetadataMessage_CHAT_MESSAGE)
|
canPost, err := org.CanPost(tc.member, testChatID1, protobuf.ApplicationMetadataMessage_CHAT_MESSAGE)
|
||||||
@ -927,7 +927,7 @@ func (s *CommunitySuite) buildCommunity(owner *ecdsa.PublicKey) *Community {
|
|||||||
config.ID = owner
|
config.ID = owner
|
||||||
config.CommunityDescription = s.buildCommunityDescription()
|
config.CommunityDescription = s.buildCommunityDescription()
|
||||||
|
|
||||||
org, err := New(config, &TimeSourceStub{}, &DescriptionEncryptorMock{})
|
org, err := New(config, &TimeSourceStub{}, &DescriptionEncryptorMock{}, nil)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
return org
|
return org
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ import (
|
|||||||
"github.com/status-im/status-go/protocol/requests"
|
"github.com/status-im/status-go/protocol/requests"
|
||||||
"github.com/status-im/status-go/protocol/transport"
|
"github.com/status-im/status-go/protocol/transport"
|
||||||
"github.com/status-im/status-go/rpc/network"
|
"github.com/status-im/status-go/rpc/network"
|
||||||
|
"github.com/status-im/status-go/server"
|
||||||
"github.com/status-im/status-go/services/wallet/bigint"
|
"github.com/status-im/status-go/services/wallet/bigint"
|
||||||
walletcommon "github.com/status-im/status-go/services/wallet/common"
|
walletcommon "github.com/status-im/status-go/services/wallet/common"
|
||||||
"github.com/status-im/status-go/services/wallet/thirdparty"
|
"github.com/status-im/status-go/services/wallet/thirdparty"
|
||||||
@ -107,6 +108,7 @@ type Manager struct {
|
|||||||
PermissionChecker PermissionChecker
|
PermissionChecker PermissionChecker
|
||||||
keyDistributor KeyDistributor
|
keyDistributor KeyDistributor
|
||||||
communityLock *CommunityLock
|
communityLock *CommunityLock
|
||||||
|
mediaServer server.MediaServerInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommunityLock struct {
|
type CommunityLock struct {
|
||||||
@ -380,7 +382,20 @@ type OwnerVerifier interface {
|
|||||||
SafeGetSignerPubKey(ctx context.Context, chainID uint64, communityID string) (string, error)
|
SafeGetSignerPubKey(ctx context.Context, chainID uint64, communityID string) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewManager(identity *ecdsa.PrivateKey, installationID string, db *sql.DB, encryptor *encryption.Protocol, logger *zap.Logger, ensverifier *ens.Verifier, ownerVerifier OwnerVerifier, transport *transport.Transport, timesource common.TimeSource, keyDistributor KeyDistributor, opts ...ManagerOption) (*Manager, error) {
|
func NewManager(
|
||||||
|
identity *ecdsa.PrivateKey,
|
||||||
|
installationID string,
|
||||||
|
db *sql.DB,
|
||||||
|
encryptor *encryption.Protocol,
|
||||||
|
logger *zap.Logger,
|
||||||
|
ensverifier *ens.Verifier,
|
||||||
|
ownerVerifier OwnerVerifier,
|
||||||
|
transport *transport.Transport,
|
||||||
|
timesource common.TimeSource,
|
||||||
|
keyDistributor KeyDistributor,
|
||||||
|
mediaServer server.MediaServerInterface,
|
||||||
|
opts ...ManagerOption,
|
||||||
|
) (*Manager, error) {
|
||||||
if identity == nil {
|
if identity == nil {
|
||||||
return nil, errors.New("empty identity")
|
return nil, errors.New("empty identity")
|
||||||
}
|
}
|
||||||
@ -412,6 +427,7 @@ func NewManager(identity *ecdsa.PrivateKey, installationID string, db *sql.DB, e
|
|||||||
timesource: timesource,
|
timesource: timesource,
|
||||||
keyDistributor: keyDistributor,
|
keyDistributor: keyDistributor,
|
||||||
communityLock: NewCommunityLock(logger),
|
communityLock: NewCommunityLock(logger),
|
||||||
|
mediaServer: mediaServer,
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.persistence = &Persistence{
|
manager.persistence = &Persistence{
|
||||||
@ -440,7 +456,6 @@ func NewManager(identity *ecdsa.PrivateKey, installationID string, db *sql.DB, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ensverifier != nil {
|
if ensverifier != nil {
|
||||||
|
|
||||||
sub := ensverifier.Subscribe()
|
sub := ensverifier.Subscribe()
|
||||||
manager.ensSubscription = sub
|
manager.ensSubscription = sub
|
||||||
manager.ensVerifier = ensverifier
|
manager.ensVerifier = ensverifier
|
||||||
@ -490,6 +505,10 @@ type CommunityResponse struct {
|
|||||||
FailedToDecrypt []*CommunityPrivateDataFailedToDecrypt `json:"-"`
|
FailedToDecrypt []*CommunityPrivateDataFailedToDecrypt `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Manager) SetMediaServer(mediaServer server.MediaServerInterface) {
|
||||||
|
m.mediaServer = mediaServer
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Manager) Subscribe() chan *Subscription {
|
func (m *Manager) Subscribe() chan *Subscription {
|
||||||
subscription := make(chan *Subscription, 100)
|
subscription := make(chan *Subscription, 100)
|
||||||
m.subscriptions = append(m.subscriptions, subscription)
|
m.subscriptions = append(m.subscriptions, subscription)
|
||||||
@ -856,7 +875,7 @@ func (m *Manager) CreateCommunity(request *requests.CreateCommunity, publish boo
|
|||||||
if m.encryptor != nil {
|
if m.encryptor != nil {
|
||||||
descriptionEncryptor = m
|
descriptionEncryptor = m
|
||||||
}
|
}
|
||||||
community, err := New(config, m.timesource, descriptionEncryptor)
|
community, err := New(config, m.timesource, descriptionEncryptor, m.mediaServer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1079,7 +1098,6 @@ func (m *Manager) reevaluateMembers(communityID types.HexBytes) (*Community, map
|
|||||||
}
|
}
|
||||||
|
|
||||||
revealedAccount, memberHasWallet := membersAccounts[memberKey]
|
revealedAccount, memberHasWallet := membersAccounts[memberKey]
|
||||||
|
|
||||||
if !memberHasWallet {
|
if !memberHasWallet {
|
||||||
result.membersToRemove[memberKey] = struct{}{}
|
result.membersToRemove[memberKey] = struct{}{}
|
||||||
continue
|
continue
|
||||||
@ -1725,7 +1743,7 @@ func (m *Manager) ImportCommunity(key *ecdsa.PrivateKey, clock uint64) (*Communi
|
|||||||
if m.encryptor != nil {
|
if m.encryptor != nil {
|
||||||
descriptionEncryptor = m
|
descriptionEncryptor = m
|
||||||
}
|
}
|
||||||
community, err = New(config, m.timesource, descriptionEncryptor)
|
community, err = New(config, m.timesource, descriptionEncryptor, m.mediaServer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -2151,7 +2169,7 @@ func (m *Manager) HandleCommunityDescriptionMessage(signer *ecdsa.PublicKey, des
|
|||||||
if m.encryptor != nil {
|
if m.encryptor != nil {
|
||||||
descriptionEncryptor = m
|
descriptionEncryptor = m
|
||||||
}
|
}
|
||||||
community, err = New(config, m.timesource, descriptionEncryptor)
|
community, err = New(config, m.timesource, descriptionEncryptor, m.mediaServer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -3890,7 +3908,7 @@ func (m *Manager) dbRecordBundleToCommunity(r *CommunityRecordBundle) (*Communit
|
|||||||
descriptionEncryptor = m
|
descriptionEncryptor = m
|
||||||
}
|
}
|
||||||
|
|
||||||
return recordBundleToCommunity(r, m.identity, m.installationID, m.logger, m.timesource, descriptionEncryptor, func(community *Community) error {
|
initializer := func(community *Community) error {
|
||||||
_, description, err := m.preprocessDescription(community.ID(), community.config.CommunityDescription)
|
_, description, err := m.preprocessDescription(community.ID(), community.config.CommunityDescription)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -3918,7 +3936,18 @@ func (m *Manager) dbRecordBundleToCommunity(r *CommunityRecordBundle) (*Communit
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}
|
||||||
|
|
||||||
|
return recordBundleToCommunity(
|
||||||
|
r,
|
||||||
|
m.identity,
|
||||||
|
m.installationID,
|
||||||
|
m.logger,
|
||||||
|
m.timesource,
|
||||||
|
descriptionEncryptor,
|
||||||
|
m.mediaServer,
|
||||||
|
initializer,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) GetByID(id []byte) (*Community, error) {
|
func (m *Manager) GetByID(id []byte) (*Community, error) {
|
||||||
|
@ -60,7 +60,7 @@ func (s *ManagerSuite) buildManagers(ownerVerifier OwnerVerifier) (*Manager, *Ar
|
|||||||
logger, err := zap.NewDevelopment()
|
logger, err := zap.NewDevelopment()
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
m, err := NewManager(key, "", db, nil, logger, nil, ownerVerifier, nil, &TimeSourceStub{}, nil)
|
m, err := NewManager(key, "", db, nil, logger, nil, ownerVerifier, nil, &TimeSourceStub{}, nil, nil)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().NoError(m.Start())
|
s.Require().NoError(m.Start())
|
||||||
|
|
||||||
@ -226,7 +226,7 @@ func (s *ManagerSuite) setupManagerForTokenPermissions() (*Manager, *testCollect
|
|||||||
WithTokenManager(tm),
|
WithTokenManager(tm),
|
||||||
}
|
}
|
||||||
|
|
||||||
m, err := NewManager(key, "", db, nil, nil, nil, nil, nil, &TimeSourceStub{}, nil, options...)
|
m, err := NewManager(key, "", db, nil, nil, nil, nil, nil, &TimeSourceStub{}, nil, nil, options...)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().NoError(m.Start())
|
s.Require().NoError(m.Start())
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/status-im/status-go/eth-node/crypto"
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
"github.com/status-im/status-go/protocol/common"
|
"github.com/status-im/status-go/protocol/common"
|
||||||
"github.com/status-im/status-go/protocol/common/shard"
|
"github.com/status-im/status-go/protocol/common/shard"
|
||||||
|
"github.com/status-im/status-go/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
func communityToRecord(community *Community) (*CommunityRecord, error) {
|
func communityToRecord(community *Community) (*CommunityRecord, error) {
|
||||||
@ -71,8 +72,16 @@ func recordToRequestToJoin(r *RequestToJoinRecord) *RequestToJoin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func recordBundleToCommunity(r *CommunityRecordBundle, memberIdentity *ecdsa.PrivateKey, installationID string,
|
func recordBundleToCommunity(
|
||||||
logger *zap.Logger, timesource common.TimeSource, encryptor DescriptionEncryptor, initializer func(*Community) error) (*Community, error) {
|
r *CommunityRecordBundle,
|
||||||
|
memberIdentity *ecdsa.PrivateKey,
|
||||||
|
installationID string,
|
||||||
|
logger *zap.Logger,
|
||||||
|
timesource common.TimeSource,
|
||||||
|
encryptor DescriptionEncryptor,
|
||||||
|
mediaServer server.MediaServerInterface,
|
||||||
|
initializer func(*Community) error,
|
||||||
|
) (*Community, error) {
|
||||||
var privateKey *ecdsa.PrivateKey
|
var privateKey *ecdsa.PrivateKey
|
||||||
var controlNode *ecdsa.PublicKey
|
var controlNode *ecdsa.PublicKey
|
||||||
var err error
|
var err error
|
||||||
@ -139,7 +148,7 @@ func recordBundleToCommunity(r *CommunityRecordBundle, memberIdentity *ecdsa.Pri
|
|||||||
Shard: s,
|
Shard: s,
|
||||||
}
|
}
|
||||||
|
|
||||||
community, err := New(config, timesource, encryptor)
|
community, err := New(config, timesource, encryptor, mediaServer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ func (s *PersistenceSuite) SetupTest() {
|
|||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
s.db = &Persistence{db: db, recordBundleToCommunity: func(r *CommunityRecordBundle) (*Community, error) {
|
s.db = &Persistence{db: db, recordBundleToCommunity: func(r *CommunityRecordBundle) (*Community, error) {
|
||||||
return recordBundleToCommunity(r, s.identity, "", nil, &TimeSourceStub{}, &DescriptionEncryptorMock{}, nil)
|
return recordBundleToCommunity(r, s.identity, "", nil, &TimeSourceStub{}, &DescriptionEncryptorMock{}, nil, nil)
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +264,7 @@ func (s *PersistenceSuite) makeNewCommunity(identity *ecdsa.PrivateKey) *Communi
|
|||||||
ControlNode: &comPrivKey.PublicKey,
|
ControlNode: &comPrivKey.PublicKey,
|
||||||
ControlDevice: true,
|
ControlDevice: true,
|
||||||
ID: &comPrivKey.PublicKey,
|
ID: &comPrivKey.PublicKey,
|
||||||
}, &TimeSourceStub{}, &DescriptionEncryptorMock{})
|
}, &TimeSourceStub{}, &DescriptionEncryptorMock{}, nil)
|
||||||
s.NoError(err, "New shouldn't give any error")
|
s.NoError(err, "New shouldn't give any error")
|
||||||
|
|
||||||
md, err := com.MarshaledDescription()
|
md, err := com.MarshaledDescription()
|
||||||
|
@ -4352,15 +4352,15 @@ func (s *MessengerCommunitiesSuite) sendImageToCommunity(sender *Messenger, chat
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *MessengerCommunitiesSuite) TestSerializedCommunities() {
|
func (s *MessengerCommunitiesSuite) TestSerializedCommunities() {
|
||||||
community, _ := s.createCommunity()
|
|
||||||
addMediaServer := func(messenger *Messenger) {
|
addMediaServer := func(messenger *Messenger) {
|
||||||
mediaServer, err := server.NewMediaServer(messenger.database, nil, nil, nil)
|
mediaServer, err := server.NewMediaServer(messenger.database, nil, nil, nil)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().NoError(mediaServer.Start())
|
s.Require().NoError(mediaServer.Start())
|
||||||
messenger.httpServer = mediaServer
|
messenger.SetMediaServer(mediaServer)
|
||||||
}
|
}
|
||||||
addMediaServer(s.owner)
|
addMediaServer(s.owner)
|
||||||
|
|
||||||
|
community, _ := s.createCommunity()
|
||||||
// update community description
|
// update community description
|
||||||
description := community.Description()
|
description := community.Description()
|
||||||
identImageName := "small"
|
identImageName := "small"
|
||||||
@ -4393,7 +4393,7 @@ func (s *MessengerCommunitiesSuite) TestSerializedCommunities() {
|
|||||||
s.Len(b.Description().Identity.Images, 1)
|
s.Len(b.Description().Identity.Images, 1)
|
||||||
s.Equal(identImagePayload, b.Description().Identity.Images[identImageName].Payload)
|
s.Equal(identImagePayload, b.Description().Identity.Images[identImageName].Payload)
|
||||||
|
|
||||||
c, err := s.owner.SerializedCommunities()
|
c, err := s.owner.Communities()
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().Len(c, 1)
|
s.Require().Len(c, 1)
|
||||||
d, err := json.Marshal(c)
|
d, err := json.Marshal(c)
|
||||||
@ -4516,17 +4516,16 @@ func (s *MessengerCommunitiesSuite) fetchImage(fullURL string) ([]byte, error) {
|
|||||||
|
|
||||||
func (s *MessengerCommunitiesSuite) TestMemberMessagesHasImageLink() {
|
func (s *MessengerCommunitiesSuite) TestMemberMessagesHasImageLink() {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
community, communityChat := s.createCommunity()
|
|
||||||
|
|
||||||
addMediaServer := func(messenger *Messenger) {
|
addMediaServer := func(messenger *Messenger) {
|
||||||
mediaServer, err := server.NewMediaServer(messenger.database, nil, nil, nil)
|
mediaServer, err := server.NewMediaServer(messenger.database, nil, nil, nil)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().NoError(mediaServer.Start())
|
s.Require().NoError(mediaServer.Start())
|
||||||
messenger.httpServer = mediaServer
|
messenger.SetMediaServer(mediaServer)
|
||||||
}
|
}
|
||||||
addMediaServer(s.alice)
|
addMediaServer(s.alice)
|
||||||
addMediaServer(s.bob)
|
addMediaServer(s.bob)
|
||||||
addMediaServer(s.owner)
|
addMediaServer(s.owner)
|
||||||
|
community, communityChat := s.createCommunity()
|
||||||
|
|
||||||
request := &requests.RequestToJoinCommunity{CommunityID: community.ID()}
|
request := &requests.RequestToJoinCommunity{CommunityID: community.ID()}
|
||||||
|
|
||||||
|
@ -499,7 +499,20 @@ func NewMessenger(
|
|||||||
encryptor: encryptionProtocol,
|
encryptor: encryptionProtocol,
|
||||||
}
|
}
|
||||||
|
|
||||||
communitiesManager, err := communities.NewManager(identity, installationID, database, encryptionProtocol, logger, ensVerifier, c.communityTokensService, transp, transp, communitiesKeyDistributor, managerOptions...)
|
communitiesManager, err := communities.NewManager(
|
||||||
|
identity,
|
||||||
|
installationID,
|
||||||
|
database,
|
||||||
|
encryptionProtocol,
|
||||||
|
logger,
|
||||||
|
ensVerifier,
|
||||||
|
c.communityTokensService,
|
||||||
|
transp,
|
||||||
|
transp,
|
||||||
|
communitiesKeyDistributor,
|
||||||
|
c.httpServer,
|
||||||
|
managerOptions...,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -931,6 +944,11 @@ func (m *Messenger) Start() (*MessengerResponse, error) {
|
|||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Messenger) SetMediaServer(server *server.MediaServer) {
|
||||||
|
m.httpServer = server
|
||||||
|
m.communitiesManager.SetMediaServer(server)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Messenger) IdentityPublicKey() *ecdsa.PublicKey {
|
func (m *Messenger) IdentityPublicKey() *ecdsa.PublicKey {
|
||||||
return &m.identity.PublicKey
|
return &m.identity.PublicKey
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ func (s *MessengerActivityCenterMessageSuite) TestReplyWithImage() {
|
|||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().NotNil(mediaServer)
|
s.Require().NotNil(mediaServer)
|
||||||
s.Require().NoError(mediaServer.Start())
|
s.Require().NoError(mediaServer.Start())
|
||||||
alice.httpServer = mediaServer
|
alice.SetMediaServer(mediaServer)
|
||||||
|
|
||||||
// Create a community
|
// Create a community
|
||||||
community, chat := s.createCommunity(bob)
|
community, chat := s.createCommunity(bob)
|
||||||
|
@ -4839,22 +4839,6 @@ func (m *Messenger) CreateResponseWithACNotification(communityID string, acType
|
|||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Messenger) SerializedCommunities() ([]json.RawMessage, error) {
|
|
||||||
cs, err := m.Communities()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
res := make([]json.RawMessage, 0, len(cs))
|
|
||||||
for _, c := range cs {
|
|
||||||
b, err := c.MarshalJSONWithMediaServer(m.httpServer)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
res = append(res, b)
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendMessageToControlNode sends a message to the control node of the community.
|
// SendMessageToControlNode sends a message to the control node of the community.
|
||||||
// use pointer to rawMessage to get the message ID and other updated properties.
|
// use pointer to rawMessage to get the message ID and other updated properties.
|
||||||
func (m *Messenger) SendMessageToControlNode(community *communities.Community, rawMessage *common.RawMessage) ([]byte, error) {
|
func (m *Messenger) SendMessageToControlNode(community *communities.Community, rawMessage *common.RawMessage) ([]byte, error) {
|
||||||
|
@ -502,7 +502,7 @@ func (s *MessengerRemoveMessageSuite) TestDeleteMessageReplyToImage() {
|
|||||||
s.Require().NotNil(mediaServer)
|
s.Require().NotNil(mediaServer)
|
||||||
s.Require().NoError(mediaServer.Start())
|
s.Require().NoError(mediaServer.Start())
|
||||||
|
|
||||||
theirMessenger.httpServer = mediaServer
|
theirMessenger.SetMediaServer(mediaServer)
|
||||||
|
|
||||||
// We reply to our own message with an image
|
// We reply to our own message with an image
|
||||||
imageMessage, err := buildImageWithoutAlbumIDMessage(*theirChat)
|
imageMessage, err := buildImageWithoutAlbumIDMessage(*theirChat)
|
||||||
@ -555,7 +555,7 @@ func (s *MessengerRemoveMessageSuite) TestDeleteMessageForMeReplyToImage() {
|
|||||||
s.Require().NotNil(mediaServer)
|
s.Require().NotNil(mediaServer)
|
||||||
s.Require().NoError(mediaServer.Start())
|
s.Require().NoError(mediaServer.Start())
|
||||||
|
|
||||||
theirMessenger.httpServer = mediaServer
|
theirMessenger.SetMediaServer(mediaServer)
|
||||||
|
|
||||||
// We reply to our own message with an image
|
// We reply to our own message with an image
|
||||||
imageMessage, err := buildImageWithoutAlbumIDMessage(*theirChat)
|
imageMessage, err := buildImageWithoutAlbumIDMessage(*theirChat)
|
||||||
|
@ -2269,7 +2269,7 @@ func (s *MessengerSuite) TestSendMessageWithPreviews() {
|
|||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
err = httpServer.SetPort(9876)
|
err = httpServer.SetPort(9876)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
s.m.httpServer = httpServer
|
s.m.SetMediaServer(httpServer)
|
||||||
|
|
||||||
chat := CreatePublicChat("test-chat", s.m.transport)
|
chat := CreatePublicChat("test-chat", s.m.transport)
|
||||||
err = s.m.SaveChat(chat)
|
err = s.m.SaveChat(chat)
|
||||||
|
@ -217,7 +217,7 @@ func (s *TestMessengerPrepareMessageSuite) Test_WHEN_MessageContainsImage_THEN_P
|
|||||||
mediaServer, err := server.NewMediaServer(s.m.database, nil, nil, nil)
|
mediaServer, err := server.NewMediaServer(s.m.database, nil, nil, nil)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().NoError(mediaServer.Start())
|
s.Require().NoError(mediaServer.Start())
|
||||||
s.m.httpServer = mediaServer
|
s.m.SetMediaServer(mediaServer)
|
||||||
|
|
||||||
// WHEN: message is prepared
|
// WHEN: message is prepared
|
||||||
loadedMessage, err := s.m.MessageByID(message.ID)
|
loadedMessage, err := s.m.MessageByID(message.ID)
|
||||||
|
6
server/server_media_interface.go
Normal file
6
server/server_media_interface.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
type MediaServerInterface interface {
|
||||||
|
MakeCommunityDescriptionTokenImageURL(communityID, symbol string) string
|
||||||
|
MakeCommunityImageURL(communityID, name string) string
|
||||||
|
}
|
@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
@ -395,16 +394,13 @@ func (api *PublicAPI) SetInstallationName(installationID string, name string) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Communities returns a list of communities that are stored
|
// Communities returns a list of communities that are stored
|
||||||
// Deprecated: Use SerializedCommunities instead
|
|
||||||
func (api *PublicAPI) Communities(parent context.Context) ([]*communities.Community, error) {
|
func (api *PublicAPI) Communities(parent context.Context) ([]*communities.Community, error) {
|
||||||
return api.service.messenger.Communities()
|
return api.service.messenger.Communities()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SerializedCommunities returns a list of serialized communities.
|
// Deprecated: renamed back to Communities. Should be removed after implementing on all platforms
|
||||||
// The key difference from the Communities function is that it uses MediaServer
|
func (api *PublicAPI) SerializedCommunities(parent context.Context) ([]*communities.Community, error) {
|
||||||
// to construct image URLs for all the images rather than using base64 encoding.
|
return api.Communities(parent)
|
||||||
func (api *PublicAPI) SerializedCommunities(parent context.Context) ([]json.RawMessage, error) {
|
|
||||||
return api.service.messenger.SerializedCommunities()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// JoinedCommunities returns a list of communities that the user has joined
|
// JoinedCommunities returns a list of communities that the user has joined
|
||||||
|
Loading…
x
Reference in New Issue
Block a user