feat: support new universal/deep link format (#17480)

This commit is contained in:
yqrashawn 2023-10-22 08:50:48 +07:00 committed by GitHub
parent ca6fd3df66
commit 04a7f76271
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 159 additions and 110 deletions

View File

@ -62,14 +62,14 @@
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" android:host="join.status.im" /> <data android:scheme="http" android:host="status.app" />
<data android:scheme="https" android:host="join.status.im" /> <data android:scheme="https" android:host="status.app" />
</intent-filter> </intent-filter>
<intent-filter android:autoVerify="true"> <intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="status-im" /> <data android:scheme="status-app" />
<data android:scheme="ethereum" /> <data android:scheme="ethereum" />
</intent-filter> </intent-filter>
</activity> </activity>

View File

@ -33,7 +33,7 @@
<string>im.status.ethereum.applink</string> <string>im.status.ethereum.applink</string>
<key>CFBundleURLSchemes</key> <key>CFBundleURLSchemes</key>
<array> <array>
<string>status-im</string> <string>status-app</string>
</array> </array>
</dict> </dict>
<dict> <dict>

View File

@ -11,7 +11,7 @@
<string>development</string> <string>development</string>
<key>com.apple.developer.associated-domains</key> <key>com.apple.developer.associated-domains</key>
<array> <array>
<string>applinks:join.status.im</string> <string>applinks:status.app</string>
</array> </array>
<key>keychain-access-groups</key> <key>keychain-access-groups</key>
<array> <array>

View File

@ -29,7 +29,7 @@
<string>im.status.ethereum.applink</string> <string>im.status.ethereum.applink</string>
<key>CFBundleURLSchemes</key> <key>CFBundleURLSchemes</key>
<array> <array>
<string>status-im</string> <string>status-app</string>
</array> </array>
</dict> </dict>
<dict> <dict>

View File

@ -11,7 +11,7 @@
<string>development</string> <string>development</string>
<key>com.apple.developer.associated-domains</key> <key>com.apple.developer.associated-domains</key>
<array> <array>
<string>applinks:join.status.im</string> <string>applinks:status.app</string>
</array> </array>
<key>keychain-access-groups</key> <key>keychain-access-groups</key>
<array> <array>

View File

@ -7,7 +7,6 @@
[status-im.ethereum.eip681 :as eip681] [status-im.ethereum.eip681 :as eip681]
[status-im.ethereum.ens :as ens] [status-im.ethereum.ens :as ens]
[status-im.ethereum.stateofus :as stateofus] [status-im.ethereum.stateofus :as stateofus]
[status-im.utils.deprecated-types :as types]
[status-im.utils.wallet-connect :as wallet-connect] [status-im.utils.wallet-connect :as wallet-connect]
[status-im2.constants :as constants] [status-im2.constants :as constants]
[status-im2.contexts.chat.events :as chat.events] [status-im2.contexts.chat.events :as chat.events]
@ -15,29 +14,22 @@
[utils.address :as address] [utils.address :as address]
[utils.ethereum.chain :as chain] [utils.ethereum.chain :as chain]
[utils.security.core :as security] [utils.security.core :as security]
[utils.transforms :as transforms]
[utils.url :as url] [utils.url :as url]
[utils.validators :as validators])) [utils.validators :as validators]))
(def ethereum-scheme "ethereum:") (def ethereum-scheme "ethereum:")
(def uri-schemes ["status-im://" "status-im:"]) (def uri-schemes ["status-app://"])
(def web-prefixes ["https://" "http://" "https://www." "http://www."]) (def web-prefixes ["https://" "http://" "https://www." "http://www."])
(def web2-domain "join.status.im") (def web2-domain "status.app")
(def web-urls (map #(str % web2-domain "/") web-prefixes)) (def web-urls (map #(str % web2-domain "/") web-prefixes))
(def handled-schemes (set (into uri-schemes web-urls))) (def handled-schemes (set (into uri-schemes web-urls)))
(def browser-extractor
{[#"(.*)" :domain] {"" :browser
"/" :browser}})
(def group-chat-extractor
{[#"(.*)" :params] {"" :group-chat
"/" :group-chat}})
(def eip-extractor (def eip-extractor
{#{[:prefix "-" :address] {#{[:prefix "-" :address]
[:address]} [:address]}
@ -47,16 +39,9 @@
(def routes (def routes
["" [""
{handled-schemes {"b/" browser-extractor {handled-schemes {["c/" :community-data] :community
"browser/" browser-extractor ["cc/" :chat-data] :community-chat
["p/" :chat-id] :private-chat ["u/" :user-data] :user}
["cr/" :community-id] :community-requests
["c/" :community-id] :community
["cc/" :chat-id] :community-chat
"g/" group-chat-extractor
["wallet/" :account] :wallet-account
["u/" :user-id] :user
["user/" :user-id] :user}
ethereum-scheme eip-extractor}]) ethereum-scheme eip-extractor}])
(defn parse-query-params (defn parse-query-params
@ -64,9 +49,52 @@
(let [url (goog.Uri. url)] (let [url (goog.Uri. url)]
(url/query->map (.getQuery url)))) (url/query->map (.getQuery url))))
(defn parse-fragment
[url]
(let [url (goog.Uri. url)
fragment (.getFragment url)]
(when-not (string/blank? fragment)
fragment)))
(defn match-uri (defn match-uri
[uri] [uri]
(assoc (bidi/match-route routes uri) :uri uri :query-params (parse-query-params uri))) ;;
(let [;; bidi has trouble parse path with `=` in it extract `=` here and add back to parsed
;; base64url regex based on https://datatracker.ietf.org/doc/html/rfc4648#section-5 may
;; include invalid base64 (invalid length, length of any base64 encoded string must be a
;; multiple of 4)
;; equal-end-of-base64url can be `=`, `==`, `nil`
equal-end-of-base64url
(last (re-find #"^(https|status-app)://(status\.app/)?(c|cc|u)/([a-zA-Z0-9_-]+)(={0,2})#" uri))
uri-without-equal-in-path
(if equal-end-of-base64url (string/replace-first uri equal-end-of-base64url "") uri)
fragment (parse-fragment uri)
ens? (ens/is-valid-eth-name? fragment)
{:keys [handler route-params] :as parsed}
(assoc (bidi/match-route routes uri-without-equal-in-path)
:uri uri
:query-params (parse-query-params uri))]
(cond-> parsed
ens?
(assoc-in [:route-params :ens-name] fragment)
(and (or (= handler :community) (= handler :community-chat)) fragment)
(assoc-in [:route-params :community-id] fragment)
(and equal-end-of-base64url (= handler :community) (:community-data route-params))
(update-in [:route-params :community-data] #(str % equal-end-of-base64url))
(and equal-end-of-base64url (= handler :community-chat) (:chat-data route-params))
(update-in [:route-params :chat-data] #(str % equal-end-of-base64url))
(and equal-end-of-base64url (= handler :user) (:user-data route-params))
(update-in [:route-params :user-data] #(str % equal-end-of-base64url))
(and (= handler :user) fragment)
(assoc-in [:route-params :user-id] fragment))))
(defn match-contact-async (defn match-contact-async
[chain {:keys [user-id ens-name]} callback] [chain {:keys [user-id ens-name]} callback]
@ -84,7 +112,7 @@
user-id user-id
constants/deserialization-key constants/deserialization-key
(fn [response] (fn [response]
(let [{:keys [error]} (types/json->clj response)] (let [{:keys [error]} (transforms/json->clj response)]
(when-not error (when-not error
(match-contact-async (match-contact-async
chain chain
@ -210,41 +238,51 @@
:community)) :community))
(defn handle-uri (defn handle-uri
[chain chats uri cb] [chain _chats uri cb]
(let [{:keys [handler route-params query-params]} (match-uri uri)] (let [{:keys [handler route-params]} (match-uri uri)]
(log/info "[router] uri " uri " matched " handler " with " route-params) (log/info "[router] uri " uri " matched " handler " with " route-params)
(cond (cond
(= handler :browser) ;; ;; NOTE: removed in `match-uri`, might need this in the future
(cb (match-browser uri route-params)) ;; (= handler :browser)
;; (cb (match-browser uri route-params))
(= handler :ethereum) (= handler :ethereum)
(cb (match-eip681 uri)) (cb (match-eip681 uri))
(= handler :user) (and (= handler :user) (:user-id route-params))
(match-contact-async chain route-params cb) (match-contact-async chain route-params cb)
(= handler :private-chat) ;; ;; NOTE: removed in `match-uri`, might need this in the future
(match-private-chat-async chain route-params cb) ;; (= handler :private-chat)
;; (match-private-chat-async chain route-params cb)
(= handler :group-chat) ;; ;; NOTE: removed in `match-uri`, might need this in the future
(cb (match-group-chat chats query-params)) ;; (= handler :group-chat)
;; (cb (match-group-chat chats query-params))
(validators/valid-public-key? uri) (validators/valid-public-key? uri)
(match-contact-async chain {:user-id uri} cb) (match-contact-async chain {:user-id uri} cb)
(= handler :community-requests) ;; ;; NOTE: removed in `match-uri`, might need this in the future
(cb {:type handler :community-id (:community-id route-params)}) ;; (= handler :community-requests)
;; (cb {:type handler :community-id (:community-id route-params)})
(= handler :community) (and (= handler :community) (:community-id route-params))
(cb {:type (community-route-type route-params) (cb {:type (community-route-type route-params)
:community-id (:community-id route-params)}) :community-id (:community-id route-params)})
(= handler :community-chat) ;; ;; TODO: jump to community overview for now, should jump to community channel
(cb {:type handler :chat-id (:chat-id route-params)}) ;; (and (= handler :community-chat) (:chat-id route-params))
;; (cb {:type handler :chat-id (:chat-id route-params)})
(= handler :wallet-account) (and (= handler :community-chat) (:community-id route-params))
(cb (match-wallet-account route-params)) (cb {:type (community-route-type route-params)
:community-id (:community-id route-params)})
;; ;; NOTE: removed in `match-uri`, might need this in the future
;; (= handler :wallet-account)
;; (cb (match-wallet-account route-params))
(address/address? uri) (address/address? uri)
(cb (address->eip681 uri)) (cb (address->eip681 uri))

View File

@ -19,33 +19,41 @@
:query-params (when (= 3 (count expected)) (last expected)) :query-params (when (= 3 (count expected)) (last expected))
:uri uri}) :uri uri})
"status-im://u/statuse2e" "https://status.app/u/G10A4B0JdgwyRww90WXtnP1oNH1ZLQNM0yX0Ja9YyAMjrqSZIYINOHCbFhrnKRAcPGStPxCMJDSZlGCKzmZrJcimHY8BbcXlORrElv_BbQEegnMDPx1g9C5VVNl0fE4y#zQ3shwQPhRuDJSjVGVBnTjCdgXy5i9WQaeVPdGJD6yTarJQSj"
[:user {:user-id "statuse2e"}] [:user
{:user-data
"G10A4B0JdgwyRww90WXtnP1oNH1ZLQNM0yX0Ja9YyAMjrqSZIYINOHCbFhrnKRAcPGStPxCMJDSZlGCKzmZrJcimHY8BbcXlORrElv_BbQEegnMDPx1g9C5VVNl0fE4y"
:user-id "zQ3shwQPhRuDJSjVGVBnTjCdgXy5i9WQaeVPdGJD6yTarJQSj"}]
(str "status-im://user/" public-key) "status-app://u/G10A4B0JdgwyRww90WXtnP1oNH1ZLQNM0yX0Ja9YyAMjrqSZIYINOHCbFhrnKRAcPGStPxCMJDSZlGCKzmZrJcimHY8BbcXlORrElv_BbQEegnMDPx1g9C5VVNl0fE4y#zQ3shwQPhRuDJSjVGVBnTjCdgXy5i9WQaeVPdGJD6yTarJQSj"
[:user {:user-id public-key}] [:user
{:user-data
"G10A4B0JdgwyRww90WXtnP1oNH1ZLQNM0yX0Ja9YyAMjrqSZIYINOHCbFhrnKRAcPGStPxCMJDSZlGCKzmZrJcimHY8BbcXlORrElv_BbQEegnMDPx1g9C5VVNl0fE4y"
:user-id "zQ3shwQPhRuDJSjVGVBnTjCdgXy5i9WQaeVPdGJD6yTarJQSj"}]
"status-im://b/www.cryptokitties.co" "https://status.app/cc/G54AAKwObLdpiGjXnckYzRcOSq0QQAS_CURGfqVU42ceGHCObstUIknTTZDOKF3E8y2MSicncpO7fTskXnoACiPKeejvjtLTGWNxUhlT7fyQS7Jrr33UVHluxv_PLjV2ePGw5GQ33innzeK34pInIgUGs5RjdQifMVmURalxxQKwiuoY5zwIjixWWRHqjHM=#zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11"
[:browser {:domain "www.cryptokitties.c"}] [:community-chat
{:chat-data
"G54AAKwObLdpiGjXnckYzRcOSq0QQAS_CURGfqVU42ceGHCObstUIknTTZDOKF3E8y2MSicncpO7fTskXnoACiPKeejvjtLTGWNxUhlT7fyQS7Jrr33UVHluxv_PLjV2ePGw5GQ33innzeK34pInIgUGs5RjdQifMVmURalxxQKwiuoY5zwIjixWWRHqjHM="
:community-id "zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11"}]
(str "status-im://g/args?a=" public-key "&a1=" chat-name-url "&a2=" chat-id) "status-app://cc/G54AAKwObLdpiGjXnckYzRcOSq0QQAS_CURGfqVU42ceGHCObstUIknTTZDOKF3E8y2MSicncpO7fTskXnoACiPKeejvjtLTGWNxUhlT7fyQS7Jrr33UVHluxv_PLjV2ePGw5GQ33innzeK34pInIgUGs5RjdQifMVmURalxxQKwiuoY5zwIjixWWRHqjHM=#zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11"
[:group-chat {:params "arg"} {"a" public-key "a1" chat-name "a2" chat-id}] [:community-chat
{:chat-data
"G54AAKwObLdpiGjXnckYzRcOSq0QQAS_CURGfqVU42ceGHCObstUIknTTZDOKF3E8y2MSicncpO7fTskXnoACiPKeejvjtLTGWNxUhlT7fyQS7Jrr33UVHluxv_PLjV2ePGw5GQ33innzeK34pInIgUGs5RjdQifMVmURalxxQKwiuoY5zwIjixWWRHqjHM="
:community-id "zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11"}]
(str "https://join.status.im/g/args?a=" public-key "&a1=" chat-name-url "&a2=" chat-id) "https://status.app/c/iyKACkQKB0Rvb2RsZXMSJ0NvbG9yaW5nIHRoZSB3b3JsZCB3aXRoIGpveSDigKIg4bSXIOKAohiYohsiByMxMzFEMkYqAwEhMwM=#zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11"
[:group-chat {:params "arg"} {"a" public-key "a1" chat-name "a2" chat-id}] [:community
{:community-data
"iyKACkQKB0Rvb2RsZXMSJ0NvbG9yaW5nIHRoZSB3b3JsZCB3aXRoIGpveSDigKIg4bSXIOKAohiYohsiByMxMzFEMkYqAwEhMwM="
:community-id "zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11"}]
"https://join.status.im/u/statuse2e" "status-app://c/iyKACkQKB0Rvb2RsZXMSJ0NvbG9yaW5nIHRoZSB3b3JsZCB3aXRoIGpveSDigKIg4bSXIOKAohiYohsiByMxMzFEMkYqAwEhMwM=#zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11"
[:user {:user-id "statuse2e"}] [:community
{:community-data
(str "https://join.status.im/user/" public-key) "iyKACkQKB0Rvb2RsZXMSJ0NvbG9yaW5nIHRoZSB3b3JsZCB3aXRoIGpveSDigKIg4bSXIOKAohiYohsiByMxMzFEMkYqAwEhMwM="
[:user {:user-id public-key}] :community-id "zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11"}]
;; Last char removed by: https://github.com/juxt/bidi/issues/104
"https://join.status.im/b/www.cryptokitties.co"
[:browser {:domain "www.cryptokitties.c"}]
"https://join.status.im/b/https://www.google.com/"
[:browser {:domain "https://www.google.co"}]
"ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"
[:ethereum {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"}] [:ethereum {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"}]

View File

@ -21,7 +21,8 @@
(i18n/label :t/browsing-site-blocked-title)] (i18n/label :t/browsing-site-blocked-title)]
[react/nested-text {:style styles/description-text} [react/nested-text {:style styles/description-text}
(i18n/label :t/browsing-site-blocked-description1) (i18n/label :t/browsing-site-blocked-description1)
[{:on-press #(.openURL ^js react/linking "status-im://chat/public/status") ;; NOTE: this link is broken
[{:on-press #(.openURL ^js react/linking "status-app://chat/public/status")
:style styles/chat-link-text} :style styles/chat-link-text}
"#status"] "#status"]
(i18n/label :t/browsing-site-blocked-description2)] (i18n/label :t/browsing-site-blocked-description2)]

View File

@ -21,8 +21,8 @@
;; domains should be without the trailing slash ;; domains should be without the trailing slash
(def domains (def domains
{:external "https://join.status.im" {:external "https://status.app"
:internal "status-im:/"}) :internal "status-app:/"})
(def links (def links
{:private-chat "%s/p/%s" {:private-chat "%s/p/%s"
@ -81,17 +81,20 @@
(log/info "universal-links: handling community" community-id) (log/info "universal-links: handling community" community-id)
(navigation/navigate-to cofx :community {:community-id community-id})) (navigation/navigate-to cofx :community {:community-id community-id}))
(rf/defn handle-navigation-to-desktop-community-from-mobile (rf/defn handle-navigation-to-desktop-community-from-mobile
{:events [:handle-navigation-to-desktop-community-from-mobile]} {:events [:handle-navigation-to-desktop-community-from-mobile]}
[cofx deserialized-key] [cofx deserialized-key]
(navigation/navigate-to cofx :community-overview deserialized-key)) (rf/merge
cofx
{:dispatch [:navigate-to :community-overview deserialized-key]}
(navigation/pop-to-root :shell-stack)))
(rf/defn handle-desktop-community (rf/defn handle-desktop-community
[cofx {:keys [community-id]}] [cofx {:keys [community-id]}]
(native-module/deserialize-and-compress-key (native-module/deserialize-and-compress-key
community-id community-id
(fn [deserialized-key] (fn [deserialized-key]
(rf/dispatch [:chat.ui/resolve-community-info (str deserialized-key)])
(rf/dispatch [:handle-navigation-to-desktop-community-from-mobile (str deserialized-key)])))) (rf/dispatch [:handle-navigation-to-desktop-community-from-mobile (str deserialized-key)]))))
(rf/defn handle-community-chat (rf/defn handle-community-chat
@ -212,9 +215,8 @@
(.then dispatch-url)) (.then dispatch-url))
200) 200)
(.addEventListener ^js react/linking "url" url-event-listener) (.addEventListener ^js react/linking "url" url-event-listener)
;;StartSearchForLocalPairingPeers() shouldn't be called ATM from the UI ;;StartSearchForLocalPairingPeers() shouldn't be called ATM from the UI It can be called after the
;;It can be called after the error "route ip+net: netlinkrib: permission denied" is fixed on status-go ;;error "route ip+net: netlinkrib: permission denied" is fixed on status-go side
;;side
#_(native-module/start-searching-for-local-pairing-peers #_(native-module/start-searching-for-local-pairing-peers
#(log/info "[local-pairing] errors from local-pairing-preflight-outbound-check ->" %))) #(log/info "[local-pairing] errors from local-pairing-preflight-outbound-check ->" %)))

View File

@ -20,9 +20,9 @@
(is (nil? (get-in (links/handle-url {:db db} "some-url") (is (nil? (get-in (links/handle-url {:db db} "some-url")
[:db :universal-links/url])))) [:db :universal-links/url]))))
(testing "Handle a custom string" (testing "Handle a custom string"
(is (= (get-in (links/handle-url {:db db} "https://join.status.im/u/statuse2e") (is (= (get-in (links/handle-url {:db db} "https://status.app/u/statuse2e")
[::router/handle-uri :uri]) [::router/handle-uri :uri])
"https://join.status.im/u/statuse2e"))))))) "https://status.app/u/statuse2e")))))))
(deftest url-event-listener (deftest url-event-listener
(testing "the url is not nil" (testing "the url is not nil"

View File

@ -5,8 +5,8 @@
;; domains should be without the trailing slash ;; domains should be without the trailing slash
(def domains (def domains
{:external "https://join.status.im" {:external "https://status.app"
:internal "status-im:/"}) :internal "status-app:/"})
(def links (def links
{:private-chat "%s/p/%s" {:private-chat "%s/p/%s"

View File

@ -4,25 +4,25 @@
[status-im.utils.universal-links.utils :as links])) [status-im.utils.universal-links.utils :as links]))
(deftest universal-link-test (deftest universal-link-test
(testing "status-im://blah" (testing "status-app://blah"
(testing "it returns true" (testing "it returns true"
(is (links/universal-link? "status-im://blah")))) (is (links/universal-link? "status-app://blah"))))
(testing "status-im://blah" (testing "status-app://blah"
(testing "it returns true" (testing "it returns true"
(is (links/deep-link? "status-im://blah")))) (is (links/deep-link? "status-app://blah"))))
(testing "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" (testing "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"
(testing "it returns true" (testing "it returns true"
(is (links/deep-link? "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7")))) (is (links/deep-link? "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"))))
(testing "http://join.status.im/blah" (testing "http://status.app/blah"
(testing "it returns true" (testing "it returns true"
(is (links/universal-link? "http://join.status.im/blah")))) (is (links/universal-link? "http://status.app/blah"))))
(testing "https://join.status.im/blah" (testing "https://status.app/blah"
(testing "it returns true" (testing "it returns true"
(is (links/universal-link? "https://join.status.im/blah")))) (is (links/universal-link? "https://status.app/blah"))))
(testing "unicode characters" (testing "unicode characters"
(testing "it returns false" (testing "it returns false"
(is (not (links/universal-link? "https://join.status.im/browse/www.аррӏе.com"))))) (is (not (links/universal-link? "https://status.app/browse/www.аррӏе.com")))))
(testing "not-status-im://blah" (testing "not-status-app://blah"
(testing "it returns false" (testing "it returns false"
(is (not (links/universal-link? "https://not.status.im/blah"))))) (is (not (links/universal-link? "https://not.status.im/blah")))))
(testing "http://not.status.im/blah" (testing "http://not.status.im/blah"
@ -31,6 +31,6 @@
(testing "https://not.status.im/blah" (testing "https://not.status.im/blah"
(testing "it returns false" (testing "it returns false"
(is (not (links/universal-link? "https://not.status.im/blah"))))) (is (not (links/universal-link? "https://not.status.im/blah")))))
(testing "http://join.status.im/blah" (testing "http://status.app/blah"
(testing "it returns false" (testing "it returns false"
(is (not (links/deep-link? "http://join.status.im/blah")))))) (is (not (links/deep-link? "http://status.app/blah"))))))

View File

@ -178,9 +178,9 @@
(def regx-bold #"\*[^*]+\*") (def regx-bold #"\*[^*]+\*")
(def regx-italic #"~[^~]+~") (def regx-italic #"~[^~]+~")
(def regx-backquote #"`[^`]+`") (def regx-backquote #"`[^`]+`")
(def regx-universal-link #"((^https?://join.status.im/)|(^status-im://))[\x00-\x7F]+$") (def regx-universal-link #"((^https?://status.app/)|(^status-app://))[\x00-\x7F]+$")
(def regx-community-universal-link #"((^https?://join.status.im/)|(^status-im://))c/([\x00-\x7F]+)$") (def regx-community-universal-link #"((^https?://status.app/)|(^status-app://))c/([\x00-\x7F]+)$")
(def regx-deep-link #"((^ethereum:.*)|(^status-im://[\x00-\x7F]+$))") (def regx-deep-link #"((^ethereum:.*)|(^status-app://[\x00-\x7F]+$))")
(def regx-ens #"^(?=.{5,255}$)([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$") (def regx-ens #"^(?=.{5,255}$)([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$")
(def regx-address #"^0x[a-fA-F0-9]{40}$") (def regx-address #"^0x[a-fA-F0-9]{40}$")
(def regx-address-contains #"(?i)0x[a-fA-F0-9]{40}") (def regx-address-contains #"(?i)0x[a-fA-F0-9]{40}")

View File

@ -34,7 +34,7 @@
(zipmap (repeat nil)))) (zipmap (repeat nil))))
([kv] (-> (init-contact) (merge kv)))) ([kv] (-> (init-contact) (merge kv))))
(def url-regex #"^https?://join.status.im/u/(.+)") (def url-regex #"^https?://status.app/u/(.+)")
(defn ->id (defn ->id
[{:keys [input] :as contact}] [{:keys [input] :as contact}]

View File

@ -11,8 +11,8 @@
(def ckey "zQ3shWj4WaBdf2zYKCkXe6PHxDxNTzZyid1i75879Ue9cX9gA") (def ckey "zQ3shWj4WaBdf2zYKCkXe6PHxDxNTzZyid1i75879Ue9cX9gA")
(def ens "esep") (def ens "esep")
(def ens-stateofus-eth (str ens ".stateofus.eth")) (def ens-stateofus-eth (str ens ".stateofus.eth"))
(def link-ckey (str "https://join.status.im/u/" ckey)) (def link-ckey (str "https://status.app/u/" ckey))
(def link-ens (str "https://join.status.im/u/" ens)) (def link-ens (str "https://status.app/u/" ens))
;;; unit tests (no app-db involved) ;;; unit tests (no app-db involved)

View File

@ -9,7 +9,7 @@
(defn community-link (defn community-link
[id] [id]
(str "https://join.status.im/c/" id)) (str "https://status.app/c/" id))
(rf/defn cache-link-preview-data (rf/defn cache-link-preview-data
{:events [:chat.ui/cache-link-preview-data]} {:events [:chat.ui/cache-link-preview-data]}

View File

@ -43,11 +43,11 @@
(defn get-abbreviated-profile-url (defn get-abbreviated-profile-url
"The goal here is to generate a string that begins with "The goal here is to generate a string that begins with
join.status.im/u/ joined with the 1st 5 characters status.app/u/ joined with the 1st 5 characters
of the compressed public key followed by an ellipsis followed by of the compressed public key followed by an ellipsis followed by
the last 10 characters of the compressed public key" the last 10 characters of the compressed public key"
[base-url public-key] [base-url public-key]
(if (and public-key base-url (> (count public-key) 17) (= "join.status.im/u/" base-url)) (if (and public-key base-url (> (count public-key) 17) (= "status.app/u/" base-url))
(let [first-part-of-public-pk (subs public-key 0 5) (let [first-part-of-public-pk (subs public-key 0 5)
ellipsis "..." ellipsis "..."
public-key-size (count public-key) public-key-size (count public-key)

View File

@ -22,22 +22,22 @@
(deftest test-get-abbreviated-profile-url (deftest test-get-abbreviated-profile-url
(testing "Ensure the function correctly generates an abbreviated profile URL for a valid public key" (testing "Ensure the function correctly generates an abbreviated profile URL for a valid public key"
(is (= "join.status.im/u/zQ3sh...mrdYpzeFUa" (is (= "status.app/u/zQ3sh...mrdYpzeFUa"
(utils.address/get-abbreviated-profile-url (utils.address/get-abbreviated-profile-url
"join.status.im/u/" "status.app/u/"
"zQ3shPrnUhhR42JJn3QdhodGest8w8MjiH8hPaimrdYpzeFUa")))) "zQ3shPrnUhhR42JJn3QdhodGest8w8MjiH8hPaimrdYpzeFUa"))))
(testing "Ensure the function returns nil when given an empty public key" (testing "Ensure the function returns nil when given an empty public key"
(is (nil? (utils.address/get-abbreviated-profile-url "join.status.im/u/" "")))) (is (nil? (utils.address/get-abbreviated-profile-url "status.app/u/" ""))))
(testing "Ensure the function returns nil when given a nil public key" (testing "Ensure the function returns nil when given a nil public key"
(is (nil? (utils.address/get-abbreviated-profile-url "join.status.im/u/" nil)))) (is (nil? (utils.address/get-abbreviated-profile-url "status.app/u/" nil))))
(testing "Ensure the function returns nil when given an incorrect base URL" (testing "Ensure the function returns nil when given an incorrect base URL"
(is (nil? (utils.address/get-abbreviated-profile-url (is (nil? (utils.address/get-abbreviated-profile-url
"join.status.im/uwu/" "status.app/uwu/"
"zQ3shPrnUhhR42JJn3QdhodGest8w8MjiH8hPaimrdYpzeFUa")))) "zQ3shPrnUhhR42JJn3QdhodGest8w8MjiH8hPaimrdYpzeFUa"))))
(testing "Ensure the function returns nil when given a public key shorter than 17 characters" (testing "Ensure the function returns nil when given a public key shorter than 17 characters"
(is (nil? (utils.address/get-abbreviated-profile-url "join.status.im/u/" "abc"))) (is (nil? (utils.address/get-abbreviated-profile-url "status.app/u/" "abc")))
(is (nil? (utils.address/get-abbreviated-profile-url "join.status.im/u/" "1234"))))) (is (nil? (utils.address/get-abbreviated-profile-url "status.app/u/" "1234")))))

View File

@ -11,8 +11,8 @@
(def ^:const account-initials-action "/accountInitials") (def ^:const account-initials-action "/accountInitials")
(def ^:const contact-images-action "/contactImages") (def ^:const contact-images-action "/contactImages")
(def ^:const generate-qr-action "/GenerateQRCode") (def ^:const generate-qr-action "/GenerateQRCode")
(def ^:const status-profile-base-url "https://join.status.im/u/") (def ^:const status-profile-base-url "https://status.app/u/")
(def ^:const status-profile-base-url-without-https "join.status.im/u/") (def ^:const status-profile-base-url-without-https "status.app/u/")
(defn get-font-file-ready (defn get-font-file-ready
"setup font file and get the absolute path to it "setup font file and get the absolute path to it