diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/AppModules.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/AppModules.kt index 32ac66ea1..d2cb4db87 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/AppModules.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/AppModules.kt @@ -26,6 +26,7 @@ import coil3.disk.DiskCache import coil3.memory.MemoryCache import com.vitorpamplona.amethyst.commons.model.NoteState import com.vitorpamplona.amethyst.commons.robohash.CachedRobohash +import com.vitorpamplona.amethyst.commons.tor.TorSettings import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.UiSettings @@ -72,7 +73,6 @@ import com.vitorpamplona.amethyst.ui.resourceCacheInit import com.vitorpamplona.amethyst.ui.screen.AccountSessionManager import com.vitorpamplona.amethyst.ui.screen.UiSettingsState import com.vitorpamplona.amethyst.ui.tor.TorManager -import com.vitorpamplona.amethyst.ui.tor.TorSettings import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/preferences/TorSharedPreferences.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/preferences/TorSharedPreferences.kt index 0bb4d80f6..f1ea5ed91 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/preferences/TorSharedPreferences.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/preferences/TorSharedPreferences.kt @@ -26,9 +26,9 @@ import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.intPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey -import com.vitorpamplona.amethyst.ui.tor.TorSettings +import com.vitorpamplona.amethyst.commons.tor.TorSettings +import com.vitorpamplona.amethyst.commons.tor.TorType import com.vitorpamplona.amethyst.ui.tor.TorSettingsFlow -import com.vitorpamplona.amethyst.ui.tor.TorType import com.vitorpamplona.quartz.utils.Log import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/privacyOptions/RoleBasedHttpClientBuilder.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/privacyOptions/RoleBasedHttpClientBuilder.kt index daea244bb..a332044be 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/privacyOptions/RoleBasedHttpClientBuilder.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/privacyOptions/RoleBasedHttpClientBuilder.kt @@ -20,9 +20,9 @@ */ package com.vitorpamplona.amethyst.model.privacyOptions +import com.vitorpamplona.amethyst.commons.tor.TorType import com.vitorpamplona.amethyst.service.okhttp.DualHttpClientManager import com.vitorpamplona.amethyst.ui.tor.TorSettingsFlow -import com.vitorpamplona.amethyst.ui.tor.TorType import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer import okhttp3.OkHttpClient import java.net.InetSocketAddress diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/torState/TorRelayEvaluation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/torState/TorRelayEvaluation.kt index 2a956fe0a..1fcdd64ec 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/torState/TorRelayEvaluation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/torState/TorRelayEvaluation.kt @@ -20,7 +20,7 @@ */ package com.vitorpamplona.amethyst.model.torState -import com.vitorpamplona.amethyst.ui.tor.TorType +import com.vitorpamplona.amethyst.commons.tor.TorType import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.isLocalHost import com.vitorpamplona.quartz.nip01Core.relay.normalizer.isOnion diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/torState/TorRelaySettings.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/torState/TorRelaySettings.kt index 4d7d5dc90..1dd025965 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/torState/TorRelaySettings.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/torState/TorRelaySettings.kt @@ -20,7 +20,7 @@ */ package com.vitorpamplona.amethyst.model.torState -import com.vitorpamplona.amethyst.ui.tor.TorType +import com.vitorpamplona.amethyst.commons.tor.TorType data class TorRelaySettings( val torType: TorType = TorType.OFF, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/torState/TorRelayState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/torState/TorRelayState.kt index 48fa7df62..b6822fc21 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/torState/TorRelayState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/torState/TorRelayState.kt @@ -21,9 +21,9 @@ package com.vitorpamplona.amethyst.model.torState import androidx.compose.runtime.Stable +import com.vitorpamplona.amethyst.commons.tor.TorType import com.vitorpamplona.amethyst.service.okhttp.DualHttpClientManager import com.vitorpamplona.amethyst.ui.tor.TorSettingsFlow -import com.vitorpamplona.amethyst.ui.tor.TorType import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index 8d43ec541..af27793ee 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -49,6 +49,7 @@ import com.vitorpamplona.amethyst.commons.model.emphChat.EphemeralChatChannel import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChannel import com.vitorpamplona.amethyst.commons.model.nip53LiveActivities.LiveActivitiesChannel import com.vitorpamplona.amethyst.commons.model.observables.CreatedAtComparator +import com.vitorpamplona.amethyst.commons.tor.TorType import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState import com.vitorpamplona.amethyst.commons.ui.notifications.CardFeedState import com.vitorpamplona.amethyst.logTime @@ -88,7 +89,6 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.CombinedZap import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.eventsync.EventSync import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.tor.TorSettingsFlow -import com.vitorpamplona.amethyst.ui.tor.TorType import com.vitorpamplona.quartz.experimental.ephemChat.chat.RoomId import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryBaseEvent import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryReadingStateEvent diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/privacy/PrivacyOptionsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/privacy/PrivacyOptionsScreen.kt index df8be0587..306447fc5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/privacy/PrivacyOptionsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/privacy/PrivacyOptionsScreen.kt @@ -34,11 +34,11 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.commons.tor.TorSettings import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.topbars.SavingTopBar import com.vitorpamplona.amethyst.ui.tor.PrivacySettingsBody import com.vitorpamplona.amethyst.ui.tor.TorDialogViewModel -import com.vitorpamplona.amethyst.ui.tor.TorSettings import com.vitorpamplona.amethyst.ui.tor.TorSettingsFlow @OptIn(ExperimentalMaterial3Api::class) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/OtsSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/OtsSettingsScreen.kt index 2d33dddee..a6dd80c71 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/OtsSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/OtsSettingsScreen.kt @@ -35,12 +35,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.commons.tor.TorType import com.vitorpamplona.amethyst.model.preferences.OtsSharedPreferences import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.tor.TorSettingsFlow -import com.vitorpamplona.amethyst.ui.tor.TorType import kotlinx.coroutines.launch @OptIn(ExperimentalMaterial3Api::class) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorDialogViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorDialogViewModel.kt index 8db02d322..ffae7081c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorDialogViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorDialogViewModel.kt @@ -24,6 +24,14 @@ import androidx.compose.runtime.Stable import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.ViewModel +import com.vitorpamplona.amethyst.commons.tor.TorPresetType +import com.vitorpamplona.amethyst.commons.tor.TorSettings +import com.vitorpamplona.amethyst.commons.tor.TorType +import com.vitorpamplona.amethyst.commons.tor.torDefaultPreset +import com.vitorpamplona.amethyst.commons.tor.torFullyPrivate +import com.vitorpamplona.amethyst.commons.tor.torOnlyWhenNeededPreset +import com.vitorpamplona.amethyst.commons.tor.torSmallPayloadsPreset +import com.vitorpamplona.amethyst.commons.tor.whichPreset @Stable class TorDialogViewModel : ViewModel() { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorManager.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorManager.kt index fe415a002..a11bf5997 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorManager.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorManager.kt @@ -21,6 +21,7 @@ package com.vitorpamplona.amethyst.ui.tor import android.content.Context +import com.vitorpamplona.amethyst.commons.tor.TorType import com.vitorpamplona.amethyst.model.preferences.TorSharedPreferences import com.vitorpamplona.quartz.utils.Log import kotlinx.coroutines.CoroutineScope diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorSettings.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorSettings.kt index ff1146c70..0268df821 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorSettings.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorSettings.kt @@ -21,138 +21,40 @@ package com.vitorpamplona.amethyst.ui.tor import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.commons.tor.TorPresetType +import com.vitorpamplona.amethyst.commons.tor.TorType -data class TorSettings( - val torType: TorType = TorType.INTERNAL, - val externalSocksPort: Int = 9050, - val onionRelaysViaTor: Boolean = true, - val dmRelaysViaTor: Boolean = true, - val newRelaysViaTor: Boolean = true, - val trustedRelaysViaTor: Boolean = false, - val urlPreviewsViaTor: Boolean = false, - val profilePicsViaTor: Boolean = false, - val imagesViaTor: Boolean = false, - val videosViaTor: Boolean = false, - val moneyOperationsViaTor: Boolean = false, - val nip05VerificationsViaTor: Boolean = false, - val mediaUploadsViaTor: Boolean = false, -) +// Re-export shared types so existing Android imports continue to work +// The canonical types now live in commons/commonMain +@Suppress("unused") +private const val RE_EXPORTS = 0 -enum class TorType( - val screenCode: Int, - val resourceId: Int, -) { - OFF(0, R.string.tor_off), - INTERNAL(1, R.string.tor_internal), - EXTERNAL(2, R.string.tor_external), -} +// Android-specific resource ID mappings for TorType +val TorType.resourceId: Int + get() = + when (this) { + TorType.OFF -> R.string.tor_off + TorType.INTERNAL -> R.string.tor_internal + TorType.EXTERNAL -> R.string.tor_external + } -fun parseTorType(code: Int?): TorType = - when (code) { - TorType.OFF.screenCode -> TorType.OFF - TorType.INTERNAL.screenCode -> TorType.INTERNAL - TorType.EXTERNAL.screenCode -> TorType.EXTERNAL - else -> TorType.INTERNAL - } +// Android-specific resource ID mappings for TorPresetType +val TorPresetType.resourceId: Int + get() = + when (this) { + TorPresetType.ONLY_WHEN_NEEDED -> R.string.tor_when_needed + TorPresetType.DEFAULT -> R.string.tor_default + TorPresetType.SMALL_PAYLOADS -> R.string.tor_small_payloads + TorPresetType.FULL_PRIVACY -> R.string.tor_full_privacy + TorPresetType.CUSTOM -> R.string.tor_custom + } -enum class TorPresetType( - val screenCode: Int, - val resourceId: Int, - val explainerId: Int, -) { - ONLY_WHEN_NEEDED(0, R.string.tor_when_needed, R.string.tor_when_needed_explainer), - DEFAULT(1, R.string.tor_default, R.string.tor_default_explainer), - SMALL_PAYLOADS(2, R.string.tor_small_payloads, R.string.tor_small_payloads_explainer), - FULL_PRIVACY(3, R.string.tor_full_privacy, R.string.tor_full_privacy_explainer), - CUSTOM(4, R.string.tor_custom, R.string.tor_custom_explainer), -} - -fun parseTorPresetType(code: Int?): TorPresetType = - when (code) { - TorPresetType.ONLY_WHEN_NEEDED.screenCode -> TorPresetType.ONLY_WHEN_NEEDED - TorPresetType.DEFAULT.screenCode -> TorPresetType.DEFAULT - TorPresetType.SMALL_PAYLOADS.screenCode -> TorPresetType.SMALL_PAYLOADS - TorPresetType.FULL_PRIVACY.screenCode -> TorPresetType.FULL_PRIVACY - else -> TorPresetType.CUSTOM - } - -fun isPreset( - torSettings: TorSettings, - preset: TorSettings, -): Boolean = - torSettings.onionRelaysViaTor == preset.onionRelaysViaTor && - torSettings.dmRelaysViaTor == preset.dmRelaysViaTor && - torSettings.newRelaysViaTor == preset.newRelaysViaTor && - torSettings.trustedRelaysViaTor == preset.trustedRelaysViaTor && - torSettings.urlPreviewsViaTor == preset.urlPreviewsViaTor && - // torSettings.profilePicsViaTor == preset.profilePicsViaTor && - torSettings.imagesViaTor == preset.imagesViaTor && - torSettings.videosViaTor == preset.videosViaTor && - torSettings.moneyOperationsViaTor == preset.moneyOperationsViaTor && - torSettings.nip05VerificationsViaTor == preset.nip05VerificationsViaTor && - torSettings.mediaUploadsViaTor == preset.mediaUploadsViaTor - -fun whichPreset(torSettings: TorSettings): TorPresetType { - if (isPreset(torSettings, torOnlyWhenNeededPreset)) return TorPresetType.ONLY_WHEN_NEEDED - if (isPreset(torSettings, torDefaultPreset)) return TorPresetType.DEFAULT - if (isPreset(torSettings, torSmallPayloadsPreset)) return TorPresetType.SMALL_PAYLOADS - if (isPreset(torSettings, torFullyPrivate)) return TorPresetType.FULL_PRIVACY - return TorPresetType.CUSTOM -} - -val torOnlyWhenNeededPreset = - TorSettings( - onionRelaysViaTor = true, - dmRelaysViaTor = false, - newRelaysViaTor = false, - trustedRelaysViaTor = false, - urlPreviewsViaTor = false, - profilePicsViaTor = false, - imagesViaTor = false, - videosViaTor = false, - moneyOperationsViaTor = false, - nip05VerificationsViaTor = false, - mediaUploadsViaTor = false, - ) -val torDefaultPreset = - TorSettings( - onionRelaysViaTor = true, - dmRelaysViaTor = true, - newRelaysViaTor = true, - trustedRelaysViaTor = false, - urlPreviewsViaTor = false, - profilePicsViaTor = false, - imagesViaTor = false, - videosViaTor = false, - moneyOperationsViaTor = false, - nip05VerificationsViaTor = false, - mediaUploadsViaTor = false, - ) -val torSmallPayloadsPreset = - TorSettings( - onionRelaysViaTor = true, - dmRelaysViaTor = true, - newRelaysViaTor = true, - trustedRelaysViaTor = true, - urlPreviewsViaTor = true, - profilePicsViaTor = true, - imagesViaTor = false, - videosViaTor = false, - moneyOperationsViaTor = true, - nip05VerificationsViaTor = true, - mediaUploadsViaTor = false, - ) -val torFullyPrivate = - TorSettings( - onionRelaysViaTor = true, - dmRelaysViaTor = true, - newRelaysViaTor = true, - trustedRelaysViaTor = true, - urlPreviewsViaTor = true, - profilePicsViaTor = true, - imagesViaTor = true, - videosViaTor = true, - moneyOperationsViaTor = true, - nip05VerificationsViaTor = true, - mediaUploadsViaTor = true, - ) +val TorPresetType.explainerId: Int + get() = + when (this) { + TorPresetType.ONLY_WHEN_NEEDED -> R.string.tor_when_needed_explainer + TorPresetType.DEFAULT -> R.string.tor_default_explainer + TorPresetType.SMALL_PAYLOADS -> R.string.tor_small_payloads_explainer + TorPresetType.FULL_PRIVACY -> R.string.tor_full_privacy_explainer + TorPresetType.CUSTOM -> R.string.tor_custom_explainer + } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorSettingsDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorSettingsDialog.kt index d64e072ee..7c1351f1b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorSettingsDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorSettingsDialog.kt @@ -49,6 +49,11 @@ import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.commons.tor.TorPresetType +import com.vitorpamplona.amethyst.commons.tor.TorSettings +import com.vitorpamplona.amethyst.commons.tor.TorType +import com.vitorpamplona.amethyst.commons.tor.parseTorPresetType +import com.vitorpamplona.amethyst.commons.tor.parseTorType import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge import com.vitorpamplona.amethyst.ui.components.TitleExplainer import com.vitorpamplona.amethyst.ui.navigation.topbars.SavingTopBar diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorSettingsFlow.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorSettingsFlow.kt index d299c8f08..89f297fed 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorSettingsFlow.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/tor/TorSettingsFlow.kt @@ -21,6 +21,8 @@ package com.vitorpamplona.amethyst.ui.tor import androidx.compose.runtime.Stable +import com.vitorpamplona.amethyst.commons.tor.TorSettings +import com.vitorpamplona.amethyst.commons.tor.TorType import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/model/torState/TorRelayEvaluationTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/model/torState/TorRelayEvaluationTest.kt index 8dbb7a590..3c47751fa 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/model/torState/TorRelayEvaluationTest.kt +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/model/torState/TorRelayEvaluationTest.kt @@ -20,7 +20,7 @@ */ package com.vitorpamplona.amethyst.model.torState -import com.vitorpamplona.amethyst.ui.tor.TorType +import com.vitorpamplona.amethyst.commons.tor.TorType import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/tor/TorSettingsTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/tor/TorSettingsTest.kt index 5f972ece3..d7361f960 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/tor/TorSettingsTest.kt +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/tor/TorSettingsTest.kt @@ -20,6 +20,17 @@ */ package com.vitorpamplona.amethyst.ui.tor +import com.vitorpamplona.amethyst.commons.tor.TorPresetType +import com.vitorpamplona.amethyst.commons.tor.TorSettings +import com.vitorpamplona.amethyst.commons.tor.TorType +import com.vitorpamplona.amethyst.commons.tor.isPreset +import com.vitorpamplona.amethyst.commons.tor.parseTorPresetType +import com.vitorpamplona.amethyst.commons.tor.parseTorType +import com.vitorpamplona.amethyst.commons.tor.torDefaultPreset +import com.vitorpamplona.amethyst.commons.tor.torFullyPrivate +import com.vitorpamplona.amethyst.commons.tor.torOnlyWhenNeededPreset +import com.vitorpamplona.amethyst.commons.tor.torSmallPayloadsPreset +import com.vitorpamplona.amethyst.commons.tor.whichPreset import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertNotEquals diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/tor/TorSettings.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/tor/TorSettings.kt new file mode 100644 index 000000000..3e734f51f --- /dev/null +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/tor/TorSettings.kt @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.commons.tor + +data class TorSettings( + val torType: TorType = TorType.INTERNAL, + val externalSocksPort: Int = 9050, + val onionRelaysViaTor: Boolean = true, + val dmRelaysViaTor: Boolean = true, + val newRelaysViaTor: Boolean = true, + val trustedRelaysViaTor: Boolean = false, + val urlPreviewsViaTor: Boolean = false, + val profilePicsViaTor: Boolean = false, + val imagesViaTor: Boolean = false, + val videosViaTor: Boolean = false, + val moneyOperationsViaTor: Boolean = false, + val nip05VerificationsViaTor: Boolean = false, + val mediaUploadsViaTor: Boolean = false, +) + +enum class TorType( + val screenCode: Int, +) { + OFF(0), + INTERNAL(1), + EXTERNAL(2), +} + +fun parseTorType(code: Int?): TorType = + when (code) { + TorType.OFF.screenCode -> TorType.OFF + TorType.INTERNAL.screenCode -> TorType.INTERNAL + TorType.EXTERNAL.screenCode -> TorType.EXTERNAL + else -> TorType.INTERNAL + } + +enum class TorPresetType( + val screenCode: Int, +) { + ONLY_WHEN_NEEDED(0), + DEFAULT(1), + SMALL_PAYLOADS(2), + FULL_PRIVACY(3), + CUSTOM(4), +} + +fun parseTorPresetType(code: Int?): TorPresetType = + when (code) { + TorPresetType.ONLY_WHEN_NEEDED.screenCode -> TorPresetType.ONLY_WHEN_NEEDED + TorPresetType.DEFAULT.screenCode -> TorPresetType.DEFAULT + TorPresetType.SMALL_PAYLOADS.screenCode -> TorPresetType.SMALL_PAYLOADS + TorPresetType.FULL_PRIVACY.screenCode -> TorPresetType.FULL_PRIVACY + else -> TorPresetType.CUSTOM + } + +fun isPreset( + torSettings: TorSettings, + preset: TorSettings, +): Boolean = + torSettings.onionRelaysViaTor == preset.onionRelaysViaTor && + torSettings.dmRelaysViaTor == preset.dmRelaysViaTor && + torSettings.newRelaysViaTor == preset.newRelaysViaTor && + torSettings.trustedRelaysViaTor == preset.trustedRelaysViaTor && + torSettings.urlPreviewsViaTor == preset.urlPreviewsViaTor && + // torSettings.profilePicsViaTor == preset.profilePicsViaTor && + torSettings.imagesViaTor == preset.imagesViaTor && + torSettings.videosViaTor == preset.videosViaTor && + torSettings.moneyOperationsViaTor == preset.moneyOperationsViaTor && + torSettings.nip05VerificationsViaTor == preset.nip05VerificationsViaTor && + torSettings.mediaUploadsViaTor == preset.mediaUploadsViaTor + +fun whichPreset(torSettings: TorSettings): TorPresetType { + if (isPreset(torSettings, torOnlyWhenNeededPreset)) return TorPresetType.ONLY_WHEN_NEEDED + if (isPreset(torSettings, torDefaultPreset)) return TorPresetType.DEFAULT + if (isPreset(torSettings, torSmallPayloadsPreset)) return TorPresetType.SMALL_PAYLOADS + if (isPreset(torSettings, torFullyPrivate)) return TorPresetType.FULL_PRIVACY + return TorPresetType.CUSTOM +} + +val torOnlyWhenNeededPreset = + TorSettings( + onionRelaysViaTor = true, + dmRelaysViaTor = false, + newRelaysViaTor = false, + trustedRelaysViaTor = false, + urlPreviewsViaTor = false, + profilePicsViaTor = false, + imagesViaTor = false, + videosViaTor = false, + moneyOperationsViaTor = false, + nip05VerificationsViaTor = false, + mediaUploadsViaTor = false, + ) +val torDefaultPreset = + TorSettings( + onionRelaysViaTor = true, + dmRelaysViaTor = true, + newRelaysViaTor = true, + trustedRelaysViaTor = false, + urlPreviewsViaTor = false, + profilePicsViaTor = false, + imagesViaTor = false, + videosViaTor = false, + moneyOperationsViaTor = false, + nip05VerificationsViaTor = false, + mediaUploadsViaTor = false, + ) +val torSmallPayloadsPreset = + TorSettings( + onionRelaysViaTor = true, + dmRelaysViaTor = true, + newRelaysViaTor = true, + trustedRelaysViaTor = true, + urlPreviewsViaTor = true, + profilePicsViaTor = true, + imagesViaTor = false, + videosViaTor = false, + moneyOperationsViaTor = true, + nip05VerificationsViaTor = true, + mediaUploadsViaTor = false, + ) +val torFullyPrivate = + TorSettings( + onionRelaysViaTor = true, + dmRelaysViaTor = true, + newRelaysViaTor = true, + trustedRelaysViaTor = true, + urlPreviewsViaTor = true, + profilePicsViaTor = true, + imagesViaTor = true, + videosViaTor = true, + moneyOperationsViaTor = true, + nip05VerificationsViaTor = true, + mediaUploadsViaTor = true, + )