From a95520067f3f751f29406ae7012f16f5c84e3927 Mon Sep 17 00:00:00 2001 From: Volodymyr Kozieiev Date: Wed, 16 Sep 2020 11:51:36 +0300 Subject: [PATCH] Added ui for asking webview page permissions Signed-off-by: Volodymyr Kozieiev --- src/status_im/constants.cljs | 3 +- src/status_im/events.cljs | 5 + src/status_im/multiaccounts/core.cljs | 7 ++ src/status_im/ui/screens/browser/styles.cljs | 35 +++++++ src/status_im/ui/screens/browser/views.cljs | 99 +++++++++++++++---- .../privacy_and_security_settings/views.cljs | 12 ++- status-go-version.json | 6 +- translations/en.json | 4 + 8 files changed, 147 insertions(+), 24 deletions(-) diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index a50cff4271..6b359a419c 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -122,7 +122,8 @@ :currency :usd :appearance 0 :waku-enabled true - :log-level config/log-level}) + :log-level config/log-level + :webview-allow-permission-requests? false}) (defn default-visible-tokens [chain] (get-in default-multiaccount [:wallet/visible-tokens chain])) diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index 43b11713a9..0673e31696 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -119,6 +119,11 @@ (fn [cofx [_ private?]] (multiaccounts/switch-preview-privacy-mode cofx private?))) +(handlers/register-handler-fx + :multiaccounts.ui/webview-permission-requests-switched + (fn [cofx [_ enabled?]] + (multiaccounts/switch-webview-permission-requests? cofx enabled?))) + (handlers/register-handler-fx :multiaccounts.ui/wallet-set-up-confirmed (fn [cofx _] diff --git a/src/status_im/multiaccounts/core.cljs b/src/status_im/multiaccounts/core.cljs index c940a672bf..f8648c85cd 100644 --- a/src/status_im/multiaccounts/core.cljs +++ b/src/status_im/multiaccounts/core.cljs @@ -103,6 +103,13 @@ :preview-privacy? (boolean private?) {}))) +(fx/defn switch-webview-permission-requests? + [{:keys [db] :as cofx} enabled?] + (multiaccounts.update/multiaccount-update + cofx + :webview-allow-permission-requests? (boolean enabled?) + {})) + (fx/defn switch-preview-privacy-mode-flag [{:keys [db]}] (let [private? (get-in db [:multiaccount :preview-privacy?])] diff --git a/src/status_im/ui/screens/browser/styles.cljs b/src/status_im/ui/screens/browser/styles.cljs index 5f828400c1..c142c4dfeb 100644 --- a/src/status_im/ui/screens/browser/styles.cljs +++ b/src/status_im/ui/screens/browser/styles.cljs @@ -114,6 +114,41 @@ :width 16 :height 16}) +(def blocked-access-container + {:align-items :center + :margin 16}) + +(def blocked-access-icon-container + {:height 40 + :width 40 + :background-color colors/blue-light + :border-radius 20 + :align-items :center + :justify-content :center}) + +(def blocked-access-camera-icon + {:color colors/blue + :width 20 + :height 20}) + +(def blocked-access-text-container + {:margin-top 16}) + +(def blocked-access-text + {:text-align :center}) + +(def blocked-access-buttons-container + {:flex-direction :row + :justify-content :center + :margin-top 16}) + +(def blocked-access-button-wrapper + {:flex 1 + :margin-horizontal 8}) + +(def blocked-access-button + {:margin-horizontal 8}) + (def permissions-panel-wallet-icon-container {:height 40 :width 40 diff --git a/src/status_im/ui/screens/browser/views.cljs b/src/status_im/ui/screens/browser/views.cljs index 450985ae35..cc228febf6 100644 --- a/src/status_im/ui/screens/browser/views.cljs +++ b/src/status_im/ui/screens/browser/views.cljs @@ -20,7 +20,9 @@ [status-im.utils.debounce :as debounce] [status-im.utils.http :as http] [status-im.utils.js-resources :as js-res] - [status-im.utils.contenthash :as contenthash]) + [status-im.utils.contenthash :as contenthash] + [status-im.ui.components.permissions :as components.permissions] + [quo.core :as quo]) (:require-macros [status-im.utils.views :as views])) (defn toolbar-content [url url-original {:keys [secure?]} url-editing? unsafe?] @@ -103,12 +105,65 @@ :accessibility-label :modal-chat-button} [icons/icon :main-icons/message]]])) +(def resources-to-permissions-map {"android.webkit.resource.VIDEO_CAPTURE" :camera + "android.webkit.resource.AUDIO_CAPTURE" :record-audio}) + +(views/defview request-resources-panel [resources url] + [react/view styles/blocked-access-container + [react/view styles/blocked-access-icon-container + [icons/icon :main-icons/camera styles/blocked-access-camera-icon]] + [react/view styles/blocked-access-text-container + [react/text {:style styles/blocked-access-text} + (str url " " (i18n/label :t/page-would-like-to-use-camera))]] + [react/view styles/blocked-access-buttons-container + [react/view styles/blocked-access-button-wrapper + [quo/button + {:theme :positive + :style styles/blocked-access-button + :on-press (fn [] + (components.permissions/request-permissions + {:permissions (map resources-to-permissions-map resources) + :on-allowed #(.answerPermissionRequest ^js @webview-ref/webview-ref true resources) + :on-denied #(.answerPermissionRequest ^js @webview-ref/webview-ref false)}) + (re-frame/dispatch [:bottom-sheet/hide]))} + (i18n/label :t/allow)]] + [react/view styles/blocked-access-button-wrapper + [quo/button + {:theme :negative + :style styles/blocked-access-button + :on-press (fn [] + (.answerPermissionRequest ^js @webview-ref/webview-ref false) + (re-frame/dispatch [:bottom-sheet/hide]))} + (i18n/label :t/deny)]]]]) + +(views/defview block-resources-panel [url] + [react/view styles/blocked-access-container + [react/view styles/blocked-access-icon-container + [icons/icon :main-icons/camera styles/blocked-access-camera-icon]] + [react/view styles/blocked-access-text-container + [react/text {:style styles/blocked-access-text} + (str url " " (i18n/label :t/page-camera-request-blocked))]]]) + +(defn request-resources-access-for-page [resources url] + (re-frame/dispatch + [:bottom-sheet/show-sheet + {:content (fn [] [request-resources-panel resources url]) + :show-handle? false + :backdrop-dismiss? false + :disable-drag? true + :back-button-cancel false}])) + +(defn block-resources-access-and-notify-user [url] + (.answerPermissionRequest ^js @webview-ref/webview-ref false) + (re-frame/dispatch [:bottom-sheet/show-sheet + {:content (fn [] [block-resources-panel url])}])) + ;; should-component-update is called only when component's props are changed, ;; that's why it can't be used in `browser`, because `url` comes from subs (views/defview browser-component [{:keys [error? url browser browser-id unsafe? can-go-back? ignore-unsafe can-go-forward? resolving? network-id url-original - show-permission show-tooltip dapp? name dapps-account]}] + show-permission show-tooltip dapp? name dapps-account resources-permission?]}] {:should-component-update (fn [_ _ args] (let [[_ props] args] (not (nil? (:url props)))))} @@ -132,6 +187,10 @@ (debounce/debounce-and-dispatch [:browser/navigation-state-changed % error?] 500)) + + :on-permission-request #(if resources-permission? + (request-resources-access-for-page (-> ^js % .-nativeEvent .-resources) url) + (block-resources-access-and-notify-user url)) ;; Extract event data here due to ;; https://reactjs.org/docs/events.html#event-pooling :on-message #(re-frame/dispatch [:browser/bridge-message-received (.. ^js % -nativeEvent -data)]) @@ -152,7 +211,8 @@ {:keys [browser-id dapp? name unsafe? ignore-unsafe] :as browser} [:get-current-browser] {:keys [url error? loading? url-editing? show-tooltip show-permission resolving?]} [:browser/options] dapps-account [:dapps-account] - network-id [:chain-id]] + network-id [:chain-id] + {:keys [webview-allow-permission-requests?]} [:multiaccount]] (let [can-go-back? (browser/can-go-back? browser) can-go-forward? (browser/can-go-forward? browser) url-original (browser/get-current-url browser)] @@ -161,19 +221,20 @@ [react/view (when loading? [connectivity/loading-indicator window-width])] - [browser-component {:dapp? dapp? - :error? error? - :url url - :url-original url-original - :browser browser - :browser-id browser-id - :unsafe? unsafe? - :ignore-unsafe ignore-unsafe - :can-go-back? can-go-back? - :can-go-forward? can-go-forward? - :resolving? resolving? - :network-id network-id - :show-permission show-permission - :show-tooltip show-tooltip - :name name - :dapps-account dapps-account}]]))) + [browser-component {:dapp? dapp? + :error? error? + :url url + :url-original url-original + :browser browser + :browser-id browser-id + :unsafe? unsafe? + :ignore-unsafe ignore-unsafe + :can-go-back? can-go-back? + :can-go-forward? can-go-forward? + :resolving? resolving? + :network-id network-id + :show-permission show-permission + :show-tooltip show-tooltip + :name name + :dapps-account dapps-account + :resources-permission? webview-allow-permission-requests?}]]))) diff --git a/src/status_im/ui/screens/privacy_and_security_settings/views.cljs b/src/status_im/ui/screens/privacy_and_security_settings/views.cljs index 2ccf37c7ca..c82698b369 100644 --- a/src/status_im/ui/screens/privacy_and_security_settings/views.cljs +++ b/src/status_im/ui/screens/privacy_and_security_settings/views.cljs @@ -14,7 +14,7 @@ [quo/separator {:style {:margin-vertical 8}}]) (views/defview privacy-and-security [] - (views/letsubs [{:keys [mnemonic preview-privacy?]} [:multiaccount] + (views/letsubs [{:keys [mnemonic preview-privacy? webview-allow-permission-requests?]} [:multiaccount] supported-biometric-auth [:supported-biometric-auth] auth-method [:auth-method] keycard? [:keycard-multiaccount?]] @@ -63,6 +63,16 @@ :on-press #(re-frame/dispatch [:multiaccounts.ui/preview-privacy-mode-switched ((complement boolean) preview-privacy?)])}] + (when platform/android? + [quo/list-item {:size :small + :title (i18n/label :t/webview-camera-permission-requests) + :active webview-allow-permission-requests? + :accessory :switch + :subtitle (i18n/label :t/webview-camera-permission-requests-subtitle) + :subtitle-max-lines 2 + :on-press #(re-frame/dispatch + [:multiaccounts.ui/webview-permission-requests-switched + ((complement boolean) webview-allow-permission-requests?)])}]) ;; TODO(rasom): remove this condition when kk support will be added (when-not keycard? [separator]) diff --git a/status-go-version.json b/status-go-version.json index 04fba1767f..a5aff0ce9d 100644 --- a/status-go-version.json +++ b/status-go-version.json @@ -2,7 +2,7 @@ "_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh ' instead", "owner": "status-im", "repo": "status-go", - "version": "v0.61.1", - "commit-sha1": "61b345ff3395e4d031da1c4b497cc431a4ab2177", - "src-sha256": "1dg9w9fdi5isdc72ydxqgin6bg8b7jqkavjs2x8bvl9lhf2mqm3c" + "version": "v0.61.2", + "commit-sha1": "8f83c5f462de854fa9b616273ccfdd4b0bda4748", + "src-sha256": "1ng699jljs9gjvnpfig73xi5gs8182amab87w6lavvrrdxxzdnr2" } diff --git a/translations/en.json b/translations/en.json index 27b5532223..81dadfdc7d 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1243,6 +1243,10 @@ "update-to-see-image": "Update to latest version to see a nice image here!", "update-to-listen-audio": "Update to latest version to listen to an audio message here!", "update-to-see-sticker": "Update to latest version to see a nice sticker here!", + "webview-camera-permission-requests" : "Webview camera permission requests", + "webview-camera-permission-requests-subtitle" : "When enabled, websites and dapps can ask to use your camera", + "page-would-like-to-use-camera" : "would like to use your camera", + "page-camera-request-blocked" : "camera requests blocked. To enable camera requests go to Settings", "nickname": "Nickname", "add-nickname": "Add a nickname (optional)", "nickname-description": "Nicknames help you identify others in Status.\nOnly you can see the nicknames you’ve added",