Skip to content

Commit

Permalink
add UI and information flow for Tor configuration (#112)
Browse files Browse the repository at this point in the history
- add a new `UserDefaults` to store a boolean saying if Tor is enabled
- add a screen to toggle this boolean
- add an observer to post any changes to the shared module that will be responsible to forward socket connections through Tor's proxy.
  • Loading branch information
Romain Boisselle authored Jan 28, 2021
1 parent b3ada85 commit 665505a
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 12 deletions.
22 changes: 12 additions & 10 deletions phoenix-ios/phoenix-ios.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
C8D7A74B29EAFF2EBD73BC6B /* ConfigurationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D7AFF1A7C09789C6CF2D06 /* ConfigurationView.swift */; };
C8D7A84CCF914B08BDB03BE6 /* RestoreWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D7A44147508AA19378B739 /* RestoreWalletView.swift */; };
C8D7AA4B09B32AD99C88BB5E /* DisplayConfigurationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D7A986A61CCD64FA661B88 /* DisplayConfigurationView.swift */; };
C8D7AB09E80CE2B6AE270A97 /* TorConfigurationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D7A2BD01ADA0DE6034AE0F /* TorConfigurationView.swift */; };
C8D7ABB189B14D3104ABB50D /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D7A2327BC90150A3E1493D /* AboutView.swift */; };
C8D7ABC95B979B59AF5A7CA7 /* InitializationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D7A209301A31C14A982ECD /* InitializationView.swift */; };
C8D7AFF5BC5754DBBEEB2688 /* ElectrumConfigurationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D7A1F8A123C59199C182C2 /* ElectrumConfigurationView.swift */; };
Expand All @@ -52,7 +53,6 @@
DC67654E25655D93004D4263 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DC67654D25655D93004D4263 /* Colors.xcassets */; };
DC682FE8258175CE00CA1114 /* Popover.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC682FE7258175CE00CA1114 /* Popover.swift */; };
DC72C2F125A3CBD6008A927A /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = DC72C2F025A3CBD6008A927A /* GoogleService-Info.plist */; };
DC72C31925A3CF87008A927A /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = DC72C31825A3CF87008A927A /* FirebaseMessaging */; };
DC72C32F25A51797008A927A /* UserDefaults+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC72C32E25A51797008A927A /* UserDefaults+Codable.swift */; };
DC72C33425A51AAC008A927A /* CurrencyPrefs.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC72C33325A51AAC008A927A /* CurrencyPrefs.swift */; };
DC72C33925A663CA008A927A /* QRCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC72C33825A663CA008A927A /* QRCode.swift */; };
Expand Down Expand Up @@ -147,6 +147,7 @@
C8D7A1F8A123C59199C182C2 /* ElectrumConfigurationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElectrumConfigurationView.swift; sourceTree = "<group>"; };
C8D7A209301A31C14A982ECD /* InitializationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InitializationView.swift; sourceTree = "<group>"; };
C8D7A2327BC90150A3E1493D /* AboutView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = "<group>"; };
C8D7A2BD01ADA0DE6034AE0F /* TorConfigurationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TorConfigurationView.swift; sourceTree = "<group>"; };
C8D7A44147508AA19378B739 /* RestoreWalletView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RestoreWalletView.swift; sourceTree = "<group>"; };
C8D7A607F036B3184C3D6EED /* QRCodeScanner.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRCodeScanner.swift; sourceTree = "<group>"; };
C8D7A986A61CCD64FA661B88 /* DisplayConfigurationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayConfigurationView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -192,7 +193,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DC72C31925A3CF87008A927A /* FirebaseMessaging in Frameworks */,
DCB0DB8A255AE42F005B29C8 /* PhoenixShared.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -416,6 +416,7 @@
C8D7A2327BC90150A3E1493D /* AboutView.swift */,
C8D7A986A61CCD64FA661B88 /* DisplayConfigurationView.swift */,
C8D7A1F8A123C59199C182C2 /* ElectrumConfigurationView.swift */,
C8D7A2BD01ADA0DE6034AE0F /* TorConfigurationView.swift */,
);
path = general;
sourceTree = "<group>";
Expand Down Expand Up @@ -489,7 +490,7 @@
);
name = "phoenix-ios";
packageProductDependencies = (
DC72C31825A3CF87008A927A /* FirebaseMessaging */,
DC72C31825A3CF87008A927A,
);
productName = "phoenix-ios";
productReference = 7555FF7B242A565900829871 /* Phoenix.app */;
Expand Down Expand Up @@ -589,7 +590,7 @@
);
mainGroup = 7555FF72242A565900829871;
packageReferences = (
DC72C2EA25A3CADC008A927A /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
DC72C2EA25A3CADC008A927A,
);
productRefGroup = 7555FF7C242A565900829871 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -737,6 +738,7 @@
F4AED297257A50CD009485C1 /* LogsConfigurationViewerView.swift in Sources */,
F4AED298257A50CD009485C1 /* LogsConfigurationView.swift in Sources */,
53BEF98CDD61115030E87C12 /* uikitAppearance.swift in Sources */,
C8D7AB09E80CE2B6AE270A97 /* TorConfigurationView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -778,7 +780,7 @@
};
DC72C32725A3D043008A927A /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
productRef = DC72C32625A3D043008A927A /* FirebaseMessaging */;
productRef = DC72C32625A3D043008A927A;
};
DCB0DBB0255AEE0E005B29C8 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
Expand Down Expand Up @@ -1168,7 +1170,7 @@
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
DC72C2EA25A3CADC008A927A /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = {
DC72C2EA25A3CADC008A927A = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/firebase/firebase-ios-sdk.git";
requirement = {
Expand All @@ -1179,14 +1181,14 @@
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
DC72C31825A3CF87008A927A /* FirebaseMessaging */ = {
DC72C31825A3CF87008A927A = {
isa = XCSwiftPackageProductDependency;
package = DC72C2EA25A3CADC008A927A /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
package = DC72C2EA25A3CADC008A927A;
productName = FirebaseMessaging;
};
DC72C32625A3D043008A927A /* FirebaseMessaging */ = {
DC72C32625A3D043008A927A = {
isa = XCSwiftPackageProductDependency;
package = DC72C2EA25A3CADC008A927A /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
package = DC72C2EA25A3CADC008A927A;
productName = FirebaseMessaging;
};
/* End XCSwiftPackageProductDependency section */
Expand Down
5 changes: 5 additions & 0 deletions phoenix-ios/phoenix-ios/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate {
nc.publisher(for: UIApplication.willEnterForegroundNotification).sink { _ in
self._applicationWillEnterForeground(application)
}.store(in: &cancellables)

// Tor configuration observer
Prefs.shared.isTorEnabledPublisher.sink {[weak self](isTorEnabled: Bool) in
self?.business.updateTorUsage(isEnabled: isTorEnabled)
}.store(in: &cancellables)

return true
}
Expand Down
16 changes: 16 additions & 0 deletions phoenix-ios/phoenix-ios/utils/preferences.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class Prefs {
case theme
case fcmTokenInfo
case pushPermissionQuery
case isTorEnabled
}

lazy private(set) var currencyTypePublisher: CurrentValueSubject<CurrencyType, Never> = {
Expand Down Expand Up @@ -97,6 +98,21 @@ class Prefs {
themePublisher.send(newValue)
}
}

lazy private(set) var isTorEnabledPublisher: CurrentValueSubject<Bool, Never> = {
var value = self.isTorEnabled
return CurrentValueSubject<Bool, Never>(value)
}()

var isTorEnabled : Bool {
get {
UserDefaults.standard.bool(forKey: Keys.isTorEnabled.rawValue)
}
set {
UserDefaults.standard.set(newValue, forKey: Keys.isTorEnabled.rawValue)
isTorEnabledPublisher.send(newValue)
}
}

var fcmTokenInfo: FcmTokenInfo? {
get {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct ConfigurationView: View {
Image(systemName: "link")
}
}
NavigationLink(destination: ComingSoonView()) {
NavigationLink(destination: TorConfigurationView()) {
Label { Text("Tor") } icon: {
Image(systemName: "shield.lefthalf.fill")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import SwiftUI

struct TorConfigurationView: View {

@State var isTorEnabled = Prefs.shared.isTorEnabled
@State var theme = Prefs.shared.theme

var body: some View {
Form {
Section(header: TorFormHeader(), content: {}).textCase(nil)

Toggle(isOn: $isTorEnabled.animation()) {
if isTorEnabled {
Text("Tor is enabled")
} else {
Text("Tor is disabled")
}
}.onChange(of: isTorEnabled) { newValue in
self.toggleTor(newValue)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.edgesIgnoringSafeArea(.bottom)
.navigationBarTitle("Tor Settings", displayMode: .inline)
}

struct TorFormHeader: View {
var body: some View {
Text(
"You can improve your privacy by only using Tor when connecting to an Electrum server or" +
" to your Lightning peer. This will slightly slow down your transactions."
)
.font(.body)
.foregroundColor(Color.primary)
.padding(.top, 10)
}
}

func toggleTor(_ isEnabled: Bool) {
Prefs.shared.isTorEnabled = isEnabled
}
}

class TorConfigurationView_Previews: PreviewProvider {

static var previews: some View {
TorConfigurationView()
.previewDevice("iPhone 11")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import io.ktor.client.features.json.JsonFeature
import io.ktor.client.features.json.serializer.*
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.flow.consumeAsFlow
import kotlinx.serialization.json.Json
import org.kodein.db.DB
import org.kodein.db.impl.factory
Expand Down Expand Up @@ -131,6 +130,8 @@ class PhoenixBusiness(private val ctx: PlatformContext) {
fun incomingPaymentFlow() =
paymentsManager.subscribeToLastIncomingPayment()

fun updateTorUsage(isEnabled: Boolean) = appConfigurationManager.updateTorUsage(isEnabled)

val controllers: ControllerFactory = object : ControllerFactory {
override fun content(): ContentController = AppContentController(loggerFactory, walletManager)
override fun initialization(): InitializationController = AppInitController(loggerFactory, walletManager)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,12 @@ class AppConfigurationManager(
)
}
//endregion

//region Tor configuration
private val isTorEnabled = MutableStateFlow(false)
fun subscribeToIsTorEnabled(): StateFlow<Boolean> = isTorEnabled
fun updateTorUsage(enabled: Boolean): Unit {
isTorEnabled.value = enabled
}
//endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ class AppConnectionsDaemon(
}
}
}
// TODO Tor usage
launch { configurationManager.subscribeToIsTorEnabled().collect {
logger.info { "Tor is ${if (it) "enabled" else "disabled"}." }
} }
}

fun incrementDisconnectCount(): Unit {
Expand Down

0 comments on commit 665505a

Please sign in to comment.