diff --git a/.env b/.env index 42b590beba6c5ddfe7917a68ee999328c37ab1bc..7fd01c45ffe23cd39c2c52108e4c4bc9a71cacdb 100644 --- a/.env +++ b/.env @@ -1 +1,2 @@ MEDIATOR_URL=https://ssi-dev.vereign.com/hin/afj-mediator/invite?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4xL2ludml0YXRpb24iLCJAaWQiOiJmOGFkYzVjZC01ZmU1LTQ5MjktODJjOC00MDdhZDY0N2I0MzQiLCJsYWJlbCI6IlZlcmVpZ24tTWVkaWF0b3IiLCJhY2NlcHQiOlsiZGlkY29tbS9haXAxIiwiZGlkY29tbS9haXAyO2Vudj1yZmMxOSJdLCJoYW5kc2hha2VfcHJvdG9jb2xzIjpbImh0dHBzOi8vZGlkY29tbS5vcmcvZGlkZXhjaGFuZ2UvMS4wIiwiaHR0cHM6Ly9kaWRjb21tLm9yZy9jb25uZWN0aW9ucy8xLjAiXSwic2VydmljZXMiOlt7ImlkIjoiI2lubGluZS0wIiwic2VydmljZUVuZHBvaW50IjoiaHR0cHM6Ly9zc2ktZGV2LnZlcmVpZ24uY29tL2hpbi9hZmotbWVkaWF0b3IiLCJ0eXBlIjoiZGlkLWNvbW11bmljYXRpb24iLCJyZWNpcGllbnRLZXlzIjpbImRpZDprZXk6ejZNa2o5TVI5dVdyZjhvWU00WXNla2VpZjNvbTJTaHY2VUpuc3hWQXdkNkdKbk1tIl0sInJvdXRpbmdLZXlzIjpbXX0seyJpZCI6IiNpbmxpbmUtMSIsInNlcnZpY2VFbmRwb2ludCI6IndzOi8vc3NpLWRldi52ZXJlaWduLmNvbS9oaW4vYWZqLW1lZGlhdG9yIiwidHlwZSI6ImRpZC1jb21tdW5pY2F0aW9uIiwicmVjaXBpZW50S2V5cyI6WyJkaWQ6a2V5Ono2TWtqOU1SOXVXcmY4b1lNNFlzZWtlaWYzb20yU2h2NlVKbnN4VkF3ZDZHSm5NbSJdLCJyb3V0aW5nS2V5cyI6W119XX0 +SVDX_BASE_URL=https://did.svdx.pro \ No newline at end of file diff --git a/.env.sample b/.env.sample index 4a4153e807ba8bba66b47daed2443f9537525b84..df29dfca612313bb76db0ad1063adc9acbaf12ac 100644 --- a/.env.sample +++ b/.env.sample @@ -1,5 +1,6 @@ MEDIATOR_URL=https://gaiax.vereign.com/mediator?c_i=eyJAdHlwZSI6ICJkaWQ6c292OkJ6Q2JzTlloTXJqSGlxWkRUVUFTSGc7c3BlYy9jb25uZWN0aW9ucy8xLjAvaW52aXRhdGlvbiIsICJAaWQiOiAiZDU0Mjc2ZDUtMDUwYy00MDI1LWExYWUtNGYzMzE4MWQyM2U3IiwgImxhYmVsIjogIk1lZGlhdG9yIiwgInJlY2lwaWVudEtleXMiOiBbIkJjdGoyQllHUWN5dVRTaVlEV0tjTWNjRDNvR3Q3ZkNDellaV0trbkVNdFA5Il0sICJzZXJ2aWNlRW5kcG9pbnQiOiAiaHR0cHM6Ly9nYWlheC52ZXJlaWduLmNvbS9tZWRpYXRvciJ9 +SVDX_BASE_URL=https://did.svdx.pro # MEDIATOR_URL=https://mediator.dev.animo.id/invite?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4xL2ludml0YXRpb24iLCJAaWQiOiIyMDc1MDM4YS05ZGU3LTRiODItYWUxYi1jNzBmNDg4MjYzYTciLCJsYWJlbCI6IkFuaW1vIE1lZGlhdG9yIiwiYWNjZXB0IjpbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwiaGFuZHNoYWtlX3Byb3RvY29scyI6WyJodHRwczovL2RpZGNvbW0ub3JnL2RpZGV4Y2hhbmdlLzEuMCIsImh0dHBzOi8vZGlkY29tbS5vcmcvY29ubmVjdGlvbnMvMS4wIl0sInNlcnZpY2VzIjpbeyJpZCI6IiNpbmxpbmUtMCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vbWVkaWF0b3IuZGV2LmFuaW1vLmlkIiwidHlwZSI6ImRpZC1jb21tdW5pY2F0aW9uIiwicmVjaXBpZW50S2V5cyI6WyJkaWQ6a2V5Ono2TWtvSG9RTUphdU5VUE5OV1pQcEw3RGs1SzNtQ0NDMlBpNDJGY3FwR25iampMcSJdLCJyb3V0aW5nS2V5cyI6W119LHsiaWQiOiIjaW5saW5lLTEiLCJzZXJ2aWNlRW5kcG9pbnQiOiJ3c3M6Ly9tZWRpYXRvci5kZXYuYW5pbW8uaWQiLCJ0eXBlIjoiZGlkLWNvbW11bmljYXRpb24iLCJyZWNpcGllbnRLZXlzIjpbImRpZDprZXk6ejZNa29Ib1FNSmF1TlVQTk5XWlBwTDdEazVLM21DQ0MyUGk0MkZjcXBHbmJqakxxIl0sInJvdXRpbmdLZXlzIjpbXX1dfQ +# MEDIATOR_URL=https://ssi-dev.vereign.com/hin/afj-mediator/invite?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4xL2ludml0YXRpb24iLCJAaWQiOiI1OTRkMTk3YS0yMzgxLTRkNmUtOTk1ZC0xODBjMzNiY2M1MGYiLCJsYWJlbCI6ImFmai12ZXJlaWduLW1lZGlhdG9yIiwiYWNjZXB0IjpbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwiaGFuZHNoYWtlX3Byb3RvY29scyI6WyJodHRwczovL2RpZGNvbW0ub3JnL2RpZGV4Y2hhbmdlLzEuMCIsImh0dHBzOi8vZGlkY29tbS5vcmcvY29ubmVjdGlvbnMvMS4wIl0sInNlcnZpY2VzIjpbeyJpZCI6IiNpbmxpbmUtMCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vc3NpLWRldi52ZXJlaWduLmNvbS9oaW4vYWZqLW1lZGlhdG9yIiwidHlwZSI6ImRpZC1jb21tdW5pY2F0aW9uIiwicmVjaXBpZW50S2V5cyI6WyJkaWQ6a2V5Ono2TWtvM0g0YWNvZ05mSHFaeUtHVERpdWRCd3o4TTU0dXRoR1ZBWFhnQzE3eHZFTCJdLCJyb3V0aW5nS2V5cyI6W119LHsiaWQiOiIjaW5saW5lLTEiLCJzZXJ2aWNlRW5kcG9pbnQiOiJ3czovL3NzaS1kZXYudmVyZWlnbi5jb20vaGluL2Fmai1tZWRpYXRvciIsInR5cGUiOiJkaWQtY29tbXVuaWNhdGlvbiIsInJlY2lwaWVudEtleXMiOlsiZGlkOmtleTp6Nk1rbzNINGFjb2dOZkhxWnlLR1REaXVkQnd6OE01NHV0aEdWQVhYZ0MxN3h2RUwiXSwicm91dGluZ0tleXMiOltdfV19 -MEDIATOR_URL=https://ssi-dev.vereign.com/hin/afj-mediator/invite?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4xL2ludml0YXRpb24iLCJAaWQiOiI1OTRkMTk3YS0yMzgxLTRkNmUtOTk1ZC0xODBjMzNiY2M1MGYiLCJsYWJlbCI6ImFmai12ZXJlaWduLW1lZGlhdG9yIiwiYWNjZXB0IjpbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwiaGFuZHNoYWtlX3Byb3RvY29scyI6WyJodHRwczovL2RpZGNvbW0ub3JnL2RpZGV4Y2hhbmdlLzEuMCIsImh0dHBzOi8vZGlkY29tbS5vcmcvY29ubmVjdGlvbnMvMS4wIl0sInNlcnZpY2VzIjpbeyJpZCI6IiNpbmxpbmUtMCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vc3NpLWRldi52ZXJlaWduLmNvbS9oaW4vYWZqLW1lZGlhdG9yIiwidHlwZSI6ImRpZC1jb21tdW5pY2F0aW9uIiwicmVjaXBpZW50S2V5cyI6WyJkaWQ6a2V5Ono2TWtvM0g0YWNvZ05mSHFaeUtHVERpdWRCd3o4TTU0dXRoR1ZBWFhnQzE3eHZFTCJdLCJyb3V0aW5nS2V5cyI6W119LHsiaWQiOiIjaW5saW5lLTEiLCJzZXJ2aWNlRW5kcG9pbnQiOiJ3czovL3NzaS1kZXYudmVyZWlnbi5jb20vaGluL2Fmai1tZWRpYXRvciIsInR5cGUiOiJkaWQtY29tbXVuaWNhdGlvbiIsInJlY2lwaWVudEtleXMiOlsiZGlkOmtleTp6Nk1rbzNINGFjb2dOZkhxWnlLR1REaXVkQnd6OE01NHV0aEdWQVhYZ0MxN3h2RUwiXSwicm91dGluZ0tleXMiOltdfV19 \ No newline at end of file diff --git a/App.tsx b/App.tsx index fcbde0c8aa79ff0b967af0c59a812bd1b16a8e44..a58338abe5fcd2ef8842697d0af9d71526a861a5 100644 --- a/App.tsx +++ b/App.tsx @@ -8,8 +8,14 @@ import { ColorPallet, customTheme } from './src/theme/theme'; import RootStack from './src/navigators/RootStack'; import { initStoredLanguage } from './src/localization'; import toastConfig from './src/components/toast/ToastConfig'; -import './src/seal/injectCryptoServiceMobile'; import {observer} from "mobx-react"; +import {Buffer} from "buffer"; +import {RealmProvider} from '@realm/react'; +import {schemas} from './src/db-models'; +import './src/seal/injectCryptoServiceMobile'; + +// Required by @vereign/lib-mime +global.Buffer = Buffer; const navigationTheme = { dark: false, @@ -29,14 +35,15 @@ const App = observer(() => { return ( <SafeAreaProvider> <AntDesignProvider theme={customTheme}> - - <NavigationContainer theme={navigationTheme}> + <NavigationContainer theme={navigationTheme}> + <RealmProvider schema={schemas}> <RootStack /> - <Toast - topOffset={Platform.OS === 'android' ? 5 : 50} - config={toastConfig} - /> - </NavigationContainer> + </RealmProvider> + <Toast + topOffset={Platform.OS === 'android' ? 5 : 50} + config={toastConfig} + /> + </NavigationContainer> </AntDesignProvider> </SafeAreaProvider> ); diff --git a/android/app/build.gradle b/android/app/build.gradle index 32e6e9a0fe6063eb3bd78a8d5fb80516e3dab7a2..3b0029420ac5e720342a988b99cdfda72a8767fd 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -154,9 +154,19 @@ android { } } + + packagingOptions { + resources { + exclude 'META-INF/NOTICE.md' + exclude 'META-INF/LICENSE.md' + } + } } dependencies { + implementation('com.sun.mail:android-mail:1.6.7') + implementation('com.sun.mail:android-activation:1.6.7') + // The version of react-native is set by the React Native Gradle Plugin implementation("com.facebook.react:react-android") diff --git a/android/app/src/main/java/com/vereign/vcm/MainApplication.java b/android/app/src/main/java/com/vereign/vcm/MainApplication.java index 0e097c321e44c5eb04e46e18377be7b01664f38d..04789083f966412578b28a3e18bad35c7a168e43 100644 --- a/android/app/src/main/java/com/vereign/vcm/MainApplication.java +++ b/android/app/src/main/java/com/vereign/vcm/MainApplication.java @@ -25,6 +25,7 @@ public class MainApplication extends Application implements ReactApplication { List<ReactPackage> packages = new PackageList(this).getPackages(); // Packages that cannot be autolinked yet can be added manually here, for example: // packages.add(new MyReactNativePackage()); + packages.add(new MyAppPackage()); return packages; } diff --git a/android/app/src/main/java/com/vereign/vcm/MyAppPackage.java b/android/app/src/main/java/com/vereign/vcm/MyAppPackage.java new file mode 100644 index 0000000000000000000000000000000000000000..044395a9ee83bfd061f7c5a1a2e24b5bcb999272 --- /dev/null +++ b/android/app/src/main/java/com/vereign/vcm/MyAppPackage.java @@ -0,0 +1,29 @@ +package com.vereign.vcm; + +import com.facebook.react.ReactPackage; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.ViewManager; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class MyAppPackage implements ReactPackage { + + @Override + public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } + + @Override + public List<NativeModule> createNativeModules( + ReactApplicationContext reactContext) { + List<NativeModule> modules = new ArrayList<>(); + + modules.add(new VereignImapModule(reactContext)); + + return modules; + } + +} \ No newline at end of file diff --git a/android/app/src/main/java/com/vereign/vcm/VereignImapModule.java b/android/app/src/main/java/com/vereign/vcm/VereignImapModule.java new file mode 100644 index 0000000000000000000000000000000000000000..53659e8067a0a71fabcfb5fd28256746d6904a88 --- /dev/null +++ b/android/app/src/main/java/com/vereign/vcm/VereignImapModule.java @@ -0,0 +1,99 @@ +package com.vereign.vcm; + +import android.util.Log; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import java.util.Map; +import java.util.HashMap; +import java.util.Properties; + +import com.facebook.react.bridge.Callback; + +import javax.mail.Folder; +import javax.mail.Message; +import javax.mail.Session; +import javax.mail.Store; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import java.nio.charset.StandardCharsets; +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +public class VereignImapModule extends ReactContextBaseJavaModule { + VereignImapModule(ReactApplicationContext context) { + super(context); + } + + @Override + public String getName() { + return "VereignImapModule"; + } + + @ReactMethod + public void checkConfiguration(String host, String username, String password, Callback callBack) { + Log.i("VereignImapModule", "checkConfiguration called"); + + String folderName = "INBOX"; // or any other folder + + Properties props = new Properties(); + props.put("mail.imap.ssl.enable", "true"); // Enables SSL + + try { + Session session = Session.getInstance(props, null); + + Store store = session.getStore("imap"); + store.connect(host, username, password); + + Folder folder = store.getFolder(folderName); + folder.open(Folder.READ_WRITE); + + folder.close(false); + store.close(); + Log.i("VereignImapModule", "closing..."); + callBack.invoke(true, null); + } catch (Exception e) { + e.printStackTrace(); + callBack.invoke(null, e.getMessage()); + Log.i("VereignImapModule", "Issue: " + e.getMessage()); + } + } + + @ReactMethod + public void saveMessage(String host, String username, String password, String content, Callback callBack) { + Log.i("VereignImapModule", "checkConfiguration called"); + + String folderName = "INBOX"; // or any other folder + + Properties props = new Properties(); + props.put("mail.imap.ssl.enable", "true"); // Enables SSL + + try { + Session session = Session.getInstance(props, null); + + Store store = session.getStore("imap"); + store.connect(host, username, password); + + Folder folder = store.getFolder(folderName); + folder.open(Folder.READ_WRITE); + + + InputStream iv = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)); + MimeMessage message = new MimeMessage(session, iv); + folder.appendMessages(new Message[]{message}); + + folder.close(false); + store.close(); + Log.i("VereignImapModule", "closing..."); + callBack.invoke(true, null); + } catch (Exception e) { + e.printStackTrace(); + callBack.invoke(null, e.getMessage()); + Log.i("VereignImapModule", "Issue: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e7805a8a832e847db6ec56f008e0ad5bcdafc880..80d2436352f828726dc8e4c382bf95f4ad3598e5 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,4 +1,12 @@ PODS: + - anoncreds (0.1.0): + - React + - React-callinvoker + - React-Core + - aries-askar (0.1.1): + - React + - React-callinvoker + - React-Core - boost (1.76.0) - CatCrypto (0.3.2) - DoubleConversion (1.1.6) @@ -12,6 +20,36 @@ PODS: - ReactCommon/turbomodule/core (= 0.71.10) - fmt (6.2.1) - glog (0.3.5) + - GoogleDataTransport (9.2.5): + - GoogleUtilities/Environment (~> 7.7) + - nanopb (< 2.30910.0, >= 2.30908.0) + - PromisesObjC (< 3.0, >= 1.2) + - GoogleMLKit/BarcodeScanning (4.0.0): + - GoogleMLKit/MLKitCore + - MLKitBarcodeScanning (~> 3.0.0) + - GoogleMLKit/MLKitCore (4.0.0): + - MLKitCommon (~> 9.0.0) + - GoogleToolboxForMac/DebugUtils (2.3.2): + - GoogleToolboxForMac/Defines (= 2.3.2) + - GoogleToolboxForMac/Defines (2.3.2) + - GoogleToolboxForMac/Logger (2.3.2): + - GoogleToolboxForMac/Defines (= 2.3.2) + - "GoogleToolboxForMac/NSData+zlib (2.3.2)": + - GoogleToolboxForMac/Defines (= 2.3.2) + - "GoogleToolboxForMac/NSDictionary+URLArguments (2.3.2)": + - GoogleToolboxForMac/DebugUtils (= 2.3.2) + - GoogleToolboxForMac/Defines (= 2.3.2) + - "GoogleToolboxForMac/NSString+URLArguments (= 2.3.2)" + - "GoogleToolboxForMac/NSString+URLArguments (2.3.2)" + - GoogleUtilities/Environment (7.11.5): + - PromisesObjC (< 3.0, >= 1.2) + - GoogleUtilities/Logger (7.11.5): + - GoogleUtilities/Environment + - GoogleUtilities/UserDefaults (7.11.5): + - GoogleUtilities/Logger + - GoogleUtilitiesComponents (1.1.0): + - GoogleUtilities/Logger + - GTMSessionFetcher/Core (2.3.0) - hermes-engine (0.71.10): - hermes-engine/Pre-built (= 0.71.10) - hermes-engine/Pre-built (0.71.10) @@ -19,7 +57,35 @@ PODS: - indy-sdk-react-native (0.3.1): - Indy - React + - indy-vdr (0.1.0): + - React + - React-callinvoker + - React-Core - libevent (2.1.12) + - MLImage (1.0.0-beta4) + - MLKitBarcodeScanning (3.0.0): + - MLKitCommon (~> 9.0) + - MLKitVision (~> 5.0) + - MLKitCommon (9.0.0): + - GoogleDataTransport (~> 9.0) + - GoogleToolboxForMac/Logger (~> 2.1) + - "GoogleToolboxForMac/NSData+zlib (~> 2.1)" + - "GoogleToolboxForMac/NSDictionary+URLArguments (~> 2.1)" + - GoogleUtilities/UserDefaults (~> 7.0) + - GoogleUtilitiesComponents (~> 1.0) + - GTMSessionFetcher/Core (< 3.0, >= 1.1) + - MLKitVision (5.0.0): + - GoogleToolboxForMac/Logger (~> 2.1) + - "GoogleToolboxForMac/NSData+zlib (~> 2.1)" + - GTMSessionFetcher/Core (< 3.0, >= 1.1) + - MLImage (= 1.0.0-beta4) + - MLKitCommon (~> 9.0) + - nanopb (2.30909.0): + - nanopb/decode (= 2.30909.0) + - nanopb/encode (= 2.30909.0) + - nanopb/decode (2.30909.0) + - nanopb/encode (2.30909.0) + - PromisesObjC (2.3.1) - RCT-Folly (2021.07.22.00): - boost - DoubleConversion @@ -434,9 +500,18 @@ PODS: - React-Core - RNVectorIcons (9.2.0): - React-Core + - vision-camera-code-scanner (0.2.0): + - GoogleMLKit/BarcodeScanning + - React-Core + - VisionCamera (2.15.4): + - React + - React-callinvoker + - React-Core - Yoga (1.14.0) DEPENDENCIES: + - "anoncreds (from `../node_modules/@hyperledger/anoncreds-react-native`)" + - "aries-askar (from `../node_modules/@hyperledger/aries-askar-react-native`)" - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) @@ -444,6 +519,7 @@ DEPENDENCIES: - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) - indy-sdk-react-native (from `../node_modules/indy-sdk-react-native`) + - "indy-vdr (from `../node_modules/@hyperledger/indy-vdr-react-native`)" - libevent (~> 2.1.12) - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) @@ -496,11 +572,25 @@ DEPENDENCIES: - RNShare (from `../node_modules/react-native-share`) - RNSVG (from `../node_modules/react-native-svg`) - RNVectorIcons (from `../node_modules/react-native-vector-icons`) + - vision-camera-code-scanner (from `../node_modules/vision-camera-code-scanner`) + - VisionCamera (from `../node_modules/react-native-vision-camera`) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: https://github.com/CocoaPods/Specs.git: - CatCrypto + - GoogleDataTransport + - GoogleMLKit + - GoogleToolboxForMac + - GoogleUtilities + - GoogleUtilitiesComponents + - GTMSessionFetcher + - MLImage + - MLKitBarcodeScanning + - MLKitCommon + - MLKitVision + - nanopb + - PromisesObjC https://github.com/hyperledger/indy-sdk-react-native: - Indy trunk: @@ -508,6 +598,10 @@ SPEC REPOS: - libevent EXTERNAL SOURCES: + anoncreds: + :path: "../node_modules/@hyperledger/anoncreds-react-native" + aries-askar: + :path: "../node_modules/@hyperledger/aries-askar-react-native" boost: :podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec" DoubleConversion: @@ -522,6 +616,8 @@ EXTERNAL SOURCES: :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" indy-sdk-react-native: :path: "../node_modules/indy-sdk-react-native" + indy-vdr: + :path: "../node_modules/@hyperledger/indy-vdr-react-native" RCT-Folly: :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTRequired: @@ -622,10 +718,16 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-svg" RNVectorIcons: :path: "../node_modules/react-native-vector-icons" + vision-camera-code-scanner: + :path: "../node_modules/vision-camera-code-scanner" + VisionCamera: + :path: "../node_modules/react-native-vision-camera" Yoga: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: + anoncreds: 8e6ab626d5250ae6301c3e96d6fc739186e083f0 + aries-askar: 738c677e194913ed3c256adc953db3fe0494f8f8 boost: 57d2868c099736d80fcd648bf211b4431e51a558 CatCrypto: a477899b6be4954e75be4897e732da098cc0a5a8 DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 @@ -633,10 +735,23 @@ SPEC CHECKSUMS: FBReactNativeSpec: 90fc1a90b4b7a171e0a7c20ea426c1bf6ce4399c fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b + GoogleDataTransport: 54dee9d48d14580407f8f5fbf2f496e92437a2f2 + GoogleMLKit: 2bd0dc6253c4d4f227aad460f69215a504b2980e + GoogleToolboxForMac: 8bef7c7c5cf7291c687cf5354f39f9db6399ad34 + GoogleUtilities: 13e2c67ede716b8741c7989e26893d151b2b2084 + GoogleUtilitiesComponents: 679b2c881db3b615a2777504623df6122dd20afe + GTMSessionFetcher: 3a63d75eecd6aa32c2fc79f578064e1214dfdec2 hermes-engine: d27603b55a48402501ad1928c05411dae9cd6b85 Indy: d9976ce47c0308bd1fea6f90e3ad3db59a3b49b9 indy-sdk-react-native: d98862d0fffa42cc427d5ceffb6589e7c7ce8c46 + indy-vdr: 85cd66089f151256581323440e78988891f4082e libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 + MLImage: 7bb7c4264164ade9bf64f679b40fb29c8f33ee9b + MLKitBarcodeScanning: 04e264482c5f3810cb89ebc134ef6b61e67db505 + MLKitCommon: c1b791c3e667091918d91bda4bba69a91011e390 + MLKitVision: 8baa5f46ee3352614169b85250574fde38c36f49 + nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431 + PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4 RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 RCTRequired: 8ef706f91e2b643cd32c26a57700b5f24fab0585 RCTTypeSafety: 5fbddd8eb9242b91ac0d901c01da3673f358b1b7 @@ -687,6 +802,8 @@ SPEC CHECKSUMS: RNShare: d82e10f6b7677f4b0048c23709bd04098d5aee6c RNSVG: 53c661b76829783cdaf9b7a57258f3d3b4c28315 RNVectorIcons: fcc2f6cb32f5735b586e66d14103a74ce6ad61f8 + vision-camera-code-scanner: dda884a7f3ec8243a2a6d6489b91860648371bca + VisionCamera: c6356b309f7b8e185b7be2e703ec67bb35acf345 Yoga: e7ea9e590e27460d28911403b894722354d73479 PODFILE CHECKSUM: a70b8841dadb169ce8704d6b9fb1be7df2e4bbbf diff --git a/package.json b/package.json index 79d7c8976c28298662631171b013a5fce692cd6d..52b04ed1f18439fcce3ae33094c102633dd461b0 100644 --- a/package.json +++ b/package.json @@ -23,11 +23,13 @@ "@hyperledger/aries-askar-shared": "^0.1.1", "@hyperledger/indy-vdr-react-native": "^0.1.0", "@hyperledger/indy-vdr-shared": "^0.1.0", + "@notifee/react-native": "^7.8.0", "@react-native-async-storage/async-storage": "^1.18.2", "@react-native-clipboard/clipboard": "^1.11.2", "@react-navigation/bottom-tabs": "^6.5.7", "@react-navigation/native": "^6.1.6", "@react-navigation/stack": "^6.3.16", + "@realm/react": "^0.6.0", "@types/url-parse": "^1.4.8", "@vereign/light-utils": "git+ssh://git@code.vereign.com:seal/building-blocks/signing-verification-utilities.git#feature-seal-reading-injecting", "buffer": "^6.0.3", @@ -70,8 +72,8 @@ "react-native-uuid": "^2.0.1", "react-native-vector-icons": "^9.2.0", "react-native-vision-camera": "^2.15.4", + "realm": "^12.2.0", "rn-fetch-blob": "^0.12.0", - "rn-secure-storage": "^2.0.8", "url-parse": "^1.5.10", "vision-camera-code-scanner": "^0.2.0" }, diff --git a/src/assets/svg/e-mail-black.svg b/src/assets/svg/e-mail-black.svg new file mode 100644 index 0000000000000000000000000000000000000000..212c416e003c35ad880b20def2f956c03fbcaeee --- /dev/null +++ b/src/assets/svg/e-mail-black.svg @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 27.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 283.5 283.5" style="enable-background:new 0 0 283.5 283.5;" xml:space="preserve"> +<path id="email-line" class="st0" d="M265.7,35.5H17.8C8,35.5,0.1,43.4,0.1,53.2l0,0v177C0.1,240,8,248,17.8,248c0,0,0,0,0,0h247.9 + c9.8,0,17.7-7.9,17.7-17.7c0,0,0,0,0,0v-177C283.4,43.4,275.5,35.5,265.7,35.5L265.7,35.5z M252,230.3H32.5l62-64.1l-12.7-12.3 + l-63.9,66.1V66.7l110,109.5c6.9,6.9,18.1,6.9,25,0L265.7,63.9v154.9l-65.1-65.1l-12.5,12.5L252,230.3z M29.4,53.2h221.9l-111,110.4 + L29.4,53.2z"/> +</svg> diff --git a/src/assets/svg/index.html b/src/assets/svg/index.html deleted file mode 100644 index adf63b111c3fd87eab98048bc3b5efd2eca0b058..0000000000000000000000000000000000000000 --- a/src/assets/svg/index.html +++ /dev/null @@ -1,50 +0,0 @@ -<html> -<head> - <style> - img { - max-width: 30px; - } - </style> -</head> -<body style="background-color: gray"> - <img src="activities.svg" > - <img src="attachments.svg" > - <img src="bank.svg" > - <img src="barcode.svg" > - <img src="bell.svg" > - <img src="building.svg" > - <img src="connections.svg" > - <img src="content.svg" > - <img src="credential.svg" > - <img src="credential-check.svg" > - <img src="credential-round.svg" > - <img src="credential_card.svg" > - <img src="download.svg" > - <img src="e-mail.svg" > - <img src="exclamation.svg" > - <img src="face-id.svg" > - <img src="fingerprint.svg" > - <img src="hash.svg" > - <img src="id.svg" > - <img src="import-wallet.svg" > - <img src="index.html" > - <img src="info.svg" > - <img src="initialization.svg" > - <img src="language.svg" > - <img src="lock.svg" > - <img src="lock_icon.svg" > - <img src="logout.svg" > - <img src="mnemonic.svg" > - <img src="new_connection.svg" > - <img src="person.svg" > - <img src="phone.svg" > - <img src="privacy.svg" > - <img src="question.svg" > - <img src="scan.svg" > - <img src="seal_history.svg" > - <img src="search.svg" > - <img src="settings.svg" > - <img src="turn.svg" > - <img src="wallet.svg" > -</body> -</html> diff --git a/src/assets/svg/scan-qr.svg b/src/assets/svg/scan-qr.svg new file mode 100644 index 0000000000000000000000000000000000000000..6fc54f77b0870b2494af0373cfca8878caa34321 --- /dev/null +++ b/src/assets/svg/scan-qr.svg @@ -0,0 +1,83 @@ +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + width="100%" viewBox="0 0 152 154" enable-background="new 0 0 152 154" xml:space="preserve"> + +<path fill="#FFFFFF" opacity="1.000000" stroke="none" + d=" +M58.599457,22.392736 + C58.941338,26.353436 58.941338,29.977104 58.941338,33.989258 + C50.887131,33.989258 43.139553,33.989258 35.005928,33.989258 + C35.005928,42.122940 35.005928,49.869415 35.005928,57.801895 + C30.869040,57.801895 27.131340,57.801895 23.201620,57.801895 + C23.201620,45.866089 23.201620,34.128132 23.201620,22.055704 + C35.018871,22.055704 46.638226,22.055704 58.599457,22.392736 +z"/> +<path fill="#FFFFFF" opacity="1.000000" stroke="none" + d=" +M111.002266,22.000000 + C117.809959,22.000000 124.118515,22.000000 130.712769,22.000000 + C130.712769,33.948997 130.712769,45.684761 130.712769,57.711327 + C127.057076,57.711327 123.317024,57.711327 119.175781,57.711327 + C119.175781,50.059387 119.175781,42.313435 119.175781,34.175735 + C111.054062,34.175735 103.310219,34.175735 95.286407,34.175735 + C95.286407,30.052572 95.286407,26.312593 95.286407,22.000000 + C100.303696,22.000000 105.403412,22.000000 111.002266,22.000000 +z"/> +<path fill="#FFFFFF" opacity="1.000000" stroke="none" + d=" +M46.985931,130.000000 + C38.848377,130.000000 31.207720,130.000000 23.284264,130.000000 + C23.284264,118.044586 23.284264,106.308586 23.284264,94.285248 + C26.949869,94.285248 30.689878,94.285248 34.831436,94.285248 + C34.831436,101.949181 34.831436,109.694382 34.831436,117.832001 + C42.955017,117.832001 50.698219,117.832001 58.717693,117.832001 + C58.717693,121.955772 58.717693,125.695663 58.717693,130.000000 + C55.026810,130.000000 51.254818,130.000000 46.985931,130.000000 +z"/> +<path fill="#FFFFFF" opacity="1.000000" stroke="none" + d=" +M95.002228,120.167786 + C96.275635,119.126328 97.535484,118.109375 98.820557,118.076447 + C105.310326,117.910149 111.806664,118.000008 118.702354,118.000008 + C118.702354,110.182884 118.702354,102.437721 118.702354,94.347595 + C122.829338,94.347595 126.569038,94.347595 130.658783,94.347595 + C130.658783,105.828926 130.658783,117.571838 130.658783,129.658264 + C119.161407,129.658264 107.421913,129.658264 95.000305,129.658264 + C95.000305,126.816856 95.000305,123.731476 95.002228,120.167786 +z"/> +<path fill="#FFFFFF" opacity="1.000000" stroke="none" + d=" +M55.049686,70.000000 + C52.242882,70.000000 49.927132,70.000000 47.306309,70.000000 + C47.306309,62.090122 47.306309,54.351261 47.306309,46.304596 + C54.912769,46.304596 62.651733,46.304596 70.696960,46.304596 + C70.696960,53.915993 70.696960,61.654903 70.696960,70.000000 + C65.728073,70.000000 60.634407,70.000000 55.049686,70.000000 +z"/> +<path fill="#FFFFFF" opacity="1.000000" stroke="none" + d=" +M93.022034,70.000000 + C89.548790,70.000000 86.568657,70.000000 83.296051,70.000000 + C83.296051,62.069641 83.296051,54.331253 83.296051,46.294830 + C90.932602,46.294830 98.670944,46.294830 106.706345,46.294830 + C106.706345,53.935070 106.706345,61.673363 106.706345,70.000000 + C102.378632,70.000000 97.946892,70.000000 93.022034,70.000000 +z"/> +<path fill="#FFFFFF" opacity="1.000000" stroke="none" + d=" +M71.000000,95.977966 + C71.000000,99.451210 71.000000,102.431343 71.000000,105.703949 + C63.069641,105.703949 55.331253,105.703949 47.294834,105.703949 + C47.294834,98.067245 47.294834,90.328865 47.294834,82.293655 + C54.935215,82.293655 62.673565,82.293655 71.000000,82.293655 + C71.000000,86.621376 71.000000,91.053108 71.000000,95.977966 +z"/> +<path fill="#FFFFFF" opacity="1.000000" stroke="none" + d=" +M83.000000,89.067169 + C83.000000,86.591560 83.000000,84.607620 83.000000,82.312347 + C90.897972,82.312347 98.636818,82.312347 106.689407,82.312347 + C106.689407,89.899902 106.689407,97.639107 106.689407,105.690857 + C99.096687,105.690857 91.357620,105.690857 83.000000,105.690857 + C83.000000,100.409920 83.000000,94.984383 83.000000,89.067169 +z"/> +</svg> \ No newline at end of file diff --git a/src/assets/svg/scan.svg b/src/assets/svg/scan.svg deleted file mode 100644 index 9f13be809f4e831dfef6979252ec26b8ec15ac4c..0000000000000000000000000000000000000000 --- a/src/assets/svg/scan.svg +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Generator: Adobe Illustrator 27.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> -<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" - viewBox="0 0 283.5 283.5" style="enable-background:new 0 0 283.5 283.5;" xml:space="preserve"> -<g id="Group_19" transform="translate(0)"> - <g id="Group_14" transform="translate(34.592 0)"> - <path id="Path_24" d="M199.6,112.8c-4.8,0-8.6-3.9-8.6-8.6c0,0,0,0,0,0V68.7c0-7.9-6.4-14.3-14.4-14.3H141c-4.8,0-8.6-3.9-8.6-8.6 - c0,0,0,0,0,0c0-4.8,3.9-8.6,8.6-8.6c0,0,0,0,0,0h35.5c17.5,0,31.6,14.2,31.7,31.6v35.5C208.2,109,204.3,112.8,199.6,112.8 - C199.6,112.8,199.6,112.8,199.6,112.8z"/> - </g> - <g id="Group_15" transform="translate(7.574 0)"> - <path id="Path_25" d="M37.6,112.8c-4.8,0-8.6-3.9-8.6-8.6c0,0,0,0,0,0V68.7C29,51.2,43.2,37,60.6,37h35.5c4.8,0,8.6,3.9,8.6,8.6 - c0,0,0,0,0,0c0,4.8-3.9,8.6-8.6,8.6c0,0,0,0,0,0H60.6c-7.9,0-14.4,6.4-14.4,14.3v35.5C46.3,109,42.4,112.8,37.6,112.8z"/> - </g> - <g id="Group_16" transform="translate(7.574 27.015)"> - <path id="Path_26" d="M96.2,216.2H60.6c-17.5,0-31.6-14.2-31.7-31.7V149c0-4.8,3.9-8.6,8.6-8.6c0,0,0,0,0,0c4.8,0,8.6,3.9,8.6,8.6 - c0,0,0,0,0,0v35.6c0,7.9,6.4,14.4,14.4,14.4h35.5c4.8,0,8.6,3.9,8.6,8.6c0,0,0,0,0,0C104.8,212.4,101,216.2,96.2,216.2z"/> - </g> - <g id="Group_17" transform="translate(34.592 27.015)"> - <path id="Path_27" d="M176.6,216.2H141c-4.8,0-8.6-3.9-8.6-8.6c0,0,0,0,0,0c0-4.8,3.9-8.6,8.6-8.6c0,0,0,0,0,0h35.5 - c7.9,0,14.4-6.4,14.4-14.4V149c0-4.8,3.9-8.6,8.6-8.6c0,0,0,0,0,0c4.8,0,8.6,3.9,8.6,8.6c0,0,0,0,0,0v35.6 - C208.2,202.1,194,216.2,176.6,216.2z"/> - </g> - <g id="Group_18" transform="translate(0 19.572)"> - <path id="Path_28" d="M274.9,129.2H8.6c-4.8,0-8.6-3.9-8.6-8.6c0,0,0,0,0,0c0-4.8,3.9-8.7,8.6-8.7c0,0,0,0,0,0h266.2 - c4.8,0,8.6,3.9,8.6,8.6c0,0,0,0,0,0C283.5,125.3,279.6,129.2,274.9,129.2C274.9,129.2,274.9,129.2,274.9,129.2z"/> - </g> -</g> -</svg> diff --git a/src/assets/svg/verifiable_e-mail2.svg b/src/assets/svg/verifiable_e-mail2.svg new file mode 100644 index 0000000000000000000000000000000000000000..f2f2f567d6898503e0866bad97e7aebf3dd96dc8 --- /dev/null +++ b/src/assets/svg/verifiable_e-mail2.svg @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 170.771 185.903"> + <g id="title" transform="translate(-726.09 -100)"> + <g id="e-mail_icon" data-name="e-mail icon" transform="translate(726.09 100)"> + <path id="Path_1057" data-name="Path 1057" d="M80.151,175.385C12.365,143.508,8.179,74.28,9.511,46a12.391,12.391,0,0,1,7.845-10.9L80.865,10.206a12.408,12.408,0,0,1,9.016,0L153.4,35.1A12.4,12.4,0,0,1,161.261,46c1.318,28.283-2.907,97.524-70.654,129.388a12.4,12.4,0,0,1-10.456,0M85.292,0a21.547,21.547,0,0,0-7.829,1.513L13.953,26.406A21.723,21.723,0,0,0,.188,45.566C-.445,58.9,0,85.3,10.09,112.292A127.055,127.055,0,0,0,35.818,154.7,128.576,128.576,0,0,0,76.17,183.821l.861.389a21.483,21.483,0,0,0,17.56-.376c31.687-14.909,53.916-38.981,66.091-71.543,10.078-26.992,10.536-53.391,9.9-66.726a21.739,21.739,0,0,0-13.778-19.16L93.3,1.514A21.484,21.484,0,0,0,85.477,0Z" transform="translate(0 -0.001)"/> + <path id="Path_1058" data-name="Path 1058" d="M39.966,44.256a12.773,12.773,0,0,0-5.111,1.061L72.051,73.5a9.441,9.441,0,0,0,11.367,0l37.11-28.122a12.78,12.78,0,0,0-5.256-1.122Z" transform="translate(7.652 9.714)"/> + <path id="Path_1059" data-name="Path 1059" d="M28.516,55.622V97.039A12.842,12.842,0,0,0,41.358,109.88h75.306a12.843,12.843,0,0,0,12.842-12.842V55.622a12.686,12.686,0,0,0-.843-4.572L90.7,79.807a19.208,19.208,0,0,1-23.147,0L29.405,50.916a12.9,12.9,0,0,0-.889,4.706" transform="translate(6.259 11.177)"/> + </g> + </g> +</svg> \ No newline at end of file diff --git a/src/screens/SealDetailsInfo/Card.tsx b/src/components/EmailCard.tsx similarity index 95% rename from src/screens/SealDetailsInfo/Card.tsx rename to src/components/EmailCard.tsx index 8e9d8754ebc0e44b8786d6df6804609fe211bdc5..eaa0e77c665562278a8b70ea16860d9ce0c20cf6 100644 --- a/src/screens/SealDetailsInfo/Card.tsx +++ b/src/components/EmailCard.tsx @@ -9,7 +9,7 @@ export interface Props { SvgIcon?: any; } -const Card = ({ children, background, SvgIcon }: Props) => { +const EmailCard = ({ children, background, SvgIcon }: Props) => { return ( <View style={[styles.wrapper, !!SvgIcon && styles.wrapperWithIcon]}> <Shadow @@ -47,7 +47,7 @@ const Card = ({ children, background, SvgIcon }: Props) => { ); }; -export default Card; +export default EmailCard; const styles = StyleSheet.create({ wrapper: { diff --git a/src/components/SealListItem.tsx b/src/components/EmailListItem.tsx similarity index 55% rename from src/components/SealListItem.tsx rename to src/components/EmailListItem.tsx index 4ab1f041b6d19702518cadcb635262a0b37cbd52..81eb10385d784acb7b1d42ab05d5e44f906a57a4 100644 --- a/src/components/SealListItem.tsx +++ b/src/components/EmailListItem.tsx @@ -1,54 +1,75 @@ -import React, { useMemo } from 'react'; +import React from 'react'; import { Pressable, StyleSheet, View } from 'react-native'; -import { StackNavigationProp } from '@react-navigation/stack'; -import { useNavigation } from '@react-navigation/core'; import { format } from "date-fns"; import { Shadow } from 'react-native-shadow-2'; import { borderRadius, ColorPallet } from 'src/theme/theme'; -import { ScanStackParams, Screens } from 'src/type/navigators'; -import CredentialSvg from 'src/assets/svg/credential.svg'; import Text from 'src/components/Text'; -import { SealQrCodeRecord } from 'src/seal/hooks/useSealQrCodes'; import { DATE_TIME_FORMAT } from "src/constants/constants"; +import CredentialSvg from "src/assets/svg/credential.svg"; +import {parseAddress} from "src/utils/email"; interface Props { - data: SealQrCodeRecord; + id: string; + createdAt: Date; + from: string; + to: string; + cc: string; + bcc: string; + subject: string; + read: boolean; + sealed: boolean; + sealUrl: string | null | undefined; + onPress?: () => void; } -const SealListItem: React.FC<Props> = ({ data }) => { - const navigation = useNavigation<StackNavigationProp<ScanStackParams>>(); - const date = useMemo(() => new Date(data.date), [data]); - const { subject, senderEmail, senderName, url } = data; +const EmailListItem: React.FC<Props> = ({ + id, + createdAt, + from, + to, + cc, + bcc, + subject, + read, + sealed, + sealUrl, + onPress +}) => { + const sender = parseAddress(from); return ( <Pressable - onPress={() => - navigation.navigate(Screens.SealDetailsInfo, { sealUrl: url }) - } - key={date.getTime()} + onPress={onPress} + key={id} > <Shadow style={styles.container}> + {!read && ( + <View style={styles.unread} /> + )} <View style={styles.info}> {subject && <Text style={styles.title}>{subject}</Text>} - {senderName && <Text style={styles.sender}>{senderName}</Text>} - {senderEmail && ( - <Text style={styles.senderEmail}>({senderEmail})</Text> + {sender?.name && <Text style={styles.sender}>{sender.name}</Text>} + {sender?.email && ( + <Text style={styles.senderEmail}>({sender.email})</Text> )} <Text style={styles.date}> - {format(date, DATE_TIME_FORMAT)} + {format(createdAt, DATE_TIME_FORMAT)} </Text> - {!(subject || senderEmail || senderName) && ( - <Text style={styles.url}>{url}</Text> + + {sealed && !(subject || sender?.name || sender?.email) && sealUrl && ( + <Text style={styles.url}>{sealUrl}</Text> )} </View> - <View style={styles.icon}> - <CredentialSvg style={styles.svg} /> - </View> + {sealed && ( + <View style={styles.icon}> + <CredentialSvg style={styles.svg} /> + </View> + )} </Shadow> </Pressable> ); }; -export default SealListItem; +export default EmailListItem; const styles = StyleSheet.create({ container: { @@ -59,6 +80,16 @@ const styles = StyleSheet.create({ flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start', + position: 'relative' + }, + unread: { + position: 'absolute', + width: 14, + height: 14, + backgroundColor: ColorPallet.baseColors.red, + borderRadius: 7, + top: 6, + right: 6 }, icon: { backgroundColor: ColorPallet.brand.primary, diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx index b0ce9cf3d9d6c777eb6e6059a55cec04873bb539..fd9db0f5c945591ff98cf10a1a686e1a2abcc91d 100644 --- a/src/components/SearchBar.tsx +++ b/src/components/SearchBar.tsx @@ -2,17 +2,17 @@ import React, { useState } from 'react'; import Icon from 'react-native-vector-icons/MaterialIcons'; import { useTranslation } from "react-i18next"; import { - Pressable, StyleSheet, View, Keyboard, TextInput, Text, + TouchableOpacity, } from 'react-native'; import { StackScreenProps } from '@react-navigation/stack'; import { useNavigation } from '@react-navigation/core'; import { borderRadius, ColorPallet, TextTheme } from 'src/theme/theme'; -import useNotifications from 'src/hooks/notifications'; +import {useAgentNotifications, useEmailNotifications} from 'src/hooks/notifications'; import SettingsSvg from 'src/assets/svg/settings.svg'; import SearchSvg from 'src/assets/svg/search.svg'; import BellSvg from 'src/assets/svg/bell.svg'; @@ -27,7 +27,10 @@ const SearchBar: React.FC<Props> = ({ searchPhrase, setSearchPhrase }) => { const { t } = useTranslation(); const [focused, setFocused] = useState(false); const navigation = useNavigation<StackScreenProps<SettingStackParams>>(); - const notifications = useNotifications(); + const agentNotifications = useAgentNotifications(); + const emailNotifications = useEmailNotifications(); + + const count = agentNotifications.length + emailNotifications.length; const cancel = () => { Keyboard.dismiss(); @@ -37,24 +40,8 @@ const SearchBar: React.FC<Props> = ({ searchPhrase, setSearchPhrase }) => { return ( <View style={styles.container}> - <Pressable - onPress={() => { - navigation.navigate(Stacks.SettingsStack); - }} - > - <SettingsSvg style={styles.settingsIcon} /> - </Pressable> <View style={styles.searchBar}> - {focused && ( - <Icon - name="close" - color={ColorPallet.grayscale.darkGrey} - size={24} - style={styles.closeIcon} - onPress={cancel} - /> - )} - + <SearchSvg style={styles.searchIcon} /> <TextInput style={[styles.input, focused ? styles.inputFocused : undefined]} returnKeyType="done" @@ -71,21 +58,38 @@ const SearchBar: React.FC<Props> = ({ searchPhrase, setSearchPhrase }) => { setFocused(true); }} /> - <SearchSvg style={styles.searchIcon} /> + {focused && ( + <TouchableOpacity onPress={cancel}> + <Icon + name="close" + color={ColorPallet.grayscale.darkGrey} + size={24} + style={styles.closeIcon} + /> + </TouchableOpacity> + )} </View> - <Pressable - style={styles.bellContainer} + <TouchableOpacity + style={styles.iconContainer} onPress={() => { navigation.navigate(Stacks.NotificationStack); }} > <BellSvg style={styles.bellIcon} /> - {notifications.length > 0 && ( + {count > 0 && ( <View style={styles.notificationBadge}> - <Text style={styles.badgeText}>{notifications.length < 100 ? notifications.length : 99}</Text> + <Text style={styles.badgeText}>{count < 100 ? count : 99}</Text> </View> )} - </Pressable> + </TouchableOpacity> + <TouchableOpacity + style={styles.iconContainer} + onPress={() => { + navigation.navigate(Stacks.SettingsStack); + }} + > + <SettingsSvg style={styles.settingsIcon} /> + </TouchableOpacity> </View> ); }; @@ -104,18 +108,17 @@ const styles = StyleSheet.create({ }, closeIcon: { marginTop: 8, - marginLeft: 6, + marginRight: 6, }, searchIcon: { width: 20, height: 20, fill: ColorPallet.baseColors.black, alignSelf: 'center', - marginRight: 10, + marginLeft: 10, }, searchBar: { marginLeft: 15, - marginRight: 15, height: 40, flexDirection: 'row', flex: 1, @@ -132,9 +135,10 @@ const styles = StyleSheet.create({ inputFocused: { marginLeft: 0, }, - bellContainer: { + iconContainer: { position: 'relative', flexDirection: 'row', + marginLeft: 15, }, bellIcon: { width: 32, diff --git a/src/components/TextInput.tsx b/src/components/TextInput.tsx index 20826df364cd089e875a1f49b1d2892cdab599f7..72b3f5b1f6d1a0fcc9f8288e2beee81a04840d7a 100644 --- a/src/components/TextInput.tsx +++ b/src/components/TextInput.tsx @@ -58,6 +58,7 @@ const TextInput: React.FC<Props> = ({ onBlur={() => setFocused(false)} {...textInputProps} placeholderTextColor={ColorPallet.grayscale.lightGrey} + autoCapitalize='none' /> </View> ); diff --git a/src/components/notifications/NotificationEmailListItem.tsx b/src/components/notifications/NotificationEmailListItem.tsx new file mode 100644 index 0000000000000000000000000000000000000000..b018e8126b5f1279de393bb3007d8170025a0236 --- /dev/null +++ b/src/components/notifications/NotificationEmailListItem.tsx @@ -0,0 +1,139 @@ +import React from 'react'; +import { Pressable, StyleSheet, View } from 'react-native'; +import { format } from "date-fns"; +import { Shadow } from 'react-native-shadow-2'; +import {borderRadius, ColorPallet, TextTheme} from 'src/theme/theme'; +import Text from 'src/components/Text'; +import { DATE_TIME_FORMAT } from "src/constants/constants"; +import {parseAddress} from "src/utils/email"; +import EmailSvg from 'src/assets/svg/verifiable_e-mail2.svg'; +import Button, {ButtonType} from "../Button"; +import {useTranslation} from "react-i18next"; + +interface Props { + id: string; + createdAt: Date; + from: string; + to: string; + cc: string; + bcc: string; + subject: string; + sealed: boolean; + sealUrl: string | null | undefined; + onPress?: () => void; +} + +const EmailListItem: React.FC<Props> = ({ + id, + createdAt, + from, + to, + cc, + bcc, + subject, + sealed, + sealUrl, + onPress +}) => { + const { t } = useTranslation(); + const sender = parseAddress(from); + return ( + <Pressable + onPress={onPress} + key={id} + > + <View style={styles.container}> + <View style={styles.avatar}> + <EmailSvg style={styles.svg} /> + </View> + <View style={styles.details}> + <View style={styles.headerContainer}> + <Text style={styles.title}>{subject}</Text> + </View> + <View style={styles.bodyContainer}> + <View> + {sender?.name && <Text style={styles.sender}>{sender.name}</Text>} + {sender?.email && ( + <Text style={styles.senderEmail}>({sender.email})</Text> + )} + <Text style={styles.date}> + {format(createdAt, DATE_TIME_FORMAT)} + </Text> + </View> + <Button + buttonType={ButtonType.Primary} + title={t<string>('Global.View')} + buttonStyle={styles.buttonView} + onPress={onPress} + /> + </View> + </View> + </View> + </Pressable> + ); +}; + +export default EmailListItem; + +const styles = StyleSheet.create({ + container: { + backgroundColor: ColorPallet.grayscale.veryLightGrey, + borderRadius: borderRadius, + padding: 8, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'flex-start', + }, + avatar: { + width: 50, + height: 50, + justifyContent: 'center', + alignItems: 'center', + borderRadius: borderRadius, + }, + svg: { + width: 50, + height: 50, + fill: ColorPallet.brand.primary, + }, + details: { + flex: 1, + flexDirection: 'column', + marginLeft: 10, + flexShrink: 1, + justifyContent: 'flex-start', + }, + + title: { + fontWeight: 'bold', + color: ColorPallet.brand.primary, + fontSize: 20, + }, + sender: { + marginTop: 4, + fontWeight: 'bold', + color: ColorPallet.baseColors.black, + fontSize: 19, + }, + senderEmail: { + color: ColorPallet.baseColors.black, + fontSize: 14, + }, + date: { + color: ColorPallet.baseColors.black, + fontSize: 14, + }, + headerContainer: { + flexDirection: 'row', + }, + bodyContainer: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + }, + buttonView: { + paddingTop: 5, + paddingBottom: 5, + height: 36, + }, +}); diff --git a/src/components/NotificationListItem/index.tsx b/src/components/notifications/NotificationListItem.tsx similarity index 94% rename from src/components/NotificationListItem/index.tsx rename to src/components/notifications/NotificationListItem.tsx index ade8a309f72828c0847a21788f11f019142d1adf..72e9f53d372054e0dc69f4d2d72465b9e8a9e096 100644 --- a/src/components/NotificationListItem/index.tsx +++ b/src/components/notifications/NotificationListItem.tsx @@ -3,13 +3,13 @@ import { useTranslation } from 'react-i18next'; import {StyleSheet, View, Text, Pressable} from 'react-native'; import {borderRadius, ColorPallet, TextTheme} from 'src/theme/theme'; import Button, { ButtonType } from 'src/components/Button'; -import {Notification} from "src/utils/agentUtils"; +import {AgentNotification} from "src/utils/agentUtils"; import rootStore from "src/store/rootStore"; import {hashCode, hashToRGBA, parseCredDef} from "src/utils/helpers"; import NewConnectionSvg from 'src/assets/svg/new_connection.svg'; interface NotificationListItemProps { - notification: Notification; + notification: AgentNotification; onView?: () => void; } @@ -23,6 +23,7 @@ const NotificationListItem: React.FC<NotificationListItemProps> = ({ useEffect(() => { (async () => { + console.log(notification); if (notification.proofRequest) { setTitle(t<string>('ProofRequest.ProofRequest')); setBody(notification.connection?.theirLabel ?? 'Connectionless proof request'); @@ -38,6 +39,10 @@ const NotificationListItem: React.FC<NotificationListItemProps> = ({ })(); }, []) + // console.log('title'); + // console.log(title); + // console.log(body); + return ( <Pressable testID="notification-list-item" onPress={onView}> diff --git a/src/db-models/Email.ts b/src/db-models/Email.ts new file mode 100644 index 0000000000000000000000000000000000000000..590995d81642d037fe919885e420aeebfd804095 --- /dev/null +++ b/src/db-models/Email.ts @@ -0,0 +1,50 @@ +import Realm from 'realm'; +class Email extends Realm.Object<Email> { + _id!: Realm.BSON.ObjectId; + messageId?: string; + createdAt!: Date; + receivedDate!: Date; + + type!: "svdx-mail" | 'sealed'; + + from!: string; + to!: string; + cc!: string; + bcc!: string; + subject!: string; + read!: boolean; + + svdxMime?: string | null; + svdxImapSaved?: boolean | null; + svdxMessageId?: string | null; + + sealUrl?: string | null; + + static schema = { + name: 'Email', + properties: { + _id: 'objectId', + messageId: 'string?', + createdAt: 'date', + receivedDate: 'date', + + type: 'string', + + from: 'string', + to: 'string', + cc: 'string', + bcc: 'string', + subject: 'string', + read: 'bool', + + svdxMime: 'string?', + svdxImapSaved: 'bool?', + svdxMessageId: 'string?', + + sealUrl: 'string?' + }, + primaryKey: '_id', + }; +} + +export default Email; \ No newline at end of file diff --git a/src/db-models/index.ts b/src/db-models/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..ae108f7b46a7678559aeba1cadb57b4863bef835 --- /dev/null +++ b/src/db-models/index.ts @@ -0,0 +1,3 @@ +import Email from './Email'; + +export const schemas = [Email]; \ No newline at end of file diff --git a/src/hooks/notifications.ts b/src/hooks/notifications.ts index 265483ad34d0afa748507fd53816542ce4d4c6f5..c9a7faba83057ad516170cff3b81b15500740e46 100644 --- a/src/hooks/notifications.ts +++ b/src/hooks/notifications.ts @@ -1,9 +1,11 @@ import { useEffect, useState } from 'react'; -import {getNotifications, Notification} from "../utils/agentUtils"; -import rootStore from "../store/rootStore"; +import {getNotifications, AgentNotification} from "src/utils/agentUtils"; +import rootStore from "src/store/rootStore"; +import {Results, useQuery} from "@realm/react"; +import Email from "../db-models/Email"; -const useNotifications = (): Notification[] => { - const [notifications, setNotifications] = useState<Notification[]>([]); +export const useAgentNotifications = (): AgentNotification[] => { + const [notifications, setNotifications] = useState<AgentNotification[]>([]); const fetchNotifications = async () => { const data = await getNotifications(rootStore.agentStore.agent); @@ -19,4 +21,10 @@ const useNotifications = (): Notification[] => { return notifications; }; -export default useNotifications; +export const useEmailNotifications = (): Results<Email> => { + let emailQuery = useQuery(Email); + emailQuery = emailQuery.filtered(`read == $0`, false); + emailQuery = emailQuery.sorted('createdAt', true); + + return emailQuery; +}; \ No newline at end of file diff --git a/src/localization/de/index.ts b/src/localization/de/index.ts index 4aefbabc30ff3b2dcb2dc3237c0af3305b32565a..fb4086d43f5422f4eb930948d9683205e7702462 100644 --- a/src/localization/de/index.ts +++ b/src/localization/de/index.ts @@ -69,7 +69,6 @@ const translation = { ReenterNewPin: 'Geben Sie die neue PIN nochmals ein', Create: 'Erstellen', ValidOldPin: 'Bitte geben Sie eine gültige alte PIN ein', - WalletCreated: 'Das Wallet wurde erfolgreich erstellt', OR: 'oder', PinInfo: 'Diese PIN wird für zum Öffnen der Wallet verwendet', GoBackAlertTitle: 'Already authenticated!', @@ -192,10 +191,10 @@ const translation = { PleaseWait: 'Please wait...', }, TabStack: { - Connections: 'Verbindung', + Contacts: 'Kontakte', Scan: 'Scan', Credentials: 'Credentials', - SealHistory: 'SEAL Archiv', + Emails: 'Email' }, Toasts:{ Success: 'Erfolg', @@ -262,7 +261,7 @@ const translation = { Initialization: 'Intialize wallet', SetupDelay: 'Initializing Wallet', EnterPin: 'Login', - ListContacts: 'Connections', + ListContacts: 'Kontakte', Notifications: 'Notifications', ChangePin: 'Change Pin', Credentials: 'Credentials', @@ -273,9 +272,10 @@ const translation = { Language: 'Language', ExportWallet: 'Export Wallet', ImportWallet: 'Import Wallet', - ContactDetails: 'Connection Details', + ContactDetails: 'Contact Details', ViewMnemonic: 'View Mnemonic', - SealScannedQrCodeList: 'SEAL History', + ReceivedEmails: 'Received Emails', + EmailDetails: 'Email Details', SealDetailsInfo: 'SEAL History Details ', }, Seal: { diff --git a/src/localization/en/index.ts b/src/localization/en/index.ts index 3f95752ae6c2d115f8694f36d8847625bd04f957..707be053963dd762f78b63e08d66fda4adc32716 100644 --- a/src/localization/en/index.ts +++ b/src/localization/en/index.ts @@ -69,7 +69,6 @@ const translation = { ReenterNewPin: 'Re-Enter the New PIN', Create: 'Create', ValidOldPin: 'Please enter valid Old PIN', - WalletCreated: 'The wallet is created successfully.', OR: 'OR', PinInfo: 'This pin is used for login', GoBackAlertTitle: 'Already authenticated!', @@ -192,10 +191,10 @@ const translation = { PleaseWait: 'Please wait...', }, TabStack: { - Connections: 'Connection', + Contacts: 'Contacts', Scan: 'Scan', Credentials: 'Credential', - SealHistory: 'SEAL History', + Emails: 'Email' }, Toasts:{ Success: 'Success', @@ -262,7 +261,7 @@ const translation = { Initialization: 'Intialize wallet', SetupDelay: 'Initializing Wallet', EnterPin: 'Login', - ListContacts: 'Connections', + ListContacts: 'Contacts', Notifications: 'Notifications', ChangePin: 'Change Pin', Credentials: 'Credentials', @@ -273,9 +272,10 @@ const translation = { Language: 'Language', ExportWallet: 'Export Wallet', ImportWallet: 'Import Wallet', - ContactDetails: 'Connection Details', + ContactDetails: 'Contact Details', ViewMnemonic: 'View Mnemonic', - SealScannedQrCodeList: 'SEAL History', + ReceivedEmails: 'Received Emails', + EmailDetails: 'Email Details', SealDetailsInfo: 'SEAL History Details', }, Seal: { diff --git a/src/localization/fr/index.ts b/src/localization/fr/index.ts index cb77e97262ce5fc68151c91f4ce10aaaccf4fed5..49e06f33fd9e13be54c23583246738b7e7eb2011 100644 --- a/src/localization/fr/index.ts +++ b/src/localization/fr/index.ts @@ -69,7 +69,6 @@ const translation = { ReenterNewPin: 'Re-Enter the New PIN', Create: 'Créer', ValidOldPin: 'Veuillez saisir un ancien code PIN valide', - WalletCreated: 'Le portefeuille est créé avec succès', OR: 'OU', PinInfo: 'Cette broche est utilisée pour la connexion', GoBackAlertTitle: 'Already authenticated!', @@ -192,10 +191,10 @@ const translation = { PleaseWait: 'Please wait...', }, TabStack: { - Connections: 'Connexion', + Contacts: 'Contacts', Scan: 'Analyse', Credentials: 'Identifiants', - SealHistory: 'SEAL l\'histoire', + Emails: 'Email' }, Toasts:{ Success: 'Succès', @@ -262,7 +261,7 @@ const translation = { Initialization: 'Intialize wallet', SetupDelay: 'Initializing Wallet', EnterPin: 'Login', - ListContacts: 'Connections', + ListContacts: 'Contacts', Notifications: 'Notifications', ChangePin: 'Change Pin', Credentials: 'Credentials', @@ -273,9 +272,10 @@ const translation = { Language: 'Language', ExportWallet: 'Export Wallet', ImportWallet: 'Import Wallet', - ContactDetails: 'Connection Details', + ContactDetails: 'Contact Details', ViewMnemonic: 'View Mnemonic', - SealScannedQrCodeList: 'SEAL History', + ReceivedEmails: 'Received Emails', + EmailDetails: 'Email Details', SealDetailsInfo: 'SEAL History Details', }, Seal: { diff --git a/src/navigators/SealStack.tsx b/src/navigators/EmailStack.tsx similarity index 53% rename from src/navigators/SealStack.tsx rename to src/navigators/EmailStack.tsx index 805d9a8e55b5ef144e205d6ef1fe205c06ad3e35..f1d141264be850428d5bbcdbd5cb515d0edb5cda 100644 --- a/src/navigators/SealStack.tsx +++ b/src/navigators/EmailStack.tsx @@ -2,28 +2,37 @@ import { createStackNavigator } from '@react-navigation/stack'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { ColorPallet } from 'src/theme/theme'; -import { SealStackParams, Screens } from 'src/type/navigators'; -import SealScannedQrCodeList from 'src/screens/SealScannedQrCodeList'; -import SealDetailsInfo from 'src/screens/SealDetailsInfo'; +import { EmailStackParams, Screens } from 'src/type/navigators'; +import ReceivedEmailList from 'src/screens/ReceivedEmailList'; +import EmailDetails from 'src/screens/EmailDetails'; import defaultStackOptions from './defaultStackOptions'; +import SealDetailsInfo from "../screens/SealDetailsInfo"; -const Stack = createStackNavigator<SealStackParams>(); +const Stack = createStackNavigator<EmailStackParams>(); -const SealStack: React.FC = () => { +const EmailStack: React.FC = () => { const { t } = useTranslation(); return ( <Stack.Navigator screenOptions={{ ...defaultStackOptions }}> <Stack.Screen - name={Screens.SealScannedQrCodeList} - component={SealScannedQrCodeList} + name={Screens.ReceivedEmails} + component={ReceivedEmailList} options={() => ({ - title: t<string>('ScreenTitles.SealScannedQrCodeList'), + title: t<string>('ScreenTitles.ReceivedEmails'), headerTintColor: ColorPallet.baseColors.white, headerShown: true, headerLeft: () => false, rightLeft: () => false, })} /> + <Stack.Screen + name={Screens.EmailDetails} + component={EmailDetails} + options={() => ({ + title: t<string>('ScreenTitles.EmailDetails'), + headerTintColor: ColorPallet.baseColors.white, + })} + /> <Stack.Screen name={Screens.SealDetailsInfo} component={SealDetailsInfo} @@ -36,4 +45,4 @@ const SealStack: React.FC = () => { ); }; -export default SealStack; +export default EmailStack; diff --git a/src/navigators/RootStack.tsx b/src/navigators/RootStack.tsx index 05eaa29ec80310c261ca3e09b7b6e3de2ff7bae4..fa1f87e45239a7090cd37d45e350c01762048c42 100644 --- a/src/navigators/RootStack.tsx +++ b/src/navigators/RootStack.tsx @@ -7,12 +7,20 @@ import AgentProvider from '@aries-framework/react-hooks'; import rootStore from "src/store/rootStore"; import MainStack from './MainStack'; import OnboardingStack from './OnboardingStack'; +import {useRealm} from "@realm/react"; +import notifee, { EventType } from '@notifee/react-native'; +import {Screens, TabStacks} from 'src/type/navigators'; const RootStack: React.FC = observer(() => { const navigation = useNavigation(); + const realm = useRealm(); useEffect(() => { rootStore.agentStore.createAgent(); rootStore.urlStore.injectNavigation(navigation); + rootStore.agentStore.injectNavigation(navigation); + rootStore.injectRealm(realm); + rootStore.agentStore.injectRealm(realm); + notifee.requestPermission(); }, []); @@ -30,6 +38,29 @@ const RootStack: React.FC = observer(() => { })(); }, []); + // Subscribe to events + useEffect(() => { + if (!rootStore.authenticated) return; + + return notifee.onForegroundEvent(({ type, detail }) => { + switch (type) { + case EventType.PRESS: + console.log('User pressed notification', detail.notification); + if (detail.notification?.data?.type === 'new-email-received') { + const realmId = detail.notification?.data?.realmId as string; + if (realmId) { + navigation.navigate(TabStacks.EmailStack, { + screen: Screens.EmailDetails, + params: { realmId: realmId }, + }); + } + } + + break; + } + }); + }, [rootStore.authenticated]); + useEffect(() => { if (rootStore.authenticated) { rootStore.urlStore.processDeepLinkIfAny(); diff --git a/src/navigators/SettingStack.tsx b/src/navigators/SettingStack.tsx index c0786c1a36d7f04385bfbbed1f4302fcc02be25c..7389be06b08589a54af66e1b7d4622cdd8172b10 100644 --- a/src/navigators/SettingStack.tsx +++ b/src/navigators/SettingStack.tsx @@ -8,6 +8,7 @@ import ExportWallet from 'src/screens/ExportWallet'; import Language from 'src/screens/Language'; import LegalAndPrivacy from 'src/screens/LegalAndPrivacy'; import ViewMnemonic from 'src/screens/ViewMnemonic'; +import ImapConfiguration from "src/screens/ImapConfiguration"; import defaultStackOptions from './defaultStackOptions'; const Stack = createStackNavigator<SettingStackParams>(); @@ -60,6 +61,13 @@ const SettingStack: React.FC<SettingStackProp> = () => { title: t<string>('ScreenTitles.LegalAndPrivacy'), }} /> + <Stack.Screen + name={Screens.ImapConfiguration} + component={ImapConfiguration} + options={{ + title: "Imap configuration" + }} + /> </Stack.Navigator> ); }; diff --git a/src/navigators/TabStack.tsx b/src/navigators/TabStack.tsx index 0d9cfd0d6e0370ccdf63943eaa16661f859a1b92..f995472777469decf92ccf7e6db5ad310b5ac1d8 100644 --- a/src/navigators/TabStack.tsx +++ b/src/navigators/TabStack.tsx @@ -1,21 +1,20 @@ import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import React from 'react'; import { useTranslation } from 'react-i18next'; -import { StyleSheet, Text, View } from 'react-native'; +import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import { ColorPallet, TextTheme } from 'src/theme/theme'; import { Screens, - Stacks, TabStackParams, TabStacks, } from 'src/type/navigators'; -import ContactStack from './ContactStack'; -import SealStack from './SealStack'; -import CredentialStack from './CredentialStack'; import CredentialSvg from 'src/assets/svg/credential.svg'; -import ScanSvg from 'src/assets/svg/scan.svg'; import ConnectionsSvg from 'src/assets/svg/connections.svg'; -import SealHistorySvg from 'src/assets/svg/seal_history.svg'; +import EmailSvg from 'src/assets/svg/verifiable_e-mail2.svg'; +import ContactStack from './ContactStack'; +import EmailStack from './EmailStack'; +import CredentialStack from './CredentialStack'; +import TabStackCustom from "./TabStackCustom"; const MainTabNavigator = createBottomTabNavigator<TabStackParams>(); @@ -56,6 +55,7 @@ const TabStack: React.FC = () => { return ( <MainTabNavigator.Navigator + tabBar={props => <TabStackCustom {...props} />} screenOptions={{ tabBarStyle: styles.tabBarStyle, tabBarActiveTintColor: ColorPallet.baseColors.white, @@ -80,25 +80,6 @@ const TabStack: React.FC = () => { unmountOnBlur: true, }} /> - <MainTabNavigator.Screen - name={TabStacks.ScanStack} - options={{ - tabBarIcon: () => <TabBarIcon focused={false} Svg={ScanSvg} />, - tabBarLabel: () => ( - <TabBarLabel label={t<string>('TabStack.Scan')} /> - ), - tabBarAccessibilityLabel: t<string>('TabStack.Scan'), - }} - listeners={({ navigation }) => ({ - tabPress: e => { - e.preventDefault(); - navigation.navigate(Screens.Scan); - }, - })} - > - {/* Just a placeholder, the tab will navigate to a different stack */} - {() => <View />} - </MainTabNavigator.Screen> <MainTabNavigator.Screen name={TabStacks.ConnectionStack} component={ContactStack} @@ -107,28 +88,28 @@ const TabStack: React.FC = () => { <TabBarIcon focused={focused} Svg={ConnectionsSvg} /> ), tabBarLabel: () => ( - <TabBarLabel label={t<string>('TabStack.Connections')} /> + <TabBarLabel label={t<string>('TabStack.Contacts')} /> ), unmountOnBlur: true, }} /> <MainTabNavigator.Screen - name={TabStacks.SealStack} - component={SealStack} + name={TabStacks.EmailStack} + component={EmailStack} options={{ tabBarIcon: ({ focused }) => ( - <TabBarIcon focused={focused} Svg={SealHistorySvg} /> + <TabBarIcon focused={focused} Svg={EmailSvg} /> ), tabBarLabel: () => ( - <TabBarLabel label={t<string>('TabStack.SealHistory')} /> + <TabBarLabel label={"Emails"} /> ), unmountOnBlur: true, }} listeners={({ navigation }) => ({ tabPress: e => { e.preventDefault(); - navigation.navigate(TabStacks.SealStack, { - screen: Screens.SealScannedQrCodeList, + navigation.navigate(TabStacks.EmailStack, { + screen: Screens.ReceivedEmails, }); }, })} diff --git a/src/navigators/TabStackCustom.tsx b/src/navigators/TabStackCustom.tsx new file mode 100644 index 0000000000000000000000000000000000000000..aba2424d802cf5f495bd04eb299a31d798e4874c --- /dev/null +++ b/src/navigators/TabStackCustom.tsx @@ -0,0 +1,65 @@ +import React from 'react'; +import { View, TouchableOpacity, Text, StyleSheet } from 'react-native'; +import { BottomTabBar } from '@react-navigation/bottom-tabs'; +import ScanQrSvg from 'src/assets/svg/scan-qr.svg'; +import {TextTheme} from "../theme/theme"; +import {useNavigation} from "@react-navigation/core"; +import {Screens} from "../type/navigators"; + +function TabStackCustom(props: any) { + const navigation = useNavigation() + return ( + <View style={styles.container}> + <BottomTabBar {...props} /> + <TouchableOpacity + style={styles.floatingButton} + onPress={() => { + navigation.navigate(Screens.Scan); + }} + > + <ScanQrSvg + style={[ + styles.svg + ]} + resizeMode="contain" + /> + </TouchableOpacity> + </View> + ); +} + +const styles = StyleSheet.create({ + container: { + position: 'relative', + }, + floatingButton: { + position: 'absolute', + bottom: 100, + right: 10, + + width: 56, + height: 56, + borderRadius: 28, // half of width/height to get a round shape + overflow: 'hidden', // this will ensure the gradient doesn't overflow the button + backgroundColor: '#42d0e2', + elevation: 4, // Shadow for Android + shadowOffset: { width: 0, height: 2 }, // Shadow for iOS + shadowOpacity: 0.3, + shadowRadius: 2, // Shadow for iOS + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + }, + text: { + ...TextTheme.label, + }, + buttonContainer: { + + }, + svg: { + width: 34, + height: 34, + } +}); + +export default TabStackCustom; \ No newline at end of file diff --git a/src/screens/ConnectionInvitation/index.tsx b/src/screens/ConnectionInvitation/index.tsx index 10f3a4731cc6155068c404eeefb9c6995420561c..0d7f5a1fbb786c6e2b5baefde04f512aee5d994f 100644 --- a/src/screens/ConnectionInvitation/index.tsx +++ b/src/screens/ConnectionInvitation/index.tsx @@ -9,7 +9,7 @@ import Button, { ButtonType } from 'src/components/Button'; import ConnectionsSvg from 'src/assets/svg/connections.svg'; import {useNavigation} from "@react-navigation/core"; import rootStore from "src/store/rootStore"; -import {warningToast} from "../../utils/toast"; +import {warningToast} from "src/utils/toast"; interface ConnectionProps { route: any; diff --git a/src/screens/CreateWallet/index.tsx b/src/screens/CreateWallet/index.tsx index fe349c9919589182abff0ee321785e5dd71fc0e9..d089f63925c793778bce65cfdf4c9e38982ec0e2 100644 --- a/src/screens/CreateWallet/index.tsx +++ b/src/screens/CreateWallet/index.tsx @@ -36,7 +36,6 @@ const CreateWallet: React.FC<CreateWalletProps> = ({ navigation }) => { await rootStore.agentStore.startAgent(); await markAsOnboardComplete(); setLoading(false); - successToast(t<string>('PinCreate.WalletCreated')); navigation.navigate(Screens.SetupDelay); } catch (error: any) { diff --git a/src/screens/CredentialDetails/CredentialDetailsStore.ts b/src/screens/CredentialDetails/CredentialDetailsStore.ts index f52e8c2ea2050336a88bab01ba541ee0f4a4349a..400048b04f7b31aa3cd2017c3cc0d79cf866a3af 100644 --- a/src/screens/CredentialDetails/CredentialDetailsStore.ts +++ b/src/screens/CredentialDetails/CredentialDetailsStore.ts @@ -5,7 +5,7 @@ import {RecordHistory} from "src/type/record"; import { CredentialExchangeRecord } from "@aries-framework/core/build/modules/credentials/repository/CredentialExchangeRecord"; -import {errorToast} from "../../utils/toast"; +import {errorToast} from "src/utils/toast"; import i18next from "i18next"; diff --git a/src/screens/CredentialOffer/CredentialOfferStore.ts b/src/screens/CredentialOffer/CredentialOfferStore.ts index 0aef53b61f511a0e739da413d5744f57452568ab..263b985625947ffa76c4a92fd000012324a1d036 100644 --- a/src/screens/CredentialOffer/CredentialOfferStore.ts +++ b/src/screens/CredentialOffer/CredentialOfferStore.ts @@ -5,14 +5,14 @@ import { CredentialState, GetCredentialFormatDataReturn } from "@aries-framework/core"; -import rootStore from "../../store/rootStore"; +import rootStore from "src/store/rootStore"; import {TFunction} from "i18next"; import {Alert} from "react-native"; import Toast from "react-native-toast-message"; import {ToastType} from "../../components/toast/BaseToast"; import {useCallback} from "react"; import {ConnectionRecord} from "@aries-framework/core/build/modules/connections/repository/ConnectionRecord"; -import {credentialDefinition} from "../../utils/helpers"; +import {credentialDefinition} from "src/utils/helpers"; // import { GetFormatDataReturn, IndyCredentialFormat} from "@aries-framework/core"; // import rootStore from "src/store/rootStore"; // import { diff --git a/src/screens/CredentialOffer/index.tsx b/src/screens/CredentialOffer/index.tsx index 7a4a8c549ee5bf4b176d83be3b9362cb0fc81395..460d0893c47d2a21e4fb73d70ea59bdfa5c0a209 100644 --- a/src/screens/CredentialOffer/index.tsx +++ b/src/screens/CredentialOffer/index.tsx @@ -6,16 +6,16 @@ import { ColorPallet, TextTheme } from 'src/theme/theme'; import { NotificationStackParams, Screens } from 'src/type/navigators'; import CredentialOfferStore from "./CredentialOfferStore"; import {useTranslation} from "react-i18next"; -import FlowDetailModal from "../../components/FlowDetailModal"; +import FlowDetailModal from "src/components/FlowDetailModal"; import {useNavigation} from "@react-navigation/core"; import CredentialPending from "./CredentialPending"; import {useConnectionById, useCredentialById} from "@aries-framework/react-hooks"; import {ConnectionRecord} from "@aries-framework/core/build/modules/connections/repository/ConnectionRecord"; import CredentialDeclined from "./CredentialDeclined"; -import CredentialCard from "../../components/CredentialCard"; -import Button, {ButtonType} from "../../components/Button"; -import Record from "../../components/Record"; -import Title from "../../components/Title"; +import CredentialCard from "src/components/CredentialCard"; +import Button, {ButtonType} from "src/components/Button"; +import Record from "src/components/Record"; +import Title from "src/components/Title"; import {CredentialState} from "@aries-framework/core"; type CredentialOfferProps = StackScreenProps< diff --git a/src/screens/EmailDetails/ContentCard.tsx b/src/screens/EmailDetails/ContentCard.tsx new file mode 100644 index 0000000000000000000000000000000000000000..baa8c56d3d3768ddf0cec334688f3f79dda1d314 --- /dev/null +++ b/src/screens/EmailDetails/ContentCard.tsx @@ -0,0 +1,67 @@ +import React from 'react'; +import {StyleSheet, Text, useWindowDimensions, View} from 'react-native'; +import { useTranslation } from "react-i18next"; +import RenderHtml from 'react-native-render-html'; +import { ColorPallet, TextTheme } from 'src/theme/theme'; +import ContentSvg from 'src/assets/svg/content.svg'; +import Card from 'src/components/EmailCard'; + +interface Props { + html: string; + plainText: string; +} + +const ContentCard = ({ html, plainText }: Props) => { + const { t } = useTranslation(); + const { width } = useWindowDimensions(); + + return ( + <Card background="white" SvgIcon={ContentSvg}> + <Text style={styles.title}>{t<string>('Seal.Ipfs.EmailContent')}</Text> + {html && ( + <RenderHtml + baseStyle={styles.html} + contentWidth={width - 100} + source={{ + html, + }} + /> + )} + {!html && plainText && ( + <View> + <Text style={styles.plainText}> + {plainText} + </Text> + </View> + )} + {!html && !plainText && ( + <View> + <Text style={styles.empty}> + No content + </Text> + </View> + )} + </Card> + ); +}; + +export default ContentCard; + +const styles = StyleSheet.create({ + title: { + ...TextTheme.headingFour, + color: ColorPallet.baseColors.black, + textAlign: 'center', + }, + html: { + color: ColorPallet.baseColors.black, + }, + plainText: { + ...TextTheme.normal, + color: ColorPallet.baseColors.black, + }, + empty: { + ...TextTheme.normal, + color: ColorPallet.baseColors.lightGrey, + } +}); diff --git a/src/screens/EmailDetails/SaveSection.tsx b/src/screens/EmailDetails/SaveSection.tsx new file mode 100644 index 0000000000000000000000000000000000000000..f5fcba99f911699b5c7b3fe56080684778ba0d4f --- /dev/null +++ b/src/screens/EmailDetails/SaveSection.tsx @@ -0,0 +1,48 @@ +import React from 'react'; +import {StyleSheet, Text, View} from 'react-native'; +import {ColorPallet, TextTheme} from 'src/theme/theme'; +import Card from 'src/components/EmailCard'; +import Button, {ButtonType} from "../../components/Button"; + +interface Props { + configInvalid: boolean; + onSettingsPress: () => void; +} + +const SaveSection = ({ configInvalid, onSettingsPress }: Props) => { + if (!configInvalid) return null; + return ( + <Card background="white"> + <Text style={styles.warn}> + IMAP Configuration Missing! + </Text> + <Text style={styles.text}> + In order to save your messages securely, you need to set up your IMAP configuration correctly. Currently, the provided IMAP settings are not valid. Please review and update the IMAP configuration in the settings to ensure your messages are saved and accessible. + </Text> + <View> + <Button + buttonType={ButtonType.Primary} + title="Configure IMAP Settings" + buttonStyle={styles.goToImapButton} + onPress={onSettingsPress} + /> + </View> + </Card> + ); +}; + +export default SaveSection; + +const styles = StyleSheet.create({ + warn: { + ...TextTheme.normal, + color: ColorPallet.baseColors.red, + marginBottom: 6 + }, + text: { + ...TextTheme.normal, + }, + goToImapButton: { + marginTop: 16 + } +}); diff --git a/src/screens/EmailDetails/SentBy.tsx b/src/screens/EmailDetails/SentBy.tsx new file mode 100644 index 0000000000000000000000000000000000000000..b44148048b99dc78bc88235decc61c1919d5725c --- /dev/null +++ b/src/screens/EmailDetails/SentBy.tsx @@ -0,0 +1,50 @@ +import React from 'react'; +import { format } from 'date-fns'; +import { StyleSheet, Text } from 'react-native'; +import { ColorPallet, TextTheme } from 'src/theme/theme'; +import Card from 'src/components/EmailCard'; +import { DATE_TIME_FORMAT } from "src/constants/constants"; +import {parseAddress} from "src/utils/email"; + +interface Props { + from: string; + createdAt: Date; +} + +const SentBy = ({ from, createdAt }: Props) => { + const sender = parseAddress(from); + + return ( + <Card background="brand"> + <Text style={styles.sentBy}>Sent by</Text> + {sender?.name && <Text style={styles.senderName}>{sender?.name}</Text>} + {sender?.email && <Text style={styles.senderEmail}> + {sender?.name ? `(${sender?.email})` : sender?.email} + </Text>} + <Text style={styles.time}>{format(createdAt, DATE_TIME_FORMAT)}</Text> + </Card> + ); +}; + +export default SentBy; + +const styles = StyleSheet.create({ + sentBy: { + ...TextTheme.normal, + color: ColorPallet.baseColors.white, + }, + senderName: { + ...TextTheme.headingFour, + marginTop: 4, + color: ColorPallet.baseColors.white, + }, + senderEmail: { + ...TextTheme.normal, + color: ColorPallet.baseColors.white, + }, + time: { + ...TextTheme.normal, + color: ColorPallet.baseColors.white, + marginTop: 8, + }, +}); diff --git a/src/screens/EmailDetails/Subject.tsx b/src/screens/EmailDetails/Subject.tsx new file mode 100644 index 0000000000000000000000000000000000000000..aed4724ae62b46864a1196274559d0c809e1b041 --- /dev/null +++ b/src/screens/EmailDetails/Subject.tsx @@ -0,0 +1,83 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { StyleSheet, Text, View } from 'react-native'; +import EmailSvg from 'src/assets/svg/e-mail.svg'; +import { ColorPallet, TextTheme } from 'src/theme/theme'; +import Card from 'src/components/EmailCard'; +import {parseEmailAddresses} from "../../utils/email"; + +interface Props { + subject: string; + to: string; + cc: string; + bcc: string; +} + +const Subject = ({ subject, to, cc, bcc }: Props) => { + const { t } = useTranslation(); + + const toList = parseEmailAddresses(to); + const ccList = parseEmailAddresses(cc); + const bccList = parseEmailAddresses(bcc); + + const all = [...toList, ...ccList, ...bccList]; + + return ( + <Card background="white" SvgIcon={EmailSvg}> + <View style={styles.container}> + {subject && ( + <Text style={styles.subject}>{subject || t<string>('Seal.Details.NoSubject')}</Text> + )} + <Text style={styles.recipientLabel}> + {all.length ? t<string>('Seal.Details.Recipients') : t<string>('Seal.Details.NoRecipients')} + </Text> + + {toList.map((recipient) => ( + <Text + key={recipient.email} + style={styles.recipientName}> + to: {recipient.name} {recipient.email} + </Text> + ))} + {ccList.map((recipient) => ( + <Text + key={recipient.email} + style={styles.recipientName}> + cc: {recipient.name} {recipient.email} + </Text> + ))} + {bccList.map((recipient) => ( + <Text + key={recipient.email} + style={styles.recipientName}> + bcc: {recipient.name} {recipient.email} + </Text> + ))} + </View> + </Card> + ); +}; + +export default Subject; + +const styles = StyleSheet.create({ + container: { + alignItems: 'center', + justifyContent: 'center', + }, + subject: { + ...TextTheme.headingFour, + marginTop: 4, + color: ColorPallet.brand.primary, + textAlign: 'center', + }, + recipientLabel: { + ...TextTheme.headingFour, + marginTop: 24, + color: ColorPallet.baseColors.black, + }, + recipientName: { + ...TextTheme.normal, + marginTop: 8, + }, +}); diff --git a/src/screens/EmailDetails/index.tsx b/src/screens/EmailDetails/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..e38ac0ccd40934429c0bf0336f2278a7ba62c5c2 --- /dev/null +++ b/src/screens/EmailDetails/index.tsx @@ -0,0 +1,128 @@ +import React, { useEffect, useState } from 'react'; +import { StackScreenProps } from '@react-navigation/stack'; +import { + StyleSheet, + View, + StatusBar, + ScrollView, + NativeModules, +} from 'react-native'; +import {observer} from "mobx-react"; +import {EmailStackParams, Screens, Stacks} from 'src/type/navigators'; +import MimeParser from "@vereign/lib-mime"; +import {getImapConfig} from "src/utils/keychain"; +import {warningToast} from "src/utils/toast"; +import { useObject, useRealm } from '@realm/react'; +import {useNavigation} from "@react-navigation/native"; +import Email from 'src/db-models/Email'; +import SentBy from './SentBy'; +import Subject from './Subject'; +import ContentCard from './ContentCard'; +import SaveSection from "./SaveSection"; + +type EmailDetailsProps = StackScreenProps< + EmailStackParams, + Screens.EmailDetails +>; + +const EmailDetails: React.FC<EmailDetailsProps> = observer(({ + route, +}) => { + const realm = useRealm(); + const realmId = route.params.realmId; + const objectId = new Realm.BSON.ObjectId(realmId); + const email = useObject(Email, objectId); + const navigation = useNavigation(); + + if (email === null) { + warningToast("Email not found"); + navigation.navigate(Screens.ReceivedEmails); + return null; + } + + const [configValid, setConfigValid] = useState(true); + const [html, setHtml] = useState(''); + const [plainText, setPlainText] = useState(''); + + const checkConfig = async () => { + const config = await getImapConfig(); + if (!config || !config.verified) { + setConfigValid(false); + return; + } + } + const parseMime = async () => { + try { + let parser = new MimeParser(email.svdxMime); + + const html = await parser.getHTML({ populateAttachments: true, hashAttachment: null }); + setHtml(html); + + const plainText = await parser.getPlain(); + setPlainText(plainText); + } catch (e: any) { + warningToast(e.message); + console.error(e); + } + } + + useEffect(() => { + if (email && !email.read) { + realm.write(() => { + email.read = true; + }); + } + checkConfig(); + parseMime(); + }, [realmId]); + + return ( + <View style={styles.container}> + <StatusBar barStyle="light-content" /> + + <ScrollView> + <View style={styles.content}> + <SaveSection + configInvalid={!configValid} + onSettingsPress={() => { + navigation.getParent().navigate(Stacks.SettingsStack, { + screen: Screens.ImapConfiguration + }); + }} + /> + + <SentBy + from={email.from} + createdAt={email.createdAt} + /> + <Subject + subject={email.subject} + to={email.to} + cc={email.cc} + bcc={email.bcc} + /> + <ContentCard + html={html} + plainText={plainText} + /> + </View> + + </ScrollView> + </View> + ); +}); + +export default EmailDetails; + +const styles = StyleSheet.create({ + container: { + flex: 1, + paddingLeft: 10, + paddingRight: 10, + paddingTop: 12, + paddingBottom: 10 + }, + content: { + paddingBottom: 20 + } +}); \ No newline at end of file diff --git a/src/screens/ImapConfiguration/index.tsx b/src/screens/ImapConfiguration/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..725159a430f6acafaa5e385244e2c48d5c0dd0a9 --- /dev/null +++ b/src/screens/ImapConfiguration/index.tsx @@ -0,0 +1,168 @@ +import React, {useEffect, useState} from 'react'; +import { + NativeModules, + StatusBar, + StyleSheet, + Keyboard, + ScrollView, + SafeAreaView +} from "react-native"; +import TextInput from "src/components/TextInput"; +import Button, {ButtonType} from "src/components/Button"; +import {getImapConfig, ImapConfiguration as ImapConfigurationInterface, setImapConfig} from "src/utils/keychain"; +import {successToast, warningToast} from "src/utils/toast"; +import {ColorPallet} from "src/theme/theme"; +import useKeyboard from "../../utils/keyboard"; + +const {VereignImapModule} = NativeModules; + +const ImapConfiguration = () => { + const [loading, setLoading] = useState(false); + const { keyboardHeight, isKeyBoardOpen } = useKeyboard(); + const [imapValues, setImapValues] = useState({ + enableSsl: true, + host: '', + username: '', + password: '', + port: '993' + }); + const loadConfig = async () => { + const config = await getImapConfig(); + if (config) { + setImapValues(config); + } + }; + useEffect(() => { + loadConfig(); + }, []); + + const saveConfig = async () => { + Keyboard.dismiss(); + setLoading(true); + try { + await setImapConfig({ + verified: false, + enableSsl: true, + host: imapValues.host, + username: imapValues.username, + password: imapValues.password, + port: Number(imapValues.port) + }); + const config = await getImapConfig() as ImapConfigurationInterface; + + VereignImapModule.checkConfiguration(config.host, config.username, config.password, (success: boolean, error: any) => { + setLoading(false); + if (success) { + setImapConfig({ + ...config, + verified: true + }); + successToast("Imap config is valid"); + } + if (error) { + warningToast("Imap config is invalid " + error); + } + }); + } catch (e: any) { + setLoading(false); + warningToast(e.message); + } + } + + return ( + <SafeAreaView + style={[ + styles.scroll, + { + paddingBottom: isKeyBoardOpen ? keyboardHeight : 0, + } + ]} + > + <ScrollView contentContainerStyle={styles.container}> + <StatusBar barStyle="light-content" /> + + <TextInput + label="host" + placeholder="host" + accessible + accessibilityLabel="host" + labelBold + labelCenter + autoFocus + value={imapValues.host} + onChangeText={(value) => setImapValues({ + ...imapValues, + host: value + })} + returnKeyType="done" + /> + <TextInput + label="username" + placeholder="username" + accessible + accessibilityLabel="username" + labelBold + labelCenter + value={imapValues.username} + onChangeText={(value) => setImapValues({ + ...imapValues, + username: value + })} + returnKeyType="done" + /> + <TextInput + label="password" + placeholder="password" + accessible + accessibilityLabel="password" + labelBold + labelCenter + secureTextEntry + value={imapValues.password} + onChangeText={(value) => setImapValues({ + ...imapValues, + password: value + })} + returnKeyType="done" + /> + <TextInput + label="port" + placeholder="port" + accessible + accessibilityLabel="port" + labelBold + labelCenter + value={imapValues.port} + onChangeText={(value) => setImapValues({ + ...imapValues, + port: value + })} + returnKeyType="done" + /> + + <Button + title="Save" + disabled={loading} + buttonType={ButtonType.Primary} + onPress={() => saveConfig()} + /> + </ScrollView> + </SafeAreaView> + ); +}; + +export default ImapConfiguration; + +const styles = StyleSheet.create({ + scroll: { + flex: 1 + }, + container: { + backgroundColor: ColorPallet.grayscale.white, + margin: 20, + paddingBottom: 80 + }, + button: { + marginTop: 16, + }, +}); diff --git a/src/screens/ListCredentials/ListCredentialsStore.ts b/src/screens/ListCredentials/ListCredentialsStore.ts index f0f1ce79d9a5a922faa05da516997a3e28a5c1cf..148cfef009fa71ec09a4d73b3fe686d19c33f8aa 100644 --- a/src/screens/ListCredentials/ListCredentialsStore.ts +++ b/src/screens/ListCredentials/ListCredentialsStore.ts @@ -1,10 +1,10 @@ import {action, makeAutoObservable, runInAction} from "mobx"; -import rootStore from "src/store/rootStore"; import {CredentialState} from "@aries-framework/core"; import { CredentialExchangeRecord } from "@aries-framework/core/build/modules/credentials/repository/CredentialExchangeRecord"; -import {parsedSchema} from "../../utils/helpers"; +import rootStore from "src/store/rootStore"; +import {parsedSchema} from "src/utils/helpers"; class ListCredentialsStore { diff --git a/src/screens/ListCredentials/index.tsx b/src/screens/ListCredentials/index.tsx index 70c95551749426cea7ae37828e3b43873527269f..fceea3195fc92e164f520c90dbe0ffeda8ae1517 100644 --- a/src/screens/ListCredentials/index.tsx +++ b/src/screens/ListCredentials/index.tsx @@ -10,7 +10,7 @@ import {StackNavigationProp} from "@react-navigation/stack"; import CredentialCard from 'src/components/CredentialCard'; import {CredentialStackParams, Screens} from "src/type/navigators"; import NoRecordsAvailable from "src/components/NoRecordsAvailable"; -import PageTitle from "../../components/PageTitle"; +import PageTitle from "src/components/PageTitle"; const ListCredentials: React.FC = observer(() => { const navigation = useNavigation<StackNavigationProp<CredentialStackParams>>(); diff --git a/src/screens/Notifications/index.tsx b/src/screens/Notifications/index.tsx index b6d0f14e138359e19c1ba70f80b3badac5ad8f78..2de3357c685f9284b94f9bc446975ccd457e8ec4 100644 --- a/src/screens/Notifications/index.tsx +++ b/src/screens/Notifications/index.tsx @@ -2,54 +2,109 @@ import React from 'react'; import {FlatList, StatusBar, StyleSheet, View} from 'react-native'; import {useNavigation} from "@react-navigation/core"; import {useTranslation} from "react-i18next"; -import NotificationListItem from 'src/components/NotificationListItem'; +import NotificationListItem from 'src/components/notifications/NotificationListItem'; +import NotificationEmailListItem from 'src/components/notifications/NotificationEmailListItem'; import {observer} from "mobx-react"; -import {Screens} from "src/type/navigators"; -import useNotifications from "src/hooks/notifications"; +import {Screens, TabStacks} from "src/type/navigators"; +import {useAgentNotifications, useEmailNotifications} from "src/hooks/notifications"; import PageTitle from "src/components/PageTitle"; import NoRecordsAvailable from "src/components/NoRecordsAvailable"; -import {ColorPallet} from "../../theme/theme"; +import {borderRadius, ColorPallet} from "src/theme/theme"; +import {AgentNotification} from "../../utils/agentUtils"; +import Email from "src/db-models/Email"; + +interface CombinedItem { + key: string; + agentNotification: AgentNotification | null; + emailNotification: Email | null; +} const Notifications = observer(() => { const { t } = useTranslation(); const navigation = useNavigation(); - const notifications = useNotifications(); + const agentNotification = useAgentNotifications(); + const emailNotifications = useEmailNotifications(); + + const combinedNotifications = [ + ...agentNotification.map(p => ({ + key: p.key, + agentNotification: p, + emailNotification: null + })), + ...emailNotifications.map((p: Email) => ({ + key: p._id.toString(), + agentNotification: null, + emailNotification: p + })) + ]; return ( <View style={styles.container}> <StatusBar barStyle="light-content" /> - {!!notifications.length && ( + {!!combinedNotifications.length && ( <PageTitle> {t<string>('Notifications.Title', { - count: notifications.length + count: combinedNotifications.length })} </PageTitle> )} - {!notifications.length && ( + {!combinedNotifications.length && ( <NoRecordsAvailable text={t<string>('Notifications.NoNewUpdates')} /> )} - {!!notifications.length && ( + {!!combinedNotifications.length && ( <FlatList - data={notifications} + data={combinedNotifications} keyExtractor={item => item.key} - renderItem={({ item, index }) => ( + style={styles.list} + renderItem={({ item, index }: { item: CombinedItem, index: number }) => ( <View key={index} style={{ + marginHorizontal: 10, marginTop: 15, - marginBottom: index === notifications.length - 1 ? 15 : 0, + marginBottom: index === combinedNotifications.length - 1 ? 15 : 0, }} > - <NotificationListItem - notification={item} - onView={() => { - if (item.credentialOffer) { - navigation.navigate(Screens.CredentialOffer, { credentialId: item.credentialOffer.id }); - } else if (item.proofRequest) { - navigation.navigate(Screens.ProofRequest, { proofId: item.proofRequest.id }); - } - }} - /> + {item.agentNotification && ( + <NotificationListItem + notification={item.agentNotification} + onView={() => { + if (item.agentNotification.credentialOffer) { + navigation.navigate(Screens.CredentialOffer, { credentialId: item.agentNotification.credentialOffer.id }); + } else if (item.agentNotification.proofRequest) { + navigation.navigate(Screens.ProofRequest, { proofId: item.agentNotification.proofRequest.id }); + } + }} + /> + )} + {item.emailNotification && ( + <NotificationEmailListItem + id={item.emailNotification._id.toString()} + createdAt={item.emailNotification.createdAt} + from={item.emailNotification.from} + to={item.emailNotification.to} + cc={item.emailNotification.cc} + bcc={item.emailNotification.bcc} + subject={item.emailNotification.subject} + read={item.emailNotification.read} + sealed={item.emailNotification.type === "sealed"} + sealUrl={item.emailNotification.sealUrl} + onPress={() => { + const realmId = item.emailNotification!._id.toString(); + if (item.emailNotification!.type === "sealed") { + navigation.getParent().navigate(TabStacks.EmailStack, { + screen: Screens.SealDetailsInfo, + params: { realmId: realmId }, + }); + } else { + navigation.getParent().navigate(TabStacks.EmailStack, { + screen: Screens.EmailDetails, + params: { realmId: realmId }, + }); + } + }} + /> + )} </View> )} /> @@ -78,4 +133,10 @@ const styles = StyleSheet.create({ marginTop: offset, marginBottom: 20, }, + list: { + marginTop: 26, + backgroundColor: ColorPallet.grayscale.white, + borderRadius: borderRadius, + flex: 1, + } }); diff --git a/src/screens/PinEnter/index.tsx b/src/screens/PinEnter/index.tsx index 867f2154cd683cde39251dcd1e610bd40a54a385..a7218c9c32083ff14b889a5aa33f1769ea70546f 100644 --- a/src/screens/PinEnter/index.tsx +++ b/src/screens/PinEnter/index.tsx @@ -22,7 +22,7 @@ import {getPasscode} from "src/utils/keychain"; import { lockAccount, getLockDate } from "src/utils/onboarding"; import rootStore from "src/store/rootStore"; import {format, isAfter} from "date-fns"; -import {DATE_TIME_FORMAT} from "../../constants/constants"; +import {DATE_TIME_FORMAT} from "src/constants/constants"; type PinEnterProps = StackScreenProps<OnboardingStackParams, Screens.EnterPin>; diff --git a/src/screens/ProofRequest/ProofRequestStore.ts b/src/screens/ProofRequest/ProofRequestStore.ts index f072548a4eda0c3516a338978b9fabe95b100380..8e6c6de258d22223b46373ad16ec1bee240387fd 100644 --- a/src/screens/ProofRequest/ProofRequestStore.ts +++ b/src/screens/ProofRequest/ProofRequestStore.ts @@ -4,7 +4,7 @@ import rootStore from "src/store/rootStore"; import {ConnectionRecord} from "@aries-framework/core/build/modules/connections/repository/ConnectionRecord"; import i18next, {TFunction} from "i18next"; import {Alert} from "react-native"; -import {errorToast} from "../../utils/toast"; +import {errorToast} from "src/utils/toast"; // interface FoundCredentialItem { // "credentialId": "4ef5adec-780a-4ae1-ba27-f75c79e21b8b", diff --git a/src/screens/ProofRequest/index.tsx b/src/screens/ProofRequest/index.tsx index 55aaea54104a590f8c840f171249c46b03129d91..83a85c3467fbf4b9b4cd166956e9bff871f0ac06 100644 --- a/src/screens/ProofRequest/index.tsx +++ b/src/screens/ProofRequest/index.tsx @@ -4,15 +4,15 @@ import {View, StyleSheet, StatusBar, Text, ScrollView} from 'react-native'; import { ColorPallet, TextTheme } from 'src/theme/theme'; import { NotificationStackParams, Screens } from 'src/type/navigators'; import {observer} from "mobx-react"; -import FlowDetailModal from "../../components/FlowDetailModal"; -import ProofRequestStore from "./ProofRequestStore"; import {Trans, useTranslation} from "react-i18next"; import {useNavigation} from "@react-navigation/core"; import {StackNavigationProp} from "@react-navigation/stack"; +import FlowDetailModal from "src/components/FlowDetailModal"; +import ProofRequestStore from "./ProofRequestStore"; import ProofDeclined from "./ProofDeclined"; import ProofPending from "./ProofPending"; import { errorToast } from 'src/utils/toast'; -import Button, {ButtonType} from "../../components/Button"; +import Button, {ButtonType} from "src/components/Button"; import ProofRequestAttributes from "."; import {ItemType} from "react-native-dropdown-picker"; import {useProofById} from "@aries-framework/react-hooks"; diff --git a/src/screens/ReceivedEmailList/index.tsx b/src/screens/ReceivedEmailList/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..725e15a6a5bc383f74d1f20b64f7eb14a3890c87 --- /dev/null +++ b/src/screens/ReceivedEmailList/index.tsx @@ -0,0 +1,94 @@ +import React, { useState } from 'react'; +import {FlatList, StatusBar, StyleSheet, View} from 'react-native'; +import {useQuery} from '@realm/react'; +import {borderRadius, ColorPallet} from 'src/theme/theme'; +import SearchBar from 'src/components/SearchBar'; +import NoRecordsAvailable from 'src/components/NoRecordsAvailable'; +import Email from 'src/db-models/Email'; +import EmailListItem from 'src/components/EmailListItem'; +import {useNavigation} from "@react-navigation/core"; +import {StackNavigationProp} from "@react-navigation/stack"; +import {EmailStackParams, Screens, TabStacks} from "../../type/navigators"; + +interface ReceivedEmailListProps { + navigation: any; + route: any; +} + +const ReceivedEmailList: React.FC<ReceivedEmailListProps> = () => { + const navigation = useNavigation<StackNavigationProp<EmailStackParams>>(); + const [searchPhrase, setSearchPhrase] = useState(''); + const emailQuery = useQuery(Email); + + let emailList = emailQuery.sorted('createdAt', true); + if (searchPhrase && searchPhrase.trim()) { + const queryText = searchPhrase.trim(); + emailList = emailList.filtered(`subject CONTAINS[c] $0 OR from CONTAINS[c] $1`, queryText, queryText) + } + return ( + <View style={styles.container}> + <StatusBar barStyle="light-content" /> + <SearchBar + searchPhrase={searchPhrase} + setSearchPhrase={searchPhrase => setSearchPhrase(searchPhrase)} + /> + {!emailList.length && <NoRecordsAvailable />} + {!!emailList.length && ( + <FlatList + data={emailList} + keyExtractor={(item: any) => item._id} + style={styles.list} + renderItem={({ item, index }) => ( + <> + <View + style={{ + marginHorizontal: 10, + marginTop: 15, + marginBottom: index === emailList.length - 1 ? 15 : 0, + }} + key={index.toString()} + > + <EmailListItem + id={item._id.toString()} + createdAt={item.createdAt} + from={item.from} + to={item.to} + cc={item.cc} + bcc={item.bcc} + subject={item.subject} + read={item.read} + sealed={item.type === "sealed"} + sealUrl={item.sealUrl} + onPress={() => { + if (item.type === "sealed") { + navigation.navigate(Screens.SealDetailsInfo, { realmId: item._id.toString() }) + } else { + navigation.navigate(Screens.EmailDetails, { realmId: item._id.toString() }) + } + }} + /> + </View> + </> + )} + /> + )} + </View> + ); +}; + +export default ReceivedEmailList; + +const styles = StyleSheet.create({ + container: { + backgroundColor: ColorPallet.grayscale.white, + margin: 20, + flex: 1, + }, + list: { + marginTop: 26, + backgroundColor: ColorPallet.grayscale.veryLightGrey, + borderRadius: borderRadius, + flex: 1, + } +}); + diff --git a/src/screens/SealDetailsInfo/Information.tsx b/src/screens/SealDetailsInfo/Information.tsx index 6d788ed282c3810949804dda35e54f590d4e29f6..c3fd0c9a45144d05bd44d99fd90bfe574d15ff88 100644 --- a/src/screens/SealDetailsInfo/Information.tsx +++ b/src/screens/SealDetailsInfo/Information.tsx @@ -13,13 +13,20 @@ import BlockchainInfo from './details/BlockchainInfo'; import IPFSInfo from './details/IPFSInfo'; import VerificationSteps from './details/VerificationSteps'; import StatusCard from './details/StatusCard'; +import {useRealm} from "@realm/react"; interface InformationProps { config: Config; - sealUrl: string; + sealUrl: string | null | undefined; + realmId: Realm.BSON.ObjectId | null | undefined; } -const Information: React.FC<InformationProps> = ({ config, sealUrl }) => { +const Information: React.FC<InformationProps> = ({ + config, + sealUrl, + realmId +}) => { + const realm = useRealm(); const { senderVerificationDetails, senderStatusData, @@ -31,7 +38,7 @@ const Information: React.FC<InformationProps> = ({ config, sealUrl }) => { sentTime, sealTime, numReceiversVerified, - } = useInformation(config, sealUrl); + } = useInformation(realm, config, sealUrl, realmId); return ( <View style={styles.container}> diff --git a/src/screens/SealDetailsInfo/details/BlockchainInfo.tsx b/src/screens/SealDetailsInfo/details/BlockchainInfo.tsx index 9f6fdc46e987795061d258ccbc724e639ae93dd3..4e06ee7616277fef9825654bed39f317091f6c9d 100644 --- a/src/screens/SealDetailsInfo/details/BlockchainInfo.tsx +++ b/src/screens/SealDetailsInfo/details/BlockchainInfo.tsx @@ -4,7 +4,7 @@ import { formatDistance } from 'date-fns'; import { VerificationData, StatusData } from '@vereign/light-utils/dist/types'; import { StyleSheet, Text } from 'react-native'; import { ColorPallet, TextTheme } from 'src/theme/theme'; -import Card from '../Card'; +import Card from 'src/components/EmailCard'; import DataPair from './DataPair'; interface Props { diff --git a/src/screens/SealDetailsInfo/details/IPFSInfo.tsx b/src/screens/SealDetailsInfo/details/IPFSInfo.tsx index 0160f013c6e0888c9adcdd719202f61409608cb9..d129ec911a5002e4f851627b68f91c7e1fb94a9c 100644 --- a/src/screens/SealDetailsInfo/details/IPFSInfo.tsx +++ b/src/screens/SealDetailsInfo/details/IPFSInfo.tsx @@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next'; import { StyleSheet, Text } from 'react-native'; import { truncateString } from 'src/utils/text'; import { ColorPallet, TextTheme } from 'src/theme/theme'; -import Card from '../Card'; +import Card from 'src/components/EmailCard'; import DataPair from './DataPair'; interface Props { diff --git a/src/screens/SealDetailsInfo/details/StatusCard.tsx b/src/screens/SealDetailsInfo/details/StatusCard.tsx index dcf7600d08a1ba439aa1654e4909a179bc002e01..b51c336ff15e6a69cf7b9cef75307792ee3f62b4 100644 --- a/src/screens/SealDetailsInfo/details/StatusCard.tsx +++ b/src/screens/SealDetailsInfo/details/StatusCard.tsx @@ -12,7 +12,7 @@ import { STATE_VERIFYING_SENDER, } from 'src/seal/hooks/useVerificationFlow'; import { ColorPallet, TextTheme } from 'src/theme/theme'; -import Card from '../Card'; +import Card from 'src/components/EmailCard'; interface Props { verificationState: number; diff --git a/src/screens/SealDetailsInfo/details/VerificationSteps.tsx b/src/screens/SealDetailsInfo/details/VerificationSteps.tsx index e64711b1cf9e1411ac29c7d75d1264d2e5f8c287..9e187bb9f2f545d4476f459fc8875c851340c15f 100644 --- a/src/screens/SealDetailsInfo/details/VerificationSteps.tsx +++ b/src/screens/SealDetailsInfo/details/VerificationSteps.tsx @@ -15,7 +15,7 @@ import { STATE_VERIFYING_SENDER, } from 'src/seal/hooks/useVerificationFlow'; import VerificationStepCard from './VerificationStepCard'; -import Card from '../Card'; +import Card from 'src/components/EmailCard'; import { STATUS_COMPLETED, STATUS_ERROR, diff --git a/src/screens/SealDetailsInfo/emailVerification/AttachmentsCard.tsx b/src/screens/SealDetailsInfo/emailVerification/AttachmentsCard.tsx index b00a23d0dc9ad1ddb51ac3d9349ad2d84a37da8a..e83ae4116d3f6a8d6339d544a1634b045517ca26 100644 --- a/src/screens/SealDetailsInfo/emailVerification/AttachmentsCard.tsx +++ b/src/screens/SealDetailsInfo/emailVerification/AttachmentsCard.tsx @@ -9,7 +9,7 @@ import AttachmentsSvg from 'src/assets/svg/attachments.svg'; import DownloadSvg from 'src/assets/svg/download.svg'; import HashSvg from 'src/assets/svg/hash.svg'; import Button, { ButtonType } from 'src/components/Button'; -import Card from '../Card'; +import Card from 'src/components/EmailCard'; interface Props { config: Config; diff --git a/src/screens/SealDetailsInfo/emailVerification/IPFSCard.tsx b/src/screens/SealDetailsInfo/emailVerification/IPFSCard.tsx index 4732ad0024a1a00ad93de99188493aad93cf43e6..e8e105f26208f682254a933677d4e443638f0e65 100644 --- a/src/screens/SealDetailsInfo/emailVerification/IPFSCard.tsx +++ b/src/screens/SealDetailsInfo/emailVerification/IPFSCard.tsx @@ -7,7 +7,7 @@ import useIpfs from 'src/seal/hooks/useIpfs'; import { ColorPallet, TextTheme } from 'src/theme/theme'; import Config from 'src/seal/config'; import ContentSvg from 'src/assets/svg/content.svg'; -import Card from '../Card'; +import Card from 'src/components/EmailCard'; interface Props { config: Config; diff --git a/src/screens/SealDetailsInfo/emailVerification/ProgressCard.tsx b/src/screens/SealDetailsInfo/emailVerification/ProgressCard.tsx index 21fb43ce15bf4f8676b3618fa6c984d5f70ed5e0..144f60c3c661971b39faeea5087387b1dd08caf7 100644 --- a/src/screens/SealDetailsInfo/emailVerification/ProgressCard.tsx +++ b/src/screens/SealDetailsInfo/emailVerification/ProgressCard.tsx @@ -8,7 +8,7 @@ import { STATE_UNVERIFIED, } from 'src/seal/hooks/useVerificationFlow'; import { ColorPallet, TextTheme } from 'src/theme/theme'; -import Card from '../Card'; +import Card from 'src/components/EmailCard'; interface Props { verificationState: number; diff --git a/src/screens/SealDetailsInfo/emailVerification/SealedBy.tsx b/src/screens/SealDetailsInfo/emailVerification/SealedBy.tsx index 141dd6bc55672688b981ad7a133355b6616587dd..eea0f6f8ce35047564a146bb310ac8c71a5efa4d 100644 --- a/src/screens/SealDetailsInfo/emailVerification/SealedBy.tsx +++ b/src/screens/SealDetailsInfo/emailVerification/SealedBy.tsx @@ -5,7 +5,7 @@ import { MessageData } from '@vereign/light-utils/dist/types'; import { StyleSheet, Text } from 'react-native'; import { STATE_LOADING_STATUS_DATA } from 'src/seal/hooks/useVerificationFlow'; import { ColorPallet, TextTheme } from 'src/theme/theme'; -import Card from '../Card'; +import Card from 'src/components/EmailCard'; import { DATE_TIME_FORMAT } from "src/constants/constants"; interface Props { diff --git a/src/screens/SealDetailsInfo/emailVerification/Subject.tsx b/src/screens/SealDetailsInfo/emailVerification/Subject.tsx index 2ff6aeedba05cabd0e82711fa4bccf3e281c917b..91def3eeead1d69ac12d9f30d01414f26ef6ca13 100644 --- a/src/screens/SealDetailsInfo/emailVerification/Subject.tsx +++ b/src/screens/SealDetailsInfo/emailVerification/Subject.tsx @@ -7,7 +7,7 @@ import EmailSvg from 'src/assets/svg/e-mail.svg'; import { STATE_LOADING_STATUS_DATA } from 'src/seal//hooks/useVerificationFlow'; import { ColorPallet, TextTheme } from 'src/theme/theme'; import { DATE_TIME_FORMAT } from "src/constants/constants"; -import Card from '../Card'; +import Card from 'src/components/EmailCard'; interface Props { verificationState: number; diff --git a/src/screens/SealDetailsInfo/index.tsx b/src/screens/SealDetailsInfo/index.tsx index c58b92f33f0f85d6509cdb6e6b225909c093ab5f..57213ca42a521fdedebff2cc2796c26ea2cf2655 100644 --- a/src/screens/SealDetailsInfo/index.tsx +++ b/src/screens/SealDetailsInfo/index.tsx @@ -4,28 +4,37 @@ import { ColorPallet } from 'src/theme/theme'; import Config from 'src/seal/config'; import Information from './Information'; import LoaderView from './LoaderView'; +import {useQuery} from "@realm/react"; +import Email from "../../db-models/Email"; interface SealDetailsInfoPropsProps { route: any; } const SealDetailsInfo: React.FC<SealDetailsInfoPropsProps> = ({ route }) => { - const { sealUrl } = route.params; + const { sealUrl, realmId } = route.params; const [config, setConfig] = useState<Config | null>(null); + let emailQuery = useQuery(Email); + const objectId = realmId && new Realm.BSON.ObjectId(realmId) || null; + if (realmId) { + emailQuery = emailQuery.filtered("_id == $0", objectId); + } useEffect(() => { + const email = emailQuery[0]; + (async () => { setConfig(null); - const config = await Config.initialize(sealUrl); + const config = await Config.initialize(sealUrl || email?.sealUrl); setConfig(config); })(); - }, [sealUrl]); + }, [sealUrl, realmId]); return ( <View style={styles.container}> <StatusBar barStyle="light-content" /> {!config && <LoaderView />} - {!!config && <Information config={config} sealUrl={sealUrl} />} + {!!config && <Information config={config} sealUrl={sealUrl} realmId={objectId} />} </View> ); }; diff --git a/src/screens/SealDetailsInfo/useInformation.ts b/src/screens/SealDetailsInfo/useInformation.ts index 7c68b9b90c906a6aede86d3145073e486c32b1d3..a528dd30e7679b4e0825a4cefcc538d790cd9e7e 100644 --- a/src/screens/SealDetailsInfo/useInformation.ts +++ b/src/screens/SealDetailsInfo/useInformation.ts @@ -1,6 +1,7 @@ import React, { useEffect, useState } from 'react'; import { MessageData, + Participant, SenderStatusObject, StatusData, VerificationData, @@ -22,7 +23,9 @@ import useQrCodeData, { TAIL_PENDING_ERROR_MESSAGE, } from 'src/seal/hooks/useQrCodeData'; import useStatuses from 'src/seal/hooks/useStatuses'; -import useSealQrCodes from 'src/seal/hooks/useSealQrCodes'; +import {useQuery} from "@realm/react"; +import Email from "../../db-models/Email"; +import Realm from "realm"; interface ExtractedData { senderVerificationDetails?: VerificationData; @@ -36,8 +39,27 @@ interface ExtractedData { sealTime: number; numReceiversVerified: number; } -const useInformation = (config: Config, url: string): ExtractedData => { - const { addSealedQrCode, updateSealedQrCodeSubject } = useSealQrCodes(); + +function formatEmailAddress(participant: Participant): string { + return `"${participant.name}" <${participant.email}>`; +} + +const useInformation = ( + realm: Realm, + config: Config, + initialUrl: string | null | undefined, + realmId: Realm.BSON.ObjectId | null | undefined +): ExtractedData => { + let emailQuery = useQuery(Email); + if (realmId) { + emailQuery = emailQuery.filtered("_id == $0", realmId); + } else if (initialUrl) { + emailQuery = emailQuery.filtered("sealUrl == $0", initialUrl); + } else { + throw new Error("Either realmId or url must be defined"); + } + const url = initialUrl || emailQuery[0]?.sealUrl as string; + const [error, setError] = useState<Error>(); const [verificationState, setVerificationState] = useState<number>( STATE_LOADING_STATUS_DATA, @@ -50,15 +72,36 @@ const useInformation = (config: Config, url: string): ExtractedData => { } = useQrCodeData(config, url); useEffect(() => { - addSealedQrCode(url); if (qrCodeData?.subject) { - updateSealedQrCodeSubject(url, { - subject: qrCodeData.subject, - senderEmail: qrCodeData.sender?.email, - senderName: qrCodeData.sender?.name, - }); + if (emailQuery.length === 0) { + const realmRecordId = new Realm.BSON.ObjectId(); + realm.write(() => { + const newEmail: Partial<Email> = { + _id: realmRecordId, + messageId: undefined, + createdAt: new Date(qrCodeData.date), + receivedDate: new Date(qrCodeData.date), + + type: 'sealed', + + from: formatEmailAddress(qrCodeData.sender), + to: qrCodeData.recipients.to?.map(formatEmailAddress).join(', '), + cc: qrCodeData.recipients.cc?.map(formatEmailAddress).join(', '), + bcc: "", + subject: qrCodeData.subject, + read: true, + + svdxMime: null, + svdxImapSaved: null, + svdxMessageId: null, + + sealUrl: url + } + realm.create('Email', newEmail); + }); + } } - }, [url, addSealedQrCode, updateSealedQrCodeSubject, qrCodeData, qrCodeData?.subject]); + }, [url, realm, qrCodeData, qrCodeData?.subject]); const { statusesData, diff --git a/src/screens/SealScannedQrCodeList/index.tsx b/src/screens/SealScannedQrCodeList/index.tsx deleted file mode 100644 index 0f5c4e0ab1a44619205ca86327c647a0108a9418..0000000000000000000000000000000000000000 --- a/src/screens/SealScannedQrCodeList/index.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import React, { useState } from 'react'; -import {FlatList, StatusBar, StyleSheet, View} from 'react-native'; -import SealListItem from 'src/components/SealListItem'; -import { borderRadius, ColorPallet } from 'src/theme/theme'; -import useSealQrCodes, { SealQrCodeRecord } from 'src/seal/hooks/useSealQrCodes'; -import SearchBar from 'src/components/SearchBar'; -import NoRecordsAvailable from 'src/components/NoRecordsAvailable'; - -interface SealScannedQrCodeListProps { - navigation: any; - route: any; -} - -const SealScannedQrCodeList: React.FC<SealScannedQrCodeListProps> = () => { - const { sealedQrCodes } = useSealQrCodes(); - const [searchPhrase, setSearchPhrase] = useState(''); - - return ( - <View style={styles.container}> - <StatusBar barStyle="light-content" /> - <SearchBar - searchPhrase={searchPhrase} - setSearchPhrase={searchPhrase => setSearchPhrase(searchPhrase)} - /> - {!sealedQrCodes.length && <NoRecordsAvailable />} - {!!sealedQrCodes.length && ( - <FlatList - data={sealedQrCodes} - keyExtractor={(item: SealQrCodeRecord) => item.date.toString()} - style={styles.list} - renderItem={({ item, index }) => ( - <View - style={{ - marginHorizontal: 10, - marginTop: 15, - marginBottom: index === sealedQrCodes.length - 1 ? 15 : 0, - }} - key={index.toString()} - > - <SealListItem key={item.date} data={item} /> - </View> - )} - /> - )} - </View> - ); -}; - -export default SealScannedQrCodeList; - -const styles = StyleSheet.create({ - container: { - margin: 20, - flex: 1, - }, - list: { - marginTop: 26, - backgroundColor: ColorPallet.grayscale.veryLightGrey, - borderRadius: borderRadius, - flex: 1, - }, -}); - diff --git a/src/screens/Settings/index.tsx b/src/screens/Settings/index.tsx index d2564644fed37ceaf4c943b74e0344fbfba1b4a4..b6d3ad5b3ed2564d26c6baa15a00dbcbf5499137 100644 --- a/src/screens/Settings/index.tsx +++ b/src/screens/Settings/index.tsx @@ -9,6 +9,7 @@ import LockIconSvg from 'src/assets/svg/lock_icon.svg'; import LanguageSvg from 'src/assets/svg/language.svg'; import MnemonicSvg from 'src/assets/svg/mnemonic.svg'; import WalletSvg from 'src/assets/svg/wallet.svg'; +import EmailSvg from 'src/assets/svg/e-mail-black.svg'; import PrivacySvg from 'src/assets/svg/privacy.svg'; import LogoutSvg from 'src/assets/svg/logout.svg'; import Loader from 'src/components/Loader'; @@ -83,6 +84,11 @@ const Settings: React.FC = () => { title={t<string>('Settings.LegalAndPrivacy')} onPress={() => navigation.navigate(Screens.LegalAndPrivacy)} /> + <SettingListItem + IconSvg={EmailSvg} + title="Imap Configuration" + onPress={() => navigation.navigate(Screens.ImapConfiguration)} + /> <SettingListItem IconSvg={LogoutSvg} title={t<string>('Settings.Logout')} diff --git a/src/seal/hooks/useSealQrCodes.ts b/src/seal/hooks/useSealQrCodes.ts deleted file mode 100644 index 475ea7cccdec8fb77dfd792bd2c3ebe3180152c3..0000000000000000000000000000000000000000 --- a/src/seal/hooks/useSealQrCodes.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { useEffect, useState } from 'react'; -import { Alert } from 'react-native'; -import RNSecureStorage, { ACCESSIBLE } from 'rn-secure-storage' - -export interface SealQrCodeRecord { - subject?: string; - senderEmail?: string; - senderName?: string; - date: number; - url: string; -} - -interface Notifications { - sealedQrCodes: SealQrCodeRecord[]; - addSealedQrCode: (url: string) => void; - updateSealedQrCodeSubject: (url: string, data: Omit<SealQrCodeRecord, 'date' | 'url'>) => void; -} - -export const SEALED_LIST = 'sealed_list'; - -const useSealQrCodes = (): Notifications => { - const [sealedQrCodes, setSealedQrCodes] = useState<SealQrCodeRecord[]>([]); - const readStorage = async (): Promise<SealQrCodeRecord[]> => { - let data: SealQrCodeRecord[] = []; - try { - const rawData = await RNSecureStorage.get(SEALED_LIST); - if (rawData) { - data = JSON.parse(rawData) as SealQrCodeRecord[]; - } - } catch (e) {} - - if (Array.isArray(data)) { - return data; - } - return []; - }; - useEffect(() => { - (async () => { - const urls = await readStorage(); - setSealedQrCodes(urls); - })(); - }, []); - - const addSealedQrCode = async (url: string) => { - if (sealedQrCodes.some(p => p.url === url)) return; - - const urls: any = []; - let subject; - sealedQrCodes.forEach(p => { - if (p.url !== url) { - urls.push(p); - } else { - subject = p.subject; - } - }); - const newUrls = [ - ...urls, - { - subject, - date: new Date().getTime(), - url, - }, - ]; - try { - const rawData = JSON.stringify(newUrls); - await RNSecureStorage.set(SEALED_LIST, rawData, { accessible: ACCESSIBLE.WHEN_UNLOCKED }); - setSealedQrCodes(newUrls); - } catch (e: any) { - console.error(e); - Alert.alert(e); - } - }; - - const updateSealedQrCodeSubject = async ( - url: string, - data: Omit<SealQrCodeRecord, 'date' | 'url'>, - ) => { - const obj = sealedQrCodes.find(p => p.url === url); - if (!obj) { - return; - } - obj.subject = data.subject; - obj.senderEmail = data.senderEmail; - obj.senderName = data.senderName; - try { - const rawData = JSON.stringify(sealedQrCodes); - await RNSecureStorage.set(SEALED_LIST, rawData, { accessible: ACCESSIBLE.WHEN_UNLOCKED }); - setSealedQrCodes(sealedQrCodes); - } catch (e: any) { - console.error(e); - Alert.alert(e); - } - }; - - return { - sealedQrCodes, - addSealedQrCode, - updateSealedQrCodeSubject, - }; -}; - -export default useSealQrCodes; diff --git a/src/store/AgentStore.ts b/src/store/AgentStore.ts index 525667497e4025d2123a04b9cbdc479d1de8d7a6..1095f4529f67e936e0db252f524406591d4c7786 100644 --- a/src/store/AgentStore.ts +++ b/src/store/AgentStore.ts @@ -3,30 +3,27 @@ import { Agent, AutoAcceptCredential, AutoAcceptProof, + BasicMessageEventTypes, + BasicMessageRole, + BasicMessageStateChangedEvent, ConnectionsModule, ConsoleLogger, CredentialsModule, DidsModule, HttpOutboundTransport, InitConfig, - Key, KeyDerivationMethod, KeyDidRegistrar, KeyDidResolver, - KeyType, LogLevel, MediationRecipientModule, - MediatorPickupStrategy, PeerDidRegistrar, PeerDidResolver, ProofsModule, - TypedArrayEncoder, V2CredentialProtocol, V2ProofProtocol, - WalletKeyExistsError, WsOutboundTransport, } from "@aries-framework/core"; -import axios, { AxiosError } from "axios"; import {agentDependencies} from '@aries-framework/react-native'; import { AnonCredsCredentialFormatService, @@ -51,7 +48,15 @@ import {ariesAskar} from "@hyperledger/aries-askar-react-native"; import uuid from 'react-native-uuid'; import indyLedgers from 'src/configs/ledgers/indy'; import {getMnemonicArrayFromWords} from "src/utils/generic"; -import {getGuid, getPasscode, getPassphrase, setGuid, setPasscode, setPassphrase} from "src/utils/keychain"; +import { + getGuid, + getImapConfig, + getPasscode, + getPassphrase, + setGuid, + setPasscode, + setPassphrase +} from "src/utils/keychain"; import {RootStore} from "src/store/rootStore"; // @ts-ignore import argon2 from "react-native-argon2"; @@ -60,15 +65,34 @@ import {WalletConfig, WalletExportImportConfig} from "@aries-framework/core/buil import { LegacyIndyCredentialFormatService } from "@aries-framework/anoncreds/build/formats/LegacyIndyCredentialFormatService"; +import {infoToast, successToast, warningToast} from 'src/utils/toast'; +import {Buffer} from "buffer"; +import Realm from "realm"; +import MimeParser from "@vereign/lib-mime"; +import notifee, {AndroidImportance, AuthorizationStatus} from '@notifee/react-native'; +import Email from "../db-models/Email"; +import axios from "axios"; +import {NativeModules} from "react-native"; + +const {VereignImapModule} = NativeModules; class AgentStore { private _rootStore: RootStore; private _agent: Agent | null = null; + private _realm!: Realm; + public get agent(): Agent { return this._agent as Agent; } + private _navigation!: any; public get agentCreated() { return !!this._agent; } + public injectNavigation = (navigation: any) => { + this._navigation = navigation; + } + public injectRealm = (realm: Realm) => { + this._realm = realm; + } public get active(): boolean { return this._agent?.isInitialized || false; } @@ -179,7 +203,13 @@ class AgentStore { runInAction(() => { this._agent = newAgent; - }) + }); + + console.log('staring to listen for messages'); + newAgent.events.on( + BasicMessageEventTypes.BasicMessageStateChanged, + (e: BasicMessageStateChangedEvent) => this._processAgentMessage(e), + ); } public startAgent = async () => { @@ -202,6 +232,199 @@ class AgentStore { } } + private _processAgentMessage = async (ev: BasicMessageStateChangedEvent) => { + if (ev.payload.basicMessageRecord.role === BasicMessageRole.Receiver) { + + let emailContent = ev.payload.basicMessageRecord.content; + try { + emailContent = Buffer.from(emailContent, 'base64').toString(); + } catch (e: any) { + console.error('Error decoding base64', e); + warningToast("Email content is not base64 encoded"); + } + + try { + let parser = new MimeParser(emailContent); + const val = (header: string[] | null) => { + return header && header[0] || ''; + } + const messageIdHeader = parser.getGlobalHeaderValue('message-id'); + const messageId = val(messageIdHeader); + + const svdxIdHeader = parser.getGlobalHeaderValue('x-message-id'); + const svdxId = val(svdxIdHeader); + + const receivedDate = new Date(); + + const createdAtHeader = parser.getGlobalHeaderValue('date'); + let createdAt = receivedDate; + if (createdAtHeader) { + createdAt = new Date(val(createdAtHeader) as string); + } + + const fromHeader = parser.getGlobalHeaderValue('from'); + const from = val(fromHeader); + + const toHeader = parser.getGlobalHeaderValue('to'); + const to = toHeader && toHeader.length ? toHeader.join(', ') : ''; + + const ccHeader = parser.getGlobalHeaderValue('cc'); + const cc = ccHeader && ccHeader.length ? ccHeader.join(', ') : ''; + + const bccHeader = parser.getGlobalHeaderValue('bcc'); + const bcc = bccHeader && bccHeader.length ? bccHeader.join(', ') : ''; + + const subjectHeader = parser.getGlobalHeaderValue('subject'); + const subject = val(subjectHeader); + + const realmRecordId = new Realm.BSON.ObjectId(); + + this._realm.write(() => { + const newEmail: Partial<Email> = { + _id: realmRecordId, + messageId: messageId, + createdAt: createdAt, + receivedDate: receivedDate, + + type: 'svdx-mail', + + from: from, + to: to, + cc: cc, + bcc: bcc, + subject: subject, + read: false, + + svdxMime: emailContent, + svdxImapSaved: false, + svdxMessageId: svdxId, + + sealUrl: null + } + this._realm.create('Email', newEmail); + }); + + infoToast("Received new message"); + + await this._saveEmail(svdxId, realmRecordId, emailContent); + + this._displayNewEmailReceived(from, subject, realmRecordId.toString()); + } catch (e) { + warningToast("Email is received but it can not be decoded"); + return; + } + } + } + + private _saveEmail = async (svdxMessageId: string, realmId: Realm.BSON.ObjectId, mime: string) => { + try { + const config = await getImapConfig(); + if (config) { + if (!(await this._checkCanSaveEmail(svdxMessageId))) return; + + VereignImapModule.saveMessage(config!.host, config!.username, config!.password, mime, (success: boolean, error: any) => { + if (success) { + successToast("Email is saved"); + const email = this._realm.objectForPrimaryKey('Email', realmId); + + if (email) { + this._realm.write(() => { + email.svdxImapSaved = true; + }); + this._notifySVDXServer(svdxMessageId); + } + } + if (error) { + warningToast("Something went wrong " + error); + } + }); + } + } catch (e: any) { + warningToast(e.message); + } + } + + private _checkCanSaveEmail = async (svdxMessageId: string) => { + try { + const response = await axios({ + url: `${Config.SVDX_BASE_URL}/v1/message/status`, + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + data: { + messageId: svdxMessageId + }, + }); + + // Check for HTTP 200 status + if (response.status === 200) { + console.log('Message has not been delivered. All is ok'); + return true; + } + return false + } catch (error: any) { + if (error.response && error.response.status === 404) { + // Handle the case where the message has been delivered already in another way + console.log('Message has been delivered already in another way'); + } else { + // Handle other errors + console.error('An error occurred:', error.message); + } + } + return false; + } + + private _notifySVDXServer = async (svdxMessageId: string) => { + try { + await axios({ + url: `${Config.SVDX_BASE_URL}/v1/message/read`, + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + data: { + messageId: svdxMessageId + }, + }); + console.log('Message has been marked as read'); + } catch (e: any) { + console.error('Something wen wrong during notifying SVDX server about read message', e.message); + } + + } + + private _displayNewEmailReceived = async (from: string, subject: string, realmId: string) => { + const authResult = await notifee.requestPermission() + if (authResult.authorizationStatus !== AuthorizationStatus.AUTHORIZED) { + return; + } + + const channelId = await notifee.createChannel({ + id: 'default', + name: 'Default Channel', + importance: AndroidImportance.HIGH, + }); + + // Display a notification + await notifee.displayNotification({ + title: `New Email from ${from}`, + body: `Subject: ${subject || '[No subject]'}`, + data: { + type: 'new-email-received', + realmId: realmId, + }, + android: { + channelId, + // smallIcon: 'ic_launcher', // optional, defaults to 'ic_launcher'. + // pressAction is needed if you want the notification to open the app when pressed + pressAction: { + id: 'default', + }, + }, + }); + } + public stopAgent = async () => { console.debug('Stop agent'); diff --git a/src/store/UrlStore.ts b/src/store/UrlStore.ts index 45e3b627e33cb4167fa0991d7280613f41fbcfbb..338aa1185d5a2d0ad96227aa908a2a5c73b2ed12 100644 --- a/src/store/UrlStore.ts +++ b/src/store/UrlStore.ts @@ -147,7 +147,7 @@ class UrlStore { }; private _processSealUrl = (url: string) => { - this._navigation.navigate(TabStacks.SealStack, { + this._navigation.navigate(TabStacks.EmailStack, { screen: Screens.SealDetailsInfo, params: { sealUrl: url }, }); diff --git a/src/store/rootStore.ts b/src/store/rootStore.ts index 0487672563235e62e06148a0c2989ed05c5b48cd..7c7f0ce6eb4676acb146c093448c3f98e464c1a2 100644 --- a/src/store/rootStore.ts +++ b/src/store/rootStore.ts @@ -1,14 +1,14 @@ -import { action, makeAutoObservable } from "mobx"; +import {makeAutoObservable, runInAction} from "mobx"; import AsyncStorage from "@react-native-async-storage/async-storage"; -import RNSecureStorage from 'rn-secure-storage' import { clearAll as keychainClearAll } from "../utils/keychain"; import AgentStore from "./AgentStore"; import UrlStore from "./UrlStore"; -import {SEALED_LIST} from "../seal/hooks/useSealQrCodes"; +import Realm from "realm"; class RootStore { public readonly agentStore: AgentStore; public readonly urlStore: UrlStore; + private _realm!: Realm; public _authenticated = false; public get authenticated() { @@ -22,23 +22,34 @@ class RootStore { this.urlStore = new UrlStore(this); } - public setAuthenticated = action((authenticated: boolean) => { - this._authenticated = authenticated; + public injectRealm = (realm: Realm) => { + this._realm = realm; + } + + public setAuthenticated = async (authenticated: boolean) => { if (authenticated) { - this.agentStore.startAgent(); + await this.agentStore.startAgent(); } else { - this.agentStore.stopAgent(); + await this.agentStore.stopAgent(); } - }); + + this._authenticated = authenticated; + }; public deleteAllData = async () => { - await this.agentStore.deleteWalletData(); - await AsyncStorage.clear(); - await keychainClearAll(); - try { - await RNSecureStorage.remove(SEALED_LIST) - } catch (e) {} - this._authenticated = false; + runInAction(async () => { + await AsyncStorage.clear(); + await this.agentStore.deleteWalletData(); + + await keychainClearAll(); + try { + this._realm.write(() => { + // Delete all objects from the realm. + this._realm.deleteAll() + }); + } catch (e) {} + this._authenticated = false; + }); } } diff --git a/src/type/navigators.ts b/src/type/navigators.ts index f985b397a7b1cc731dec0b5dfbf695ae785ecc61..cdbda7cc70ad9a3cf30f3939356535a9da6f963a 100644 --- a/src/type/navigators.ts +++ b/src/type/navigators.ts @@ -26,8 +26,10 @@ export enum Screens { CreateWallet = 'CreateWallet', Biometric = 'Biometric', SetupDelay = 'SetupDelay', - SealScannedQrCodeList = 'SealScannedQrCodeList', - SealDetailsInfo = 'SealDetailsInfo' + SealDetailsInfo = 'SealDetailsInfo', + ReceivedEmails = 'ReceivedEmails', + EmailDetails = 'EmailDetails', + ImapConfiguration = 'ImapConfiguration', } export type OnboardingStackParams = { @@ -48,6 +50,7 @@ export type MainStackParams = { [Screens.Scan]: undefined; [Screens.ListContacts]: undefined; [Screens.ConnectionInvitation]: undefined; + [Screens.EmailDetails]: { realmId: string }; [Stacks.SettingsStack]: undefined; [Stacks.NotificationStack]: undefined; }; @@ -61,11 +64,10 @@ export type ContactStackParams = { [Screens.ContactDetails]: { connectionId: string }; }; -export type SealStackParams = { - [Screens.ListContacts]: undefined; - [Screens.ContactDetails]: { connectionId: string }; - [Screens.SealScannedQrCodeList]: undefined; - [Screens.SealDetailsInfo]: { sealUrl: string }; +export type EmailStackParams = { + [Screens.ReceivedEmails]: undefined; + [Screens.EmailDetails]: { realmId: string }; + [Screens.SealDetailsInfo]: { realmId?: string, sealUrl?: string }; }; export type CredentialStackParams = { @@ -92,20 +94,21 @@ export type SettingStackParams = { [Screens.ExportWallet]: undefined; [Screens.ViewMnemonic]: undefined; [Screens.LegalAndPrivacy]: undefined; + [Screens.ImapConfiguration]: undefined; }; export enum TabStacks { ConnectionStack = 'Tab Connection Stack', ScanStack = 'Tab Scan Stack', CredentialStack = 'Tab Credential Stack', - SealStack = 'Tab Seal Stack', + EmailStack = 'Tab Email Stack' } export type TabStackParams = { [TabStacks.ConnectionStack]: NavigatorScreenParams<ContactStackParams>; [TabStacks.ScanStack]: NavigatorScreenParams<ScanStackParams>; [TabStacks.CredentialStack]: NavigatorScreenParams<CredentialStackParams>; - [TabStacks.SealStack]: NavigatorScreenParams<SealStackParams>; + [TabStacks.EmailStack]: NavigatorScreenParams<EmailStackParams>; }; export enum Stacks { diff --git a/src/utils/agentUtils.ts b/src/utils/agentUtils.ts index b33df40fe03b0b4a9c441171b95d2c8b79a35337..4eb10f489407d89e7e0b7d79f0e5aaea7117ffe3 100644 --- a/src/utils/agentUtils.ts +++ b/src/utils/agentUtils.ts @@ -1,14 +1,14 @@ import {Agent, CredentialExchangeRecord, CredentialState, ProofExchangeRecord, ProofState} from "@aries-framework/core"; -export interface Notification { +export interface AgentNotification { key: string; connection?: any; credentialOffer?: CredentialExchangeRecord; proofRequest?: ProofExchangeRecord; } -export const getNotifications = async (agent: Agent): Promise<Notification[]> => { +export const getNotifications = async (agent: Agent): Promise<AgentNotification[]> => { const newOffers = await agent.credentials.findAllByQuery({ state: CredentialState.OfferReceived }); const newProofRequests = await agent.proofs.findAllByQuery({ state: ProofState.RequestReceived }); @@ -28,7 +28,7 @@ export const getNotifications = async (agent: Agent): Promise<Notification[]> => } } - const notifications: Notification[] = []; + const notifications: AgentNotification[] = []; const filteredOffers = newOffers.filter(p => !rejectedIds.some(rejId => rejId === p.id)); for await (const offer of filteredOffers) { diff --git a/src/utils/email.ts b/src/utils/email.ts new file mode 100644 index 0000000000000000000000000000000000000000..eb247722fd2397910fe257753426e07b68c523be --- /dev/null +++ b/src/utils/email.ts @@ -0,0 +1,38 @@ +export interface EmailAddress { + name: string; + email: string; +} + +export function parseEmailAddresses(to: string | undefined): EmailAddress[] { + if (!to) return []; + + const result: EmailAddress[] = []; + const addresses = to.split(",").map(p => p.trim()); + addresses.forEach(address => { + const parsed = parseAddress(address); + if (parsed) { + result.push(parsed); + } + }); + + return result; +} + +export function parseAddress(to: string): EmailAddress | null { + if (!to) return null; + const parts = to.split('<') + .map(p => p.replace('>', '').trim()); + + if (parts.length == 0) return null; + + let name = ''; + let email = ''; + if (parts.length > 1) { + name = parts[0]; + email = parts[1]; + } else { + email = parts[0]; + } + + return { name, email }; +} diff --git a/src/utils/keychain.ts b/src/utils/keychain.ts index 466b546a05e324be1105e1f37d0ec6a3478b17a3..339bbbe3ba4fcb83741a8d044a89b4ba489d87c1 100644 --- a/src/utils/keychain.ts +++ b/src/utils/keychain.ts @@ -5,6 +5,16 @@ enum KeychainStorageKeys { GUID = 'guid', Passphrase = 'passphrase', Passcode = 'passcode', + ImapConfig = 'imap-config', +} + +export interface ImapConfiguration { + verified: boolean; + enableSsl: boolean; + host: string; + username: string; + password: string; + port: number; } export const setGuid = async (guid: string) => { @@ -64,3 +74,27 @@ export const clearAll = async () => { }); } } + +export const setImapConfig = async (config: ImapConfiguration) => { + try { + await Keychain.setGenericPassword(KeychainStorageKeys.ImapConfig, JSON.stringify(config), { + service: KeychainStorageKeys.ImapConfig, + }); + } catch (e: any) { + Alert.alert(e); + } +}; + +export const getImapConfig = async (): Promise<ImapConfiguration | null> => { + const entity = await Keychain.getGenericPassword({ service: KeychainStorageKeys.ImapConfig }) as UserCredentials; + const config = entity?.password; + if (!config) return null; + + let result: ImapConfiguration | null = null; + try { + result = JSON.parse(config); + } catch (e) { + console.error(e); + } + return result; +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index f2c8180fce35fd0ab4717738aef5380b771fa470..a3b919058377ccbfaf42b493a4a2f7e654e49f10 100644 --- a/yarn.lock +++ b/yarn.lock @@ -183,6 +183,14 @@ dependencies: "@babel/highlight" "^7.18.6" +"@babel/code-frame@^7.22.13": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== + dependencies: + "@babel/highlight" "^7.22.13" + chalk "^2.4.2" + "@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.0", "@babel/compat-data@^7.22.3": version "7.22.3" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.3.tgz#cd502a6a0b6e37d7ad72ce7e71a7160a3ae36f7e" @@ -235,6 +243,13 @@ dependencies: "@babel/types" "^7.18.6" +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": version "7.22.3" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.3.tgz#c9b83d1ba74e163e023f008a3d3204588a7ceb60" @@ -294,6 +309,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.1.tgz#ac3a56dbada59ed969d712cf527bd8271fe3eba8" integrity sha512-Z2tgopurB/kTbidvzeBrc2To3PUP/9i5MUe+fU6QJCQDyPwSH2oRapkLw3KGECDYSjhQZCNxEvNvZlLw8JjGwA== +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + "@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0", "@babel/helper-function-name@^7.21.0": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4" @@ -302,6 +322,14 @@ "@babel/template" "^7.20.7" "@babel/types" "^7.21.0" +"@babel/helper-function-name@^7.22.5": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + "@babel/helper-hoist-variables@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" @@ -323,6 +351,13 @@ dependencies: "@babel/types" "^7.21.4" +"@babel/helper-module-imports@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + "@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.20.11", "@babel/helper-module-transforms@^7.21.5", "@babel/helper-module-transforms@^7.22.1": version "7.22.1" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.1.tgz#e0cad47fedcf3cae83c11021696376e2d5a50c63" @@ -349,6 +384,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz#345f2377d05a720a4e5ecfa39cbf4474a4daed56" integrity sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg== +"@babel/helper-plugin-utils@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + "@babel/helper-remap-async-to-generator@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" @@ -359,6 +399,15 @@ "@babel/helper-wrap-function" "^7.18.9" "@babel/types" "^7.18.9" +"@babel/helper-remap-async-to-generator@^7.22.5": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz#7b68e1cb4fa964d2996fd063723fb48eca8498e0" + integrity sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-wrap-function" "^7.22.20" + "@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.20.7", "@babel/helper-replace-supers@^7.22.1": version "7.22.1" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.1.tgz#38cf6e56f7dc614af63a21b45565dd623f0fdc95" @@ -397,11 +446,21 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz#2b3eea65443c6bdc31c22d037c65f6d323b6b2bd" integrity sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w== +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + "@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": version "7.19.1" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + "@babel/helper-validator-option@^7.21.0": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180" @@ -417,6 +476,15 @@ "@babel/traverse" "^7.20.5" "@babel/types" "^7.20.5" +"@babel/helper-wrap-function@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz#15352b0b9bfb10fc9c76f79f6342c00e3411a569" + integrity sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw== + dependencies: + "@babel/helper-function-name" "^7.22.5" + "@babel/template" "^7.22.15" + "@babel/types" "^7.22.19" + "@babel/helpers@^7.22.0": version "7.22.3" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.3.tgz#53b74351da9684ea2f694bf0877998da26dd830e" @@ -435,11 +503,25 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/highlight@^7.22.13": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" + integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + "@babel/parser@^7.1.0", "@babel/parser@^7.1.6", "@babel/parser@^7.13.16", "@babel/parser@^7.14.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.0", "@babel/parser@^7.20.7", "@babel/parser@^7.21.9", "@babel/parser@^7.22.0", "@babel/parser@^7.22.4": version "7.22.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.4.tgz#a770e98fd785c231af9d93f6459d36770993fb32" integrity sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA== +"@babel/parser@^7.22.15": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" + integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" @@ -466,7 +548,7 @@ "@babel/helper-remap-async-to-generator" "^7.18.9" "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.1.0", "@babel/plugin-proposal-class-properties@^7.13.0": +"@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.1.0", "@babel/plugin-proposal-class-properties@^7.13.0", "@babel/plugin-proposal-class-properties@^7.18.0": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== @@ -482,7 +564,7 @@ "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-syntax-export-default-from" "^7.18.6" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.0.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.1.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8": +"@babel/plugin-proposal-nullish-coalescing-operator@^7.0.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.1.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8", "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.0": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== @@ -490,7 +572,15 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-object-rest-spread@^7.0.0": +"@babel/plugin-proposal-numeric-separator@^7.0.0": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" + integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.0.0", "@babel/plugin-proposal-object-rest-spread@^7.20.0": version "7.20.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== @@ -509,7 +599,7 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.0.0", "@babel/plugin-proposal-optional-chaining@^7.1.0", "@babel/plugin-proposal-optional-chaining@^7.13.12": +"@babel/plugin-proposal-optional-chaining@^7.0.0", "@babel/plugin-proposal-optional-chaining@^7.1.0", "@babel/plugin-proposal-optional-chaining@^7.13.12", "@babel/plugin-proposal-optional-chaining@^7.20.0": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea" integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== @@ -564,7 +654,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-dynamic-import@^7.0.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": +"@babel/plugin-syntax-dynamic-import@^7.0.0", "@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== @@ -592,6 +682,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.20.2" +"@babel/plugin-syntax-flow@^7.12.1", "@babel/plugin-syntax-flow@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz#163b820b9e7696ce134df3ee716d9c0c98035859" + integrity sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-import-assertions@^7.20.0": version "7.20.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz#bb50e0d4bea0957235390641209394e87bdb9cc4" @@ -724,6 +821,15 @@ "@babel/helper-plugin-utils" "^7.20.2" "@babel/helper-remap-async-to-generator" "^7.18.9" +"@babel/plugin-transform-async-to-generator@^7.20.0": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz#c7a85f44e46f8952f6d27fe57c2ed3cc084c3775" + integrity sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ== + dependencies: + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.5" + "@babel/plugin-transform-block-scoped-functions@^7.0.0", "@babel/plugin-transform-block-scoped-functions@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" @@ -785,6 +891,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.20.2" +"@babel/plugin-transform-destructuring@^7.20.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz#6447aa686be48b32eaf65a73e0e2c0bd010a266c" + integrity sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8" @@ -832,6 +945,14 @@ "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-flow" "^7.18.6" +"@babel/plugin-transform-flow-strip-types@^7.20.0": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.22.5.tgz#0bb17110c7bf5b35a60754b2f00c58302381dee2" + integrity sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-flow" "^7.22.5" + "@babel/plugin-transform-for-of@^7.0.0", "@babel/plugin-transform-for-of@^7.21.5": version "7.21.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.5.tgz#e890032b535f5a2e237a18535f56a9fdaa7b83fc" @@ -1288,6 +1409,13 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== +"@babel/runtime@>=7": + version "7.23.1" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.1.tgz#72741dc4d413338a91dcb044a86f3c0bc402646d" + integrity sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@^7.0.0", "@babel/runtime@^7.20.0", "@babel/runtime@^7.20.6", "@babel/runtime@^7.21.0", "@babel/runtime@^7.8.4": version "7.22.3" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.3.tgz#0a7fce51d43adbf0f7b517a71f4c3aaca92ebcbb" @@ -1304,6 +1432,15 @@ "@babel/parser" "^7.21.9" "@babel/types" "^7.21.5" +"@babel/template@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + "@babel/traverse@^7.20.0", "@babel/traverse@^7.20.5", "@babel/traverse@^7.22.1", "@babel/traverse@^7.7.2", "@babel/traverse@^7.7.4": version "7.22.4" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.4.tgz#c3cf96c5c290bd13b55e29d025274057727664c0" @@ -1329,6 +1466,15 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" +"@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" + integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + "@bang88/react-native-ultimate-listview@^4.1.0": version "4.1.0" resolved "https://registry.yarnpkg.com/@bang88/react-native-ultimate-listview/-/react-native-ultimate-listview-4.1.0.tgz#efff14ce5a09e8c52116580cdfa17f253faffde2" @@ -1654,6 +1800,13 @@ dependencies: "@sinclair/typebox" "^0.25.16" +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== + dependencies: + "@sinclair/typebox" "^0.27.8" + "@jest/source-map@^29.4.3": version "29.4.3" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.4.3.tgz#ff8d05cbfff875d4a791ab679b4333df47951d20" @@ -1738,6 +1891,18 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== + dependencies: + "@jest/schemas" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + "@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": version "0.3.3" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" @@ -1863,6 +2028,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@notifee/react-native@^7.8.0": + version "7.8.0" + resolved "https://registry.yarnpkg.com/@notifee/react-native/-/react-native-7.8.0.tgz#2990883753990f3585aa0cb5becc5cbdbcd87a43" + integrity sha512-sx8h62U4FrR4pqlbN1rkgPsdamDt9Tad0zgfO6VtP6rNJq/78k8nxUnh0xIX3WPDcCV8KAzdYCE7+UNvhF1CpQ== + "@peculiar/asn1-schema@^2.3.6": version "2.3.6" resolved "https://registry.yarnpkg.com/@peculiar/asn1-schema/-/asn1-schema-2.3.6.tgz#3dd3c2ade7f702a9a94dfb395c192f5fa5d6b922" @@ -1955,6 +2125,16 @@ resolved "https://registry.yarnpkg.com/@react-native-clipboard/clipboard/-/clipboard-1.11.2.tgz#e826d0336b34e67294aaffa6878308900bc7d197" integrity sha512-bHyZVW62TuleiZsXNHS1Pv16fWc0fh8O9WvBzl4h2fykqZRW9a+Pv/RGTH56E3X2PqzHP38K5go8zmCZUoIsoQ== +"@react-native-community/cli-clean@11.3.7": + version "11.3.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-11.3.7.tgz#cb4c2f225f78593412c2d191b55b8570f409a48f" + integrity sha512-twtsv54ohcRyWVzPXL3F9VHGb4Qhn3slqqRs3wEuRzjR7cTmV2TIO2b1VhaqF4HlCgNd+cGuirvLtK2JJyaxMg== + dependencies: + "@react-native-community/cli-tools" "11.3.7" + chalk "^4.1.2" + execa "^5.0.0" + prompts "^2.4.0" + "@react-native-community/cli-clean@^10.1.1": version "10.1.1" resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-10.1.1.tgz#4c73ce93a63a24d70c0089d4025daac8184ff504" @@ -1965,6 +2145,18 @@ execa "^1.0.0" prompts "^2.4.0" +"@react-native-community/cli-config@11.3.7": + version "11.3.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-11.3.7.tgz#4ce95548252ecb094b576369abebf9867c95d277" + integrity sha512-FDBLku9xskS+bx0YFJFLCmUJhEZ4/MMSC9qPYOGBollWYdgE7k/TWI0IeYFmMALAnbCdKQAYP5N29N55Tad8lg== + dependencies: + "@react-native-community/cli-tools" "11.3.7" + chalk "^4.1.2" + cosmiconfig "^5.1.0" + deepmerge "^4.3.0" + glob "^7.1.3" + joi "^17.2.1" + "@react-native-community/cli-config@^10.1.1": version "10.1.1" resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-10.1.1.tgz#08dcc5d7ca1915647dc06507ed853fe0c1488395" @@ -1977,6 +2169,13 @@ glob "^7.1.3" joi "^17.2.1" +"@react-native-community/cli-debugger-ui@11.3.7": + version "11.3.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-11.3.7.tgz#2147b73313af8de3c9b396406d5d344b904cf2bb" + integrity sha512-aVmKuPKHZENR8SrflkMurZqeyLwbKieHdOvaZCh1Nn/0UC5CxWcyST2DB2XQboZwsvr3/WXKJkSUO+SZ1J9qTQ== + dependencies: + serve-static "^1.13.1" + "@react-native-community/cli-debugger-ui@^10.0.0": version "10.0.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-10.0.0.tgz#4bb6d41c7e46449714dc7ba5d9f5b41ef0ea7c57" @@ -1984,6 +2183,30 @@ dependencies: serve-static "^1.13.1" +"@react-native-community/cli-doctor@11.3.7": + version "11.3.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-11.3.7.tgz#7d5f5b1aea78134bba713fa97795986345ff1344" + integrity sha512-YEHUqWISOHnsl5+NM14KHelKh68Sr5/HeEZvvNdIcvcKtZic3FU7Xd1WcbNdo3gCq5JvzGFfufx02Tabh5zmrg== + dependencies: + "@react-native-community/cli-config" "11.3.7" + "@react-native-community/cli-platform-android" "11.3.7" + "@react-native-community/cli-platform-ios" "11.3.7" + "@react-native-community/cli-tools" "11.3.7" + chalk "^4.1.2" + command-exists "^1.2.8" + envinfo "^7.7.2" + execa "^5.0.0" + hermes-profile-transformer "^0.0.6" + ip "^1.1.5" + node-stream-zip "^1.9.1" + ora "^5.4.1" + prompts "^2.4.0" + semver "^7.5.2" + strip-ansi "^5.2.0" + sudo-prompt "^9.0.0" + wcwidth "^1.0.1" + yaml "^2.2.1" + "@react-native-community/cli-doctor@^10.2.2": version "10.2.2" resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-10.2.2.tgz#b1893604fa9fc8971064e7c00042350f96868bfe" @@ -2006,6 +2229,17 @@ sudo-prompt "^9.0.0" wcwidth "^1.0.1" +"@react-native-community/cli-hermes@11.3.7": + version "11.3.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-11.3.7.tgz#091e730a1f8bace6c3729e8744bad6141002e0e8" + integrity sha512-chkKd8n/xeZkinRvtH6QcYA8rjNOKU3S3Lw/3Psxgx+hAYV0Gyk95qJHTalx7iu+PwjOOqqvCkJo5jCkYLkoqw== + dependencies: + "@react-native-community/cli-platform-android" "11.3.7" + "@react-native-community/cli-tools" "11.3.7" + chalk "^4.1.2" + hermes-profile-transformer "^0.0.6" + ip "^1.1.5" + "@react-native-community/cli-hermes@^10.2.0": version "10.2.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-10.2.0.tgz#cc252f435b149f74260bc918ce22fdf58033a87e" @@ -2028,6 +2262,17 @@ glob "^7.1.3" logkitty "^0.7.1" +"@react-native-community/cli-platform-android@11.3.7": + version "11.3.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-11.3.7.tgz#7845bc48258b6bb55df208a23b3690647f113995" + integrity sha512-WGtXI/Rm178UQb8bu1TAeFC/RJvYGnbHpULXvE20GkmeJ1HIrMjkagyk6kkY3Ej25JAP2R878gv+TJ/XiRhaEg== + dependencies: + "@react-native-community/cli-tools" "11.3.7" + chalk "^4.1.2" + execa "^5.0.0" + glob "^7.1.3" + logkitty "^0.7.1" + "@react-native-community/cli-platform-ios@10.2.1", "@react-native-community/cli-platform-ios@^10.2.1": version "10.2.1" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-10.2.1.tgz#2e6bd2cb6d48cbb8720d7b7265bb1bab80745f72" @@ -2040,6 +2285,35 @@ glob "^7.1.3" ora "^5.4.1" +"@react-native-community/cli-platform-ios@11.3.7": + version "11.3.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-11.3.7.tgz#87478f907634713b7236c77870446a5ca1f35ff1" + integrity sha512-Z/8rseBput49EldX7MogvN6zJlWzZ/4M97s2P+zjS09ZoBU7I0eOKLi0N9wx+95FNBvGQQ/0P62bB9UaFQH2jw== + dependencies: + "@react-native-community/cli-tools" "11.3.7" + chalk "^4.1.2" + execa "^5.0.0" + fast-xml-parser "^4.0.12" + glob "^7.1.3" + ora "^5.4.1" + +"@react-native-community/cli-plugin-metro@11.3.7": + version "11.3.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-11.3.7.tgz#2e8a9deb30b40495c5c1347a1837a824400fa00f" + integrity sha512-0WhgoBVGF1f9jXcuagQmtxpwpfP+2LbLZH4qMyo6OtYLWLG13n2uRep+8tdGzfNzl1bIuUTeE9yZSAdnf9LfYQ== + dependencies: + "@react-native-community/cli-server-api" "11.3.7" + "@react-native-community/cli-tools" "11.3.7" + chalk "^4.1.2" + execa "^5.0.0" + metro "0.76.8" + metro-config "0.76.8" + metro-core "0.76.8" + metro-react-native-babel-transformer "0.76.8" + metro-resolver "0.76.8" + metro-runtime "0.76.8" + readline "^1.3.0" + "@react-native-community/cli-plugin-metro@^10.2.2": version "10.2.2" resolved "https://registry.yarnpkg.com/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-10.2.2.tgz#766914e3c8007dfe52b253544c4f6cd8549919ac" @@ -2057,6 +2331,21 @@ metro-runtime "0.73.9" readline "^1.3.0" +"@react-native-community/cli-server-api@11.3.7": + version "11.3.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-11.3.7.tgz#2cce54b3331c9c51b9067129c297ab2e9a142216" + integrity sha512-yoFyGdvR3HxCnU6i9vFqKmmSqFzCbnFSnJ29a+5dppgPRetN+d//O8ard/YHqHzToFnXutAFf2neONn23qcJAg== + dependencies: + "@react-native-community/cli-debugger-ui" "11.3.7" + "@react-native-community/cli-tools" "11.3.7" + compression "^1.7.1" + connect "^3.6.5" + errorhandler "^1.5.1" + nocache "^3.0.1" + pretty-format "^26.6.2" + serve-static "^1.13.1" + ws "^7.5.1" + "@react-native-community/cli-server-api@^10.1.1": version "10.1.1" resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-10.1.1.tgz#e382269de281bb380c2e685431364fbbb8c1cb3a" @@ -2072,6 +2361,21 @@ serve-static "^1.13.1" ws "^7.5.1" +"@react-native-community/cli-tools@11.3.7": + version "11.3.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-11.3.7.tgz#37aa7efc7b4a1b7077d541f1d7bb11a2ab7b6ff2" + integrity sha512-peyhP4TV6Ps1hk+MBHTFaIR1eI3u+OfGBvr5r0wPwo3FAJvldRinMgcB/TcCcOBXVORu7ba1XYjkubPeYcqAyA== + dependencies: + appdirsjs "^1.2.4" + chalk "^4.1.2" + find-up "^5.0.0" + mime "^2.4.1" + node-fetch "^2.6.0" + open "^6.2.0" + ora "^5.4.1" + semver "^7.5.2" + shell-quote "^1.7.3" + "@react-native-community/cli-tools@^10.1.1": version "10.1.1" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-10.1.1.tgz#fa66e509c0d3faa31f7bb87ed7d42ad63f368ddd" @@ -2087,6 +2391,13 @@ semver "^6.3.0" shell-quote "^1.7.3" +"@react-native-community/cli-types@11.3.7": + version "11.3.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-11.3.7.tgz#12fe7cff3da08bd27e11116531b2e001939854b9" + integrity sha512-OhSr/TiDQkXjL5YOs8+hvGSB+HltLn5ZI0+A3DCiMsjUgTTsYh+Z63OtyMpNjrdCEFcg0MpfdU2uxstCS6Dc5g== + dependencies: + joi "^17.2.1" + "@react-native-community/cli-types@^10.0.0": version "10.0.0" resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-10.0.0.tgz#046470c75ec18f8b3bd906e54e43a6f678e01a45" @@ -2117,6 +2428,29 @@ prompts "^2.4.0" semver "^6.3.0" +"@react-native-community/cli@11.3.7": + version "11.3.7" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-11.3.7.tgz#564c0054269d8385fa9d301750b2e56dbb5c0cc9" + integrity sha512-Ou8eDlF+yh2rzXeCTpMPYJ2fuqsusNOhmpYPYNQJQ2h6PvaF30kPomflgRILems+EBBuggRtcT+I+1YH4o/q6w== + dependencies: + "@react-native-community/cli-clean" "11.3.7" + "@react-native-community/cli-config" "11.3.7" + "@react-native-community/cli-debugger-ui" "11.3.7" + "@react-native-community/cli-doctor" "11.3.7" + "@react-native-community/cli-hermes" "11.3.7" + "@react-native-community/cli-plugin-metro" "11.3.7" + "@react-native-community/cli-server-api" "11.3.7" + "@react-native-community/cli-tools" "11.3.7" + "@react-native-community/cli-types" "11.3.7" + chalk "^4.1.2" + commander "^9.4.1" + execa "^5.0.0" + find-up "^4.1.0" + fs-extra "^8.1.0" + graceful-fs "^4.1.3" + prompts "^2.4.0" + semver "^7.5.2" + "@react-native-community/eslint-config@^3.2.0": version "3.2.0" resolved "https://registry.yarnpkg.com/@react-native-community/eslint-config/-/eslint-config-3.2.0.tgz#42f677d5fff385bccf1be1d3b8faa8c086cf998d" @@ -2141,16 +2475,51 @@ resolved "https://registry.yarnpkg.com/@react-native-community/eslint-plugin/-/eslint-plugin-1.3.0.tgz#9e558170c106bbafaa1ef502bd8e6d4651012bf9" integrity sha512-+zDZ20NUnSWghj7Ku5aFphMzuM9JulqCW+aPXT6IfIXFbb8tzYTTOSeRFOtuekJ99ibW2fUCSsjuKNlwDIbHFg== +"@react-native/assets-registry@^0.72.0": + version "0.72.0" + resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.72.0.tgz#c82a76a1d86ec0c3907be76f7faf97a32bbed05d" + integrity sha512-Im93xRJuHHxb1wniGhBMsxLwcfzdYreSZVQGDoMJgkd6+Iky61LInGEHnQCTN0fKNYF1Dvcofb4uMmE1RQHXHQ== + "@react-native/assets@1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@react-native/assets/-/assets-1.0.0.tgz#c6f9bf63d274bafc8e970628de24986b30a55c8e" integrity sha512-KrwSpS1tKI70wuKl68DwJZYEvXktDHdZMG0k2AXD/rJVSlB23/X2CB2cutVR0HwNMJIal9HOUOBB2rVfa6UGtQ== +"@react-native/codegen@^0.72.7": + version "0.72.7" + resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.72.7.tgz#b6832ce631ac63143024ea094a6b5480a780e589" + integrity sha512-O7xNcGeXGbY+VoqBGNlZ3O05gxfATlwE1Q1qQf5E38dK+tXn5BY4u0jaQ9DPjfE8pBba8g/BYI1N44lynidMtg== + dependencies: + "@babel/parser" "^7.20.0" + flow-parser "^0.206.0" + jscodeshift "^0.14.0" + nullthrows "^1.1.1" + +"@react-native/gradle-plugin@^0.72.11": + version "0.72.11" + resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.72.11.tgz#c063ef12778706611de7a1e42b74b14d9405fb9f" + integrity sha512-P9iRnxiR2w7EHcZ0mJ+fmbPzMby77ZzV6y9sJI3lVLJzF7TLSdbwcQyD3lwMsiL+q5lKUHoZJS4sYmih+P2HXw== + +"@react-native/js-polyfills@^0.72.1": + version "0.72.1" + resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.72.1.tgz#905343ef0c51256f128256330fccbdb35b922291" + integrity sha512-cRPZh2rBswFnGt5X5EUEPs0r+pAsXxYsifv/fgy9ZLQokuT52bPH+9xjDR+7TafRua5CttGW83wP4TntRcWNDA== + "@react-native/normalize-color@*", "@react-native/normalize-color@2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.1.0.tgz#939b87a9849e81687d3640c5efa2a486ac266f91" integrity sha512-Z1jQI2NpdFJCVgpY+8Dq/Bt3d+YUi1928Q+/CZm/oh66fzM0RUl54vvuXlPJKybH4pdCZey1eDTPaLHkMPNgWA== +"@react-native/normalize-colors@*": + version "0.73.1" + resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.73.1.tgz#5c1d28ec825b053142c435e0b52bf2e2f2a03d8d" + integrity sha512-PxbovgSN1lxBtS81D7sG96JBK+QcxUMXq4BKhESI0WjEi4dAVbhEHq39uDlhfdcVpeID6gMiBKBLFurD2F6RNQ== + +"@react-native/normalize-colors@^0.72.0": + version "0.72.0" + resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.72.0.tgz#14294b7ed3c1d92176d2a00df48456e8d7d62212" + integrity sha512-285lfdqSXaqKuBbbtP9qL2tDrfxdOFtIMvkKadtleRQkdOxx+uzGvFr82KHmc/sSiMtfXGp7JnFYWVh4sFl7Yw== + "@react-native/polyfills@2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@react-native/polyfills/-/polyfills-2.0.0.tgz#4c40b74655c83982c8cf47530ee7dc13d957b6aa" @@ -2164,6 +2533,14 @@ invariant "^2.2.4" nullthrows "^1.1.1" +"@react-native/virtualized-lists@^0.72.8": + version "0.72.8" + resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.72.8.tgz#a2c6a91ea0f1d40eb5a122fb063daedb92ed1dc3" + integrity sha512-J3Q4Bkuo99k7mu+jPS9gSUSgq+lLRSI/+ahXNwV92XgJ/8UgOTxu2LPwhJnBk/sQKxq7E8WkZBnBiozukQMqrw== + dependencies: + invariant "^2.2.4" + nullthrows "^1.1.1" + "@react-navigation/bottom-tabs@^6.5.7": version "6.5.7" resolved "https://registry.yarnpkg.com/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.7.tgz#08470c96e0d11481422214bb98f0ff034038856c" @@ -2216,6 +2593,16 @@ color "^4.2.3" warn-once "^0.1.0" +"@realm/react@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@realm/react/-/react-0.6.0.tgz#64a62725a777b17d88c8c35cf617484503bdbf08" + integrity sha512-gggNChqj3J2ImgIf3Q6I++DEAo2KW+52Dh0ndv7QWhek0CLCHKIGiWYXBikDmW1bqGsj8gbLVr7mxbOshnRkKg== + dependencies: + lodash "^4.17.21" + optionalDependencies: + "@babel/runtime" ">=7" + react-native ">=0.68" + "@sideway/address@^4.1.3": version "4.1.4" resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" @@ -2238,6 +2625,11 @@ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + "@sinonjs/commons@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.0.tgz#beb434fe875d965265e04722ccfc21df7f755d72" @@ -3054,6 +3446,13 @@ ast-types@0.14.2: dependencies: tslib "^2.0.1" +ast-types@0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.15.2.tgz#39ae4809393c4b16df751ee563411423e85fb49d" + integrity sha512-c27loCv9QkZinsa5ProX751khO9DJl/AcB5c2KNtA6NRvHKS0PgLfcftz72KVq504vB0Gku5s2kUZzDBvQWvHg== + dependencies: + tslib "^2.0.1" + astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -3196,6 +3595,13 @@ babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz#aa213c1435e2bffeb6fca842287ef534ad05d5cf" integrity sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ== +babel-plugin-transform-flow-enums@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz#d1d0cc9bdc799c850ca110d0ddc9f21b9ec3ef25" + integrity sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ== + dependencies: + "@babel/plugin-syntax-flow" "^7.12.1" + babel-preset-current-node-syntax@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" @@ -3301,7 +3707,7 @@ bignumber.js@^9.0.0: resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6" integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig== -bl@^4.1.0: +bl@^4.0.3, bl@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== @@ -3393,12 +3799,19 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" +bson@^4.7.2: + version "4.7.2" + resolved "https://registry.yarnpkg.com/bson/-/bson-4.7.2.tgz#320f4ad0eaf5312dd9b45dc369cc48945e2a5f2e" + integrity sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ== + dependencies: + buffer "^5.6.0" + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer@^5.5.0: +buffer@^5.5.0, buffer@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -3500,7 +3913,7 @@ canvas@^2.8.0: nan "^2.17.0" simple-get "^3.0.3" -chalk@^2.0.0: +chalk@^2.0.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -3537,6 +3950,11 @@ charenc@0.0.2: resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + chownr@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" @@ -4039,11 +4457,23 @@ decompress-response@^4.2.0: dependencies: mimic-response "^2.0.0" +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -4054,7 +4484,7 @@ deepmerge@^3.2.0: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-3.3.0.tgz#d3c47fd6f3a93d517b14426b0628a17b0125f5f7" integrity sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA== -deepmerge@^4.2.2: +deepmerge@^4.2.2, deepmerge@^4.3.0: version "4.3.1" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== @@ -4116,6 +4546,15 @@ depd@2.0.0: resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== +deprecated-react-native-prop-types@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-4.1.0.tgz#8ed03a64c21b7fbdd2d000957b6838d4f38d2c66" + integrity sha512-WfepZHmRbbdTvhcolb8aOKEvQdcmTMn5tKLbqbXmkBvjFjRVWAYqsXk/DBsV8TZxws8SdGHLuHaJrHSQUPRdfw== + dependencies: + "@react-native/normalize-colors" "*" + invariant "*" + prop-types "*" + deprecated-react-native-prop-types@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-3.0.1.tgz#a275f84cd8519cd1665e8df3c99e9067d57a23ec" @@ -4282,7 +4721,7 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -end-of-stream@^1.1.0: +end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -4323,7 +4762,7 @@ error-stack-parser@^2.0.6: dependencies: stackframe "^1.3.4" -errorhandler@^1.5.0: +errorhandler@^1.5.0, errorhandler@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/errorhandler/-/errorhandler-1.5.1.tgz#b9ba5d17cf90744cd1e851357a6e75bf806a9a91" integrity sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A== @@ -4687,6 +5126,11 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + expect@^29.0.0, expect@^29.5.0: version "29.5.0" resolved "https://registry.yarnpkg.com/expect/-/expect-29.5.0.tgz#68c0509156cb2a0adb8865d413b137eeaae682f7" @@ -4917,6 +5361,11 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== +flow-enums-runtime@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/flow-enums-runtime/-/flow-enums-runtime-0.0.5.tgz#95884bfcc82edaf27eef7e1dd09732331cfbafbc" + integrity sha512-PSZF9ZuaZD03sT9YaIs0FrGJ7lSUw7rHZIex+73UYVXg46eL/wxN5PaVcPJFudE2cJu5f0fezitV5aBkLHPUOQ== + flow-parser@0.*: version "0.207.0" resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.207.0.tgz#376975f6b88991bf0ef9496fa3bffd5eb3120046" @@ -4932,6 +5381,11 @@ flow-parser@^0.185.0: resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.185.2.tgz#cb7ee57f77377d6c5d69a469e980f6332a15e492" integrity sha512-2hJ5ACYeJCzNtiVULov6pljKOLygy0zddoqSI1fFetM+XRPpRshFdGEijtqlamA1XwyZ+7rhryI6FQFzvtLWUQ== +flow-parser@^0.206.0: + version "0.206.0" + resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.206.0.tgz#f4f794f8026535278393308e01ea72f31000bfef" + integrity sha512-HVzoK3r6Vsg+lKvlIZzaWNBVai+FXTX1wdYhz/wVlH13tb/gOdLXmlTqy6odmTBhT5UoWUbq0k8263Qhr9d88w== + follow-redirects@^1.10.0: version "1.15.2" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" @@ -4979,6 +5433,11 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" @@ -5100,6 +5559,11 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== + glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -5289,11 +5753,23 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +hermes-estree@0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.12.0.tgz#8a289f9aee854854422345e6995a48613bac2ca8" + integrity sha512-+e8xR6SCen0wyAKrMT3UD0ZCCLymKhRgjEB5sS28rKiFir/fXgLoeRilRUssFCILmGHb+OvHDUlhxs0+IEyvQw== + hermes-estree@0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.8.0.tgz#530be27243ca49f008381c1f3e8b18fb26bf9ec0" integrity sha512-W6JDAOLZ5pMPMjEiQGLCXSSV7pIBEgRR5zGkxgmzGSXHOxqV5dC/M1Zevqpbm9TZDE5tu358qZf8Vkzmsc+u7Q== +hermes-parser@0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.12.0.tgz#114dc26697cfb41a6302c215b859b74224383773" + integrity sha512-d4PHnwq6SnDLhYl3LHNHvOg7nQ6rcI7QVil418REYksv0Mh3cEkHDcuhGxNQ3vgnLSLl4QSvDrFCwQNYdpWlzw== + dependencies: + hermes-estree "0.12.0" + hermes-parser@0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.8.0.tgz#116dceaba32e45b16d6aefb5c4c830eaeba2d257" @@ -5406,6 +5882,13 @@ image-size@^0.6.0: resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.6.3.tgz#e7e5c65bb534bd7cdcedd6cb5166272a85f75fb2" integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== +image-size@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.0.2.tgz#d778b6d0ab75b2737c1556dd631652eb963bc486" + integrity sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg== + dependencies: + queue "6.0.2" + import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" @@ -5455,6 +5938,11 @@ inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + internal-slot@^1.0.3, internal-slot@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" @@ -5969,6 +6457,11 @@ jest-get-type@^29.4.3: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== + jest-haste-map@^29.5.0: version "29.5.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.5.0.tgz#69bd67dc9012d6e2723f20a945099e972b2e94de" @@ -6196,6 +6689,18 @@ jest-validate@^26.5.2: leven "^3.1.0" pretty-format "^26.6.2" +jest-validate@^29.2.1: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" + integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== + dependencies: + "@jest/types" "^29.6.3" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^29.6.3" + leven "^3.1.0" + pretty-format "^29.7.0" + jest-validate@^29.5.0: version "29.5.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.5.0.tgz#8e5a8f36178d40e47138dc00866a5f3bd9916ffc" @@ -6297,6 +6802,11 @@ jsc-android@^250231.0.0: resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-250231.0.0.tgz#91720f8df382a108872fa4b3f558f33ba5e95262" integrity sha512-rS46PvsjYmdmuz1OAWXY/1kCYG7pnf1TBqeTiOJr1iDz7s5DLxxC9n/ZMknLDxzYzNVfI7R95MH10emSSG1Wuw== +jsc-safe-url@^0.2.2: + version "0.2.4" + resolved "https://registry.yarnpkg.com/jsc-safe-url/-/jsc-safe-url-0.2.4.tgz#141c14fbb43791e88d5dc64e85a374575a83477a" + integrity sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q== + jscodeshift@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.11.0.tgz#4f95039408f3f06b0e39bb4d53bc3139f5330e2f" @@ -6347,6 +6857,31 @@ jscodeshift@^0.13.1: temp "^0.8.4" write-file-atomic "^2.3.0" +jscodeshift@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.14.0.tgz#7542e6715d6d2e8bde0b4e883f0ccea358b46881" + integrity sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA== + dependencies: + "@babel/core" "^7.13.16" + "@babel/parser" "^7.13.16" + "@babel/plugin-proposal-class-properties" "^7.13.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.13.8" + "@babel/plugin-proposal-optional-chaining" "^7.13.12" + "@babel/plugin-transform-modules-commonjs" "^7.13.8" + "@babel/preset-flow" "^7.13.13" + "@babel/preset-typescript" "^7.13.0" + "@babel/register" "^7.13.16" + babel-core "^7.0.0-bridge.0" + chalk "^4.1.2" + flow-parser "0.*" + graceful-fs "^4.2.4" + micromatch "^4.0.4" + neo-async "^2.5.0" + node-dir "^0.1.17" + recast "^0.21.0" + temp "^0.8.4" + write-file-atomic "^2.3.0" + jsdom@^19.0.0: version "19.0.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-19.0.0.tgz#93e67c149fe26816d38a849ea30ac93677e16b6a" @@ -6704,11 +7239,25 @@ metro-babel-transformer@0.73.9: metro-source-map "0.73.9" nullthrows "^1.1.1" +metro-babel-transformer@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.76.8.tgz#5efd1027353b36b73706164ef09c290dceac096a" + integrity sha512-Hh6PW34Ug/nShlBGxkwQJSgPGAzSJ9FwQXhUImkzdsDgVu6zj5bx258J8cJVSandjNoQ8nbaHK6CaHlnbZKbyA== + dependencies: + "@babel/core" "^7.20.0" + hermes-parser "0.12.0" + nullthrows "^1.1.1" + metro-cache-key@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.73.9.tgz#7d8c441a3b7150f7b201273087ef3cf7d3435d9f" integrity sha512-uJg+6Al7UoGIuGfoxqPBy6y1Ewq7Y8/YapGYIDh6sohInwt/kYKnPZgLDYHIPvY2deORnQ/2CYo4tOeBTnhCXQ== +metro-cache-key@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.76.8.tgz#8a0a5e991c06f56fcc584acadacb313c312bdc16" + integrity sha512-buKQ5xentPig9G6T37Ww/R/bC+/V1MA5xU/D8zjnhlelsrPG6w6LtHUS61ID3zZcMZqYaELWk5UIadIdDsaaLw== + metro-cache@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.73.9.tgz#773c2df6ba53434e58ccbe421b0c54e6da8d2890" @@ -6717,6 +7266,14 @@ metro-cache@0.73.9: metro-core "0.73.9" rimraf "^3.0.2" +metro-cache@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.76.8.tgz#296c1c189db2053b89735a8f33dbe82575f53661" + integrity sha512-QBJSJIVNH7Hc/Yo6br/U/qQDUpiUdRgZ2ZBJmvAbmAKp2XDzsapnMwK/3BGj8JNWJF7OLrqrYHsRsukSbUBpvQ== + dependencies: + metro-core "0.76.8" + rimraf "^3.0.2" + metro-config@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.73.9.tgz#6b43c70681bdd6b00f44400fc76dddbe53374500" @@ -6729,6 +7286,19 @@ metro-config@0.73.9: metro-core "0.73.9" metro-runtime "0.73.9" +metro-config@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.76.8.tgz#20bd5397fcc6096f98d2a813a7cecb38b8af062d" + integrity sha512-SL1lfKB0qGHALcAk2zBqVgQZpazDYvYFGwCK1ikz0S6Y/CM2i2/HwuZN31kpX6z3mqjv/6KvlzaKoTb1otuSAA== + dependencies: + connect "^3.6.5" + cosmiconfig "^5.0.5" + jest-validate "^29.2.1" + metro "0.76.8" + metro-cache "0.76.8" + metro-core "0.76.8" + metro-runtime "0.76.8" + metro-core@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.73.9.tgz#410c5c0aeae840536c10039f68098fdab3da568e" @@ -6737,6 +7307,14 @@ metro-core@0.73.9: lodash.throttle "^4.1.1" metro-resolver "0.73.9" +metro-core@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.76.8.tgz#917c8157c63406cb223522835abb8e7c6291dcad" + integrity sha512-sl2QLFI3d1b1XUUGxwzw/KbaXXU/bvFYrSKz6Sg19AdYGWFyzsgZ1VISRIDf+HWm4R/TJXluhWMEkEtZuqi3qA== + dependencies: + lodash.throttle "^4.1.1" + metro-resolver "0.76.8" + metro-file-map@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.73.9.tgz#09c04a8e8ef1eaa6ecb2b9cb8cb53bb0fa0167ec" @@ -6758,6 +7336,26 @@ metro-file-map@0.73.9: optionalDependencies: fsevents "^2.3.2" +metro-file-map@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.76.8.tgz#a1db1185b6c316904ba6b53d628e5d1323991d79" + integrity sha512-A/xP1YNEVwO1SUV9/YYo6/Y1MmzhL4ZnVgcJC3VmHp/BYVOXVStzgVbWv2wILe56IIMkfXU+jpXrGKKYhFyHVw== + dependencies: + anymatch "^3.0.3" + debug "^2.2.0" + fb-watchman "^2.0.0" + graceful-fs "^4.2.4" + invariant "^2.2.4" + jest-regex-util "^27.0.6" + jest-util "^27.2.0" + jest-worker "^27.2.0" + micromatch "^4.0.4" + node-abort-controller "^3.1.1" + nullthrows "^1.1.1" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + metro-hermes-compiler@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro-hermes-compiler/-/metro-hermes-compiler-0.73.9.tgz#6f473e67e8f76066066f00e2e0ecce865f7d445d" @@ -6773,6 +7371,17 @@ metro-inspector-proxy@0.73.9: ws "^7.5.1" yargs "^17.5.1" +metro-inspector-proxy@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.76.8.tgz#6b8678a7461b0b42f913a7881cc9319b4d3cddff" + integrity sha512-Us5o5UEd4Smgn1+TfHX4LvVPoWVo9VsVMn4Ldbk0g5CQx3Gu0ygc/ei2AKPGTwsOZmKxJeACj7yMH2kgxQP/iw== + dependencies: + connect "^3.6.5" + debug "^2.2.0" + node-fetch "^2.2.0" + ws "^7.5.1" + yargs "^17.6.2" + metro-minify-terser@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.73.9.tgz#301aef2e106b0802f7a14ef0f2b4883b20c80018" @@ -6780,6 +7389,13 @@ metro-minify-terser@0.73.9: dependencies: terser "^5.15.0" +metro-minify-terser@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.76.8.tgz#915ab4d1419257fc6a0b9fa15827b83fe69814bf" + integrity sha512-Orbvg18qXHCrSj1KbaeSDVYRy/gkro2PC7Fy2tDSH1c9RB4aH8tuMOIXnKJE+1SXxBtjWmQ5Yirwkth2DyyEZA== + dependencies: + terser "^5.15.0" + metro-minify-uglify@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.73.9.tgz#cf4f8c19b688deea103905689ec736c2f2acd733" @@ -6787,6 +7403,13 @@ metro-minify-uglify@0.73.9: dependencies: uglify-es "^3.1.9" +metro-minify-uglify@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.76.8.tgz#74745045ea2dd29f8783db483b2fce58385ba695" + integrity sha512-6l8/bEvtVaTSuhG1FqS0+Mc8lZ3Bl4RI8SeRIifVLC21eeSDp4CEBUWSGjpFyUDfi6R5dXzYaFnSgMNyfxADiQ== + dependencies: + uglify-es "^3.1.9" + metro-react-native-babel-preset@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.9.tgz#ef54637dd20f025197beb49e71309a9c539e73e2" @@ -6831,6 +7454,51 @@ metro-react-native-babel-preset@0.73.9: "@babel/template" "^7.0.0" react-refresh "^0.4.0" +metro-react-native-babel-preset@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.76.8.tgz#7476efae14363cbdfeeec403b4f01d7348e6c048" + integrity sha512-Ptza08GgqzxEdK8apYsjTx2S8WDUlS2ilBlu9DR1CUcHmg4g3kOkFylZroogVAUKtpYQNYwAvdsjmrSdDNtiAg== + dependencies: + "@babel/core" "^7.20.0" + "@babel/plugin-proposal-async-generator-functions" "^7.0.0" + "@babel/plugin-proposal-class-properties" "^7.18.0" + "@babel/plugin-proposal-export-default-from" "^7.0.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.0" + "@babel/plugin-proposal-numeric-separator" "^7.0.0" + "@babel/plugin-proposal-object-rest-spread" "^7.20.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" + "@babel/plugin-proposal-optional-chaining" "^7.20.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-export-default-from" "^7.0.0" + "@babel/plugin-syntax-flow" "^7.18.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0" + "@babel/plugin-syntax-optional-chaining" "^7.0.0" + "@babel/plugin-transform-arrow-functions" "^7.0.0" + "@babel/plugin-transform-async-to-generator" "^7.20.0" + "@babel/plugin-transform-block-scoping" "^7.0.0" + "@babel/plugin-transform-classes" "^7.0.0" + "@babel/plugin-transform-computed-properties" "^7.0.0" + "@babel/plugin-transform-destructuring" "^7.20.0" + "@babel/plugin-transform-flow-strip-types" "^7.20.0" + "@babel/plugin-transform-function-name" "^7.0.0" + "@babel/plugin-transform-literals" "^7.0.0" + "@babel/plugin-transform-modules-commonjs" "^7.0.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.0.0" + "@babel/plugin-transform-parameters" "^7.0.0" + "@babel/plugin-transform-react-display-name" "^7.0.0" + "@babel/plugin-transform-react-jsx" "^7.0.0" + "@babel/plugin-transform-react-jsx-self" "^7.0.0" + "@babel/plugin-transform-react-jsx-source" "^7.0.0" + "@babel/plugin-transform-runtime" "^7.0.0" + "@babel/plugin-transform-shorthand-properties" "^7.0.0" + "@babel/plugin-transform-spread" "^7.0.0" + "@babel/plugin-transform-sticky-regex" "^7.0.0" + "@babel/plugin-transform-typescript" "^7.5.0" + "@babel/plugin-transform-unicode-regex" "^7.0.0" + "@babel/template" "^7.0.0" + babel-plugin-transform-flow-enums "^0.0.2" + react-refresh "^0.4.0" + metro-react-native-babel-transformer@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.73.9.tgz#4f4f0cfa5119bab8b53e722fabaf90687d0cbff0" @@ -6844,6 +7512,17 @@ metro-react-native-babel-transformer@0.73.9: metro-source-map "0.73.9" nullthrows "^1.1.1" +metro-react-native-babel-transformer@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.76.8.tgz#c3a98e1f4cd5faf1e21eba8e004b94a90c4db69b" + integrity sha512-3h+LfS1WG1PAzhq8QF0kfXjxuXetbY/lgz8vYMQhgrMMp17WM1DNJD0gjx8tOGYbpbBC1qesJ45KMS4o5TA73A== + dependencies: + "@babel/core" "^7.20.0" + babel-preset-fbjs "^3.4.0" + hermes-parser "0.12.0" + metro-react-native-babel-preset "0.76.8" + nullthrows "^1.1.1" + metro-resolver@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.73.9.tgz#f3cf77e6c7606a34aa81bad40edb856aad671cf3" @@ -6851,6 +7530,11 @@ metro-resolver@0.73.9: dependencies: absolute-path "^0.0.0" +metro-resolver@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.76.8.tgz#0862755b9b84e26853978322464fb37c6fdad76d" + integrity sha512-KccOqc10vrzS7ZhG2NSnL2dh3uVydarB7nOhjreQ7C4zyWuiW9XpLC4h47KtGQv3Rnv/NDLJYeDqaJ4/+140HQ== + metro-runtime@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.73.9.tgz#0b24c0b066b8629ee855a6e5035b65061fef60d5" @@ -6859,6 +7543,14 @@ metro-runtime@0.73.9: "@babel/runtime" "^7.0.0" react-refresh "^0.4.0" +metro-runtime@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.76.8.tgz#74b2d301a2be5f3bbde91b8f1312106f8ffe50c3" + integrity sha512-XKahvB+iuYJSCr3QqCpROli4B4zASAYpkK+j3a0CJmokxCDNbgyI4Fp88uIL6rNaZfN0Mv35S0b99SdFXIfHjg== + dependencies: + "@babel/runtime" "^7.0.0" + react-refresh "^0.4.0" + metro-source-map@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.73.9.tgz#89ca41f6346aeb12f7f23496fa363e520adafebe" @@ -6873,6 +7565,20 @@ metro-source-map@0.73.9: source-map "^0.5.6" vlq "^1.0.0" +metro-source-map@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.76.8.tgz#f085800152a6ba0b41ca26833874d31ec36c5a53" + integrity sha512-Hh0ncPsHPVf6wXQSqJqB3K9Zbudht4aUtNpNXYXSxH+pteWqGAXnjtPsRAnCsCWl38wL0jYF0rJDdMajUI3BDw== + dependencies: + "@babel/traverse" "^7.20.0" + "@babel/types" "^7.20.0" + invariant "^2.2.4" + metro-symbolicate "0.76.8" + nullthrows "^1.1.1" + ob1 "0.76.8" + source-map "^0.5.6" + vlq "^1.0.0" + metro-symbolicate@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.73.9.tgz#cb452299a36e5b86b2826e7426d51221635c48bf" @@ -6885,6 +7591,18 @@ metro-symbolicate@0.73.9: through2 "^2.0.1" vlq "^1.0.0" +metro-symbolicate@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.76.8.tgz#f102ac1a306d51597ecc8fdf961c0a88bddbca03" + integrity sha512-LrRL3uy2VkzrIXVlxoPtqb40J6Bf1mlPNmUQewipc3qfKKFgtPHBackqDy1YL0njDsWopCKcfGtFYLn0PTUn3w== + dependencies: + invariant "^2.2.4" + metro-source-map "0.76.8" + nullthrows "^1.1.1" + source-map "^0.5.6" + through2 "^2.0.1" + vlq "^1.0.0" + metro-transform-plugins@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.73.9.tgz#9fffbe1b24269e3d114286fa681abc570072d9b8" @@ -6896,6 +7614,17 @@ metro-transform-plugins@0.73.9: "@babel/traverse" "^7.20.0" nullthrows "^1.1.1" +metro-transform-plugins@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.76.8.tgz#d77c28a6547a8e3b72250f740fcfbd7f5408f8ba" + integrity sha512-PlkGTQNqS51Bx4vuufSQCdSn2R2rt7korzngo+b5GCkeX5pjinPjnO2kNhQ8l+5bO0iUD/WZ9nsM2PGGKIkWFA== + dependencies: + "@babel/core" "^7.20.0" + "@babel/generator" "^7.20.0" + "@babel/template" "^7.0.0" + "@babel/traverse" "^7.20.0" + nullthrows "^1.1.1" + metro-transform-worker@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.73.9.tgz#30384cef2d5e35a4abe91b15bf1a8344f5720441" @@ -6915,6 +7644,24 @@ metro-transform-worker@0.73.9: metro-transform-plugins "0.73.9" nullthrows "^1.1.1" +metro-transform-worker@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.76.8.tgz#b9012a196cee205170d0c899b8b175b9305acdea" + integrity sha512-mE1fxVAnJKmwwJyDtThildxxos9+DGs9+vTrx2ktSFMEVTtXS/bIv2W6hux1pqivqAfyJpTeACXHk5u2DgGvIQ== + dependencies: + "@babel/core" "^7.20.0" + "@babel/generator" "^7.20.0" + "@babel/parser" "^7.20.0" + "@babel/types" "^7.20.0" + babel-preset-fbjs "^3.4.0" + metro "0.76.8" + metro-babel-transformer "0.76.8" + metro-cache "0.76.8" + metro-cache-key "0.76.8" + metro-source-map "0.76.8" + metro-transform-plugins "0.76.8" + nullthrows "^1.1.1" + metro@0.73.9: version "0.73.9" resolved "https://registry.yarnpkg.com/metro/-/metro-0.73.9.tgz#150e69a6735fab0bcb4f6ee97fd1efc65b3ec36f" @@ -6971,6 +7718,60 @@ metro@0.73.9: ws "^7.5.1" yargs "^17.5.1" +metro@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/metro/-/metro-0.76.8.tgz#ba526808b99977ca3f9ac5a7432fd02a340d13a6" + integrity sha512-oQA3gLzrrYv3qKtuWArMgHPbHu8odZOD9AoavrqSFllkPgOtmkBvNNDLCELqv5SjBfqjISNffypg+5UGG3y0pg== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/core" "^7.20.0" + "@babel/generator" "^7.20.0" + "@babel/parser" "^7.20.0" + "@babel/template" "^7.0.0" + "@babel/traverse" "^7.20.0" + "@babel/types" "^7.20.0" + accepts "^1.3.7" + async "^3.2.2" + chalk "^4.0.0" + ci-info "^2.0.0" + connect "^3.6.5" + debug "^2.2.0" + denodeify "^1.2.1" + error-stack-parser "^2.0.6" + graceful-fs "^4.2.4" + hermes-parser "0.12.0" + image-size "^1.0.2" + invariant "^2.2.4" + jest-worker "^27.2.0" + jsc-safe-url "^0.2.2" + lodash.throttle "^4.1.1" + metro-babel-transformer "0.76.8" + metro-cache "0.76.8" + metro-cache-key "0.76.8" + metro-config "0.76.8" + metro-core "0.76.8" + metro-file-map "0.76.8" + metro-inspector-proxy "0.76.8" + metro-minify-terser "0.76.8" + metro-minify-uglify "0.76.8" + metro-react-native-babel-preset "0.76.8" + metro-resolver "0.76.8" + metro-runtime "0.76.8" + metro-source-map "0.76.8" + metro-symbolicate "0.76.8" + metro-transform-plugins "0.76.8" + metro-transform-worker "0.76.8" + mime-types "^2.1.27" + node-fetch "^2.2.0" + nullthrows "^1.1.1" + rimraf "^3.0.2" + serialize-error "^2.1.0" + source-map "^0.5.6" + strip-ansi "^6.0.0" + throat "^5.0.0" + ws "^7.5.1" + yargs "^17.6.2" + micromatch@^3.1.10: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -7030,6 +7831,11 @@ mimic-response@^2.0.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -7044,7 +7850,7 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -7077,6 +7883,11 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + mkdirp@^0.5.1: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" @@ -7153,6 +7964,11 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + natural-compare-lite@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" @@ -7183,6 +7999,18 @@ nocache@^3.0.1: resolved "https://registry.yarnpkg.com/nocache/-/nocache-3.0.4.tgz#5b37a56ec6e09fc7d401dceaed2eab40c8bfdf79" integrity sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw== +node-abi@^3.3.0: + version "3.47.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.47.0.tgz#6cbfa2916805ae25c2b7156ca640131632eb05e8" + integrity sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A== + dependencies: + semver "^7.3.5" + +node-abort-controller@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548" + integrity sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ== + node-dir@^0.1.17: version "0.1.17" resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" @@ -7205,11 +8033,23 @@ node-fetch@^2.2.0, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.11, nod dependencies: whatwg-url "^5.0.0" +node-fetch@^2.6.9: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== +node-machine-id@^1.1.12: + version "1.1.12" + resolved "https://registry.yarnpkg.com/node-machine-id/-/node-machine-id-1.1.12.tgz#37904eee1e59b320bb9c5d6c0a59f3b469cb6267" + integrity sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ== + node-releases@^2.0.12: version "2.0.12" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.12.tgz#35627cc224a23bfb06fb3380f2b3afaaa7eb1039" @@ -7283,6 +8123,11 @@ ob1@0.73.9: resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.73.9.tgz#d5677a0dd3e2f16ad84231278d79424436c38c59" integrity sha512-kHOzCOFXmAM26fy7V/YuXNKne2TyRiXbFAvPBIbuedJCZZWQZHLdPzMeXJI4Egt6IcfDttRzN3jQ90wOwq1iNw== +ob1@0.76.8: + version "0.76.8" + resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.76.8.tgz#ac4c459465b1c0e2c29aaa527e09fc463d3ffec8" + integrity sha512-dlBkJJV5M/msj9KYA9upc+nUWVwuOFFTbu28X6kZeGwcuW+JxaHSBZ70SYQnk5M+j5JbNLR6yKHmgW4M5E7X5g== + object-assign@4.x, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -7636,6 +8481,24 @@ postcss-value-parser@^4.0.2: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== +prebuild-install@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" + integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -7677,6 +8540,15 @@ pretty-format@^29.0.0, pretty-format@^29.5.0: ansi-styles "^5.0.0" react-is "^18.0.0" +pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== + dependencies: + "@jest/schemas" "^29.6.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -7799,6 +8671,13 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +queue@6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/queue/-/queue-6.0.2.tgz#b91525283e2315c7553d2efa18d83e76432fed65" + integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA== + dependencies: + inherits "~2.0.3" + ramda@^0.27.2: version "0.27.2" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.2.tgz#84463226f7f36dc33592f6f4ed6374c48306c3f1" @@ -7820,6 +8699,16 @@ rc-util@^4.21.1: react-lifecycles-compat "^3.0.4" shallowequal "^1.1.0" +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + react-devtools-core@^4.26.1: version "4.27.8" resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.27.8.tgz#b7b387b079c14ae9a214d4846a402da2b6efd164" @@ -7828,6 +8717,14 @@ react-devtools-core@^4.26.1: shell-quote "^1.6.1" ws "^7" +react-devtools-core@^4.27.2: + version "4.28.0" + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.28.0.tgz#3fa18709b24414adddadac33b6b9cea96db60f2f" + integrity sha512-E3C3X1skWBdBzwpOUbmXG8SgH6BtsluSMe+s6rRcujNKG1DGi8uIfhdhszkgDpAsMoE55hwqRUzeXCmETDBpTg== + dependencies: + shell-quote "^1.6.1" + ws "^7" + react-freeze@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/react-freeze/-/react-freeze-1.0.3.tgz#5e3ca90e682fed1d73a7cb50c2c7402b3e85618d" @@ -8135,6 +9032,48 @@ react-native@0.71.10: whatwg-fetch "^3.0.0" ws "^6.2.2" +react-native@>=0.68: + version "0.72.5" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.72.5.tgz#2c343fa6f3ead362cf07376634a33a4078864357" + integrity sha512-oIewslu5DBwOmo7x5rdzZlZXCqDIna0R4dUwVpfmVteORYLr4yaZo5wQnMeR+H7x54GaMhmgeqp0ZpULtulJFg== + dependencies: + "@jest/create-cache-key-function" "^29.2.1" + "@react-native-community/cli" "11.3.7" + "@react-native-community/cli-platform-android" "11.3.7" + "@react-native-community/cli-platform-ios" "11.3.7" + "@react-native/assets-registry" "^0.72.0" + "@react-native/codegen" "^0.72.7" + "@react-native/gradle-plugin" "^0.72.11" + "@react-native/js-polyfills" "^0.72.1" + "@react-native/normalize-colors" "^0.72.0" + "@react-native/virtualized-lists" "^0.72.8" + abort-controller "^3.0.0" + anser "^1.4.9" + base64-js "^1.1.2" + deprecated-react-native-prop-types "4.1.0" + event-target-shim "^5.0.1" + flow-enums-runtime "^0.0.5" + invariant "^2.2.4" + jest-environment-node "^29.2.1" + jsc-android "^250231.0.0" + memoize-one "^5.0.0" + metro-runtime "0.76.8" + metro-source-map "0.76.8" + mkdirp "^0.5.1" + nullthrows "^1.1.1" + pretty-format "^26.5.2" + promise "^8.3.0" + react-devtools-core "^4.27.2" + react-refresh "^0.4.0" + react-shallow-renderer "^16.15.0" + regenerator-runtime "^0.13.2" + scheduler "0.24.0-canary-efb381bbf-20230505" + stacktrace-parser "^0.1.10" + use-sync-external-store "^1.0.0" + whatwg-fetch "^3.0.0" + ws "^6.2.2" + yargs "^17.6.2" + react-refresh@^0.4.0: version "0.4.3" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.3.tgz#966f1750c191672e76e16c2efa569150cc73ab53" @@ -8164,7 +9103,7 @@ react@18.2.0: dependencies: loose-envify "^1.1.0" -readable-stream@^3.4.0, readable-stream@^3.6.0: +readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -8191,6 +9130,17 @@ readline@^1.3.0: resolved "https://registry.yarnpkg.com/readline/-/readline-1.3.0.tgz#c580d77ef2cfc8752b132498060dc9793a7ac01c" integrity sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg== +realm@^12.2.0: + version "12.2.0" + resolved "https://registry.yarnpkg.com/realm/-/realm-12.2.0.tgz#a1758b5051bb6996bce90492cf94b6030ca7950d" + integrity sha512-4MFmWWl5eARaU0toMGX6cjgSX53/4jLNoHyc3UN30bXoTPKw3JVAsL070GM+Ywuhl4D5ubFZOU4y+x+r9vDgew== + dependencies: + bson "^4.7.2" + debug "^4.3.4" + node-fetch "^2.6.9" + node-machine-id "^1.1.12" + prebuild-install "^7.1.1" + recast@^0.20.3, recast@^0.20.4: version "0.20.5" resolved "https://registry.yarnpkg.com/recast/-/recast-0.20.5.tgz#8e2c6c96827a1b339c634dd232957d230553ceae" @@ -8201,6 +9151,16 @@ recast@^0.20.3, recast@^0.20.4: source-map "~0.6.1" tslib "^2.0.1" +recast@^0.21.0: + version "0.21.5" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.21.5.tgz#e8cd22bb51bcd6130e54f87955d33a2b2e57b495" + integrity sha512-hjMmLaUXAm1hIuTqOdeYObMslq/q+Xff6QE3Y2P+uoHAg2nmVlLBps2hzh1UJDdMtDTMXOFewK6ky51JQIeECg== + dependencies: + ast-types "0.15.2" + esprima "~4.0.0" + source-map "~0.6.1" + tslib "^2.0.1" + reflect-metadata@^0.1.13: version "0.1.13" resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" @@ -8228,6 +9188,11 @@ regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.2: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + regenerator-transform@^0.15.1: version "0.15.1" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.1.tgz#f6c4e99fc1b4591f780db2586328e4d9a9d8dc56" @@ -8396,11 +9361,6 @@ rn-fetch-blob@^0.12.0: base-64 "0.1.0" glob "7.0.6" -rn-secure-storage@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/rn-secure-storage/-/rn-secure-storage-2.0.8.tgz#ccdb0aa3e69239b77fecc3a3dee88ddfa46371e3" - integrity sha512-byk51qL+4GNfaBxs30TZsv3l1vXRry8Pck3q2xzwNUYfSyEdTn8NnCW2l8hOog0XEGCJdfbeFy5+EgCVnMsRAQ== - run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -8420,7 +9380,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@~5.2.0: +safe-buffer@^5.0.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -8453,6 +9413,13 @@ saxes@^5.0.1: dependencies: xmlchars "^2.2.0" +scheduler@0.24.0-canary-efb381bbf-20230505: + version "0.24.0-canary-efb381bbf-20230505" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.24.0-canary-efb381bbf-20230505.tgz#5dddc60e29f91cd7f8b983d7ce4a99c2202d178f" + integrity sha512-ABvovCDe/k9IluqSh4/ISoq8tIJnW8euVAWYt5j/bg6dRnqwQwiGO1F/V4AyK96NGF/FB04FhOUDuWj8IKfABA== + dependencies: + loose-envify "^1.1.0" + scheduler@^0.23.0: version "0.23.0" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" @@ -8477,6 +9444,13 @@ semver@^7.3.5, semver@^7.3.7: dependencies: lru-cache "^6.0.0" +semver@^7.5.2: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + send@0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" @@ -8612,6 +9586,15 @@ simple-get@^3.0.3: once "^1.3.1" simple-concat "^1.0.0" +simple-get@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" @@ -8754,7 +9737,7 @@ stackframe@^1.3.4: resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== -stacktrace-parser@^0.1.3: +stacktrace-parser@^0.1.10, stacktrace-parser@^0.1.3: version "0.1.10" resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== @@ -8914,6 +9897,11 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + strnum@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" @@ -8973,6 +9961,27 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +tar-fs@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + tar@^6.1.11: version "6.1.15" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.15.tgz#c9738b0b98845a3b344d334b8fa3041aaba53a69" @@ -9135,6 +10144,13 @@ tsyringe@^4.7.0: dependencies: tslib "^1.9.3" +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -9638,6 +10654,11 @@ yaml@^1.10.0: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yaml@^2.2.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.2.tgz#f522db4313c671a0ca963a75670f1c12ea909144" + integrity sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg== + yargs-parser@^18.1.2: version "18.1.3" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" @@ -9686,7 +10707,7 @@ yargs@^16.1.1: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@^17.3.1, yargs@^17.5.1: +yargs@^17.3.1, yargs@^17.5.1, yargs@^17.6.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==