Validate rpc-url when creating a custom network
Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
parent
c66c457bbb
commit
34174cd539
|
@ -0,0 +1,66 @@
|
|||
(ns status-im.models.network
|
||||
(:require [clojure.string :as string]
|
||||
[status-im.utils.ethereum.core :as ethereum]
|
||||
[status-im.utils.handlers-macro :as handlers-macro]
|
||||
[status-im.ui.screens.accounts.utils :as accounts.utils]))
|
||||
|
||||
(def url-regex
|
||||
#"https?://(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}(\.[a-z]{2,6})?\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)")
|
||||
|
||||
(defn valid-rpc-url? [url]
|
||||
(boolean (re-matches url-regex (str url))))
|
||||
|
||||
(def default-manage
|
||||
{:name {:value ""}
|
||||
:url {:value ""}
|
||||
:chain {:value :mainnet}})
|
||||
|
||||
(defn validate-string [{:keys [value]}]
|
||||
{:value value
|
||||
:error (string/blank? value)})
|
||||
|
||||
(defn validate-url [{:keys [value]}]
|
||||
{:value value
|
||||
:error (not (valid-rpc-url? value))})
|
||||
|
||||
(defn validate-manage [manage]
|
||||
(-> manage
|
||||
(update :url validate-url)
|
||||
(update :name validate-string)
|
||||
(update :chain validate-string)))
|
||||
|
||||
(defn valid-manage? [manage]
|
||||
(->> (validate-manage manage)
|
||||
vals
|
||||
(map :error)
|
||||
(not-any? identity)))
|
||||
|
||||
(defn- new-network [{:keys [random-id] :as cofx} network-name upstream-url type]
|
||||
(let [data-dir (str "/ethereum/" (name type) "_rpc")
|
||||
config {:NetworkId (ethereum/chain-keyword->chain-id type)
|
||||
:DataDir data-dir
|
||||
:UpstreamConfig {:Enabled true
|
||||
:URL upstream-url}}]
|
||||
{:id (string/replace random-id "-" "")
|
||||
:name network-name
|
||||
:config config}))
|
||||
|
||||
(defn set-input [input-key value {:keys [db]}]
|
||||
{:db (-> db
|
||||
(update-in [:networks/manage input-key] assoc :value value)
|
||||
(update-in [:networks/manage] validate-manage))})
|
||||
|
||||
(defn save [{{:networks/keys [manage] :account/keys [account] :as db} :db :as cofx}]
|
||||
(when (valid-manage? manage)
|
||||
(let [{:keys [name url chain]} manage
|
||||
network (new-network cofx (:value name) (:value url) (:value chain))
|
||||
new-networks (merge {(:id network) network} (:networks account))]
|
||||
(handlers-macro/merge-fx cofx
|
||||
{:db (dissoc db :networks/manage)
|
||||
:dispatch [:navigate-back]}
|
||||
(accounts.utils/account-update {:networks new-networks})))))
|
||||
|
||||
;; No edit functionality actually implemented
|
||||
(defn edit [{db :db}]
|
||||
{:db (assoc db :networks/manage (validate-manage default-manage))
|
||||
:dispatch [:navigate-to :edit-network]})
|
|
@ -1,46 +1,20 @@
|
|||
(ns status-im.ui.screens.network-settings.edit-network.events
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.utils.handlers :refer [register-handler] :as handlers]
|
||||
[status-im.utils.handlers-macro :as handlers-macro]
|
||||
[status-im.ui.screens.accounts.utils :as accounts.utils]
|
||||
[status-im.utils.ethereum.core :as ethereum]
|
||||
[status-im.utils.types :as types]
|
||||
[clojure.string :as string]))
|
||||
|
||||
(defn- new-network [{:keys [random-id] :as cofx} network-name upstream-url type]
|
||||
(let [data-dir (str "/ethereum/" (name type) "_rpc")
|
||||
config {:NetworkId (ethereum/chain-keyword->chain-id type)
|
||||
:DataDir data-dir
|
||||
:UpstreamConfig {:Enabled true
|
||||
:URL upstream-url}}]
|
||||
{:id (string/replace random-id "-" "")
|
||||
:name network-name
|
||||
:config config}))
|
||||
[status-im.models.network :as models.network]
|
||||
[status-im.utils.handlers :refer [register-handler] :as handlers]))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:save-new-network
|
||||
[(re-frame/inject-cofx :random-id)]
|
||||
(fn [{{:networks/keys [manage] :account/keys [account] :as db} :db :as cofx} _]
|
||||
(let [{:keys [name url chain]} manage
|
||||
network (new-network cofx (:value name) (:value url) (:value chain))
|
||||
new-networks (merge {(:id network) network} (:networks account))]
|
||||
(handlers-macro/merge-fx cofx
|
||||
{:db (dissoc db :networks/manage)
|
||||
:dispatch [:navigate-back]}
|
||||
(accounts.utils/account-update {:networks new-networks})))))
|
||||
(fn [cofx _]
|
||||
(models.network/save cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:network-set-input
|
||||
(fn [{db :db} [_ input-key value]]
|
||||
{:db (update db :networks/manage merge {input-key {:value value
|
||||
:error (and (string? value) (empty? value))}})}))
|
||||
(fn [cofx [_ input-key value]]
|
||||
(models.network/set-input input-key value cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:edit-network
|
||||
(fn [{db :db} _]
|
||||
{:db (update-in db [:networks/manage] assoc
|
||||
:name {:error true}
|
||||
:url {:error true}
|
||||
:chain {:value :mainnet})
|
||||
:dispatch [:navigate-to :edit-network]}))
|
||||
|
||||
(fn [cofx _]
|
||||
(models.network/edit cofx)))
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
(ns status-im.test.models.network
|
||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.models.network :as model]))
|
||||
|
||||
(deftest valid-rpc-url-test
|
||||
(testing "nil?"
|
||||
(is (not (model/valid-rpc-url? nil))))
|
||||
(testing "a blank url"
|
||||
(is (not (model/valid-rpc-url? ""))))
|
||||
(testing "a url without a protocol"
|
||||
(is (not (model/valid-rpc-url? "something"))))
|
||||
(testing "a url without a protocol"
|
||||
(is (not (model/valid-rpc-url? "http://something with space"))))
|
||||
(testing "a url without a hostname"
|
||||
(is (not (model/valid-rpc-url? "https://"))))
|
||||
(testing "an http url"
|
||||
(is (model/valid-rpc-url? "http://valid.com")))
|
||||
(testing "an https url"
|
||||
(is (model/valid-rpc-url? "https://valid.something.else")))
|
||||
(testing "a fully qualified url"
|
||||
(is (model/valid-rpc-url? "https://mainnet.infura.io:6523/z6GCTmjdP3FETEJmMBI4")))
|
||||
(testing "an ip address"
|
||||
(is (model/valid-rpc-url? "https://192.168.1.1")))
|
||||
(testing "localhost"
|
||||
(is (model/valid-rpc-url? "https://localhost")))
|
||||
(testing "a fully qualified url, ip address"
|
||||
(is (model/valid-rpc-url? "https://192.168.1.1:6523/z6GCTmjdP3FETEJmMBI4")))
|
||||
(testing "an https url not on the default port"
|
||||
(is (model/valid-rpc-url? "https://valid.something.else:65323"))))
|
||||
|
||||
(deftest new-network-test
|
||||
(let [actual (model/new-network {:random-id "random-id"}
|
||||
"network-name"
|
||||
"upstream-url"
|
||||
:mainnet)]
|
||||
(is (= {:id "randomid"
|
||||
:name "network-name"
|
||||
:config {:NetworkId 1
|
||||
:DataDir "/ethereum/mainnet_rpc"
|
||||
:UpstreamConfig {:Enabled true
|
||||
:URL "upstream-url"}}}
|
||||
actual))))
|
||||
|
||||
(deftest valid-manage-test
|
||||
(testing "a valid manage"
|
||||
(is (model/valid-manage? {:url {:value "http://valid.com"}
|
||||
:name {:value "valid"}
|
||||
:chain {:value "valid"}})))
|
||||
(testing "invalid url"
|
||||
(is (not (model/valid-manage? {:url {:value "invalid"}
|
||||
:name {:value "valid"}
|
||||
:chain {:value "valid"}}))))
|
||||
|
||||
(testing "invalid name"
|
||||
(is (not (model/valid-manage? {:url {:value "http://valid.com"}
|
||||
:name {:value ""}
|
||||
:chain {:value "valid"}}))))
|
||||
|
||||
(testing "invalid chain"
|
||||
(is (not (model/valid-manage? {:url {:value "http://valid.com"}
|
||||
:name {:value "valid"}
|
||||
:chain {:value ""}})))))
|
||||
|
||||
(deftest set-input-test
|
||||
(testing "it updates and validate a field"
|
||||
(is (= {:db {:networks/manage {:url {:value "http://valid.com"
|
||||
:error false}
|
||||
:name {:value ""
|
||||
:error true}
|
||||
:chain {:value "mainnet"
|
||||
:error false}}}}
|
||||
(model/set-input :url "http://valid.com"
|
||||
{:db {:networks/manage {:url {:value "something"
|
||||
:error true}
|
||||
:name {:value ""
|
||||
:error false}
|
||||
:chain {:value "mainnet"
|
||||
:error false}}}})))))
|
||||
|
||||
(deftest save
|
||||
(testing "it does not save a network with an invalid url"
|
||||
(is (nil? (model/save {:random-id "random"
|
||||
:db {:networks/manage {:url {:value "wrong"}
|
||||
:chain {:value "1"}
|
||||
:name {:value "empty"}}
|
||||
:account/account {}}})))))
|
|
@ -14,6 +14,7 @@
|
|||
[status-im.test.models.bootnode]
|
||||
[status-im.test.models.account]
|
||||
[status-im.test.models.contact]
|
||||
[status-im.test.models.network]
|
||||
[status-im.test.transport.core]
|
||||
[status-im.test.transport.inbox]
|
||||
[status-im.test.transport.handlers]
|
||||
|
@ -39,7 +40,6 @@
|
|||
[status-im.test.utils.datetime]
|
||||
[status-im.test.utils.mixpanel]
|
||||
[status-im.test.utils.prices]
|
||||
[status-im.test.ui.screens.network-settings.edit-network.events]
|
||||
[status-im.test.ui.screens.accounts.login.events]))
|
||||
|
||||
(enable-console-print!)
|
||||
|
@ -64,6 +64,7 @@
|
|||
'status-im.test.models.bootnode
|
||||
'status-im.test.models.account
|
||||
'status-im.test.models.contact
|
||||
'status-im.test.models.network
|
||||
'status-im.test.bots.events
|
||||
'status-im.test.wallet.subs
|
||||
'status-im.test.wallet.transactions.subs
|
||||
|
@ -90,5 +91,4 @@
|
|||
'status-im.test.utils.datetime
|
||||
'status-im.test.utils.mixpanel
|
||||
'status-im.test.utils.prices
|
||||
'status-im.test.ui.screens.network-settings.edit-network.events
|
||||
'status-im.test.ui.screens.accounts.login.events)
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
(ns status-im.test.ui.screens.network-settings.edit-network.events
|
||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.ui.screens.network-settings.edit-network.events :as events]))
|
||||
|
||||
(deftest new-network
|
||||
(let [actual (events/new-network {:random-id "random-id"}
|
||||
"network-name"
|
||||
"upstream-url"
|
||||
:mainnet)]
|
||||
(is (= {:id "randomid"
|
||||
:name "network-name"
|
||||
:config {:NetworkId 1
|
||||
:DataDir "/ethereum/mainnet_rpc"
|
||||
:UpstreamConfig {:Enabled true
|
||||
:URL "upstream-url"}}}
|
||||
actual))))
|
Loading…
Reference in New Issue