[#17347] move [status-im.utils.http :as http] to status-im2 (#17350)

This commit is contained in:
flexsurfer 2023-09-20 14:16:07 +02:00 committed by GitHub
parent a15c9788fe
commit 6a169bd0bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 123 additions and 305 deletions

View File

@ -707,7 +707,7 @@ SPEC CHECKSUMS:
FBLazyVector: a8af91c2b5a0029d12ff6b32e428863d63c48991
FBReactNativeSpec: 1b2309b096448a1dc9d0c43999216f8fda809ae8
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 166d178815c300e8126de9a7900101814eb16253
glog: d93527a855523adb8c113837db4be68fb00e230d
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef
@ -772,7 +772,7 @@ SPEC CHECKSUMS:
RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e
RNPermissions: ad71dd4f767ec254f2cd57592fbee02afee75467
RNReactNativeHapticFeedback: 2566b468cc8d0e7bb2f84b23adc0f4614594d071
RNReanimated: b3b67ebe099c0b0e7b5c7386b18d2468e29c9d41
RNReanimated: 43adb0307a62c1ce9694f36f124ca3b51a15272a
RNShare: d82e10f6b7677f4b0048c23709bd04098d5aee6c
RNStaticSafeAreaInsets: 055ddbf5e476321720457cdaeec0ff2ba40ec1b8
RNSVG: 80584470ff1ffc7994923ea135a3e5ad825546b9
@ -785,6 +785,6 @@ SPEC CHECKSUMS:
TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4
Yoga: d24d6184b6b85f742536bd93bd07d69d7b9bb4c1
PODFILE CHECKSUM: 8df67467da1e4e60ec164479744536c6f8fc98ed
PODFILE CHECKSUM: ac30a0172ff0126b6f307c20f34c47ce0ebf278f
COCOAPODS: 1.12.0

View File

@ -46,7 +46,6 @@
"react-native-dialogs": "^1.0.4",
"react-native-draggable-flatlist": "^4.0.1",
"react-native-fast-image": "^8.5.11",
"react-native-fetch-polyfill": "^1.1.2",
"react-native-fs": "^2.14.1",
"react-native-gesture-handler": "2.6.1",
"react-native-gifted-charts": "git+https://github.com/status-im/react-native-gifted-charts.git#refs/tags/1.3.2-status.1",

View File

@ -17,7 +17,7 @@
[status-im.signing.core :as signing]
[status-im.ui.components.list-selection :as list-selection]
[utils.re-frame :as rf]
[status-im.utils.http :as http]
[utils.url :as url]
[status-im.utils.platform :as platform]
[status-im.utils.random :as random]
[status-im.utils.types :as types]
@ -75,7 +75,7 @@
(defn check-if-phishing-url
[{:keys [history history-index] :as browser}]
(let [history-host (http/url-host (try (nth history history-index) (catch js/Error _)))]
(let [history-host (url/url-host (try (nth history history-index) (catch js/Error _)))]
(cond-> browser history-host (assoc :unsafe? (eth-phishing-detect history-host)))))
(defn resolve-ens-contenthash-callback
@ -88,7 +88,7 @@
[{:keys [db]} {:keys [error? resolved-url]}]
(when (not error?)
(let [current-url (get-current-url (get-current-browser db))
host (http/url-host current-url)]
host (url/url-host current-url)]
(if (and (not resolved-url) (ens/is-valid-eth-name? host))
{:db (update db :browser/options assoc :resolving? true)
:browser/resolve-ens-contenthash {:chain-id (ethereum/chain-id db)
@ -162,7 +162,7 @@
{:events [:browser/ignore-unsafe]}
[cofx]
(let [browser (get-current-browser (:db cofx))
host (http/url-host (get-current-url browser))]
host (url/url-host (get-current-url browser))]
(update-browser cofx (assoc browser :ignore-unsafe host))))
(defn can-go-forward?
@ -194,7 +194,7 @@
{:events [:browser.callback/resolve-ens-multihash-success]}
[{:keys [db] :as cofx} url]
(let [current-url (get-current-url (get-current-browser db))
host (http/url-host current-url)
host (url/url-host current-url)
path (subs current-url (+ (.indexOf ^js current-url host) (count host)))
gateway url]
(rf/merge cofx
@ -247,9 +247,9 @@
(not= (.indexOf ^js url (second v)) -1))
(:resolved-ens options)))
resolved-url (if resolved-ens
(http/normalize-url (string/replace url
(second resolved-ens)
(first resolved-ens)))
(url/normalize-url (string/replace url
(second resolved-ens)
(first resolved-ens)))
url)]
(rf/merge cofx
(update-browser-history browser resolved-url)
@ -282,7 +282,7 @@
{:events [:browser.ui/url-submitted]}
[cofx url]
(let [browser (get-current-browser (:db cofx))
normalized-url (http/normalize-and-decode-url url)]
normalized-url (url/normalize-and-decode-url url)]
(if (links/universal-link? normalized-url)
{:dispatch [:universal-links/handle-url normalized-url]}
(rf/merge cofx
@ -296,7 +296,7 @@
If the browser is reused, the history is flushed"
{:events [:browser.ui/open-url]}
[{:keys [db] :as cofx} url]
(let [normalized-url (http/normalize-and-decode-url url)
(let [normalized-url (url/normalize-and-decode-url url)
browser {:browser-id (random/id)
:history-index 0
:history [normalized-url]}]
@ -503,7 +503,7 @@
{:keys [dapp? name]} browser
dapp-name (if dapp?
name
(http/url-host
(url/url-host
url-original))]
(cond
(and (= type constants/history-state-changed)

View File

@ -1,7 +1,7 @@
(ns status-im.browser.core-test
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.browser.core :as browser]
[status-im.utils.http :as http]))
[utils.url :as url]))
(defn has-wrong-properties?
[result dapp-url expected-browser]
@ -16,7 +16,7 @@
(defn get-dapp-id
[result dapp-url]
(some #(when (= (http/normalize-and-decode-url dapp-url) (first (:history %))) (:browser-id %))
(some #(when (= (url/normalize-and-decode-url dapp-url) (first (:history %))) (:browser-id %))
(vals (get-in result [:db :browser/browsers]))))
(deftest browser-test

View File

@ -17,7 +17,6 @@
status-im.currency.core
status-im.ethereum.subscriptions
status-im.fleet.core
status-im.http.core
[utils.i18n :as i18n]
[status-im.keycard.core :as keycard]
status-im.log-level.core

View File

@ -1,11 +0,0 @@
(ns status-im.http.core
(:require [re-frame.core :as re-frame]
[status-im.utils.http :as http]))
(re-frame/reg-fx
:http-post
(fn [{:keys [url data response-validator on-success on-error timeout-ms opts]}]
(let [all-opts (assoc opts
:valid-response? response-validator
:timeout-ms timeout-ms)]
(http/post url data on-success on-error all-opts))))

View File

@ -5,8 +5,6 @@
[utils.i18n :as i18n]
[status-im.node.core :as node]
[utils.re-frame :as rf]
[status-im.utils.http :as http]
[status-im.utils.types :as types]
[status-im2.navigation.events :as navigation]))
(def url-regex
@ -97,31 +95,8 @@
(rf/defn connect
{:events [::connect-network-pressed]}
[{:keys [db] :as cofx} network-id]
(if-let [config (get-in db [:networks/networks network-id :config])]
(if-let [upstream-url (get-in config [:UpstreamConfig :URL])]
{:http-post {:url upstream-url
:data (types/clj->json {:jsonrpc "2.0"
:method "net_version"
:id 2})
:opts {:headers {"Content-Type" "application/json"}}
:on-success (fn [{:keys [response-body]}]
(let [response (http/parse-payload response-body)
expected-network-id (:NetworkId config)
rpc-network-id (when-let [res (:result response)]
(js/parseInt res))]
(if (and network-id (= expected-network-id rpc-network-id))
(re-frame/dispatch [::connect-success network-id])
(re-frame/dispatch [::connect-failure
(if (not= expected-network-id rpc-network-id)
(i18n/label :t/network-invalid-network-id)
(i18n/label :t/network-invalid-url))]))))
:on-error (fn [{:keys [response-body status-code]}]
(let [reason (if status-code
(i18n/label :t/network-invalid-status-code
{:code status-code})
(str response-body))]
(re-frame/dispatch [::connect-failure reason])))}}
(connect-success cofx network-id))
(if (get-in db [:networks/networks network-id :config])
(connect-success cofx network-id)
(connect-failure cofx "A network with the specified id doesn't exist")))
(rf/defn delete

View File

@ -11,7 +11,7 @@
[native-module.core :as native-module]
[status-im.ethereum.stateofus :as stateofus]
[utils.validators :as validators]
[status-im.utils.http :as http]
[utils.url :as url]
[status-im.utils.wallet-connect :as wallet-connect]
[taoensso.timbre :as log]
[utils.security.core :as security]))
@ -60,7 +60,7 @@
(defn parse-query-params
[url]
(let [url (goog.Uri. url)]
(http/query->map (.getQuery url))))
(url/query->map (.getQuery url))))
(defn match-uri
[uri]
@ -247,7 +247,7 @@
(ethereum/address? uri)
(cb (address->eip681 uri))
(http/url? uri)
(url/url? uri)
(cb (match-browser-string uri))
(wallet-connect/url? uri)

View File

@ -4,7 +4,7 @@
[status-im.ui.components.action-sheet :as action-sheet]
[status-im.ui.components.dialog :as dialog]
[status-im.ui.components.react :as react]
[status-im.utils.http :as http]
[utils.url :as url]
[status-im.utils.platform :as platform]))
(defn open-share
@ -29,12 +29,12 @@
:options [{:label (i18n/label :t/browsing-open-in-status)
:action #(re-frame/dispatch [:browser.ui/open-url link])}
{:label (i18n/label (platform-web-browser))
:action #(.openURL ^js react/linking (http/normalize-url link))}]
:action #(.openURL ^js react/linking (url/normalize-url link))}]
:cancel-text (i18n/label :t/browsing-cancel)}))
(defn browse-in-web-browser
[link]
(show {:title (i18n/label :t/browsing-title)
:options [{:label (i18n/label (platform-web-browser))
:action #(.openURL ^js react/linking (http/normalize-url link))}]
:action #(.openURL ^js react/linking (url/normalize-url link))}]
:cancel-text (i18n/label :t/browsing-cancel)}))

View File

@ -13,7 +13,7 @@
[status-im.ui.screens.browser.empty-tab.styles :as styles]
[status-im.ui.screens.browser.views :as browser]
[status-im.ui.screens.wallet.components.views :as components]
[status-im.utils.http :as http])
[utils.url :as url])
(:require-macros [status-im.utils.views :as views]))
(defn hide-sheet-and-dispatch
@ -67,7 +67,7 @@
[react/image
{:onLoad #(reset! loaded true)
:style {:width 32 :height 32 :position :absolute :top 4 :left 4}
:source {:uri (str "https://" (http/url-host url) "/favicon.ico")}}])
:source {:uri (str "https://" (url/url-host url) "/favicon.ico")}}])
(when-not @loaded
[react/view
{:width 40

View File

@ -10,7 +10,7 @@
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.react :as react]
[status-im.ui.screens.wallet.components.views :as components]
[status-im.utils.http :as http]
[utils.url :as url]
[status-im.utils.utils :as utils]))
(defn hide-sheet-and-dispatch
@ -45,7 +45,7 @@
permissions @(re-frame/subscribe [:dapps/permissions])
fav? (get bookmarks url)
connected? (some #{constants/dapp-permission-web3}
(get-in permissions [(http/url-host url) :permissions]))]
(get-in permissions [(url/url-host url) :permissions]))]
[react/view {:flex 1}
[quo/button
{:style {:align-self :flex-end
@ -94,7 +94,7 @@
:chevron true
:on-press #(hide-sheet-and-dispatch
[:bottom-sheet/show-sheet-old
{:content (wallet-connection (http/url-host url) account)}])}]
{:content (wallet-connection (url/url-host url) account)}])}]
[quo/list-item
{:theme :accent
:title (i18n/label :t/connect-wallet)

View File

@ -11,7 +11,7 @@
[status-im.ui.components.react :as react]
[status-im.ui.components.topbar :as topbar]
[status-im.ui.screens.wallet.components.views :as components]
[status-im.utils.http :as http]))
[utils.url :as url]))
(defn list-item
[_]
@ -35,7 +35,7 @@
[react/image
{:onLoad #(reset! loaded true)
:style {:width 32 :height 32 :position :absolute :top 4 :left 4}
:source {:uri (str "https://" (http/url-host url) "/favicon.ico")}}])
:source {:uri (str "https://" (url/url-host url) "/favicon.ico")}}])
(when-not @loaded
[react/view
{:width 40

View File

@ -21,7 +21,7 @@
[status-im.ui.screens.browser.site-blocked.views :as site-blocked.views]
[status-im.ui.screens.browser.styles :as styles]
[status-im.ui.screens.wallet.components.views :as components]
[status-im.utils.http :as http]
[utils.url :as url]
[status-im.utils.js-resources :as js-res]
[utils.debounce :as debounce])
(:require-macros [status-im.utils.views :as views]))
@ -52,7 +52,7 @@
[react/touchable-highlight
{:style styles/url-text-container
:on-press #(re-frame/dispatch [:browser.ui/url-input-pressed])}
[react/text {:number-of-lines 1} (http/url-host url-original)]])
[react/text {:number-of-lines 1} (url/url-host url-original)]])
(when-not unsafe?
[react/touchable-highlight
{:on-press #(.reload ^js @webview-ref/webview-ref)
@ -192,7 +192,7 @@
{:flex 1
:elevation -10}
[react/view {:flex 1}
(if (and unsafe? (not= (http/url-host url) ignore-unsafe))
(if (and unsafe? (not= (url/url-host url) ignore-unsafe))
[site-blocked.views/view
{:can-go-back? can-go-back?
:site browser-id}]

View File

@ -1,196 +0,0 @@
(ns status-im.utils.http
(:require ["react-native-fetch-polyfill" :default fetch]
[clojure.string :as string]
[status-im.utils.utils :as utils]
[taoensso.timbre :as log])
(:refer-clojure :exclude [get]))
;; Default HTTP request timeout ms
(def http-request-default-timeout-ms 3000)
(defn- response-headers
[^js response]
(let [entries (es6-iterator-seq (.entries ^js (.-headers response)))]
(reduce #(assoc %1 (string/trim (string/lower-case (first %2))) (string/trim (second %2)))
{}
entries)))
(defn raw-post
"Performs an HTTP POST request and returns raw results :status :headers :body."
([url body on-success] (raw-post url body on-success nil))
([url body on-success on-error]
(raw-post url body on-success on-error nil))
([url body on-success on-error {:keys [timeout-ms headers]}]
(-> (fetch
url
(clj->js {:method "POST"
:headers (merge {"Cache-Control" "no-cache"} headers)
:body body
:timeout (or timeout-ms http-request-default-timeout-ms)}))
(.then (fn [^js response]
(->
(.text response)
(.then (fn [body]
(on-success {:status (.-status response)
:headers (response-headers response)
:body body}))))))
(.catch (or on-error
(fn [error]
(utils/show-popup "Error" url (str error))))))))
;; FIXME: Should be more extensible and accept multiple methods
(defn post
"Performs an HTTP POST request"
([url data on-success]
(post url data on-success nil))
([url data on-success on-error]
(post url data on-success on-error nil))
([url data on-success on-error
{:keys [valid-response? method timeout-ms headers]
:or {method "POST"}}]
(-> (fetch
url
(clj->js (merge {:method method
:body data
:timeout (or timeout-ms http-request-default-timeout-ms)}
(when headers
{:headers headers}))))
(.then (fn [^js response]
(-> (.text response)
(.then (fn [response-body]
(let [ok? (.-ok response)
ok?' (if valid-response?
(and ok? (valid-response? response))
ok?)]
{:response-body response-body
:ok? ok?'
:status-text (.-statusText response)
:status-code (.-status response)}))))))
(.then (fn [{:keys [ok?] :as data}]
(cond
(and on-success ok?)
(on-success data)
(and on-error (not ok?))
(on-error data)
:else false)))
(.catch (fn [error]
(if on-error
(on-error {:response-body error})
(utils/show-popup "Error" url (str error))))))))
(defn get
"Performs an HTTP GET request"
([url] (get url nil))
([url on-success] (get url on-success nil))
([url on-success on-error]
(get url on-success on-error nil))
([url on-success on-error params]
(get url on-success on-error params nil))
([url on-success on-error {:keys [valid-response? timeout-ms]} headers]
(-> (fetch
url
(clj->js {:method "GET"
:headers (merge {"Cache-Control" "no-cache"} headers)
:timeout (or timeout-ms http-request-default-timeout-ms)}))
(.then (fn [^js response]
(->
(.text response)
(.then (fn [response-body]
(let [ok? (.-ok response)
ok?' (if valid-response?
(and ok? (valid-response? response))
ok?)]
[response-body ok?']))))))
(.then (fn [[response ok?]]
(cond
(and on-success ok?)
(on-success response)
(and on-error (not ok?))
(on-error response)
:else false)))
(.catch (or on-error #())))))
(defn normalize-url
[url]
(str (when (and (string? url)
(not (re-find #"^[a-zA-Z-_]+:/" url)))
"https://")
((fnil string/trim "") url)))
(def normalize-and-decode-url (comp js/decodeURI normalize-url))
(defn url-host
[url]
(try
(when-let [host (.getDomain ^js (goog.Uri. url))]
(when-not (string/blank? host)
(string/replace host #"www." "")))
(catch :default _ nil)))
(defn url?
[s]
(try
(when-let [host (.getDomain ^js (goog.Uri. s))]
(not (string/blank? host)))
(catch :default _ nil)))
(defn parse-payload
[o]
(when o
(try
(js->clj (js/JSON.parse o)
:keywordize-keys
true)
(catch :default _
(log/debug (str "Failed to parse " o))))))
(defn url-sanitized?
[uri]
(not (nil? (re-find #"^(https:)([/|.|\w|\s|-])*\.(?:jpg|svg|png)$" uri))))
(defn- split-param
[param]
(->
(string/split param #"=")
(concat (repeat ""))
(->>
(take 2))))
(defn- url-decode
[string]
(some-> string
str
(string/replace #"\+" "%20")
(js/decodeURIComponent)))
(defn query->map
[qstr]
(when-not (string/blank? qstr)
(some->> (string/split qstr #"&")
seq
(mapcat split-param)
(map url-decode)
(apply hash-map))))
(defn filter-letters-numbers-and-replace-dot-on-dash
[^js value]
(let [cc (.charCodeAt value 0)]
(cond (or (and (> cc 96) (< cc 123))
(and (> cc 64) (< cc 91))
(and (> cc 47) (< cc 58)))
value
(= cc 46)
"-")))
(defn topic-from-url
[url]
(string/lower-case (apply str (map filter-letters-numbers-and-replace-dot-on-dash (url-host url)))))
(defn replace-port
[url new-port]
(when url
(string/replace url #"(:\d+)" (str ":" new-port))))

View File

@ -9,7 +9,7 @@
[status-im.qr-scanner.core :as qr-scaner]
[status-im.router.core :as router]
[utils.re-frame :as rf]
[status-im.utils.http :as http]
[utils.url :as url]
[utils.money :as money]
[status-im.utils.universal-links.utils :as links]
[status-im.utils.wallet-connect :as wallet-connect]
@ -140,7 +140,7 @@
(assoc-in message path address))
message
(map vector paths addresses)) uri]))}})
(if (and (http/url? uri) (not ignore-url))
(if (and (url/url? uri) (not ignore-url))
(if (links/universal-link? uri)
{:dispatch [:universal-links/handle-url uri]}
{:browser/show-browser-selection uri})

View File

@ -6,7 +6,7 @@
[react-native.orientation :as orientation]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[status-im.utils.http :as http]
[utils.url :as url]
[status-im2.contexts.chat.lightbox.animations :as anim]
[status-im2.contexts.chat.lightbox.style :as style]
[utils.datetime :as datetime]
@ -45,8 +45,7 @@
(defn drawer
[messages index]
(let [{:keys [content]} (nth messages index)
uri (http/replace-port (:image content)
(rf/sub [:mediaserver/port]))]
uri (url/replace-port (:image content) (rf/sub [:mediaserver/port]))]
[quo/action-drawer
[[{:icon :i/save
:accessibility-label :save-image
@ -65,8 +64,7 @@
(defn share-image
[messages index]
(let [{:keys [content]} (nth messages index)
uri (http/replace-port (:image content)
(rf/sub [:mediaserver/port]))]
uri (url/replace-port (:image content) (rf/sub [:mediaserver/port]))]
(images/share-image uri)))
(defn top-view

View File

@ -11,7 +11,7 @@
[status-im2.contexts.chat.lightbox.zoomable-image.constants :as c]
[status-im2.contexts.chat.lightbox.zoomable-image.style :as style]
[status-im2.contexts.chat.lightbox.zoomable-image.utils :as utils]
[status-im.utils.http :as http]))
[utils.url :as url]))
(defn tap-gesture
[on-tap]
@ -227,7 +227,7 @@
(= curr-orientation orientation/portrait))}
[reanimated/fast-image
(merge
{:source {:uri (http/replace-port (:image content) (rf/sub [:mediaserver/port]))}
{:source {:uri (url/replace-port (:image content) (rf/sub [:mediaserver/port]))}
:native-ID (when focused? :shared-element)
:style (style/image dimensions animations render-data index)}
(when image-dimensions-nil?

View File

@ -8,7 +8,7 @@
[status-im2.contexts.chat.messages.content.image.view :as image]
[status-im2.contexts.chat.messages.content.text.view :as text]
[utils.re-frame :as rf]
[status-im.utils.http :as http]))
[utils.url :as url]))
(def rectangular-style-count 3)
@ -55,8 +55,8 @@
:index index}])}
[fast-image/fast-image
{:style (style/image dimensions index portrait? images-count)
:source {:uri (http/replace-port (:image (:content item))
(rf/sub [:mediaserver/port]))}
:source {:uri (url/replace-port (:image (:content item))
(rf/sub [:mediaserver/port]))}
:native-ID (when (and (= shared-element-id (:message-id item))
(< index constants/max-album-photos))
:shared-element)}]

View File

@ -6,7 +6,7 @@
[status-im2.constants :as constants]
[utils.re-frame :as rf]
[status-im2.contexts.chat.messages.content.text.view :as text]
[status-im.utils.http :as http]))
[utils.url :as url]))
(defn calculate-dimensions
[width height]
@ -19,7 +19,7 @@
(let [insets (safe-area/get-insets)
dimensions (calculate-dimensions (or image-width 1000) (or image-height 1000))
shared-element-id (rf/sub [:shared-element-id])
image-local-url (http/replace-port (:image content) (rf/sub [:mediaserver/port]))]
image-local-url (url/replace-port (:image content) (rf/sub [:mediaserver/port]))]
[:<>
(when (= index 0)
[text/text-content message])

View File

@ -10,7 +10,7 @@
[utils.datetime :as datetime]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[status-im.utils.http :as http]))
[utils.url :as url]))
;; NOTE: Replies support text, image and stickers only.
(defn- get-message-content
@ -21,7 +21,7 @@
constants/content-type-image
(let [image (get-in message [:content :image])
image-local-url (http/replace-port image (rf/sub [:mediaserver/port]))
image-local-url (url/replace-port image (rf/sub [:mediaserver/port]))
photos (when image-local-url [{:uri image-local-url}])]
[quo/activity-logs-photos {:photos photos}])

59
src/utils/url.cljs Normal file
View File

@ -0,0 +1,59 @@
(ns utils.url
(:require [clojure.string :as string]))
(defn normalize-url
[url]
(str (when (and (string? url)
(not (re-find #"^[a-zA-Z-_]+:/" url)))
"https://")
((fnil string/trim "") url)))
(def normalize-and-decode-url (comp js/decodeURI normalize-url))
(defn url-host
[url]
(try
(when-let [host (.getDomain ^js (goog.Uri. url))]
(when-not (string/blank? host)
(string/replace host #"www." "")))
(catch :default _ nil)))
(defn url?
[s]
(try
(when-let [host (.getDomain ^js (goog.Uri. s))]
(not (string/blank? host)))
(catch :default _ nil)))
(defn url-sanitized?
[uri]
(not (nil? (re-find #"^(https:)([/|.|\w|\s|-])*\.(?:jpg|svg|png)$" uri))))
(defn- split-param
[param]
(->
(string/split param #"=")
(concat (repeat ""))
(->>
(take 2))))
(defn- url-decode
[string]
(some-> string
str
(string/replace #"\+" "%20")
(js/decodeURIComponent)))
(defn query->map
[qstr]
(when-not (string/blank? qstr)
(some->> (string/split qstr #"&")
seq
(mapcat split-param)
(map url-decode)
(apply hash-map))))
(defn replace-port
[url new-port]
(when url
(string/replace url #"(:\d+)" (str ":" new-port))))

View File

@ -1,37 +1,37 @@
(ns status-im.utils.http-test
(ns utils.url-test
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.utils.http :as http]))
[utils.url :as url]))
(deftest url-sanitize-check
(testing
"https://storage.googleapis.com/ck-kitty-image/0x06012c8cf97bead5deae237070f9587f8e7a266d/818934.svg"
(testing "it returns true"
(is
(http/url-sanitized?
(url/url-sanitized?
"https://storage.googleapis.com/ck-kitty-image/0x06012c8cf97bead5deae237070f9587f8e7a266d/818934.svg"))))
(testing "https://www.cryptostrikers.com/assets/images/cards/017.svg"
(testing "it returns true"
(is (http/url-sanitized? "https://www.cryptostrikers.com/assets/images/cards/017.svg"))))
(is (url/url-sanitized? "https://www.cryptostrikers.com/assets/images/cards/017.svg"))))
(testing "https://www.etheremon.com/assets/images/mons_origin/025.png"
(testing "it returns true"
(is (http/url-sanitized? "https://www.etheremon.com/assets/images/mons_origin/025.png"))))
(is (url/url-sanitized? "https://www.etheremon.com/assets/images/mons_origin/025.png"))))
(testing "http://www.etheremon.com/assets/images/mons_origin/025.png"
(testing "it returns false"
(is (not (http/url-sanitized? "http://www.etheremon.com/assets/images/mons_origin/025.png")))))
(is (not (url/url-sanitized? "http://www.etheremon.com/assets/images/mons_origin/025.png")))))
(testing "xxx:x \\\\x0Aonerror=javascript:alert(1)"
(testing "it returns false"
(is (not (http/url-sanitized? "xxx:x \\\\x0Aonerror=javascript:alert(1)")))))
(is (not (url/url-sanitized? "xxx:x \\\\x0Aonerror=javascript:alert(1)")))))
(testing
"https://www.etheremon.com/assets/images/mons_origin/025.png'&lt;script&gt;alert(&#39;123&#39;);&lt;/script&gt;"
(testing "it returns false"
(is
(not
(http/url-sanitized?
(url/url-sanitized?
"https://www.etheremon.com/assets/images/mons_origin/025.png'&lt;script&gt;alert(&#39;123&#39;);&lt;/script&gt;")))))
(testing
@ -39,7 +39,7 @@
(testing "it returns false"
(is
(not
(http/url-sanitized?
(url/url-sanitized?
"https://www.etheremon.com/assets/images/mons'&lt;script&gt;alert(&#39;123&#39;);&lt;/script&gt;origin/025.png")))))
(testing
@ -47,7 +47,7 @@
(testing "it returns false"
(is
(not
(http/url-sanitized?
(url/url-sanitized?
"https://www.etheremon.com/assets/images/mons_origin/025.png'><script>\\\\x3Bjavascript:alert(1)</script>")))))
(testing
@ -55,19 +55,19 @@
(testing "it returns false"
(is
(not
(http/url-sanitized?
(url/url-sanitized?
"https://www.etheremon.com/assets/images/mons'><script>\\\\x3Bjavascript:alert(1)</script>origin/025.png"))))))
(deftest url-host-check
(testing "Extract host/domain from URL"
(testing "Valid URL with endpoint"
(is (= "status.im" (http/url-host "https://status.im/testing"))))
(is (= "status.im" (url/url-host "https://status.im/testing"))))
(testing "Valid URL"
(is (= "status.im" (http/url-host "http://status.im"))))
(is (= "status.im" (url/url-host "http://status.im"))))
(testing "Blank domainlocalhost"
(is (nil? (http/url-host "localhost:3000/testing")))))
(is (nil? (url/url-host "localhost:3000/testing")))))
(testing "Return nil for Invalid URL"
(testing "Bad scheme"
(is (nil? (http/url-host "invalid//status.im/testing"))))
(is (nil? (url/url-host "invalid//status.im/testing"))))
(testing "No scheme"
(is (nil? (http/url-host "status.im/testing"))))))
(is (nil? (url/url-host "status.im/testing"))))))

View File

@ -8878,11 +8878,6 @@ react-native-fast-image@^8.5.11:
resolved "https://registry.yarnpkg.com/react-native-fast-image/-/react-native-fast-image-8.5.11.tgz#e3dc969d0e4e8df026646bf18194465aa55cbc2b"
integrity sha512-cNW4bIJg3nvKaheG8vGMfqCt5LMWX9MS5+wMudgKIHbGO51spRr4sgnlhVgwHLcZ5aeNOVJ8CPRxDIWKRq/0QA==
react-native-fetch-polyfill@^1.1.2:
version "1.1.3"
resolved "https://registry.yarnpkg.com/react-native-fetch-polyfill/-/react-native-fetch-polyfill-1.1.3.tgz#a02d9069a2f7108ca0b70b8469085c67cc02949c"
integrity sha512-zr5yXQftuGq+ABGa3n4ZE+vkL1lBsMSePkRINm3/6vlpbwnLXYoijwazTO/W8GjsV4LAgGmzuieZxKO/NxW19A==
react-native-fs@^2.14.1:
version "2.16.6"
resolved "https://registry.yarnpkg.com/react-native-fs/-/react-native-fs-2.16.6.tgz#2901789a43210a35a0ef0a098019bbef3af395fd"