From a5d199404fd3a23535a4918cd782d2ac0907b7fd Mon Sep 17 00:00:00 2001 From: KoalaSat Date: Wed, 26 Jun 2024 18:42:48 +0200 Subject: [PATCH 1/2] New Tor engine Android test --- android/app/build.gradle | 5 +- .../src/main/java/com/zeus/MainApplication.kt | 2 +- .../app/src/main/java/com/zeus/TorMobile.java | 138 +++++++ .../main/java/com/zeus/TorMobilePackage.java | 22 + .../main/java/com/zeus/tor/EnumTorState.kt | 8 + .../main/java/com/zeus/tor/TorKmpManager.kt | 389 ++++++++++++++++++ .../src/main/java/com/zeus/tor/TorState.kt | 14 + package.json | 1 - patches/patch-sifir_android.mjs | 31 -- tormobile/index.ts | 17 + utils/TorUtils.ts | 59 +-- 11 files changed, 614 insertions(+), 72 deletions(-) create mode 100644 android/app/src/main/java/com/zeus/TorMobile.java create mode 100644 android/app/src/main/java/com/zeus/TorMobilePackage.java create mode 100644 android/app/src/main/java/com/zeus/tor/EnumTorState.kt create mode 100644 android/app/src/main/java/com/zeus/tor/TorKmpManager.kt create mode 100644 android/app/src/main/java/com/zeus/tor/TorState.kt delete mode 100644 patches/patch-sifir_android.mjs create mode 100644 tormobile/index.ts diff --git a/android/app/build.gradle b/android/app/build.gradle index 17d87b92f..cd2d3ce9f 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -188,7 +188,6 @@ dependencies { implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01' - implementation files("../../node_modules/react-native-tor/android/libs/sifir_android.aar") // gif implementation 'com.facebook.fresco:fresco:3.1.3' implementation 'com.facebook.fresco:animated-gif:3.1.3' @@ -214,10 +213,14 @@ dependencies { // implementation 'info.guardianproject:tor-android:0.4.7.8' // implementation 'info.guardianproject:jtorctl:0.4.5.7' + implementation "io.matthewnelson.kotlin-components:kmp-tor:4.8.10-0-1.4.4" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2" implementation('dev.doubledot.doki:library:0.0.1@aar') { transitive = true } + } configurations { diff --git a/android/app/src/main/java/com/zeus/MainApplication.kt b/android/app/src/main/java/com/zeus/MainApplication.kt index 189f187d7..602358bd1 100644 --- a/android/app/src/main/java/com/zeus/MainApplication.kt +++ b/android/app/src/main/java/com/zeus/MainApplication.kt @@ -29,7 +29,7 @@ class MainApplication : Application(), ReactApplication { add(LndMobileToolsPackage()) add(LndMobileScheduledSyncPackage()) add(LncPackage()) - // add(new ZeusTorPackage()); + add(TorMobilePackage()); } override fun getJSMainModuleName(): String = "index" diff --git a/android/app/src/main/java/com/zeus/TorMobile.java b/android/app/src/main/java/com/zeus/TorMobile.java new file mode 100644 index 000000000..9ff99f997 --- /dev/null +++ b/android/app/src/main/java/com/zeus/TorMobile.java @@ -0,0 +1,138 @@ +package app.zeusln.zeus; + +import android.util.Log; + +import androidx.annotation.NonNull; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.modules.core.DeviceEventManagerModule; +import io.bluewallet.bluewallet.tor.TorKmpManager; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + + +public class TorMobile extends ReactContextBaseJavaModule { + private final String TAG = "TorMobile"; + private TorKmpManager torKmpManager; + private ReactApplicationContext context; + public TorMobile(ReactApplicationContext reactContext) { + context = reactContext; + } + + @Override + public String getName() { + return "TorMobile"; + } + + @ReactMethod + public void sendRequest(String action, String url, String headers, String body, final Promise promise) throws JSONException { + OkHttpClient client = new OkHttpClient.Builder() + .connectTimeout(60, TimeUnit.SECONDS) // Set connection timeout + .readTimeout(30, TimeUnit.SECONDS) // Set read timeout + .proxy(torKmpManager.getProxy()).build(); + + Request.Builder requestBuilder = new Request.Builder().url(url); + + JSONObject headersObject = new JSONObject(headers); + headersObject.keys().forEachRemaining(key -> { + String value = headersObject.optString(key); + requestBuilder.addHeader(key, value); + }); + + if (Objects.equals(action, "DELETE")) { + requestBuilder.delete(); + } else if (Objects.equals(action, "POST")) { + RequestBody requestBody = RequestBody.create(body, MediaType.get("application/json; charset=utf-8")); + requestBuilder.post(requestBody); + } else { + requestBuilder.get(); + } + + Request request = requestBuilder.build(); + client.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(@NonNull Call call, @NonNull IOException e) { + Log.d(TAG, e.toString()); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + String body = response.body() != null ? response.body().string() : "{}"; + JSONObject headersJson = new JSONObject(); + response.headers().names().forEach(name -> { + try { + headersJson.put(name, response.header(name)); + } catch (JSONException e) { + throw new RuntimeException(e); + } + }); + promise.resolve("{\"json\":" + body + ", \"headers\": " + headersJson +"}"); + } + }); + } + + @ReactMethod(isBlockingSynchronousMethod = true) + public String getTorStatus() { + return torKmpManager.getTorState().getState().name(); + } + + @ReactMethod + public void stop(Promise promise) { + try { + torKmpManager.getTorOperationManager().stopQuietly(); + promise.resolve(true); + } catch (Exception e) { + promise.reject("ERROR_CODE", e); + } + } + + @ReactMethod + public void start(Promise promise) { + try { + torKmpManager = new TorKmpManager(context.getCurrentActivity().getApplication()); + torKmpManager.getTorOperationManager().startQuietly(); + promise.resolve(true); + } catch (Exception e) { + promise.reject("ERROR_CODE", e); + } + } + + @ReactMethod + public void restart(Promise promise) { + try { + torKmpManager = new TorKmpManager(context.getCurrentActivity().getApplication()); + torKmpManager.getTorOperationManager().restartQuietly(); + promise.resolve(true); + } catch (Exception e) { + promise.reject("ERROR_CODE", e); + } + } + + @ReactMethod + public void newIdentity(Promise promise) { + try { + torKmpManager.newIdentity(context.getCurrentActivity().getApplication()); + promise.resolve(true); + } catch (Exception e) { + promise.reject("ERROR_CODE", e); + } + } +} diff --git a/android/app/src/main/java/com/zeus/TorMobilePackage.java b/android/app/src/main/java/com/zeus/TorMobilePackage.java new file mode 100644 index 000000000..74a4ab110 --- /dev/null +++ b/android/app/src/main/java/com/zeus/TorMobilePackage.java @@ -0,0 +1,22 @@ +package app.zeusln.zeus; + +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.Arrays; +import java.util.Collections; +import java.util.List; + +public class TorMobilePackage implements ReactPackage { + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } + + @Override + public List createNativeModules(ReactApplicationContext reactContext) { + return Arrays.asList(new TorMobile(reactContext)); + } +} diff --git a/android/app/src/main/java/com/zeus/tor/EnumTorState.kt b/android/app/src/main/java/com/zeus/tor/EnumTorState.kt new file mode 100644 index 000000000..fdc1e7458 --- /dev/null +++ b/android/app/src/main/java/com/zeus/tor/EnumTorState.kt @@ -0,0 +1,8 @@ +package io.bluewallet.bluewallet.tor + +enum class EnumTorState { + STARTING, + ON, + STOPPING, + OFF +} \ No newline at end of file diff --git a/android/app/src/main/java/com/zeus/tor/TorKmpManager.kt b/android/app/src/main/java/com/zeus/tor/TorKmpManager.kt new file mode 100644 index 000000000..0d758fe14 --- /dev/null +++ b/android/app/src/main/java/com/zeus/tor/TorKmpManager.kt @@ -0,0 +1,389 @@ +package io.bluewallet.bluewallet.tor + +import android.app.Application +import android.util.Log +import android.widget.Toast +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import io.matthewnelson.kmp.tor.KmpTorLoaderAndroid +import io.matthewnelson.kmp.tor.TorConfigProviderAndroid +import io.matthewnelson.kmp.tor.common.address.* +import io.matthewnelson.kmp.tor.controller.common.config.TorConfig +import io.matthewnelson.kmp.tor.controller.common.config.TorConfig.Option.* +import io.matthewnelson.kmp.tor.controller.common.config.TorConfig.Setting.* +import io.matthewnelson.kmp.tor.controller.common.control.usecase.TorControlInfoGet +import io.matthewnelson.kmp.tor.controller.common.control.usecase.TorControlSignal +import io.matthewnelson.kmp.tor.controller.common.events.TorEvent +import io.matthewnelson.kmp.tor.manager.TorManager +import io.matthewnelson.kmp.tor.manager.TorServiceConfig +import io.matthewnelson.kmp.tor.manager.common.TorControlManager +import io.matthewnelson.kmp.tor.manager.common.TorOperationManager +import io.matthewnelson.kmp.tor.manager.common.event.TorManagerEvent +import io.matthewnelson.kmp.tor.manager.common.state.isOff +import io.matthewnelson.kmp.tor.manager.common.state.isOn +import io.matthewnelson.kmp.tor.manager.common.state.isStarting +import io.matthewnelson.kmp.tor.manager.common.state.isStopping +import io.matthewnelson.kmp.tor.manager.R +import kotlinx.coroutines.* +import java.net.InetSocketAddress +import java.net.Proxy + +class TorKmpManager(application : Application) { + + private val TAG = "TorListener" + + private val providerAndroid by lazy { + object : TorConfigProviderAndroid(context = application) { + override fun provide(): TorConfig { + return TorConfig.Builder { + // Set multiple ports for all of the things + val dns = Ports.Dns() + put(dns.set(AorDorPort.Value(PortProxy(9252)))) + put(dns.set(AorDorPort.Value(PortProxy(9253)))) + + val socks = Ports.Socks() + put(socks.set(AorDorPort.Value(PortProxy(9254)))) + put(socks.set(AorDorPort.Value(PortProxy(9255)))) + + val http = Ports.HttpTunnel() + put(http.set(AorDorPort.Value(PortProxy(9258)))) + put(http.set(AorDorPort.Value(PortProxy(9259)))) + + val trans = Ports.Trans() + put(trans.set(AorDorPort.Value(PortProxy(9262)))) + put(trans.set(AorDorPort.Value(PortProxy(9263)))) + + // If a port (9263) is already taken (by ^^^^ trans port above) + // this will take its place and "overwrite" the trans port entry + // because port 9263 is taken. + put(socks.set(AorDorPort.Value(PortProxy(9263)))) + + // Set Flags + socks.setFlags(setOf( + Ports.Socks.Flag.OnionTrafficOnly + )).setIsolationFlags(setOf( + Ports.IsolationFlag.IsolateClientAddr, + )).set(AorDorPort.Value(PortProxy(9264))) + put(socks) + + // reset our socks object to defaults + socks.setDefault() + + // Not necessary, as if ControlPort is missing it will be + // automatically added for you; but for demonstration purposes... +// put(Ports.Control().set(AorDorPort.Auto)) + + // Use a UnixSocket instead of TCP for the ControlPort. + // + // A unix domain socket will always be preferred on Android + // if neither Ports.Control or UnixSockets.Control are provided. + put(UnixSockets.Control().set(FileSystemFile( + workDir.builder { + + // Put the file in the "data" directory + // so that we avoid any directory permission + // issues. + // + // Note that DataDirectory is automatically added + // for you if it is not present in your provided + // config. If you set a custom Path for it, you + // should use it here. + addSegment(DataDirectory.DEFAULT_NAME) + + addSegment(UnixSockets.Control.DEFAULT_NAME) + } + ))) + + // Use a UnixSocket instead of TCP for the SocksPort. + put(UnixSockets.Socks().set(FileSystemFile( + workDir.builder { + + // Put the file in the "data" directory + // so that we avoid any directory permission + // issues. + // + // Note that DataDirectory is automatically added + // for you if it is not present in your provided + // config. If you set a custom Path for it, you + // should use it here. + addSegment(DataDirectory.DEFAULT_NAME) + + addSegment(UnixSockets.Socks.DEFAULT_NAME) + } + ))) + + // For Android, disabling & reducing connection padding is + // advisable to minimize mobile data usage. + put(ConnectionPadding().set(AorTorF.False)) + put(ConnectionPaddingReduced().set(TorF.True)) + + // Tor default is 24h. Reducing to 10 min helps mitigate + // unnecessary mobile data usage. + put(DormantClientTimeout().set(Time.Minutes(10))) + + // Tor defaults this setting to false which would mean if + // Tor goes dormant, the next time it is started it will still + // be in the dormant state and will not bootstrap until being + // set to "active". This ensures that if it is a fresh start, + // dormancy will be cancelled automatically. + put(DormantCanceledByStartup().set(TorF.True)) + + // If planning to use v3 Client Authentication in a persistent + // manner (where private keys are saved to disk via the "Persist" + // flag), this is needed to be set. + put(ClientOnionAuthDir().set(FileSystemDir( + workDir.builder { addSegment(ClientOnionAuthDir.DEFAULT_NAME) } + ))) + + val hsPath = workDir.builder { + addSegment(HiddenService.DEFAULT_PARENT_DIR_NAME) + addSegment("test_service") + } + // Add Hidden services + put(HiddenService() + .setPorts(ports = setOf( + // Use a unix domain socket to communicate via IPC instead of over TCP + HiddenService.UnixSocket(virtualPort = Port(80), targetUnixSocket = hsPath.builder { + addSegment(HiddenService.UnixSocket.DEFAULT_UNIX_SOCKET_NAME) + }), + )) + .setMaxStreams(maxStreams = HiddenService.MaxStreams(value = 2)) + .setMaxStreamsCloseCircuit(value = TorF.True) + .set(FileSystemDir(path = hsPath)) + ) + + put(HiddenService() + .setPorts(ports = setOf( + HiddenService.Ports(virtualPort = Port(80), targetPort = Port(1030)), // http + HiddenService.Ports(virtualPort = Port(443), targetPort = Port(1030)) // https + )) + .set(FileSystemDir(path = + workDir.builder { + addSegment(HiddenService.DEFAULT_PARENT_DIR_NAME) + addSegment("test_service_2") + } + )) + ) + }.build() + } + } + } + + private val loaderAndroid by lazy { + KmpTorLoaderAndroid(provider = providerAndroid) + } + + private val manager: TorManager by lazy { + TorManager.newInstance(application = application, loader = loaderAndroid, requiredEvents = null) + } + + // only expose necessary interfaces + val torOperationManager: TorOperationManager get() = manager + val torControlManager: TorControlManager get() = manager + + private val listener = TorListener() + + val events: LiveData get() = listener.eventLines + + private val appScope by lazy { + CoroutineScope(Dispatchers.Main.immediate + SupervisorJob()) + } + + val torStateLiveData: MutableLiveData = MutableLiveData() + get() = field + var torState: TorState = TorState() + get() = field + + var proxy: Proxy? = null + get() = field + + init { + manager.debug(true) + manager.addListener(listener) + listener.addLine(TorServiceConfig.getMetaData(application).toString()) + } + + fun isConnected(): Boolean { + return manager.state.isOn() && manager.state.bootstrap >= 100 + } + + fun isStarting(): Boolean { + return manager.state.isStarting() || + (manager.state.isOn() && manager.state.bootstrap < 100); + } + + + fun newIdentity(appContext: Application) { + appScope.launch { + val result = manager.signal(TorControlSignal.Signal.NewNym) + result.onSuccess { + if (it !is String) { + listener.addLine(TorControlSignal.NEW_NYM_SUCCESS) + Toast.makeText(appContext, TorControlSignal.NEW_NYM_SUCCESS, Toast.LENGTH_SHORT).show() + return@onSuccess + } + + val post: String? = when { + it.startsWith(TorControlSignal.NEW_NYM_RATE_LIMITED) -> { + // Rate limiting NEWNYM request: delaying by 8 second(s) + val seconds: Int? = it.drop(TorControlSignal.NEW_NYM_RATE_LIMITED.length) + .substringBefore(' ') + .toIntOrNull() + + if (seconds == null) { + it + } else { + appContext.getString( + R.string.kmp_tor_newnym_rate_limited, + seconds + ) + } + } + it == TorControlSignal.NEW_NYM_SUCCESS -> { + appContext.getString(R.string.kmp_tor_newnym_success) + } + else -> { + null + } + } + + if (post != null) { + listener.addLine(post) + Toast.makeText(appContext, post, Toast.LENGTH_SHORT).show() + } + } + result.onFailure { + val msg = "Tor identity change failed" + listener.addLine(msg) + Toast.makeText(appContext, msg, Toast.LENGTH_SHORT).show() + } + } + } + + + private inner class TorListener: TorManagerEvent.Listener() { + private val _eventLines: MutableLiveData = MutableLiveData("") + val eventLines: LiveData = _eventLines + private val events: MutableList = ArrayList(50) + fun addLine(line: String) { + synchronized(this) { + if (events.size > 49) { + events.removeAt(0) + } + events.add(line) + //Log.i(TAG, line) + //_eventLines.value = events.joinToString("\n") + _eventLines.postValue(events.joinToString("\n")) + } + } + + override fun onEvent(event: TorManagerEvent) { + + if (event is TorManagerEvent.State) { + val stateEvent: TorManagerEvent.State = event + val state = stateEvent.torState + torState.progressIndicator = state.bootstrap + val liveTorState = TorState() + liveTorState.progressIndicator = state.bootstrap + + if (state.isOn()) { + if (state.bootstrap >= 100) { + torState.state = EnumTorState.ON + liveTorState.state = EnumTorState.ON + } else { + torState.state = EnumTorState.STARTING + liveTorState.state = EnumTorState.STARTING + } + } else if (state.isStarting()) { + torState.state = EnumTorState.STARTING + liveTorState.state = EnumTorState.STARTING + } else if (state.isOff()) { + torState.state = EnumTorState.OFF + liveTorState.state = EnumTorState.OFF + } else if (state.isStopping()) { + torState.state = EnumTorState.STOPPING + liveTorState.state = EnumTorState.STOPPING + } + torStateLiveData.postValue(liveTorState) + } + addLine(event.toString()) + super.onEvent(event) + } + + override fun onEvent(event: TorEvent.Type.SingleLineEvent, output: String) { + addLine("$event - $output") + + super.onEvent(event, output) + } + + override fun onEvent(event: TorEvent.Type.MultiLineEvent, output: List) { + addLine("multi-line event: $event. See Logs.") + + // these events are many many many lines and should be moved + // off the main thread if ever needed to be dealt with. + val enabled = false + if (enabled) { + appScope.launch(Dispatchers.IO) { + Log.d(TAG, "-------------- multi-line event START: $event --------------") + for (line in output) { + Log.d(TAG, line) + } + Log.d(TAG, "--------------- multi-line event END: $event ---------------") + } + } + + super.onEvent(event, output) + } + + override fun managerEventError(t: Throwable) { + t.printStackTrace() + } + + override fun managerEventAddressInfo(info: TorManagerEvent.AddressInfo) { + if (info.isNull) { + // Tear down HttpClient + } else { + info.socksInfoToProxyAddressOrNull()?.firstOrNull()?.let { proxyAddress -> + @Suppress("UNUSED_VARIABLE") + val socket = InetSocketAddress(proxyAddress.address.value, proxyAddress.port.value) + proxy = Proxy(Proxy.Type.SOCKS, socket) + } + } + } + + override fun managerEventStartUpCompleteForTorInstance() { + // Do one-time things after we're bootstrapped + + appScope.launch { + torControlManager.onionAddNew( + type = OnionAddress.PrivateKey.Type.ED25519_V3, + hsPorts = setOf(HiddenService.Ports(virtualPort = Port(443))), + flags = null, + maxStreams = null, + ).onSuccess { hsEntry -> + addLine( + "New HiddenService: " + + "\n - Address: https://${hsEntry.address.canonicalHostname()}" + + "\n - PrivateKey: ${hsEntry.privateKey}" + ) + + torControlManager.onionDel(hsEntry.address).onSuccess { + addLine("Aaaaaaaaand it's gone...") + }.onFailure { t -> + t.printStackTrace() + } + }.onFailure { t -> + t.printStackTrace() + } + + delay(20_000L) + + torControlManager.infoGet(TorControlInfoGet.KeyWord.Uptime()).onSuccess { uptime -> + addLine("Uptime - $uptime") + }.onFailure { t -> + t.printStackTrace() + } + } + } + } +} diff --git a/android/app/src/main/java/com/zeus/tor/TorState.kt b/android/app/src/main/java/com/zeus/tor/TorState.kt new file mode 100644 index 000000000..fdf867239 --- /dev/null +++ b/android/app/src/main/java/com/zeus/tor/TorState.kt @@ -0,0 +1,14 @@ +package io.bluewallet.bluewallet.tor + +class TorState { + var state : EnumTorState = EnumTorState.OFF + get() = field + set(value) { + field = value + } + var progressIndicator : Int = 0 + get() = field + set(value) { + field = value + } +} \ No newline at end of file diff --git a/package.json b/package.json index e452616be..818ca924e 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,6 @@ "react-native-svg-transformer": "1.3.0", "react-native-system-navigation-bar": "2.6.4", "react-native-tcp": "aprock/react-native-tcp#be5f656", - "react-native-tor": "0.1.8", "react-native-udp": "4.1.7", "react-native-v8": "0.61.5-patch.4", "react-native-vector-icons": "7.1.0", diff --git a/patches/patch-sifir_android.mjs b/patches/patch-sifir_android.mjs deleted file mode 100644 index aef41591c..000000000 --- a/patches/patch-sifir_android.mjs +++ /dev/null @@ -1,31 +0,0 @@ -// This might be removed when this issue is fixed: https://github.com/Sifir-io/react-native-tor/issues/57 - -import compressing from 'compressing'; -import fs from 'fs'; - -console.log('Removing unsupported arm64 JNI from sifir_android'); - -(async () => { - await compressing.zip.uncompress( - './node_modules/react-native-tor/android/libs/sifir_android.aar', - './node_modules/react-native-tor/android/libs/sifir_android' - ); - - fs.rmSync( - './node_modules/react-native-tor/android/libs/sifir_android/jni/arm64', - { force: true, recursive: true } - ); - - fs.rmSync('./node_modules/react-native-tor/android/libs/sifir_android.aar'); - - await compressing.zip.compressDir( - './node_modules/react-native-tor/android/libs/sifir_android', - './node_modules/react-native-tor/android/libs/sifir_android.aar', - { ignoreBase: true } - ); - - fs.rmSync('./node_modules/react-native-tor/android/libs/sifir_android', { - force: true, - recursive: true - }); -})(); diff --git a/tormobile/index.ts b/tormobile/index.ts new file mode 100644 index 000000000..c96e64f9e --- /dev/null +++ b/tormobile/index.ts @@ -0,0 +1,17 @@ +import { NativeModules } from 'react-native'; +const { TorMobile } = NativeModules; + +interface TorMobileInterface { + start: () => Promise; + restart: () => Promise; + stop: () => Promise; + getTorStatus: () => string; + sendRequest: ( + action: string, + url: string, + headers: string, + body: string + ) => Promise; +} + +export default TorMobile as TorMobileInterface; diff --git a/utils/TorUtils.ts b/utils/TorUtils.ts index 22df51a8b..fe4051a3d 100644 --- a/utils/TorUtils.ts +++ b/utils/TorUtils.ts @@ -1,43 +1,26 @@ -import Tor, { RequestMethod } from 'react-native-tor'; -const tor = Tor(); -const doTorRequest = async ( +import TorMobile from '../tormobile'; + +declare enum RequestMethod { + 'GET' = 'GET', + 'POST' = 'POST', + 'DELETE' = 'DELETE' +} + +const doTorRequest = async ( url: string, - method: T, - data?: string, - headers?: any, - trustSSL = true + method: RequestMethod, + body?: string, + headers?: any ) => { - await tor.startIfNotStarted(); - switch (method.toLowerCase()) { - case RequestMethod.GET: - const getResult = await tor.get(url, headers, trustSSL); - if (getResult.json) { - return getResult.json; - } - break; - case RequestMethod.POST: - const postResult = await tor.post( - url, - data || '', - headers, - trustSSL - ); - if (postResult.json) { - return postResult.json; - } - break; - case RequestMethod.DELETE: - const deleteResult = await tor.delete(url, data, headers, trustSSL); - if (deleteResult.json) { - return deleteResult.json; - } - break; - } -}; + await TorMobile.start(); + const result = await TorMobile.sendRequest( + method.toUpperCase(), + url, + JSON.stringify(headers ?? {}), + body ?? '' + ); -const restartTor = async () => { - await tor.stopIfRunning(); - await tor.startIfNotStarted(); + return JSON.parse(result).json; }; -export { doTorRequest, restartTor, RequestMethod }; +export { doTorRequest, RequestMethod }; From c95b28235893eb3f377ebb7b6fa692070ebc5603 Mon Sep 17 00:00:00 2001 From: KoalaSat Date: Wed, 26 Jun 2024 19:02:19 +0200 Subject: [PATCH 2/2] .lock file --- yarn.lock | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/yarn.lock b/yarn.lock index efa4642a0..68828f6a4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2756,11 +2756,6 @@ resolved "https://registry.yarnpkg.com/@types/aes-js/-/aes-js-3.1.4.tgz#90afb62e69b0365a392d2e79579a6f424b772792" integrity sha512-v3D66IptpUqh+pHKVNRxY8yvp2ESSZXe0rTzsGdzUhEwag7ljVfgCllkWv2YgiYXDhWFBrEywll4A5JToyTNFA== -"@types/async@^3.2.6": - version "3.2.24" - resolved "https://registry.yarnpkg.com/@types/async/-/async-3.2.24.tgz#3a96351047575bbcf2340541b2d955a35339608f" - integrity sha512-8iHVLHsCCOBKjCF2KwFe0p9Z3rfM9mL+sSP8btyR5vTjJRAqpBYD28/ZLgXPf0pjG1VxOvtCV/BgXkQbpSe8Hw== - "@types/babel__core@^7.1.14": version "7.20.5" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" @@ -3564,11 +3559,6 @@ async-limiter@~1.0.0: resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== -async@^3.2.0: - version "3.2.5" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" - integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== - available-typed-arrays@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" @@ -8878,14 +8868,6 @@ react-native-tcp@aprock/react-native-tcp#be5f656: process "^0.11.9" util "^0.12.1" -react-native-tor@0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/react-native-tor/-/react-native-tor-0.1.8.tgz#7e888aecaeb69aae5da2348639e761b6ee97c1a2" - integrity sha512-rRArwpqTQoUrQ3WQxc1WLkk1Eg/yjiwU775AxnSt6E7Nfy1V9H6+R9reMD5PJ/39qcuDYv3F7i3MR8Rjy7lOZA== - dependencies: - "@types/async" "^3.2.6" - async "^3.2.0" - react-native-udp@4.1.7: version "4.1.7" resolved "https://registry.yarnpkg.com/react-native-udp/-/react-native-udp-4.1.7.tgz#9fa90b772b44c991605e8191444dd2ca3259cb58"