Files
status-react/src/react_native/keychain.cljs
T
Siddarth Kumar 761a7df06f upgrade react-native to 0.72.5 (#17241)
This commit does many things :
- Upgrade `react-native ` to `0.72.5`
- Upgrade `react-native-reanimated` to  `3.5.4`
- Upgrade `react-native-navigation` to `7.37.0`
- `ndkVersion` has been bumped to `25.2.9519653`
- `cmakeVersion` has been bumped to `3.22.1`
- `kotlinVersion` has been bumped to `1.7.22`
- `AGP` has been bumped to `7.4.2`
- `Gradle` has been upgraded to `8.0.1`
- Android `CompileSDK` and `TargetSDK` have been bumped to 33
- `@react-native-async-storage/async-storage` has been upgraded to `1.19.3`
- `@walletconnect/client` has been nuked
- some of the old `react-native-reanimated` code has been nuked
- `react-native-keychain` fork has been replaced with `8.1.2`

- On Android we are currently relying on `Hermes` Engine.
- On iOS we are currently relying on `JSC`
- We are not enabling new architecture for now (I have plans for that in the future) ref: https://github.com/status-im/status-mobile/issues/18138

IOS only PR : https://github.com/status-im/status-mobile/pull/16721
Android only PR : https://github.com/status-im/status-mobile/pull/17062

- `make run-metro` now has a target of `android` which was `clojure` earlier, this will increase the time it takes to start metro terminal but this is needed otherwise you will get a nasty error while developing for android locally.
2023-12-11 21:22:23 +05:30

83 lines
3.4 KiB
Clojure
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
(ns react-native.keychain
(:require
["react-native-keychain" :as react-native-keychain]
[clojure.string :as string]
[taoensso.timbre :as log]))
;; ********************************************************************************
;; Storing / Retrieving a user password to/from Keychain
;; ********************************************************************************
;;
;; We are using set/get/reset internet credentials there because they are bound
;; to an address (`server`) property.
(defn enum-val
[enum-name value-name]
(get-in (js->clj ^js react-native-keychain) [enum-name value-name]))
;; We need a more strict access mode for keychain entries that save user password.
;; iOS
;; see this article for more details:
;; https://developer.apple.com/documentation/security/keychain_services/keychain_items/restricting_keychain_item_accessibility?language=objc
(def keychain-restricted-availability
;; From Apple's documentation:
;; > The kSecAttrAccessible attribute enables you to control item availability
;; > relative to the lock state of the device.
;; > It also lets you specify eligibility for restoration to a new device.
;; > If the attribute ends with the string ThisDeviceOnly,
;; > the item can be restored to the same device that created a backup,
;; > but it isnt migrated when restoring another devices backup data.
;; > ...
;; > For extremely sensitive data
;; > THAT YOU NEVER WANT STORED IN iCloud,
;; > you might choose kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly.
;; That is exactly what we use there.
;; Note that the password won't be stored if the device isn't locked by a passcode.
#js {:accessible (enum-val "ACCESSIBLE" "WHEN_PASSCODE_SET_THIS_DEVICE_ONLY")})
(def keychain-secure-hardware
;; (Android) Requires storing the encryption key for the entry in secure hardware
;; or StrongBox (see https://developer.android.com/training/articles/keystore#ExtractionPrevention)
#js {:accessible (enum-val "SECURITY_LEVEL" "SECURE_HARDWARE")})
;; Android only
(defn secure-hardware-available?
[callback]
(-> (.getSecurityLevel ^js react-native-keychain)
(.then (fn [level]
(callback (= level "SECURE_HARDWARE"))))))
;; iOS only
(defn device-encrypted?
[callback]
(-> (.canImplyAuthentication
^js react-native-keychain
(clj->js
{:authenticationType
(enum-val "ACCESS_CONTROL" "BIOMETRY_ANY_OR_DEVICE_PASSCODE")}))
(.then callback)))
(defn save-credentials
"Stores the credentials for the address to the Keychain"
([server username password]
(save-credentials server username password identity))
([server username password callback]
(-> (.setInternetCredentials ^js react-native-keychain
(string/lower-case server)
username
password
keychain-secure-hardware
keychain-restricted-availability)
(.then callback))))
(defn get-credentials
"Gets the credentials for a specified server from the Keychain"
[server callback]
(-> (.getInternetCredentials ^js react-native-keychain (string/lower-case server))
(.then callback)))
(defn reset-credentials
[server]
(-> (.resetInternetCredentials ^js react-native-keychain (string/lower-case server))
(.then #(when-not % (log/error (str "Error while clearing saved password."))))))