[fix #3913] do not logout when changing mailserver

- do not logout and remove previous mailserver
from peers when changing mailserver
- rename wnode mailserver
- move transport.inbox to mailserver.core
- fix all subs and db keys

Signed-off-by: yenda <eric@status.im>
This commit is contained in:
yenda 2018-10-18 02:05:02 +02:00
parent ed16d9f191
commit a3b2bc1b87
No known key found for this signature in database
GPG Key ID: 0095623C0069DCE6
56 changed files with 1053 additions and 994 deletions

View File

Before

Width:  |  Height:  |  Size: 322 B

After

Width:  |  Height:  |  Size: 322 B

View File

@ -41,7 +41,7 @@
(spec/def :account/networks (spec/nilable :networks/networks))
(spec/def :account/bootnodes (spec/nilable :bootnodes/bootnodes))
(spec/def :account/extensions (spec/nilable :extensions/extensions))
(spec/def :account/wnode (spec/nilable string?))
(spec/def :account/mailserver (spec/nilable string?))
(spec/def :account/settings (spec/nilable (spec/map-of keyword? any?)))
(spec/def :account/signing-phrase :global/not-empty-string)
(spec/def :account/mnemonic (spec/nilable string?))
@ -59,7 +59,7 @@
:account/installation-id]
:opt-un [:account/debug? :account/status :account/last-updated
:account/email :account/signed-up? :account/network
:account/networks :account/settings :account/wnode
:account/networks :account/settings :account/mailserver
:account/last-sign-in :account/sharing-usage-data? :account/dev-mode?
:account/seed-backed-up? :account/mnemonic :account/desktop-notifications?
:account/wallet-set-up-passed? :account/last-request

View File

@ -22,7 +22,7 @@
(def blocks-per-hour 120)
(def one-earth-day 86400)
(def inbox-password "status-offline-inbox")
(def mailserver-password "status-offline-inbox")
(def default-network config/default-network)

View File

@ -1,5 +1,6 @@
(ns status-im.data-store.mailservers
(:require [re-frame.core :as re-frame]
(:require [cljs.tools.reader.edn :as edn]
[re-frame.core :as re-frame]
[status-im.data-store.realm.core :as core]))
(re-frame/reg-cofx
@ -27,3 +28,39 @@
(fn [realm]
(core/delete realm
(core/get-by-field realm :mailserver :id id))))
(defn deserialize-mailserver-topic [serialized-mailserver-topic]
(-> serialized-mailserver-topic
(dissoc :topic)
(update :chat-ids edn/read-string)))
(re-frame/reg-cofx
:data-store/mailserver-topics
(fn [cofx _]
(assoc cofx
:data-store/mailserver-topics
(reduce (fn [acc {:keys [topic] :as mailserver-topic}]
(assoc acc topic (deserialize-mailserver-topic mailserver-topic)))
{}
(-> @core/account-realm
(core/get-all :mailserver-topic)
(core/all-clj :mailserver-topic))))))
(defn save-mailserver-topic-tx
"Returns tx function for saving mailserver topic"
[{:keys [topic mailserver-topic]}]
(fn [realm]
(core/create realm
:mailserver-topic
(-> mailserver-topic
(assoc :topic topic)
(update :chat-ids pr-str))
true)))
(defn delete-mailserver-topic-tx
"Returns tx function for deleting mailserver topic"
[topic]
(fn [realm]
(let [mailserver-topic (core/single
(core/get-by-field realm :mailserver-topic :topic topic))]
(core/delete realm mailserver-topic))))

View File

@ -2,6 +2,7 @@
(:require [status-im.data-store.realm.schemas.account.chat :as chat]
[status-im.data-store.realm.schemas.account.transport :as transport]
[status-im.data-store.realm.schemas.account.transport-inbox-topic :as transport-inbox-topic]
[status-im.data-store.realm.schemas.account.mailserver-topic :as mailserver-topic]
[status-im.data-store.realm.schemas.account.contact :as contact]
[status-im.data-store.realm.schemas.account.message :as message]
[status-im.data-store.realm.schemas.account.user-status :as user-status]
@ -212,6 +213,19 @@
browser/v8
dapp-permissions/v9])
(def v22 [chat/v8
transport/v7
mailserver-topic/v1
contact/v2
message/v7
mailserver/v11
user-status/v1
membership-update/v1
installation/v2
local-storage/v1
browser/v8
dapp-permissions/v9])
;; put schemas ordered by version
(def schemas [{:schema v1
:schemaVersion 1
@ -275,4 +289,7 @@
:migration migrations/v20}
{:schema v21
:schemaVersion 21
:migration migrations/v21}])
:migration migrations/v21}
{:schema v22
:schemaVersion 22
:migration migrations/v22}])

View File

@ -0,0 +1,7 @@
(ns status-im.data-store.realm.schemas.account.mailserver-topic)
(def v1 {:name :mailserver-topic
:primaryKey :topic
:properties {:topic :string
:chat-ids :string
:last-request {:type :int :default 1}}})

View File

@ -130,3 +130,6 @@
(defn v21 [old-realm new-realm]
(log/debug "migrating v21 account database"))
(defn v22 [old-realm new-realm]
(log/debug "migrating v22 account database"))

View File

@ -52,6 +52,8 @@
extension/v12
account/v13])
(def v14 v13)
;; put schemas ordered by version
(def schemas [{:schema v1
:schemaVersion 1
@ -91,4 +93,7 @@
:migration migrations/v12}
{:schema v13
:schemaVersion 13
:migration migrations/v13}])
:migration migrations/v13}
{:schema v14
:schemaVersion 14
:migration migrations/v14}])

View File

@ -93,3 +93,18 @@
(defn v13 [old-realm new-realm]
(log/debug "migrating base database v13: " old-realm new-realm))
(defn v14
"Rename wnode to mailserver in account settings"
[old-realm new-realm]
(log/debug "migrating accounts schema v14")
(let [accounts (.objects new-realm "account")]
(dotimes [i (.-length accounts)]
(let [account (aget accounts i)
{:keys [wnode] :as old-settings} (deserialize (aget account "settings"))
new-settings (when wnode
(-> old-settings
(dissoc :wnode)
(assoc :mailserver wnode)))
updated (serialize new-settings)]
(aset account "settings" updated)))))

View File

@ -44,39 +44,3 @@
(let [transport (core/single
(core/get-by-field realm :transport :chat-id chat-id))]
(core/delete realm transport))))
(defn deserialize-inbox-topic [serialized-inbox-topic]
(-> serialized-inbox-topic
(dissoc :topic)
(update :chat-ids edn/read-string)))
(re-frame/reg-cofx
:data-store/transport-inbox-topics
(fn [cofx _]
(assoc cofx
:data-store/transport-inbox-topics
(reduce (fn [acc {:keys [topic] :as inbox-topic}]
(assoc acc topic (deserialize-inbox-topic inbox-topic)))
{}
(-> @core/account-realm
(core/get-all :transport-inbox-topic)
(core/all-clj :transport-inbox-topic))))))
(defn save-transport-inbox-topic-tx
"Returns tx function for saving transport inbox topic"
[{:keys [topic inbox-topic]}]
(fn [realm]
(core/create realm
:transport-inbox-topic
(-> inbox-topic
(assoc :topic topic)
(update :chat-ids pr-str))
true)))
(defn delete-transport-inbox-topic-tx
"Returns tx function for deleting transport inbox-topic"
[topic]
(fn [realm]
(let [transport-inbox-topic (core/single
(core/get-by-field realm :transport-inbox-topic :topic topic))]
(core/delete realm transport-inbox-topic))))

View File

@ -33,7 +33,6 @@
[status-im.qr-scanner.core :as qr-scanner]
[status-im.search.core :as search]
[status-im.signals.core :as signals]
[status-im.transport.inbox :as inbox]
[status-im.transport.message.core :as transport.message]
[status-im.ui.screens.currency-settings.models
:as
@ -99,7 +98,7 @@
(re-frame/inject-cofx :data-store/get-all-installations)
(re-frame/inject-cofx :data-store/get-all-mailservers)
(re-frame/inject-cofx :data-store/transport)
(re-frame/inject-cofx :data-store/transport-inbox-topics)
(re-frame/inject-cofx :data-store/mailserver-topics)
(re-frame/inject-cofx :data-store/all-browsers)
(re-frame/inject-cofx :data-store/all-dapp-permissions)]
(fn [cofx [_ address]]
@ -289,7 +288,7 @@
(handlers/register-handler-fx
:mailserver.ui/delete-confirmed
(fn [cofx [_ mailserver-id]]
(mailserver/delete mailserver-id cofx)))
(mailserver/delete cofx mailserver-id)))
(handlers/register-handler-fx
:mailserver.ui/delete-pressed
@ -311,6 +310,32 @@
(fn [cofx [_ current-fleet mailserver-id]]
(mailserver/save-settings cofx current-fleet mailserver-id)))
(handlers/register-handler-fx
:mailserver.ui/reconnect-mailserver-pressed
(fn [cofx [_ args]]
(mailserver/connect-to-mailserver cofx)))
(handlers/register-handler-fx
:mailserver/check-connection-timeout
(fn [cofx _]
(mailserver/check-connection cofx)))
(handlers/register-handler-fx
:mailserver.callback/generate-mailserver-symkey-success
(fn [cofx [_ mailserver sym-key-id]]
(mailserver/add-mailserver-sym-key cofx mailserver sym-key-id)))
(handlers/register-handler-fx
:mailserver.callback/mark-trusted-peer-success
(fn [cofx _]
(mailserver/add-mailserver-trusted cofx)))
(handlers/register-handler-fx
:mailserver.callback/mark-trusted-peer-error
(fn [cofx [_ error]]
(log/error "Error on mark-trusted-peer: " error)
(mailserver/check-connection cofx)))
;; network module
(handlers/register-handler-fx
@ -996,34 +1021,6 @@
(fn [cofx]
(browser/open-url cofx "names.statusnet.eth")))
;; inbox module
(handlers/register-handler-fx
:inbox.ui/reconnect-mailserver-pressed
(fn [cofx [_ args]]
(inbox/connect-to-mailserver cofx)))
(handlers/register-handler-fx
:inbox/check-connection-timeout
(fn [cofx _]
(inbox/check-connection cofx)))
(handlers/register-handler-fx
:inbox.callback/generate-mailserver-symkey-success
(fn [cofx [_ wnode sym-key-id]]
(inbox/add-mailserver-sym-key cofx wnode sym-key-id)))
(handlers/register-handler-fx
:inbox.callback/mark-trusted-peer-success
(fn [cofx _]
(inbox/add-mailserver-trusted cofx)))
(handlers/register-handler-fx
:inbox.callback/mark-trusted-peer-error
(fn [cofx [_ error]]
(log/error "Error on mark-trusted-peer: " error)
(inbox/check-connection cofx)))
;; transport module
(handlers/register-handler-fx

View File

@ -28,23 +28,23 @@
[(slurp "resources/config/fleets.json")
(slurp "resources/config/fleets-les.json")])))
(defn format-wnode
[wnode address]
{:id wnode
:name (name wnode)
:password constants/inbox-password
(defn format-mailserver
[mailserver address]
{:id mailserver
:name (name mailserver)
:password constants/mailserver-password
:address address})
(defn format-wnodes
[wnodes]
(reduce (fn [acc [wnode address]]
(assoc acc wnode (format-wnode wnode address)))
(defn format-mailservers
[mailservers]
(reduce (fn [acc [mailserver address]]
(assoc acc mailserver (format-mailserver mailserver address)))
{}
wnodes))
mailservers))
(def default-wnodes
(def default-mailservers
(reduce (fn [acc [fleet node-by-type]]
(assoc acc fleet (format-wnodes (:mail node-by-type))))
(assoc acc fleet (format-mailservers (:mail node-by-type))))
{}
fleets))

View File

@ -1,13 +1,485 @@
(ns status-im.mailserver.core
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
(ns ^{:doc "Mailserver events and API"}
status-im.mailserver.core
(:require [re-frame.core :as re-frame]
[status-im.accounts.db :as accounts.db]
[status-im.data-store.core :as data-store]
[status-im.fleet.core :as fleet]
[status-im.native-module.core :as status]
[status-im.transport.utils :as transport.utils]
[status-im.utils.fx :as fx]
[status-im.utils.utils :as utils]
[taoensso.timbre :as log]
[status-im.transport.db :as transport.db]
[clojure.string :as string]
[status-im.data-store.mailservers :as data-store.mailservers]
[status-im.i18n :as i18n]
[status-im.fleet.core :as fleet]
[status-im.accounts.update.core :as accounts.update]
[status-im.utils.fx :as fx]
[status-im.ui.screens.navigation :as navigation]))
;; How do mailserver work ?
;;
;; - We send a request to the mailserver, we are only interested in the
;; messages since `last-request` up to the last seven days
;; and the last 24 hours for topics that were just joined
;; - The mailserver doesn't directly respond to the request and
;; instead we start receiving messages in the filters for the requested
;; topics.
;; - If the mailserver was not ready when we tried for instance to request
;; the history of a topic after joining a chat, the request will be done
;; as soon as the mailserver becomes available
(def one-day (* 24 3600))
(def seven-days (* 7 one-day))
(def maximum-number-of-attempts 2)
(def request-timeout 30)
(def connection-timeout
"Time after which mailserver connection is considered to have failed"
10000)
(defn connected? [{:keys [db]} id]
(= (:mailserver/current-id db) id))
(defn fetch [{:keys [db] :as cofx} id]
(get-in db [:mailserver/mailservers (fleet/current-fleet db) id]))
(defn fetch-current [{:keys [db] :as cofx}]
(fetch cofx (:mailserver/current-id db)))
(defn preferred-mailserver-id [{:keys [db] :as cofx}]
(get-in db [:account/account :settings :mailserver (fleet/current-fleet db)]))
(defn- round-robin
"Find the choice and pick the next one, default to first if not found"
[choices current-id]
(let [next-index (reduce
(fn [index choice]
(if (= current-id choice)
(reduced (inc index))
(inc index)))
0
choices)]
(nth choices
(mod
next-index
(count choices)))))
(defn selected-or-random-id
"Use the preferred mailserver if set & exists, otherwise picks one randomly
if current-id is not set, else round-robin"
[{:keys [db] :as cofx}]
(let [current-fleet (fleet/current-fleet db)
current-id (:mailserver/current-id db)
preference (preferred-mailserver-id cofx)
choices (-> db :mailserver/mailservers current-fleet keys)]
(if (and preference
(fetch cofx preference))
preference
(if current-id
(round-robin choices current-id)
(rand-nth choices)))))
(fx/defn set-current-mailserver
[{:keys [db] :as cofx}]
{:db (assoc db :mailserver/current-id
(selected-or-random-id cofx))})
(fx/defn add-custom-mailservers
[{:keys [db]} mailservers]
{:db (reduce (fn [db {:keys [id fleet] :as mailserver}]
(assoc-in db [:mailserver/mailservers fleet id]
(-> mailserver
(dissoc :fleet)
(assoc :user-defined true))))
db
mailservers)})
(defn- parse-json
;; NOTE(dmitryn) Expects JSON response like:
;; {"error": "msg"} or {"result": true}
[s]
(try
(let [res (-> s
js/JSON.parse
(js->clj :keywordize-keys true))]
;; NOTE(dmitryn): AddPeer() may return {"error": ""}
;; assuming empty error is a success response
;; by transforming {"error": ""} to {:result true}
(if (and (:error res)
(= (:error res) ""))
{:result true}
res))
(catch :default e
{:error (.-message e)})))
(defn- response-handler [success-fn error-fn]
(fn handle-response
([response]
(let [{:keys [error result]} (parse-json response)]
(handle-response error result)))
([error result]
(if error
(error-fn error)
(success-fn result)))))
(defn add-peer! [enode]
(status/add-peer enode
(response-handler #(log/debug "mailserver: add-peer success" %)
#(log/error "mailserver: add-peer error" %))))
(defn remove-peer! [enode]
(let [args {:jsonrpc "2.0"
:id 2
:method "admin_removePeer"
:params [enode]}
payload (.stringify js/JSON (clj->js args))]
(status/call-private-rpc payload
(response-handler #(log/debug "mailserver: remove-peer success" %)
#(log/error "mailserver: remove-peer error" %)))))
(re-frame/reg-fx
:mailserver/add-peer
(fn [enode]
(add-peer! enode)))
(re-frame/reg-fx
:mailserver/remove-peer
(fn [enode]
(remove-peer! enode)))
(defn mark-trusted-peer! [web3 enode]
(.markTrustedPeer (transport.utils/shh web3)
enode
(fn [error response]
(if error
(re-frame/dispatch [:mailserver.callback/mark-trusted-peer-error error])
(re-frame/dispatch [:mailserver.callback/mark-trusted-peer-success response])))))
(re-frame/reg-fx
:mailserver/mark-trusted-peer
(fn [{:keys [address web3]}]
(mark-trusted-peer! web3 address)))
(fx/defn generate-mailserver-symkey
[{:keys [db] :as cofx} {:keys [password id] :as mailserver}]
(let [current-fleet (fleet/current-fleet db)]
{:db (assoc-in db [:mailserver/mailservers current-fleet id :generating-sym-key?] true)
:shh/generate-sym-key-from-password
[{:password password
:web3 (:web3 db)
:on-success (fn [_ sym-key-id]
(re-frame/dispatch [:mailserver.callback/generate-mailserver-symkey-success mailserver sym-key-id]))
:on-error #(log/error "mailserver: get-sym-key error" %)}]}))
(defn registered-peer?
"truthy if the enode is a registered peer"
[peers enode]
(let [peer-ids (into #{} (map :id) peers)
enode-id (transport.utils/extract-enode-id enode)]
(contains? peer-ids enode-id)))
(defn update-mailserver-state [db state]
(assoc db :mailserver/state state))
(fx/defn mark-trusted-peer
[{:keys [db] :as cofx}]
(let [{:keys [address sym-key-id generating-sym-key?] :as mailserver} (fetch-current cofx)]
(fx/merge cofx
{:db (update-mailserver-state db :added)
:mailserver/mark-trusted-peer {:web3 (:web3 db)
:address address}}
(when-not (or sym-key-id generating-sym-key?)
(generate-mailserver-symkey mailserver)))))
(fx/defn add-peer
[{:keys [db] :as cofx}]
(let [{:keys [address sym-key-id generating-sym-key?] :as mailserver} (fetch-current cofx)]
(fx/merge cofx
{:db (-> db
(update-mailserver-state :connecting)
(update :mailserver/connection-checks inc))
:mailserver/add-peer address
:utils/dispatch-later [{:ms connection-timeout
:dispatch [:mailserver/check-connection-timeout]}]}
(when-not (or sym-key-id generating-sym-key?)
(generate-mailserver-symkey mailserver)))))
(fx/defn connect-to-mailserver
"Add mailserver as a peer using `::add-peer` cofx and generate sym-key when
it doesn't exists
Peer summary will change and we will receive a signal from status go when
this is successful
A connection-check is made after `connection timeout` is reached and
mailserver-state is changed to error if it is not connected by then"
[{:keys [db] :as cofx}]
(let [{:keys [address] :as mailserver} (fetch-current cofx)
{:keys [peers-summary]} db
added? (registered-peer? peers-summary
address)]
(fx/merge cofx
{:db (dissoc db :mailserver/current-request)}
(if added?
(mark-trusted-peer)
(add-peer)))))
(fx/defn peers-summary-change
"There is only 2 summary changes that require mailserver action:
- mailserver disconnected: we try to reconnect
- mailserver connected: we mark the mailserver as trusted peer"
[{:keys [db] :as cofx} previous-summary]
(when (:account/account db)
(let [{:keys [peers-summary peers-count]} db
{:keys [address sym-key-id] :as mailserver} (fetch-current cofx)
mailserver-was-registered? (registered-peer? previous-summary
address)
mailserver-is-registered? (registered-peer? peers-summary
address)
mailserver-added? (and mailserver-is-registered?
(not mailserver-was-registered?))
mailserver-removed? (and mailserver-was-registered?
(not mailserver-is-registered?))]
(cond
mailserver-added?
(mark-trusted-peer cofx)
mailserver-removed?
(connect-to-mailserver cofx)))))
(defn request-messages! [web3 {:keys [sym-key-id address]} {:keys [topics to from]}]
(log/info "mailserver: request-messages for: "
" topics " topics
" from " from
" to " to)
(.requestMessages (transport.utils/shh web3)
(clj->js {:topics topics
:mailServerPeer address
:symKeyID sym-key-id
:timeout request-timeout
:from from
:to to})
(fn [error request-id]
(if-not error
(log/info "mailserver: messages request success for topic " topics "from" from "to" to)
(log/error "mailserver: messages request error for topic " topics ": " error)))))
(re-frame/reg-fx
:mailserver/request-messages
(fn [{:keys [web3 mailserver request]}]
(request-messages! web3 mailserver request)))
(defn get-mailserver-when-ready
"return the mailserver if the mailserver is ready"
[{:keys [db] :as cofx}]
(let [{:keys [sym-key-id] :as mailserver} (fetch-current cofx)
mailserver-state (:mailserver/state db)]
(when (and (= :connected mailserver-state)
sym-key-id)
mailserver)))
(defn split-request-per-day
"NOTE: currently the mailserver is only accepting requests for a span
of 24 hours, so we split requests per 24h spans if the last request was
done more than 24h ago"
[now-in-s [last-request topics]]
(let [days (conj
(into [] (range (max last-request
(- now-in-s one-day))
now-in-s
one-day))
now-in-s)
day-ranges (map vector days (rest days))]
(for [[from to] day-ranges]
{:topics topics
:from from
:to to})))
(defn prepare-messages-requests
[{:keys [db now] :as cofx} request-to]
(let [web3 (:web3 db)]
(remove nil?
(mapcat (partial split-request-per-day request-to)
(reduce (fn [acc [topic {:keys [last-request]}]]
(update acc last-request conj topic))
{}
(:mailserver/topics db))))))
(fx/defn process-next-messages-request
[{:keys [db now] :as cofx}]
(when (and (transport.db/all-filters-added? cofx)
(not (:mailserver/current-request db)))
(when-let [mailserver (get-mailserver-when-ready cofx)]
(let [request-to (or (:mailserver/request-to db)
(quot now 1000))
requests (prepare-messages-requests cofx request-to)
web3 (:web3 db)]
(if-let [request (first requests)]
{:db (assoc db
:mailserver/pending-requests (count requests)
:mailserver/current-request request
:mailserver/request-to request-to)
:mailserver/request-messages {:web3 web3
:mailserver mailserver
:request request}}
{:db (dissoc db
:mailserver/pending-requests
:mailserver/request-to)})))))
(fx/defn add-mailserver-trusted
"the current mailserver has been trusted
update mailserver status to `:connected` and request messages
if mailserver is ready"
[{:keys [db] :as cofx}]
(fx/merge cofx
{:db (update-mailserver-state db :connected)}
(process-next-messages-request)))
(fx/defn add-mailserver-sym-key
"the current mailserver sym-key has been generated
add sym-key to the mailserver in app-db and request messages if
mailserver is ready"
[{:keys [db] :as cofx} {:keys [id]} sym-key-id]
(let [current-fleet (fleet/current-fleet db)]
(fx/merge cofx
{:db (-> db
(assoc-in [:mailserver/mailservers current-fleet id :sym-key-id] sym-key-id)
(update-in [:mailserver/mailservers current-fleet id] dissoc :generating-sym-key?))}
(process-next-messages-request))))
(fx/defn change-mailserver
"mark mailserver status as `:error` if custom mailserver is used
otherwise try to reconnect to another mailserver"
[{:keys [db] :as cofx}]
(if (preferred-mailserver-id cofx)
{:db (update-mailserver-state db :error)}
(let [{:keys [address]} (fetch-current cofx)]
(fx/merge cofx
{:mailserver/remove-peer address}
(set-current-mailserver)
(connect-to-mailserver)))))
(fx/defn check-connection
"connection-checks counter is used to prevent changing
mailserver on flaky connections
if there is more than one connection check pending
decrement the connection check counter
else
change mailserver if mailserver is connected"
[{:keys [db] :as cofx}]
(if (zero? (dec (:mailserver/connection-checks db)))
(fx/merge cofx
{:db (dissoc db :mailserver/connection-checks)}
(when (= :connecting (:mailserver/state db))
(change-mailserver cofx)))
{:db (update db :mailserver/connection-checks dec)}))
(fx/defn reset-request-to
[{:keys [db]}]
{:db (dissoc db :mailserver/request-to)})
(fx/defn network-connection-status-changed
"when host reconnects, reset request-to and
reconnect to mailserver"
[{:keys [db] :as cofx} is-connected?]
(when (and (accounts.db/logged-in? cofx)
is-connected?)
(fx/merge cofx
(reset-request-to)
(connect-to-mailserver))))
(fx/defn remove-chat-from-mailserver-topic
"if the chat is the only chat of the mailserver topic delete the mailserver topic
and process-next-messages-requests again to remove pending request for that topic
otherwise remove the chat-id of the chat from the mailserver topic and save"
[{:keys [db now] :as cofx} chat-id]
(let [topic (get-in db [:transport/chats chat-id :topic])
{:keys [chat-ids] :as mailserver-topic} (update (get-in db [:mailserver/topics topic])
:chat-ids
disj chat-id)]
(if (empty? chat-ids)
(fx/merge cofx
{:db (update db :mailserver/topics dissoc topic)
:data-store/tx [(data-store.mailservers/delete-mailserver-topic-tx topic)]}
(process-next-messages-request))
{:db (assoc-in db [:mailserver/topics topic] mailserver-topic)
:data-store/tx [(data-store.mailservers/save-mailserver-topic-tx
{:topic topic
:mailserver-topic mailserver-topic})]})))
(defn get-updated-mailserver-topics [db topics last-request]
(reduce (fn [acc topic]
(if-let [mailserver-topic (some-> (get-in db [:mailserver/topics topic])
(assoc :last-request last-request))]
(assoc acc topic mailserver-topic)
acc))
{}
topics))
(fx/defn update-mailserver-topics
"TODO: add support for cursors
if there is a cursor, do not update `last-request`"
[{:keys [db now] :as cofx} {:keys [request-id]}]
(when-let [request (get db :mailserver/current-request)]
(let [{:keys [from to topics]} request
mailserver-topics (get-updated-mailserver-topics db topics to)]
(log/info "mailserver: message request " request-id
"completed for mailserver topics" topics "from" from "to" to)
(if (empty? mailserver-topics)
;; when topics were deleted (filter was removed while request was pending)
(fx/merge cofx
{:db (dissoc db :mailserver/current-request)}
(process-next-messages-request))
(fx/merge cofx
{:db (-> db
(dissoc :mailserver/current-request)
(update :mailserver/topics merge mailserver-topics))
:data-store/tx (mapv (fn [[topic mailserver-topic]]
(data-store.mailservers/save-mailserver-topic-tx
{:topic topic
:mailserver-topic mailserver-topic}))
mailserver-topics)}
(process-next-messages-request))))))
(fx/defn upsert-mailserver-topic
"if the topic didn't exist
create the topic
else if chat-id is not in the topic
add the chat-id to the topic and reset last-request
there was no filter for the chat and messages for that
so the whole history for that topic needs to be re-fetched"
[{:keys [db] :as cofx} {:keys [topic chat-id]}]
(let [{:keys [chat-ids last-request] :as current-mailserver-topic}
(get-in db [:mailserver/topics topic] {:chat-ids #{}})]
(when-let [mailserver-topic (when-not (chat-ids chat-id)
(-> current-mailserver-topic
(assoc :last-request 1)
(update :chat-ids conj chat-id)))]
(fx/merge cofx
{:db (assoc-in db [:mailserver/topics topic] mailserver-topic)
:data-store/tx [(data-store.mailservers/save-mailserver-topic-tx
{:topic topic
:mailserver-topic mailserver-topic})]}))))
(fx/defn resend-request
[{:keys [db] :as cofx} {:keys [request-id]}]
(if (<= maximum-number-of-attempts
(get-in db [:mailserver/current-request :attemps]))
(fx/merge cofx
{:db (update db :mailserver/current-request dissoc :attemps)}
(change-mailserver))
(when-let [mailserver (get-mailserver-when-ready cofx)]
(let [{:keys [topics from to] :as request} (get db :mailserver/current-request)
web3 (:web3 db)]
(log/info "mailserver: message request " request-id "expired for mailserver topic" topics "from" from "to" to)
{:db (update-in db [:mailserver/current-request :attemps] inc)
:mailserver/request-messages {:web3 web3
:mailserver mailserver
:request request}}))))
(fx/defn initialize-mailserver
[cofx custom-mailservers]
(fx/merge cofx
(add-custom-mailservers custom-mailservers)
(set-current-mailserver)))
(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})")
(def enode-url-regex #"enode://[a-zA-Z0-9]+:(.+)\@\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b:(\d{1,5})")
@ -30,7 +502,7 @@
(fx/defn set-input [{:keys [db]} input-key value]
{:db (update
db
:mailservers/manage
:mailserver.edit/mailserver
assoc
input-key
{:value value
@ -52,74 +524,8 @@
:id id
:name mailserver-name))
(defn connected? [{:keys [db]} id]
(= (:inbox/current-id db) id))
(defn fetch [{:keys [db] :as cofx} id]
(get-in db [:inbox/wnodes (fleet/current-fleet db) id]))
(defn fetch-current [{:keys [db] :as cofx}]
(fetch cofx (:inbox/current-id db)))
(defn preferred-mailserver-id [{:keys [db] :as cofx}]
(get-in db [:account/account :settings :wnode (fleet/current-fleet db)]))
(defn- round-robin
"Find the choice and pick the next one, default to first if not found"
[choices current-id]
(let [next-index (reduce
(fn [index choice]
(if (= current-id choice)
(reduced (inc index))
(inc index)))
0
choices)]
(nth choices
(mod
next-index
(count choices)))))
(defn selected-or-random-id
"Use the preferred mailserver if set & exists, otherwise picks one randomly
if current-id is not set, else round-robin"
[{:keys [db] :as cofx}]
(let [current-fleet (fleet/current-fleet db)
current-id (:inbox/current-id db)
preference (preferred-mailserver-id cofx)
choices (-> db :inbox/wnodes current-fleet keys)]
(if (and preference
(fetch cofx preference))
preference
(if current-id
(round-robin choices current-id)
(rand-nth choices)))))
(def default? (comp not :user-defined fetch))
(fx/defn delete
[{:keys [db] :as cofx} id]
(merge (when-not (or
(default? cofx id)
(connected? cofx id))
{:db (update-in db [:inbox/wnodes (fleet/current-fleet db)] dissoc id)
:data-store/tx [(data-store.mailservers/delete-tx id)]})
{:dispatch [:navigate-back]}))
(fx/defn set-current-mailserver
[{:keys [db] :as cofx}]
{:db (assoc db :inbox/current-id
(selected-or-random-id cofx))})
(fx/defn add-custom-mailservers
[{:keys [db]} mailservers]
{:db (reduce (fn [db {:keys [id fleet] :as mailserver}]
(assoc-in db [:inbox/wnodes fleet id]
(-> mailserver
(dissoc :fleet)
(assoc :user-defined true))))
db
mailservers)})
(fx/defn edit [{:keys [db] :as cofx} id]
(let [{:keys [id
address
@ -133,9 +539,9 @@
(navigation/navigate-to-cofx :edit-mailserver nil))))
(fx/defn upsert
[{{:mailservers/keys [manage] :account/keys [account] :as db} :db
[{{:mailserver.edit/keys [mailserver] :account/keys [account] :as db} :db
random-id-generator :random-id-generator :as cofx}]
(let [{:keys [name url id]} manage
(let [{:keys [name url id]} mailserver
current-fleet (fleet/current-fleet db)
mailserver (build
(or (:value id)
@ -144,8 +550,8 @@
(:value url))
current (connected? cofx (:id mailserver))]
{:db (-> db
(dissoc :mailservers/manage)
(assoc-in [:inbox/wnodes current-fleet (:id mailserver)] mailserver))
(dissoc :mailserver.edit/mailserver)
(assoc-in [:mailserver/mailservers current-fleet (:id mailserver)] mailserver))
:data-store/tx [{:transaction
(data-store.mailservers/save-tx (assoc
mailserver
@ -155,13 +561,22 @@
:success-event (when current [:accounts.logout.ui/logout-confirmed])}]
:dispatch [:navigate-back]}))
(fx/defn delete
[{:keys [db] :as cofx} id]
(merge (when-not (or
(default? cofx id)
(connected? cofx id))
{:db (update-in db [:mailserver/mailservers (fleet/current-fleet db)] dissoc id)
:data-store/tx [(data-store.mailservers/delete-tx id)]})
{:dispatch [:navigate-back]}))
(fx/defn show-connection-confirmation
[{:keys [db]} mailserver-id]
(let [current-fleet (fleet/current-fleet db)]
{:ui/show-confirmation
{:title (i18n/label :t/close-app-title)
:content (i18n/label :t/connect-wnode-content
{:name (get-in db [:inbox/wnodes current-fleet mailserver-id :name])})
:content (i18n/label :t/connect-mailserver-content
{:name (get-in db [:mailserver/mailservers current-fleet mailserver-id :name])})
:confirm-button-text (i18n/label :t/close-app-button)
:on-accept #(re-frame/dispatch [:mailserver.ui/connect-confirmed current-fleet mailserver-id])
:on-cancel nil}}))
@ -174,14 +589,18 @@
:confirm-button-text (i18n/label :t/delete-mailserver)
:on-accept #(re-frame/dispatch [:mailserver.ui/delete-confirmed mailserver-id])}})
(fx/defn save-settings
[{:keys [db] :as cofx} current-fleet mailserver-id]
(let [settings (get-in db [:account/account :settings])]
(accounts.update/update-settings cofx
(assoc-in settings [:wnode current-fleet] mailserver-id)
{:success-event [:accounts.update.callback/save-settings-success]})))
(fx/defn set-url-from-qr
[cofx url]
(assoc (set-input :url url cofx)
(assoc (set-input cofx :url url)
:dispatch [:navigate-back]))
(fx/defn save-settings
[{:keys [db] :as cofx} current-fleet mailserver-id]
(let [{:keys [address]} (fetch-current cofx)
settings (get-in db [:account/account :settings])]
(fx/merge cofx
{:db (assoc db :mailserver/current-id mailserver-id)
:mailserver/remove-peer address}
(connect-to-mailserver)
(accounts.update/update-settings (assoc-in settings [:mailserver current-fleet] mailserver-id)
{}))))

View File

@ -0,0 +1,42 @@
(ns status-im.mailserver.db
(:require [status-im.mailserver.core :as mailserver]
[cljs.spec.alpha :as spec]))
(spec/def :mailserver/state (spec/nilable #{:disconnected :connecting :added :connected :error}))
(spec/def :mailserver/current-id (spec/nilable keyword?))
(spec/def :mailserver/address (spec/and string? mailserver/valid-enode-address?))
(spec/def :mailserver/name :global/not-empty-string)
(spec/def :mailserver/id keyword?)
(spec/def :mailserver/user-defined boolean?)
(spec/def :mailserver/password :global/not-empty-string)
(spec/def :mailserver/sym-key-id string?)
(spec/def :mailserver/generating-sym-key? boolean?)
(spec/def :mailserver/mailserver (spec/keys :req-un [:mailserver/address :mailserver/name :mailserver/id]
:opt-un [:mailserver/sym-key-id
:mailserver/generating-sym-key?
:mailserver/user-defined
:mailserver/password]))
(spec/def :mailserver/mailservers (spec/nilable (spec/map-of keyword? (spec/map-of :mailserver/id :mailserver/mailserver))))
(spec/def :request/from pos-int?)
(spec/def :request/to pos-int?)
(spec/def :request/attemps int?)
(spec/def :request/cursor :global/not-empty-string)
(spec/def :mailserver.topic/last-request pos-int?)
(spec/def :mailserver.topic/started-at pos-int?)
(spec/def :mailserver.topic/chat-id (spec/or :keyword keyword?
:chat-id :global/not-empty-string))
(spec/def :mailserver.topic/chat-ids (spec/coll-of :mailserver.topic/chat-id
:kind set?
:min-count 1))
(spec/def :mailserver/topic (spec/keys :req-un [:mailserver.topic/last-request
:mailserver.topic/chat-ids]))
(spec/def :mailserver/request-to :request/to)
(spec/def :mailserver/connection-checks pos-int?)
(spec/def :mailserver/topics (spec/map-of :global/not-empty-string :mailserver/topic))
(spec/def :mailserver/current-request (spec/keys :req-un [:request/from :request/to ::topics]
:opt-un [:request/attemps]))
(spec/def :mailserver/pending-requests integer?)

View File

@ -0,0 +1,70 @@
(ns status-im.mailserver.subs
(:require [re-frame.core :as re-frame]))
(re-frame/reg-sub
:mailserver/state
(fn [db]
(get db :mailserver/state)))
(re-frame/reg-sub
:mailserver/pending-requests
(fn [db]
(get db :mailserver/pending-requests)))
(re-frame/reg-sub
:mailserver/fetching?
:<- [:mailserver/state]
:<- [:mailserver/pending-requests]
(fn [[state pending-requests]]
(when (and pending-requests
(= state :connected)
(pos-int? pending-requests))
pending-requests)))
(re-frame/reg-sub
:mailserver/error
:<- [:mailserver/state]
(fn [state]
(#{:error :disconnected} state)))
(re-frame/reg-sub
:mailserver/connected?
:<- [:mailserver/state]
(fn [state]
(= :connected state)))
(re-frame/reg-sub
:mailserver/current-id
(fn [db]
(:mailserver/current-id db)))
(re-frame/reg-sub
:mailserver/mailservers
(fn [db]
(:mailserver/mailservers db)))
(re-frame/reg-sub
:mailserver/fleet-mailservers
:<- [:settings/current-fleet]
:<- [:mailserver/mailservers]
(fn [[current-fleet mailservers]]
(current-fleet mailservers)))
(re-frame/reg-sub
:mailserver.edit/mailserver
(fn [db]
(get db :mailserver.edit/mailserver)))
(re-frame/reg-sub
:mailserver.edit/connected?
:<- [:mailserver.edit/mailserver]
:<- [:mailserver/current-id]
(fn [[mailserver current-mailserver-id]]
(= (get-in mailserver [:id :value])
current-mailserver-id)))
(re-frame/reg-sub
:mailserver.edit/valid?
:<- [:mailserver.edit/mailserver]
(fn [mailserver]
(not-any? :error (vals mailserver))))

View File

@ -5,7 +5,7 @@
[status-im.i18n :as i18n]
[status-im.native-module.core :as status]
[status-im.network.net-info :as net-info]
[status-im.transport.inbox :as inbox]
[status-im.mailserver.core :as mailserver]
[status-im.utils.ethereum.core :as ethereum]
[status-im.ui.screens.navigation :as navigation]
[status-im.fleet.core :as fleet-core]
@ -205,7 +205,7 @@
[{:keys [db] :as cofx} is-connected?]
(fx/merge cofx
{:db (assoc db :network-status (if is-connected? :online :offline))}
(inbox/network-connection-status-changed is-connected?)))
(mailserver/network-connection-status-changed is-connected?)))
(defn- navigate-to-network-details
[cofx network show-warning?]

View File

@ -2,7 +2,7 @@
(:require [re-frame.core :as re-frame]
[status-im.constants :as constants]
[status-im.transport.core :as transport]
[status-im.transport.inbox :as transport.inbox]
[status-im.mailserver.core :as mailserver]
[status-im.utils.ethereum.core :as ethereum]
[status-im.utils.fx :as fx]
[status-im.utils.semaphores :as semaphores]
@ -45,7 +45,7 @@
(semaphores/lock :check-sync-state?))))
(fx/defn initialize-protocol
[{:data-store/keys [transport transport-inbox-topics mailservers]
[{:data-store/keys [transport mailserver-topics mailservers]
:keys [db web3] :as cofx} address]
(let [network (get-in db [:account/account :network])
network-id (str (get-in db [:account/account :networks network :config :NetworkId]))]
@ -53,11 +53,11 @@
{:db (assoc db
:rpc-url constants/ethereum-rpc-url
:transport/chats transport
:transport.inbox/topics transport-inbox-topics)
:mailserver/topics mailserver-topics)
:protocol/assert-correct-network {:web3 web3
:network-id network-id}}
(start-check-sync-state)
(transport.inbox/initialize-offline-inbox mailservers)
(mailserver/initialize-mailserver mailservers)
(transport/init-whisper address))))
(fx/defn handle-close-app-confirmed

View File

@ -4,7 +4,7 @@
[status-im.init.core :as init]
[status-im.node.core :as node]
[status-im.pairing.core :as pairing]
[status-im.transport.inbox :as inbox]
[status-im.mailserver.core :as mailserver]
[status-im.transport.message.core :as transport.message]
[status-im.utils.fx :as fx]
[status-im.utils.types :as types]
@ -45,7 +45,7 @@
:peers-summary peers-summary
:peers-count peers-count)}
(transport.message/resend-contact-messages previous-summary)
(inbox/peers-summary-change previous-summary))))
(mailserver/peers-summary-change previous-summary))))
(fx/defn process
[cofx event-str]
@ -58,9 +58,9 @@
"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)
(inbox/update-inbox-topics cofx {:request-id (:requestID event)
:cursor (:cursor event)}))
(mailserver/update-mailserver-topics cofx {:request-id (:requestID event)
:cursor (:cursor event)}))
"mailserver.request.expired" (when (accounts.db/logged-in? cofx)
(inbox/resend-request cofx {:request-id (:hash event)}))
(mailserver/resend-request cofx {:request-id (:hash event)}))
"discovery.summary" (summary cofx event)
(log/debug "Event " type " not handled"))))

View File

@ -1,6 +1,6 @@
(ns status-im.transport.chat.core
(:require [status-im.data-store.transport :as transport-store]
[status-im.transport.inbox :as inbox]
[status-im.mailserver.core :as mailserver]
[status-im.utils.fx :as fx]))
(fx/defn remove-transport-chat
@ -14,5 +14,5 @@
"Unsubscribe from chat on transport layer"
[cofx chat-id]
(fx/merge cofx
(inbox/remove-chat-from-inbox-topic chat-id)
(mailserver/remove-chat-from-mailserver-topic chat-id)
(remove-transport-chat chat-id)))

View File

@ -4,7 +4,7 @@
[re-frame.core :as re-frame]
[status-im.constants :as constants]
[status-im.data-store.transport :as transport-store]
[status-im.transport.inbox :as inbox]
[status-im.mailserver.core :as mailserver]
[status-im.transport.message.core :as message]
[status-im.transport.shh :as shh]
[status-im.transport.utils :as transport.utils]
@ -16,7 +16,7 @@
"Initialises whisper protocol by:
- adding fixed shh discovery filter
- restoring existing symetric keys along with their unique filters
- (optionally) initializing offline inboxing"
- (optionally) initializing mailserver"
[{:keys [db web3] :as cofx} current-account-id]
(log/debug :init-whisper)
(when-let [public-key (get-in db [:account/account :public-key])]
@ -33,7 +33,7 @@
:shh/restore-sym-keys {:web3 web3
:transport (filter (comp :topic second) (:transport/chats db))
:on-success sym-key-added-callback}}
(inbox/connect-to-mailserver)
(mailserver/connect-to-mailserver)
(message/resend-contact-messages [])))))
;;TODO (yenda) remove once go implements persistence

View File

@ -3,8 +3,7 @@
(:require [cljs.spec.alpha :as spec]
[clojure.string :as s]
status-im.contact.db
[status-im.utils.clocks :as utils.clocks])
(:require-macros [status-im.utils.db :refer [allowed-keys]]))
[status-im.utils.clocks :as utils.clocks]))
;; required
(spec/def ::ack (spec/coll-of string? :kind vector?))
@ -22,35 +21,14 @@
(spec/def :transport/filter-id (spec/or :keyword keyword?
:chat-id :global/not-empty-string))
(spec/def :transport/filter any?)
(spec/def :request/from pos-int?)
(spec/def :request/to pos-int?)
(spec/def :request/attemps int?)
(spec/def :request/cursor :global/not-empty-string)
(spec/def :pairing/installation-id :global/not-empty-string)
(spec/def :pairing/device-type :global/not-empty-string)
(spec/def :transport.inbox.topic/last-request pos-int?)
(spec/def :transport.inbox.topic/started-at pos-int?)
(spec/def :transport.inbox.topic/chat-id (spec/or :keyword keyword?
:chat-id :global/not-empty-string))
(spec/def :transport.inbox.topic/chat-ids (spec/coll-of :transport.inbox.topic/chat-id
:kind set?
:min-count 1))
(spec/def :transport.inbox/topic (spec/keys :req-un [:transport.inbox.topic/last-request
:transport.inbox.topic/chat-ids]))
(spec/def :transport/chat (spec/keys :req-un [::ack ::seen ::pending-ack ::pending-send ::topic]
:opt-un [::sym-key-id ::sym-key ::resend?]))
(spec/def :transport.inbox/request-to :request/to)
(spec/def :transport/chats (spec/map-of :global/not-empty-string :transport/chat))
(spec/def :transport/filters (spec/map-of :transport/filter-id :transport/filter))
(spec/def :transport.inbox/connection-checks pos-int?)
(spec/def :transport.inbox/topics (spec/map-of :global/not-empty-string :transport.inbox/topic))
(spec/def :transport.inbox/current-request (spec/keys :req-un [:request/from :request/to ::topics]
:opt-un [:request/attemps]))
(spec/def :transport.inbox/pending-requests integer?)
(defn create-chat
"Initialize datastructure for chat representation at the transport level

View File

@ -1,7 +1,7 @@
(ns ^{:doc "API for whisper filters"}
status-im.transport.filters
(:require [re-frame.core :as re-frame]
[status-im.transport.inbox :as inbox]
[status-im.mailserver.core :as mailserver]
[status-im.transport.utils :as utils]
[status-im.utils.fx :as fx]
[status-im.utils.handlers :as handlers]
@ -55,10 +55,10 @@
(fn [{:keys [db] :as cofx} [_ topic chat-id filter]]
(fx/merge cofx
{:db (assoc-in db [:transport/filters chat-id] filter)}
(inbox/reset-request-to)
(inbox/upsert-inbox-topic {:topic topic
:chat-id chat-id})
(inbox/process-next-messages-request))))
(mailserver/reset-request-to)
(mailserver/upsert-mailserver-topic {:topic topic
:chat-id chat-id})
(mailserver/process-next-messages-request))))
(handlers/register-handler-fx
:shh.callback/filter-removed

View File

@ -1,405 +0,0 @@
(ns ^{:doc "Offline inboxing events and API"}
status-im.transport.inbox
(:require [re-frame.core :as re-frame]
[status-im.accounts.db :as accounts.db]
[status-im.data-store.core :as data-store]
[status-im.data-store.transport :as transport-store]
[status-im.fleet.core :as fleet]
[status-im.mailserver.core :as mailserver]
[status-im.native-module.core :as status]
[status-im.transport.utils :as transport.utils]
[status-im.utils.fx :as fx]
[status-im.utils.utils :as utils]
[taoensso.timbre :as log]
[status-im.transport.db :as transport.db]))
;; How does offline inboxing work ?
;;
;; - We send a request to the mailserver, we are only interested in the
;; messages since `last-request` up to the last seven days
;; and the last 24 hours for topics that were just joined
;; - The mailserver doesn't directly respond to the request and
;; instead we start receiving messages in the filters for the requested
;; topics.
;; - If the mailserver was not ready when we tried for instance to request
;; the history of a topic after joining a chat, the request will be done
;; as soon as the mailserver becomes available
(def one-day (* 24 3600))
(def seven-days (* 7 one-day))
(def maximum-number-of-attempts 2)
(def request-timeout 30)
(def connection-timeout
"Time after which mailserver connection is considered to have failed"
10000)
(defn- parse-json
;; NOTE(dmitryn) Expects JSON response like:
;; {"error": "msg"} or {"result": true}
[s]
(try
(let [res (-> s
js/JSON.parse
(js->clj :keywordize-keys true))]
;; NOTE(dmitryn): AddPeer() may return {"error": ""}
;; assuming empty error is a success response
;; by transforming {"error": ""} to {:result true}
(if (and (:error res)
(= (:error res) ""))
{:result true}
res))
(catch :default e
{:error (.-message e)})))
(defn- response-handler [success-fn error-fn]
(fn handle-response
([response]
(let [{:keys [error result]} (parse-json response)]
(handle-response error result)))
([error result]
(if error
(error-fn error)
(success-fn result)))))
(defn add-peer! [wnode]
(status/add-peer wnode
(response-handler #(log/debug "offline inbox: add-peer success" %)
#(log/error "offline inbox: add-peer error" %))))
(re-frame/reg-fx
:transport.inbox/add-peer
(fn [wnode]
(add-peer! wnode)))
(defn mark-trusted-peer! [web3 enode]
(.markTrustedPeer (transport.utils/shh web3)
enode
(fn [error response]
(if error
(re-frame/dispatch [:inbox.callback/mark-trusted-peer-error error])
(re-frame/dispatch [:inbox.callback/mark-trusted-peer-success response])))))
(re-frame/reg-fx
:transport.inbox/mark-trusted-peer
(fn [{:keys [wnode web3]}]
(mark-trusted-peer! web3 wnode)))
(fx/defn generate-mailserver-symkey
[{:keys [db] :as cofx} {:keys [password id] :as wnode}]
(let [current-fleet (fleet/current-fleet db)]
{:db (assoc-in db [:inbox/wnodes current-fleet id :generating-sym-key?] true)
:shh/generate-sym-key-from-password
[{:password password
:web3 (:web3 db)
:on-success (fn [_ sym-key-id]
(re-frame/dispatch [:inbox.callback/generate-mailserver-symkey-success wnode sym-key-id]))
:on-error #(log/error "offline inbox: get-sym-key error" %)}]}))
(defn registered-peer?
"truthy if the enode is a registered peer"
[peers enode]
(let [peer-ids (into #{} (map :id) peers)
enode-id (transport.utils/extract-enode-id enode)]
(contains? peer-ids enode-id)))
(defn update-mailserver-status [db state]
(assoc db :mailserver-status state))
(fx/defn mark-trusted-peer
[{:keys [db] :as cofx}]
(let [{:keys [address sym-key-id generating-sym-key?] :as wnode} (mailserver/fetch-current cofx)]
(fx/merge cofx
{:db (update-mailserver-status db :added)
:transport.inbox/mark-trusted-peer {:web3 (:web3 db)
:wnode address}}
(when-not (or sym-key-id generating-sym-key?)
(generate-mailserver-symkey wnode)))))
(fx/defn add-peer
[{:keys [db] :as cofx}]
(let [{:keys [address sym-key-id generating-sym-key?] :as wnode} (mailserver/fetch-current cofx)]
(fx/merge cofx
{:db (-> db
(update-mailserver-status :connecting)
(update :transport.inbox/connection-checks inc))
:transport.inbox/add-peer address
:utils/dispatch-later [{:ms connection-timeout
:dispatch [:inbox/check-connection-timeout]}]}
(when-not (or sym-key-id generating-sym-key?)
(generate-mailserver-symkey wnode)))))
(fx/defn connect-to-mailserver
"Add mailserver as a peer using `::add-peer` cofx and generate sym-key when
it doesn't exists
Peer summary will change and we will receive a signal from status go when
this is successful
A connection-check is made after `connection timeout` is reached and
mailserver-status is changed to error if it is not connected by then"
[{:keys [db] :as cofx}]
(let [{:keys [address] :as wnode} (mailserver/fetch-current cofx)
{:keys [peers-summary]} db
added? (registered-peer? peers-summary
address)]
(fx/merge cofx
{:db (dissoc db :transport.inbox/current-request)}
(if added?
(mark-trusted-peer)
(add-peer)))))
(fx/defn peers-summary-change
"There is only 2 summary changes that require offline inboxing action:
- mailserver disconnected: we try to reconnect
- mailserver connected: we mark the mailserver as trusted peer"
[{:keys [db] :as cofx} previous-summary]
(when (:account/account db)
(let [{:keys [peers-summary peers-count]} db
{:keys [address sym-key-id] :as wnode} (mailserver/fetch-current cofx)
mailserver-was-registered? (registered-peer? previous-summary
address)
mailserver-is-registered? (registered-peer? peers-summary
address)
mailserver-added? (and mailserver-is-registered?
(not mailserver-was-registered?))
mailserver-removed? (and mailserver-was-registered?
(not mailserver-is-registered?))]
(cond
mailserver-added?
(mark-trusted-peer cofx)
mailserver-removed?
(connect-to-mailserver cofx)))))
(defn request-messages! [web3 {:keys [sym-key-id address]} {:keys [topics to from]}]
(log/info "offline inbox: request-messages for: "
" topics " topics
" from " from
" to " to)
(.requestMessages (transport.utils/shh web3)
(clj->js {:topics topics
:mailServerPeer address
:symKeyID sym-key-id
:timeout request-timeout
:from from
:to to})
(fn [error request-id]
(if-not error
(log/info "offline inbox: messages request success for topic " topics "from" from "to" to)
(log/error "offline inbox: messages request error for topic " topics ": " error)))))
(re-frame/reg-fx
:transport.inbox/request-messages
(fn [{:keys [web3 wnode request]}]
(request-messages! web3 wnode request)))
(defn get-wnode-when-ready
"return the wnode if the inbox is ready"
[{:keys [db] :as cofx}]
(let [{:keys [sym-key-id] :as wnode} (mailserver/fetch-current cofx)
mailserver-status (:mailserver-status db)]
(when (and (= :connected mailserver-status)
sym-key-id)
wnode)))
(defn split-request-per-day
"NOTE: currently the mailserver is only accepting requests for a span
of 24 hours, so we split requests per 24h spans if the last request was
done more than 24h ago"
[now-in-s [last-request topics]]
(let [days (conj
(into [] (range (max last-request
(- now-in-s one-day))
now-in-s
one-day))
now-in-s)
day-ranges (map vector days (rest days))]
(for [[from to] day-ranges]
{:topics topics
:from from
:to to})))
(defn prepare-messages-requests
[{:keys [db now] :as cofx} request-to]
(let [web3 (:web3 db)]
(remove nil?
(mapcat (partial split-request-per-day request-to)
(reduce (fn [acc [topic {:keys [last-request]}]]
(update acc last-request conj topic))
{}
(:transport.inbox/topics db))))))
(fx/defn process-next-messages-request
[{:keys [db now] :as cofx}]
(when (and (transport.db/all-filters-added? cofx)
(not (:transport.inbox/current-request db)))
(when-let [wnode (get-wnode-when-ready cofx)]
(let [request-to (or (:transport.inbox/request-to db)
(quot now 1000))
requests (prepare-messages-requests cofx request-to)
web3 (:web3 db)]
(if-let [request (first requests)]
{:db (assoc db
:transport.inbox/pending-requests (count requests)
:transport.inbox/current-request request
:transport.inbox/request-to request-to)
:transport.inbox/request-messages {:web3 web3
:wnode wnode
:request request}}
{:db (dissoc db
:transport.inbox/pending-requests
:transport.inbox/request-to)})))))
(fx/defn add-mailserver-trusted
"the current mailserver has been trusted
update mailserver status to `:connected` and request messages
if wnode is ready"
[{:keys [db] :as cofx}]
(fx/merge cofx
{:db (update-mailserver-status db :connected)}
(process-next-messages-request)))
(fx/defn add-mailserver-sym-key
"the current mailserver sym-key has been generated
add sym-key to the wnode in app-db and request messages if
wnode is ready"
[{:keys [db] :as cofx} {:keys [id]} sym-key-id]
(let [current-fleet (fleet/current-fleet db)]
(fx/merge cofx
{:db (-> db
(assoc-in [:inbox/wnodes current-fleet id :sym-key-id] sym-key-id)
(update-in [:inbox/wnodes current-fleet id] dissoc :generating-sym-key?))}
(process-next-messages-request))))
(fx/defn change-mailserver
"mark mailserver status as `:error` if custom mailserver is used
otherwise try to reconnect to another mailserver"
[{:keys [db] :as cofx}]
(if (mailserver/preferred-mailserver-id cofx)
{:db (update-mailserver-status db :error)}
(fx/merge cofx
(mailserver/set-current-mailserver)
(connect-to-mailserver))))
(fx/defn check-connection
"connection-checks counter is used to prevent changing
mailserver on flaky connections
if there is more than one connection check pending
decrement the connection check counter
else
change mailserver if mailserver is connected"
[{:keys [db] :as cofx}]
(if (zero? (dec (:transport.inbox/connection-checks db)))
(fx/merge cofx
{:db (dissoc db :transport.inbox/connection-checks)}
(when (= :connecting (:mailserver-status db))
(change-mailserver cofx)))
{:db (update db :transport.inbox/connection-checks dec)}))
(fx/defn reset-request-to
[{:keys [db]}]
{:db (dissoc db :transport.inbox/request-to)})
(fx/defn network-connection-status-changed
"when host reconnects, reset request-to and
reconnect to mailserver"
[{:keys [db] :as cofx} is-connected?]
(when (and (accounts.db/logged-in? cofx)
is-connected?)
(fx/merge cofx
(reset-request-to)
(connect-to-mailserver))))
(fx/defn remove-chat-from-inbox-topic
"if the chat is the only chat of the inbox topic delete the inbox topic
and process-next-messages-requests again to remove pending request for that topic
otherwise remove the chat-id of the chat from the inbox topic and save"
[{:keys [db now] :as cofx} chat-id]
(let [topic (get-in db [:transport/chats chat-id :topic])
{:keys [chat-ids] :as inbox-topic} (update (get-in db [:transport.inbox/topics topic])
:chat-ids
disj chat-id)]
(if (empty? chat-ids)
(fx/merge cofx
{:db (update db :transport.inbox/topics dissoc topic)
:data-store/tx [(transport-store/delete-transport-inbox-topic-tx topic)]}
(process-next-messages-request))
{:db (assoc-in db [:transport.inbox/topics topic] inbox-topic)
:data-store/tx [(transport-store/save-transport-inbox-topic-tx
{:topic topic
:inbox-topic inbox-topic})]})))
(defn get-updated-inbox-topics [db topics last-request]
(reduce (fn [acc topic]
(if-let [inbox-topic (some-> (get-in db [:transport.inbox/topics topic])
(assoc :last-request last-request))]
(assoc acc topic inbox-topic)
acc))
{}
topics))
(fx/defn update-inbox-topics
"TODO: add support for cursors
if there is a cursor, do not update `last-request`"
[{:keys [db now] :as cofx} {:keys [request-id]}]
(when-let [request (get db :transport.inbox/current-request)]
(let [{:keys [from to topics]} request
inbox-topics (get-updated-inbox-topics db topics to)]
(log/info "offline inbox: message request " request-id
"completed for inbox topics" topics "from" from "to" to)
(if (empty? inbox-topics)
;; when topics were deleted (filter was removed while request was pending)
(fx/merge cofx
{:db (dissoc db :transport.inbox/current-request)}
(process-next-messages-request))
(fx/merge cofx
{:db (-> db
(dissoc :transport.inbox/current-request)
(update :transport.inbox/topics merge inbox-topics))
:data-store/tx (mapv (fn [[topic inbox-topic]]
(transport-store/save-transport-inbox-topic-tx
{:topic topic
:inbox-topic inbox-topic}))
inbox-topics)}
(process-next-messages-request))))))
(fx/defn upsert-inbox-topic
"if the topic didn't exist
create the topic
else if chat-id is not in the topic
add the chat-id to the topic and reset last-request
there was no filter for the chat and messages for that
so the whole history for that topic needs to be re-fetched"
[{:keys [db] :as cofx} {:keys [topic chat-id]}]
(let [{:keys [chat-ids last-request] :as current-inbox-topic}
(get-in db [:transport.inbox/topics topic] {:chat-ids #{}})]
(when-let [inbox-topic (when-not (chat-ids chat-id)
(-> current-inbox-topic
(assoc :last-request 1)
(update :chat-ids conj chat-id)))]
(fx/merge cofx
{:db (assoc-in db [:transport.inbox/topics topic] inbox-topic)
:data-store/tx [(transport-store/save-transport-inbox-topic-tx
{:topic topic
:inbox-topic inbox-topic})]}))))
(fx/defn resend-request
[{:keys [db] :as cofx} {:keys [request-id]}]
(if (<= maximum-number-of-attempts
(get-in db [:transport.inbox/current-request :attemps]))
(fx/merge cofx
{:db (update db :transport.inbox/current-request dissoc :attemps)}
(change-mailserver))
(when-let [wnode (get-wnode-when-ready cofx)]
(let [{:keys [topics from to] :as request} (get db :transport.inbox/current-request)
web3 (:web3 db)]
(log/info "offline inbox: message request " request-id "expired for inbox topic" topics "from" from "to" to)
{:db (update-in db [:transport.inbox/current-request :attemps] inc)
:transport.inbox/request-messages {:web3 web3
:wnode wnode
:request request}}))))
(fx/defn initialize-offline-inbox
[cofx custom-mailservers]
(fx/merge cofx
(mailserver/add-custom-mailservers custom-mailservers)
(mailserver/set-current-mailserver)))

View File

@ -7,8 +7,7 @@
[status-im.i18n :as i18n]))
(defview error-label
[{:keys [view-id label fetching? mailserver-error?] :as opts}]
[{:keys [view-id label mailserver-fetching? mailserver-error?] :as opts}]
{:should-component-update
(fn [_ [_ old-props] [_ new-props]]
;; prevents flickering on navigation
@ -19,16 +18,17 @@
:accessibility-label :connection-status-text}
[react/text {:style styles/text
:on-press (when mailserver-error?
#(re-frame/dispatch [:inbox.ui/reconnect-mailserver-pressed]))}
(if (and (not mailserver-error?) fetching?)
(i18n/label :t/fetching-messages {:requests-left (str fetching?)})
#(re-frame/dispatch [:mailserver.ui/reconnect-mailserver-pressed]))}
(if (and (not mailserver-error?)
mailserver-fetching?)
(i18n/label :t/fetching-messages {:requests-left (str mailserver-fetching?)})
(i18n/label label))]]))
(defview error-view [{:keys [top]}]
(letsubs [offline? [:offline?]
disconnected? [:disconnected?]
mailserver-error? [:mailserver-error?]
fetching? [:fetching?]
mailserver-error? [:mailserver/error]
mailserver-fetching? [:mailserver/fetching?]
current-chat-contact [:get-current-chat-contact]
view-id [:get :view-id]
window-width [:dimensions/window-width]]
@ -36,14 +36,14 @@
offline? :t/offline
disconnected? :t/disconnected
mailserver-error? :t/mailserver-reconnect
fetching? :t/fetching-messages
mailserver-fetching? :t/fetching-messages
:else nil)]
(let [pending? (and (:pending current-chat-contact) (= :chat view-id))]
[error-label
{:view-id view-id
:top top
:window-width window-width
:pending? pending?
:label label
:fetching? fetching?
:mailserver-error? mailserver-error?}]))))
{:view-id view-id
:top top
:window-width window-width
:pending? pending?
:label label
:mailserver-fetching? mailserver-fetching?
:mailserver-error? mailserver-error?}]))))

View File

@ -83,9 +83,9 @@
:icons/tooltip-triangle (js/require "./resources/icons/tooltip-triangle.svg")
:icons/open (js/require "./resources/icons/open.svg")
:icons/network (js/require "./resources/icons/network.svg")
:icons/wnode (js/require "./resources/icons/wnode.svg")
:icons/log-level (js/require "./resources/icons/wnode.svg")
:icons/fleet (js/require "./resources/icons/wnode.svg")
:icons/mailserver (js/require "./resources/icons/mailserver.svg")
:icons/log-level (js/require "./resources/icons/mailserver.svg")
:icons/fleet (js/require "./resources/icons/mailserver.svg")
:icons/refresh (js/require "./resources/icons/refresh.svg")
:icons/newchat (js/require "./resources/icons/newchat.svg")
:icons/logo (js/require "./resources/icons/logo.svg")
@ -155,9 +155,9 @@
:icons/tooltip-triangle (components.svg/slurp-svg "./resources/icons/tooltip-triangle.svg")
:icons/open (components.svg/slurp-svg "./resources/icons/open.svg")
:icons/network (components.svg/slurp-svg "./resources/icons/network.svg")
:icons/wnode (components.svg/slurp-svg "./resources/icons/wnode.svg")
:icons/log-level (components.svg/slurp-svg "./resources/icons/wnode.svg")
:icons/fleet (components.svg/slurp-svg "./resources/icons/wnode.svg")
:icons/mailserver (components.svg/slurp-svg "./resources/icons/mailserver.svg")
:icons/log-level (components.svg/slurp-svg "./resources/icons/mailserver.svg")
:icons/fleet (components.svg/slurp-svg "./resources/icons/mailserver.svg")
:icons/refresh (components.svg/slurp-svg "./resources/icons/refresh.svg")
:icons/newchat (components.svg/slurp-svg "./resources/icons/newchat.svg")
:icons/logo (components.svg/slurp-svg "./resources/icons/logo.svg")

View File

@ -25,7 +25,7 @@
(letsubs [{:keys [command-completion]} [:selected-chat-command]
{:keys [input-text seq-arg-input-text]} [:get-current-chat]
network-status [:network-status]
mailserver-connected? [:mailserver-connected?]
mailserver-connected? [:mailserver/connected?]
spin-value (animation/create-value 1)]
{:component-did-update (send-button-view-on-update {:spin-value spin-value
:command-completion command-completion})}

View File

@ -14,7 +14,7 @@
status-im.chat.specs
status-im.ui.screens.profile.db
status-im.ui.screens.network-settings.db
status-im.ui.screens.offline-messaging-settings.db
status-im.mailserver.db
status-im.browser.db
status-im.ui.screens.add-new.db
status-im.ui.screens.add-new.new-public-chat.db))
@ -47,13 +47,13 @@
:semaphores #{}
:network constants/default-network
:networks/networks constants/default-networks
:inbox/wnodes fleet/default-wnodes
:my-profile/editing? false
:transport/chats {}
:transport/filters {}
:transport/message-envelopes {}
:transport.inbox/topics {}
:transport.inbox/pending-requests 0
:mailserver/mailservers fleet/default-mailservers
:mailserver/topics {}
:mailserver/pending-requests 0
:chat/cooldowns 0
:chat/cooldown-enabled? false
:chat/last-outgoing-message-sent-at 0
@ -93,8 +93,6 @@
;;:online - presence of internet connection in the phone
(spec/def ::network-status (spec/nilable keyword?))
(spec/def ::mailserver-status (spec/nilable #{:disconnected :connecting :added :connected :error}))
(spec/def ::app-state string?)
;;;;NODE
@ -156,7 +154,6 @@
(spec/def ::chain (spec/nilable string?))
(spec/def ::peers-count (spec/nilable integer?))
(spec/def ::peers-summary (spec/nilable vector?))
(spec/def :inbox/current-id (spec/nilable keyword?))
(spec/def ::collectible (spec/nilable map?))
(spec/def ::collectibles (spec/nilable map?))
@ -217,11 +214,8 @@
:networks/selected-network
:networks/networks
:networks/manage
:mailservers/manage
:bootnodes/manage
:extensions/manage
:inbox/wnodes
:inbox/current-id
:node/status
:node/restart?
:node/address
@ -238,11 +232,15 @@
:transport/message-envelopes
:transport/chats
:transport/filters
:transport.inbox/topics
:transport.inbox/pending-requests
:transport.inbox/current-request
:transport.inbox/connection-checks
:transport.inbox/request-to
:mailserver.edit/mailserver
:mailserver/mailservers
:mailserver/current-id
:mailserver/state
:mailserver/topics
:mailserver/pending-requests
:mailserver/current-request
:mailserver/connection-checks
:mailserver/request-to
:desktop/desktop
:dimensions/window
:dapps/permissions
@ -263,7 +261,6 @@
::keyboard-max-height
::tab-bar-visible?
::network-status
::mailserver-status
::peers-count
::peers-summary
::sync-state

View File

@ -296,7 +296,7 @@
(views/defview chat-text-input [chat-id input-text]
(views/letsubs [inp-ref (atom nil)
network-status [:network-status]
mailserver-connected? [:mailserver-connected?]]
mailserver-connected? [:mailserver/connected?]]
{:component-will-update
(fn [e [_ new-chat-id new-input-text]]
(let [[_ old-chat-id] (.. e -props -argv)]

View File

@ -89,10 +89,10 @@
[pairing.views/render-row installation]])])
(views/defview advanced-settings []
(views/letsubs [current-wnode-id [:settings/current-wnode]
installations [:pairing/installations]
wnodes [:settings/fleet-wnodes]]
(let [render-fn (offline-messaging.views/render-row current-wnode-id)]
(views/letsubs [installations [:pairing/installations]
current-mailserver-id [:mailserver/current-id]
mailservers [:mailserver/fleet-mailservers]]
(let [render-fn (offline-messaging.views/render-row current-mailserver-id)]
[react/scroll-view
[react/text {:style styles/advanced-settings-title
:font :medium}
@ -100,10 +100,10 @@
[react/view {:style styles/title-separator}]
[react/text {:style styles/mailserver-title} (i18n/label :offline-messaging)]
[react/view
(for [node (vals wnodes)]
^{:key (:id node)}
(for [mailserver (vals mailservers)]
^{:key (:id mailserver)}
[react/view {:style {:margin-vertical 8}}
[render-fn node]])]
[render-fn mailserver]])]
(when (config/pairing-enabled? true)
(installations-section installations))])))

View File

@ -26,7 +26,7 @@
[re-frame.core :as re-frame]
[status-im.hardwallet.core :as hardwallet]
[status-im.native-module.core :as status]
[status-im.transport.inbox :as inbox]
[status-im.mailserver.core :as mailserver]
[status-im.ui.components.permissions :as permissions]
[status-im.utils.dimensions :as dimensions]
[status-im.utils.handlers :as handlers]
@ -118,7 +118,7 @@
(fx/defn on-return-from-background [cofx]
(fx/merge cofx
(inbox/process-next-messages-request)
(mailserver/process-next-messages-request)
(hardwallet/return-back-from-nfc-settings)))
(defn app-state-change [state {:keys [db] :as cofx}]

View File

@ -25,7 +25,7 @@
:line-height 20}
:android {:font-size 16}})
(defn wnode-icon [connected?]
(defn mailserver-icon [connected?]
{:width 40
:height 40
:border-radius 20
@ -38,4 +38,3 @@
(def empty-list
{:color colors/black
:text-align :center})

View File

@ -10,16 +10,16 @@
[status-im.ui.components.toolbar.actions :as toolbar.actions]
[status-im.ui.screens.extensions.styles :as styles]))
(def wnode-icon
[react/view (styles/wnode-icon true)
[vector-icons/icon :icons/wnode {:color :white}]])
(def mailserver-icon
[react/view (styles/mailserver-icon true)
[vector-icons/icon :icons/mailserver {:color :white}]])
(defn- render-extension [{:keys [id name url active?]}]
[list/list-item-with-checkbox
{:checked? active?
:on-value-change #(re-frame/dispatch [:extensions.ui/activation-checkbox-pressed id %])}
[list/item
wnode-icon
mailserver-icon
[list/item-content
[list/item-primary name]
[list/item-secondary url]]]])

View File

@ -1,22 +0,0 @@
(ns status-im.ui.screens.offline-messaging-settings.db
(:require-macros [status-im.utils.db :refer [allowed-keys]])
(:require
[status-im.mailserver.core :as mailserver]
[cljs.spec.alpha :as spec]))
(spec/def ::not-blank-string (spec/and string? seq))
(spec/def :wnode/address (spec/and string? mailserver/valid-enode-address?))
(spec/def :wnode/name ::not-blank-string)
(spec/def :wnode/id keyword?)
(spec/def :wnode/user-defined boolean?)
(spec/def :wnode/password ::not-blank-string)
(spec/def :wnode/sym-key-id string?)
(spec/def :wnode/generating-sym-key? boolean?)
(spec/def :wnode/wnode (allowed-keys :req-un [:wnode/address :wnode/name :wnode/id]
:opt-un [:wnode/sym-key-id
:wnode/generating-sym-key?
:wnode/user-defined
:wnode/password]))
(spec/def :inbox/wnodes (spec/nilable (spec/map-of keyword? (spec/map-of :wnode/id :wnode/wnode))))

View File

@ -1,22 +0,0 @@
(ns status-im.ui.screens.offline-messaging-settings.edit-mailserver.subs
(:require
[re-frame.core :refer [reg-sub]]
[status-im.mailserver.core :as mailserver]))
(reg-sub
:get-manage-mailserver
:<- [:get :mailservers/manage]
(fn [manage]
manage))
(reg-sub
:get-connected-mailserver
(fn [db]
(mailserver/connected? (get-in db [:mailservers/manage :id :value])
{:db db})))
(reg-sub
:manage-mailserver-valid?
:<- [:get-manage-mailserver]
(fn [manage]
(not-any? :error (vals manage))))

View File

@ -42,12 +42,12 @@
[vector-icons/icon :icons/qr {:color colors/blue}]]])
(views/defview edit-mailserver []
(views/letsubs [manage-mailserver [:get-manage-mailserver]
connected? [:get-connected-mailserver]
is-valid? [:manage-mailserver-valid?]]
(let [url (get-in manage-mailserver [:url :value])
id (get-in manage-mailserver [:id :value])
name (get-in manage-mailserver [:name :value])]
(views/letsubs [mailserver [:mailserver.edit/mailserver]
connected? [:mailserver.edit/connected?]
is-valid? [:mailserver.edit/valid?]]
(let [url (get-in mailserver [:url :value])
id (get-in mailserver [:id :value])
name (get-in mailserver [:name :value])]
[react/view components.styles/flex
[status-bar/status-bar]
[react/keyboard-avoiding-view components.styles/flex

View File

@ -7,10 +7,10 @@
{:flex 1
:background-color :white})
(def wnode-item-inner
(def mailserver-item-inner
{:padding-horizontal 16})
(defstyle wnode-item
(defstyle mailserver-item
{:flex-direction :row
:background-color :white
:align-items :center
@ -18,7 +18,7 @@
:ios {:height 64}
:android {:height 56}})
(defstyle wnode-item-name-text
(defstyle mailserver-item-name-text
{:color colors/black
:ios {:font-size 17
:letter-spacing -0.2
@ -26,7 +26,7 @@
:desktop {:font-size 16}
:android {:font-size 16}})
(defstyle wnode-item-connected-text
(defstyle mailserver-item-connected-text
{:color colors/gray
:ios {:font-size 14
:margin-top 6
@ -34,7 +34,7 @@
:android {:font-size 12
:margin-top 2}})
(defn wnode-icon-container [connected?]
(defn mailserver-icon-container [connected?]
{:width 40
:height 40
:border-radius 20
@ -44,5 +44,5 @@
:align-items :center
:justify-content :center})
(defn wnode-icon [connected?]
(defn mailserver-icon [connected?]
(hash-map (if platform/desktop? :tint-color :color) (if connected? :white :gray)))

View File

@ -1,14 +0,0 @@
(ns status-im.ui.screens.offline-messaging-settings.subs
(:require [re-frame.core :as re-frame]
status-im.ui.screens.offline-messaging-settings.edit-mailserver.subs
[status-im.utils.ethereum.core :as ethereum]))
(re-frame/reg-sub :settings/current-wnode
(fn [db _]
(:inbox/current-id db)))
(re-frame/reg-sub :settings/fleet-wnodes
:<- [:settings/current-fleet]
:<- [:get :inbox/wnodes]
(fn [[current-fleet wnodes]]
(current-fleet wnodes)))

View File

@ -12,31 +12,31 @@
[status-im.ui.components.toolbar.actions :as toolbar.actions]
[status-im.ui.screens.offline-messaging-settings.styles :as styles]))
(defn- wnode-icon [connected?]
(defn- mailserver-icon [connected?]
[react/view (if platform/desktop?
{:style (styles/wnode-icon-container connected?)}
(styles/wnode-icon-container connected?))
[vector-icons/icon :icons/wnode
(if platform/desktop? {:style (styles/wnode-icon connected?)}
(styles/wnode-icon connected?))]])
{:style (styles/mailserver-icon-container connected?)}
(styles/mailserver-icon-container connected?))
[vector-icons/icon :icons/mailserver
(if platform/desktop? {:style (styles/mailserver-icon connected?)}
(styles/mailserver-icon connected?))]])
(defn render-row [current-wnode-id]
(defn render-row [current-mailserver-id]
(fn [{:keys [name id user-defined]}]
(let [connected? (= id current-wnode-id)]
(let [connected? (= id current-mailserver-id)]
[react/touchable-highlight
{:on-press #(if user-defined
(re-frame/dispatch [:mailserver.ui/user-defined-mailserver-selected id])
(re-frame/dispatch [:mailserver.ui/default-mailserver-selected id]))
:accessibility-label :mailserver-item}
[react/view styles/wnode-item
[wnode-icon connected?]
[react/view styles/wnode-item-inner
[react/text {:style styles/wnode-item-name-text}
[react/view styles/mailserver-item
[mailserver-icon connected?]
[react/view styles/mailserver-item-inner
[react/text {:style styles/mailserver-item-name-text}
name]]]])))
(views/defview offline-messaging-settings []
(views/letsubs [current-wnode-id [:settings/current-wnode]
wnodes [:settings/fleet-wnodes]]
(views/letsubs [current-mailserver-id [:mailserver/current-id]
mailservers [:mailserver/fleet-mailservers]]
[react/view {:flex 1}
[status-bar/status-bar]
[toolbar/toolbar {}
@ -45,7 +45,7 @@
[toolbar/actions
[(toolbar.actions/add false #(re-frame/dispatch [:mailserver.ui/add-pressed]))]]]
[react/view styles/wrapper
[list/flat-list {:data (vals wnodes)
[list/flat-list {:data (vals mailservers)
:default-separator? false
:key-fn :name
:render-fn (render-row current-wnode-id)}]]]))
:render-fn (render-row current-mailserver-id)}]]]))

View File

@ -4,6 +4,7 @@
status-im.chat.subs
status-im.contact.subs
status-im.search.subs
status-im.mailserver.subs
status-im.ui.screens.accounts.subs
status-im.ui.screens.extensions.subs
status-im.ui.screens.home.subs
@ -16,7 +17,6 @@
status-im.ui.screens.network-settings.subs
status-im.ui.screens.log-level-settings.subs
status-im.ui.screens.fleet-settings.subs
status-im.ui.screens.offline-messaging-settings.subs
status-im.ui.screens.bootnodes-settings.subs
status-im.ui.screens.pairing.subs
status-im.ui.screens.currency-settings.subs
@ -46,14 +46,6 @@
(reg-sub :sync-state :sync-state)
(reg-sub :network-status :network-status)
(reg-sub :peers-count :peers-count)
(reg-sub :mailserver-status :mailserver-status)
(reg-sub :fetching?
(fn [db]
(let [pending-requests (get db :transport.inbox/pending-requests)]
(when (and (pos-int? pending-requests)
(:transport.inbox/current-request db))
pending-requests))))
(reg-sub :offline?
:<- [:network-status]
@ -67,16 +59,6 @@
(fn [peers-count]
(zero? peers-count)))
(reg-sub :mailserver-error?
:<- [:mailserver-status]
(fn [mailserver-status]
(#{:error :disconnected} mailserver-status)))
(reg-sub :mailserver-connected?
:<- [:mailserver-status]
(fn [mailserver-status]
(= :connected mailserver-status)))
(reg-sub :syncing?
:<- [:sync-state]
(fn [sync-state]

View File

@ -1,7 +1,43 @@
(ns status-im.test.mailserver.core
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.transport.utils :as utils]
[status-im.mailserver.core :as mailserver]))
(def enode "enode://08d8eb6177b187049f6c97ed3f6c74fbbefb94c7ad10bafcaf4b65ce89c314dcfee0a8bc4e7a5b824dfa08b45b360cc78f34f0aff981f8386caa07652d2e601b@163.172.177.138:40404")
(def enode2 "enode://12d8eb6177b187049f6c97ed3f6c74fbbefb94c7ad10bafcaf4b65ce89c314dcfee0a8bc4e7a5b824dfa08b45b360cc78f34f0aff981f8386caa07652d2e601b@163.172.177.138:40404")
(deftest test-extract-enode-id
(testing "Get enode id from enode uri"
(is (= "08d8eb6177b187049f6c97ed3f6c74fbbefb94c7ad10bafcaf4b65ce89c314dcfee0a8bc4e7a5b824dfa08b45b360cc78f34f0aff981f8386caa07652d2e601b"
(utils/extract-enode-id enode))))
(testing "Get enode id from mailformed enode uri"
(is (= ""
(utils/extract-enode-id "08d8eb6177b187049f6c97ed3f6c74fbbefb94c7ad10bafcaf4b65ce89c314dcfee0a8bc4e7a5b824dfa08b45b360cc78f34f0aff981f8386caa07652d2e601b@163.172.177.138:40404"))))
(testing "Test empty string"
(is (= ""
(utils/extract-enode-id ""))))
(testing "Test nil"
(is (= ""
(utils/extract-enode-id nil)))))
(def peers
[{:id "08d8eb6177b187049f6c97ed3f6c74fbbefb94c7ad10bafcaf4b65ce89c314dcfee0a8bc4e7a5b824dfa08b45b360cc78f34f0aff981f8386caa07652d2e601b"
:name "StatusIM/v0.9.9-unstable/linux-amd64/go1.9.2"}
{:id "0f7c65277f916ff4379fe520b875082a56e587eb3ce1c1567d9ff94206bdb05ba167c52272f20f634cd1ebdec5d9dfeb393018bfde1595d8e64a717c8b46692f"
:name "Geth/v1.7.2-stable/linux-amd64/go1.9.1"}])
(deftest test-registered-peer?
(testing "Peer is registered"
(is (mailserver/registered-peer? peers enode)))
(testing "Peer is not peers list"
(is (not (mailserver/registered-peer? peers enode2))))
(testing "Empty peers"
(is (not (mailserver/registered-peer? [] enode))))
(testing "Empty peer"
(is (not (mailserver/registered-peer? peers ""))))
(testing "Nil peer"
(is (not (mailserver/registered-peer? peers nil)))))
(def enode-id "1da276e34126e93babf24ec88aac1a7602b4cbb2e11b0961d0ab5e989ca9c261aa7f7c1c85f15550a5f1e5a5ca2305b53b9280cf5894d5ecf7d257b173136d40")
(def password "password")
(def host "167.99.209.61:30504")
@ -45,25 +81,25 @@
(deftest set-input
(testing "it validates names"
(testing "correct name"
(is (= {:db {:mailservers/manage {:name {:value "value"
:error false}}}}
(is (= {:db {:mailserver.edit/mailserver {:name {:value "value"
:error false}}}}
(mailserver/set-input {:db {}} :name "value"))))
(testing "blank name"
(is (= {:db {:mailservers/manage {:name {:value ""
:error true}}}}
(is (= {:db {:mailserver.edit/mailserver {:name {:value ""
:error true}}}}
(mailserver/set-input {:db {}} :name "")))))
(testing "it validates enodes url"
(testing "correct url"
(is (= {:db {:mailservers/manage {:url {:value valid-enode-url
:error false}}}}
(is (= {:db {:mailserver.edit/mailserver {:url {:value valid-enode-url
:error false}}}}
(mailserver/set-input {:db {}} :url valid-enode-url))))
(testing "broken url"
(is (= {:db {:mailservers/manage {:url {:value "broken"
:error true}}}}
(is (= {:db {:mailserver.edit/mailserver {:url {:value "broken"
:error true}}}}
(mailserver/set-input {:db {}} :url "broken"))))))
(deftest edit-mailserver
(let [db {:inbox/wnodes
(let [db {:mailserver/mailservers
{:eth.beta {"a" {:id "a"
:address valid-enode-address
:password password
@ -78,12 +114,12 @@
:error true}
:name {:value ""
:error true}}
(-> actual :db :mailservers/manage))))
(-> actual :db :mailserver.edit/mailserver))))
(testing "it navigates to edit-mailserver view"
(is (= :edit-mailserver
(:status-im.ui.screens.navigation/navigate-to actual))))))
(testing "when an id is given"
(testing "when the wnode is in the list"
(testing "when the mailserver is in the list"
(let [actual (mailserver/edit cofx "a")]
(testing "it populates the fields with the correct values"
(is (= {:id {:value "a"
@ -92,11 +128,11 @@
:error false}
:name {:value "name"
:error false}}
(-> actual :db :mailservers/manage))))
(-> actual :db :mailserver.edit/mailserver))))
(testing "it navigates to edit-mailserver view"
(is (= :edit-mailserver
(:status-im.ui.screens.navigation/navigate-to actual))))))
(testing "when the wnode is not in the list"
(testing "when the mailserver is not in the list"
(let [actual (mailserver/edit cofx "not-existing")]
(testing "it populates the fields with the correct values"
(is (= {:id {:value nil
@ -105,88 +141,88 @@
:error true}
:name {:value ""
:error true}}
(-> actual :db :mailservers/manage))))
(-> actual :db :mailserver.edit/mailserver))))
(testing "it navigates to edit-mailserver view"
(is (= :edit-mailserver
(:status-im.ui.screens.navigation/navigate-to actual)))))))))
(deftest connected-mailserver
(testing "it returns true when set in inbox/current-id"
(let [cofx {:db {:inbox/current-id "a"}}]
(testing "it returns true when set in mailserver/current-id"
(let [cofx {:db {:mailserver/current-id "a"}}]
(is (mailserver/connected? cofx "a"))))
(testing "it returns false otherwise"
(is (not (mailserver/connected? {:db {}} "a")))))
(deftest fetch-mailserver
(testing "it fetches the mailserver from the db"
(let [cofx {:db {:inbox/wnodes {:eth.beta {"a" {:id "a"
:name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}]
(let [cofx {:db {:mailserver/mailservers {:eth.beta {"a" {:id "a"
:name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}]
(is (mailserver/fetch cofx "a")))))
(deftest fetch-current-mailserver
(testing "it fetches the mailserver from the db with corresponding id"
(let [cofx {:db {:inbox/current-id "a"
:inbox/wnodes {:eth.beta {"a" {:id "a"
:name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}]
(let [cofx {:db {:mailserver/current-id "a"
:mailserver/mailservers {:eth.beta {"a" {:id "a"
:name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}]
(is (mailserver/fetch-current cofx)))))
(deftest set-current-mailserver
(with-redefs [rand-nth (comp last sort)]
(let [cofx {:db {:inbox/wnodes {:eth.beta {"a" {}
"b" {}
"c" {}
"d" {}}}}}]
(let [cofx {:db {:mailserver/mailservers {:eth.beta {"a" {}
"b" {}
"c" {}
"d" {}}}}}]
(testing "the user has already a preference"
(let [cofx (assoc-in cofx
[:db :account/account :settings]
{:wnode {:eth.beta "a"}})]
{:mailserver {:eth.beta "a"}})]
(testing "the mailserver exists"
(testing "it sets the preferred mailserver"
(is (= "a" (-> (mailserver/set-current-mailserver cofx)
:db
:inbox/current-id)))))
:mailserver/current-id)))))
(testing "the mailserver does not exists"
(let [cofx (update-in cofx [:db :inbox/wnodes :eth.beta] dissoc "a")]
(let [cofx (update-in cofx [:db :mailserver/mailservers :eth.beta] dissoc "a")]
(testing "sets a random mailserver"
(is (= "d" (-> (mailserver/set-current-mailserver cofx)
:db
:inbox/current-id))))))))
:mailserver/current-id))))))))
(testing "the user has not set an explicit preference"
(testing "current-id is not set"
(testing "it sets a random mailserver"
(is (= "d" (-> (mailserver/set-current-mailserver cofx)
:db
:inbox/current-id)))))
:mailserver/current-id)))))
(testing "current-id is set"
(testing "it sets the next mailserver"
(is (= "c" (-> (mailserver/set-current-mailserver (assoc-in
cofx
[:db :inbox/current-id]
[:db :mailserver/current-id]
"b"))
:db
:inbox/current-id)))
:mailserver/current-id)))
(is (= "a" (-> (mailserver/set-current-mailserver (assoc-in
cofx
[:db :inbox/current-id]
[:db :mailserver/current-id]
"d"))
:db
:inbox/current-id)))
:mailserver/current-id)))
(is (= "a" (-> (mailserver/set-current-mailserver (assoc-in
cofx
[:db :inbox/current-id]
[:db :mailserver/current-id]
"non-existing"))
:db
:inbox/current-id)))))))))
:mailserver/current-id)))))))))
(deftest delete-mailserver
(testing "the user is not connected to the mailserver"
(let [cofx {:random-id-generator (constantly "random-id")
:db {:inbox/wnodes {:eth.beta {"a" {:id "a"
:name "old-name"
:user-defined true
:address "enode://old-id:old-password@url:port"}}}}}
:db {:mailserver/mailservers {:eth.beta {"a" {:id "a"
:name "old-name"
:user-defined true
:address "enode://old-id:old-password@url:port"}}}}}
actual (mailserver/delete cofx "a")]
(testing "it removes the mailserver from the list"
(is (not (mailserver/fetch actual "a"))))
@ -194,17 +230,17 @@
(is (= 1 (count (:data-store/tx actual)))))))
(testing "the mailserver is not user-defined"
(let [cofx {:random-id-generator (constantly "random-id")
:db {:inbox/wnodes {:eth.beta {"a" {:id "a"
:name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}
:db {:mailserver/mailservers {:eth.beta {"a" {:id "a"
:name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}
actual (mailserver/delete cofx "a")]
(testing "it does not delete the mailserver"
(is (= {:dispatch [:navigate-back]} actual)))))
(testing "the user is connected to the mailserver"
(let [cofx {:random-id-generator (constantly "random-id")
:db {:inbox/wnodes {:eth.beta {"a" {:id "a"
:name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}
:db {:mailserver/mailservers {:eth.beta {"a" {:id "a"
:name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}
actual (mailserver/delete cofx "a")]
(testing "it does not remove the mailserver from the list"
(is (= {:dispatch [:navigate-back]} actual))))))
@ -212,19 +248,19 @@
(deftest upsert-mailserver
(testing "new mailserver"
(let [cofx {:random-id-generator (constantly "random-id")
:db {:mailservers/manage {:name {:value "test-name"}
:url {:value "enode://test-id:test-password@url:port"}}
:db {:mailserver.edit/mailserver {:name {:value "test-name"}
:url {:value "enode://test-id:test-password@url:port"}}
:inbox/wnodes {}}}
:mailserver/mailservers {}}}
actual (mailserver/upsert cofx)]
(testing "it adds the enode to inbox/wnodes"
(testing "it adds the enode to mailserver/mailservers"
(is (= {:eth.beta {:randomid {:password "test-password"
:address "enode://test-id@url:port"
:name "test-name"
:id :randomid
:user-defined true}}}
(get-in actual [:db :inbox/wnodes]))))
(get-in actual [:db :mailserver/mailservers]))))
(testing "it navigates back"
(is (= [:navigate-back]
(:dispatch actual))))
@ -232,28 +268,93 @@
(is (= 1 (count (:data-store/tx actual)))))))
(testing "existing mailserver"
(let [cofx {:random-id-generator (constantly "random-id")
:db {:mailservers/manage {:id {:value :a}
:name {:value "new-name"}
:url {:value "enode://new-id:new-password@url:port"}}
:db {:mailserver.edit/mailserver {:id {:value :a}
:name {:value "new-name"}
:url {:value "enode://new-id:new-password@url:port"}}
:inbox/wnodes {:eth.beta {:a {:id :a
:name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}
:mailserver/mailservers {:eth.beta {:a {:id :a
:name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}
actual (mailserver/upsert cofx)]
(testing "it navigates back"
(is (= [:navigate-back]
(:dispatch actual))))
(testing "it updates the enode to inbox/wnodes"
(testing "it updates the enode to mailserver/mailservers"
(is (= {:eth.beta {:a {:password "new-password"
:address "enode://new-id@url:port"
:name "new-name"
:id :a
:user-defined true}}}
(get-in actual [:db :inbox/wnodes]))))
(get-in actual [:db :mailserver/mailservers]))))
(testing "it stores it in the db"
(is (= 1 (count (:data-store/tx actual)))))
(testing "it logs the user out if connected to the current mailserver"
(let [actual (mailserver/upsert (assoc-in cofx
[:db :inbox/current-id] :a))]
[:db :mailserver/current-id] :a))]
(is (= [:accounts.logout.ui/logout-confirmed]
(-> actual :data-store/tx first :success-event))))))))
(defn cofx-fixtures [sym-key registered-peer?]
{:db {:mailserver/state :connected
:peers-summary (if registered-peer?
[{:id "mailserver-id"}]
[])
:account/account {:settings {:fleet :eth.beta}}
:mailserver/current-id "mailserver-a"
:mailserver/mailservers {:eth.beta {"mailserver-a" {:sym-key-id sym-key
:address "enode://mailserver-id@ip"}}}}})
(defn peers-summary-change-result [sym-key registered-peer? registered-peer-before?]
(mailserver/peers-summary-change (cofx-fixtures sym-key
registered-peer?)
(if registered-peer-before?
[{:id "mailserver-id"}]
[])))
(deftest peers-summary-change
(testing "Mailserver added, sym-key doesn't exist"
(let [result (peers-summary-change-result false true false)]
(is (= (into #{} (keys result))
#{:mailserver/mark-trusted-peer :shh/generate-sym-key-from-password :db}))))
(testing "Mailserver disconnected, sym-key exists"
(let [result (peers-summary-change-result true false true)]
(is (= (into #{} (keys result))
#{:db :mailserver/add-peer :utils/dispatch-later}))
(is (= (get-in result [:db :mailserver/state])
:connecting))))
(testing "Mailserver disconnected, sym-key doesn't exists (unlikely situation in practice)"
(let [result (peers-summary-change-result false false true)]
(is (= (into #{} (keys result))
#{:db :mailserver/add-peer :utils/dispatch-later :shh/generate-sym-key-from-password}))
(is (= (get-in result [:db :mailserver/state])
:connecting))))
(testing "Mailserver isn't concerned by peer summary changes"
(is (= (into #{} (keys (peers-summary-change-result true true true)))
#{}))
(is (= (into #{} (keys (peers-summary-change-result true false false)))
#{}))))
(deftest connect-to-mailserver
(let [db {:mailserver/current-id "mailserverid"
:mailserver/mailservers
{:eth.beta {"mailserverid" {:address "mailserver-address"
:password "mailserver-password"}}}
:account/account
{:settings {:fleet :eth.beta
:mailserver {:eth.beta "mailserverid"}}}}]
(testing "it adds the peer"
(is (= "mailserver-address"
(:mailserver/add-peer (mailserver/connect-to-mailserver {:db db})))))
(testing "it generates a sym key if hasn't been generated before"
(is (= "mailserver-password"
(-> (mailserver/connect-to-mailserver {:db db})
:shh/generate-sym-key-from-password
first
:password))))
(let [mailserver-with-sym-key-db (assoc-in db
[:mailserver/mailservers :eth.beta "mailserverid" :sym-key-id]
"somesymkeyid")]
(testing "it does not generate a sym key if already present"
(is (not (-> (mailserver/connect-to-mailserver {:db mailserver-with-sym-key-db})
:shh/generate-sym-key-from-password
first)))))))

View File

@ -1,39 +0,0 @@
(ns status-im.test.protocol.web3.inbox
(:require [status-im.transport.inbox :as inbox]
[status-im.transport.utils :as utils]
[cljs.test :refer-macros [deftest is testing]]))
(def enode "enode://08d8eb6177b187049f6c97ed3f6c74fbbefb94c7ad10bafcaf4b65ce89c314dcfee0a8bc4e7a5b824dfa08b45b360cc78f34f0aff981f8386caa07652d2e601b@163.172.177.138:40404")
(def enode2 "enode://12d8eb6177b187049f6c97ed3f6c74fbbefb94c7ad10bafcaf4b65ce89c314dcfee0a8bc4e7a5b824dfa08b45b360cc78f34f0aff981f8386caa07652d2e601b@163.172.177.138:40404")
(deftest test-extract-enode-id
(testing "Get enode id from enode uri"
(is (= "08d8eb6177b187049f6c97ed3f6c74fbbefb94c7ad10bafcaf4b65ce89c314dcfee0a8bc4e7a5b824dfa08b45b360cc78f34f0aff981f8386caa07652d2e601b"
(utils/extract-enode-id enode))))
(testing "Get enode id from mailformed enode uri"
(is (= ""
(utils/extract-enode-id "08d8eb6177b187049f6c97ed3f6c74fbbefb94c7ad10bafcaf4b65ce89c314dcfee0a8bc4e7a5b824dfa08b45b360cc78f34f0aff981f8386caa07652d2e601b@163.172.177.138:40404"))))
(testing "Test empty string"
(is (= ""
(utils/extract-enode-id ""))))
(testing "Test nil"
(is (= ""
(utils/extract-enode-id nil)))))
(def peers
[{:id "08d8eb6177b187049f6c97ed3f6c74fbbefb94c7ad10bafcaf4b65ce89c314dcfee0a8bc4e7a5b824dfa08b45b360cc78f34f0aff981f8386caa07652d2e601b"
:name "StatusIM/v0.9.9-unstable/linux-amd64/go1.9.2"}
{:id "0f7c65277f916ff4379fe520b875082a56e587eb3ce1c1567d9ff94206bdb05ba167c52272f20f634cd1ebdec5d9dfeb393018bfde1595d8e64a717c8b46692f"
:name "Geth/v1.7.2-stable/linux-amd64/go1.9.1"}])
(deftest test-registered-peer?
(testing "Peer is registered"
(is (inbox/registered-peer? peers enode)))
(testing "Peer is not peers list"
(is (not (inbox/registered-peer? peers enode2))))
(testing "Empty peers"
(is (not (inbox/registered-peer? [] enode))))
(testing "Empty peer"
(is (not (inbox/registered-peer? peers ""))))
(testing "Nil peer"
(is (not (inbox/registered-peer? peers nil)))))

View File

@ -20,7 +20,6 @@
[status-im.test.models.wallet]
[status-im.test.search.core]
[status-im.test.transport.core]
[status-im.test.transport.inbox]
[status-im.test.chat.models]
[status-im.test.chat.models.input]
[status-im.test.chat.models.loading]
@ -32,7 +31,6 @@
[status-im.test.chat.commands.input]
[status-im.test.chat.commands.impl.transactions]
[status-im.test.i18n]
[status-im.test.protocol.web3.inbox]
[status-im.test.utils.utils]
[status-im.test.utils.money]
[status-im.test.utils.clocks]
@ -99,8 +97,6 @@
'status-im.test.i18n
'status-im.test.search.core
'status-im.test.transport.core
'status-im.test.transport.inbox
'status-im.test.protocol.web3.inbox
'status-im.test.utils.utils
'status-im.test.utils.money
'status-im.test.utils.clocks

View File

@ -32,24 +32,24 @@
:name "name-3"
:address "address-3"
:password "password-3"}
expected-wnodes {:eth.beta {"1" (-> ms-1
(dissoc :fleet)
(assoc :user-defined true))
"2" (-> ms-2
(dissoc ms-2 :fleet)
(assoc :user-defined true))}
:eth.test {"3" (-> ms-3
(dissoc :fleet)
(assoc :user-defined true))}}
expected-mailservers {:eth.beta {"1" (-> ms-1
(dissoc :fleet)
(assoc :user-defined true))
"2" (-> ms-2
(dissoc ms-2 :fleet)
(assoc :user-defined true))}
:eth.test {"3" (-> ms-3
(dissoc :fleet)
(assoc :user-defined true))}}
cofx-with-ms (assoc cofx
:data-store/mailservers
[ms-1
ms-2
ms-3])]
(is (= expected-wnodes
(is (= expected-mailservers
(-> (get-in
(protocol/initialize-protocol cofx-with-ms "user-address")
[:db :inbox/wnodes])
[:db :mailserver/mailservers])
(update-in [:eth.beta "1"] dissoc :generating-sym-key?)
(update-in [:eth.beta "2"] dissoc :generating-sym-key?)
(update-in [:eth.test "3"] dissoc :generating-sym-key?))))))))

View File

@ -1,68 +0,0 @@
(ns status-im.test.transport.inbox
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.transport.inbox :as inbox]))
(defn cofx-fixtures [sym-key registered-peer?]
{:db {:mailserver-status :connected
:peers-summary (if registered-peer?
[{:id "wnode-id"}]
[])
:account/account {:settings {:fleet :eth.beta}}
:inbox/current-id "mailserver-a"
:inbox/wnodes {:eth.beta {"mailserver-a" {:sym-key-id sym-key
:address "enode://wnode-id@ip"}}}}})
(defn peers-summary-change-result [sym-key registered-peer? registered-peer-before?]
(inbox/peers-summary-change (cofx-fixtures sym-key
registered-peer?)
(if registered-peer-before?
[{:id "wnode-id"}]
[])))
(deftest peers-summary-change
(testing "Mailserver added, sym-key doesn't exist"
(let [result (peers-summary-change-result false true false)]
(is (= (into #{} (keys result))
#{:transport.inbox/mark-trusted-peer :shh/generate-sym-key-from-password :db}))))
(testing "Mailserver disconnected, sym-key exists"
(let [result (peers-summary-change-result true false true)]
(is (= (into #{} (keys result))
#{:db :transport.inbox/add-peer :utils/dispatch-later}))
(is (= (get-in result [:db :mailserver-status])
:connecting))))
(testing "Mailserver disconnected, sym-key doesn't exists (unlikely situation in practice)"
(let [result (peers-summary-change-result false false true)]
(is (= (into #{} (keys result))
#{:db :transport.inbox/add-peer :utils/dispatch-later :shh/generate-sym-key-from-password}))
(is (= (get-in result [:db :mailserver-status])
:connecting))))
(testing "Mailserver isn't concerned by peer summary changes"
(is (= (into #{} (keys (peers-summary-change-result true true true)))
#{}))
(is (= (into #{} (keys (peers-summary-change-result true false false)))
#{}))))
(deftest connect-to-mailserver
(let [db {:inbox/current-id "wnodeid"
:inbox/wnodes
{:eth.beta {"wnodeid" {:address "wnode-address"
:password "wnode-password"}}}
:account/account
{:settings {:fleet :eth.beta
:wnode {:eth.beta "wnodeid"}}}}]
(testing "it adds the peer"
(is (= "wnode-address"
(:transport.inbox/add-peer (inbox/connect-to-mailserver {:db db})))))
(testing "it generates a sym key if hasn't been generated before"
(is (= "wnode-password"
(-> (inbox/connect-to-mailserver {:db db})
:shh/generate-sym-key-from-password
first
:password))))
(let [wnode-with-sym-key-db (assoc-in db
[:inbox/wnodes :eth.beta "wnodeid" :sym-key-id]
"somesymkeyid")]
(testing "it does not generate a sym key if already present"
(is (not (-> (inbox/connect-to-mailserver {:db wnode-with-sym-key-db})
:shh/generate-sym-key-from-password
first)))))))

View File

@ -242,7 +242,7 @@
"edit-contacts": "Επεξεργασία επαφών",
"more": "περισσότερα",
"cancel": "Ακύρωση",
"existing-wnodes": "Υπάρχοντες mailservers",
"existing-mailservers": "Υπάρχοντες mailservers",
"no-statuses-found": "Δεν βρέθηκαν καταστάσεις",
"can-not-add-yourself": "Δεν μπορείτε να προσθέσετε τον εαυτό σας",
"transaction-description": "Περιμένετε τουλάχιστον 12 επιβεβαιώσεις για να βεβαιωθείτε ότι η συναλλαγή σας γίνεται με ασφάλεια",
@ -299,7 +299,7 @@
"profile": "Προφίλ",
"wallet-choose-recipient": "Επιλογή παραλήπτη",
"no-statuses-discovered": "Δεν βρέθηκαν καταστάσεις",
"add-wnode": "Προσθήκη mailserver",
"add-mailserver": "Προσθήκη mailserver",
"none": "Κανένα",
"removed": "αφαιρέθηκες",
"empty-topic": "Κενό θέμα",

View File

@ -495,7 +495,7 @@
"currency-display-name-clp": "Chile Peso",
"currency-display-name-ghs": "Ghana Cedi",
"currency-display-name-isk": "Iceland Krona",
"connect-wnode-content": "Connect to {{name}}?",
"connect-mailserver-content": "Connect to {{name}}?",
"view-cryptostrikers": "View in CryptoStrikers",
"view-gitcoin": "View in Gitcoin",
"view-superrare": "View in SuperRare",
@ -548,7 +548,7 @@
"edit-contacts": "Edit contacts",
"more": "more",
"cancel": "Cancel",
"existing-wnodes": "Existing mailservers",
"existing-mailservers": "Existing mailservers",
"delete-network-confirmation": "Are you sure you want to delete this network?",
"no-statuses-found": "No statuses found",
"extension-address": "Extension address",
@ -659,7 +659,7 @@
"profile": "Profile",
"wallet-choose-recipient": "Choose Recipient",
"no-statuses-discovered": "No statuses discovered",
"add-wnode": "Add mailserver",
"add-mailserver": "Add mailserver",
"currency-display-name-nzd": "New Zealand Dollar",
"none": "None",
"removed": "removed",

View File

@ -14,7 +14,7 @@
"add-new-contact": "Agregar nuevo contacto",
"add-new-network": "Agregar red",
"add-to-contacts": "Agregar a contactos",
"add-wnode": "Agregar servidor de correo",
"add-mailserver": "Agregar servidor de correo",
"address": "Dirección",
"address-explication": "Tu clave pública se usa para generar tu dirección en Ethereum y es una serie de números y letras. Puedes encontrarlo fácilmente en tu perfil",
"advanced-settings": "Ajustes avanzados",
@ -85,7 +85,7 @@
"confirmations": "Confirmaciones",
"confirmations-helper-text": "Cuando la transacción tenga 12 confirmaciones, puede considerarla resuelta.",
"connect": "Conectar",
"connect-wnode-content": "¿Conectar con {{name}}?",
"connect-mailserver-content": "¿Conectar con {{name}}?",
"connected": "Conectado",
"connecting-requires-login": "Para conectarse a otra red es necesario iniciar sesión",
"connection-problem": "Problema de conexión de mensajes",
@ -285,7 +285,7 @@
"estimated-time": "Tiempo estimado {{time}}",
"eth": "ETH",
"existing-networks": "Redes existentes",
"existing-wnodes": "Servidores de correo existentes",
"existing-mailservers": "Servidores de correo existentes",
"extension": "Extensión",
"extension-address": "Dirección de extensión",
"extension-find": "Buscar extensión",

View File

@ -14,7 +14,7 @@
"add-new-contact": "افزودن مخاطب جدید",
"add-new-network": "افزودن شبکه جدید",
"add-to-contacts": "افزودن به مخاطبین",
"add-wnode": "افزودن Mailserver",
"add-mailserver": "افزودن Mailserver",
"address": "آدرس",
"address-explication": "کلید عمومی شما برای تولید آدرس شما روی اتریوم استفاده می شود و یک سری از اعداد و حروف است. شما می توانید آنرا به راحتی در قسمت مشخصات خود پیدا کنید",
"advanced-settings": "تنظیمات پیشرفته",
@ -86,7 +86,7 @@
"confirmations": "تاييديه",
"confirmations-helper-text": "زمانی که یک تراکنش 12 تایید دریافت کند می توانید آنرا انجام شده در نظر بگیرید",
"connect": "اتصال",
"connect-wnode-content": "اتصال به {{name}}؟",
"connect-mailserver-content": "اتصال به {{name}}؟",
"connected": "متصل شده",
"connecting-requires-login": "اتصال به شبکه دیگر نیاز به ورود شما به سیستم دارد",
"connection-problem": "مشکل اتصال به پیام ها",
@ -287,7 +287,7 @@
"estimated-time": "زمان تقریبی {{time}}",
"eth": "ETH",
"existing-networks": "شبکه های موجود",
"existing-wnodes": "mailserver های موجود",
"existing-mailservers": "mailserver های موجود",
"extension": "افزونه",
"extension-address": "آدرس افزونه",
"extension-find": "یافتن افزونه",

View File

@ -247,7 +247,7 @@
"edit-contacts": "Modifier contacts",
"more": "plus",
"cancel": "Annuler",
"existing-wnodes": "Serveurs de mail existants",
"existing-mailservers": "Serveurs de mail existants",
"no-statuses-found": "Aucun statut trouvé",
"can-not-add-yourself": "Vous ne pouvez pas vous ajouter vous-même",
"transaction-description": "Veuillez attendre au moins 12 confirmations pour être sûr que votre transaction a bien été définitivement validée",

View File

@ -236,7 +236,7 @@
"edit-contacts": "連絡先を編集",
"more": "もっと",
"cancel": "キャンセル",
"existing-wnodes": "既存のメールサーバー",
"existing-mailservers": "既存のメールサーバー",
"no-statuses-found": "ステータスが見つかりませんでした",
"can-not-add-yourself": "自分を追加することはできません",
"transaction-description": "あなたの取引が安全に処理されることを確認するために少なくとも12回の確認を待ってください。",
@ -293,7 +293,7 @@
"profile": "プロフィール",
"wallet-choose-recipient": "受信者を選択",
"no-statuses-discovered": "ステータスは見つかりませんでした",
"add-wnode": "メールサーバーを追加する",
"add-mailserver": "メールサーバーを追加する",
"none": "なし",
"removed": "削除済み",
"empty-topic": "空のトピック",

View File

@ -14,7 +14,7 @@
"add-new-contact": "새 연락처 추가",
"add-new-network": "새 네트워크 추가",
"add-to-contacts": "연락처에 추가",
"add-wnode": "메일서버 추가",
"add-mailserver": "메일서버 추가",
"address": "주소",
"address-explication": "공개 키는 Ethereum 주소를 생성하기 위해 사용되며, 숫자와 알파벳으로 이루어져 있습니다. 프로필에서 쉽게 확인할 수 있습니다.",
"advanced-settings": "고급 설정",
@ -87,7 +87,7 @@
"confirmations": "확인",
"confirmations-helper-text": "12번 확인된 거래는 확정된 것으로 간주됩니다.",
"connect": "접속",
"connect-wnode-content": "{{name}}에 연결 하시겠습니까?",
"connect-mailserver-content": "{{name}}에 연결 하시겠습니까?",
"connected": "연결됨",
"connecting-requires-login": "다른 네트워크에 연결하기 위해서는 로그인이 필요합니다",
"connection-problem": "메시지 연결 문제",
@ -290,7 +290,7 @@
"estimated-time": "예상 시간 {{time}}",
"eth": "ETH",
"existing-networks": "기존 네트워크",
"existing-wnodes": "기존 메일서버",
"existing-mailservers": "기존 메일서버",
"extension": "확장 프로그램",
"extension-address": "확장 프로그램 주소",
"extension-find": "확장 프로그램 찾기",

View File

@ -14,7 +14,7 @@
"add-new-contact": "Tambah kenalan baru",
"add-new-network": "Tambah rangkaian baru",
"add-to-contacts": "Tambah pada senarai kenalan",
"add-wnode": "Tambah mailserver",
"add-mailserver": "Tambah mailserver",
"address": "Address",
"address-explication": "Mungkin disini sepatutnya terdapat sedikit teks menjelaskan apa itu address dan dimana untuk melihatnya",
"advanced-settings": "Tetapan lanjutan",
@ -87,7 +87,7 @@
"confirmations": "Pengesahan",
"confirmations-helper-text": "Apabila transaksi mempunyai 12 pengesahan, anda boleh menganggap ia telah diselesaikan.",
"connect": "Sambung",
"connect-wnode-content": "Sambung ke {{name}}?",
"connect-mailserver-content": "Sambung ke {{name}}?",
"connected": "Bersambung",
"connecting-requires-login": "Menyambung ke rangkaian lain memerlukan daftar masuk",
"connection-problem": "Masalah sambungan mesej",
@ -291,7 +291,7 @@
"estimated-time": "Anggaran masa {{time}}",
"eth": "ETH",
"existing-networks": "Rangkaian sedia ada",
"existing-wnodes": "Mailserver sedia ada",
"existing-mailservers": "Mailserver sedia ada",
"extension": "Sambungan",
"extension-address": "Alamat sambungan",
"extension-find": "Cari sambungan",

View File

@ -14,7 +14,7 @@
"add-new-contact": "Dodaj nowy kontakt",
"add-new-network": "Dodaj nową sieć",
"add-to-contacts": "Dodaj do kontaktów",
"add-wnode": "Dodaj mailserver",
"add-mailserver": "Dodaj mailserver",
"address": "Adres",
"address-explication": "Być może tutaj powinien znajdować się tekst wyjaśniający, czym jest adres i gdzie go szukać",
"advanced-settings": "Zaawansowane ustawienia",
@ -81,7 +81,7 @@
"confirmations": "Potwierdzenia",
"confirmations-helper-text": "Kiedy transakcja ma 12 potwierdzeń, możesz uznać ją za uregulowaną.",
"connect": "Połącz",
"connect-wnode-content": "Połącz z {{name}}?",
"connect-mailserver-content": "Połącz z {{name}}?",
"connected": "Połączono",
"connecting-requires-login": "Połączenie z inną siecią wymaga logowania",
"connection-problem": "Problem z połączeniem",
@ -279,7 +279,7 @@
"errors": "Błędy",
"eth": "ETH",
"existing-networks": "Istniejące sieci",
"existing-wnodes": "Istniejące mailserver'y",
"existing-mailservers": "Istniejące mailserver'y",
"extension": "Rozszerzenie",
"extension-address": "Adres rozszerzenia",
"extension-find": "Znajdź rozszerzenie",

View File

@ -14,7 +14,7 @@
"add-new-contact": "Добавить новый контакт",
"add-new-network": "Добавить новую сеть",
"add-to-contacts": "Добавить в контакты",
"add-wnode": "Добавить Mailserver",
"add-mailserver": "Добавить Mailserver",
"address": "Адрес",
"address-explication": "Ваш публичный ключ используется для создания вашего адреса в Ethereum и представляет собой ряд цифр и букв. Вы можете легко найти его в своем профиле",
"advanced-settings": "Расширенные настройки",
@ -87,7 +87,7 @@
"confirmations": "Подтверждения",
"confirmations-helper-text": "Пожалуйста, дождитесь как минимум 12-ти подтверждений, чтобы убедиться, что транзакция обработана безопасно",
"connect": "Подключиться",
"connect-wnode-content": "Подключиться к {{name}} ?",
"connect-mailserver-content": "Подключиться к {{name}} ?",
"connected": "Подключен",
"connecting-requires-login": "Подключение к другой сети требует входа в систему",
"connection-problem": "Проблема с подключением сообщений",
@ -290,7 +290,7 @@
"estimated-time": "Примерное время {{time}}",
"eth": "ETH",
"existing-networks": "Существующие сети",
"existing-wnodes": "Существующие почтовые серверы",
"existing-mailservers": "Существующие почтовые серверы",
"extension": "Расширение",
"extension-address": "Адрес расширения",
"extension-find": "Найти расширение",

View File

@ -232,7 +232,7 @@
"edit-contacts": "Редагування контактів",
"more": "більше",
"cancel": "Скасувати",
"existing-wnodes": "Існуючі поштові сервери",
"existing-mailservers": "Існуючі поштові сервери",
"no-statuses-found": "Статуси не виявлені",
"can-not-add-yourself": "Ви не можете додати себе",
"transaction-description": "Будь ласка, почекайте як мінімум 12 підтверджень, щоб переконатися, що транзакція оброблена безпечно",
@ -289,7 +289,7 @@
"profile": "Профіль",
"wallet-choose-recipient": "Виберіть Одержувача",
"no-statuses-discovered": "Статуси не виявлені",
"add-wnode": "Додати поштовий сервер",
"add-mailserver": "Додати поштовий сервер",
"none": "Жоден",
"removed": "видалений",
"empty-topic": "Порожня тема",

View File

@ -14,7 +14,7 @@
"add-new-contact": "添加新的联系人",
"add-new-network": "添加新网络",
"add-to-contacts": "添加到联系人",
"add-wnode": "添加邮件服务器",
"add-mailserver": "添加邮件服务器",
"address": "地址",
"address-explication": "你的公钥可以用来生成以太坊地址,由一系列数字和字母组成,可以在个人简介中轻松地找到。",
"advanced-settings": "高级设置",
@ -87,7 +87,7 @@
"confirmations": "确认",
"confirmations-helper-text": "请等待达到至少12个确认来确保交易已被安全地处理。",
"connect": "连接",
"connect-wnode-content": "连接到{{name}} ",
"connect-mailserver-content": "连接到{{name}} ",
"connected": "已连接",
"connecting-requires-login": "连接其它网络需要登录",
"connection-problem": "消息连接问题",
@ -291,7 +291,7 @@
"estimated-time": "预估时间{{time}}",
"eth": "ETH",
"existing-networks": "已有的网络",
"existing-wnodes": "现有的邮件服务器",
"existing-mailservers": "现有的邮件服务器",
"extension": "扩展",
"extension-address": "扩展地址",
"extension-find": "查找扩展",