From d834b6e37d1ecc52a2367676cee0b338c383087f Mon Sep 17 00:00:00 2001 From: Andrey Shovkoplyas Date: Mon, 30 Jul 2018 13:13:23 +0300 Subject: [PATCH] [#4380] Improve browser security warning Signed-off-by: Andrey Shovkoplyas --- resources/icons/lock.svg | 2 +- resources/icons/lock_opened.svg | 5 ++ src/status_im/models/browser.cljs | 13 +++- src/status_im/translations/en.cljs | 3 +- .../ui/components/icons/vector_icons.cljs | 1 + .../ui/components/tooltip/views.cljs | 26 +++---- .../ui/screens/add_new/open_dapp/views.cljs | 2 +- src/status_im/ui/screens/browser/db.cljs | 4 + .../{contacts => browser}/default_dapps.cljs | 8 +- src/status_im/ui/screens/browser/events.cljs | 23 +----- src/status_im/ui/screens/browser/styles.cljs | 26 ++++--- src/status_im/ui/screens/browser/views.cljs | 73 ++++++++++--------- src/status_im/ui/screens/contacts/events.cljs | 2 +- src/status_im/utils/http.cljs | 2 +- test/cljs/status_im/test/browser/events.cljs | 8 +- 15 files changed, 102 insertions(+), 96 deletions(-) create mode 100644 resources/icons/lock_opened.svg rename src/status_im/ui/screens/{contacts => browser}/default_dapps.cljs (96%) diff --git a/resources/icons/lock.svg b/resources/icons/lock.svg index e679bea758..291cf61c6e 100644 --- a/resources/icons/lock.svg +++ b/resources/icons/lock.svg @@ -1,3 +1,3 @@ - + diff --git a/resources/icons/lock_opened.svg b/resources/icons/lock_opened.svg new file mode 100644 index 0000000000..43eb95435b --- /dev/null +++ b/resources/icons/lock_opened.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/status_im/models/browser.cljs b/src/status_im/models/browser.cljs index 96cc56e684..a39b5b4042 100644 --- a/src/status_im/models/browser.cljs +++ b/src/status_im/models/browser.cljs @@ -2,7 +2,9 @@ (:require [status-im.data-store.browser :as browser-store] [status-im.data-store.dapp-permissions :as dapp-permissions] [status-im.i18n :as i18n] - [status-im.constants :as constants])) + [status-im.constants :as constants] + [status-im.ui.screens.browser.default-dapps :as default-dapps] + [status-im.utils.http :as http])) (defn get-current-url [{:keys [history history-index]}] (when (and history-index history) @@ -14,8 +16,15 @@ (defn can-go-forward? [{:keys [history-index history]}] (< history-index (dec (count history)))) +(defn check-if-dapp-in-list [{:keys [history history-index] :as browser}] + (let [history-host (http/url-host (try (nth history history-index) (catch js/Error _))) + dapp (first (filter #(= history-host (http/url-host (:dapp-url %))) (apply concat (mapv :data default-dapps/all))))] + (if dapp + (assoc browser :dapp? true :name (:name dapp)) + (assoc browser :dapp? false :name (i18n/label :t/browser))))) + (defn update-browser-fx [{:keys [db now]} browser] - (let [updated-browser (assoc browser :timestamp now)] + (let [updated-browser (check-if-dapp-in-list (assoc browser :timestamp now))] {:db (update-in db [:browser/browsers (:browser-id updated-browser)] merge updated-browser) :data-store/tx [(browser-store/save-browser-tx updated-browser)]})) diff --git a/src/status_im/translations/en.cljs b/src/status_im/translations/en.cljs index 2d56fc4719..891598163d 100644 --- a/src/status_im/translations/en.cljs +++ b/src/status_im/translations/en.cljs @@ -700,7 +700,8 @@ :dapp "ÐApp" :selected "Selected" :selected-dapps "Selected ÐApps" - :browser-warning "Connection is not proven secure. Make sure you trust this site before signing transactions or entering personal data." + :browser-secure "Connection is secure. Make sure you really trust this site before signing transactions or entering personal data." + :browser-not-secure "Connection is not secure! Do not sign transactions or send personal data on this site." :make-sure-you-trust-dapp "Make sure that you trust this DApp" :would-like-to-access "Would like to Access" :your-contact-code "Your Contact Code"}) \ No newline at end of file diff --git a/src/status_im/ui/components/icons/vector_icons.cljs b/src/status_im/ui/components/icons/vector_icons.cljs index a558433904..53ad9d3e5b 100644 --- a/src/status_im/ui/components/icons/vector_icons.cljs +++ b/src/status_im/ui/components/icons/vector_icons.cljs @@ -126,6 +126,7 @@ :icons/hidden (components.svg/slurp-svg "./resources/icons/hidden.svg") :icons/in-contacts (components.svg/slurp-svg "./resources/icons/in_contacts.svg") :icons/lock (components.svg/slurp-svg "./resources/icons/lock.svg") + :icons/lock-opened (components.svg/slurp-svg "./resources/icons/lock_opened.svg") :icons/mic (components.svg/slurp-svg "./resources/icons/mic.svg") :icons/ok (components.svg/slurp-svg "./resources/icons/ok.svg") :icons/public (components.svg/slurp-svg "./resources/icons/public.svg") diff --git a/src/status_im/ui/components/tooltip/views.cljs b/src/status_im/ui/components/tooltip/views.cljs index 908c2f5646..960036ef4e 100644 --- a/src/status_im/ui/components/tooltip/views.cljs +++ b/src/status_im/ui/components/tooltip/views.cljs @@ -18,19 +18,17 @@ [react/text {:style (styles/tooltip-text font-size)} label]] [vector-icons/icon :icons/tooltip-triangle {:color color :style styles/tooltip-triangle}]]])) -(views/defview bottom-tooltip-info [label] - (views/letsubs [opened? (reagent/atom true) - bottom-anim-value (animation/create-value -150) +(views/defview bottom-tooltip-info [label on-close] + (views/letsubs [bottom-anim-value (animation/create-value -150) opacity-value (animation/create-value 0)] {:component-did-mount (animations/animate-tooltip -150 bottom-anim-value opacity-value -10)} - (when @opened? - [react/view styles/bottom-tooltip-container - [react/animated-view {:style (styles/tooltip-animated bottom-anim-value opacity-value)} - [vector-icons/icon :icons/tooltip-triangle {:color colors/gray-notifications - :style styles/tooltip-triangle - :container-style {:transform [{:rotate "180deg"}]}}] - [react/view styles/bottom-tooltip-text-container - [react/text {:style styles/bottom-tooltip-text} label] - [react/touchable-highlight {:on-press #(reset! opened? false) - :style styles/close-icon} - [vector-icons/icon :icons/close {:color colors/white}]]]]]))) + [react/view styles/bottom-tooltip-container + [react/animated-view {:style (styles/tooltip-animated bottom-anim-value opacity-value)} + [vector-icons/icon :icons/tooltip-triangle {:color colors/gray-notifications + :style styles/tooltip-triangle + :container-style {:transform [{:rotate "180deg"}]}}] + [react/view styles/bottom-tooltip-text-container + [react/text {:style styles/bottom-tooltip-text} label] + [react/touchable-highlight {:on-press on-close + :style styles/close-icon} + [vector-icons/icon :icons/close {:color colors/white}]]]]])) diff --git a/src/status_im/ui/screens/add_new/open_dapp/views.cljs b/src/status_im/ui/screens/add_new/open_dapp/views.cljs index b0453f0d4c..446b16cd69 100644 --- a/src/status_im/ui/screens/add_new/open_dapp/views.cljs +++ b/src/status_im/ui/screens/add_new/open_dapp/views.cljs @@ -64,7 +64,7 @@ :accessibility-label :open-dapp-button :on-press #(do (re-frame/dispatch [:navigate-to-clean :home]) - (re-frame/dispatch [:open-dapp-in-browser dapp]))}] + (re-frame/dispatch [:open-url-in-browser dapp-url]))}] [components/separator {:margin-left 72}]] [react/view styles/description-container [react/i18n-text {:style styles/gray-label :key :description}] diff --git a/src/status_im/ui/screens/browser/db.cljs b/src/status_im/ui/screens/browser/db.cljs index f8541b8b2e..d425b5eceb 100644 --- a/src/status_im/ui/screens/browser/db.cljs +++ b/src/status_im/ui/screens/browser/db.cljs @@ -10,11 +10,15 @@ (spec/def :browser/history (spec/nilable vector?)) (spec/def :browser/history-index (spec/nilable int?)) (spec/def :browser/loading? (spec/nilable boolean?)) +(spec/def :browser/url-editing? (spec/nilable boolean?)) +(spec/def :browser/show-tooltip (spec/nilable keyword?)) (spec/def :browser/options (allowed-keys :opt-un [:browser/browser-id :browser/loading? + :browser/url-editing? + :browser/show-tooltip :browser/error?])) (spec/def :browser/browser diff --git a/src/status_im/ui/screens/contacts/default_dapps.cljs b/src/status_im/ui/screens/browser/default_dapps.cljs similarity index 96% rename from src/status_im/ui/screens/contacts/default_dapps.cljs rename to src/status_im/ui/screens/browser/default_dapps.cljs index c003e8d154..d96a29f754 100644 --- a/src/status_im/ui/screens/contacts/default_dapps.cljs +++ b/src/status_im/ui/screens/browser/default_dapps.cljs @@ -1,4 +1,4 @@ -(ns status-im.ui.screens.contacts.default-dapps) +(ns status-im.ui.screens.browser.default-dapps) (def all [{:title "Exchanges" @@ -94,11 +94,11 @@ :description "The Beautiful (card) Game"}]} {:title "Social Networks" :data [{:name "Cent" - :dapp-url "https://beta.cent.co" + :dapp-url "https://beta.cent.co/" :photo-path "contacts://cent" :description "Get wisdom, get money"} {:name "Peepeth" - :dapp-url "http://peepeth.com/" + :dapp-url "https://peepeth.com/" :photo-path "contacts://peepeth" :description "Blockchain-powered microblogging"} {:name "Purrbook" @@ -124,6 +124,6 @@ :developer? true}]} {:title "Other: Media" :data [{:name "LivePeer" - :dapp-url "http://livepeer.tv" + :dapp-url "https://media.livepeer.org/" :photo-path "contacts://livepeer" :description "Decentralized video broadcasting"}]}]) diff --git a/src/status_im/ui/screens/browser/events.cljs b/src/status_im/ui/screens/browser/events.cljs index 168ce179cd..5419073235 100644 --- a/src/status_im/ui/screens/browser/events.cljs +++ b/src/status_im/ui/screens/browser/events.cljs @@ -58,29 +58,14 @@ (fn [_ [_ link]] {:browse link})) -(handlers/register-handler-fx - :open-dapp-in-browser - [re-frame/trim-v] - (fn [cofx [{:keys [name dapp-url]}]] - (let [browser {:browser-id name - :name name - :dapp? true - :history-index 0 - :history [(http/normalize-and-decode-url dapp-url)]}] - (model/update-browser-and-navigate cofx browser)))) - (handlers/register-handler-fx :open-url-in-browser [re-frame/trim-v] (fn [cofx [url]] - (let [normalized-url (http/normalize-and-decode-url url) - browser {:browser-id (or (http/url-host normalized-url) - ;; purely as a fallback should url not parse... - (random/id)) - :name (i18n/label :t/browser) - :history-index 0 - :history [normalized-url]}] - (model/update-browser-and-navigate cofx browser)))) + (let [normalized-url (http/normalize-and-decode-url url)] + (model/update-browser-and-navigate cofx {:browser-id (or (http/url-host normalized-url) (random/id)) + :history-index 0 + :history [normalized-url]})))) (handlers/register-handler-fx :open-browser diff --git a/src/status_im/ui/screens/browser/styles.cljs b/src/status_im/ui/screens/browser/styles.cljs index 69ba37ce42..f1de41f12e 100644 --- a/src/status_im/ui/screens/browser/styles.cljs +++ b/src/status_im/ui/screens/browser/styles.cljs @@ -65,18 +65,20 @@ :height 36 :background-color colors/gray-lighter :padding-horizontal 12 - :android {:align-items :flex-start - :margin-left (if show-actions 66 20) - :padding-bottom 6} - :ios {:align-items :center - :margin-horizontal 15}}) + :margin-right 5 + :align-items :center + :android {:margin-left (if show-actions 66 20)} + :ios {:margin-left 20}}) (defstyle url-input - {:flex 1 - :font-size 14 - :letter-spacing -0.2 - :android {:padding 0}}) + {:flex 1 + :font-size 14 + :letter-spacing -0.2 + :margin-horizontal 5 + :android {:padding 0}}) + +(def url-text + {:font-size 14 + :letter-spacing -0.2 + :margin-horizontal 5}) -(def toolbar-content-dapp - {:flex-direction :row - :margin-horizontal 15}) diff --git a/src/status_im/ui/screens/browser/views.cljs b/src/status_im/ui/screens/browser/views.cljs index 9518aa673a..a947459c27 100644 --- a/src/status_im/ui/screens/browser/views.cljs +++ b/src/status_im/ui/screens/browser/views.cljs @@ -11,7 +11,6 @@ [status-im.utils.js-resources :as js-res] [status-im.ui.components.react :as components] [reagent.core :as reagent] - [status-im.ui.components.chat-icon.screen :as chat-icon.screen] [status-im.ui.components.icons.vector-icons :as icons] [status-im.i18n :as i18n] [status-im.utils.ethereum.core :as ethereum] @@ -19,39 +18,42 @@ [status-im.ui.components.tooltip.views :as tooltip] [status-im.models.browser :as model] [status-im.utils.http :as http] - [status-im.ui.components.styles :as components.styles])) - -(views/defview toolbar-content-dapp [name] - (views/letsubs [dapp [:get-dapp-by-name name]] - [react/view - [react/view styles/toolbar-content-dapp - [chat-icon.screen/dapp-icon-browser dapp 36] - [react/view styles/dapp-name - [react/text {:style styles/dapp-name-text - :number-of-lines 1 - :font :toolbar-title - :accessibility-label :dapp-name-text} - name] - [react/i18n-text {:style styles/dapp-text :key :dapp}]]]])) + [status-im.ui.components.styles :as components.styles] + [status-im.ui.components.colors :as colors] + [clojure.string :as string])) (def browser-config (reader/read-string (slurp "./src/status_im/utils/browser_config.edn"))) -(defn toolbar-content [url browser] - (let [url-text (atom url)] +(defn toolbar-content [url {:keys [dapp? history history-index] :as browser} error? url-editing?] + (let [url-text (atom url) + history-url (try (nth history history-index) (catch js/Error _)) + secure? (or dapp? (and (not error?) (string/starts-with? history-url "https://")))] [react/view [react/view (styles/toolbar-content false) - [react/text-input {:on-change-text #(reset! url-text %) - :on-submit-editing #(re-frame/dispatch [:update-browser-on-nav-change - browser - (http/normalize-and-decode-url @url-text) - false]) - :auto-focus (not url) - :placeholder (i18n/label :t/enter-url) - :auto-capitalize :none - :auto-correct false - :default-value url - :style styles/url-input}]]])) + [react/touchable-highlight {:on-press #(re-frame/dispatch [:update-browser-options + {:show-tooltip (if secure? :secure :not-secure)}])} + (if secure? + [icons/icon :icons/lock {:color colors/green}] + [icons/icon :icons/lock-opened])] + (if url-editing? + [react/text-input {:on-change-text #(reset! url-text %) + :on-blur #(re-frame/dispatch [:update-browser-options {:url-editing? false}]) + :on-submit-editing #(do + (re-frame/dispatch [:update-browser-options {:url-editing? false}]) + (re-frame/dispatch [:update-browser-on-nav-change + browser + (http/normalize-and-decode-url @url-text) + false])) + :placeholder (i18n/label :t/enter-url) + :auto-capitalize :none + :auto-correct false + :auto-focus true + :default-value url + :ellipsize :end + :style styles/url-input}] + [react/touchable-highlight {:style {:flex 1} :on-press #(re-frame/dispatch [:update-browser-options {:url-editing? true}])} + [react/text {:style styles/url-text} (http/url-host url)]])]])) (defn- web-view-error [_ code desc] (reagent/as-element @@ -75,8 +77,8 @@ (views/defview browser [] (views/letsubs [webview (atom nil) {:keys [address]} [:get-current-account] - {:keys [dapp? browser-id name] :as browser} [:get-current-browser] - {:keys [error? loading?]} [:get :browser/options] + {:keys [browser-id] :as browser} [:get-current-browser] + {:keys [error? loading? url-editing? show-tooltip]} [:get :browser/options] rpc-url [:get :rpc-url] network-id [:get-network-id]] (let [can-go-back? (model/can-go-back? browser) @@ -92,9 +94,7 @@ (re-frame/dispatch [:navigate-back]) (when error? (re-frame/dispatch [:remove-browser browser-id]))))] - (if dapp? - [toolbar-content-dapp name] - [toolbar-content url browser]) + [toolbar-content url browser error? url-editing?] [toolbar.view/actions [{:icon :icons/wallet :icon-opts {:color :black} :handler #(re-frame/dispatch [:navigate-to-modal :wallet-modal])}]]] @@ -142,6 +142,9 @@ [react/view {:flex 1}] [react/touchable-highlight {:on-press #(.reload @webview)} [icons/icon :icons/refresh]]] - (when-not dapp? + (when show-tooltip [tooltip/bottom-tooltip-info - (i18n/label :t/browser-warning)])]))) \ No newline at end of file + (if (= show-tooltip :secure) + (i18n/label :t/browser-secure) + (i18n/label :t/browser-not-secure)) + #(re-frame/dispatch [:update-browser-options {:show-tooltip nil}])])]))) \ No newline at end of file diff --git a/src/status_im/ui/screens/contacts/events.cljs b/src/status_im/ui/screens/contacts/events.cljs index 4778734ff3..51e46ee289 100644 --- a/src/status_im/ui/screens/contacts/events.cljs +++ b/src/status_im/ui/screens/contacts/events.cljs @@ -2,7 +2,7 @@ (:require [re-frame.core :as re-frame] [status-im.i18n :as i18n] [status-im.ui.screens.add-new.new-chat.db :as new-chat.db] - [status-im.ui.screens.contacts.default-dapps :as default-dapps] + [status-im.ui.screens.browser.default-dapps :as default-dapps] [status-im.utils.handlers :as handlers] [status-im.utils.handlers-macro :as handlers-macro] [status-im.utils.js-resources :as js-res] diff --git a/src/status_im/utils/http.cljs b/src/status_im/utils/http.cljs index cc5952961f..77273ae509 100644 --- a/src/status_im/utils/http.cljs +++ b/src/status_im/utils/http.cljs @@ -71,7 +71,7 @@ (try (when-let [host (.getDomain (goog.Uri. url))] (when-not (string/blank? host) - host)) + (string/replace host #"www." ""))) (catch :default _ nil))) (defn parse-payload [o] diff --git a/test/cljs/status_im/test/browser/events.cljs b/test/cljs/status_im/test/browser/events.cljs index a04f1e6a90..85c2122bb3 100644 --- a/test/cljs/status_im/test/browser/events.cljs +++ b/test/cljs/status_im/test/browser/events.cljs @@ -43,16 +43,14 @@ (re-frame/dispatch [:initialize-browsers]) (let [browsers (re-frame/subscribe [:browsers]) - dapp1-url "test.com" + dapp1-url "cryptokitties.co" dapp2-url "http://test2.com"] (testing "open and remove dapps" (is (zero? (count @browsers))) - (re-frame/dispatch [:open-dapp-in-browser {:name "Test Dapp" - :dapp-url dapp1-url - :description "Test description"}]) + (re-frame/dispatch [:open-url-in-browser dapp1-url]) (is (= 1 (count @browsers))) @@ -69,7 +67,7 @@ (is (and (= [(str "http://" dapp1-url) (:history browser1)]) (= [dapp2-url] (:history browser2))))) - (re-frame/dispatch [:remove-browser "Test Dapp"]) + (re-frame/dispatch [:remove-browser dapp1-url]) (is (= 1 (count @browsers))))