[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:
parent
ed16d9f191
commit
a3b2bc1b87
Before Width: | Height: | Size: 322 B After Width: | Height: | Size: 322 B |
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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))))
|
||||
|
|
|
@ -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}])
|
||||
|
|
|
@ -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}}})
|
|
@ -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"))
|
||||
|
|
|
@ -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}])
|
||||
|
|
|
@ -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)))))
|
||||
|
|
|
@ -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))))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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)
|
||||
{}))))
|
||||
|
|
|
@ -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?)
|
|
@ -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))))
|
|
@ -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?]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"))))
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)))
|
|
@ -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?}]))))
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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})}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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))])))
|
||||
|
||||
|
|
|
@ -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}]
|
||||
|
|
|
@ -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})
|
||||
|
||||
|
|
|
@ -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]]]])
|
||||
|
|
|
@ -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))))
|
|
@ -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))))
|
|
@ -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
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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)))
|
|
@ -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)}]]]))
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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)))))))
|
||||
|
|
|
@ -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)))))
|
|
@ -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
|
||||
|
|
|
@ -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?))))))))
|
||||
|
|
|
@ -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)))))))
|
|
@ -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": "Κενό θέμα",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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": "یافتن افزونه",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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": "空のトピック",
|
||||
|
|
|
@ -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": "확장 프로그램 찾기",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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": "Найти расширение",
|
||||
|
|
|
@ -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": "Порожня тема",
|
||||
|
|
|
@ -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": "查找扩展",
|
||||
|
|
Loading…
Reference in New Issue