Add pairing
Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
parent
ca8a3037d8
commit
073dddcee0
3
.env
3
.env
|
@ -8,7 +8,8 @@ POW_TARGET=0.002
|
||||||
POW_TIME=1
|
POW_TIME=1
|
||||||
DEFAULT_NETWORK=mainnet_rpc
|
DEFAULT_NETWORK=mainnet_rpc
|
||||||
DEBUG_WEBVIEW=1
|
DEBUG_WEBVIEW=1
|
||||||
GROUP_CHATS_ENABLED=1
|
GROUP_CHATS_ENABLED=0
|
||||||
|
PAIRING_ENABLED=0
|
||||||
CACHED_WEBVIEWS_ENABLED=1
|
CACHED_WEBVIEWS_ENABLED=1
|
||||||
EXTENSIONS=1
|
EXTENSIONS=1
|
||||||
HARDWALLET_ENABLED=0
|
HARDWALLET_ENABLED=0
|
||||||
|
|
|
@ -8,8 +8,9 @@ POW_TARGET=0.002
|
||||||
POW_TIME=1
|
POW_TIME=1
|
||||||
DEFAULT_NETWORK=mainnet_rpc
|
DEFAULT_NETWORK=mainnet_rpc
|
||||||
DEBUG_WEBVIEW=1
|
DEBUG_WEBVIEW=1
|
||||||
GROUP_CHATS_ENABLED=1
|
GROUP_CHATS_ENABLED=0
|
||||||
MAINNET_WARNING_ENABLED=1
|
MAINNET_WARNING_ENABLED=1
|
||||||
CACHED_WEBVIEWS_ENABLED=1
|
CACHED_WEBVIEWS_ENABLED=1
|
||||||
EXTENSIONS=1
|
EXTENSIONS=1
|
||||||
PFS_ENCRYPTION_ENABLED=0
|
PFS_ENCRYPTION_ENABLED=0
|
||||||
|
PAIRING_ENABLED=0
|
||||||
|
|
|
@ -9,6 +9,7 @@ POW_TIME=1
|
||||||
DEFAULT_NETWORK=mainnet_rpc
|
DEFAULT_NETWORK=mainnet_rpc
|
||||||
DEBUG_WEBVIEW=1
|
DEBUG_WEBVIEW=1
|
||||||
GROUP_CHATS_ENABLED=0
|
GROUP_CHATS_ENABLED=0
|
||||||
|
PAIRING_ENABLED=0
|
||||||
MAINNET_WARNING_ENABLED=1
|
MAINNET_WARNING_ENABLED=1
|
||||||
EXTENSIONS=1
|
EXTENSIONS=1
|
||||||
PFS_ENCRYPTION_ENABLED=0
|
PFS_ENCRYPTION_ENABLED=0
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
0.16.3
|
0.16.3-3-g37e4ef01
|
||||||
|
|
|
@ -14021,7 +14021,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"web3": {
|
"web3": {
|
||||||
"version": "git+https://github.com/status-im/web3.js.git#b1c2e2b75f6a190b320dda4be7931d3680ecb727",
|
"version": "git+https://github.com/status-im/web3.js.git#5fd0b24fd10ce55183a5253a370840540a07db1e",
|
||||||
"requires": {
|
"requires": {
|
||||||
"bignumber.js": "github:status-im/bignumber.js#cc066a0a3d6bfe0c436c9957f4ea8344bf963c89",
|
"bignumber.js": "github:status-im/bignumber.js#cc066a0a3d6bfe0c436c9957f4ea8344bf963c89",
|
||||||
"crypto-js": "3.1.8",
|
"crypto-js": "3.1.8",
|
||||||
|
|
|
@ -84,7 +84,7 @@
|
||||||
"string_decoder": "0.10.31",
|
"string_decoder": "0.10.31",
|
||||||
"text-encoding": "^0.6.4",
|
"text-encoding": "^0.6.4",
|
||||||
"url": "0.10.3",
|
"url": "0.10.3",
|
||||||
"web3": "https://github.com/status-im/web3.js.git#feature/chat-api",
|
"web3": "https://github.com/status-im/web3.js.git#features/pairing-message",
|
||||||
"web3-utils": "1.0.0-beta.36"
|
"web3-utils": "1.0.0-beta.36"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -10966,7 +10966,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"web3": {
|
"web3": {
|
||||||
"version": "git+https://github.com/status-im/web3.js.git#b1c2e2b75f6a190b320dda4be7931d3680ecb727",
|
"version": "git+https://github.com/status-im/web3.js.git#5fd0b24fd10ce55183a5253a370840540a07db1e",
|
||||||
"requires": {
|
"requires": {
|
||||||
"bignumber.js": "github:status-im/bignumber.js#cc066a0a3d6bfe0c436c9957f4ea8344bf963c89",
|
"bignumber.js": "github:status-im/bignumber.js#cc066a0a3d6bfe0c436c9957f4ea8344bf963c89",
|
||||||
"crypto-js": "3.1.8",
|
"crypto-js": "3.1.8",
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
"string_decoder": "0.10.31",
|
"string_decoder": "0.10.31",
|
||||||
"text-encoding": "^0.6.4",
|
"text-encoding": "^0.6.4",
|
||||||
"url": "0.10.3",
|
"url": "0.10.3",
|
||||||
"web3": "https://github.com/status-im/web3.js.git#feature/chat-api",
|
"web3": "https://github.com/status-im/web3.js.git#features/pairing-message",
|
||||||
"web3-utils": "1.0.0-beta.36"
|
"web3-utils": "1.0.0-beta.36"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im.chat.subs
|
(ns status-im.chat.subs
|
||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
[re-frame.core :refer [reg-sub subscribe]]
|
[re-frame.core :refer [reg-sub subscribe]]
|
||||||
|
[status-im.utils.config :as utils.config]
|
||||||
[status-im.chat.constants :as chat.constants]
|
[status-im.chat.constants :as chat.constants]
|
||||||
[status-im.chat.commands.core :as commands]
|
[status-im.chat.commands.core :as commands]
|
||||||
[status-im.chat.commands.input :as commands.input]
|
[status-im.chat.commands.input :as commands.input]
|
||||||
|
@ -76,9 +77,13 @@
|
||||||
platform/ios? kb-height
|
platform/ios? kb-height
|
||||||
:default 0)))
|
:default 0)))
|
||||||
|
|
||||||
(defn active-chats [[contacts chats]]
|
(defn active-chats [[contacts chats {:keys [dev-mode?]}]]
|
||||||
(reduce (fn [acc [chat-id {:keys [is-active] :as chat}]]
|
(reduce (fn [acc [chat-id {:keys [group-chat public? is-active] :as chat}]]
|
||||||
(if is-active
|
(if (and is-active
|
||||||
|
;; not a group chat
|
||||||
|
(or (not (and group-chat (not public?)))
|
||||||
|
;; if it's a group chat
|
||||||
|
(utils.config/group-chats-enabled? dev-mode?)))
|
||||||
(assoc acc chat-id (if-let [contact (get contacts chat-id)]
|
(assoc acc chat-id (if-let [contact (get contacts chat-id)]
|
||||||
(-> chat
|
(-> chat
|
||||||
(assoc :name (:name contact))
|
(assoc :name (:name contact))
|
||||||
|
@ -93,6 +98,7 @@
|
||||||
:get-active-chats
|
:get-active-chats
|
||||||
:<- [:get-contacts]
|
:<- [:get-contacts]
|
||||||
:<- [:get-chats]
|
:<- [:get-chats]
|
||||||
|
:<- [:get-current-account]
|
||||||
active-chats)
|
active-chats)
|
||||||
|
|
||||||
(reg-sub
|
(reg-sub
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
status-im.data-store.chats
|
status-im.data-store.chats
|
||||||
status-im.data-store.messages
|
status-im.data-store.messages
|
||||||
status-im.data-store.contacts
|
status-im.data-store.contacts
|
||||||
|
status-im.data-store.installations
|
||||||
status-im.data-store.transport
|
status-im.data-store.transport
|
||||||
status-im.data-store.browser
|
status-im.data-store.browser
|
||||||
status-im.data-store.accounts
|
status-im.data-store.accounts
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
(ns status-im.data-store.installations
|
||||||
|
(:require [re-frame.core :as re-frame]
|
||||||
|
[status-im.data-store.realm.core :as core]))
|
||||||
|
|
||||||
|
(re-frame/reg-cofx
|
||||||
|
:data-store/get-all-installations
|
||||||
|
(fn [coeffects _]
|
||||||
|
(assoc coeffects :all-installations (-> @core/account-realm
|
||||||
|
(core/get-all :installation)
|
||||||
|
(core/all-clj :installation)))))
|
||||||
|
|
||||||
|
(defn save
|
||||||
|
"Returns tx function for saving a installation"
|
||||||
|
[installation]
|
||||||
|
(fn [realm]
|
||||||
|
(core/create realm
|
||||||
|
:installation
|
||||||
|
installation
|
||||||
|
true)))
|
||||||
|
|
||||||
|
(defn confirm
|
||||||
|
[installation-id]
|
||||||
|
(save {:installation-id installation-id
|
||||||
|
:confirmed? true}))
|
|
@ -11,6 +11,7 @@
|
||||||
[status-im.data-store.realm.schemas.account.dapp-permissions :as dapp-permissions]
|
[status-im.data-store.realm.schemas.account.dapp-permissions :as dapp-permissions]
|
||||||
[status-im.data-store.realm.schemas.account.request :as request]
|
[status-im.data-store.realm.schemas.account.request :as request]
|
||||||
[status-im.data-store.realm.schemas.account.membership-update :as membership-update]
|
[status-im.data-store.realm.schemas.account.membership-update :as membership-update]
|
||||||
|
[status-im.data-store.realm.schemas.account.installation :as installation]
|
||||||
[status-im.data-store.realm.schemas.account.migrations :as migrations]
|
[status-im.data-store.realm.schemas.account.migrations :as migrations]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
|
@ -183,6 +184,19 @@
|
||||||
|
|
||||||
(def v18 v17)
|
(def v18 v17)
|
||||||
|
|
||||||
|
(def v19 [chat/v8
|
||||||
|
transport/v7
|
||||||
|
transport-inbox-topic/v1
|
||||||
|
contact/v2
|
||||||
|
message/v7
|
||||||
|
mailserver/v11
|
||||||
|
user-status/v1
|
||||||
|
membership-update/v1
|
||||||
|
installation/v1
|
||||||
|
local-storage/v1
|
||||||
|
browser/v8
|
||||||
|
dapp-permissions/v9])
|
||||||
|
|
||||||
;; put schemas ordered by version
|
;; put schemas ordered by version
|
||||||
(def schemas [{:schema v1
|
(def schemas [{:schema v1
|
||||||
:schemaVersion 1
|
:schemaVersion 1
|
||||||
|
@ -237,4 +251,7 @@
|
||||||
:migration migrations/v17}
|
:migration migrations/v17}
|
||||||
{:schema v18
|
{:schema v18
|
||||||
:schemaVersion 18
|
:schemaVersion 18
|
||||||
:migration migrations/v18}])
|
:migration migrations/v18}
|
||||||
|
{:schema v19
|
||||||
|
:schemaVersion 19
|
||||||
|
:migration migrations/v19}])
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
(ns status-im.data-store.realm.schemas.account.installation)
|
||||||
|
|
||||||
|
(def v1 {:name :installation
|
||||||
|
:primaryKey :installation-id
|
||||||
|
:properties {:installation-id :string
|
||||||
|
:confirmed? :bool}})
|
|
@ -113,3 +113,6 @@
|
||||||
(.objects "transport-inbox-topic")
|
(.objects "transport-inbox-topic")
|
||||||
(.map (fn [inbox-topic _ _]
|
(.map (fn [inbox-topic _ _]
|
||||||
(aset inbox-topic "last-request" 1)))))
|
(aset inbox-topic "last-request" 1)))))
|
||||||
|
|
||||||
|
(defn v19 [old-realm new-realm]
|
||||||
|
(log/debug "migrating v19 account database"))
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
[status-im.mailserver.core :as mailserver]
|
[status-im.mailserver.core :as mailserver]
|
||||||
[status-im.network.core :as network]
|
[status-im.network.core :as network]
|
||||||
[status-im.notifications.core :as notifications]
|
[status-im.notifications.core :as notifications]
|
||||||
|
[status-im.pairing.core :as pairing]
|
||||||
[status-im.privacy-policy.core :as privacy-policy]
|
[status-im.privacy-policy.core :as privacy-policy]
|
||||||
[status-im.protocol.core :as protocol]
|
[status-im.protocol.core :as protocol]
|
||||||
[status-im.qr-scanner.core :as qr-scanner]
|
[status-im.qr-scanner.core :as qr-scanner]
|
||||||
|
@ -95,6 +96,7 @@
|
||||||
(re-frame/inject-cofx :data-store/deduplication-ids)
|
(re-frame/inject-cofx :data-store/deduplication-ids)
|
||||||
(re-frame/inject-cofx :data-store/get-local-storage-data)
|
(re-frame/inject-cofx :data-store/get-local-storage-data)
|
||||||
(re-frame/inject-cofx :data-store/get-all-contacts)
|
(re-frame/inject-cofx :data-store/get-all-contacts)
|
||||||
|
(re-frame/inject-cofx :data-store/get-all-installations)
|
||||||
(re-frame/inject-cofx :data-store/get-all-mailservers)
|
(re-frame/inject-cofx :data-store/get-all-mailservers)
|
||||||
(re-frame/inject-cofx :data-store/transport)
|
(re-frame/inject-cofx :data-store/transport)
|
||||||
(re-frame/inject-cofx :data-store/transport-inbox-topics)
|
(re-frame/inject-cofx :data-store/transport-inbox-topics)
|
||||||
|
@ -1092,3 +1094,17 @@
|
||||||
:search/filter-changed
|
:search/filter-changed
|
||||||
(fn [cofx [_ search-filter]]
|
(fn [cofx [_ search-filter]]
|
||||||
(search/filter-changed cofx search-filter)))
|
(search/filter-changed cofx search-filter)))
|
||||||
|
|
||||||
|
;; pairing module
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:pairing.ui/pair-devices-pressed
|
||||||
|
[]
|
||||||
|
(fn [cofx _]
|
||||||
|
(pairing/start cofx)))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:pairing.ui/synchronize-installation-pressed
|
||||||
|
[]
|
||||||
|
(fn [cofx _]
|
||||||
|
(pairing/send-installation-message cofx)))
|
||||||
|
|
|
@ -304,16 +304,17 @@
|
||||||
message
|
message
|
||||||
membership-updates] :as membership-update}
|
membership-updates] :as membership-update}
|
||||||
sender-signature]
|
sender-signature]
|
||||||
(when (and config/group-chats-enabled?
|
(let [dev-mode? (get-in cofx [:db :account/account :dev-mode?])]
|
||||||
(valid-chat-id? chat-id (-> membership-updates first :from)))
|
(when (and (config/group-chats-enabled? dev-mode?)
|
||||||
(let [previous-chat (get-in cofx [:db :chats chat-id])]
|
(valid-chat-id? chat-id (-> membership-updates first :from)))
|
||||||
(fx/merge cofx
|
(let [previous-chat (get-in cofx [:db :chats chat-id])]
|
||||||
(update-membership previous-chat membership-update)
|
(fx/merge cofx
|
||||||
#(when (and message
|
(update-membership previous-chat membership-update)
|
||||||
;; don't allow anything but group messages
|
#(when (and message
|
||||||
(instance? protocol/Message message)
|
;; don't allow anything but group messages
|
||||||
(= :group-user-message (:message-type message)))
|
(instance? protocol/Message message)
|
||||||
(protocol/receive message chat-id sender-signature nil %))))))
|
(= :group-user-message (:message-type message)))
|
||||||
|
(protocol/receive message chat-id sender-signature nil %)))))))
|
||||||
|
|
||||||
(defn handle-sign-success
|
(defn handle-sign-success
|
||||||
"Upsert chat and send signed payload to group members"
|
"Upsert chat and send signed payload to group members"
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
[status-im.contact.core :as contact]
|
[status-im.contact.core :as contact]
|
||||||
[status-im.models.dev-server :as models.dev-server]
|
[status-im.models.dev-server :as models.dev-server]
|
||||||
[status-im.protocol.core :as protocol]
|
[status-im.protocol.core :as protocol]
|
||||||
|
[status-im.pairing.core :as pairing]
|
||||||
[status-im.models.transactions :as transactions]
|
[status-im.models.transactions :as transactions]
|
||||||
[status-im.models.wallet :as models.wallet]
|
[status-im.models.wallet :as models.wallet]
|
||||||
[status-im.native-module.core :as status]
|
[status-im.native-module.core :as status]
|
||||||
|
@ -149,7 +150,7 @@
|
||||||
(let [{:universal-links/keys [url]
|
(let [{:universal-links/keys [url]
|
||||||
:keys [accounts/accounts accounts/create contacts/contacts networks/networks
|
:keys [accounts/accounts accounts/create contacts/contacts networks/networks
|
||||||
network network-status peers-count peers-summary view-id navigation-stack
|
network network-status peers-count peers-summary view-id navigation-stack
|
||||||
status-module-initialized? device-UUID semaphores]
|
pairing/installations status-module-initialized? device-UUID semaphores]
|
||||||
:node/keys [status]
|
:node/keys [status]
|
||||||
:or {network (get app-db :network)}} db
|
:or {network (get app-db :network)}} db
|
||||||
current-account (get accounts address)
|
current-account (get accounts address)
|
||||||
|
@ -206,6 +207,7 @@
|
||||||
(initialize-account-db address)
|
(initialize-account-db address)
|
||||||
(protocol/initialize-protocol address)
|
(protocol/initialize-protocol address)
|
||||||
(contact/load-contacts)
|
(contact/load-contacts)
|
||||||
|
(pairing/load-installations)
|
||||||
#(when (dev-mode? %)
|
#(when (dev-mode? %)
|
||||||
(models.dev-server/start))
|
(models.dev-server/start))
|
||||||
(chat-loading/initialize-chats)
|
(chat-loading/initialize-chats)
|
||||||
|
|
|
@ -100,7 +100,11 @@
|
||||||
:RequireTopics (get-topics network)
|
:RequireTopics (get-topics network)
|
||||||
:InstallationID installation-id
|
:InstallationID installation-id
|
||||||
:PFSEnabled (or config/pfs-encryption-enabled?
|
:PFSEnabled (or config/pfs-encryption-enabled?
|
||||||
config/group-chats-enabled?))
|
;; We don't check dev-mode? here as
|
||||||
|
;; otherwise we would have to restart the node
|
||||||
|
;; when the user enables it
|
||||||
|
(config/group-chats-enabled? true)
|
||||||
|
(config/pairing-enabled? true)))
|
||||||
|
|
||||||
(and
|
(and
|
||||||
config/bootnodes-settings-enabled?
|
config/bootnodes-settings-enabled?
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
(ns status-im.pairing.core
|
||||||
|
(:require
|
||||||
|
[status-im.utils.fx :as fx]
|
||||||
|
[status-im.utils.config :as config]
|
||||||
|
[status-im.transport.message.protocol :as protocol]
|
||||||
|
[status-im.data-store.installations :as data-store.installations]
|
||||||
|
[status-im.utils.identicon :as identicon]
|
||||||
|
[status-im.data-store.contacts :as data-store.contacts]
|
||||||
|
[status-im.transport.message.pairing :as transport.pairing]))
|
||||||
|
|
||||||
|
(defn start [cofx]
|
||||||
|
(let [{:keys [current-public-key web3]} (:db cofx)]
|
||||||
|
{:shh/send-pairing-message {:web3 web3
|
||||||
|
:src current-public-key
|
||||||
|
:payload []}}))
|
||||||
|
|
||||||
|
(defn merge-contact [local remote]
|
||||||
|
(let [[old-contact new-contact] (sort-by :last-updated [local remote])]
|
||||||
|
(-> local
|
||||||
|
(merge new-contact)
|
||||||
|
(assoc :photo-path
|
||||||
|
(or (:photo-path new-contact)
|
||||||
|
(:photo-path old-contact)
|
||||||
|
(identicon/identicon (:whisper-identity local))))
|
||||||
|
(assoc :pending? (boolean
|
||||||
|
(and (:pending? local true)
|
||||||
|
(:pending? remote true)))))))
|
||||||
|
|
||||||
|
(def merge-contacts (partial merge-with merge-contact))
|
||||||
|
|
||||||
|
(defn handle-bundles-added [{:keys [db]} bundle]
|
||||||
|
(let [dev-mode? (get-in db [:account/account :dev-mode?])]
|
||||||
|
(when (config/pairing-enabled? dev-mode?)
|
||||||
|
(let [installation-id (:installationID bundle)
|
||||||
|
new-installation {:installation-id installation-id
|
||||||
|
:confirmed? false}]
|
||||||
|
(when
|
||||||
|
(and (= (:identity bundle)
|
||||||
|
(:current-public-key db))
|
||||||
|
(not (get-in db [:pairing/installations installation-id])))
|
||||||
|
{:db (assoc-in db
|
||||||
|
[:pairing/installations installation-id]
|
||||||
|
new-installation)
|
||||||
|
:data-store/tx [(data-store.installations/save new-installation)]})))))
|
||||||
|
|
||||||
|
(defn sync-installation-messages [{:keys [db]}]
|
||||||
|
(let [contacts (:contacts/contacts db)]
|
||||||
|
(map
|
||||||
|
(fn [[k v]] (transport.pairing/SyncInstallation. {k (dissoc v :photo-path)}))
|
||||||
|
contacts)))
|
||||||
|
|
||||||
|
(defn send-installation-message [cofx]
|
||||||
|
;; The message needs to be broken up in chunks as we hit the whisper size limit
|
||||||
|
(let [{:keys [current-public-key web3]} (:db cofx)
|
||||||
|
sync-messages (sync-installation-messages cofx)]
|
||||||
|
{:shh/send-direct-message
|
||||||
|
(map #(hash-map :web3 web3
|
||||||
|
:src current-public-key
|
||||||
|
:dst current-public-key
|
||||||
|
:payload %) sync-messages)}))
|
||||||
|
|
||||||
|
(defn handle-sync-installation [{:keys [db] :as cofx} {:keys [contacts]} sender]
|
||||||
|
(let [dev-mode? (get-in db [:account/account :dev-mode?])]
|
||||||
|
(when (and (config/pairing-enabled? dev-mode?)
|
||||||
|
(= sender (get-in cofx [:db :current-public-key])))
|
||||||
|
(let [new-contacts (merge-contacts (:contacts/contacts db) contacts)]
|
||||||
|
{:db (assoc db :contacts/contacts new-contacts)
|
||||||
|
:data-store/tx [(data-store.contacts/save-contacts-tx (vals new-contacts))]}))))
|
||||||
|
|
||||||
|
(fx/defn load-installations [{:keys [db all-installations]}]
|
||||||
|
{:db (assoc db :pairing/installations (reduce
|
||||||
|
(fn [acc {:keys [installation-id] :as i}]
|
||||||
|
(assoc acc installation-id i))
|
||||||
|
{}
|
||||||
|
all-installations))})
|
|
@ -3,6 +3,7 @@
|
||||||
[status-im.accounts.login.core :as accounts.login]
|
[status-im.accounts.login.core :as accounts.login]
|
||||||
[status-im.init.core :as init]
|
[status-im.init.core :as init]
|
||||||
[status-im.node.core :as node]
|
[status-im.node.core :as node]
|
||||||
|
[status-im.pairing.core :as pairing]
|
||||||
[status-im.transport.inbox :as inbox]
|
[status-im.transport.inbox :as inbox]
|
||||||
[status-im.transport.message.core :as transport.message]
|
[status-im.transport.message.core :as transport.message]
|
||||||
[status-im.utils.fx :as fx]
|
[status-im.utils.fx :as fx]
|
||||||
|
@ -55,6 +56,7 @@
|
||||||
"module.initialized" (status-module-initialized cofx)
|
"module.initialized" (status-module-initialized cofx)
|
||||||
"envelope.sent" (transport.message/update-envelope-status cofx (:hash event) :sent)
|
"envelope.sent" (transport.message/update-envelope-status cofx (:hash event) :sent)
|
||||||
"envelope.expired" (transport.message/update-envelope-status cofx (:hash event) :sent)
|
"envelope.expired" (transport.message/update-envelope-status cofx (:hash event) :sent)
|
||||||
|
"bundles.added" (pairing/handle-bundles-added cofx event)
|
||||||
"mailserver.request.completed" (when (accounts.db/logged-in? cofx)
|
"mailserver.request.completed" (when (accounts.db/logged-in? cofx)
|
||||||
(inbox/update-inbox-topics cofx {:request-id (:requestID event)
|
(inbox/update-inbox-topics cofx {:request-id (:requestID event)
|
||||||
:cursor (:cursor event)}))
|
:cursor (:cursor event)}))
|
||||||
|
|
|
@ -104,6 +104,7 @@
|
||||||
(spec/def :message/message-seen (spec/keys :req-un [:message/ids]))
|
(spec/def :message/message-seen (spec/keys :req-un [:message/ids]))
|
||||||
|
|
||||||
(spec/def :message/group-membership-update (spec/keys :req-un [:group-chat/membership-updates :group-chat/chat-id]))
|
(spec/def :message/group-membership-update (spec/keys :req-un [:group-chat/membership-updates :group-chat/chat-id]))
|
||||||
|
(spec/def :message/sync-installation (spec/keys :req-un [:contacts/contacts]))
|
||||||
|
|
||||||
(spec/def :message/message-common (spec/keys :req-un [::content-type ::message-type ::clock-value ::timestamp]))
|
(spec/def :message/message-common (spec/keys :req-un [::content-type ::message-type ::clock-value ::timestamp]))
|
||||||
(spec/def :message.text/content (spec/keys :req-un [:message.content/text]
|
(spec/def :message.text/content (spec/keys :req-un [:message.content/text]
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
(ns status-im.transport.impl.receive
|
(ns status-im.transport.impl.receive
|
||||||
(:require [status-im.group-chats.core :as group-chats]
|
(:require [status-im.group-chats.core :as group-chats]
|
||||||
[status-im.contact.core :as contact]
|
[status-im.contact.core :as contact]
|
||||||
|
[status-im.pairing.core :as pairing]
|
||||||
[status-im.transport.message.contact :as transport.contact]
|
[status-im.transport.message.contact :as transport.contact]
|
||||||
[status-im.transport.message.group-chat :as transport.group-chat]
|
[status-im.transport.message.group-chat :as transport.group-chat]
|
||||||
|
[status-im.transport.message.pairing :as transport.pairing]
|
||||||
[status-im.transport.message.protocol :as protocol]))
|
[status-im.transport.message.protocol :as protocol]))
|
||||||
|
|
||||||
(extend-type transport.group-chat/GroupMembershipUpdate
|
(extend-type transport.group-chat/GroupMembershipUpdate
|
||||||
|
@ -24,3 +26,8 @@
|
||||||
protocol/StatusMessage
|
protocol/StatusMessage
|
||||||
(receive [this _ signature timestamp cofx]
|
(receive [this _ signature timestamp cofx]
|
||||||
(contact/receive-contact-update signature timestamp this cofx)))
|
(contact/receive-contact-update signature timestamp this cofx)))
|
||||||
|
|
||||||
|
(extend-type transport.pairing/SyncInstallation
|
||||||
|
protocol/StatusMessage
|
||||||
|
(receive [this _ signature _ cofx]
|
||||||
|
(pairing/handle-sync-installation cofx this signature)))
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
(ns status-im.transport.impl.send
|
(ns status-im.transport.impl.send
|
||||||
(:require [status-im.group-chats.core :as group-chats]
|
(:require [status-im.group-chats.core :as group-chats]
|
||||||
|
[status-im.pairing.core :as pairing]
|
||||||
|
[status-im.transport.message.pairing :as transport.pairing]
|
||||||
[status-im.transport.message.group-chat :as transport.group-chat]
|
[status-im.transport.message.group-chat :as transport.group-chat]
|
||||||
[status-im.transport.message.protocol :as protocol]))
|
[status-im.transport.message.protocol :as protocol]))
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
(ns status-im.transport.message.pairing
|
||||||
|
(:require [cljs.spec.alpha :as spec]
|
||||||
|
[status-im.transport.message.protocol :as protocol]
|
||||||
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
|
(defrecord SyncInstallation
|
||||||
|
[contacts]
|
||||||
|
protocol/StatusMessage
|
||||||
|
(validate [this]
|
||||||
|
(if (spec/valid? :message/sync-installation this)
|
||||||
|
this
|
||||||
|
(log/warn "failed sync installation validation" (spec/explain :message/sync-installation this)))))
|
|
@ -3,6 +3,7 @@
|
||||||
(:require [status-im.transport.message.contact :as contact]
|
(:require [status-im.transport.message.contact :as contact]
|
||||||
[status-im.transport.message.protocol :as protocol]
|
[status-im.transport.message.protocol :as protocol]
|
||||||
[status-im.transport.message.group-chat :as group-chat]
|
[status-im.transport.message.group-chat :as group-chat]
|
||||||
|
[status-im.transport.message.pairing :as pairing]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[cognitect.transit :as transit]))
|
[cognitect.transit :as transit]))
|
||||||
|
|
||||||
|
@ -87,6 +88,12 @@
|
||||||
(rep [this {:keys [chat-id membership-updates message]}]
|
(rep [this {:keys [chat-id membership-updates message]}]
|
||||||
#js [chat-id membership-updates message]))
|
#js [chat-id membership-updates message]))
|
||||||
|
|
||||||
|
(deftype SyncInstallationHandler []
|
||||||
|
Object
|
||||||
|
(tag [this v] "p1")
|
||||||
|
(rep [this {:keys [contacts]}]
|
||||||
|
#js [contacts]))
|
||||||
|
|
||||||
(def writer (transit/writer :json
|
(def writer (transit/writer :json
|
||||||
{:handlers
|
{:handlers
|
||||||
{contact/NewContactKey (NewContactKeyHandler.)
|
{contact/NewContactKey (NewContactKeyHandler.)
|
||||||
|
@ -95,7 +102,8 @@
|
||||||
contact/ContactUpdate (ContactUpdateHandler.)
|
contact/ContactUpdate (ContactUpdateHandler.)
|
||||||
protocol/Message (MessageHandler.)
|
protocol/Message (MessageHandler.)
|
||||||
protocol/MessagesSeen (MessagesSeenHandler.)
|
protocol/MessagesSeen (MessagesSeenHandler.)
|
||||||
group-chat/GroupMembershipUpdate (GroupMembershipUpdateHandler.)}}))
|
group-chat/GroupMembershipUpdate (GroupMembershipUpdateHandler.)
|
||||||
|
pairing/SyncInstallation (SyncInstallationHandler.)}}))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Reader handlers
|
;; Reader handlers
|
||||||
|
@ -146,7 +154,9 @@
|
||||||
"c6" (fn [[name profile-image address fcm-token]]
|
"c6" (fn [[name profile-image address fcm-token]]
|
||||||
(contact/ContactUpdate. name profile-image address fcm-token))
|
(contact/ContactUpdate. name profile-image address fcm-token))
|
||||||
"g5" (fn [[chat-id membership-updates message]]
|
"g5" (fn [[chat-id membership-updates message]]
|
||||||
(group-chat/GroupMembershipUpdate. chat-id membership-updates message))}}))
|
(group-chat/GroupMembershipUpdate. chat-id membership-updates message))
|
||||||
|
"p1" (fn [[contacts]]
|
||||||
|
(pairing/SyncInstallation. contacts))}}))
|
||||||
|
|
||||||
(defn serialize
|
(defn serialize
|
||||||
"Serializes a record implementing the StatusMessage protocol using the custom writers"
|
"Serializes a record implementing the StatusMessage protocol using the custom writers"
|
||||||
|
|
|
@ -82,6 +82,21 @@
|
||||||
direct-message
|
direct-message
|
||||||
(handle-response success-event error-event)))))))
|
(handle-response success-event error-event)))))))
|
||||||
|
|
||||||
|
(re-frame/reg-fx
|
||||||
|
:shh/send-pairing-message
|
||||||
|
(fn [params]
|
||||||
|
(let [{:keys [web3 payload src dsts success-event error-event]
|
||||||
|
:or {error-event :protocol/send-status-message-error}} params
|
||||||
|
message (clj->js {:sig src
|
||||||
|
:payload (-> payload
|
||||||
|
transit/serialize
|
||||||
|
transport.utils/from-utf8)})]
|
||||||
|
(.. web3
|
||||||
|
-shh
|
||||||
|
(sendPairingMessage
|
||||||
|
message
|
||||||
|
(handle-response success-event error-event))))))
|
||||||
|
|
||||||
(re-frame/reg-fx
|
(re-frame/reg-fx
|
||||||
:shh/send-group-message
|
:shh/send-group-message
|
||||||
(fn [params]
|
(fn [params]
|
||||||
|
|
|
@ -51,4 +51,4 @@
|
||||||
(def text black)
|
(def text black)
|
||||||
(def text-gray gray)
|
(def text-gray gray)
|
||||||
|
|
||||||
(def default-chat-color "#a187d5") ;; legacy
|
(def default-chat-color "#a187d5") ;; legacy
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
[status-im.ui.components.toolbar.view :as toolbar]
|
[status-im.ui.components.toolbar.view :as toolbar]
|
||||||
[status-im.utils.config :as config]))
|
[status-im.utils.config :as config]))
|
||||||
|
|
||||||
(defn- options-list [{:keys [anon-id]}]
|
(defn- options-list [{:keys [dev-mode?]}]
|
||||||
[react/view action-button.styles/actions-list
|
[react/view action-button.styles/actions-list
|
||||||
[action-button/action-button
|
[action-button/action-button
|
||||||
{:label (i18n/label :t/start-new-chat)
|
{:label (i18n/label :t/start-new-chat)
|
||||||
|
@ -23,14 +23,14 @@
|
||||||
:on-press #(re-frame/dispatch [:navigate-to :new-chat])}]
|
:on-press #(re-frame/dispatch [:navigate-to :new-chat])}]
|
||||||
[action-button/action-separator]
|
[action-button/action-separator]
|
||||||
;; Hide behind flag (false by default), till everything is fixed in group chats
|
;; Hide behind flag (false by default), till everything is fixed in group chats
|
||||||
(when config/group-chats-enabled?
|
(when (config/group-chats-enabled? dev-mode?)
|
||||||
[action-button/action-button
|
[action-button/action-button
|
||||||
{:label (i18n/label :t/start-group-chat)
|
{:label (i18n/label :t/start-group-chat)
|
||||||
:accessibility-label :start-group-chat-button
|
:accessibility-label :start-group-chat-button
|
||||||
:icon :icons/contacts
|
:icon :icons/contacts
|
||||||
:icon-opts {:color colors/blue}
|
:icon-opts {:color colors/blue}
|
||||||
:on-press #(re-frame/dispatch [:contact.ui/start-group-chat-pressed])}])
|
:on-press #(re-frame/dispatch [:contact.ui/start-group-chat-pressed])}])
|
||||||
(when config/group-chats-enabled?
|
(when (config/group-chats-enabled? dev-mode?)
|
||||||
[action-button/action-separator])
|
[action-button/action-separator])
|
||||||
[action-button/action-button
|
[action-button/action-button
|
||||||
{:label (i18n/label :t/new-public-group-chat)
|
{:label (i18n/label :t/new-public-group-chat)
|
||||||
|
@ -69,4 +69,4 @@
|
||||||
[status-bar/status-bar]
|
[status-bar/status-bar]
|
||||||
[toolbar/simple-toolbar (i18n/label :t/new)]
|
[toolbar/simple-toolbar (i18n/label :t/new)]
|
||||||
[common/separator]
|
[common/separator]
|
||||||
[options-list (assoc account :anon-id device-UUID)]]))
|
[options-list account]]))
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
:tab-bar-visible? true
|
:tab-bar-visible? true
|
||||||
:navigation-stack '()
|
:navigation-stack '()
|
||||||
:contacts/contacts {}
|
:contacts/contacts {}
|
||||||
|
:pairing/installations {}
|
||||||
:qr-codes {}
|
:qr-codes {}
|
||||||
:group/selected-contacts #{}
|
:group/selected-contacts #{}
|
||||||
:chats {}
|
:chats {}
|
||||||
|
@ -198,6 +199,7 @@
|
||||||
:contacts/click-handler
|
:contacts/click-handler
|
||||||
:contacts/click-action
|
:contacts/click-action
|
||||||
:contacts/click-params
|
:contacts/click-params
|
||||||
|
:pairing/installations
|
||||||
:commands/stored-command
|
:commands/stored-command
|
||||||
:group/selected-contacts
|
:group/selected-contacts
|
||||||
:accounts/accounts
|
:accounts/accounts
|
||||||
|
|
|
@ -92,7 +92,7 @@
|
||||||
[react/image {:style styles/suggested-contact-image
|
[react/image {:style styles/suggested-contact-image
|
||||||
:source {:uri (:photo-path c)}}]
|
:source {:uri (:photo-path c)}}]
|
||||||
[react/text {:style styles/new-contact-subtitle} (:name c)]]]))]]
|
[react/text {:style styles/new-contact-subtitle} (:name c)]]]))]]
|
||||||
(when config/group-chats-enabled? group-chat-section)
|
(when (config/group-chats-enabled? true) group-chat-section)
|
||||||
^{:key "publicchat"}
|
^{:key "publicchat"}
|
||||||
[react/view {:style styles/new-contact-title}
|
[react/view {:style styles/new-contact-title}
|
||||||
[react/text {:style styles/new-contact-title-text
|
[react/text {:style styles/new-contact-title-text
|
||||||
|
|
|
@ -172,3 +172,6 @@
|
||||||
:margin-top 36
|
:margin-top 36
|
||||||
:margin-bottom 16
|
:margin-bottom 16
|
||||||
:font-size 16})
|
:font-size 16})
|
||||||
|
|
||||||
|
(def pair-button
|
||||||
|
{:margin-left 32})
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.utils.build :as build]
|
[status-im.utils.build :as build]
|
||||||
|
[status-im.utils.config :as config]
|
||||||
[status-im.utils.utils :as utils]
|
[status-im.utils.utils :as utils]
|
||||||
[status-im.ui.components.colors :as colors]
|
[status-im.ui.components.colors :as colors]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
|
@ -11,6 +12,7 @@
|
||||||
[status-im.utils.gfycat.core :as gfy]
|
[status-im.utils.gfycat.core :as gfy]
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[status-im.ui.screens.offline-messaging-settings.views :as offline-messaging.views]
|
[status-im.ui.screens.offline-messaging-settings.views :as offline-messaging.views]
|
||||||
|
[status-im.ui.screens.pairing.views :as pairing.views]
|
||||||
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
|
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
|
||||||
[status-im.ui.screens.desktop.main.tabs.profile.styles :as styles]
|
[status-im.ui.screens.desktop.main.tabs.profile.styles :as styles]
|
||||||
[status-im.ui.screens.profile.user.views :as profile]
|
[status-im.ui.screens.profile.user.views :as profile]
|
||||||
|
@ -74,11 +76,24 @@
|
||||||
[react/text {:style styles/qr-code-copy-text}
|
[react/text {:style styles/qr-code-copy-text}
|
||||||
(i18n/label :copy-qr)]]]]]))
|
(i18n/label :copy-qr)]]]]]))
|
||||||
|
|
||||||
|
(defn installations-section [installations]
|
||||||
|
[react/view
|
||||||
|
[react/view {:style styles/title-separator}]
|
||||||
|
[react/text {:style styles/mailserver-title} (i18n/label :devices)]
|
||||||
|
[react/touchable-highlight {:style styles/pair-button
|
||||||
|
:on-press pairing.views/pair!}
|
||||||
|
[react/text (i18n/label :pair)]]
|
||||||
|
(for [installation installations]
|
||||||
|
^{:key (:installation-id installation)}
|
||||||
|
[react/view {:style {:margin-vertical 8}}
|
||||||
|
[pairing.views/render-row installation]])])
|
||||||
|
|
||||||
(views/defview advanced-settings []
|
(views/defview advanced-settings []
|
||||||
(views/letsubs [current-wnode-id [:settings/current-wnode]
|
(views/letsubs [current-wnode-id [:settings/current-wnode]
|
||||||
|
installations [:pairing/installations]
|
||||||
wnodes [:settings/fleet-wnodes]]
|
wnodes [:settings/fleet-wnodes]]
|
||||||
(let [render-fn (offline-messaging.views/render-row current-wnode-id)]
|
(let [render-fn (offline-messaging.views/render-row current-wnode-id)]
|
||||||
[react/view
|
[react/scroll-view
|
||||||
[react/text {:style styles/advanced-settings-title
|
[react/text {:style styles/advanced-settings-title
|
||||||
:font :medium}
|
:font :medium}
|
||||||
(i18n/label :advanced-settings)]
|
(i18n/label :advanced-settings)]
|
||||||
|
@ -88,7 +103,9 @@
|
||||||
(for [node (vals wnodes)]
|
(for [node (vals wnodes)]
|
||||||
^{:key (:id node)}
|
^{:key (:id node)}
|
||||||
[react/view {:style {:margin-vertical 8}}
|
[react/view {:style {:margin-vertical 8}}
|
||||||
[render-fn node]])]])))
|
[render-fn node]])]
|
||||||
|
(when (config/pairing-enabled? true)
|
||||||
|
(installations-section installations))])))
|
||||||
|
|
||||||
(views/defview backup-recovery-phrase []
|
(views/defview backup-recovery-phrase []
|
||||||
[profile.recovery/backup-seed])
|
[profile.recovery/backup-seed])
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
(ns status-im.ui.screens.pairing.styles
|
||||||
|
(:require [status-im.ui.components.colors :as colors])
|
||||||
|
(:require-macros [status-im.utils.styles :refer [defstyle]]))
|
||||||
|
|
||||||
|
(def wrapper
|
||||||
|
{:flex 1
|
||||||
|
:background-color :white})
|
||||||
|
|
||||||
|
(def installation-item-inner
|
||||||
|
{:padding-horizontal 16})
|
||||||
|
|
||||||
|
(defstyle installation-item
|
||||||
|
{:flex-direction :row
|
||||||
|
:background-color :white
|
||||||
|
:align-items :center
|
||||||
|
:padding-horizontal 16
|
||||||
|
:ios {:height 64}
|
||||||
|
:android {:height 56}})
|
||||||
|
|
||||||
|
(defstyle installation-item-name-text
|
||||||
|
{:color colors/black
|
||||||
|
:ios {:font-size 17
|
||||||
|
:letter-spacing -0.2
|
||||||
|
:line-height 20}
|
||||||
|
:android {:font-size 16}})
|
|
@ -0,0 +1,7 @@
|
||||||
|
(ns status-im.ui.screens.pairing.subs
|
||||||
|
(:require [re-frame.core :as re-frame]
|
||||||
|
[status-im.utils.ethereum.core :as ethereum]))
|
||||||
|
|
||||||
|
(re-frame/reg-sub :pairing/installations
|
||||||
|
:<- [:get :pairing/installations]
|
||||||
|
vals)
|
|
@ -0,0 +1,47 @@
|
||||||
|
(ns status-im.ui.screens.pairing.views
|
||||||
|
(:require-macros [status-im.utils.views :as views])
|
||||||
|
(:require [re-frame.core :as re-frame]
|
||||||
|
[status-im.i18n :as i18n]
|
||||||
|
[status-im.utils.config :as config]
|
||||||
|
[status-im.ui.components.colors :as colors]
|
||||||
|
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||||
|
[status-im.ui.components.list.views :as list]
|
||||||
|
[status-im.ui.components.react :as react]
|
||||||
|
[status-im.ui.components.status-bar.view :as status-bar]
|
||||||
|
[status-im.ui.components.toolbar.view :as toolbar]
|
||||||
|
[status-im.ui.components.toolbar.actions :as toolbar.actions]
|
||||||
|
[status-im.ui.screens.profile.components.views :as profile.components]
|
||||||
|
[status-im.ui.screens.pairing.styles :as styles]))
|
||||||
|
|
||||||
|
(defn synchronize-installation! [id]
|
||||||
|
(re-frame/dispatch [:pairing.ui/synchronize-installation-pressed id]))
|
||||||
|
|
||||||
|
(defn pair! []
|
||||||
|
(re-frame/dispatch [:pairing.ui/pair-devices-pressed]))
|
||||||
|
|
||||||
|
(defn render-row [{:keys [installation-id]}]
|
||||||
|
[react/touchable-highlight
|
||||||
|
{:on-press #(synchronize-installation! installation-id)
|
||||||
|
:accessibility-label :installation-item}
|
||||||
|
[react/view styles/installation-item
|
||||||
|
[react/view styles/installation-item-inner
|
||||||
|
[react/text {:style styles/installation-item-name-text}
|
||||||
|
installation-id]]]])
|
||||||
|
|
||||||
|
(defn render-rows [installations]
|
||||||
|
[react/view styles/wrapper
|
||||||
|
[list/flat-list {:data installations
|
||||||
|
:default-separator? false
|
||||||
|
:key-fn :installation-id
|
||||||
|
:render-fn render-row}]])
|
||||||
|
|
||||||
|
(views/defview installations []
|
||||||
|
(views/letsubs [installations [:pairing/installations]]
|
||||||
|
[react/view {:flex 1}
|
||||||
|
[status-bar/status-bar]
|
||||||
|
[toolbar/toolbar {}
|
||||||
|
toolbar/default-nav-back
|
||||||
|
[toolbar/content-title (i18n/label :t/devices)]
|
||||||
|
[toolbar/actions
|
||||||
|
[(toolbar.actions/add false pair!)]]]
|
||||||
|
(render-rows installations)]))
|
|
@ -61,3 +61,6 @@
|
||||||
{:font-size 15
|
{:font-size 15
|
||||||
:letter-spacing -0.2
|
:letter-spacing -0.2
|
||||||
:color colors/blue})
|
:color colors/blue})
|
||||||
|
|
||||||
|
(def pair-button
|
||||||
|
{:margin-left 32})
|
||||||
|
|
|
@ -175,6 +175,13 @@
|
||||||
{:label-kw :t/bootnodes
|
{:label-kw :t/bootnodes
|
||||||
:action-fn #(re-frame/dispatch [:navigate-to :bootnodes-settings])
|
:action-fn #(re-frame/dispatch [:navigate-to :bootnodes-settings])
|
||||||
:accessibility-label :bootnodes-settings-button}])
|
:accessibility-label :bootnodes-settings-button}])
|
||||||
|
(when (config/pairing-enabled? dev-mode?)
|
||||||
|
[profile.components/settings-item-separator])
|
||||||
|
(when (config/pairing-enabled? dev-mode?)
|
||||||
|
[profile.components/settings-item
|
||||||
|
{:label-kw :t/devices
|
||||||
|
:action-fn #(re-frame/dispatch [:navigate-to :installations])
|
||||||
|
:accessibility-label :pairing-settings-button}])
|
||||||
(when dev-mode?
|
(when dev-mode?
|
||||||
[profile.components/settings-switch-item
|
[profile.components/settings-switch-item
|
||||||
{:label-kw :t/web3-opt-in
|
{:label-kw :t/web3-opt-in
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
status-im.ui.screens.fleet-settings.subs
|
status-im.ui.screens.fleet-settings.subs
|
||||||
status-im.ui.screens.offline-messaging-settings.subs
|
status-im.ui.screens.offline-messaging-settings.subs
|
||||||
status-im.ui.screens.bootnodes-settings.subs
|
status-im.ui.screens.bootnodes-settings.subs
|
||||||
|
status-im.ui.screens.pairing.subs
|
||||||
status-im.ui.screens.currency-settings.subs
|
status-im.ui.screens.currency-settings.subs
|
||||||
status-im.ui.screens.browser.subs
|
status-im.ui.screens.browser.subs
|
||||||
status-im.ui.screens.add-new.new-chat.subs
|
status-im.ui.screens.add-new.new-chat.subs
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.views :refer [edit-mailserver]]
|
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.views :refer [edit-mailserver]]
|
||||||
[status-im.ui.screens.extensions.add.views :refer [edit-extension show-extension]]
|
[status-im.ui.screens.extensions.add.views :refer [edit-extension show-extension]]
|
||||||
[status-im.ui.screens.bootnodes-settings.views :refer [bootnodes-settings]]
|
[status-im.ui.screens.bootnodes-settings.views :refer [bootnodes-settings]]
|
||||||
|
[status-im.ui.screens.pairing.views :refer [installations]]
|
||||||
[status-im.ui.screens.bootnodes-settings.edit-bootnode.views :refer [edit-bootnode]]
|
[status-im.ui.screens.bootnodes-settings.edit-bootnode.views :refer [edit-bootnode]]
|
||||||
[status-im.ui.screens.currency-settings.views :refer [currency-settings]]
|
[status-im.ui.screens.currency-settings.views :refer [currency-settings]]
|
||||||
[status-im.ui.screens.help-center.views :refer [help-center]]
|
[status-im.ui.screens.help-center.views :refer [help-center]]
|
||||||
|
@ -270,6 +271,7 @@
|
||||||
:profile-photo-capture profile-photo-capture
|
:profile-photo-capture profile-photo-capture
|
||||||
:about-app about-app/about-app
|
:about-app about-app/about-app
|
||||||
:bootnodes-settings bootnodes-settings
|
:bootnodes-settings bootnodes-settings
|
||||||
|
:installations installations
|
||||||
:edit-bootnode edit-bootnode
|
:edit-bootnode edit-bootnode
|
||||||
:offline-messaging-settings offline-messaging-settings
|
:offline-messaging-settings offline-messaging-settings
|
||||||
:edit-mailserver edit-mailserver
|
:edit-mailserver edit-mailserver
|
||||||
|
|
|
@ -17,7 +17,14 @@
|
||||||
|
|
||||||
(def bootnodes-settings-enabled? (enabled? (get-config :BOOTNODES_SETTINGS_ENABLED "1")))
|
(def bootnodes-settings-enabled? (enabled? (get-config :BOOTNODES_SETTINGS_ENABLED "1")))
|
||||||
(def rpc-networks-only? (enabled? (get-config :RPC_NETWORKS_ONLY "1")))
|
(def rpc-networks-only? (enabled? (get-config :RPC_NETWORKS_ONLY "1")))
|
||||||
(def group-chats-enabled? (enabled? (get-config :GROUP_CHATS_ENABLED "0")))
|
(defn group-chats-enabled? [dev-mode?]
|
||||||
|
(and (enabled? (get-config :GROUP_CHATS_ENABLED "0"))
|
||||||
|
(or dev-mode? platform/desktop?)))
|
||||||
|
(defn pairing-enabled? [dev-mode?]
|
||||||
|
(and (enabled? (get-config :PAIRING_ENABLED "0"))
|
||||||
|
(or dev-mode? platform/desktop?)
|
||||||
|
;; Hard disable as desktop ignores build parameters
|
||||||
|
false))
|
||||||
(def mainnet-warning-enabled? (enabled? (get-config :MAINNET_WARNING_ENABLED 0)))
|
(def mainnet-warning-enabled? (enabled? (get-config :MAINNET_WARNING_ENABLED 0)))
|
||||||
(def pfs-encryption-enabled? (enabled? (get-config :PFS_ENCRYPTION_ENABLED "0")))
|
(def pfs-encryption-enabled? (enabled? (get-config :PFS_ENCRYPTION_ENABLED "0")))
|
||||||
(def in-app-notifications-enabled? (enabled? (get-config :IN_APP_NOTIFICATIONS_ENABLED 0)))
|
(def in-app-notifications-enabled? (enabled? (get-config :IN_APP_NOTIFICATIONS_ENABLED 0)))
|
||||||
|
|
|
@ -118,4 +118,4 @@
|
||||||
(testing "it returns only chats with is-active"
|
(testing "it returns only chats with is-active"
|
||||||
(is (= {1 active-chat-1
|
(is (= {1 active-chat-1
|
||||||
2 active-chat-2}
|
2 active-chat-2}
|
||||||
(s/active-chats [{} chats]))))))
|
(s/active-chats [{} chats {}]))))))
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
(is (= 3 (group-chats/get-last-clock-value {:db {:chats {chat-id initial-message}}} chat-id))))
|
(is (= 3 (group-chats/get-last-clock-value {:db {:chats {chat-id initial-message}}} chat-id))))
|
||||||
|
|
||||||
(deftest handle-group-membership-update
|
(deftest handle-group-membership-update
|
||||||
(with-redefs [config/group-chats-enabled? true]
|
(with-redefs [config/group-chats-enabled? (constantly true)]
|
||||||
(testing "a brand new chat"
|
(testing "a brand new chat"
|
||||||
(let [actual (->
|
(let [actual (->
|
||||||
(group-chats/handle-membership-update {:db {}} initial-message admin)
|
(group-chats/handle-membership-update {:db {}} initial-message admin)
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
(is (= "id" (:InstallationID actual))))))
|
(is (= "id" (:InstallationID actual))))))
|
||||||
(testing "pfs & group chats disabled"
|
(testing "pfs & group chats disabled"
|
||||||
(with-redefs [config/pfs-encryption-enabled? false
|
(with-redefs [config/pfs-encryption-enabled? false
|
||||||
config/group-chats-enabled? false]
|
config/group-chats-enabled? (constantly false)]
|
||||||
(testing "the user is not logged in"
|
(testing "the user is not logged in"
|
||||||
(let [actual (parse-node-config (node/start cofx nil))]
|
(let [actual (parse-node-config (node/start cofx nil))]
|
||||||
(is (not (:PFSEnabled actual)))))
|
(is (not (:PFSEnabled actual)))))
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
(let [actual (parse-node-config (node/start cofx address))]
|
(let [actual (parse-node-config (node/start cofx address))]
|
||||||
(is (:PFSEnabled actual))))))
|
(is (:PFSEnabled actual))))))
|
||||||
(testing "group chats is enabled"
|
(testing "group chats is enabled"
|
||||||
(with-redefs [config/group-chats-enabled? true]
|
(with-redefs [config/group-chats-enabled? (constantly true)]
|
||||||
(testing "the user is not logged in"
|
(testing "the user is not logged in"
|
||||||
(let [actual (parse-node-config (node/start cofx nil))]
|
(let [actual (parse-node-config (node/start cofx nil))]
|
||||||
(is (not (:PFSEnabled actual)))))
|
(is (not (:PFSEnabled actual)))))
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
(ns status-im.test.pairing.core
|
||||||
|
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||||
|
[status-im.transport.message.pairing :as transport.pairing]
|
||||||
|
[status-im.utils.config :as config]
|
||||||
|
[status-im.pairing.core :as pairing]))
|
||||||
|
|
||||||
|
(deftest merge-contact-test
|
||||||
|
(testing "vanilla contacts"
|
||||||
|
(let [contact-1 {:pending? false
|
||||||
|
:this-should-be-kept true
|
||||||
|
:last-updated 1
|
||||||
|
:name "name-v1"
|
||||||
|
:photo-path "photo-v1"}
|
||||||
|
contact-2 {:pending? false
|
||||||
|
:last-updated 2
|
||||||
|
:name "name-v2"
|
||||||
|
:photo-path "photo-v2"}
|
||||||
|
expected {:pending? false
|
||||||
|
: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 {:pending? false
|
||||||
|
:name "name-v1"
|
||||||
|
:photo-path "photo-v1"}
|
||||||
|
contact-2 {:pending? false
|
||||||
|
:last-updated 2
|
||||||
|
:name "name-v2"
|
||||||
|
:photo-path "photo-v2"}
|
||||||
|
expected {:pending? false
|
||||||
|
: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 {:pending? false
|
||||||
|
:last-updated 2
|
||||||
|
:name "name-v2"
|
||||||
|
:photo-path "photo-v2"}
|
||||||
|
expected {:pending? false
|
||||||
|
:last-updated 2
|
||||||
|
:name "name-v2"
|
||||||
|
:photo-path "photo-v2"}]
|
||||||
|
(is (= expected (pairing/merge-contact contact-1 contact-2)))))
|
||||||
|
(testing "not pending in one device"
|
||||||
|
(let [contact-1 {:pending? false
|
||||||
|
:last-updated 1
|
||||||
|
:name "name-v1"
|
||||||
|
:photo-path "photo-v1"}
|
||||||
|
contact-2 {:pending? true
|
||||||
|
:last-updated 2
|
||||||
|
:name "name-v2"
|
||||||
|
:photo-path "photo-v2"}
|
||||||
|
expected {:pending? false
|
||||||
|
: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 {:pending? true
|
||||||
|
:last-updated 2
|
||||||
|
:name "name-v2"
|
||||||
|
:photo-path "photo-v2"}
|
||||||
|
expected {:pending? true
|
||||||
|
: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 [config/pairing-enabled? (constantly true)]
|
||||||
|
(let [old-contact-1 {:name "old-contact-one"
|
||||||
|
:last-updated 0
|
||||||
|
:photo-path "old-contact-1"
|
||||||
|
:pending? true}
|
||||||
|
new-contact-1 {:name "new-contact-one"
|
||||||
|
:last-updated 1
|
||||||
|
:photo-path "new-contact-1"
|
||||||
|
:pending? false}
|
||||||
|
old-contact-2 {:name "old-contact-2"
|
||||||
|
:last-updated 0
|
||||||
|
:photo-path "old-contact-2"
|
||||||
|
:pending? false}
|
||||||
|
new-contact-2 {:name "new-contact-2"
|
||||||
|
:last-updated 1
|
||||||
|
:photo-path "new-contact-2"
|
||||||
|
:pending? false}
|
||||||
|
contact-3 {:name "contact-3"
|
||||||
|
:photo-path "contact-3"
|
||||||
|
:pending? false}
|
||||||
|
contact-4 {:name "contact-4"
|
||||||
|
:photo-path "contact-4"
|
||||||
|
:pending? true}
|
||||||
|
cofx {:db {:current-public-key "us"
|
||||||
|
:contacts/contacts {"contact-1" old-contact-1
|
||||||
|
"contact-2" new-contact-2
|
||||||
|
"contact-3" contact-3}}}
|
||||||
|
sync-message {:contacts {"contact-1" new-contact-1
|
||||||
|
"contact-2" old-contact-2
|
||||||
|
"contact-4" contact-4}}
|
||||||
|
expected {"contact-1" new-contact-1
|
||||||
|
"contact-2" new-contact-2
|
||||||
|
"contact-3" contact-3
|
||||||
|
"contact-4" contact-4}]
|
||||||
|
(testing "not coming from us"
|
||||||
|
(is (not (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])))))))
|
||||||
|
|
||||||
|
(deftest sync-installation-messages-test
|
||||||
|
(testing "it creates a sync installation message"
|
||||||
|
(let [cofx {:db {:current-public-key "us"
|
||||||
|
:contacts/contacts {"contact-1" {:name "contact-1"}
|
||||||
|
"contact-2" {:name "contact-2"}}}}
|
||||||
|
expected [(transport.pairing/SyncInstallation. {"contact-1" {:name "contact-1"}})
|
||||||
|
(transport.pairing/SyncInstallation. {"contact-2" {:name "contact-2"}})]]
|
||||||
|
(is (= expected (pairing/sync-installation-messages cofx))))))
|
||||||
|
|
||||||
|
(deftest handle-bundles-added-test
|
||||||
|
(with-redefs [config/pairing-enabled? (constantly true)]
|
||||||
|
(let [installation-1 {:confirmed? true
|
||||||
|
:installation-id "installation-1"}
|
||||||
|
cofx {:db {:current-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" {:confirmed? false
|
||||||
|
:installation-id "installation-2"}}]
|
||||||
|
(is (= expected (get-in (pairing/handle-bundles-added cofx new-installation) [:db :pairing/installations])))))
|
||||||
|
(testing "already existing installation"
|
||||||
|
(let [old-installation {:identity "us" :installationID "installation-1"}]
|
||||||
|
(is (not (pairing/handle-bundles-added cofx old-installation)))))
|
||||||
|
(testing "not from us"
|
||||||
|
(let [new-installation {:identity "not-us" :installationID "does-not-matter"}]
|
||||||
|
(is (not (pairing/handle-bundles-added cofx new-installation))))))))
|
|
@ -11,6 +11,7 @@
|
||||||
[status-im.test.wallet.transactions.views]
|
[status-im.test.wallet.transactions.views]
|
||||||
[status-im.test.mailserver.core]
|
[status-im.test.mailserver.core]
|
||||||
[status-im.test.group-chats.core]
|
[status-im.test.group-chats.core]
|
||||||
|
[status-im.test.pairing.core]
|
||||||
[status-im.test.node.core]
|
[status-im.test.node.core]
|
||||||
[status-im.test.models.bootnode]
|
[status-im.test.models.bootnode]
|
||||||
[status-im.test.models.account]
|
[status-im.test.models.account]
|
||||||
|
@ -78,6 +79,7 @@
|
||||||
'status-im.test.extensions.core
|
'status-im.test.extensions.core
|
||||||
'status-im.test.mailserver.core
|
'status-im.test.mailserver.core
|
||||||
'status-im.test.group-chats.core
|
'status-im.test.group-chats.core
|
||||||
|
'status-im.test.pairing.core
|
||||||
'status-im.test.node.core
|
'status-im.test.node.core
|
||||||
'status-im.test.models.bootnode
|
'status-im.test.models.bootnode
|
||||||
'status-im.test.models.account
|
'status-im.test.models.account
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
"confirm": "Confirm",
|
"confirm": "Confirm",
|
||||||
"public-chat": "Public chat",
|
"public-chat": "Public chat",
|
||||||
"description": "Description",
|
"description": "Description",
|
||||||
|
"devices": "Devices",
|
||||||
|
"pair": "Pair devices",
|
||||||
"currency-display-name-tzs": "Tanzanian Shilling",
|
"currency-display-name-tzs": "Tanzanian Shilling",
|
||||||
"currency-display-name-brl": "Brazil Real",
|
"currency-display-name-brl": "Brazil Real",
|
||||||
"mainnet-network": "Main network",
|
"mainnet-network": "Main network",
|
||||||
|
|
Loading…
Reference in New Issue