[Fix #2751] Allow switching between wnodes for offline messaging
Signed-off-by: Eric Dvorsak <eric@dvorsak.fr>
This commit is contained in:
parent
3b6b987db4
commit
8582be2e69
|
@ -13,7 +13,7 @@
|
|||
(def text-content-type "text/plain")
|
||||
(def content-type-log-message "log-message")
|
||||
(def content-type-command "command")
|
||||
(def content-type-command-request "command-request")
|
||||
(def content-type-command-request "command-request")
|
||||
(def content-type-status "status")
|
||||
|
||||
(def min-password-length 6)
|
||||
|
@ -82,10 +82,15 @@
|
|||
(when config/mainnet-networks-enabled? mainnet-networks))))
|
||||
|
||||
;; adamb's status-cluster enode
|
||||
(def default-wnode {:name "Status mailserver"
|
||||
:address "enode://08d8eb6177b187049f6c97ed3f6c74fbbefb94c7ad10bafcaf4b65ce89c314dcfee0a8bc4e7a5b824dfa08b45b360cc78f34f0aff981f8386caa07652d2e601b@163.172.177.138:40404"})
|
||||
(def default-wnode "main")
|
||||
|
||||
(def default-wnodes [default-wnode])
|
||||
(def default-wnodes
|
||||
{"main" {:id "main"
|
||||
:name "Status mailserver"
|
||||
:address "enode://08d8eb6177b187049f6c97ed3f6c74fbbefb94c7ad10bafcaf4b65ce89c314dcfee0a8bc4e7a5b824dfa08b45b360cc78f34f0aff981f8386caa07652d2e601b@163.172.177.138:40404"}
|
||||
"test" {:id "test"
|
||||
:name "Status mailserver (test)"
|
||||
:address "enode://e2fdcf8a55d9d1ab75b492c3b9a99c206cf5ceede3db716033d0605205218c9d9a406d04b3460f4e8a64f16907ab78ba88e0e46324568bf58b3329e2c5483faa@163.172.177.138:30353"}})
|
||||
|
||||
;; TODO(oskarth): Determine if this is the correct topic or not
|
||||
(def inbox-topic "0xaabb11ee")
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
[status-im.data-store.realm.schemas.base.v2.core :as v2]
|
||||
[status-im.data-store.realm.schemas.base.v3.core :as v3]
|
||||
[status-im.data-store.realm.schemas.base.v4.core :as v4]
|
||||
[status-im.data-store.realm.schemas.base.v5.core :as v5]))
|
||||
[status-im.data-store.realm.schemas.base.v5.core :as v5]
|
||||
[status-im.data-store.realm.schemas.base.v6.core :as v6]))
|
||||
|
||||
; put schemas ordered by version
|
||||
(def schemas [{:schema v1/schema
|
||||
|
@ -20,4 +21,7 @@
|
|||
:migration v4/migration}
|
||||
{:schema v5/schema
|
||||
:schemaVersion 5
|
||||
:migration v5/migration}])
|
||||
:migration v5/migration}
|
||||
{:schema v6/schema
|
||||
:schemaVersion 6
|
||||
:migration v6/migration}])
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
(ns status-im.data-store.realm.schemas.base.v6.account
|
||||
(:require [taoensso.timbre :as log]
|
||||
[status-im.constants :as constants]))
|
||||
|
||||
(def schema {:name :account
|
||||
:primaryKey :address
|
||||
:properties {:address :string
|
||||
:public-key :string
|
||||
:updates-public-key {:type :string
|
||||
:optional true}
|
||||
:updates-private-key {:type :string
|
||||
:optional true}
|
||||
:name {:type :string :optional true}
|
||||
:phone {:type :string :optional true}
|
||||
:email {:type :string :optional true}
|
||||
:status {:type :string :optional true}
|
||||
:debug? {:type :bool :default false}
|
||||
:photo-path :string
|
||||
:signing-phrase {:type :string}
|
||||
:last-updated {:type :int :default 0}
|
||||
:signed-up? {:type :bool
|
||||
:default false}
|
||||
:network :string
|
||||
:networks {:type :list
|
||||
:objectType :network}
|
||||
:wnode :string
|
||||
:settings {:type :string}}})
|
||||
|
||||
(defn migration [_old-realm new-realm]
|
||||
(log/debug "migrating account schema v6")
|
||||
(let [accounts (.objects new-realm "account")]
|
||||
(dotimes [i (.-length accounts)]
|
||||
(let [account (aget accounts i)]
|
||||
(aset account "wnode" constants/default-wnode)))))
|
|
@ -0,0 +1,11 @@
|
|||
(ns status-im.data-store.realm.schemas.base.v6.core
|
||||
(:require [status-im.data-store.realm.schemas.base.v4.network :as network]
|
||||
[status-im.data-store.realm.schemas.base.v6.account :as account]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def schema [network/schema
|
||||
account/schema])
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating v6 base database: " old-realm new-realm)
|
||||
(account/migration old-realm new-realm))
|
|
@ -17,7 +17,7 @@
|
|||
[status-im.chat.models.message :as models.message]
|
||||
[status-im.protocol.web3.inbox :as inbox]
|
||||
[status-im.protocol.web3.keys :as web3.keys]
|
||||
[status-im.utils.datetime :as datetime]
|
||||
[status-im.utils.datetime :as datetime]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.native-module.core :as status]
|
||||
[clojure.string :as string]
|
||||
|
@ -274,14 +274,16 @@
|
|||
:initialize-offline-inbox
|
||||
(fn [{:keys [db]} [_ web3]]
|
||||
(log/info "offline inbox: initialize")
|
||||
(let [wnode (get-in db [:inbox/wnode :address])]
|
||||
(let [wnode-id (get db :inbox/wnode)
|
||||
wnode (get-in db [:inbox/wnodes wnode-id :address])]
|
||||
{::add-peer {:wnode wnode
|
||||
:web3 web3}})))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
::add-peer-success
|
||||
(fn [{:keys [db]} [_ web3 response]]
|
||||
(let [wnode (get-in db [:inbox/wnode :address])]
|
||||
(let [wnode-id (get db :inbox/wnode)
|
||||
wnode (get-in db [:inbox/wnodes wnode-id :address])]
|
||||
(log/info "offline inbox: add-peer response" wnode response)
|
||||
{::fetch-peers {:wnode wnode
|
||||
:web3 web3
|
||||
|
@ -290,7 +292,8 @@
|
|||
(handlers/register-handler-fx
|
||||
::fetch-peers-success
|
||||
(fn [{:keys [db]} [_ web3 peers retries]]
|
||||
(let [wnode (get-in db [:inbox/wnode :address])]
|
||||
(let [wnode-id (get db :inbox/wnode)
|
||||
wnode (get-in db [:inbox/wnodes wnode-id :address])]
|
||||
(log/info "offline inbox: fetch-peers response" peers)
|
||||
(if (inbox/registered-peer? peers wnode)
|
||||
{::mark-trusted-peer {:wnode wnode
|
||||
|
@ -298,14 +301,15 @@
|
|||
:peers peers}}
|
||||
(do
|
||||
(log/info "Peer" wnode "is not registered. Retrying fetch peers.")
|
||||
{::fetch-peers {:wnode wnode
|
||||
:web3 web3
|
||||
{::fetch-peers {:wnode wnode
|
||||
:web3 web3
|
||||
:retries (inc retries)}})))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
::mark-trusted-peer-success
|
||||
(fn [{:keys [db]} [_ web3 response]]
|
||||
(let [wnode (get-in db [:inbox/wnode :address])
|
||||
(let [wnode-id (get db :inbox/wnode)
|
||||
wnode (get-in db [:inbox/wnodes wnode-id :address])
|
||||
password (:inbox/password db)]
|
||||
(log/info "offline inbox: mark-trusted-peer response" wnode response)
|
||||
{::get-sym-key {:password password
|
||||
|
@ -317,8 +321,9 @@
|
|||
::get-sym-key-success
|
||||
(fn [{:keys [db]} [_ web3 sym-key-id]]
|
||||
(log/info "offline inbox: get-sym-key response" sym-key-id)
|
||||
(let [wnode (get-in db [:inbox/wnode :address])
|
||||
topic (:inbox/topic db)]
|
||||
(let [wnode-id (get db :inbox/wnode)
|
||||
wnode (get-in db [:inbox/wnodes wnode-id :address])
|
||||
topic (:inbox/topic db)]
|
||||
{::request-messages {:wnode wnode
|
||||
:topic topic
|
||||
:sym-key-id sym-key-id
|
||||
|
@ -424,7 +429,7 @@
|
|||
|
||||
;;; MESSAGES
|
||||
|
||||
(defn- transform-protocol-message [{:keys [from to payload]}]
|
||||
(defn- transform-protocol-message [{:keys [from to payload]}]
|
||||
(merge payload {:from from
|
||||
:to to
|
||||
:chat-id (or (:group-id payload) from)}))
|
||||
|
@ -439,7 +444,7 @@
|
|||
(or ack-of-message message-id))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:incoming-message
|
||||
:incoming-message
|
||||
(fn [{:keys [db]} [_ type {:keys [payload ttl id] :as message}]]
|
||||
(let [message-id (or id (:message-id payload))]
|
||||
(when-not (cache/exists? message-id type)
|
||||
|
@ -473,7 +478,7 @@
|
|||
:discoveries-response {:dispatch [:discoveries-response-received message]}
|
||||
:profile {:dispatch [:contact-update-received message]}
|
||||
:update-keys {:dispatch [:update-keys-received message]}
|
||||
:online {:dispatch [:contact-online-received message]}
|
||||
:online {:dispatch [:contact-online-received message]}
|
||||
nil)]
|
||||
(when (nil? route-fx) (log/debug "Unknown message type" type))
|
||||
(cache/add! processed-message)
|
||||
|
@ -487,19 +492,19 @@
|
|||
(fn [{:keys [db get-stored-message]} [{:keys [from sent-from payload]} status]]
|
||||
(let [message-identifier (get-message-id payload)
|
||||
chat-identifier (or (:group-id payload) from)
|
||||
message-db-path [:chats chat-identifier :messages message-identifier]
|
||||
from-id (or sent-from from)
|
||||
message-db-path [:chats chat-identifier :messages message-identifier]
|
||||
from-id (or sent-from from)
|
||||
message (or (get-in db message-db-path)
|
||||
(and (get (:not-loaded-message-ids db) message-identifier)
|
||||
(get-stored-message message-identifier)))]
|
||||
;; proceed with updating status if chat is in db, status is not the same and message was not already seen
|
||||
;; proceed with updating status if chat is in db, status is not the same and message was not already seen
|
||||
(when (and message
|
||||
(get-in db [:chats chat-identifier])
|
||||
(not= status (get-in message [:user-statuses from-id]))
|
||||
(not (models.message/message-seen-by? message from-id)))
|
||||
(let [statuses (assoc (:user-statuses message) from-id status)]
|
||||
(cond-> {:update-message {:message-id message-identifier
|
||||
:user-statuses statuses}}
|
||||
:user-statuses statuses}}
|
||||
(get-in db message-db-path)
|
||||
(assoc :db (assoc-in db (conj message-db-path :user-statuses) statuses))))))))
|
||||
|
||||
|
@ -527,7 +532,7 @@
|
|||
;; Get timestamp from message root level.
|
||||
;; Root level "timestamp" is a unix ts in seconds.
|
||||
timestamp' (or (:payload timestamp)
|
||||
(* 1000 timestamp))]
|
||||
(* 1000 timestamp))]
|
||||
(if-not existing-contact
|
||||
(let [contact (assoc contact :pending? true)]
|
||||
{:dispatch-n [[:add-contacts [contact]]
|
||||
|
|
|
@ -399,6 +399,7 @@
|
|||
:close-app-title "Warning!"
|
||||
:close-app-content "The app will stop and close. When you reopen it, the selected network will be used"
|
||||
:close-app-button "Confirm"
|
||||
:connect-wnode-content "Connect to {{name}}?"
|
||||
|
||||
;; browser
|
||||
:browser "Browser"
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
(spec/def :account/status (spec/nilable string?))
|
||||
(spec/def :account/network (spec/nilable string?))
|
||||
(spec/def :account/networks (spec/nilable :networks/networks))
|
||||
(spec/def :account/wnode (spec/nilable string?))
|
||||
(spec/def :account/settings (spec/nilable (spec/map-of keyword? any?)))
|
||||
(spec/def :account/phone (spec/nilable string?))
|
||||
(spec/def :account/signing-phrase :global/not-empty-string)
|
||||
|
@ -28,7 +29,8 @@
|
|||
:opt-un [:account/debug? :account/status :account/last-updated
|
||||
:account/updates-private-key :account/updates-public-key
|
||||
:account/email :account/signed-up? :account/network
|
||||
:account/phone :account/networks :account/settings]))
|
||||
:account/phone :account/networks :account/settings
|
||||
:account/wnode]))
|
||||
|
||||
(spec/def :accounts/accounts (spec/nilable (spec/map-of :account/address :accounts/account)))
|
||||
|
||||
|
|
|
@ -92,11 +92,12 @@
|
|||
|
||||
(defn add-account
|
||||
"Takes db and new account, creates map of effects describing adding account to database and realm"
|
||||
[{:keys [network] :networks/keys [networks] :as db} {:keys [address] :as account}]
|
||||
[{:keys [network inbox/wnode] :networks/keys [networks] :as db} {:keys [address] :as account}]
|
||||
(let [enriched-account (assoc account
|
||||
:network network
|
||||
:network network
|
||||
:networks networks
|
||||
:address address)]
|
||||
:wnode wnode
|
||||
:address address)]
|
||||
{:db (assoc-in db [:accounts/accounts address] enriched-account)
|
||||
::save-account enriched-account}))
|
||||
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
[status-im.native-module.core :as status]
|
||||
[status-im.constants :refer [console-chat-id]]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.utils.utils :as utils]))
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im.constants :as constants]))
|
||||
|
||||
;;;; FX
|
||||
|
||||
|
@ -70,6 +71,9 @@
|
|||
{:network network
|
||||
:config config}))
|
||||
|
||||
(defn get-wnode-by-address [db address]
|
||||
(get-in db [:accounts/accounts address :wnode] constants/default-wnode))
|
||||
|
||||
(defn wrap-with-initialize-geth-fx [db address password]
|
||||
(let [{:keys [network config]} (get-network-by-address db address)]
|
||||
{:initialize-geth-fx config
|
||||
|
@ -92,8 +96,10 @@
|
|||
(fn [{{:keys [network status-node-started?] :as db} :db}
|
||||
[_ address password account-creation?]]
|
||||
(let [{account-network :network} (get-network-by-address db address)
|
||||
wnode (get-wnode-by-address db address)
|
||||
db' (-> db
|
||||
(assoc :accounts/account-creation? account-creation?)
|
||||
(assoc :inbox/wnode wnode)
|
||||
(assoc-in [:accounts/login :processing] true))
|
||||
wrap-fn (cond (not status-node-started?)
|
||||
wrap-with-initialize-geth-fx
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
:network constants/default-network
|
||||
:networks/networks constants/default-networks
|
||||
:inbox/wnode constants/default-wnode
|
||||
:inbox/wnodes constants/default-wnodes
|
||||
:inbox/topic constants/inbox-topic
|
||||
:inbox/password constants/inbox-password
|
||||
:my-profile/editing? false})
|
||||
|
@ -132,6 +133,7 @@
|
|||
:node/after-start
|
||||
:node/after-stop
|
||||
:inbox/wnode
|
||||
:inbox/wnodes
|
||||
:inbox/topic
|
||||
:inbox/password
|
||||
:browser/browsers
|
||||
|
@ -176,7 +178,7 @@
|
|||
:chat/message-data
|
||||
:chat/message-status
|
||||
:chat/selected-participants
|
||||
:chat/chat-loaded-callbacks
|
||||
:chat/chat-loaded-callbacks
|
||||
:chat/public-group-topic
|
||||
:chat/confirmation-code-sms-listener
|
||||
:chat/messages
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
status-im.ui.screens.wallet.choose-recipient.events
|
||||
status-im.ui.screens.browser.events
|
||||
status-im.ui.screens.add-new.open-dapp.events
|
||||
status-im.ui.screens.offline-messaging-settings.events
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.native-module.core :as status]
|
||||
[status-im.ui.components.react :as react]
|
||||
|
@ -250,8 +251,10 @@
|
|||
(fn [{:keys [accounts/accounts contacts/contacts networks/networks
|
||||
network network-status view-id navigation-stack chats
|
||||
access-scope->commands-responses layout-height
|
||||
status-module-initialized? status-node-started?]
|
||||
:or [network (get app-db :network)]
|
||||
status-module-initialized? status-node-started?
|
||||
inbox/wnode]
|
||||
:or [network (get app-db :network)
|
||||
wnode (get app-db :inbox/wnode)]
|
||||
:as db} [_ address]]
|
||||
(let [console-contact (get contacts console-chat-id)]
|
||||
(cond-> (assoc app-db
|
||||
|
@ -270,7 +273,8 @@
|
|||
:accounts/creating-account? false
|
||||
:networks/networks networks
|
||||
:network-status network-status
|
||||
:network network)
|
||||
:network network
|
||||
:inbox/wnode wnode)
|
||||
console-contact
|
||||
(assoc :contacts/contacts {console-chat-id console-contact})))))
|
||||
|
||||
|
|
|
@ -5,8 +5,13 @@
|
|||
(def enode-address-regex #"enode://[a-zA-Z0-9]+\@\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b:(\d{1,5})")
|
||||
|
||||
(spec/def ::not-blank-string (spec/and string? seq))
|
||||
|
||||
(spec/def :wnode/address (spec/and string? #(re-matches enode-address-regex %)))
|
||||
(spec/def :wnode/name ::not-blank-string)
|
||||
(spec/def :wnode/id ::not-blank-string)
|
||||
(spec/def :wnode/wnode (allowed-keys :req-un [:wnode/address :wnode/name :wnode/id]))
|
||||
|
||||
(spec/def :inbox/topic ::not-blank-string)
|
||||
(spec/def :inbox/password ::not-blank-string)
|
||||
(spec/def :inbox/wnode (allowed-keys :req-un [:wnode/address :wnode/name]))
|
||||
(spec/def :inbox/wnode ::not-blank-string)
|
||||
(spec/def :inbox/wnodes (spec/nilable (spec/map-of :wnode/id :wnode/wnode)))
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
(ns status-im.ui.screens.offline-messaging-settings.events
|
||||
(:require [re-frame.core :refer [dispatch]]
|
||||
[status-im.utils.handlers :as handlers]
|
||||
[status-im.ui.screens.accounts.events :as accounts-events]
|
||||
[status-im.i18n :as i18n]))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
::save-wnode
|
||||
(fn [{:keys [db now]} [_ wnode]]
|
||||
(-> (accounts-events/account-update {:db db}
|
||||
{:wnode wnode :last-updated now})
|
||||
(merge {:dispatch [:navigate-to-clean :accounts]
|
||||
:stop-whisper nil}))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:connect-wnode
|
||||
(fn [{:keys [db now]} [_ wnode]]
|
||||
{:show-confirmation {:title (i18n/label :t/close-app-title)
|
||||
:content (i18n/label :t/connect-wnode-content
|
||||
{:name (get-in db [:inbox/wnodes wnode :name])})
|
||||
:confirm-button-text (i18n/label :t/close-app-button)
|
||||
:on-accept #(dispatch [::save-wnode wnode])
|
||||
:on-cancel nil}}))
|
|
@ -1,5 +1,6 @@
|
|||
(ns status-im.ui.screens.offline-messaging-settings.views
|
||||
(:require [status-im.constants :as constants]
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.common.common :as common]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
|
@ -11,23 +12,19 @@
|
|||
[status-im.utils.platform :as platform]
|
||||
[taoensso.timbre :as log]
|
||||
[reagent.core :as reagent])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(defn- add-wnode []
|
||||
;; TODO:(dmitryn) to be added in #2751
|
||||
(log/info "add wnode not implemented"))
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
|
||||
(defn- wnode-icon [connected?]
|
||||
[react/view (styles/wnode-icon connected?)
|
||||
[vector-icons/icon :icons/wnode {:color (if connected? :white :gray)}]])
|
||||
|
||||
(defn- render-row [current-wnode]
|
||||
(fn [{:keys [address name] :as row} _ _]
|
||||
(let [connected? (= address (:address current-wnode))]
|
||||
(fn [{:keys [address name id] :as row} _ _]
|
||||
(let [connected? (= id current-wnode)]
|
||||
[react/list-item
|
||||
^{:key row}
|
||||
[react/touchable-highlight
|
||||
{:on-press add-wnode}
|
||||
{:on-press #(re-frame/dispatch [:connect-wnode id])}
|
||||
[react/view styles/wnode-item
|
||||
[wnode-icon connected?]
|
||||
[react/view styles/wnode-item-inner
|
||||
|
@ -53,10 +50,9 @@
|
|||
[common/list-footer]
|
||||
[common/bottom-shadow]]])
|
||||
|
||||
(views/defview offline-messaging-settings []
|
||||
;; TODO:(dmitryn) store wnodes in user account, but now use defaults for MVP
|
||||
(let [current-wnode constants/default-wnode
|
||||
wnodes constants/default-wnodes]
|
||||
(defview offline-messaging-settings []
|
||||
(letsubs [current-wnode [:get :inbox/wnode]
|
||||
wnodes [:get :inbox/wnodes]]
|
||||
[react/view {:flex 1}
|
||||
[status-bar/status-bar]
|
||||
[toolbar/simple-toolbar (i18n/label :t/offline-messaging-settings)]
|
||||
|
@ -66,7 +62,7 @@
|
|||
;; TODO(dmitryn) migrate to :header/:footer properties of flat-list
|
||||
;; after merge of https://github.com/status-im/status-react/pull/2297/
|
||||
[render-header wnodes]
|
||||
[list/flat-list {:data wnodes
|
||||
[list/flat-list {:data (vals wnodes)
|
||||
:separator? false
|
||||
:render-fn (render-row current-wnode)
|
||||
:ListFooterComponent (reagent/as-element (render-footer))
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
:status "be the hero of your own journey"
|
||||
:network constants/default-network
|
||||
:networks constants/default-networks
|
||||
:wnode constants/default-wnode
|
||||
:public-key "0x049b3a8c04f2c5bccda91c1f5e6434ae72957e93a31c0301b4563eda1d6ce419f63c503ebaee143115f96c1f04f232a7a22ca0454e9ee3d579ad1f870315b151d0"})
|
||||
|
||||
(def new-account
|
||||
|
@ -38,6 +39,7 @@
|
|||
:status "the future starts today, not tomorrow"
|
||||
:network constants/default-network
|
||||
:networks constants/default-networks
|
||||
:wnode constants/default-wnode
|
||||
:signing-phrase "long loan limo"
|
||||
:public-key "0x04f5722fba79eb36d73263417531007f43d13af76c6233573a8e3e60f667710611feba0785d751b50609bfc0b7cef35448875c5392c0a91948c95798a0ce600847"})
|
||||
|
||||
|
|
Loading…
Reference in New Issue