From c739f73f497b2cc1f22be0a176683193766d5193 Mon Sep 17 00:00:00 2001 From: Andrea Maria Piana Date: Wed, 7 Apr 2021 14:57:14 +0200 Subject: [PATCH] Add activity center & messages from contacts only --- VERSION | 2 +- appdatabase/migrations/bindata.go | 100 ++++--- .../sql/1618395756_contacts_only.up.sql | 2 + mailserver/migrations/bindata.go | 6 +- multiaccounts/accounts/database.go | 19 +- multiaccounts/migrations/bindata.go | 14 +- protocol/activity_center.go | 46 +++ protocol/activity_center_persistence.go | 273 ++++++++++++++++++ protocol/chat.go | 17 +- protocol/communities_messenger_test.go | 6 +- protocol/encryption/migrations/migrations.go | 34 +-- protocol/message_handler.go | 187 ++++++++++-- protocol/messenger.go | 116 ++++---- protocol/messenger_activity_center.go | 75 +++++ protocol/messenger_chats.go | 24 ++ ...{messenger_locker.go => messenger_maps.go} | 0 protocol/messenger_response.go | 38 ++- protocol/messenger_test.go | 24 +- protocol/migrations/migrations.go | 84 ++++-- .../1617694931_add_notification_center.up.sql | 16 + protocol/persistence_test.go | 130 +++++++++ .../migrations/migrations.go | 14 +- .../migrations/migrations.go | 10 +- .../transport/waku/migrations/migrations.go | 6 +- .../whisper/migrations/migrations.go | 6 +- services/ext/api.go | 32 ++ static/bindata.go | 28 +- t/bindata.go | 6 +- 28 files changed, 1085 insertions(+), 230 deletions(-) create mode 100644 appdatabase/migrations/sql/1618395756_contacts_only.up.sql create mode 100644 protocol/activity_center.go create mode 100644 protocol/activity_center_persistence.go create mode 100644 protocol/messenger_activity_center.go rename protocol/{messenger_locker.go => messenger_maps.go} (100%) create mode 100644 protocol/migrations/sqlite/1617694931_add_notification_center.up.sql diff --git a/VERSION b/VERSION index be0e1ece7..62df9f538 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.75.2 +0.76.0 diff --git a/appdatabase/migrations/bindata.go b/appdatabase/migrations/bindata.go index 05250475e..fd730b9bf 100644 --- a/appdatabase/migrations/bindata.go +++ b/appdatabase/migrations/bindata.go @@ -36,6 +36,7 @@ // 0020_metrics.up.sql (235B) // 0021_add_session_id_to_metrics.up.sql (55B) // 1618237885_settings_anon_metrics_should_send.up.sql (80B) +// 1618395756_contacts_only.up.sql (136B) // doc.go (74B) package migrations @@ -120,7 +121,7 @@ func _0001_appDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0001_app.down.sql", size: 356, mode: os.FileMode(0644), modTime: time.Unix(1589413297, 0)} + info := bindataFileInfo{name: "0001_app.down.sql", size: 356, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb5, 0x25, 0xa0, 0xf8, 0x7d, 0x2d, 0xd, 0xcf, 0x18, 0xe4, 0x73, 0xc3, 0x95, 0xf5, 0x24, 0x20, 0xa9, 0xe6, 0x9e, 0x1d, 0x93, 0xe5, 0xc5, 0xad, 0x93, 0x8f, 0x5e, 0x40, 0xb5, 0x30, 0xaa, 0x25}} return a, nil } @@ -140,7 +141,7 @@ func _0001_appUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0001_app.up.sql", size: 2967, mode: os.FileMode(0644), modTime: time.Unix(1589413297, 0)} + info := bindataFileInfo{name: "0001_app.up.sql", size: 2967, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf7, 0x3a, 0xa7, 0xf2, 0x8f, 0xfa, 0x82, 0x7c, 0xc5, 0x49, 0xac, 0xac, 0xf, 0xc, 0x77, 0xe2, 0xba, 0xe8, 0x4d, 0xe, 0x6f, 0x5d, 0x2c, 0x2c, 0x18, 0x80, 0xc2, 0x1d, 0xe, 0x25, 0xe, 0x18}} return a, nil } @@ -160,7 +161,7 @@ func _0002_tokensDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0002_tokens.down.sql", size: 19, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "0002_tokens.down.sql", size: 19, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd1, 0x31, 0x2, 0xcc, 0x2f, 0x38, 0x90, 0xf7, 0x58, 0x37, 0x47, 0xf4, 0x18, 0xf7, 0x72, 0x74, 0x67, 0x14, 0x7e, 0xf3, 0xb1, 0xd6, 0x5f, 0xb0, 0xd5, 0xe7, 0x91, 0xf4, 0x26, 0x77, 0x8e, 0x68}} return a, nil } @@ -180,7 +181,7 @@ func _0002_tokensUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0002_tokens.up.sql", size: 248, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "0002_tokens.up.sql", size: 248, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xcc, 0xd6, 0xde, 0xd3, 0x7b, 0xee, 0x92, 0x11, 0x38, 0xa4, 0xeb, 0x84, 0xca, 0xcb, 0x37, 0x75, 0x5, 0x77, 0x7f, 0x14, 0x39, 0xee, 0xa1, 0x8b, 0xd4, 0x5c, 0x6e, 0x55, 0x6, 0x50, 0x16, 0xd4}} return a, nil } @@ -200,7 +201,7 @@ func _0003_settingsDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0003_settings.down.sql", size: 118, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "0003_settings.down.sql", size: 118, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe5, 0xa6, 0xf5, 0xc0, 0x60, 0x64, 0x77, 0xe2, 0xe7, 0x3c, 0x9b, 0xb1, 0x52, 0xa9, 0x95, 0x16, 0xf8, 0x60, 0x2f, 0xa5, 0xeb, 0x46, 0xb9, 0xb9, 0x8f, 0x4c, 0xf4, 0xfd, 0xbb, 0xe7, 0xe5, 0xe5}} return a, nil } @@ -220,7 +221,7 @@ func _0003_settingsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0003_settings.up.sql", size: 1311, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "0003_settings.up.sql", size: 1311, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xea, 0x35, 0x0, 0xeb, 0xe2, 0x33, 0x68, 0xb9, 0xf4, 0xf6, 0x8e, 0x9e, 0x10, 0xe9, 0x58, 0x68, 0x28, 0xb, 0xcd, 0xec, 0x74, 0x71, 0xa7, 0x9a, 0x5a, 0x77, 0x59, 0xb1, 0x13, 0x1c, 0xa1, 0x5b}} return a, nil } @@ -240,7 +241,7 @@ func _0004_pending_stickersDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0004_pending_stickers.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1589413297, 0)} + info := bindataFileInfo{name: "0004_pending_stickers.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}} return a, nil } @@ -260,7 +261,7 @@ func _0004_pending_stickersUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0004_pending_stickers.up.sql", size: 61, mode: os.FileMode(0644), modTime: time.Unix(1589413297, 0)} + info := bindataFileInfo{name: "0004_pending_stickers.up.sql", size: 61, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3c, 0xed, 0x25, 0xdf, 0x75, 0x2, 0x6c, 0xf0, 0xa2, 0xa8, 0x37, 0x62, 0x65, 0xad, 0xfd, 0x98, 0xa0, 0x9d, 0x63, 0x94, 0xdf, 0x6b, 0x46, 0xe0, 0x68, 0xec, 0x9c, 0x7f, 0x77, 0xdd, 0xb3, 0x6}} return a, nil } @@ -280,7 +281,7 @@ func _0005_waku_modeDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0005_waku_mode.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1589413297, 0)} + info := bindataFileInfo{name: "0005_waku_mode.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}} return a, nil } @@ -300,7 +301,7 @@ func _0005_waku_modeUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0005_waku_mode.up.sql", size: 146, mode: os.FileMode(0644), modTime: time.Unix(1589413297, 0)} + info := bindataFileInfo{name: "0005_waku_mode.up.sql", size: 146, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa6, 0x91, 0xc, 0xd7, 0x89, 0x61, 0x2e, 0x4c, 0x5a, 0xb6, 0x67, 0xd1, 0xc1, 0x42, 0x24, 0x38, 0xd6, 0x1b, 0x75, 0x41, 0x9c, 0x23, 0xb0, 0xca, 0x5c, 0xf1, 0x5c, 0xd0, 0x13, 0x92, 0x3e, 0xe1}} return a, nil } @@ -320,7 +321,7 @@ func _0006_appearanceUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0006_appearance.up.sql", size: 67, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0006_appearance.up.sql", size: 67, mode: os.FileMode(0644), modTime: time.Unix(1609934130, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xae, 0x6, 0x25, 0x6c, 0xe4, 0x9d, 0xa7, 0x72, 0xe8, 0xbc, 0xe4, 0x1f, 0x1e, 0x2d, 0x7c, 0xb7, 0xf6, 0xa3, 0xec, 0x3b, 0x4e, 0x93, 0x2e, 0xa4, 0xec, 0x6f, 0xe5, 0x95, 0x94, 0xe8, 0x4, 0xfb}} return a, nil } @@ -340,7 +341,7 @@ func _0007_enable_waku_defaultUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0007_enable_waku_default.up.sql", size: 38, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0007_enable_waku_default.up.sql", size: 38, mode: os.FileMode(0644), modTime: time.Unix(1609934130, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd4, 0x42, 0xb6, 0xe5, 0x48, 0x41, 0xeb, 0xc0, 0x7e, 0x3b, 0xe6, 0x8e, 0x96, 0x33, 0x20, 0x92, 0x24, 0x5a, 0x60, 0xfa, 0xa0, 0x3, 0x5e, 0x76, 0x4b, 0x89, 0xaa, 0x37, 0x66, 0xbc, 0x26, 0x11}} return a, nil } @@ -360,7 +361,7 @@ func _0008_add_push_notificationsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0008_add_push_notifications.up.sql", size: 349, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0008_add_push_notifications.up.sql", size: 349, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x5a, 0x0, 0xbf, 0xd0, 0xdd, 0xcd, 0x73, 0xe0, 0x7c, 0x56, 0xef, 0xdc, 0x57, 0x61, 0x94, 0x64, 0x70, 0xb9, 0xfa, 0xa1, 0x2a, 0x36, 0xc, 0x2f, 0xf8, 0x95, 0xa, 0x57, 0x3e, 0x7a, 0xd7, 0x12}} return a, nil } @@ -380,7 +381,7 @@ func _0009_enable_sending_push_notificationsDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0009_enable_sending_push_notifications.down.sql", size: 49, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0009_enable_sending_push_notifications.down.sql", size: 49, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe9, 0xae, 0x1b, 0x41, 0xcb, 0x9c, 0x2c, 0x93, 0xc6, 0x2a, 0x77, 0x3, 0xb9, 0x51, 0xe0, 0x68, 0x68, 0x0, 0xf7, 0x5b, 0xb3, 0x1e, 0x94, 0x44, 0xba, 0x9c, 0xd0, 0x3b, 0x80, 0x21, 0x6f, 0xb5}} return a, nil } @@ -400,7 +401,7 @@ func _0009_enable_sending_push_notificationsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0009_enable_sending_push_notifications.up.sql", size: 49, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0009_enable_sending_push_notifications.up.sql", size: 49, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1b, 0x80, 0xe4, 0x9c, 0xc8, 0xb8, 0xd5, 0xef, 0xce, 0x74, 0x9b, 0x7b, 0xdd, 0xa, 0x99, 0x1e, 0xef, 0x7f, 0xb8, 0x99, 0x84, 0x4, 0x0, 0x6b, 0x1d, 0x2c, 0xa, 0xf8, 0x2c, 0x4f, 0xb5, 0x44}} return a, nil } @@ -420,7 +421,7 @@ func _0010_add_block_mentionsDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0010_add_block_mentions.down.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0010_add_block_mentions.down.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x6d, 0x9e, 0x27, 0x1e, 0xba, 0x9f, 0xca, 0xae, 0x98, 0x2e, 0x6e, 0xe3, 0xdd, 0xac, 0x73, 0x34, 0x4e, 0x69, 0x92, 0xb5, 0xf6, 0x9, 0xab, 0x50, 0x35, 0xd, 0xee, 0xeb, 0x3e, 0xcc, 0x7e, 0xce}} return a, nil } @@ -440,7 +441,7 @@ func _0010_add_block_mentionsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0010_add_block_mentions.up.sql", size: 89, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0010_add_block_mentions.up.sql", size: 89, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd7, 0x23, 0x85, 0xa2, 0xb5, 0xb6, 0xb4, 0x3f, 0xdc, 0x4e, 0xff, 0xe2, 0x6b, 0x66, 0x68, 0x5e, 0xb2, 0xb4, 0x14, 0xb2, 0x1b, 0x4d, 0xb1, 0xce, 0xf7, 0x6, 0x58, 0xa7, 0xaf, 0x93, 0x3f, 0x25}} return a, nil } @@ -460,7 +461,7 @@ func _0011_allow_webview_permission_requestsDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0011_allow_webview_permission_requests.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0011_allow_webview_permission_requests.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}} return a, nil } @@ -480,7 +481,7 @@ func _0011_allow_webview_permission_requestsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0011_allow_webview_permission_requests.up.sql", size: 88, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0011_allow_webview_permission_requests.up.sql", size: 88, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x43, 0x5f, 0x22, 0x4c, 0x98, 0x1d, 0xc6, 0xf4, 0x89, 0xaf, 0xf4, 0x44, 0xba, 0xf8, 0x28, 0xa7, 0xb5, 0xb9, 0xf0, 0xf2, 0xcb, 0x5, 0x59, 0x7a, 0xc, 0xdf, 0xd3, 0x38, 0xa4, 0xb8, 0x98, 0xc2}} return a, nil } @@ -500,7 +501,7 @@ func _0012_pending_transactionsDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0012_pending_transactions.down.sql", size: 33, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0012_pending_transactions.down.sql", size: 33, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7e, 0x41, 0xfe, 0x5c, 0xd8, 0xc3, 0x29, 0xfd, 0x31, 0x78, 0x99, 0x7a, 0xeb, 0x17, 0x62, 0x88, 0x41, 0xb3, 0xe7, 0xb5, 0x5, 0x0, 0x90, 0xa1, 0x7, 0x1a, 0x23, 0x88, 0x81, 0xba, 0x56, 0x9d}} return a, nil } @@ -520,7 +521,7 @@ func _0012_pending_transactionsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0012_pending_transactions.up.sql", size: 321, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0012_pending_transactions.up.sql", size: 321, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd, 0x17, 0xff, 0xd7, 0xa7, 0x49, 0x1e, 0x7b, 0x34, 0x63, 0x7c, 0x53, 0xaa, 0x6b, 0x2d, 0xc8, 0xe0, 0x82, 0x21, 0x90, 0x3a, 0x94, 0xf1, 0xa6, 0xe4, 0x70, 0xe5, 0x85, 0x1a, 0x48, 0x25, 0xb}} return a, nil } @@ -540,7 +541,7 @@ func _0013_favouritesDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0013_favourites.down.sql", size: 23, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0013_favourites.down.sql", size: 23, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x32, 0xf8, 0x55, 0x13, 0x4f, 0x4a, 0x19, 0x83, 0x9c, 0xda, 0x34, 0xb8, 0x3, 0x54, 0x82, 0x1e, 0x99, 0x36, 0x6b, 0x42, 0x3, 0xf6, 0x43, 0xde, 0xe6, 0x32, 0xb6, 0xdf, 0xe2, 0x59, 0x8c, 0x84}} return a, nil } @@ -560,7 +561,7 @@ func _0013_favouritesUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0013_favourites.up.sql", size: 132, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0013_favourites.up.sql", size: 132, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xbe, 0x1, 0x27, 0x38, 0x76, 0xf5, 0xcb, 0x61, 0xda, 0x5b, 0xce, 0xd9, 0x8b, 0x18, 0x77, 0x61, 0x84, 0xe7, 0x22, 0xe2, 0x13, 0x99, 0xab, 0x32, 0xbc, 0xbe, 0xed, 0x1f, 0x2f, 0xb0, 0xe4, 0x8d}} return a, nil } @@ -580,7 +581,7 @@ func _0014_add_use_mailserversDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0014_add_use_mailservers.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0014_add_use_mailservers.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}} return a, nil } @@ -600,7 +601,7 @@ func _0014_add_use_mailserversUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0014_add_use_mailservers.up.sql", size: 111, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0014_add_use_mailservers.up.sql", size: 111, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc9, 0xba, 0x65, 0xbf, 0x1b, 0xc9, 0x6d, 0x45, 0xf2, 0xf5, 0x30, 0x7c, 0xc1, 0xde, 0xb8, 0xe3, 0x3f, 0xa9, 0x2f, 0x9f, 0xea, 0x1, 0x29, 0x29, 0x65, 0xe7, 0x38, 0xab, 0xa4, 0x62, 0xf, 0xd0}} return a, nil } @@ -620,7 +621,7 @@ func _0015_link_previewsDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0015_link_previews.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0015_link_previews.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}} return a, nil } @@ -640,7 +641,7 @@ func _0015_link_previewsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0015_link_previews.up.sql", size: 203, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0015_link_previews.up.sql", size: 203, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb1, 0xf7, 0x38, 0x25, 0xa6, 0xfc, 0x6b, 0x9, 0xe4, 0xd9, 0xbf, 0x58, 0x7b, 0x80, 0xd8, 0x48, 0x63, 0xde, 0xa5, 0x5e, 0x30, 0xa3, 0xeb, 0x68, 0x8e, 0x6a, 0x9f, 0xfd, 0xf4, 0x46, 0x41, 0x34}} return a, nil } @@ -660,7 +661,7 @@ func _0016_local_notifications_preferencesDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0016_local_notifications_preferences.down.sql", size: 43, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0016_local_notifications_preferences.down.sql", size: 43, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe0, 0x50, 0xc7, 0xdd, 0x53, 0x9c, 0x5d, 0x1e, 0xb5, 0x71, 0x25, 0x50, 0x58, 0xcf, 0x6d, 0xbe, 0x5a, 0x8, 0x12, 0xc9, 0x13, 0xd, 0x9a, 0x3d, 0x4b, 0x7a, 0x2f, 0x1b, 0xe5, 0x23, 0x52, 0x78}} return a, nil } @@ -680,7 +681,7 @@ func _0016_local_notifications_preferencesUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0016_local_notifications_preferences.up.sql", size: 204, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0016_local_notifications_preferences.up.sql", size: 204, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3f, 0x3a, 0x16, 0x25, 0xdf, 0xba, 0x62, 0xd3, 0x81, 0x73, 0xc, 0x10, 0x85, 0xbc, 0x8d, 0xe, 0x1d, 0x62, 0xcb, 0xb, 0x6d, 0x8c, 0x4f, 0x63, 0x5f, 0xe2, 0xd, 0xc5, 0x46, 0xa8, 0x35, 0x5b}} return a, nil } @@ -700,7 +701,7 @@ func _0017_bookmarksDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0017_bookmarks.down.sql", size: 22, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0017_bookmarks.down.sql", size: 22, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x9a, 0x13, 0x2a, 0x44, 0xb0, 0x3, 0x18, 0x63, 0xb8, 0x33, 0xda, 0x3a, 0xeb, 0xb8, 0xcb, 0xd1, 0x98, 0x29, 0xa7, 0xf0, 0x6, 0x9d, 0xc9, 0x62, 0xe7, 0x89, 0x7f, 0x77, 0xaf, 0xec, 0x6b, 0x8f}} return a, nil } @@ -720,7 +721,7 @@ func _0017_bookmarksUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0017_bookmarks.up.sql", size: 147, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0017_bookmarks.up.sql", size: 147, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xbc, 0x47, 0xe1, 0xe3, 0xd8, 0xc6, 0x4, 0x6d, 0x5f, 0x2f, 0xa, 0x51, 0xa6, 0x8c, 0x6a, 0xe0, 0x3d, 0x8c, 0x91, 0x47, 0xbc, 0x1, 0x75, 0x46, 0x92, 0x2, 0x18, 0x6e, 0xe3, 0x4f, 0x18, 0x57}} return a, nil } @@ -740,7 +741,7 @@ func _0018_profile_pictures_visibilityUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0018_profile_pictures_visibility.up.sql", size: 84, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0018_profile_pictures_visibility.up.sql", size: 84, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc9, 0xe3, 0xc5, 0xec, 0x83, 0x55, 0x45, 0x57, 0x7a, 0xaa, 0xd2, 0xa7, 0x59, 0xa7, 0x87, 0xef, 0x63, 0x19, 0x9c, 0x46, 0x9c, 0xc5, 0x32, 0x89, 0xa4, 0x68, 0x70, 0xd8, 0x83, 0x43, 0xa4, 0x72}} return a, nil } @@ -760,7 +761,7 @@ func _0019_blocks_ranges_extra_dataUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0019_blocks_ranges_extra_data.up.sql", size: 89, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0019_blocks_ranges_extra_data.up.sql", size: 89, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa3, 0x96, 0x32, 0x58, 0xf0, 0xb9, 0xe1, 0x70, 0x81, 0xca, 0x8d, 0x45, 0x57, 0x8a, 0x7, 0x5d, 0x9e, 0x2a, 0x30, 0xb, 0xad, 0x5f, 0xf8, 0xd4, 0x30, 0x94, 0x73, 0x37, 0x8d, 0xc1, 0x9a, 0xed}} return a, nil } @@ -780,7 +781,7 @@ func _0020_metricsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0020_metrics.up.sql", size: 235, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "0020_metrics.up.sql", size: 235, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe8, 0x32, 0xbc, 0xb6, 0x9b, 0x5a, 0x8f, 0x9f, 0x4c, 0x90, 0x81, 0x3e, 0x2e, 0xd1, 0x23, 0xcd, 0xf1, 0x83, 0x35, 0xca, 0x66, 0x87, 0x52, 0x4e, 0x30, 0x3e, 0x4f, 0xa8, 0xfd, 0x30, 0x16, 0xbd}} return a, nil } @@ -800,7 +801,7 @@ func _0021_add_session_id_to_metricsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0021_add_session_id_to_metrics.up.sql", size: 55, mode: os.FileMode(0644), modTime: time.Unix(1618237288, 0)} + info := bindataFileInfo{name: "0021_add_session_id_to_metrics.up.sql", size: 55, mode: os.FileMode(0644), modTime: time.Unix(1618558805, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb7, 0x81, 0xfc, 0x97, 0xd1, 0x8b, 0xea, 0x8e, 0xd7, 0xc2, 0x53, 0x62, 0xe9, 0xbc, 0xf, 0x8c, 0x46, 0x41, 0x41, 0xb7, 0x6, 0x35, 0xf5, 0xba, 0xbb, 0x28, 0x50, 0x48, 0xbf, 0x36, 0x90, 0x5c}} return a, nil } @@ -820,11 +821,31 @@ func _1618237885_settings_anon_metrics_should_sendUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1618237885_settings_anon_metrics_should_send.up.sql", size: 80, mode: os.FileMode(0644), modTime: time.Unix(1618237288, 0)} + info := bindataFileInfo{name: "1618237885_settings_anon_metrics_should_send.up.sql", size: 80, mode: os.FileMode(0644), modTime: time.Unix(1618558805, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xea, 0x6c, 0x1d, 0x1f, 0x54, 0x62, 0x18, 0x22, 0x5c, 0xa7, 0x8c, 0x59, 0x24, 0xd3, 0x4d, 0x55, 0xc4, 0x2a, 0x9e, 0x4c, 0x37, 0x6b, 0xfd, 0xac, 0xec, 0xb7, 0x68, 0x21, 0x26, 0x26, 0xf3, 0x92}} return a, nil } +var __1618395756_contacts_onlyUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\xcc\x31\x0e\xc2\x30\x0c\x05\xd0\xbd\xa7\xf8\x47\x60\xaf\x18\x5c\xe2\x4e\xa6\x41\xd4\x99\xa3\xaa\x0a\x15\x12\x49\x24\xec\x85\xdb\xb3\x32\x71\x81\x47\xa2\x7c\x87\xd2\x24\x0c\x2b\xee\xcf\x76\x18\x28\x04\x5c\xa2\xa4\xeb\x82\x5a\xcc\xb6\xa3\x58\x7e\xbc\x7b\xcd\x7b\x6f\xbe\xed\x6e\xb9\xb7\xd7\x07\x53\x8c\xc2\xb4\x20\xf0\x4c\x49\x14\x33\xc9\xca\xe3\x90\x6e\x81\xf4\x47\x5b\x59\xff\x32\x67\x9c\xc6\xe1\x1b\x00\x00\xff\xff\x99\x20\xa4\x1d\x88\x00\x00\x00") + +func _1618395756_contacts_onlyUpSqlBytes() ([]byte, error) { + return bindataRead( + __1618395756_contacts_onlyUpSql, + "1618395756_contacts_only.up.sql", + ) +} + +func _1618395756_contacts_onlyUpSql() (*asset, error) { + bytes, err := _1618395756_contacts_onlyUpSqlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "1618395756_contacts_only.up.sql", size: 136, mode: os.FileMode(0644), modTime: time.Unix(1618577521, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1, 0xe3, 0xd0, 0xe7, 0xf2, 0x6e, 0xbf, 0x27, 0xf6, 0xe2, 0x2e, 0x16, 0x4b, 0x52, 0x3b, 0xcf, 0x63, 0x52, 0xfc, 0x1d, 0x43, 0xba, 0x42, 0xf9, 0x1e, 0x1e, 0x39, 0x40, 0xed, 0x0, 0x20, 0xa8}} + 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) { @@ -840,7 +861,7 @@ func docGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0x7c, 0x28, 0xcd, 0x47, 0xf2, 0xfa, 0x7c, 0x51, 0x2d, 0xd8, 0x38, 0xb, 0xb0, 0x34, 0x9d, 0x4c, 0x62, 0xa, 0x9e, 0x28, 0xc3, 0x31, 0x23, 0xd9, 0xbb, 0x89, 0x9f, 0xa0, 0x89, 0x1f, 0xe8}} return a, nil } @@ -1008,6 +1029,8 @@ var _bindata = map[string]func() (*asset, error){ "1618237885_settings_anon_metrics_should_send.up.sql": _1618237885_settings_anon_metrics_should_sendUpSql, + "1618395756_contacts_only.up.sql": _1618395756_contacts_onlyUpSql, + "doc.go": docGo, } @@ -1088,7 +1111,8 @@ var _bintree = &bintree{nil, map[string]*bintree{ "0020_metrics.up.sql": &bintree{_0020_metricsUpSql, map[string]*bintree{}}, "0021_add_session_id_to_metrics.up.sql": &bintree{_0021_add_session_id_to_metricsUpSql, map[string]*bintree{}}, "1618237885_settings_anon_metrics_should_send.up.sql": &bintree{_1618237885_settings_anon_metrics_should_sendUpSql, map[string]*bintree{}}, - "doc.go": &bintree{docGo, map[string]*bintree{}}, + "1618395756_contacts_only.up.sql": &bintree{_1618395756_contacts_onlyUpSql, map[string]*bintree{}}, + "doc.go": &bintree{docGo, map[string]*bintree{}}, }} // RestoreAsset restores an asset under the given directory. diff --git a/appdatabase/migrations/sql/1618395756_contacts_only.up.sql b/appdatabase/migrations/sql/1618395756_contacts_only.up.sql new file mode 100644 index 000000000..84ba2cef4 --- /dev/null +++ b/appdatabase/migrations/sql/1618395756_contacts_only.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE settings ADD COLUMN messages_from_contacts_only BOOLEAN DEFAULT FALSE; +UPDATE settings SET messages_from_contacts_only = 0; diff --git a/mailserver/migrations/bindata.go b/mailserver/migrations/bindata.go index fd799b44d..a6b468809 100644 --- a/mailserver/migrations/bindata.go +++ b/mailserver/migrations/bindata.go @@ -86,7 +86,7 @@ func _1557732988_initialize_dbDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1557732988_initialize_db.down.sql", size: 72, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1557732988_initialize_db.down.sql", size: 72, mode: os.FileMode(0644), modTime: time.Unix(1599559877, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x77, 0x40, 0x78, 0xb7, 0x71, 0x3c, 0x20, 0x3b, 0xc9, 0xb, 0x2f, 0x49, 0xe4, 0xff, 0x1c, 0x84, 0x54, 0xa1, 0x30, 0xe3, 0x90, 0xf8, 0x73, 0xda, 0xb0, 0x2a, 0xea, 0x8e, 0xf1, 0x82, 0xe7, 0xd2}} return a, nil } @@ -106,7 +106,7 @@ func _1557732988_initialize_dbUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1557732988_initialize_db.up.sql", size: 234, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1557732988_initialize_db.up.sql", size: 234, mode: os.FileMode(0644), modTime: time.Unix(1599559877, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x8f, 0xa, 0x31, 0xf, 0x94, 0xe, 0xd7, 0xd6, 0xaa, 0x22, 0xd6, 0x6c, 0x7a, 0xbc, 0xad, 0x6a, 0xed, 0x2e, 0x7a, 0xf0, 0x24, 0x81, 0x87, 0x14, 0xe, 0x1c, 0x8a, 0xf1, 0x45, 0xaf, 0x9e, 0x85}} return a, nil } @@ -126,7 +126,7 @@ func staticGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "static.go", size: 178, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "static.go", size: 178, mode: os.FileMode(0644), modTime: time.Unix(1599559877, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xab, 0x8a, 0xf4, 0x27, 0x24, 0x9d, 0x2a, 0x1, 0x7b, 0x54, 0xea, 0xae, 0x4a, 0x35, 0x40, 0x92, 0xb5, 0xf9, 0xb3, 0x54, 0x3e, 0x3a, 0x1a, 0x2b, 0xae, 0xfb, 0x9e, 0x82, 0xeb, 0x4c, 0xf, 0x6}} return a, nil } diff --git a/multiaccounts/accounts/database.go b/multiaccounts/accounts/database.go index 95d09c1c7..f52179dc5 100644 --- a/multiaccounts/accounts/database.go +++ b/multiaccounts/accounts/database.go @@ -79,6 +79,7 @@ type Settings struct { LinkPreviewRequestEnabled bool `json:"link-preview-request-enabled,omitempty"` LinkPreviewsEnabledSites *json.RawMessage `json:"link-previews-enabled-sites,omitempty"` LogLevel *string `json:"log-level,omitempty"` + MessagesFromContactsOnly bool `json:"messages-from-contacts-only"` Mnemonic *string `json:"mnemonic,omitempty"` Name string `json:"name,omitempty"` Networks *json.RawMessage `json:"networks/networks"` @@ -230,6 +231,12 @@ func (db *Database) SaveSetting(setting string, value interface{}) error { return ErrInvalidConfig } update, err = db.db.Prepare("UPDATE settings SET hide_home_tooltip = ? WHERE synthetic_id = 'id'") + case "messages-from-contacts-only": + _, ok := value.(bool) + if !ok { + return ErrInvalidConfig + } + update, err = db.db.Prepare("UPDATE settings SET messages_from_contacts_only = ? WHERE synthetic_id = 'id'") case "keycard-instance_uid": update, err = db.db.Prepare("UPDATE settings SET keycard_instance_uid = ? WHERE synthetic_id = 'id'") case "keycard-paired_on": @@ -385,7 +392,7 @@ func (db *Database) GetNodeConfig(nodecfg interface{}) error { 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, 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, use_mailservers, usernames, appearance, profile_pictures_visibility, wallet_root_address, wallet_set_up_passed, wallet_visible_tokens, waku_bloom_filter_mode, webview_allow_permission_requests 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, 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, use_mailservers, messages_from_contacts_only, usernames, appearance, profile_pictures_visibility, wallet_root_address, wallet_set_up_passed, wallet_visible_tokens, waku_bloom_filter_mode, webview_allow_permission_requests FROM settings WHERE synthetic_id = 'id'").Scan( &s.Address, &s.AnonMetricsShouldSend, &s.ChaosMode, @@ -428,6 +435,7 @@ func (db *Database) GetSettings() (Settings, error) { &s.StickersRecentStickers, &s.SyncingOnMobileNetwork, &s.UseMailservers, + &s.MessagesFromContactsOnly, &s.Usernames, &s.Appearance, &s.ProfilePicturesVisibility, @@ -541,6 +549,15 @@ func (db *Database) GetNotificationsEnabled() (bool, error) { return result, err } +func (db *Database) GetMessagesFromContactsOnly() (bool, error) { + var result bool + err := db.db.QueryRow("SELECT messages_from_contacts_only FROM settings WHERE synthetic_id = 'id'").Scan(&result) + if err == sql.ErrNoRows { + return result, nil + } + return result, err +} + func (db *Database) GetWalletAddress() (rst types.Address, err error) { err = db.db.QueryRow("SELECT address FROM accounts WHERE wallet = 1").Scan(&rst) return diff --git a/multiaccounts/migrations/bindata.go b/multiaccounts/migrations/bindata.go index d72511736..e5dc39f99 100644 --- a/multiaccounts/migrations/bindata.go +++ b/multiaccounts/migrations/bindata.go @@ -90,7 +90,7 @@ func _0001_accountsDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0001_accounts.down.sql", size: 21, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "0001_accounts.down.sql", size: 21, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd2, 0x61, 0x4c, 0x18, 0xfc, 0xc, 0xdf, 0x5c, 0x1f, 0x5e, 0xd3, 0xbd, 0xfa, 0x12, 0x5e, 0x8d, 0x8d, 0x8b, 0xb9, 0x5f, 0x99, 0x46, 0x63, 0xa5, 0xe3, 0xa6, 0x8a, 0x4, 0xf1, 0x73, 0x8a, 0xe9}} return a, nil } @@ -110,7 +110,7 @@ func _0001_accountsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0001_accounts.up.sql", size: 163, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "0001_accounts.up.sql", size: 163, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf2, 0xfa, 0x99, 0x8e, 0x96, 0xb3, 0x13, 0x6c, 0x1f, 0x6, 0x27, 0xc5, 0xd2, 0xd4, 0xe0, 0xa5, 0x26, 0x82, 0xa7, 0x26, 0xf2, 0x68, 0x9d, 0xed, 0x9c, 0x3d, 0xbb, 0xdc, 0x37, 0x28, 0xbc, 0x1}} return a, nil } @@ -130,7 +130,7 @@ func _1605007189_identity_imagesDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1605007189_identity_images.down.sql", size: 29, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1605007189_identity_images.down.sql", size: 29, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2f, 0xcf, 0xa7, 0xae, 0xd5, 0x4f, 0xcd, 0x14, 0x63, 0x9, 0xbe, 0x39, 0x49, 0x18, 0x96, 0xb2, 0xa3, 0x8, 0x7d, 0x41, 0xdb, 0x50, 0x5d, 0xf5, 0x4d, 0xa2, 0xd, 0x8f, 0x57, 0x79, 0x77, 0x67}} return a, nil } @@ -150,7 +150,7 @@ func _1605007189_identity_imagesUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1605007189_identity_images.up.sql", size: 268, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1605007189_identity_images.up.sql", size: 268, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x50, 0xb6, 0xc1, 0x5c, 0x76, 0x72, 0x6b, 0x22, 0x34, 0xdc, 0x96, 0xdc, 0x2b, 0xfd, 0x2d, 0xbe, 0xcc, 0x1e, 0xd4, 0x5, 0x93, 0xd, 0xc2, 0x51, 0xf3, 0x1a, 0xef, 0x2b, 0x26, 0xa4, 0xeb, 0x65}} return a, nil } @@ -170,7 +170,7 @@ func _1606224181_drop_photo_path_from_accountsDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1606224181_drop_photo_path_from_accounts.down.sql", size: 892, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1606224181_drop_photo_path_from_accounts.down.sql", size: 892, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x90, 0x24, 0x17, 0x7, 0x80, 0x93, 0x6f, 0x8d, 0x5d, 0xaa, 0x8c, 0x79, 0x15, 0x5d, 0xb3, 0x19, 0xd7, 0xd8, 0x39, 0xf9, 0x3a, 0x63, 0x8f, 0x81, 0x15, 0xb6, 0xd6, 0x9a, 0x37, 0xa8, 0x8e, 0x9b}} return a, nil } @@ -190,7 +190,7 @@ func _1606224181_drop_photo_path_from_accountsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1606224181_drop_photo_path_from_accounts.up.sql", size: 866, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1606224181_drop_photo_path_from_accounts.up.sql", size: 866, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xff, 0x4c, 0x97, 0xee, 0xef, 0x82, 0xb8, 0x6c, 0x71, 0xbb, 0x50, 0x7b, 0xe6, 0xd9, 0x22, 0x31, 0x7c, 0x1a, 0xfe, 0x91, 0x28, 0xf6, 0x6, 0x36, 0xe, 0xb1, 0xf1, 0xc8, 0x25, 0xac, 0x7e, 0xd6}} return a, nil } @@ -210,7 +210,7 @@ func docGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0x7c, 0x28, 0xcd, 0x47, 0xf2, 0xfa, 0x7c, 0x51, 0x2d, 0xd8, 0x38, 0xb, 0xb0, 0x34, 0x9d, 0x4c, 0x62, 0xa, 0x9e, 0x28, 0xc3, 0x31, 0x23, 0xd9, 0xbb, 0x89, 0x9f, 0xa0, 0x89, 0x1f, 0xe8}} return a, nil } diff --git a/protocol/activity_center.go b/protocol/activity_center.go new file mode 100644 index 000000000..c9ef03c61 --- /dev/null +++ b/protocol/activity_center.go @@ -0,0 +1,46 @@ +package protocol + +import ( + "errors" + + "github.com/status-im/status-go/eth-node/types" + "github.com/status-im/status-go/protocol/common" +) + +// The activity center is a place where we store incoming notifications before +// they are shown to the users as new chats, in order to mitigate the impact of spam +// on the messenger + +type ActivityCenterType int + +const ( + ActivityCenterNotificationTypeNewOneToOne = iota + 1 + ActivityCenterNotificationTypeNewPrivateGroupChat +) + +var ErrInvalidActivityCenterNotification = errors.New("invalid activity center notification") + +type ActivityCenterNotification struct { + ID types.HexBytes `json:"id"` + ChatID string `json:"chatId"` + Name string `json:"name"` + Type ActivityCenterType `json:"type"` + LastMessage *common.Message `json:"lastMessage"` + Timestamp uint64 `json:"timestamp"` + Read bool `json:"read"` + Dismissed bool `json:"dismissed"` + Accepted bool `json:"accepted"` +} + +type ActivityCenterPaginationResponse struct { + Cursor string `json:"cursor"` + Notifications []*ActivityCenterNotification `json:"notifications"` +} + +func (n *ActivityCenterNotification) Valid() error { + if len(n.ID) == 0 || n.Type == 0 || n.Timestamp == 0 { + return ErrInvalidActivityCenterNotification + } + return nil + +} diff --git a/protocol/activity_center_persistence.go b/protocol/activity_center_persistence.go new file mode 100644 index 000000000..f55f519ac --- /dev/null +++ b/protocol/activity_center_persistence.go @@ -0,0 +1,273 @@ +package protocol + +import ( + "context" + "database/sql" + "encoding/json" + "fmt" + "strings" + + "github.com/status-im/status-go/eth-node/types" + "github.com/status-im/status-go/protocol/common" +) + +func (db sqlitePersistence) DeleteActivityCenterNotification(id []byte) error { + + _, err := db.db.Exec(`DELETE FROM activity_center_notifications WHERE id = ?`, id) + return err +} + +func (db sqlitePersistence) SaveActivityCenterNotification(notification *ActivityCenterNotification) error { + var tx *sql.Tx + var err error + + err = notification.Valid() + if err != nil { + return err + } + + tx, err = db.db.BeginTx(context.Background(), &sql.TxOptions{}) + if err != nil { + return err + } + defer func() { + if err == nil { + err = tx.Commit() + return + } + // don't shadow original error + _ = tx.Rollback() + }() + + if notification.Type == ActivityCenterNotificationTypeNewOneToOne { + // Delete other notifications so it pop us again if not currently dismissed + _, err = tx.Exec(`DELETE FROM activity_center_notifications WHERE id = ? AND dismissed`, notification.ID) + if err != nil { + return err + } + } + + _, err = tx.Exec(`INSERT INTO activity_center_notifications (id,timestamp,notification_type, chat_id) VALUES (?,?,?,?)`, notification.ID, notification.Timestamp, notification.Type, notification.ChatID) + return err +} + +func (db sqlitePersistence) unmarshalActivityCenterNotificationRows(rows *sql.Rows) (string, []*ActivityCenterNotification, error) { + var notifications []*ActivityCenterNotification + latestCursor := "" + for rows.Next() { + var chatID sql.NullString + var lastMessageBytes []byte + var name sql.NullString + notification := &ActivityCenterNotification{} + err := rows.Scan( + ¬ification.ID, + ¬ification.Timestamp, + ¬ification.Type, + &chatID, + ¬ification.Read, + ¬ification.Accepted, + ¬ification.Dismissed, + &lastMessageBytes, + &name, + &latestCursor) + if err != nil { + return "", nil, err + } + if chatID.Valid { + notification.ChatID = chatID.String + + } + + if name.Valid { + notification.Name = name.String + } + + // Restore last message + if lastMessageBytes != nil { + message := &common.Message{} + if err = json.Unmarshal(lastMessageBytes, message); err != nil { + return "", nil, err + } + notification.LastMessage = message + } + + notifications = append(notifications, notification) + } + + return latestCursor, notifications, nil + +} +func (db sqlitePersistence) buildActivityCenterQuery(tx *sql.Tx, cursor string, limit int, ids []types.HexBytes) (string, []*ActivityCenterNotification, error) { + var args []interface{} + cursorWhere := "" + inQueryWhere := "" + if cursor != "" { + cursorWhere = "AND cursor <= ?" //nolint: goconst + args = append(args, cursor) + } + + if len(ids) != 0 { + + inVector := strings.Repeat("?, ", len(ids)-1) + "?" + inQueryWhere = fmt.Sprintf(" AND a.id IN (%s)", inVector) + for _, id := range ids { + args = append(args, id) + } + + } + + query := fmt.Sprintf( // nolint: gosec + ` + SELECT + a.id, + a.timestamp, + a.notification_type, + a.chat_id, + a.read, + a.accepted, + a.dismissed, + c.last_message, + c.name, + substr('0000000000000000000000000000000000000000000000000000000000000000' || a.timestamp, -64, 64) || a.id as cursor + FROM activity_center_notifications a + LEFT JOIN chats c + ON + c.id = a.chat_id + WHERE NOT a.dismissed AND NOT a.accepted + %s + %s + ORDER BY cursor DESC`, cursorWhere, inQueryWhere) + if limit != 0 { + args = append(args, limit) + query += ` LIMIT ?` + } + + rows, err := tx.Query(query, args...) + if err != nil { + return "", nil, err + } + return db.unmarshalActivityCenterNotificationRows(rows) +} + +func (db sqlitePersistence) ActivityCenterNotifications(currCursor string, limit uint64) (string, []*ActivityCenterNotification, error) { + var tx *sql.Tx + var err error + // We fetch limit + 1 to check for pagination + incrementedLimit := int(limit) + 1 + tx, err = db.db.BeginTx(context.Background(), &sql.TxOptions{}) + if err != nil { + return "", nil, err + } + defer func() { + if err == nil { + err = tx.Commit() + return + } + // don't shadow original error + _ = tx.Rollback() + }() + + latestCursor, notifications, err := db.buildActivityCenterQuery(tx, currCursor, incrementedLimit, nil) + if err != nil { + return "", nil, err + } + + if len(notifications) == incrementedLimit { + notifications = notifications[0:limit] + } else { + latestCursor = "" + } + + return latestCursor, notifications, nil +} + +func (db sqlitePersistence) DismissAllActivityCenterNotifications() error { + _, err := db.db.Exec(`UPDATE activity_center_notifications SET dismissed = 1 WHERE NOT dismissed AND NOT accepted`) + return err +} + +func (db sqlitePersistence) DismissActivityCenterNotifications(ids []types.HexBytes) error { + + idsArgs := make([]interface{}, 0, len(ids)) + for _, id := range ids { + idsArgs = append(idsArgs, id) + } + + inVector := strings.Repeat("?, ", len(ids)-1) + "?" + query := "UPDATE activity_center_notifications SET dismissed = 1 WHERE id IN (" + inVector + ")" // nolint: gosec + _, err := db.db.Exec(query, idsArgs...) + return err + +} + +func (db sqlitePersistence) AcceptAllActivityCenterNotifications() ([]*ActivityCenterNotification, error) { + var tx *sql.Tx + var err error + + tx, err = db.db.BeginTx(context.Background(), &sql.TxOptions{}) + if err != nil { + return nil, err + } + defer func() { + if err == nil { + err = tx.Commit() + return + } + // don't shadow original error + _ = tx.Rollback() + }() + + _, notifications, err := db.buildActivityCenterQuery(tx, "", 0, nil) + + _, err = tx.Exec(`UPDATE activity_center_notifications SET accepted = 1 WHERE NOT accepted AND NOT dismissed`) + if err != nil { + return nil, err + } + return notifications, nil +} + +func (db sqlitePersistence) AcceptActivityCenterNotifications(ids []types.HexBytes) ([]*ActivityCenterNotification, error) { + + var tx *sql.Tx + var err error + + tx, err = db.db.BeginTx(context.Background(), &sql.TxOptions{}) + if err != nil { + return nil, err + } + defer func() { + if err == nil { + err = tx.Commit() + return + } + // don't shadow original error + _ = tx.Rollback() + }() + + _, notifications, err := db.buildActivityCenterQuery(tx, "", 0, ids) + + if err != nil { + return nil, err + } + + idsArgs := make([]interface{}, 0, len(ids)) + for _, id := range ids { + idsArgs = append(idsArgs, id) + } + + inVector := strings.Repeat("?, ", len(ids)-1) + "?" + query := "UPDATE activity_center_notifications SET accepted = 1 WHERE id IN (" + inVector + ")" // nolint: gosec + _, err = tx.Exec(query, idsArgs...) + return notifications, err +} + +func (db sqlitePersistence) MarkAllActivityCenterNotificationsRead() error { + _, err := db.db.Exec(`UPDATE activity_center_notifications SET read = 1 WHERE NOT read`) + return err +} + +func (db sqlitePersistence) UnreadActivityCenterNotificationsCount() (uint64, error) { + var count uint64 + err := db.db.QueryRow(`SELECT COUNT(1) FROM activity_center_notifications WHERE NOT read`).Scan(&count) + return count, err +} diff --git a/protocol/chat.go b/protocol/chat.go index de4982485..1aa1966bb 100644 --- a/protocol/chat.go +++ b/protocol/chat.go @@ -165,10 +165,17 @@ func (c *Chat) HasMember(memberID string) bool { return false } -func (c *Chat) updateChatFromGroupMembershipChanges(myID string, g *v1protocol.Group) { +func (c *Chat) HasJoinedMember(memberID string) bool { + for _, member := range c.Members { + if member.Joined && memberID == member.ID { + return true + } + } - // Check if we were already in the chat - hadJoined := c.HasMember(myID) + return false +} + +func (c *Chat) updateChatFromGroupMembershipChanges(g *v1protocol.Group) { // ID c.ID = g.ChatID() @@ -182,10 +189,6 @@ func (c *Chat) updateChatFromGroupMembershipChanges(myID string, g *v1protocol.G joined := g.Joined() chatMembers := make([]ChatMember, 0, len(members)) for _, m := range members { - // Check if we joined thanks to these changes, if so, make chat active - if m == myID && !hadJoined { - c.Active = true - } chatMember := ChatMember{ ID: m, diff --git a/protocol/communities_messenger_test.go b/protocol/communities_messenger_test.go index 9d93972f4..c2402d071 100644 --- a/protocol/communities_messenger_test.go +++ b/protocol/communities_messenger_test.go @@ -956,6 +956,11 @@ func (s *MessengerCommunitiesSuite) TestShareCommunity() { s.Require().NotNil(response) s.Require().Len(response.Messages, 1) + // Add bob to contacts so it does not go on activity center + bobPk := common.PubkeyToHex(&s.alice.identity.PublicKey) + _, err = s.alice.AddContact(context.Background(), bobPk) + s.Require().NoError(err) + // Pull message and make sure org is received err = tt.RetryWithBackOff(func() error { response, err = s.alice.RetrieveAll() @@ -970,7 +975,6 @@ func (s *MessengerCommunitiesSuite) TestShareCommunity() { s.Require().NoError(err) s.Require().Len(response.Messages, 1) - } func (s *MessengerCommunitiesSuite) TestBanUser() { diff --git a/protocol/encryption/migrations/migrations.go b/protocol/encryption/migrations/migrations.go index 2ae056236..01aa7c0b5 100644 --- a/protocol/encryption/migrations/migrations.go +++ b/protocol/encryption/migrations/migrations.go @@ -100,7 +100,7 @@ func _1536754952_initial_schemaDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1536754952_initial_schema.down.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1536754952_initial_schema.down.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x44, 0xcf, 0x76, 0x71, 0x1f, 0x5e, 0x9a, 0x43, 0xd8, 0xcd, 0xb8, 0xc3, 0x70, 0xc3, 0x7f, 0xfc, 0x90, 0xb4, 0x25, 0x1e, 0xf4, 0x66, 0x20, 0xb8, 0x33, 0x7e, 0xb0, 0x76, 0x1f, 0xc, 0xc0, 0x75}} return a, nil } @@ -120,7 +120,7 @@ func _1536754952_initial_schemaUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1536754952_initial_schema.up.sql", size: 962, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1536754952_initial_schema.up.sql", size: 962, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xea, 0x90, 0x5a, 0x59, 0x3e, 0x3, 0xe2, 0x3c, 0x81, 0x42, 0xcd, 0x4c, 0x9a, 0xe8, 0xda, 0x93, 0x2b, 0x70, 0xa4, 0xd5, 0x29, 0x3e, 0xd5, 0xc9, 0x27, 0xb6, 0xb7, 0x65, 0xff, 0x0, 0xcb, 0xde}} return a, nil } @@ -140,7 +140,7 @@ func _1539249977_update_ratchet_infoDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1539249977_update_ratchet_info.down.sql", size: 311, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1539249977_update_ratchet_info.down.sql", size: 311, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1, 0xa4, 0xeb, 0xa0, 0xe6, 0xa0, 0xd4, 0x48, 0xbb, 0xad, 0x6f, 0x7d, 0x67, 0x8c, 0xbd, 0x25, 0xde, 0x1f, 0x73, 0x9a, 0xbb, 0xa8, 0xc9, 0x30, 0xb7, 0xa9, 0x7c, 0xaf, 0xb5, 0x1, 0x61, 0xdd}} return a, nil } @@ -160,7 +160,7 @@ func _1539249977_update_ratchet_infoUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1539249977_update_ratchet_info.up.sql", size: 368, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1539249977_update_ratchet_info.up.sql", size: 368, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc, 0x8e, 0xbf, 0x6f, 0xa, 0xc0, 0xe1, 0x3c, 0x42, 0x28, 0x88, 0x1d, 0xdb, 0xba, 0x1c, 0x83, 0xec, 0xba, 0xd3, 0x5f, 0x5c, 0x77, 0x5e, 0xa7, 0x46, 0x36, 0xec, 0x69, 0xa, 0x4b, 0x17, 0x79}} return a, nil } @@ -180,7 +180,7 @@ func _1540715431_add_versionDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1540715431_add_version.down.sql", size: 127, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1540715431_add_version.down.sql", size: 127, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0x9, 0x4, 0xe3, 0x76, 0x2e, 0xb8, 0x9, 0x23, 0xf0, 0x70, 0x93, 0xc4, 0x50, 0xe, 0x9d, 0x84, 0x22, 0x8c, 0x94, 0xd3, 0x24, 0x9, 0x9a, 0xc1, 0xa1, 0x48, 0x45, 0xfd, 0x40, 0x6e, 0xe6}} return a, nil } @@ -200,7 +200,7 @@ func _1540715431_add_versionUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1540715431_add_version.up.sql", size: 265, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1540715431_add_version.up.sql", size: 265, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc7, 0x4c, 0x36, 0x96, 0xdf, 0x16, 0x10, 0xa6, 0x27, 0x1a, 0x79, 0x8b, 0x42, 0x83, 0x23, 0xc, 0x7e, 0xb6, 0x3d, 0x2, 0xda, 0xa4, 0xb4, 0xd, 0x27, 0x55, 0xba, 0xdc, 0xb2, 0x88, 0x8f, 0xa6}} return a, nil } @@ -220,7 +220,7 @@ func _1541164797_add_installationsDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1541164797_add_installations.down.sql", size: 26, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1541164797_add_installations.down.sql", size: 26, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0xfd, 0xe6, 0xd8, 0xca, 0x3b, 0x38, 0x18, 0xee, 0x0, 0x5f, 0x36, 0x9e, 0x1e, 0xd, 0x19, 0x3e, 0xb4, 0x73, 0x53, 0xe9, 0xa5, 0xac, 0xdd, 0xa1, 0x2f, 0xc7, 0x6c, 0xa8, 0xd9, 0xa, 0x88}} return a, nil } @@ -240,7 +240,7 @@ func _1541164797_add_installationsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1541164797_add_installations.up.sql", size: 216, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1541164797_add_installations.up.sql", size: 216, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2d, 0x18, 0x26, 0xb8, 0x88, 0x47, 0xdb, 0x83, 0xcc, 0xb6, 0x9d, 0x1c, 0x1, 0xae, 0x2f, 0xde, 0x97, 0x82, 0x3, 0x30, 0xa8, 0x63, 0xa1, 0x78, 0x4b, 0xa5, 0x9, 0x8, 0x75, 0xa2, 0x57, 0x81}} return a, nil } @@ -260,7 +260,7 @@ func _1558084410_add_secretDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1558084410_add_secret.down.sql", size: 56, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1558084410_add_secret.down.sql", size: 56, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x49, 0xb, 0x65, 0xdf, 0x59, 0xbf, 0xe9, 0x5, 0x5b, 0x6f, 0xd5, 0x3a, 0xb7, 0x57, 0xe8, 0x78, 0x38, 0x73, 0x53, 0x57, 0xf7, 0x24, 0x4, 0xe4, 0xa2, 0x49, 0x22, 0xa2, 0xc6, 0xfd, 0x80, 0xa4}} return a, nil } @@ -280,7 +280,7 @@ func _1558084410_add_secretUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1558084410_add_secret.up.sql", size: 301, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1558084410_add_secret.up.sql", size: 301, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0x32, 0x36, 0x8e, 0x47, 0xb0, 0x8f, 0xc1, 0xc6, 0xf7, 0xc6, 0x9f, 0x2d, 0x44, 0x75, 0x2b, 0x26, 0xec, 0x6, 0xa0, 0x7b, 0xa5, 0xbd, 0xc8, 0x76, 0x8a, 0x82, 0x68, 0x2, 0x42, 0xb5, 0xf4}} return a, nil } @@ -300,7 +300,7 @@ func _1558588866_add_versionDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1558588866_add_version.down.sql", size: 47, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1558588866_add_version.down.sql", size: 47, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0x52, 0x34, 0x3c, 0x46, 0x4a, 0xf0, 0x72, 0x47, 0x6f, 0x49, 0x5c, 0xc7, 0xf9, 0x32, 0xce, 0xc4, 0x3d, 0xfd, 0x61, 0xa1, 0x8b, 0x8f, 0xf2, 0x31, 0x34, 0xde, 0x15, 0x49, 0xa6, 0xde, 0xb9}} return a, nil } @@ -320,7 +320,7 @@ func _1558588866_add_versionUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1558588866_add_version.up.sql", size: 57, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1558588866_add_version.up.sql", size: 57, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2a, 0xea, 0x64, 0x39, 0x61, 0x20, 0x83, 0x83, 0xb, 0x2e, 0x79, 0x64, 0xb, 0x53, 0xfa, 0xfe, 0xc6, 0xf7, 0x67, 0x42, 0xd3, 0x4f, 0xdc, 0x7e, 0x30, 0x32, 0xe8, 0x14, 0x41, 0xe9, 0xe7, 0x3b}} return a, nil } @@ -340,7 +340,7 @@ func _1559627659_add_contact_codeDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1559627659_add_contact_code.down.sql", size: 32, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1559627659_add_contact_code.down.sql", size: 32, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x5d, 0x64, 0x6d, 0xce, 0x24, 0x42, 0x20, 0x8d, 0x4f, 0x37, 0xaa, 0x9d, 0xc, 0x57, 0x98, 0xc1, 0xd1, 0x1a, 0x34, 0xcd, 0x9f, 0x8f, 0x34, 0x86, 0xb3, 0xd3, 0xdc, 0xf1, 0x7d, 0xe5, 0x1b, 0x6e}} return a, nil } @@ -360,7 +360,7 @@ func _1559627659_add_contact_codeUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1559627659_add_contact_code.up.sql", size: 198, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1559627659_add_contact_code.up.sql", size: 198, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x16, 0xf6, 0xc2, 0x62, 0x9c, 0xd2, 0xc9, 0x1e, 0xd8, 0xea, 0xaa, 0xea, 0x95, 0x8f, 0x89, 0x6a, 0x85, 0x5d, 0x9d, 0x99, 0x78, 0x3c, 0x90, 0x66, 0x99, 0x3e, 0x4b, 0x19, 0x62, 0xfb, 0x31, 0x4d}} return a, nil } @@ -380,7 +380,7 @@ func _1561368210_add_installation_metadataDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1561368210_add_installation_metadata.down.sql", size: 35, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1561368210_add_installation_metadata.down.sql", size: 35, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa8, 0xde, 0x3f, 0xd2, 0x4a, 0x50, 0x98, 0x56, 0xe3, 0xc0, 0xcd, 0x9d, 0xb0, 0x34, 0x3b, 0xe5, 0x62, 0x18, 0xb5, 0x20, 0xc9, 0x3e, 0xdc, 0x6a, 0x40, 0x36, 0x66, 0xea, 0x51, 0x8c, 0x71, 0xf5}} return a, nil } @@ -400,7 +400,7 @@ func _1561368210_add_installation_metadataUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1561368210_add_installation_metadata.up.sql", size: 267, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1561368210_add_installation_metadata.up.sql", size: 267, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb4, 0x71, 0x8f, 0x29, 0xb1, 0xaa, 0xd6, 0xd1, 0x8c, 0x17, 0xef, 0x6c, 0xd5, 0x80, 0xb8, 0x2c, 0xc3, 0xfe, 0xec, 0x24, 0x4d, 0xc8, 0x25, 0xd3, 0xb4, 0xcd, 0xa9, 0xac, 0x63, 0x61, 0xb2, 0x9c}} return a, nil } @@ -420,7 +420,7 @@ func docGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "doc.go", size: 377, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "doc.go", size: 377, mode: os.FileMode(0644), modTime: time.Unix(1603694100, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xef, 0xaf, 0xdf, 0xcf, 0x65, 0xae, 0x19, 0xfc, 0x9d, 0x29, 0xc1, 0x91, 0xaf, 0xb5, 0xd5, 0xb1, 0x56, 0xf3, 0xee, 0xa8, 0xba, 0x13, 0x65, 0xdb, 0xab, 0xcf, 0x4e, 0xac, 0x92, 0xe9, 0x60, 0xf1}} return a, nil } diff --git a/protocol/message_handler.go b/protocol/message_handler.go index 28b28e9f7..076516a54 100644 --- a/protocol/message_handler.go +++ b/protocol/message_handler.go @@ -10,6 +10,7 @@ import ( "github.com/status-im/status-go/eth-node/crypto" "github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/images" + "github.com/status-im/status-go/multiaccounts/accounts" "github.com/status-im/status-go/protocol/common" "github.com/status-im/status-go/protocol/communities" "github.com/status-im/status-go/protocol/encryption/multidevice" @@ -27,20 +28,24 @@ const ( requestAddressForTransactionDeclinedMessage = "Request address for transaction declined" ) +var ErrMessageNotAllowed = errors.New("message from a non-contact") + type MessageHandler struct { identity *ecdsa.PrivateKey persistence *sqlitePersistence + settings *accounts.Database transport transport.Transport ensVerifier *ens.Verifier communitiesManager *communities.Manager logger *zap.Logger } -func newMessageHandler(identity *ecdsa.PrivateKey, logger *zap.Logger, persistence *sqlitePersistence, communitiesManager *communities.Manager, transport transport.Transport, ensVerifier *ens.Verifier) *MessageHandler { +func newMessageHandler(identity *ecdsa.PrivateKey, logger *zap.Logger, persistence *sqlitePersistence, communitiesManager *communities.Manager, transport transport.Transport, ensVerifier *ens.Verifier, settings *accounts.Database) *MessageHandler { return &MessageHandler{ identity: identity, persistence: persistence, communitiesManager: communitiesManager, + settings: settings, ensVerifier: ensVerifier, transport: transport, logger: logger} @@ -66,6 +71,15 @@ func (m *MessageHandler) HandleMembershipUpdate(messageState *ReceivedMessageSta return err } + allowed, err := m.isMessageAllowedFrom(messageState.AllContacts, messageState.CurrentMessageState.Contact.ID, chat) + if err != nil { + return err + } + + if !allowed { + return ErrMessageNotAllowed + } + //if chat.InvitationAdmin exists means we are waiting for invitation request approvement, and in that case //we need to create a new chat instance like we don't have a chat and just use a regular invitation flow if chat == nil || len(chat.InvitationAdmin) > 0 { @@ -103,11 +117,16 @@ func (m *MessageHandler) HandleMembershipUpdate(messageState *ReceivedMessageSta return err } + ourKey := contactIDFromPublicKey(&m.identity.PublicKey) // A new chat must contain us - if !group.IsMember(contactIDFromPublicKey(&m.identity.PublicKey)) { + if !group.IsMember(ourKey) { return errors.New("can't create a new group chat without us being a member") } newChat := CreateGroupChat(messageState.Timesource) + // We set group chat inactive and create a notification instead + // unless is coming from us or a contact + isActive := messageState.CurrentMessageState.Contact.IsAdded() || messageState.CurrentMessageState.Contact.ID == ourKey + newChat.Active = isActive chat = &newChat } else { existingGroup, err := newProtocolGroupFromChat(chat) @@ -125,7 +144,22 @@ func (m *MessageHandler) HandleMembershipUpdate(messageState *ReceivedMessageSta } } - chat.updateChatFromGroupMembershipChanges(contactIDFromPublicKey(&m.identity.PublicKey), group) + chat.updateChatFromGroupMembershipChanges(group) + + if !chat.Active { + notification := &ActivityCenterNotification{ + ID: types.FromHex(chat.ID), + Name: chat.Name, + LastMessage: chat.LastMessage, + Type: ActivityCenterNotificationTypeNewPrivateGroupChat, + Timestamp: messageState.CurrentMessageState.WhisperTimestamp, + ChatID: chat.ID, + } + err := m.addActivityCenterNotification(messageState, notification) + if err != nil { + m.logger.Warn("failed to create activity center notification", zap.Error(err)) + } + } systemMessages := buildSystemMessages(message.Events, translations) @@ -141,9 +175,9 @@ func (m *MessageHandler) HandleMembershipUpdate(messageState *ReceivedMessageSta messageState.Response.Messages = append(messageState.Response.Messages, message) } + messageState.Response.AddChat(chat) // Store in chats map as it might be a new one messageState.AllChats.Store(chat.ID, chat) - messageState.Response.AddChat(chat) if message.Message != nil { messageState.CurrentMessageState.Message = *message.Message @@ -166,11 +200,20 @@ func (m *MessageHandler) handleCommandMessage(state *ReceivedMessageState, messa if err := message.PrepareContent(); err != nil { return fmt.Errorf("failed to prepare content: %v", err) } - chat, err := m.matchChatEntity(message, state.AllChats, state.Timesource) + chat, err := m.matchChatEntity(message, state.AllChats, state.AllContacts, state.Timesource) if err != nil { return err } + allowed, err := m.isMessageAllowedFrom(state.AllContacts, state.CurrentMessageState.Contact.ID, chat) + if err != nil { + return err + } + + if !allowed { + return ErrMessageNotAllowed + } + // If deleted-at is greater, ignore message if chat.DeletedAtClockValue >= message.Clock { return nil @@ -200,17 +243,30 @@ func (m *MessageHandler) handleCommandMessage(state *ReceivedMessageState, messa return err } - // Set chat active - chat.Active = true - // Set in the modified maps chat - state.Response.AddChat(chat) - // TODO(samyoul) remove storing of an updated reference pointer? - state.AllChats.Store(chat.ID, chat) + if !chat.Active { + notification := &ActivityCenterNotification{ + ID: types.FromHex(chat.ID), + Type: ActivityCenterNotificationTypeNewOneToOne, + Name: chat.Name, + LastMessage: chat.LastMessage, + Timestamp: state.CurrentMessageState.WhisperTimestamp, + ChatID: chat.ID, + } + err := m.addActivityCenterNotification(state, notification) + if err != nil { + m.logger.Warn("failed to save notification", zap.Error(err)) + } + } // Add to response + state.Response.AddChat(chat) if message != nil { state.Response.Messages = append(state.Response.Messages, message) } + + // Set in the modified maps chat + state.AllChats.Store(chat.ID, chat) + return nil } @@ -271,6 +327,15 @@ func (m *MessageHandler) HandleContactUpdate(state *ReceivedMessageState, messag logger := m.logger.With(zap.String("site", "HandleContactUpdate")) contact := state.CurrentMessageState.Contact chat, ok := state.AllChats.Load(contact.ID) + + allowed, err := m.isMessageAllowedFrom(state.AllContacts, state.CurrentMessageState.Contact.ID, chat) + if err != nil { + return err + } + if !allowed { + return ErrMessageNotAllowed + } + if !ok { chat = OneToOneFromPublicKey(state.CurrentMessageState.PublicKey, state.Timesource) // We don't want to show the chat to the user @@ -460,11 +525,20 @@ func (m *MessageHandler) HandleChatMessage(state *ReceivedMessageState) error { if err != nil { return fmt.Errorf("failed to prepare message content: %v", err) } - chat, err := m.matchChatEntity(receivedMessage, state.AllChats, state.Timesource) + chat, err := m.matchChatEntity(receivedMessage, state.AllChats, state.AllContacts, state.Timesource) if err != nil { return err // matchChatEntity returns a descriptive error message } + allowed, err := m.isMessageAllowedFrom(state.AllContacts, state.CurrentMessageState.Contact.ID, chat) + if err != nil { + return err + } + + if !allowed { + return ErrMessageNotAllowed + } + // It looks like status-react created profile chats as public chats // so for now we need to check for the presence of "@" in their chatID if chat.Public() && receivedMessage.ContentType == protobuf.ChatMessage_IMAGE && !chat.ProfileUpdates() { @@ -504,8 +578,21 @@ func (m *MessageHandler) HandleChatMessage(state *ReceivedMessageState) error { return err } - // Set chat active - chat.Active = true + // If the chat is not active, create a notification in the center + if chat.OneToOne() && !chat.Active { + notification := &ActivityCenterNotification{ + ID: types.FromHex(chat.ID), + Name: chat.Name, + LastMessage: chat.LastMessage, + Type: ActivityCenterNotificationTypeNewOneToOne, + Timestamp: state.CurrentMessageState.WhisperTimestamp, + ChatID: chat.ID, + } + err := m.addActivityCenterNotification(state, notification) + if err != nil { + m.logger.Warn("failed to create notification", zap.Error(err)) + } + } // Set in the modified maps chat state.Response.AddChat(chat) // TODO(samyoul) remove storing of an updated reference pointer? @@ -538,12 +625,22 @@ func (m *MessageHandler) HandleChatMessage(state *ReceivedMessageState) error { state.Response.AddCommunity(community) state.Response.CommunityChanges = append(state.Response.CommunityChanges, communityResponse.Changes) } - // Add to response + state.Response.Messages = append(state.Response.Messages, receivedMessage) return nil } +func (m *MessageHandler) addActivityCenterNotification(state *ReceivedMessageState, notification *ActivityCenterNotification) error { + err := m.persistence.SaveActivityCenterNotification(notification) + if err != nil { + m.logger.Warn("failed to save notification", zap.Error(err)) + return err + } + state.Response.AddActivityCenterNotification(notification) + return nil +} + func (m *MessageHandler) HandleRequestAddressForTransaction(messageState *ReceivedMessageState, command protobuf.RequestAddressForTransaction) error { err := ValidateReceivedRequestAddressForTransaction(&command, messageState.CurrentMessageState.WhisperTimestamp) if err != nil { @@ -745,7 +842,7 @@ func (m *MessageHandler) HandleDeclineRequestTransaction(messageState *ReceivedM return m.handleCommandMessage(messageState, oldMessage) } -func (m *MessageHandler) matchChatEntity(chatEntity common.ChatEntity, chats *chatMap, timesource common.TimeSource) (*Chat, error) { +func (m *MessageHandler) matchChatEntity(chatEntity common.ChatEntity, chats *chatMap, contacts *contactMap, timesource common.TimeSource) (*Chat, error) { if chatEntity.GetSigPubKey() == nil { m.logger.Error("public key can't be empty") return nil, errors.New("received a chatEntity with empty public key") @@ -791,7 +888,12 @@ func (m *MessageHandler) matchChatEntity(chatEntity common.ChatEntity, chats *ch if !ok { // TODO: this should be a three-word name used in the mobile client chat = CreateOneToOneChat(chatID[:8], chatEntity.GetSigPubKey(), timesource) + chat.Active = false } + // We set the chat as inactive and will create a notification + // if it's not coming from a contact + contact, ok := contacts.Load(chatID) + chat.Active = chat.Active || (ok && contact.IsAdded()) return chat, nil case chatEntity.GetMessageType() == protobuf.MessageType_COMMUNITY_CHAT: chatID := chatEntity.GetChatId() @@ -898,7 +1000,7 @@ func (m *MessageHandler) HandleEmojiReaction(state *ReceivedMessageState, pbEmoj return nil } - chat, err := m.matchChatEntity(emojiReaction, state.AllChats, state.Timesource) + chat, err := m.matchChatEntity(emojiReaction, state.AllChats, state.AllContacts, state.Timesource) if err != nil { return err // matchChatEntity returns a descriptive error message } @@ -928,6 +1030,14 @@ func (m *MessageHandler) HandleEmojiReaction(state *ReceivedMessageState, pbEmoj } func (m *MessageHandler) HandleGroupChatInvitation(state *ReceivedMessageState, pbGHInvitations protobuf.GroupChatInvitation) error { + allowed, err := m.isMessageAllowedFrom(state.AllContacts, state.CurrentMessageState.Contact.ID, nil) + if err != nil { + return err + } + + if !allowed { + return ErrMessageNotAllowed + } logger := m.logger.With(zap.String("site", "HandleGroupChatInvitation")) if err := ValidateReceivedGroupChatInvitation(&pbGHInvitations); err != nil { logger.Error("invalid group chat invitation", zap.Error(err)) @@ -973,6 +1083,14 @@ func (m *MessageHandler) HandleGroupChatInvitation(state *ReceivedMessageState, // extracts contact information stored in the protobuf and adds it to the user's contact for update. func (m *MessageHandler) HandleChatIdentity(state *ReceivedMessageState, ci protobuf.ChatIdentity) error { logger := m.logger.With(zap.String("site", "HandleChatIdentity")) + allowed, err := m.isMessageAllowedFrom(state.AllContacts, state.CurrentMessageState.Contact.ID, nil) + if err != nil { + return err + } + + if !allowed { + return ErrMessageNotAllowed + } contact := state.CurrentMessageState.Contact logger.Info("Handling contact update") @@ -994,3 +1112,38 @@ func (m *MessageHandler) HandleChatIdentity(state *ReceivedMessageState, ci prot return nil } + +func (m *MessageHandler) isMessageAllowedFrom(allContacts *contactMap, publicKey string, chat *Chat) (bool, error) { + onlyFromContacts, err := m.settings.GetMessagesFromContactsOnly() + if err != nil { + return false, err + } + + if !onlyFromContacts { + return true, nil + } + + // if it's from us, it's allowed + if contactIDFromPublicKey(&m.identity.PublicKey) == publicKey { + return true, nil + } + + // If the chat is active, we allow it + if chat != nil && chat.Active { + return true, nil + } + + // If the chat is public, we allow it + if chat != nil && chat.Public() { + return true, nil + } + + contact, ok := allContacts.Load(publicKey) + if !ok { + // If it's not in contacts, we don't allow it + return false, nil + } + + // Otherwise we check if we added it + return contact.IsAdded(), nil +} diff --git a/protocol/messenger.go b/protocol/messenger.go index e1c5b05e1..e5aebc206 100644 --- a/protocol/messenger.go +++ b/protocol/messenger.go @@ -74,7 +74,6 @@ var messageCacheIntervalMs uint64 = 1000 * 60 * 60 * 48 // because installations are managed by the user. // Similarly, it needs to expose an interface to manage // mailservers because they can also be managed by the user. -// TODO we may want to change the maps into sync.Maps if we start getting unexpected locks or weird collision bugs type Messenger struct { node types.Node config *config @@ -284,7 +283,8 @@ func NewMessenger( if err != nil { return nil, err } - handler := newMessageHandler(identity, logger, sqlitePersistence, communitiesManager, transp, ensVerifier) + settings := accounts.NewDB(database) + handler := newMessageHandler(identity, logger, sqlitePersistence, communitiesManager, transp, ensVerifier, settings) messenger = &Messenger{ config: &c, @@ -309,7 +309,7 @@ func NewMessenger( verifyTransactionClient: c.verifyTransactionClient, database: database, multiAccounts: c.multiAccount, - settings: accounts.NewDB(database), + settings: settings, mailserversDatabase: c.mailserversDatabase, account: c.account, quit: make(chan struct{}), @@ -1036,8 +1036,8 @@ func (m *Messenger) Init() error { if err != nil { return err } - for _, contact := range contacts { - m.allContacts.Store(contact.ID, contact) + for idx, contact := range contacts { + m.allContacts.Store(contact.ID, contacts[idx]) // We only need filters for contacts added by us and not blocked. if !contact.IsAdded() || contact.IsBlocked() { continue @@ -1199,7 +1199,7 @@ func (m *Messenger) CreateGroupChatWithMembers(ctx context.Context, name string, } chat.LastClockValue = clock - chat.updateChatFromGroupMembershipChanges(contactIDFromPublicKey(&m.identity.PublicKey), group) + chat.updateChatFromGroupMembershipChanges(group) clock, _ = chat.NextClockAndTimestamp(m.getTimesource()) @@ -1242,7 +1242,7 @@ func (m *Messenger) CreateGroupChatWithMembers(ctx context.Context, name string, return nil, err } - chat.updateChatFromGroupMembershipChanges(contactIDFromPublicKey(&m.identity.PublicKey), group) + chat.updateChatFromGroupMembershipChanges(group) response.AddChat(&chat) response.Messages = buildSystemMessages(chat.MembershipUpdates, m.systemMessagesTranslations) @@ -1317,7 +1317,7 @@ func (m *Messenger) RemoveMemberFromGroupChat(ctx context.Context, chatID string return nil, err } - chat.updateChatFromGroupMembershipChanges(contactIDFromPublicKey(&m.identity.PublicKey), group) + chat.updateChatFromGroupMembershipChanges(group) response.AddChat(chat) response.Messages = buildSystemMessages(chat.MembershipUpdates, m.systemMessagesTranslations) @@ -1403,7 +1403,7 @@ func (m *Messenger) AddMembersToGroupChat(ctx context.Context, chatID string, me return nil, err } - chat.updateChatFromGroupMembershipChanges(contactIDFromPublicKey(&m.identity.PublicKey), group) + chat.updateChatFromGroupMembershipChanges(group) response.AddChat(chat) response.Messages = buildSystemMessages([]v1protocol.MembershipUpdateEvent{event}, m.systemMessagesTranslations) @@ -1464,7 +1464,7 @@ func (m *Messenger) ChangeGroupChatName(ctx context.Context, chatID string, name return nil, err } - chat.updateChatFromGroupMembershipChanges(contactIDFromPublicKey(&m.identity.PublicKey), group) + chat.updateChatFromGroupMembershipChanges(group) var response MessengerResponse response.AddChat(chat) @@ -1665,7 +1665,7 @@ func (m *Messenger) AddAdminsToGroupChat(ctx context.Context, chatID string, mem return nil, err } - chat.updateChatFromGroupMembershipChanges(contactIDFromPublicKey(&m.identity.PublicKey), group) + chat.updateChatFromGroupMembershipChanges(group) response.AddChat(chat) response.Messages = buildSystemMessages([]v1protocol.MembershipUpdateEvent{event}, m.systemMessagesTranslations) @@ -1728,7 +1728,7 @@ func (m *Messenger) ConfirmJoiningGroup(ctx context.Context, chatID string) (*Me return nil, err } - chat.updateChatFromGroupMembershipChanges(contactIDFromPublicKey(&m.identity.PublicKey), group) + chat.updateChatFromGroupMembershipChanges(group) response.AddChat(chat) response.Messages = buildSystemMessages([]v1protocol.MembershipUpdateEvent{event}, m.systemMessagesTranslations) @@ -1748,62 +1748,61 @@ func (m *Messenger) LeaveGroupChat(ctx context.Context, chatID string, remove bo return nil, ErrChatNotFound } - err := m.Leave(*chat) - if err != nil { - return nil, err - } + joined := chat.HasJoinedMember(common.PubkeyToHex(&m.identity.PublicKey)) - group, err := newProtocolGroupFromChat(chat) - if err != nil { - return nil, err - } - clock, _ := chat.NextClockAndTimestamp(m.getTimesource()) - event := v1protocol.NewMemberRemovedEvent( - contactIDFromPublicKey(&m.identity.PublicKey), - clock, - ) - event.ChatID = chat.ID - err = event.Sign(m.identity) - if err != nil { - return nil, err - } + if joined { + group, err := newProtocolGroupFromChat(chat) + if err != nil { + return nil, err + } + clock, _ := chat.NextClockAndTimestamp(m.getTimesource()) + event := v1protocol.NewMemberRemovedEvent( + contactIDFromPublicKey(&m.identity.PublicKey), + clock, + ) + event.ChatID = chat.ID + err = event.Sign(m.identity) + if err != nil { + return nil, err + } - err = group.ProcessEvent(event) - if err != nil { - return nil, err - } + err = group.ProcessEvent(event) + if err != nil { + return nil, err + } - recipients, err := stringSliceToPublicKeys(group.Members()) - if err != nil { - return nil, err - } + recipients, err := stringSliceToPublicKeys(group.Members()) + if err != nil { + return nil, err + } - encodedMessage, err := m.processor.EncodeMembershipUpdate(group, nil) - if err != nil { - return nil, err - } - _, err = m.dispatchMessage(ctx, common.RawMessage{ - LocalChatID: chat.ID, - Payload: encodedMessage, - MessageType: protobuf.ApplicationMetadataMessage_MEMBERSHIP_UPDATE_MESSAGE, - Recipients: recipients, - }) - if err != nil { - return nil, err - } + encodedMessage, err := m.processor.EncodeMembershipUpdate(group, nil) + if err != nil { + return nil, err + } + _, err = m.dispatchMessage(ctx, common.RawMessage{ + LocalChatID: chat.ID, + Payload: encodedMessage, + MessageType: protobuf.ApplicationMetadataMessage_MEMBERSHIP_UPDATE_MESSAGE, + Recipients: recipients, + }) + if err != nil { + return nil, err + } - chat.updateChatFromGroupMembershipChanges(contactIDFromPublicKey(&m.identity.PublicKey), group) + chat.updateChatFromGroupMembershipChanges(group) + response.Messages = buildSystemMessages([]v1protocol.MembershipUpdateEvent{event}, m.systemMessagesTranslations) + err = m.persistence.SaveMessages(response.Messages) + if err != nil { + return nil, err + } + } if remove { chat.Active = false } response.AddChat(chat) - response.Messages = buildSystemMessages([]v1protocol.MembershipUpdateEvent{event}, m.systemMessagesTranslations) - err = m.persistence.SaveMessages(response.Messages) - if err != nil { - return nil, err - } return &response, m.saveChat(chat) } @@ -2534,7 +2533,6 @@ func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filte switch msg.ParsedMessage.Interface().(type) { case protobuf.MembershipUpdateMessage: logger.Debug("Handling MembershipUpdateMessage") - rawMembershipUpdate := msg.ParsedMessage.Interface().(protobuf.MembershipUpdateMessage) chat, _ := messageState.AllChats.Load(rawMembershipUpdate.ChatId) @@ -2658,6 +2656,7 @@ func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filte case protobuf.RequestTransaction: command := msg.ParsedMessage.Interface().(protobuf.RequestTransaction) + logger.Debug("Handling RequestTransaction") err = m.handler.HandleRequestTransaction(messageState, command) if err != nil { @@ -2781,7 +2780,6 @@ func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filte continue } case protobuf.ChatIdentity: - logger.Debug("Received ChatIdentity") err = m.handler.HandleChatIdentity(messageState, msg.ParsedMessage.Interface().(protobuf.ChatIdentity)) if err != nil { logger.Warn("failed to handle ChatIdentity", zap.Error(err)) diff --git a/protocol/messenger_activity_center.go b/protocol/messenger_activity_center.go new file mode 100644 index 000000000..d5b868479 --- /dev/null +++ b/protocol/messenger_activity_center.go @@ -0,0 +1,75 @@ +package protocol + +import ( + "github.com/status-im/status-go/eth-node/types" +) + +func (m *Messenger) UnreadActivityCenterNotificationsCount() (uint64, error) { + return m.persistence.UnreadActivityCenterNotificationsCount() +} + +func (m *Messenger) MarkAllActivityCenterNotificationsRead() error { + return m.persistence.MarkAllActivityCenterNotificationsRead() +} + +func (m *Messenger) processAcceptedActivityCenterNotifications(notifications []*ActivityCenterNotification) (*MessengerResponse, error) { + response := &MessengerResponse{} + var chats []*Chat + for _, notification := range notifications { + if notification.ChatID != "" { + chat, ok := m.allChats.Load(notification.ChatID) + if !ok { + // This should not really happen, but ignore just in case it was deleted in the meantime + m.logger.Warn("chat not found") + continue + } + chat.Active = true + + chats = append(chats, chat) + response.AddChat(chat) + } + } + if len(chats) != 0 { + err := m.saveChats(chats) + if err != nil { + return nil, err + } + } + return response, nil +} + +func (m *Messenger) AcceptAllActivityCenterNotifications() (*MessengerResponse, error) { + notifications, err := m.persistence.AcceptAllActivityCenterNotifications() + if err != nil { + return nil, err + } + return m.processAcceptedActivityCenterNotifications(notifications) +} + +func (m *Messenger) AcceptActivityCenterNotifications(ids []types.HexBytes) (*MessengerResponse, error) { + notifications, err := m.persistence.AcceptActivityCenterNotifications(ids) + if err != nil { + return nil, err + } + return m.processAcceptedActivityCenterNotifications(notifications) +} + +func (m *Messenger) DismissAllActivityCenterNotifications() error { + return m.persistence.DismissAllActivityCenterNotifications() +} + +func (m *Messenger) DismissActivityCenterNotifications(ids []types.HexBytes) error { + return m.persistence.DismissActivityCenterNotifications(ids) +} + +func (m *Messenger) ActivityCenterNotifications(cursor string, limit uint64) (*ActivityCenterPaginationResponse, error) { + cursor, notifications, err := m.persistence.ActivityCenterNotifications(cursor, limit) + if err != nil { + return nil, err + } + + return &ActivityCenterPaginationResponse{ + Cursor: cursor, + Notifications: notifications, + }, nil +} diff --git a/protocol/messenger_chats.go b/protocol/messenger_chats.go index bde52fded..5d0794ff6 100644 --- a/protocol/messenger_chats.go +++ b/protocol/messenger_chats.go @@ -4,6 +4,7 @@ import ( "context" "errors" + "github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/protocol/common" "github.com/status-im/status-go/protocol/requests" "github.com/status-im/status-go/protocol/transport" @@ -20,6 +21,22 @@ func (m *Messenger) Chats() []*Chat { return chats } +func (m *Messenger) ActiveChats() []*Chat { + m.mutex.Lock() + defer m.mutex.Unlock() + + var chats []*Chat + + m.allChats.Range(func(chatID string, c *Chat) bool { + if c.Active { + chats = append(chats, c) + } + return true + }) + + return chats +} + func (m *Messenger) CreateOneToOneChat(request *requests.CreateOneToOneChat) (*MessengerResponse, error) { if err := request.Validate(); err != nil { return nil, err @@ -135,6 +152,13 @@ func (m *Messenger) saveChats(chats []*Chat) error { func (m *Messenger) saveChat(chat *Chat) error { previousChat, ok := m.allChats.Load(chat.ID) if chat.OneToOne() { + // We clear all notifications so it pops up again + if !chat.Active { + err := m.persistence.DeleteActivityCenterNotification(types.FromHex(chat.ID)) + if err != nil { + return err + } + } name, identicon, err := generateAliasAndIdenticon(chat.ID) if err != nil { return err diff --git a/protocol/messenger_locker.go b/protocol/messenger_maps.go similarity index 100% rename from protocol/messenger_locker.go rename to protocol/messenger_maps.go diff --git a/protocol/messenger_response.go b/protocol/messenger_response.go index f17d4da66..7f8d4be22 100644 --- a/protocol/messenger_response.go +++ b/protocol/messenger_response.go @@ -27,10 +27,11 @@ type MessengerResponse struct { // notifications a list of notifications derived from messenger events // that are useful to notify the user about - notifications map[string]*localnotifications.Notification - chats map[string]*Chat - removedChats map[string]bool - communities map[string]*communities.Community + notifications map[string]*localnotifications.Notification + chats map[string]*Chat + removedChats map[string]bool + communities map[string]*communities.Community + activityCenterNotifications map[string]*ActivityCenterNotification } func (r *MessengerResponse) MarshalJSON() ([]byte, error) { @@ -51,8 +52,9 @@ func (r *MessengerResponse) MarshalJSON() ([]byte, error) { MailserverRanges []mailservers.ChatRequestRange `json:"mailserverRanges,omitempty"` // Notifications a list of notifications derived from messenger events // that are useful to notify the user about - Notifications []*localnotifications.Notification `json:"notifications"` - Communities []*communities.Community `json:"communities,omitempty"` + Notifications []*localnotifications.Notification `json:"notifications"` + Communities []*communities.Community `json:"communities,omitempty"` + ActivityCenterNotifications []*ActivityCenterNotification `json:"activityCenterNotifications,omitempty"` }{ Messages: r.Messages, Contacts: r.Contacts, @@ -72,6 +74,7 @@ func (r *MessengerResponse) MarshalJSON() ([]byte, error) { responseItem.Chats = r.Chats() responseItem.Communities = r.Communities() responseItem.RemovedChats = r.RemovedChats() + responseItem.ActivityCenterNotifications = r.ActivityCenterNotifications() return json.Marshal(responseItem) } @@ -124,6 +127,7 @@ func (r *MessengerResponse) IsEmpty() bool { len(r.Mailservers)+ len(r.MailserverRanges)+ len(r.notifications)+ + len(r.activityCenterNotifications)+ len(r.RequestsToJoinCommunity) == 0 } @@ -261,3 +265,25 @@ func (r *MessengerResponse) AddRemovedChat(chatID string) { r.removedChats[chatID] = true } + +func (r *MessengerResponse) AddActivityCenterNotifications(ns []*ActivityCenterNotification) { + for _, n := range ns { + r.AddActivityCenterNotification(n) + } +} + +func (r *MessengerResponse) AddActivityCenterNotification(n *ActivityCenterNotification) { + if r.activityCenterNotifications == nil { + r.activityCenterNotifications = make(map[string]*ActivityCenterNotification) + } + + r.activityCenterNotifications[n.ID.String()] = n +} + +func (r *MessengerResponse) ActivityCenterNotifications() []*ActivityCenterNotification { + var ns []*ActivityCenterNotification + for _, n := range r.activityCenterNotifications { + ns = append(ns, n) + } + return ns +} diff --git a/protocol/messenger_test.go b/protocol/messenger_test.go index 01425f042..29483a419 100644 --- a/protocol/messenger_test.go +++ b/protocol/messenger_test.go @@ -757,7 +757,8 @@ func (s *MessengerSuite) TestRetrieveTheirPrivateChatExisting() { ) s.Require().NoError(err) - s.Require().Equal(len(response.Chats()), 1) + s.Require().Len(response.Chats(), 1) + s.Require().Len(response.ActivityCenterNotifications(), 1) actualChat := response.Chats()[0] // It updates the unviewed messages count s.Require().Equal(uint(2), actualChat.UnviewedMessagesCount) @@ -765,7 +766,7 @@ func (s *MessengerSuite) TestRetrieveTheirPrivateChatExisting() { s.Require().Equal(sentMessage.Clock, actualChat.LastClockValue) // It sets the last message s.Require().NotNil(actualChat.LastMessage) - s.Require().True(actualChat.Active) + s.Require().False(actualChat.Active) s.Require().NoError(theirMessenger.Shutdown()) } @@ -796,6 +797,7 @@ func (s *MessengerSuite) TestRetrieveTheirPrivateChatNonExisting() { s.Require().NoError(err) s.Require().Len(response.Chats(), 1) + s.Require().Len(response.ActivityCenterNotifications(), 1) actualChat := response.Chats()[0] // It updates the unviewed messages count s.Require().Equal(uint(1), actualChat.UnviewedMessagesCount) @@ -803,8 +805,8 @@ func (s *MessengerSuite) TestRetrieveTheirPrivateChatNonExisting() { s.Require().Equal(sentMessage.Clock, actualChat.LastClockValue) // It sets the last message s.Require().NotNil(actualChat.LastMessage) - // It sets the chat as active - s.Require().True(actualChat.Active) + // It does not set the chat as active + s.Require().False(actualChat.Active) } // Test receiving a message on an non-existing public chat @@ -852,12 +854,15 @@ func (s *MessengerSuite) TestRetrieveTheirPrivateGroupChat() { s.NoError(err) // Retrieve their messages so that the chat is created - _, err = WaitOnMessengerResponse( + response, err = WaitOnMessengerResponse( theirMessenger, func(r *MessengerResponse) bool { return len(r.Chats()) > 0 }, "chat invitation not received", ) s.Require().NoError(err) + s.Require().Len(response.Chats(), 1) + s.Require().Len(response.ActivityCenterNotifications(), 1) + s.Require().False(response.Chats()[0].Active) _, err = theirMessenger.ConfirmJoiningGroup(context.Background(), ourChat.ID) s.NoError(err) @@ -970,12 +975,14 @@ func (s *MessengerSuite) TestReInvitedToGroupChat() { s.NoError(err) // Retrieve their messages so that the chat is created - _, err = WaitOnMessengerResponse( + response, err = WaitOnMessengerResponse( theirMessenger, func(r *MessengerResponse) bool { return len(r.Chats()) > 0 }, "chat invitation not received", ) s.Require().NoError(err) + s.Require().Len(response.ActivityCenterNotifications(), 1) + s.Require().False(response.Chats()[0].Active) _, err = theirMessenger.ConfirmJoiningGroup(context.Background(), ourChat.ID) s.NoError(err) @@ -1017,7 +1024,7 @@ func (s *MessengerSuite) TestReInvitedToGroupChat() { s.Require().NoError(err) s.Require().Len(response.Chats(), 1) - s.Require().True(response.Chats()[0].Active) + s.Require().False(response.Chats()[0].Active) s.Require().NoError(theirMessenger.Shutdown()) } @@ -2509,6 +2516,7 @@ func (s *MessageHandlerSuite) TestRun() { for idx, tc := range testCases { s.Run(tc.Name, func() { chatsMap := new(chatMap) + contactsMap := new(contactMap) if tc.Chat != nil && tc.Chat.ID != "" { chatsMap.Store(tc.Chat.ID, tc.Chat) } @@ -2519,7 +2527,7 @@ func (s *MessageHandlerSuite) TestRun() { s.Empty(message.LocalChatID) message.ID = strconv.Itoa(idx) // manually set the ID because messages does not go through messageProcessor - chat, err := s.messageHandler.matchChatEntity(&message, chatsMap, &testTimeSource{}) + chat, err := s.messageHandler.matchChatEntity(&message, chatsMap, contactsMap, &testTimeSource{}) if tc.Error { s.Require().Error(err) } else { diff --git a/protocol/migrations/migrations.go b/protocol/migrations/migrations.go index f61880595..2922a8c15 100644 --- a/protocol/migrations/migrations.go +++ b/protocol/migrations/migrations.go @@ -26,6 +26,7 @@ // 1612870480_add_datasync_id.up.sql (111B) // 1614152139_add_communities_request_to_join.up.sql (831B) // 1615374373_add_confirmations.up.sql (227B) +// 1617694931_add_notification_center.up.sql (572B) // README.md (554B) // doc.go (850B) @@ -111,7 +112,7 @@ func _000001_initDownDbSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "000001_init.down.db.sql", size: 65, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "000001_init.down.db.sql", size: 65, mode: os.FileMode(0644), modTime: time.Unix(1610007618, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x5e, 0xbb, 0x3f, 0x1, 0x75, 0x19, 0x70, 0x86, 0xa7, 0x34, 0x40, 0x17, 0x34, 0x3e, 0x18, 0x51, 0x79, 0xd4, 0x22, 0xad, 0x8f, 0x80, 0xcc, 0xa6, 0xcc, 0x6, 0x2b, 0x62, 0x2, 0x47, 0xba, 0xf9}} return a, nil } @@ -131,7 +132,7 @@ func _000001_initUpDbSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "000001_init.up.db.sql", size: 2719, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "000001_init.up.db.sql", size: 2719, mode: os.FileMode(0644), modTime: time.Unix(1610007618, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x60, 0xdc, 0xeb, 0xe, 0xc2, 0x4f, 0x75, 0xa, 0xf6, 0x3e, 0xc7, 0xc4, 0x4, 0xe2, 0xe1, 0xa4, 0x73, 0x2f, 0x4a, 0xad, 0x1a, 0x0, 0xc3, 0x93, 0x9d, 0x77, 0x3e, 0x31, 0x91, 0x77, 0x2e, 0xc8}} return a, nil } @@ -151,7 +152,7 @@ func _000002_add_last_ens_clock_valueUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "000002_add_last_ens_clock_value.up.sql", size: 77, mode: os.FileMode(0644), modTime: time.Unix(1589413297, 0)} + info := bindataFileInfo{name: "000002_add_last_ens_clock_value.up.sql", size: 77, mode: os.FileMode(0644), modTime: time.Unix(1610007618, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4d, 0x3, 0x8f, 0xd5, 0x85, 0x83, 0x47, 0xbe, 0xf9, 0x82, 0x7e, 0x81, 0xa4, 0xbd, 0xaa, 0xd5, 0x98, 0x18, 0x5, 0x2d, 0x82, 0x42, 0x3b, 0x3, 0x50, 0xc3, 0x1e, 0x84, 0x35, 0xf, 0xb6, 0x2b}} return a, nil } @@ -171,7 +172,7 @@ func _1586358095_add_replaceUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1586358095_add_replace.up.sql", size: 224, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1586358095_add_replace.up.sql", size: 224, mode: os.FileMode(0644), modTime: time.Unix(1611588719, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd2, 0xb3, 0xa9, 0xc7, 0x7f, 0x9d, 0x8f, 0x43, 0x8c, 0x9e, 0x58, 0x8d, 0x44, 0xbc, 0xfa, 0x6b, 0x5f, 0x3f, 0x5a, 0xbe, 0xe8, 0xb1, 0x16, 0xf, 0x91, 0x2a, 0xa0, 0x71, 0xbb, 0x8d, 0x6b, 0xcb}} return a, nil } @@ -191,7 +192,7 @@ func _1588665364_add_image_dataUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1588665364_add_image_data.up.sql", size: 186, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1588665364_add_image_data.up.sql", size: 186, mode: os.FileMode(0644), modTime: time.Unix(1611588719, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd6, 0xc6, 0x35, 0xb4, 0x4c, 0x39, 0x96, 0x29, 0x30, 0xda, 0xf4, 0x8f, 0xcb, 0xf1, 0x9f, 0x84, 0xdc, 0x88, 0xd4, 0xd5, 0xbc, 0xb6, 0x5b, 0x46, 0x78, 0x67, 0x76, 0x1a, 0x5, 0x36, 0xdc, 0xe5}} return a, nil } @@ -211,7 +212,7 @@ func _1589365189_add_pow_targetUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1589365189_add_pow_target.up.sql", size: 66, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1589365189_add_pow_target.up.sql", size: 66, mode: os.FileMode(0644), modTime: time.Unix(1611588719, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4e, 0x3a, 0xe2, 0x2e, 0x7d, 0xaf, 0xbb, 0xcc, 0x21, 0xa1, 0x7a, 0x41, 0x9a, 0xd0, 0xbb, 0xa9, 0xc8, 0x35, 0xf9, 0x32, 0x34, 0x46, 0x44, 0x9a, 0x86, 0x40, 0x7c, 0xb9, 0x23, 0xc7, 0x3, 0x3f}} return a, nil } @@ -231,7 +232,7 @@ func _1591277220_add_index_messagesUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1591277220_add_index_messages.up.sql", size: 240, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1591277220_add_index_messages.up.sql", size: 240, mode: os.FileMode(0644), modTime: time.Unix(1614609069, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x9c, 0xfe, 0xbe, 0xd5, 0xb8, 0x8f, 0xdd, 0xef, 0xbb, 0xa8, 0xad, 0x7f, 0xed, 0x5b, 0x5b, 0x2f, 0xe6, 0x82, 0x27, 0x78, 0x1f, 0xb9, 0x57, 0xdc, 0x8, 0xc2, 0xb2, 0xa9, 0x9a, 0x4, 0xe1, 0x7a}} return a, nil } @@ -251,7 +252,7 @@ func _1593087212_add_mute_chat_and_raw_message_fieldsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1593087212_add_mute_chat_and_raw_message_fields.up.sql", size: 215, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1593087212_add_mute_chat_and_raw_message_fields.up.sql", size: 215, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x73, 0x99, 0x61, 0xd1, 0xaa, 0xb4, 0xbf, 0xaf, 0xd7, 0x20, 0x17, 0x40, 0xf9, 0x2, 0xfb, 0xcc, 0x40, 0x2a, 0xd, 0x86, 0x36, 0x30, 0x88, 0x89, 0x25, 0x80, 0x42, 0xb0, 0x5b, 0xe9, 0x73, 0x78}} return a, nil } @@ -271,7 +272,7 @@ func _1595862781_add_audio_dataUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1595862781_add_audio_data.up.sql", size: 246, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1595862781_add_audio_data.up.sql", size: 246, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xae, 0xd2, 0xee, 0x55, 0xfb, 0x36, 0xa4, 0x92, 0x66, 0xe, 0x81, 0x62, 0x1e, 0x7a, 0x69, 0xa, 0xd5, 0x4b, 0xa5, 0x6a, 0x8d, 0x1d, 0xce, 0xf3, 0x3e, 0xc0, 0x5f, 0x9c, 0x66, 0x1b, 0xb4, 0xed}} return a, nil } @@ -291,7 +292,7 @@ func _1595865249_create_emoji_reactions_tableUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1595865249_create_emoji_reactions_table.up.sql", size: 300, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1595865249_create_emoji_reactions_table.up.sql", size: 300, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3e, 0xc5, 0x43, 0x5c, 0x3d, 0x53, 0x43, 0x2c, 0x1a, 0xa5, 0xb6, 0xbf, 0x7, 0x4, 0x5a, 0x3e, 0x40, 0x8b, 0xa4, 0x57, 0x12, 0x58, 0xbc, 0x42, 0xe2, 0xc3, 0xde, 0x76, 0x98, 0x80, 0xe2, 0xbe}} return a, nil } @@ -311,7 +312,7 @@ func _1596805115_create_group_chat_invitations_tableUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1596805115_create_group_chat_invitations_table.up.sql", size: 231, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1596805115_create_group_chat_invitations_table.up.sql", size: 231, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x6d, 0xb1, 0x14, 0x6d, 0x54, 0x28, 0x67, 0xc3, 0x23, 0x6a, 0xfc, 0x80, 0xdf, 0x9e, 0x4c, 0x35, 0x36, 0xf, 0xf8, 0xf3, 0x5f, 0xae, 0xad, 0xb, 0xc1, 0x51, 0x8e, 0x17, 0x7, 0xe5, 0x7f, 0x91}} return a, nil } @@ -331,7 +332,7 @@ func _1597322655_add_invitation_admin_chat_fieldUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1597322655_add_invitation_admin_chat_field.up.sql", size: 54, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1597322655_add_invitation_admin_chat_field.up.sql", size: 54, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa9, 0x7a, 0xa0, 0xf2, 0xdb, 0x13, 0x91, 0x91, 0xa8, 0x34, 0x1a, 0xa1, 0x49, 0x68, 0xd5, 0xae, 0x2c, 0xd8, 0xd5, 0xea, 0x8f, 0x8c, 0xc7, 0x2, 0x4e, 0x58, 0x2c, 0x3a, 0x14, 0xd4, 0x4f, 0x2c}} return a, nil } @@ -351,7 +352,7 @@ func _1597757544_add_nicknameUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1597757544_add_nickname.up.sql", size: 52, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1597757544_add_nickname.up.sql", size: 52, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf4, 0xa2, 0x64, 0x50, 0xc5, 0x4, 0xb9, 0x8b, 0xd1, 0x18, 0x9b, 0xc3, 0x91, 0x36, 0x2a, 0x1f, 0xc3, 0x6c, 0x2d, 0x92, 0xf8, 0x5e, 0xff, 0xb1, 0x59, 0x61, 0x2, 0x1c, 0xe1, 0x85, 0x90, 0xa4}} return a, nil } @@ -371,7 +372,7 @@ func _1598955122_add_mentionsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1598955122_add_mentions.up.sql", size: 52, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1598955122_add_mentions.up.sql", size: 52, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x8d, 0x22, 0x17, 0x92, 0xd2, 0x11, 0x4e, 0x7, 0x93, 0x9a, 0x55, 0xfd, 0xb, 0x97, 0xc4, 0x63, 0x6a, 0x81, 0x97, 0xcd, 0xb2, 0xf8, 0x4b, 0x5f, 0x3c, 0xfa, 0x3a, 0x38, 0x53, 0x10, 0xed, 0x9d}} return a, nil } @@ -391,7 +392,7 @@ func _1599641390_add_emoji_reactions_indexUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1599641390_add_emoji_reactions_index.up.sql", size: 126, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1599641390_add_emoji_reactions_index.up.sql", size: 126, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf9, 0xd8, 0xdc, 0xa7, 0xb, 0x92, 0x7a, 0x61, 0x37, 0x24, 0x1c, 0x77, 0x5e, 0xe, 0x7e, 0xfc, 0x9f, 0x98, 0x7b, 0x65, 0xe7, 0xf9, 0x71, 0x57, 0x89, 0x2d, 0x90, 0x1b, 0xf6, 0x5e, 0x37, 0xe8}} return a, nil } @@ -411,7 +412,7 @@ func _1599720851_add_seen_index_remove_long_messagesUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1599720851_add_seen_index_remove_long_messages.up.sql", size: 150, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1599720851_add_seen_index_remove_long_messages.up.sql", size: 150, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x24, 0x1c, 0xc4, 0x78, 0x91, 0xc7, 0xeb, 0xfe, 0xc8, 0xa0, 0xd8, 0x13, 0x27, 0x97, 0xc8, 0x96, 0x56, 0x97, 0x33, 0x2c, 0x1e, 0x16, 0x8a, 0xd3, 0x49, 0x99, 0x3, 0xe9, 0xbb, 0xc4, 0x5, 0x3c}} return a, nil } @@ -431,7 +432,7 @@ func _1603198582_add_profile_chat_fieldUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1603198582_add_profile_chat_field.up.sql", size: 45, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1603198582_add_profile_chat_field.up.sql", size: 45, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xaa, 0xca, 0xe, 0x46, 0xa0, 0x9, 0x9d, 0x47, 0x57, 0xe9, 0xfb, 0x17, 0xeb, 0x9c, 0xf6, 0xb8, 0x1d, 0xe9, 0xd, 0x0, 0xd5, 0xe5, 0xd8, 0x9e, 0x60, 0xa, 0xbf, 0x32, 0x2c, 0x52, 0x7f, 0x6a}} return a, nil } @@ -451,7 +452,7 @@ func _1603816533_add_linksUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1603816533_add_links.up.sql", size: 48, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1603816533_add_links.up.sql", size: 48, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc9, 0x24, 0xd6, 0x1d, 0xa, 0x83, 0x1e, 0x4d, 0xf, 0xae, 0x4d, 0x8c, 0x51, 0x32, 0xa8, 0x37, 0xb0, 0x14, 0xfb, 0x32, 0x34, 0xc8, 0xc, 0x4e, 0x5b, 0xc5, 0x15, 0x65, 0x73, 0x0, 0x0, 0x1d}} return a, nil } @@ -471,7 +472,7 @@ func _1603888149_create_chat_identity_last_published_tableUpSql() (*asset, error return nil, err } - info := bindataFileInfo{name: "1603888149_create_chat_identity_last_published_table.up.sql", size: 407, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1603888149_create_chat_identity_last_published_table.up.sql", size: 407, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7f, 0x9, 0xf, 0xfb, 0xdb, 0x3c, 0x86, 0x70, 0x82, 0xda, 0x10, 0x25, 0xe2, 0x4e, 0x40, 0x45, 0xab, 0x8b, 0x1c, 0x91, 0x7c, 0xf1, 0x70, 0x2e, 0x81, 0xf3, 0x71, 0x45, 0xda, 0xe2, 0xa4, 0x57}} return a, nil } @@ -491,7 +492,7 @@ func _1605075346_add_communitiesUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1605075346_add_communities.up.sql", size: 6971, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1605075346_add_communities.up.sql", size: 6971, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1f, 0x64, 0xea, 0xb4, 0xae, 0x9e, 0xdb, 0x9, 0x58, 0xb6, 0x5c, 0x7a, 0x50, 0xc5, 0xfe, 0x93, 0x5d, 0x36, 0x85, 0x5d, 0x6a, 0xba, 0xc9, 0x7e, 0x84, 0xd7, 0xbf, 0x2a, 0x53, 0xf3, 0x97, 0xf1}} return a, nil } @@ -511,7 +512,7 @@ func _1610117927_add_message_cacheUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1610117927_add_message_cache.up.sql", size: 142, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1610117927_add_message_cache.up.sql", size: 142, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x34, 0xf1, 0xf0, 0x82, 0x79, 0x28, 0x19, 0xc2, 0x39, 0x6a, 0xa5, 0x96, 0x59, 0x23, 0xa0, 0xed, 0x60, 0x58, 0x86, 0x9, 0xb9, 0xad, 0xfb, 0xa, 0xe3, 0x47, 0x6e, 0xa1, 0x18, 0xe8, 0x39, 0x2c}} return a, nil } @@ -531,7 +532,7 @@ func _1610959908_add_dont_wrap_to_raw_messagesUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1610959908_add_dont_wrap_to_raw_messages.up.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1610959908_add_dont_wrap_to_raw_messages.up.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x71, 0x2, 0x9a, 0xca, 0xd4, 0x38, 0x44, 0x30, 0x2b, 0xa8, 0x27, 0x32, 0x63, 0x53, 0x22, 0x60, 0x59, 0x84, 0x23, 0x96, 0x77, 0xf0, 0x56, 0xd7, 0x94, 0xe0, 0x95, 0x28, 0x6, 0x1d, 0x4e, 0xb1}} return a, nil } @@ -551,7 +552,7 @@ func _1610960912_add_send_on_personal_topicUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1610960912_add_send_on_personal_topic.up.sql", size: 82, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1610960912_add_send_on_personal_topic.up.sql", size: 82, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x77, 0xac, 0x2f, 0xc4, 0xd, 0xa7, 0x1b, 0x37, 0x30, 0xc2, 0x68, 0xee, 0xde, 0x54, 0x5e, 0xbf, 0x3f, 0xa0, 0xd6, 0xc6, 0x9f, 0xd4, 0x34, 0x12, 0x76, 0x1e, 0x66, 0x4a, 0xfc, 0xf, 0xee, 0xc9}} return a, nil } @@ -571,7 +572,7 @@ func _1612870480_add_datasync_idUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1612870480_add_datasync_id.up.sql", size: 111, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1612870480_add_datasync_id.up.sql", size: 111, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x34, 0x9a, 0xbc, 0xfa, 0xaa, 0x8c, 0x9c, 0x37, 0x67, 0x15, 0x9c, 0x7e, 0x78, 0x75, 0x66, 0x82, 0x18, 0x72, 0x10, 0xbc, 0xd4, 0xab, 0x44, 0xfe, 0x57, 0x85, 0x6d, 0x19, 0xf5, 0x96, 0x8a, 0xbe}} return a, nil } @@ -591,7 +592,7 @@ func _1614152139_add_communities_request_to_joinUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1614152139_add_communities_request_to_join.up.sql", size: 831, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1614152139_add_communities_request_to_join.up.sql", size: 831, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x11, 0x3, 0x26, 0xf9, 0x29, 0x50, 0x4f, 0xcd, 0x46, 0xe5, 0xb1, 0x6b, 0xb9, 0x2, 0x40, 0xb1, 0xdf, 0x4a, 0x4c, 0x7a, 0xda, 0x3, 0x35, 0xcd, 0x2d, 0xcc, 0x80, 0x7d, 0x57, 0x5f, 0x3, 0x5c}} return a, nil } @@ -611,11 +612,31 @@ func _1615374373_add_confirmationsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1615374373_add_confirmations.up.sql", size: 227, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1615374373_add_confirmations.up.sql", size: 227, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xdd, 0xa6, 0x65, 0xc5, 0x1d, 0xb2, 0x77, 0x36, 0xe3, 0x79, 0xda, 0xe8, 0x7a, 0xa4, 0xdf, 0x45, 0xae, 0xd8, 0xb4, 0xba, 0x90, 0xfd, 0x74, 0x71, 0x14, 0x75, 0x73, 0x72, 0xb9, 0x9e, 0x1, 0x81}} return a, nil } +var __1617694931_add_notification_centerUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x90\x41\x6b\x02\x31\x14\x84\xef\xf9\x15\x73\x54\xf0\xd2\xb3\xf4\x10\x37\x11\x97\xc6\x44\x62\xb6\xd6\xd3\x12\xb2\x91\x06\xba\xeb\x62\x42\xc1\x7f\x5f\x52\x71\xb7\xb0\xa5\xf6\xfa\xde\xf7\x66\xe6\x0d\x15\x86\x6b\x18\xba\x12\x1c\xee\xdd\xa6\x08\xca\x18\x0a\x25\xaa\xad\x84\x75\xce\xf7\xc9\x37\x58\x29\x25\x38\x95\x60\x7c\x4d\x2b\x61\x70\xb2\x1f\xd1\x2f\x49\xb5\x63\xd4\xdc\xef\xf6\xdc\x8c\x07\xcf\x78\x5a\x12\x52\x68\x9e\xf7\x37\x75\xeb\x52\xf8\x0c\xe9\x5a\x3b\xdf\x25\x7f\xa9\xbb\x73\x0a\xa7\xe0\x6c\x0a\xe7\x2e\x62\x46\x80\xd0\xe0\x95\xea\x62\x43\x35\xa4\x32\x90\x95\x10\xd8\xe9\x72\x4b\xf5\x11\x2f\xfc\xb8\x20\x40\x0a\xad\x8f\xc9\xb6\x3d\x4a\x69\x06\x2a\x6f\x7e\xca\xd5\xe9\xda\xfb\x09\x91\x63\xd6\xa3\x47\x1e\x5d\xbc\x1d\x9f\x1b\x3c\xef\x5f\xae\xa9\xd8\xf3\x8c\x35\x21\xb6\x21\x46\xff\x1f\x76\xd2\xd9\xef\x28\x99\xe3\x50\x9a\x8d\xaa\x0c\xb4\x3a\x94\x6c\x6c\xab\x94\x8c\xbf\x4d\xda\x6a\xc2\x2d\x41\x3d\xe8\x2b\xf9\x77\xa5\xb3\x21\xf5\x62\x08\x35\x7f\x64\xf3\x5d\xc8\x43\xe5\x4c\xcd\x97\xe4\x2b\x00\x00\xff\xff\x42\x2c\xa0\x0a\x3c\x02\x00\x00") + +func _1617694931_add_notification_centerUpSqlBytes() ([]byte, error) { + return bindataRead( + __1617694931_add_notification_centerUpSql, + "1617694931_add_notification_center.up.sql", + ) +} + +func _1617694931_add_notification_centerUpSql() (*asset, error) { + bytes, err := _1617694931_add_notification_centerUpSqlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "1617694931_add_notification_center.up.sql", size: 572, mode: os.FileMode(0644), modTime: time.Unix(1618594380, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x10, 0x45, 0xc6, 0xc9, 0x73, 0xbb, 0x1f, 0xda, 0xa3, 0x4d, 0x19, 0x98, 0x85, 0x2d, 0xca, 0xda, 0xcc, 0x3b, 0x32, 0xff, 0xc7, 0x7b, 0xe3, 0x9f, 0x9b, 0x2a, 0x93, 0xf5, 0xdf, 0x65, 0x38, 0x91}} + return a, nil +} + var _readmeMd = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x91\xc1\xce\xd3\x30\x10\x84\xef\x7e\x8a\x91\x7a\x01\xa9\x2a\x8f\xc0\x0d\x71\x82\x03\x48\x1c\xc9\x36\x9e\x36\x96\x1c\x6f\xf0\xae\x93\xe6\xed\x91\xa3\xc2\xdf\xff\x66\xed\xd8\x33\xdf\x78\x4f\xa7\x13\xbe\xea\x06\x57\x6c\x35\x39\x31\xa7\x7b\x15\x4f\x5a\xec\x73\x08\xbf\x08\x2d\x79\x7f\x4a\x43\x5b\x86\x17\xfd\x8c\x21\xea\x56\x5e\x47\x90\x4a\x14\x75\x48\xde\x64\x37\x2c\x6a\x96\xae\x99\x48\x05\xf6\x27\x77\x13\xad\x08\xae\x8a\x51\xe7\x25\xf3\xf1\xa9\x9f\xf9\x58\x58\x2c\xad\xbc\xe0\x8b\x56\xf0\x21\x5d\xeb\x4c\x95\xb3\xae\x84\x60\xd4\xdc\xe6\x82\x5d\x1b\x36\x6d\x39\x62\x92\xf5\xb8\x11\xdb\x92\xd3\x28\xce\xe0\x13\xe1\x72\xcd\x3c\x63\xd4\x65\x87\xae\xac\xe8\xc3\x28\x2e\x67\x44\x66\x3a\x21\x25\xa2\x72\xac\x14\x67\xbc\x84\x9f\x53\x32\x8c\x52\x70\x25\x56\xd6\xfd\x8d\x05\x37\xad\x30\x9d\x9f\xa6\x86\x0f\xcd\x58\x7f\xcf\x34\x93\x3b\xed\x90\x9f\xa4\x1f\xcf\x30\x85\x4d\x07\x58\xaf\x7f\x25\xc4\x9d\xf3\x72\x64\x84\xd0\x7f\xf9\x9b\x3a\x2d\x84\xef\x85\x48\x66\x8d\xd8\x88\x9b\x8c\x8c\x98\x5b\xf6\x74\x14\x4e\x33\x0d\xc9\xe0\x93\x38\xda\x12\xc5\x69\xbd\xe4\xf0\x2e\x7a\x78\x07\x1c\xfe\x13\x9f\x91\x29\x31\x95\x7b\x7f\x62\x59\x37\xb4\xe5\x5e\x25\xfe\x33\xee\xd5\x53\x71\xd6\xda\x3a\xd8\xcb\xde\x2e\xf8\xa1\x90\x55\x53\x0c\xc7\xaa\x0d\xe9\x76\x14\x29\x1c\x7b\x68\xdd\x2f\xe1\x6f\x00\x00\x00\xff\xff\x3c\x0a\xc2\xfe\x2a\x02\x00\x00") func readmeMdBytes() ([]byte, error) { @@ -631,7 +652,7 @@ func readmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "README.md", size: 554, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "README.md", size: 554, mode: os.FileMode(0644), modTime: time.Unix(1617280156, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1c, 0x6e, 0xfb, 0xcc, 0x81, 0x94, 0x4d, 0x8c, 0xa0, 0x3b, 0x5, 0xb0, 0x18, 0xd6, 0xbb, 0xb3, 0x79, 0xc8, 0x8f, 0xff, 0xc1, 0x10, 0xf9, 0xf, 0x20, 0x1b, 0x4a, 0x74, 0x96, 0x42, 0xd7, 0xa8}} return a, nil } @@ -651,7 +672,7 @@ func docGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "doc.go", size: 850, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "doc.go", size: 850, mode: os.FileMode(0644), modTime: time.Unix(1611588719, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa0, 0xcc, 0x41, 0xe1, 0x61, 0x12, 0x97, 0xe, 0x36, 0x8c, 0xa7, 0x9e, 0xe0, 0x6e, 0x59, 0x9e, 0xee, 0xd5, 0x4a, 0xcf, 0x1e, 0x60, 0xd6, 0xc3, 0x3a, 0xc9, 0x6c, 0xf2, 0x86, 0x5a, 0xb4, 0x1e}} return a, nil } @@ -799,6 +820,8 @@ var _bindata = map[string]func() (*asset, error){ "1615374373_add_confirmations.up.sql": _1615374373_add_confirmationsUpSql, + "1617694931_add_notification_center.up.sql": _1617694931_add_notification_centerUpSql, + "README.md": readmeMd, "doc.go": docGo, @@ -871,8 +894,9 @@ var _bintree = &bintree{nil, map[string]*bintree{ "1612870480_add_datasync_id.up.sql": &bintree{_1612870480_add_datasync_idUpSql, map[string]*bintree{}}, "1614152139_add_communities_request_to_join.up.sql": &bintree{_1614152139_add_communities_request_to_joinUpSql, map[string]*bintree{}}, "1615374373_add_confirmations.up.sql": &bintree{_1615374373_add_confirmationsUpSql, map[string]*bintree{}}, - "README.md": &bintree{readmeMd, map[string]*bintree{}}, - "doc.go": &bintree{docGo, map[string]*bintree{}}, + "1617694931_add_notification_center.up.sql": &bintree{_1617694931_add_notification_centerUpSql, map[string]*bintree{}}, + "README.md": &bintree{readmeMd, map[string]*bintree{}}, + "doc.go": &bintree{docGo, map[string]*bintree{}}, }} // RestoreAsset restores an asset under the given directory. diff --git a/protocol/migrations/sqlite/1617694931_add_notification_center.up.sql b/protocol/migrations/sqlite/1617694931_add_notification_center.up.sql new file mode 100644 index 000000000..eaa54461c --- /dev/null +++ b/protocol/migrations/sqlite/1617694931_add_notification_center.up.sql @@ -0,0 +1,16 @@ +ALTER TABLE chats ADD COLUMN accepted BOOLEAN DEFAULT false; +UPDATE chats SET accepted = 1; + +CREATE TABLE activity_center_notifications ( + id VARCHAR NOT NULL PRIMARY KEY, + timestamp INT NOT NULL, + notification_type INT NOT NULL, + chat_id VARCHAR, + read BOOLEAN NOT NULL DEFAULT FALSE, + dismissed BOOLEAN NOT NULL DEFAULT FALSE, + accepted BOOLEAN NOT NULL DEFAULT FALSE +) WITHOUT ROWID; + +CREATE INDEX activity_center_dimissed_accepted ON activity_center_notifications(dismissed, accepted); + +CREATE INDEX activity_center_read ON activity_center_notifications(read); diff --git a/protocol/persistence_test.go b/protocol/persistence_test.go index d807472e9..8ddce00b8 100644 --- a/protocol/persistence_test.go +++ b/protocol/persistence_test.go @@ -1019,3 +1019,133 @@ func TestConfirmationsAtLeastOne(t *testing.T) { require.NotNil(t, messageID) require.Equal(t, types.HexBytes(messageID1), messageID) } + +func TestActivityCenterPersistence(t *testing.T) { + nID1 := types.HexBytes([]byte("1")) + nID2 := types.HexBytes([]byte("2")) + nID3 := types.HexBytes([]byte("3")) + nID4 := types.HexBytes([]byte("4")) + + db, err := openTestDB() + require.NoError(t, err) + p := NewSQLitePersistence(db) + + chat := CreatePublicChat("test-chat", &testTimeSource{}) + message := &common.Message{} + message.Text = "sample text" + chat.LastMessage = message + err = p.SaveChat(*chat) + require.NoError(t, err) + + notification := &ActivityCenterNotification{ + ID: nID1, + Type: ActivityCenterNotificationTypeNewOneToOne, + ChatID: chat.ID, + Timestamp: 1, + } + err = p.SaveActivityCenterNotification(notification) + require.NoError(t, err) + + cursor, notifications, err := p.ActivityCenterNotifications("", 2) + require.NoError(t, err) + require.Empty(t, cursor) + require.Len(t, notifications, 1) + require.Equal(t, chat.ID, notifications[0].ChatID) + require.Equal(t, message, notifications[0].LastMessage) + + // Add another notification + + notification = &ActivityCenterNotification{ + ID: nID2, + Type: ActivityCenterNotificationTypeNewOneToOne, + Timestamp: 2, + } + err = p.SaveActivityCenterNotification(notification) + require.NoError(t, err) + + cursor, notifications, err = p.ActivityCenterNotifications("", 1) + require.NoError(t, err) + require.Len(t, notifications, 1) + require.NotEmpty(t, cursor) + require.Equal(t, nID2, notifications[0].ID) + + // fetch next pagination + + cursor, notifications, err = p.ActivityCenterNotifications(cursor, 1) + require.NoError(t, err) + require.Len(t, notifications, 1) + require.Empty(t, cursor) + require.False(t, notifications[0].Read) + require.Equal(t, nID1, notifications[0].ID) + + // Check count + count, err := p.UnreadActivityCenterNotificationsCount() + require.NoError(t, err) + require.Equal(t, uint64(2), count) + + // Mark the all read + require.NoError(t, p.MarkAllActivityCenterNotificationsRead()) + _, notifications, err = p.ActivityCenterNotifications(cursor, 2) + require.NoError(t, err) + require.Len(t, notifications, 2) + require.Empty(t, cursor) + require.True(t, notifications[0].Read) + require.True(t, notifications[1].Read) + + // Check count + count, err = p.UnreadActivityCenterNotificationsCount() + require.NoError(t, err) + require.Equal(t, uint64(0), count) + + // Mark first one as accepted + + notifications, err = p.AcceptActivityCenterNotifications([]types.HexBytes{nID1}) + require.NoError(t, err) + require.Len(t, notifications, 1) + _, notifications, err = p.ActivityCenterNotifications("", 2) + require.NoError(t, err) + // It should not be returned anymore + require.Len(t, notifications, 1) + + // Mark last one as dismissed + require.NoError(t, p.DismissActivityCenterNotifications([]types.HexBytes{nID2})) + _, notifications, err = p.ActivityCenterNotifications("", 2) + require.NoError(t, err) + // Dismissed notifications should not be returned + require.Len(t, notifications, 0) + + // Insert new notification + notification = &ActivityCenterNotification{ + ID: nID3, + Type: ActivityCenterNotificationTypeNewOneToOne, + Timestamp: 3, + } + err = p.SaveActivityCenterNotification(notification) + require.NoError(t, err) + + // Mark all as accepted + notifications, err = p.AcceptAllActivityCenterNotifications() + require.NoError(t, err) + require.Len(t, notifications, 1) + + _, notifications, err = p.ActivityCenterNotifications("", 2) + require.NoError(t, err) + // It should not return those + require.Len(t, notifications, 0) + + // Insert new notification + notification = &ActivityCenterNotification{ + ID: nID4, + Type: ActivityCenterNotificationTypeNewOneToOne, + Timestamp: 4, + } + err = p.SaveActivityCenterNotification(notification) + require.NoError(t, err) + + // Mark all as dismissed + require.NoError(t, p.DismissAllActivityCenterNotifications()) + _, notifications, err = p.ActivityCenterNotifications("", 2) + require.NoError(t, err) + // It should not return those + require.Len(t, notifications, 0) +} diff --git a/protocol/pushnotificationclient/migrations/migrations.go b/protocol/pushnotificationclient/migrations/migrations.go index 458ebe182..9bd002b56 100644 --- a/protocol/pushnotificationclient/migrations/migrations.go +++ b/protocol/pushnotificationclient/migrations/migrations.go @@ -90,7 +90,7 @@ func _1593601729_initial_schemaDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1593601729_initial_schema.down.sql", size: 144, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1593601729_initial_schema.down.sql", size: 144, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa, 0x95, 0x55, 0x64, 0x38, 0x40, 0x16, 0xbf, 0x8b, 0x1c, 0x18, 0xb4, 0xc5, 0x7f, 0xd0, 0xb8, 0xf0, 0x3c, 0xa2, 0x82, 0xf8, 0x8d, 0x5a, 0xd3, 0xb6, 0x6e, 0xa3, 0xb4, 0xc, 0x9, 0x33, 0x0}} return a, nil } @@ -110,7 +110,7 @@ func _1593601729_initial_schemaUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1593601729_initial_schema.up.sql", size: 1773, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1593601729_initial_schema.up.sql", size: 1773, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4e, 0x1e, 0x5, 0x35, 0x9, 0xb2, 0x2d, 0x6f, 0x33, 0x63, 0xa2, 0x7a, 0x5b, 0xd2, 0x2d, 0xcb, 0x79, 0x7e, 0x6, 0xb4, 0x9d, 0x35, 0xd8, 0x9b, 0x55, 0xe5, 0xf8, 0x44, 0xca, 0xa6, 0xf3, 0xd3}} return a, nil } @@ -130,7 +130,7 @@ func _1597909626_add_server_typeDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1597909626_add_server_type.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1597909626_add_server_type.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}} return a, nil } @@ -150,7 +150,7 @@ func _1597909626_add_server_typeUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1597909626_add_server_type.up.sql", size: 145, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1597909626_add_server_type.up.sql", size: 145, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc8, 0x3f, 0xe0, 0xe7, 0x57, 0x0, 0x5d, 0x60, 0xf3, 0x55, 0x64, 0x71, 0x80, 0x3c, 0xca, 0x8, 0x61, 0xb5, 0x3c, 0xe, 0xa1, 0xe4, 0x61, 0xd1, 0x4e, 0xd8, 0xb2, 0x55, 0xdd, 0x87, 0x62, 0x9b}} return a, nil } @@ -170,7 +170,7 @@ func _1599053776_add_chat_id_and_typeDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1599053776_add_chat_id_and_type.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1599053776_add_chat_id_and_type.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}} return a, nil } @@ -190,7 +190,7 @@ func _1599053776_add_chat_id_and_typeUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1599053776_add_chat_id_and_type.up.sql", size: 264, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1599053776_add_chat_id_and_type.up.sql", size: 264, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xea, 0x7a, 0xf9, 0xc4, 0xa2, 0x96, 0x2e, 0xf9, 0x8f, 0x7, 0xf1, 0x1e, 0x73, 0x8a, 0xa6, 0x3a, 0x13, 0x4, 0x73, 0x82, 0x83, 0xb, 0xe3, 0xb5, 0x3b, 0x7e, 0xd, 0x23, 0xce, 0x98, 0xd4, 0xdc}} return a, nil } @@ -210,7 +210,7 @@ func docGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "doc.go", size: 382, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "doc.go", size: 382, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc0, 0x2f, 0x1e, 0x64, 0x9, 0x93, 0xe4, 0x8b, 0xf2, 0x98, 0x5a, 0x45, 0xe2, 0x80, 0x88, 0x67, 0x7a, 0x2d, 0xd7, 0x4b, 0xd1, 0x73, 0xb6, 0x6d, 0x15, 0xc2, 0x0, 0x34, 0xcd, 0xa0, 0xdb, 0x20}} return a, nil } diff --git a/protocol/pushnotificationserver/migrations/migrations.go b/protocol/pushnotificationserver/migrations/migrations.go index fcd95da0c..feb73a6aa 100644 --- a/protocol/pushnotificationserver/migrations/migrations.go +++ b/protocol/pushnotificationserver/migrations/migrations.go @@ -88,7 +88,7 @@ func _1593601728_initial_schemaDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1593601728_initial_schema.down.sql", size: 200, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1593601728_initial_schema.down.sql", size: 200, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x88, 0x8a, 0x61, 0x81, 0x57, 0x45, 0x9b, 0x97, 0x9b, 0x1f, 0xf6, 0x94, 0x8a, 0x20, 0xb3, 0x2b, 0xff, 0x69, 0x49, 0xf4, 0x58, 0xcc, 0xd0, 0x55, 0xcc, 0x9a, 0x8b, 0xb6, 0x7f, 0x29, 0x53, 0xc1}} return a, nil } @@ -108,7 +108,7 @@ func _1593601728_initial_schemaUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1593601728_initial_schema.up.sql", size: 675, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1593601728_initial_schema.up.sql", size: 675, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfd, 0x61, 0x90, 0x79, 0xd9, 0x14, 0x65, 0xe9, 0x96, 0x53, 0x17, 0x33, 0x54, 0xeb, 0x8b, 0x5d, 0x95, 0x99, 0x10, 0x36, 0x58, 0xdd, 0xb2, 0xbf, 0x45, 0xd9, 0xbb, 0xc4, 0x92, 0xe, 0xce, 0x2}} return a, nil } @@ -128,7 +128,7 @@ func _1598419937_add_push_notifications_tableDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1598419937_add_push_notifications_table.down.sql", size: 51, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1598419937_add_push_notifications_table.down.sql", size: 51, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc, 0x98, 0xc8, 0x30, 0x45, 0x5b, 0xc5, 0x7d, 0x13, 0x5d, 0xe7, 0xc8, 0x23, 0x43, 0xf7, 0xdc, 0x9c, 0xe2, 0xdd, 0x63, 0xf0, 0xb7, 0x16, 0x40, 0xc, 0xda, 0xb9, 0x16, 0x70, 0x2b, 0x5a, 0x7e}} return a, nil } @@ -148,7 +148,7 @@ func _1598419937_add_push_notifications_tableUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1598419937_add_push_notifications_table.up.sql", size: 104, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "1598419937_add_push_notifications_table.up.sql", size: 104, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2, 0x3e, 0xef, 0xf, 0xc2, 0xdf, 0xbc, 0x99, 0x7a, 0xc2, 0xd3, 0x64, 0x4f, 0x4c, 0x7e, 0xfc, 0x2e, 0x8c, 0xa7, 0x54, 0xd3, 0x4d, 0x25, 0x98, 0x41, 0xbc, 0xea, 0xd7, 0x2, 0xc1, 0xd0, 0x52}} return a, nil } @@ -168,7 +168,7 @@ func docGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "doc.go", size: 382, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "doc.go", size: 382, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc0, 0x2f, 0x1e, 0x64, 0x9, 0x93, 0xe4, 0x8b, 0xf2, 0x98, 0x5a, 0x45, 0xe2, 0x80, 0x88, 0x67, 0x7a, 0x2d, 0xd7, 0x4b, 0xd1, 0x73, 0xb6, 0x6d, 0x15, 0xc2, 0x0, 0x34, 0xcd, 0xa0, 0xdb, 0x20}} return a, nil } diff --git a/protocol/transport/waku/migrations/migrations.go b/protocol/transport/waku/migrations/migrations.go index 91ee07077..3e7b1a01e 100644 --- a/protocol/transport/waku/migrations/migrations.go +++ b/protocol/transport/waku/migrations/migrations.go @@ -86,7 +86,7 @@ func _1561059284_add_waku_keysDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1561059284_add_waku_keys.down.sql", size: 22, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1561059284_add_waku_keys.down.sql", size: 22, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe5, 0x2a, 0x7e, 0x9, 0xa3, 0xdd, 0xc6, 0x3, 0xfa, 0xaa, 0x98, 0xa0, 0x26, 0x5e, 0x67, 0x43, 0xe6, 0x20, 0xfd, 0x10, 0xfd, 0x60, 0x89, 0x17, 0x13, 0x87, 0x1b, 0x44, 0x36, 0x79, 0xb6, 0x60}} return a, nil } @@ -106,7 +106,7 @@ func _1561059284_add_waku_keysUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1561059284_add_waku_keys.up.sql", size: 109, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1561059284_add_waku_keys.up.sql", size: 109, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa9, 0x5c, 0x8, 0x32, 0xef, 0x12, 0x88, 0x21, 0xd, 0x7a, 0x42, 0x4d, 0xe7, 0x2d, 0x6c, 0x99, 0xb6, 0x1, 0xf1, 0xba, 0x2c, 0x40, 0x8d, 0xa9, 0x4b, 0xe6, 0xc4, 0x21, 0xec, 0x47, 0x6b, 0xf7}} return a, nil } @@ -126,7 +126,7 @@ func docGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "doc.go", size: 373, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "doc.go", size: 373, mode: os.FileMode(0644), modTime: time.Unix(1603694101, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x23, 0x6a, 0xc1, 0xce, 0x94, 0xf6, 0xef, 0xf1, 0x97, 0x95, 0xb, 0x35, 0xaf, 0x5f, 0xe7, 0x5f, 0xac, 0x6e, 0xb8, 0xab, 0xba, 0xb5, 0x35, 0x97, 0x22, 0x36, 0x11, 0xce, 0x44, 0xfc, 0xfa, 0xac}} return a, nil } diff --git a/protocol/transport/whisper/migrations/migrations.go b/protocol/transport/whisper/migrations/migrations.go index 32031d366..ff60d2d6b 100644 --- a/protocol/transport/whisper/migrations/migrations.go +++ b/protocol/transport/whisper/migrations/migrations.go @@ -86,7 +86,7 @@ func _1561059285_add_whisper_keysDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1561059285_add_whisper_keys.down.sql", size: 25, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1561059285_add_whisper_keys.down.sql", size: 25, mode: os.FileMode(0644), modTime: time.Unix(1610115164, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb9, 0x31, 0x3f, 0xce, 0xfa, 0x44, 0x36, 0x1b, 0xb0, 0xec, 0x5d, 0xb, 0x90, 0xb, 0x21, 0x4f, 0xd5, 0xe5, 0x50, 0xed, 0xc7, 0x43, 0xdf, 0x83, 0xb4, 0x3a, 0xc1, 0x55, 0x2e, 0x53, 0x7c, 0x67}} return a, nil } @@ -106,7 +106,7 @@ func _1561059285_add_whisper_keysUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1561059285_add_whisper_keys.up.sql", size: 112, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "1561059285_add_whisper_keys.up.sql", size: 112, mode: os.FileMode(0644), modTime: time.Unix(1610115164, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x25, 0x41, 0xc, 0x92, 0xdd, 0x9e, 0xff, 0x5d, 0xd0, 0x93, 0xe4, 0x24, 0x50, 0x29, 0xcf, 0xc6, 0xf7, 0x49, 0x3c, 0x73, 0xd9, 0x8c, 0xfa, 0xf2, 0xcf, 0xf6, 0x6f, 0xbc, 0x31, 0xe6, 0xf7, 0xe2}} return a, nil } @@ -126,7 +126,7 @@ func docGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "doc.go", size: 373, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "doc.go", size: 373, mode: os.FileMode(0644), modTime: time.Unix(1610115164, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x23, 0x6a, 0xc1, 0xce, 0x94, 0xf6, 0xef, 0xf1, 0x97, 0x95, 0xb, 0x35, 0xaf, 0x5f, 0xe7, 0x5f, 0xac, 0x6e, 0xb8, 0xab, 0xba, 0xb5, 0x35, 0x97, 0x22, 0x36, 0x11, 0xce, 0x44, 0xfc, 0xfa, 0xac}} return a, nil } diff --git a/services/ext/api.go b/services/ext/api.go index 59efc49e0..7727ff8cf 100644 --- a/services/ext/api.go +++ b/services/ext/api.go @@ -265,6 +265,10 @@ func (api *PublicAPI) Chats(parent context.Context) []*protocol.Chat { return api.service.messenger.Chats() } +func (api *PublicAPI) ActiveChats(parent context.Context) []*protocol.Chat { + return api.service.messenger.ActiveChats() +} + func (api *PublicAPI) DeleteChat(parent context.Context, chatID string) error { return api.service.messenger.DeleteChat(chatID) } @@ -696,6 +700,34 @@ func (api *PublicAPI) EnsVerified(pk, ensName string) error { return api.service.messenger.ENSVerified(pk, ensName) } +func (api *PublicAPI) UnreadActivityCenterNotificationsCount() (uint64, error) { + return api.service.messenger.UnreadActivityCenterNotificationsCount() +} + +func (api *PublicAPI) MarkAllActivityCenterNotificationsRead() error { + return api.service.messenger.MarkAllActivityCenterNotificationsRead() +} + +func (api *PublicAPI) AcceptAllActivityCenterNotifications() (*protocol.MessengerResponse, error) { + return api.service.messenger.AcceptAllActivityCenterNotifications() +} + +func (api *PublicAPI) AcceptActivityCenterNotifications(ids []types.HexBytes) (*protocol.MessengerResponse, error) { + return api.service.messenger.AcceptActivityCenterNotifications(ids) +} + +func (api *PublicAPI) DismissAllActivityCenterNotifications() error { + return api.service.messenger.DismissAllActivityCenterNotifications() +} + +func (api *PublicAPI) DismissActivityCenterNotifications(ids []types.HexBytes) error { + return api.service.messenger.DismissActivityCenterNotifications(ids) +} + +func (api *PublicAPI) ActivityCenterNotifications(cursor string, limit uint64) (*protocol.ActivityCenterPaginationResponse, error) { + return api.service.messenger.ActivityCenterNotifications(cursor, limit) +} + // Echo is a method for testing purposes. func (api *PublicAPI) Echo(ctx context.Context, message string) (string, error) { return message, nil diff --git a/static/bindata.go b/static/bindata.go index 79a3c3d6f..189d77edd 100644 --- a/static/bindata.go +++ b/static/bindata.go @@ -97,7 +97,7 @@ func ConfigReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "../config/README.md", size: 3153, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "../config/README.md", size: 3153, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x84, 0xf1, 0x44, 0x5b, 0x33, 0xe5, 0xfa, 0xe6, 0x38, 0x77, 0x19, 0x91, 0x6e, 0xd8, 0x8e, 0x8d, 0xaa, 0x32, 0xb2, 0x8b, 0xf9, 0x4f, 0x3, 0xe, 0xc0, 0xca, 0x5e, 0x5d, 0xec, 0x37, 0x1d, 0xc3}} return a, nil } @@ -117,7 +117,7 @@ func ConfigCliFleetEthProdJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "../config/cli/fleet-eth.prod.json", size: 4925, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "../config/cli/fleet-eth.prod.json", size: 4925, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x97, 0x5a, 0x72, 0x64, 0x6b, 0xee, 0xe6, 0x97, 0xda, 0xe8, 0x53, 0x7c, 0x33, 0x25, 0x27, 0x55, 0xa8, 0xe0, 0x9a, 0xc2, 0x16, 0xcf, 0xc0, 0x91, 0x8a, 0xbc, 0x98, 0x5, 0xe5, 0x63, 0x83, 0x77}} return a, nil } @@ -137,7 +137,7 @@ func ConfigCliFleetEthStagingJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "../config/cli/fleet-eth.staging.json", size: 2307, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "../config/cli/fleet-eth.staging.json", size: 2307, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa, 0x55, 0x35, 0x5e, 0xf5, 0x90, 0x37, 0x0, 0xe4, 0x45, 0x8c, 0x19, 0x77, 0x14, 0xa0, 0x94, 0x1c, 0x9b, 0x78, 0xa7, 0x2e, 0x58, 0x45, 0x1b, 0xba, 0xf3, 0xfb, 0x62, 0x87, 0x97, 0xf8, 0x96}} return a, nil } @@ -157,7 +157,7 @@ func ConfigCliFleetEthTestJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "../config/cli/fleet-eth.test.json", size: 2315, mode: os.FileMode(0644), modTime: time.Unix(1618237056, 0)} + info := bindataFileInfo{name: "../config/cli/fleet-eth.test.json", size: 2315, mode: os.FileMode(0644), modTime: time.Unix(1611588835, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7, 0x92, 0x14, 0x26, 0xa6, 0x12, 0xb1, 0x0, 0x2d, 0xbe, 0x9a, 0xb7, 0x55, 0xdb, 0xfc, 0x1f, 0x75, 0xe, 0xc2, 0x2b, 0xad, 0xfe, 0x44, 0x78, 0x2e, 0x7f, 0x8, 0x7f, 0xd1, 0x9e, 0x11, 0x2c}} return a, nil } @@ -177,7 +177,7 @@ func ConfigCliLesEnabledJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "../config/cli/les-enabled.json", size: 58, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "../config/cli/les-enabled.json", size: 58, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7e, 0xee, 0x27, 0xa7, 0x74, 0xa0, 0x46, 0xa1, 0x41, 0xed, 0x4d, 0x16, 0x5b, 0xf3, 0xf0, 0x7c, 0xc8, 0x2f, 0x6f, 0x47, 0xa4, 0xbb, 0x5f, 0x43, 0x33, 0xd, 0x9, 0x9d, 0xea, 0x9e, 0x15, 0xee}} return a, nil } @@ -197,7 +197,7 @@ func ConfigCliMailserverEnabledJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "../config/cli/mailserver-enabled.json", size: 176, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "../config/cli/mailserver-enabled.json", size: 176, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x34, 0xec, 0x81, 0x8b, 0x99, 0xb6, 0xdb, 0xc0, 0x8b, 0x46, 0x97, 0x96, 0xc7, 0x58, 0x30, 0x33, 0xef, 0x54, 0x25, 0x87, 0x7b, 0xb9, 0x94, 0x6b, 0x18, 0xa4, 0x5b, 0x58, 0x67, 0x7c, 0x44, 0xa6}} return a, nil } @@ -217,7 +217,7 @@ func ConfigStatusChainGenesisJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "../config/status-chain-genesis.json", size: 612, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "../config/status-chain-genesis.json", size: 612, mode: os.FileMode(0644), modTime: time.Unix(1599559876, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb, 0xf0, 0xc, 0x1, 0x95, 0x65, 0x6, 0x55, 0x48, 0x8f, 0x83, 0xa0, 0xb4, 0x81, 0xda, 0xad, 0x30, 0x6d, 0xb2, 0x78, 0x1b, 0x26, 0x4, 0x13, 0x12, 0x9, 0x6, 0xae, 0x3a, 0x2c, 0x1, 0x71}} return a, nil } @@ -237,7 +237,7 @@ func keysBootnodeKey() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/bootnode.key", size: 65, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "keys/bootnode.key", size: 65, mode: os.FileMode(0644), modTime: time.Unix(1599559877, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x31, 0xcf, 0x27, 0xd4, 0x96, 0x2e, 0x32, 0xcd, 0x58, 0x96, 0x2a, 0xe5, 0x8c, 0xa0, 0xf1, 0x73, 0x1f, 0xd6, 0xd6, 0x8b, 0xb, 0x73, 0xd3, 0x2c, 0x84, 0x1a, 0x56, 0xa4, 0x74, 0xb6, 0x95, 0x20}} return a, nil } @@ -257,7 +257,7 @@ func keysFirebaseauthkey() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/firebaseauthkey", size: 153, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "keys/firebaseauthkey", size: 153, mode: os.FileMode(0644), modTime: time.Unix(1536843582, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe, 0x69, 0x23, 0x64, 0x7d, 0xf9, 0x14, 0x37, 0x6f, 0x2b, 0x1, 0xf0, 0xb0, 0xa4, 0xb2, 0xd0, 0x18, 0xcd, 0xf9, 0xeb, 0x57, 0xa3, 0xfd, 0x79, 0x25, 0xa7, 0x9c, 0x3, 0xce, 0x26, 0xec, 0xe1}} return a, nil } @@ -277,7 +277,7 @@ func keysTestAccount1StatusChainPk() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/test-account1-status-chain.pk", size: 489, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "keys/test-account1-status-chain.pk", size: 489, mode: os.FileMode(0644), modTime: time.Unix(1599559877, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x8f, 0xba, 0x35, 0x1, 0x2b, 0x9d, 0xad, 0xf0, 0x2d, 0x3c, 0x4d, 0x6, 0xb5, 0x22, 0x2, 0x47, 0xd4, 0x1c, 0xf4, 0x31, 0x2f, 0xb, 0x5b, 0x27, 0x5d, 0x43, 0x97, 0x58, 0x2d, 0xf0, 0xe1, 0xbe}} return a, nil } @@ -297,7 +297,7 @@ func keysTestAccount1Pk() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/test-account1.pk", size: 491, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "keys/test-account1.pk", size: 491, mode: os.FileMode(0644), modTime: time.Unix(1599559877, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x9, 0x43, 0xc2, 0xf4, 0x8c, 0xc6, 0x64, 0x25, 0x8c, 0x7, 0x8c, 0xa8, 0x89, 0x2b, 0x7b, 0x9b, 0x4f, 0x81, 0xcb, 0xce, 0x3d, 0xef, 0x82, 0x9c, 0x27, 0x27, 0xa9, 0xc5, 0x46, 0x70, 0x30, 0x38}} return a, nil } @@ -317,7 +317,7 @@ func keysTestAccount2StatusChainPk() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/test-account2-status-chain.pk", size: 489, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "keys/test-account2-status-chain.pk", size: 489, mode: os.FileMode(0644), modTime: time.Unix(1599559877, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x9, 0xf8, 0x5c, 0xe9, 0x92, 0x96, 0x2d, 0x88, 0x2b, 0x8e, 0x42, 0x3f, 0xa4, 0x93, 0x6c, 0xad, 0xe9, 0xc0, 0x1b, 0x8a, 0x8, 0x8c, 0x5e, 0x7a, 0x84, 0xa2, 0xf, 0x9f, 0x77, 0x58, 0x2c, 0x2c}} return a, nil } @@ -337,7 +337,7 @@ func keysTestAccount2Pk() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/test-account2.pk", size: 491, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "keys/test-account2.pk", size: 491, mode: os.FileMode(0644), modTime: time.Unix(1599559877, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x9f, 0x72, 0xd5, 0x95, 0x5c, 0x5a, 0x99, 0x9d, 0x2f, 0x21, 0x83, 0xd7, 0x10, 0x17, 0x4a, 0x3d, 0x65, 0xc9, 0x26, 0x1a, 0x2c, 0x9d, 0x65, 0x63, 0xd2, 0xa0, 0xfc, 0x7c, 0x0, 0x87, 0x38, 0x9f}} return a, nil } @@ -357,7 +357,7 @@ func keysTestAccount3BeforeEip55Pk() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "keys/test-account3-before-eip55.pk", size: 489, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "keys/test-account3-before-eip55.pk", size: 489, mode: os.FileMode(0644), modTime: time.Unix(1599559877, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x81, 0x40, 0x56, 0xc1, 0x5e, 0x10, 0x6e, 0x28, 0x15, 0x3, 0x4e, 0xc4, 0xc4, 0x71, 0x4d, 0x16, 0x99, 0xcc, 0x1b, 0x63, 0xee, 0x10, 0x20, 0xe4, 0x59, 0x52, 0x3f, 0xc0, 0xad, 0x15, 0x13, 0x72}} return a, nil } diff --git a/t/bindata.go b/t/bindata.go index cf96ec39e..14abbfc1e 100644 --- a/t/bindata.go +++ b/t/bindata.go @@ -86,7 +86,7 @@ func configPublicChainAccountsJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "config/public-chain-accounts.json", size: 307, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "config/public-chain-accounts.json", size: 307, mode: os.FileMode(0644), modTime: time.Unix(1599559877, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x76, 0x5d, 0xc0, 0xfe, 0x57, 0x50, 0x18, 0xec, 0x2d, 0x61, 0x1b, 0xa9, 0x81, 0x11, 0x5f, 0x77, 0xf7, 0xb6, 0x67, 0x82, 0x1, 0x40, 0x68, 0x9d, 0xc5, 0x41, 0xaf, 0xce, 0x43, 0x81, 0x92, 0x96}} return a, nil } @@ -106,7 +106,7 @@ func configStatusChainAccountsJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "config/status-chain-accounts.json", size: 543, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "config/status-chain-accounts.json", size: 543, mode: os.FileMode(0644), modTime: time.Unix(1599559877, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x8e, 0xb3, 0x61, 0x51, 0x70, 0x3c, 0x12, 0x3e, 0xf1, 0x1c, 0x81, 0xfb, 0x9a, 0x7c, 0xe3, 0x63, 0xd0, 0x8f, 0x12, 0xc5, 0x2d, 0xf4, 0xea, 0x27, 0x33, 0xef, 0xca, 0xf9, 0x3f, 0x72, 0x44, 0xbf}} return a, nil } @@ -126,7 +126,7 @@ func configTestDataJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "config/test-data.json", size: 84, mode: os.FileMode(0644), modTime: time.Unix(1585751575, 0)} + info := bindataFileInfo{name: "config/test-data.json", size: 84, mode: os.FileMode(0644), modTime: time.Unix(1599559877, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xce, 0x9d, 0x80, 0xf5, 0x87, 0xfa, 0x57, 0x1d, 0xa1, 0xd5, 0x7a, 0x10, 0x3, 0xac, 0xd7, 0xf4, 0x64, 0x32, 0x96, 0x2b, 0xb7, 0x21, 0xb7, 0xa6, 0x80, 0x40, 0xe9, 0x65, 0xe3, 0xd6, 0xbd, 0x40}} return a, nil }