Contact updates & pairing in status-go
Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
parent
b0727ff1a9
commit
b2fd81fc76
|
@ -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() {},
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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" {}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")})))))
|
||||
|
|
|
@ -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))})
|
||||
|
|
|
@ -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)))))
|
|
@ -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))))
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' 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"
|
||||
}
|
||||
|
|
|
@ -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))))))
|
|
@ -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
|
||||
|
|
|
@ -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]))
|
||||
|
|
Loading…
Reference in New Issue