diff --git a/appdatabase/migrations/bindata.go b/appdatabase/migrations/bindata.go index c874752f6..353d5db28 100644 --- a/appdatabase/migrations/bindata.go +++ b/appdatabase/migrations/bindata.go @@ -27,6 +27,7 @@ // 1655462032_create_bookmarks_deleted_at_index.up.sql (81B) // 1657617291_add_multi_transactions_table.up.sql (412B) // 1660134042_add_social_links_settings_table.up.sql (334B) +// 1660134060_settings_bio.up.sql (91B) // doc.go (74B) package migrations @@ -636,6 +637,26 @@ func _1660134042_add_social_links_settings_tableUpSql() (*asset, error) { return a, nil } +var __1660134060_settings_bioUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\x28\x4e\x2d\x29\xc9\xcc\x4b\x2f\x56\x70\x74\x71\x51\x70\xf6\xf7\x09\xf5\xf5\x53\x48\xca\xcc\x57\x08\x71\x8d\x08\x51\xf0\xf3\x0f\x51\xf0\x0b\xf5\xf1\x51\x70\x71\x75\x73\x0c\xf5\x09\x51\x50\x52\xb2\xe6\x0a\x0d\x70\x71\x0c\x41\xd2\x18\xec\x1a\x02\xd6\x61\x0b\x92\x05\x04\x00\x00\xff\xff\xe2\x7f\x74\xc2\x5b\x00\x00\x00") + +func _1660134060_settings_bioUpSqlBytes() ([]byte, error) { + return bindataRead( + __1660134060_settings_bioUpSql, + "1660134060_settings_bio.up.sql", + ) +} + +func _1660134060_settings_bioUpSql() (*asset, error) { + bytes, err := _1660134060_settings_bioUpSqlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "1660134060_settings_bio.up.sql", size: 91, mode: os.FileMode(0664), modTime: time.Unix(1660134283, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x46, 0x25, 0xa0, 0xa6, 0x47, 0xff, 0xbc, 0x2a, 0x0, 0xff, 0x59, 0x4b, 0xb0, 0xc9, 0x4e, 0x15, 0xe4, 0xd9, 0xda, 0xeb, 0xfe, 0x55, 0x98, 0xc3, 0x9d, 0x96, 0xe7, 0xf, 0xd1, 0x5c, 0x93, 0x73}} + return a, nil +} + var _docGo = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\xc9\xb1\x0d\xc4\x20\x0c\x05\xd0\x9e\x29\xfe\x02\xd8\xfd\x6d\xe3\x4b\xac\x2f\x44\x82\x09\x78\x7f\xa5\x49\xfd\xa6\x1d\xdd\xe8\xd8\xcf\x55\x8a\x2a\xe3\x47\x1f\xbe\x2c\x1d\x8c\xfa\x6f\xe3\xb4\x34\xd4\xd9\x89\xbb\x71\x59\xb6\x18\x1b\x35\x20\xa2\x9f\x0a\x03\xa2\xe5\x0d\x00\x00\xff\xff\x60\xcd\x06\xbe\x4a\x00\x00\x00") func docGoBytes() ([]byte, error) { @@ -801,6 +822,8 @@ var _bindata = map[string]func() (*asset, error){ "1660134042_add_social_links_settings_table.up.sql": _1660134042_add_social_links_settings_tableUpSql, + "1660134060_settings_bio.up.sql": _1660134060_settings_bioUpSql, + "doc.go": docGo, } @@ -872,7 +895,8 @@ var _bintree = &bintree{nil, map[string]*bintree{ "1655462032_create_bookmarks_deleted_at_index.up.sql": &bintree{_1655462032_create_bookmarks_deleted_at_indexUpSql, map[string]*bintree{}}, "1657617291_add_multi_transactions_table.up.sql": &bintree{_1657617291_add_multi_transactions_tableUpSql, map[string]*bintree{}}, "1660134042_add_social_links_settings_table.up.sql": &bintree{_1660134042_add_social_links_settings_tableUpSql, map[string]*bintree{}}, - "doc.go": &bintree{docGo, map[string]*bintree{}}, + "1660134060_settings_bio.up.sql": &bintree{_1660134060_settings_bioUpSql, map[string]*bintree{}}, + "doc.go": &bintree{docGo, map[string]*bintree{}}, }} // RestoreAsset restores an asset under the given directory. diff --git a/appdatabase/migrations/sql/1660134060_settings_bio.up.sql b/appdatabase/migrations/sql/1660134060_settings_bio.up.sql new file mode 100644 index 000000000..a82be37de --- /dev/null +++ b/appdatabase/migrations/sql/1660134060_settings_bio.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE settings ADD COLUMN bio TEXT NOT NULL DEFAULT ""; +UPDATE settings SET bio = ""; \ No newline at end of file diff --git a/multiaccounts/settings/columns.go b/multiaccounts/settings/columns.go index 060cd776c..3a963d476 100644 --- a/multiaccounts/settings/columns.go +++ b/multiaccounts/settings/columns.go @@ -73,6 +73,10 @@ var ( reactFieldName: "display-name", dBColumnName: "display_name", } + Bio = SettingField{ + reactFieldName: "bio", + dBColumnName: "bio", + } EIP1581Address = SettingField{ reactFieldName: "eip1581-address", dBColumnName: "eip1581_address", diff --git a/multiaccounts/settings/database.go b/multiaccounts/settings/database.go index 209e56532..d1668fcb5 100644 --- a/multiaccounts/settings/database.go +++ b/multiaccounts/settings/database.go @@ -92,6 +92,7 @@ INSERT INTO settings ( current_network, dapps_address, display_name, + bio, eip1581_address, installation_id, key_uid, @@ -109,13 +110,14 @@ INSERT INTO settings ( wallet_root_address, synthetic_id ) VALUES ( -?,?,?,?,?,?,?,?,?,?,?, +?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,'id')`, s.Address, s.Currency, s.CurrentNetwork, s.DappsAddress, s.DisplayName, + s.Bio, s.EIP1581Address, s.InstallationID, s.KeyUID, @@ -265,7 +267,7 @@ func (db *Database) SetSettingLastSynced(setting SettingField, clock uint64) err func (db *Database) GetSettings() (Settings, error) { var s Settings - err := db.db.QueryRow("SELECT address, anon_metrics_should_send, chaos_mode, currency, current_network, custom_bootnodes, custom_bootnodes_enabled, dapps_address, display_name, eip1581_address, fleet, hide_home_tooltip, installation_id, key_uid, keycard_instance_uid, keycard_paired_on, keycard_pairing, last_updated, latest_derived_path, link_preview_request_enabled, link_previews_enabled_sites, log_level, mnemonic, name, networks, notifications_enabled, push_notifications_server_enabled, push_notifications_from_contacts_only, remote_push_notifications_enabled, send_push_notifications, push_notifications_block_mentions, photo_path, pinned_mailservers, preferred_name, preview_privacy, public_key, remember_syncing_choice, signing_phrase, stickers_packs_installed, stickers_packs_pending, stickers_recent_stickers, syncing_on_mobile_network, default_sync_period, use_mailservers, messages_from_contacts_only, usernames, appearance, profile_pictures_show_to, profile_pictures_visibility, wallet_root_address, wallet_set_up_passed, wallet_visible_tokens, waku_bloom_filter_mode, webview_allow_permission_requests, current_user_status, send_status_updates, gif_recents, gif_favorites, opensea_enabled, last_backup, backup_enabled, telemetry_server_url, auto_message_enabled, gif_api_key, test_networks_enabled, mutual_contact_enabled FROM settings WHERE synthetic_id = 'id'").Scan( + err := db.db.QueryRow("SELECT address, anon_metrics_should_send, chaos_mode, currency, current_network, custom_bootnodes, custom_bootnodes_enabled, dapps_address, display_name, bio, eip1581_address, fleet, hide_home_tooltip, installation_id, key_uid, keycard_instance_uid, keycard_paired_on, keycard_pairing, last_updated, latest_derived_path, link_preview_request_enabled, link_previews_enabled_sites, log_level, mnemonic, name, networks, notifications_enabled, push_notifications_server_enabled, push_notifications_from_contacts_only, remote_push_notifications_enabled, send_push_notifications, push_notifications_block_mentions, photo_path, pinned_mailservers, preferred_name, preview_privacy, public_key, remember_syncing_choice, signing_phrase, stickers_packs_installed, stickers_packs_pending, stickers_recent_stickers, syncing_on_mobile_network, default_sync_period, use_mailservers, messages_from_contacts_only, usernames, appearance, profile_pictures_show_to, profile_pictures_visibility, wallet_root_address, wallet_set_up_passed, wallet_visible_tokens, waku_bloom_filter_mode, webview_allow_permission_requests, current_user_status, send_status_updates, gif_recents, gif_favorites, opensea_enabled, last_backup, backup_enabled, telemetry_server_url, auto_message_enabled, gif_api_key, test_networks_enabled, mutual_contact_enabled FROM settings WHERE synthetic_id = 'id'").Scan( &s.Address, &s.AnonMetricsShouldSend, &s.ChaosMode, @@ -275,6 +277,7 @@ func (db *Database) GetSettings() (Settings, error) { &s.CustomBootnodesEnabled, &s.DappsAddress, &s.DisplayName, + &s.Bio, &s.EIP1581Address, &s.Fleet, &s.HideHomeTooltip, @@ -488,6 +491,10 @@ func (db *Database) DisplayName() (string, error) { return db.makeSelectString(DisplayName) } +func (db *Database) Bio() (string, error) { + return db.makeSelectString(Bio) +} + func (db *Database) GifAPIKey() (string, error) { return db.makeSelectString(GifAPIKey) } diff --git a/multiaccounts/settings/structs.go b/multiaccounts/settings/structs.go index 80f80f7ef..44c2afa0d 100644 --- a/multiaccounts/settings/structs.go +++ b/multiaccounts/settings/structs.go @@ -119,6 +119,7 @@ type Settings struct { CustomBootnodesEnabled *json.RawMessage `json:"custom-bootnodes-enabled?,omitempty"` DappsAddress types.Address `json:"dapps-address"` DisplayName string `json:"display-name"` + Bio string `json:"bio,omitempty"` EIP1581Address types.Address `json:"eip1581-address"` Fleet *string `json:"fleet,omitempty"` HideHomeTooltip bool `json:"hide-home-tooltip?,omitempty"` diff --git a/protocol/communities_messenger_test.go b/protocol/communities_messenger_test.go index bc6abce1f..ca59868db 100644 --- a/protocol/communities_messenger_test.go +++ b/protocol/communities_messenger_test.go @@ -500,6 +500,8 @@ func (s *MessengerCommunitiesSuite) TestCommunityContactCodeAdvertisement() { // Trigger ContactCodeAdvertisement err = patryk.SetDisplayName("patryk") s.Require().NoError(err) + err = patryk.SetBio("I like P2P chats") + s.Require().NoError(err) // Ensure alice receives patryk's ContactCodeAdvertisement err = tt.RetryWithBackOff(func() error { @@ -513,6 +515,9 @@ func (s *MessengerCommunitiesSuite) TestCommunityContactCodeAdvertisement() { if response.Contacts[0].DisplayName != "patryk" { return errors.New("display name was not updated") } + if response.Contacts[0].Bio != "I like P2P chats" { + return errors.New("bio was not updated") + } return nil }) s.Require().NoError(err) diff --git a/protocol/contact.go b/protocol/contact.go index 66839e9c1..99b59b4c2 100644 --- a/protocol/contact.go +++ b/protocol/contact.go @@ -102,6 +102,9 @@ type Contact struct { // Display name of the contact DisplayName string `json:"displayName"` + // Bio - description of the contact (tell us about yourself) + Bio string `json:"bio"` + SocialLinks identity.SocialLinks `json:"socialLinks"` Images map[string]images.IdentityImage `json:"images"` diff --git a/protocol/messenger.go b/protocol/messenger.go index fd8cda416..ff5368405 100644 --- a/protocol/messenger.go +++ b/protocol/messenger.go @@ -865,12 +865,17 @@ func (m *Messenger) attachChatIdentity(cca *protobuf.ContactCodeAdvertisement) e return err } + bio, err := m.settings.Bio() + if err != nil { + return err + } + socialLinks, err := m.settings.GetSocialLinks() if err != nil { return err } - identityHash, err := m.getIdentityHash(displayName, img, &socialLinks) + identityHash, err := m.getIdentityHash(displayName, bio, img, &socialLinks) if err != nil { return err } @@ -940,12 +945,17 @@ func (m *Messenger) handleStandaloneChatIdentity(chat *Chat) error { return err } + bio, err := m.settings.Bio() + if err != nil { + return err + } + socialLinks, err := m.settings.GetSocialLinks() if err != nil { return err } - identityHash, err := m.getIdentityHash(displayName, img, &socialLinks) + identityHash, err := m.getIdentityHash(displayName, bio, img, &socialLinks) if err != nil { return err } @@ -958,15 +968,15 @@ func (m *Messenger) handleStandaloneChatIdentity(chat *Chat) error { return nil } -func (m *Messenger) getIdentityHash(displayName string, img *userimage.IdentityImage, socialLinks *identity.SocialLinks) ([]byte, error) { +func (m *Messenger) getIdentityHash(displayName, bio string, img *userimage.IdentityImage, socialLinks *identity.SocialLinks) ([]byte, error) { socialLinksData, err := socialLinks.Serialize() if err != nil { return []byte{}, err } if img == nil { - return crypto.Keccak256([]byte(displayName), socialLinksData), nil + return crypto.Keccak256([]byte(displayName), []byte(bio), socialLinksData), nil } - return crypto.Keccak256(img.Payload, []byte(displayName), socialLinksData), nil + return crypto.Keccak256(img.Payload, []byte(displayName), []byte(bio), socialLinksData), nil } // shouldPublishChatIdentity returns true if the last time the ChatIdentity was attached was more than 24 hours ago @@ -995,12 +1005,17 @@ func (m *Messenger) shouldPublishChatIdentity(chatID string) (bool, error) { return false, err } + bio, err := m.settings.Bio() + if err != nil { + return false, err + } + socialLinks, err := m.settings.GetSocialLinks() if err != nil { return false, err } - identityHash, err := m.getIdentityHash(displayName, img, &socialLinks) + identityHash, err := m.getIdentityHash(displayName, bio, img, &socialLinks) if err != nil { return false, err } @@ -1025,6 +1040,11 @@ func (m *Messenger) createChatIdentity(context chatContext) (*protobuf.ChatIdent return nil, err } + bio, err := m.settings.Bio() + if err != nil { + return nil, err + } + socialLinks, err := m.settings.GetSocialLinks() if err != nil { return nil, err @@ -1034,6 +1054,7 @@ func (m *Messenger) createChatIdentity(context chatContext) (*protobuf.ChatIdent Clock: m.transport.GetCurrentTime(), EnsName: "", // TODO add ENS name handling to dedicate PR DisplayName: displayName, + Description: bio, SocialLinks: socialLinks.TransformToProtobuf(), } diff --git a/protocol/messenger_handler.go b/protocol/messenger_handler.go index 2bd970389..2624cb5f3 100644 --- a/protocol/messenger_handler.go +++ b/protocol/messenger_handler.go @@ -1887,6 +1887,11 @@ func (m *Messenger) HandleChatIdentity(state *ReceivedMessageState, ci protobuf. contactModified = true } + if contact.Bio != ci.Description { + contact.Bio = ci.Description + contactModified = true + } + if !contact.SocialLinks.EqualsProtobuf(ci.SocialLinks) { contact.SocialLinks = *identity.NewSocialLinks(ci.SocialLinks) contactModified = true diff --git a/protocol/messenger_display_name.go b/protocol/messenger_identity.go similarity index 65% rename from protocol/messenger_display_name.go rename to protocol/messenger_identity.go index 12f1eec9d..e2b69cb94 100644 --- a/protocol/messenger_display_name.go +++ b/protocol/messenger_identity.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/status-im/status-go/multiaccounts/settings" + "github.com/status-im/status-go/protocol/identity" "github.com/status-im/status-go/protocol/identity/alias" ) @@ -70,3 +71,53 @@ func (m *Messenger) SetDisplayName(displayName string) error { return m.publishContactCode() } + +func (m *Messenger) SetBio(bio string) error { + currentBio, err := m.settings.Bio() + if err != nil { + return err + } + + if currentBio == bio { + return nil // Do nothing + } + + // TODO: add validation + + err = m.settings.SaveSettingField(settings.Bio, bio) + if err != nil { + return err + } + + err = m.resetLastPublishedTimeForChatIdentity() + if err != nil { + return err + } + + return m.publishContactCode() +} + +func (m *Messenger) SetSocialLinks(socialLinks *identity.SocialLinks) error { + currentSocialLinks, err := m.settings.GetSocialLinks() + if err != nil { + return err + } + + if currentSocialLinks.Equals(*socialLinks) { + return nil // Do nothing + } + + // TODO: add validation + + err = m.settings.SetSocialLinks(socialLinks) + if err != nil { + return err + } + + err = m.resetLastPublishedTimeForChatIdentity() + if err != nil { + return err + } + + return m.publishContactCode() +} diff --git a/protocol/messenger_social_links.go b/protocol/messenger_social_links.go deleted file mode 100644 index 2a0ee4d58..000000000 --- a/protocol/messenger_social_links.go +++ /dev/null @@ -1,26 +0,0 @@ -package protocol - -import "github.com/status-im/status-go/protocol/identity" - -func (m *Messenger) SetSocialLinks(socialLinks *identity.SocialLinks) error { - currentSocialLinks, err := m.settings.GetSocialLinks() - if err != nil { - return err - } - - if currentSocialLinks.Equals(*socialLinks) { - return nil // Do nothing - } - - err = m.settings.SetSocialLinks(socialLinks) - if err != nil { - return err - } - - err = m.resetLastPublishedTimeForChatIdentity() - if err != nil { - return err - } - - return m.publishContactCode() -} diff --git a/services/accounts/settings.go b/services/accounts/settings.go index 29b0f08b0..388e80c72 100644 --- a/services/accounts/settings.go +++ b/services/accounts/settings.go @@ -160,6 +160,10 @@ func (api *SettingsAPI) DeleteExemptions(id string) error { return api.db.DeleteExemptions(id) } +func (api *SettingsAPI) SetBio(bio string) error { + return (*api.messenger).SetBio(bio) +} + func (api *SettingsAPI) GetSocialLinks() (identity.SocialLinks, error) { return api.db.GetSocialLinks() }