diff --git a/externs.js b/externs.js index 6250e584a5..5028479406 100644 --- a/externs.js +++ b/externs.js @@ -67,6 +67,7 @@ var TopLevel = { "confirmMessagesProcessedByID" : function () {}, "connectionChange" : function () {}, "console" : function () {}, + "contacts": function () {}, "ContactRequest" : function () {}, "ContactRequestConfirmed" : function () {}, "ContactRequestConfirmedHandler" : function () {}, @@ -145,6 +146,7 @@ var TopLevel = { "extractGroupMembershipSignatures" : function () {}, "identicon": function() {}, "identiconAsync": function() {}, + "installations": function() {}, "generateAlias": function() {}, "generateAliasAsync": function() {}, "generateAliasAndIdenticonAsync": function() {}, diff --git a/src/status_im/chat/models.cljs b/src/status_im/chat/models.cljs index f165708030..8a844f701d 100644 --- a/src/status_im/chat/models.cljs +++ b/src/status_im/chat/models.cljs @@ -98,8 +98,13 @@ (let [chat (merge (or (get (:chats db) chat-id) (create-new-chat chat-id cofx)) - chat-props)] - {:db (update-in db [:chats chat-id] merge chat)})) + chat-props) + new? (not (get-in db [:chats chat-id])) + public? (public-chat? chat)] + (fx/merge cofx + {:db (update-in db [:chats chat-id] merge chat)} + (when (and public? new?) + (transport.filters/load-chat chat-id))))) (fx/defn upsert-chat "Upsert chat when not deleted" diff --git a/src/status_im/contact/core.cljs b/src/status_im/contact/core.cljs index 1c029632ec..64e6837a3b 100644 --- a/src/status_im/contact/core.cljs +++ b/src/status_im/contact/core.cljs @@ -1,10 +1,13 @@ (ns status-im.contact.core (:require [re-frame.core :as re-frame] + [taoensso.timbre :as log] + [status-im.multiaccounts.update.core :as multiaccounts.update] [status-im.multiaccounts.model :as multiaccounts.model] [status-im.transport.filters.core :as transport.filters] [status-im.contact.db :as contact.db] [status-im.ethereum.core :as ethereum] + [status-im.ethereum.json-rpc :as json-rpc] [status-im.data-store.contacts :as contacts-store] [status-im.mailserver.core :as mailserver] [status-im.transport.message.contact :as message.contact] @@ -51,6 +54,27 @@ :profile-image photo-path :address address})) +(fx/defn handle-update-from-contact-request [{:keys [db] :as cofx} {:keys [last-updated photo-path]}] + (when (> last-updated (get-in db [:multiaccount :last-updated])) + (fx/merge cofx + (multiaccounts.update/multiaccount-update :last-updated last-updated {:dont-sync? true}) + (multiaccounts.update/multiaccount-update :photo-path photo-path {:dont-sync? true})))) + +(fx/defn ensure-contact + [{:keys [db] :as cofx} + {:keys [public-key] :as contact}] + (let [new? (get-in db [:contacts/contacts public-key]) + us? (= public-key (multiaccounts.model/current-public-key cofx))] + (fx/merge cofx + {:db (-> db + (update-in [:contacts/contacts public-key] merge contact))} + + (cond + us? + (handle-update-from-contact-request contact) + new? + (transport.filters/load-contact contact))))) + (fx/defn upsert-contact [{:keys [db] :as cofx} {:keys [public-key] :as contact}] @@ -62,9 +86,10 @@ (fx/defn send-contact-request [{:keys [db] :as cofx} {:keys [public-key] :as contact}] - (if (contact.db/pending? contact) - (protocol/send (message.contact/map->ContactRequest (own-info db)) public-key cofx) - (protocol/send (message.contact/map->ContactRequestConfirmed (own-info db)) public-key cofx))) + (let [{:keys [name profile-image]} (own-info db)] + {::json-rpc/call [{:method "shhext_sendContactUpdate" + :params [public-key name profile-image] + :on-success #(log/debug "contact request sent" public-key)}]})) (fx/defn add-contact "Add a contact and set pending to false" @@ -186,4 +211,4 @@ merge {:name ens-name :ens-verified-at (quot (time/timestamp) 1000) - :ens-verified true})}) \ No newline at end of file + :ens-verified true})}) diff --git a/src/status_im/core.cljs b/src/status_im/core.cljs index 4bc9441673..7e461c46b3 100644 --- a/src/status_im/core.cljs +++ b/src/status_im/core.cljs @@ -4,8 +4,6 @@ [status-im.utils.platform :as platform] [status-im.ui.components.react :as react] [reagent.core :as reagent] - status-im.transport.impl.receive - status-im.transport.impl.send [status-im.react-native.js-dependencies :as js-dependencies] [status-im.utils.logging.core :as utils.logs] cljs.core.specs.alpha)) diff --git a/src/status_im/ethereum/json_rpc.cljs b/src/status_im/ethereum/json_rpc.cljs index d20171d706..05682a12dc 100644 --- a/src/status_im/ethereum/json_rpc.cljs +++ b/src/status_im/ethereum/json_rpc.cljs @@ -30,6 +30,8 @@ "shh_generateSymKeyFromPassword" {} "shh_getSymKey" {} "shh_markTrustedPeer" {} + "shhext_sendPairInstallation" {} + "shhext_syncDevices" {} "shhext_requestMessages" {} "shhext_sendDirectMessage" {} "shhext_sendPublicMessage" {} @@ -49,6 +51,8 @@ "shhext_loadFilters" {} "shhext_loadFilter" {} "shhext_removeFilters" {} + "shhext_sendContactUpdate" {} + "shhext_sendContactUpdates" {} "shhext_chats" {} "shhext_addSystemMessages" {} "shhext_deleteMessagesFrom" {} diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index cb4f1c0a24..d551e04016 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -507,10 +507,7 @@ (handlers/register-handler-fx :chat.ui/start-public-chat (fn [cofx [_ topic opts]] - (fx/merge - cofx - (chat/start-public-chat topic opts) - (pairing/sync-public-chat topic)))) + (chat/start-public-chat cofx topic opts))) (handlers/register-handler-fx :chat.ui/remove-chat @@ -1248,7 +1245,8 @@ (handlers/register-handler-fx :pairing.ui/pair-devices-pressed (fn [cofx _] - (pairing/pair-installation cofx))) + (log/info "Sending pair installation") + (pairing/send-pair-installation cofx))) (handlers/register-handler-fx :pairing.ui/set-name-pressed diff --git a/src/status_im/multiaccounts/update/core.cljs b/src/status_im/multiaccounts/update/core.cljs index 49e7e7d0bf..9b18d66037 100644 --- a/src/status_im/multiaccounts/update/core.cljs +++ b/src/status_im/multiaccounts/update/core.cljs @@ -1,6 +1,5 @@ (ns status-im.multiaccounts.update.core (:require [status-im.contact.db :as contact.db] - [status-im.ethereum.json-rpc :as json-rpc] [status-im.transport.message.contact :as message.contact] [status-im.transport.message.protocol :as protocol] @@ -8,43 +7,19 @@ [status-im.utils.types :as types] [taoensso.timbre :as log])) -(fx/defn multiaccount-update-message [{:keys [db] :as cofx}] +(fx/defn send-multiaccount-update [{:keys [db]}] (let [multiaccount (:multiaccount db) {:keys [name preferred-name photo-path address]} multiaccount] - (message.contact/ContactUpdate. (or preferred-name name) photo-path address nil nil))) - -(fx/defn send-multiaccount-update [cofx] - (protocol/send - (multiaccount-update-message cofx) - nil - cofx)) - -(fx/defn send-contact-update-fx - [{:keys [db] :as cofx} chat-id payload] - (protocol/send-with-pubkey cofx - {:chat-id chat-id - :payload payload - :success-event [:transport/contact-message-sent chat-id]})) - -(fx/defn contact-public-keys [{:keys [db]}] - (reduce (fn [acc [_ {:keys [public-key] :as contact}]] - (if (contact.db/active? contact) - (conj acc public-key) - acc)) - #{} - (:contacts/contacts db))) - -(fx/defn send-contact-update [cofx payload] - (let [public-keys (contact-public-keys cofx)] - ;;NOTE: chats with contacts use public-key as chat-id - (map #(send-contact-update-fx % payload) public-keys))) + {::json-rpc/call [{:method "shhext_sendContactUpdates" + :params [(or preferred-name name) photo-path] + :on-success #(log/debug "sent contact update")}]})) (fx/defn multiaccount-update "Takes effects (containing :db) + new multiaccount fields, adds all effects necessary for multiaccount update. Optionally, one can specify a success-event to be dispatched after fields are persisted." [{:keys [db] :as cofx} setting setting-value - {:keys [on-success] :or {on-success #()}}] + {:keys [dont-sync? on-success] :or {on-success #()}}] (let [current-multiaccount (:multiaccount db)] (if (empty? current-multiaccount) ;; NOTE: this should never happen, but if it does this is a critical error @@ -58,7 +33,8 @@ [{:method "settings_saveSetting" :params [setting setting-value] :on-success on-success}]} - (when (#{:name :photo-path :prefered-name} setting) + (when (and (not dont-sync?) + (#{:name :photo-path :prefered-name} setting)) (send-multiaccount-update)))))) (fx/defn clean-seed-phrase diff --git a/src/status_im/multiaccounts/update/publisher.cljs b/src/status_im/multiaccounts/update/publisher.cljs index 4d5302d42e..4063920f23 100644 --- a/src/status_im/multiaccounts/update/publisher.cljs +++ b/src/status_im/multiaccounts/update/publisher.cljs @@ -1,6 +1,8 @@ (ns status-im.multiaccounts.update.publisher - (:require [status-im.constants :as constants] + (:require [taoensso.timbre :as log] + [status-im.constants :as constants] [status-im.multiaccounts.update.core :as multiaccounts] + [status-im.ethereum.json-rpc :as json-rpc] [status-im.pairing.core :as pairing] [status-im.transport.shh :as shh])) @@ -17,21 +19,10 @@ (pos? last-updated) (< publish-updates-interval (- now last-updated))) - (let [public-keys (multiaccounts/contact-public-keys {:db db}) - payload (multiaccounts/multiaccount-update-message {:db db}) - sync-message (pairing/sync-installation-multiaccount-message {:db db})] - (doseq [pk public-keys] - (shh/send-direct-message! {:pubKey pk - :sig my-public-key - :chat constants/contact-discovery - :payload payload} - [:multiaccounts.update.callback/published] - [:multiaccounts.update.callback/failed-to-publish] - 1)) - (shh/send-direct-message! {:pubKey my-public-key - :sig my-public-key - :chat constants/contact-discovery - :payload sync-message} - [:multiaccounts.update.callback/published] - [:multiaccounts.update.callback/failed-to-publish] - 1))))) + (let [multiaccount (:multiaccount db) + {:keys [name preferred-name photo-path address]} multiaccount] + + (log/debug "sending contact updates") + (json-rpc/call {:method "shhext_sendContactUpdates" + :params [(or preferred-name name) photo-path] + :on-success #(log/debug "sent contact updates")}))))) diff --git a/src/status_im/pairing/core.cljs b/src/status_im/pairing/core.cljs index f36c750eb8..548e461be8 100644 --- a/src/status_im/pairing/core.cljs +++ b/src/status_im/pairing/core.cljs @@ -43,8 +43,6 @@ :on-success on-success :on-failure on-failure})) -(def contact-batch-n 4) - (defn compare-installation "Sort installations, first by our installation-id, then on whether is enabled, and last on timestamp value" @@ -66,17 +64,11 @@ [our-installation-id installations] (sort (partial compare-installation our-installation-id) installations)) -(defn pair-installation [cofx] - (let [installation-id (get-in cofx [:db :multiaccount :installation-id]) - installation-name (get-in cofx [:db :pairing/installations installation-id :name]) - device-type utils.platform/os] - (protocol/send (transport.pairing/PairInstallation. installation-id device-type installation-name nil) nil cofx))) - (defn send-pair-installation - [cofx payload] - (let [current-public-key (multiaccounts.model/current-public-key cofx)] - {:shh/send-pairing-message {:src current-public-key - :payload payload}})) + [cofx] + {::json-rpc/call [{:method "shhext_sendPairInstallation" + :params [] + :on-success #(log/info "sent pair installation message")}]}) (defn merge-contact [local remote] ;;TODO we don't sync contact/blocked for now, it requires more complex handling @@ -136,46 +128,6 @@ (= :installations (:view-id db))) (prompt-user-on-new-installation %)))))) -(defn sync-installation-multiaccount-message [{:keys [db]}] - (let [multiaccount (-> db - :multiaccount - (select-keys multiaccount-mergeable-keys))] - (transport.pairing/SyncInstallation. {} multiaccount {}))) - -(defn- contact->pairing [contact] - (cond-> (-> contact - (dissoc :photo-path) - (update :system-tags disj :contact/blocked)) - ;; for compatibility with version < contact.v7 - (contact.db/added? contact) (assoc :pending? false) - (contact.db/legacy-pending? contact) (assoc :pending? true))) - -(defn- contact-batch->sync-installation-message [batch] - (let [contacts-to-sync - (reduce (fn [acc {:keys [public-key system-tags] :as contact}] - (assoc acc - public-key - (contact->pairing contact))) - {} - batch)] - (transport.pairing/SyncInstallation. contacts-to-sync {} {}))) - -(defn- chats->sync-installation-messages [{:keys [db]}] - (->> db - :chats - vals - (filter :public?) - (filter :is-active) - (map #(select-keys % [:chat-id :public?])) - (map #(transport.pairing/SyncInstallation. {} {} %)))) - -(defn sync-installation-messages [{:keys [db] :as cofx}] - (let [contacts (contact.db/get-active-contacts (:contacts/contacts db)) - contact-batches (partition-all contact-batch-n contacts)] - (concat (mapv contact-batch->sync-installation-message contact-batches) - [(sync-installation-multiaccount-message cofx)] - (chats->sync-installation-messages cofx)))) - (fx/defn enable [{:keys [db]} installation-id] {:db (assoc-in db [:pairing/installations installation-id :enabled?] @@ -253,116 +205,19 @@ :pairing/get-our-installations get-our-installations) -(fx/defn send-sync-installation - [cofx payload] - (let [current-public-key (multiaccounts.model/current-public-key cofx)] - {:shh/send-direct-message - [{:src current-public-key - :dst current-public-key - :payload payload}]})) +(defn send-installation-messages [{:keys [db]}] + (let [multiaccount (:multiaccount db) + {:keys [name preferred-name photo-path]} multiaccount] + {::json-rpc/call [{:method "shhext_syncDevices" + :params [(or preferred-name name) photo-path] + :on-success #(log/debug "successfully synced devices")}]})) -(fx/defn send-installation-message-fx [cofx payload] - (when (pairing.utils/has-paired-installations? cofx) - (protocol/send payload nil cofx))) - -(fx/defn sync-public-chat [cofx chat-id] - (let [sync-message (transport.pairing/SyncInstallation. {} {} {:public? true - :chat-id chat-id})] - (send-installation-message-fx cofx sync-message))) - -(fx/defn sync-contact - [cofx {:keys [public-key] :as contact}] - (let [sync-message (transport.pairing/SyncInstallation. - {public-key (cond-> contact - ;; for compatibility with version < contact.v7 - (contact.db/added? contact) (assoc :pending? false) - (contact.db/legacy-pending? contact) (assoc :pending? true))} - {} {})] - (send-installation-message-fx cofx sync-message))) - -(defn send-installation-messages [cofx] - ;; The message needs to be broken up in chunks as we hit the whisper size limit - (let [sync-messages (sync-installation-messages cofx) - sync-messages-fx (map send-installation-message-fx sync-messages)] - (apply fx/merge cofx sync-messages-fx))) - -(defn ensure-photo-path - "Make sure a photo path is there, generate otherwise" - [contacts] - (reduce-kv (fn [acc k {:keys [public-key photo-path] :as v}] - (assoc acc k - (assoc - v - :photo-path - (if (string/blank? photo-path) - (identicon/identicon public-key) - photo-path)))) - {} - contacts)) - -(defn ensure-system-tags - "Make sure system tags is there" - [contacts] - (reduce-kv (fn [acc k {:keys [system-tags] :as v}] - (assoc acc k - (assoc - v - :system-tags - (if system-tags - system-tags - (if (and (contains? v :pending?) (not (:pending? v))) - #{:contact/added} - #{:contact/request-received}))))) - {} - contacts)) - -(defn handle-sync-installation - [{:keys [db] :as cofx} {:keys [contacts account chat]} sender] - (let [confirmation (:metadata cofx)] - (when (= sender (multiaccounts.model/current-public-key cofx)) - (let [new-contacts (when (seq contacts) - (vals (merge-contacts (:contacts/contacts db) - ((comp ensure-photo-path - ensure-system-tags) contacts)))) - {old-name :name - old-photo-path :photo-path - old-last-updated :last-updated - :as multiaccount} (:multiaccount db) - {:keys [name photo-path last-updated]} - (merge-multiaccount multiaccount account) - contacts-fx (when new-contacts - (mapv contact/upsert-contact new-contacts))] - (apply fx/merge - cofx - (concat - [{:db (-> db - (assoc-in [:multiaccount :name] name) - (assoc-in [:multiaccount :last-updated] last-updated) - (assoc-in [:multiaccount :photo-path] photo-path)) - ::json-rpc/call - [(when (not= old-name name) - {:method "settings_saveConfig" - :params [:name name] - :on-success #(log/debug "handled sync of name field successfully")}) - (when (not= old-photo-path photo-path) - {:method "settings_saveConfig" - :params [:photo-path photo-path] - :on-success #(log/debug "handled sync of photo-path field successfully")}) - (when (not= old-last-updated last-updated) - {:method "settings_saveConfig" - :params [:last-updated last-updated] - :on-success #(log/debug "handled sync of last-updated field successfully")})]} - #(when (:public? chat) - (models.chat/start-public-chat % (:chat-id chat) {:dont-navigate? true}))] - contacts-fx)))))) - -(defn handle-pair-installation - [{:keys [db] :as cofx} {:keys [name installation-id - device-type]} timestamp sender] - (when (and (= sender (multiaccounts.model/current-public-key cofx)) - (not= (get-in db [:multiaccount :installation-id]) installation-id)) - {:pairing/set-installation-metadata [[installation-id {:name name - :deviceType device-type}]]})) +(defn installation<-rpc [{:keys [metadata id enabled]}] + {:installation-id id + :name (:name metadata) + :timestamp (:timestamp metadata) + :device-type (:deviceType metadata) + :enabled? enabled}) (fx/defn update-installation [{:keys [db]} installation-id metadata] {:db (update-in db [:pairing/installations installation-id] @@ -371,14 +226,13 @@ :name (:name metadata) :device-type (:deviceType metadata))}) +(fx/defn handle-installation [{:keys [db]} {:keys [id] :as i}] + {:db (assoc-in db [:pairing/installations id] (installation<-rpc i))}) + (fx/defn load-installations [{:keys [db]} installations] {:db (assoc db :pairing/installations (reduce - (fn [acc {:keys [metadata id enabled] :as i}] + (fn [acc {:keys [id] :as i}] (assoc acc id - {:installation-id id - :name (:name metadata) - :timestamp (:timestamp metadata) - :device-type (:deviceType metadata) - :enabled? enabled})) + (installation<-rpc i))) {} installations))}) diff --git a/src/status_im/transport/impl/receive.cljs b/src/status_im/transport/impl/receive.cljs deleted file mode 100644 index 240a58a0e4..0000000000 --- a/src/status_im/transport/impl/receive.cljs +++ /dev/null @@ -1,62 +0,0 @@ -(ns status-im.transport.impl.receive - (:require [status-im.group-chats.core :as group-chats] - [status-im.contact.core :as contact] - [status-im.utils.fx :as fx] - [status-im.chat.models.message :as chat.message] - [status-im.ens.core :as ens] - [status-im.pairing.core :as pairing] - [status-im.transport.message.contact :as transport.contact] - [status-im.transport.message.pairing :as transport.pairing] - [status-im.transport.message.core :as transport.message] - - [status-im.transport.message.protocol :as protocol])) - -(extend-type transport.contact/ContactRequest - protocol/StatusMessage - (receive [this _ signature timestamp cofx] - (fx/merge - cofx - (contact/handle-contact-update cofx signature timestamp this) - (ens/verify-names-from-contact-request this signature)))) - -(extend-type transport.contact/ContactRequestConfirmed - protocol/StatusMessage - (receive [this _ signature timestamp cofx] - (fx/merge - cofx - (contact/handle-contact-update cofx signature timestamp this) - (ens/verify-names-from-contact-request this signature)))) - -(extend-type transport.contact/ContactUpdate - protocol/StatusMessage - (receive [this _ signature timestamp cofx] - (fx/merge - cofx - (contact/handle-contact-update cofx signature timestamp this) - (ens/verify-names-from-contact-request this signature)))) - -(extend-type transport.pairing/SyncInstallation - protocol/StatusMessage - (receive [this _ signature _ cofx] - (pairing/handle-sync-installation cofx this signature))) - -(extend-type transport.pairing/PairInstallation - protocol/StatusMessage - (receive [this _ signature timestamp cofx] - (pairing/handle-pair-installation cofx this timestamp signature))) - -(extend-type protocol/Message - protocol/StatusMessage - (receive [this chat-id signature timestamp {:keys [db] :as cofx}] - (let [message (assoc (into {} this) - :message-id - (get-in cofx [:metadata :messageId]) - :chat-id chat-id - :whisper-timestamp (* 1000 timestamp) - :alias (get-in cofx [:metadata :author :alias]) - :identicon (get-in cofx [:metadata :author :identicon]) - :from signature - :metadata (:metadata cofx))] - (fx/merge cofx - (chat.message/receive-one message) - (ens/verify-names-from-message this signature))))) diff --git a/src/status_im/transport/impl/send.cljs b/src/status_im/transport/impl/send.cljs deleted file mode 100644 index 4042156fef..0000000000 --- a/src/status_im/transport/impl/send.cljs +++ /dev/null @@ -1,58 +0,0 @@ -(ns status-im.transport.impl.send - (:require [status-im.group-chats.core :as group-chats] - [status-im.utils.fx :as fx] - [status-im.pairing.core :as pairing] - [status-im.multiaccounts.update.core :as multiaccounts.update] - [status-im.transport.db :as transport.db] - [status-im.transport.message.pairing :as transport.pairing] - [status-im.transport.message.contact :as transport.contact] - [status-im.transport.message.protocol :as protocol])) - -(extend-type transport.pairing/PairInstallation - protocol/StatusMessage - (send [this _ cofx] - (pairing/send-pair-installation cofx this))) - -(extend-type transport.pairing/SyncInstallation - protocol/StatusMessage - (send [this _ cofx] - (pairing/send-sync-installation cofx this))) - -(extend-type transport.contact/ContactRequest - protocol/StatusMessage - (send [this chat-id cofx] - (let [sync-message (transport.pairing/SyncInstallation. - {chat-id (pairing/contact->pairing - (get-in cofx [:db :contacts/contacts chat-id]))} - nil - nil)] - (fx/merge cofx - (protocol/send-with-pubkey {:chat-id chat-id - :payload this - :success-event [:transport/contact-message-sent chat-id]}) - (pairing/send-installation-message-fx sync-message))))) - -(extend-type transport.contact/ContactRequestConfirmed - protocol/StatusMessage - (send [this chat-id {:keys [db] :as cofx}] - (let [sync-message (transport.pairing/SyncInstallation. - (select-keys - (get-in cofx [:db :contacts/contacts]) - [chat-id]) - nil - nil) - success-event [:transport/contact-message-sent chat-id]] - (fx/merge cofx - (protocol/send-with-pubkey {:chat-id chat-id - :payload this - :success-event success-event}) - (pairing/send-installation-message-fx sync-message))))) - -(extend-type transport.contact/ContactUpdate - protocol/StatusMessage - (send [this _ {:keys [db] :as cofx}] - (let [send-contact-update-fxs (multiaccounts.update/send-contact-update cofx this) - sync-message (pairing/sync-installation-multiaccount-message cofx) - fxs (conj send-contact-update-fxs - (pairing/send-installation-message-fx sync-message))] - (apply fx/merge cofx fxs)))) diff --git a/src/status_im/transport/message/core.cljs b/src/status_im/transport/message/core.cljs index be8be6e17a..ddaf41d94d 100644 --- a/src/status_im/transport/message/core.cljs +++ b/src/status_im/transport/message/core.cljs @@ -4,7 +4,10 @@ [re-frame.core :as re-frame] [status-im.chat.models.message :as models.message] [status-im.chat.models :as models.chat] + [status-im.contact.core :as models.contact] + [status-im.pairing.core :as models.pairing] [status-im.data-store.messages :as data-store.messages] + [status-im.data-store.contacts :as data-store.contacts] [status-im.data-store.chats :as data-store.chats] [status-im.constants :as constants] [status-im.utils.handlers :as handlers] @@ -57,16 +60,32 @@ ;; over it (models.chat/ensure-chat cofx (dissoc chat :unviewed-messages-count))) -(fx/defn handle-message-2 [cofx message] +(fx/defn handle-contact [cofx contact] + (models.contact/ensure-contact cofx contact)) + +(fx/defn handle-message [cofx message] (fx/merge cofx (models.message/receive-one message) (ens/verify-names-from-message message (:from message)))) (fx/defn process-response [cofx response-js] (let [chats (.-chats response-js) + contacts (.-contacts response-js) + installations (.-installations response-js) raw-messages (.-rawMessages response-js) messages (.-messages response-js)] (cond + (seq installations) + (let [installation (.pop installations)] + (fx/merge cofx + {:dispatch-later [{:ms 20 :dispatch [::process response-js]}]} + (models.pairing/handle-installation (clj-bean/->clj installation)))) + + (seq contacts) + (let [contact (.pop contacts)] + (fx/merge cofx + {:dispatch-later [{:ms 20 :dispatch [::process response-js]}]} + (handle-contact (-> contact (clj-bean/->clj) (data-store.contacts/<-rpc))))) (seq chats) (let [chat (.pop chats)] (fx/merge cofx @@ -88,7 +107,7 @@ (let [message (.pop messages)] (fx/merge cofx {:dispatch-later [{:ms 20 :dispatch [::process response-js]}]} - (handle-message-2 (-> message (clj-bean/->clj) (data-store.messages/<-rpc)))))))) + (handle-message (-> message (clj-bean/->clj) (data-store.messages/<-rpc)))))))) (handlers/register-handler-fx ::process diff --git a/src/status_im/utils/universal_links/core.cljs b/src/status_im/utils/universal_links/core.cljs index e0ae7a13f5..cc8944ee20 100644 --- a/src/status_im/utils/universal_links/core.cljs +++ b/src/status_im/utils/universal_links/core.cljs @@ -71,10 +71,7 @@ (fx/defn handle-public-chat [cofx public-chat] (log/info "universal-links: handling public chat" public-chat) - (fx/merge - cofx - (chat/start-public-chat public-chat {}) - (pairing/sync-public-chat public-chat))) + (chat/start-public-chat cofx public-chat {})) (fx/defn handle-view-profile [{:keys [db] :as cofx} public-key] (log/info "universal-links: handling view profile" public-key) diff --git a/status-go-version.json b/status-go-version.json index 7042889d34..5102435347 100644 --- a/status-go-version.json +++ b/status-go-version.json @@ -2,7 +2,7 @@ "_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh ' instead", "owner": "status-im", "repo": "status-go", - "version": "v0.39.2", - "commit-sha1": "88a1d0111e9a9d51370f14ad6b2c998f4514639b", - "src-sha256": "0vdkjxi3vj6fv5ypq98g6swrq4v020dzm45n9d3vwbk3j7ln6p40" + "version": "v0.39.4", + "commit-sha1": "e11e0b5d6c9e8222aa47c342aaa3e3ca8d83bd9d", + "src-sha256": "1sg5hbpdwj1xclqgw051rxxs3qpx3fgvw02ramlr0bgxhb3xgdi9" } diff --git a/test/cljs/status_im/test/pairing/core.cljs b/test/cljs/status_im/test/pairing/core.cljs deleted file mode 100644 index 60fca8a766..0000000000 --- a/test/cljs/status_im/test/pairing/core.cljs +++ /dev/null @@ -1,308 +0,0 @@ -(ns status-im.test.pairing.core - (:require [cljs.test :refer-macros [deftest is testing]] - [status-im.utils.gfycat.core :as gfycat] - [status-im.utils.identicon :as identicon] - [status-im.transport.message.pairing :as transport.pairing] - [status-im.utils.pairing :as pairing.utils] - [status-im.utils.config :as config] - [status-im.pairing.core :as pairing])) - -(deftest merge-contact-test - (testing "vanilla contacts" - (let [contact-1 {:system-tags #{:contact/added} - :this-should-be-kept true - :last-updated 1 - :name "name-v1" - :photo-path "photo-v1"} - contact-2 {:system-tags #{:contact/added} - :last-updated 2 - :name "name-v2" - :photo-path "photo-v2"} - expected {:system-tags #{:contact/added} - :this-should-be-kept true - :last-updated 2 - - :name "name-v2" - :photo-path "photo-v2"}] - (is (= expected (pairing/merge-contact contact-1 contact-2))))) - (testing "without last-updated" - (let [contact-1 {:system-tags #{:contact/added} - :name "name-v1" - :photo-path "photo-v1"} - contact-2 {:system-tags #{:contact/added} - :last-updated 2 - :name "name-v2" - :photo-path "photo-v2"} - expected {:system-tags #{:contact/added} - :last-updated 2 - - :name "name-v2" - :photo-path "photo-v2"}] - (is (= expected (pairing/merge-contact contact-1 contact-2))))) - (testing "nil contact" - (let [contact-1 nil - contact-2 {:system-tags #{:contact/added} - :last-updated 2 - :name "name-v2" - :photo-path "photo-v2"} - expected {:system-tags #{:contact/added} - :last-updated 2 - - :name "name-v2" - :photo-path "photo-v2"}] - (is (= expected (pairing/merge-contact contact-1 contact-2))))) - (testing "added in one device but updated less recently" - (let [contact-1 {:system-tags #{:contact/added} - :last-updated 1 - :name "name-v1" - :photo-path "photo-v1"} - contact-2 {:system-tags #{} - :last-updated 2 - :name "name-v2" - :photo-path "photo-v2"} - expected {:system-tags #{} - :last-updated 2 - - :name "name-v2" - :photo-path "photo-v2"}] - (is (= expected (pairing/merge-contact contact-1 contact-2))))) - (testing "added in one device updated more recently" - (let [contact-1 {:system-tags #{} - :last-updated 1 - :name "name-v1" - :photo-path "photo-v1"} - contact-2 {:system-tags #{:contact/added} - :last-updated 2 - :name "name-v2" - :photo-path "photo-v2"} - expected {:system-tags #{:contact/added} - :last-updated 2 - - :name "name-v2" - :photo-path "photo-v2"}] - (is (= expected (pairing/merge-contact contact-1 contact-2))))) - (testing "pending in one device and nil" - (let [contact-1 nil - contact-2 {:system-tags #{} - :last-updated 2 - :name "name-v2" - :photo-path "photo-v2"} - expected {:system-tags #{} - :last-updated 2 - - :name "name-v2" - :photo-path "photo-v2"}] - (is (= expected (pairing/merge-contact contact-1 contact-2)))))) - -(deftest handle-sync-installation-test - (with-redefs [gfycat/generate-gfy (constantly "generated") - identicon/identicon (constantly "generated")] - (testing "syncing contacts" - (let [old-contact-1 {:name "old-contact-one" - :public-key "contact-1" - :last-updated 0 - :photo-path "old-contact-1" - :system-tags #{}} - new-contact-1 {:name "new-contact-one" - :public-key "contact-1" - :last-updated 1 - :photo-path "new-contact-1" - :system-tags #{:contact/added}} - old-contact-2 {:name "old-contact-2" - :public-key "contact-2" - :last-updated 0 - :photo-path "old-contact-2" - :system-tags #{:contact/added}} - new-contact-2 {:name "new-contact-2" - :public-key "contact-2" - :last-updated 1 - :photo-path "new-contact-2" - :system-tags #{:contact/added}} - contact-3 {:name "contact-3" - :public-key "contact-3" - :photo-path "contact-3" - :system-tags #{:contact/added}} - contact-4 {:name "contact-4" - :public-key "contact-4" - :system-tags #{}} - local-contact-5 {:name "contact-5" - :photo-path "local" - :public-key "contact-5" - :system-tags #{} - :last-updated 1} - remote-contact-5 {:name "contact-5" - :public-key "contact-5" - :photo-path "remote" - :system-tags #{} - :last-updated 1} - cofx {:db {:multiaccount {:public-key "us"} - :contacts/contacts {"contact-1" old-contact-1 - "contact-2" new-contact-2 - "contact-3" contact-3 - "contact-5" local-contact-5}}} - sync-message {:contacts {"contact-1" new-contact-1 - "contact-2" old-contact-2 - "contact-4" contact-4 - "contact-5" remote-contact-5}} - expected {"contact-1" new-contact-1 - "contact-2" new-contact-2 - "contact-3" contact-3 - "contact-4" (assoc contact-4 - :photo-path "generated") - "contact-5" local-contact-5}] - (testing "not coming from us" - (is (not (:db (pairing/handle-sync-installation cofx sync-message "not-us"))))) - (testing "coming from us" - (is (= expected (get-in - (pairing/handle-sync-installation cofx sync-message "us") - [:db :contacts/contacts])))))) - (testing "syncing multiaccount" - (let [old-multiaccount {:name "old-name" - :public-key "us" - :photo-path "old-photo-path" - :last-updated 0} - new-multiaccount {:name "new-name" - :public-key "us" - :photo-path "new-photo-path" - :last-updated 1}] - (testing "newer update" - (let [cofx {:db {:multiaccount old-multiaccount}} - sync-message {:account new-multiaccount}] - (is (= new-multiaccount (get-in (pairing/handle-sync-installation cofx sync-message "us") - [:db :multiaccount]))))) - (testing "older update" - (let [cofx {:db {:multiaccount new-multiaccount}} - sync-message {:multiaccount old-multiaccount}] - (is (= new-multiaccount (get-in (pairing/handle-sync-installation cofx sync-message "us") - [:db :multiaccount]))))))) - (testing "syncing public chats" - (let [cofx {:db {:multiaccount {:public-key "us"}}}] - (testing "a new chat" - (let [sync-message {:chat {:public? true - :chat-id "status" - :is-active true}}] - (is (get-in (pairing/handle-sync-installation cofx sync-message "us") - [:db :chats "status"])))))))) - -(deftest handle-pair-installation-test - (let [cofx {:db {:multiaccount {:public-key "us"} - :pairing/installations {"1" {:has-bundle? true - :installation-id "1"} - "2" {:has-bundle? false - :installation-id "2"}}}} - pair-message {:device-type "ios" - :name "name" - :installation-id "1"}] - (testing "not coming from us" - (is (not (:db (pairing/handle-pair-installation cofx pair-message 1 "not-us"))))) - (testing "coming from us" - (is (= [["1" - {:name "name" - :deviceType "ios"}]] - (:pairing/set-installation-metadata - (pairing/handle-pair-installation cofx pair-message 1 "us"))))))) - -(deftest sync-installation-messages-test - (testing "it creates a sync installation message" - (let [cofx {:db {:multiaccount {:public-key "us" - :name "name" - :photo-path "photo-path" - :last-updated 1} - :chats {"status" {:public? true - :is-active true - :chat-id "status"}} - :contacts/contacts {"contact-1" {:name "contact-1" - :public-key "contact-1" - :system-tags #{:contact/added}} - "contact-2" {:name "contact-2" - :public-key "contact-2" - :system-tags #{:contact/added}} - "contact-3" {:name "contact-3" - :public-key "contact-3" - :system-tags #{:contact/added}} - "contact-4" {:name "contact-4" - :public-key "contact-4" - :system-tags #{:contact/added}} - "contact-5" {:name "contact-5" - :public-key "contact-5" - :system-tags #{:contact/added}} - "contact-6" {:name "contact-6" - :public-key "contact-6" - :system-tags #{:contact/blocked}}}}} - expected [(transport.pairing/SyncInstallation. {"contact-1" {:name "contact-1" - :public-key "contact-1" - :pending? false - :system-tags #{:contact/added}} - "contact-2" {:name "contact-2" - :pending? false - :public-key "contact-2" - :system-tags #{:contact/added}} - "contact-3" {:name "contact-3" - :pending? false - :public-key "contact-3" - :system-tags #{:contact/added}} - "contact-4" {:name "contact-4" - :pending? false - :public-key "contact-4" - :system-tags #{:contact/added}}} - {} {}) - (transport.pairing/SyncInstallation. {"contact-5" {:name "contact-5" - :public-key "contact-5" - :pending? false - :system-tags #{:contact/added}}} {} {}) - (transport.pairing/SyncInstallation. {} {:photo-path "photo-path" - :name "name" - :last-updated 1} {}) - (transport.pairing/SyncInstallation. {} {} {:public? true - :chat-id "status"})]] - (is (= expected (pairing/sync-installation-messages cofx)))))) - -(deftest handle-bundles-added-test - (let [installation-1 {:has-bundle? false - :installation-id "installation-1"} - cofx {:db {:multiaccount {:public-key "us"} - :pairing/installations {"installation-1" installation-1}}}] - (testing "new installations" - (let [new-installation {:identity "us" :installationID "installation-2"} - expected {"installation-1" installation-1 - "installation-2" {:has-bundle? true - :installation-id "installation-2"}}] - (is ((into #{} (keys (pairing/handle-bundles-added cofx new-installation))) - :pairing/get-our-installations)))) - (testing "not from us" - (let [new-installation {:identity "not-us" :installationID "does-not-matter"}] - (is (not (pairing/handle-bundles-added cofx new-installation))))))) - -(deftest has-paired-installations-test - (testing "no paired devices" - (is (not (pairing.utils/has-paired-installations? {:db {:multiaccount {:installation-id "1"} - :pairing/installations {"1" {:installation-id "1" - :enabled? true} - "2" {:installation-id "2"} - "3" {:installation-id "3"}}}})))) - (testing "has paired devices" - (is (pairing.utils/has-paired-installations? {:db {:pairing/installations {:multiaccount {:instllation-id "1"} - "1" {:installation-id "1" - :enabled? true} - "2" {:installation-id "2"} - "3" {:installation-id "3" - :enabled? true}}}})))) - -(deftest sort-installations - (let [id "0" - expected [{:installation-id id - :timestamp (rand-int 200) - :enabled? false} - {:installation-id "1" - :timestamp 3 - :enabled? true} - {:installation-id "2" - :timestamp 2 - :enabled? true} - {:installation-id "3" - :timestamp 10 - :enabled? false} - {:installation-id "4" - :timestamp 9 - :enabled? false}]] - (is (= expected (pairing/sort-installations id (shuffle expected)))))) diff --git a/test/cljs/status_im/test/runner.cljs b/test/cljs/status_im/test/runner.cljs index e6331520bf..a5a5eac254 100644 --- a/test/cljs/status_im/test/runner.cljs +++ b/test/cljs/status_im/test/runner.cljs @@ -31,7 +31,6 @@ [status-im.test.multiaccounts.recover.core] [status-im.test.multiaccounts.update.core] [status-im.test.network.core] - [status-im.test.pairing.core] [status-im.test.search.core] [status-im.test.sign-in.flow] [status-im.test.stickers.core] @@ -103,7 +102,6 @@ 'status-im.test.multiaccounts.recover.core 'status-im.test.multiaccounts.update.core 'status-im.test.network.core - 'status-im.test.pairing.core 'status-im.test.search.core 'status-im.test.sign-in.flow 'status-im.test.stickers.core diff --git a/test/cljs/status_im/test/transport/core.cljs b/test/cljs/status_im/test/transport/core.cljs index 477f197f99..f2d9a50584 100644 --- a/test/cljs/status_im/test/transport/core.cljs +++ b/test/cljs/status_im/test/transport/core.cljs @@ -1,7 +1,6 @@ (ns status-im.test.transport.core (:require [cljs.test :refer-macros [deftest is testing]] [status-im.utils.fx :as fx] - status-im.transport.impl.receive [status-im.protocol.core :as protocol] [status-im.transport.core :as transport] [status-im.transport.message.core :as message]))