diff --git a/mobile/ios/Podfile.lock b/mobile/ios/Podfile.lock index 9e2317ca7..3b2e3cda4 100644 --- a/mobile/ios/Podfile.lock +++ b/mobile/ios/Podfile.lock @@ -56,6 +56,8 @@ PODS: - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS + - url_launcher_ios (0.0.1): + - Flutter DEPENDENCIES: - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) @@ -63,6 +65,7 @@ DEPENDENCIES: - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - mobile_scanner (from `.symlinks/plugins/mobile_scanner/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) SPEC REPOS: trunk: @@ -89,6 +92,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/mobile_scanner/ios" shared_preferences_foundation: :path: ".symlinks/plugins/shared_preferences_foundation/darwin" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" SPEC CHECKSUMS: connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd @@ -107,6 +112,7 @@ SPEC CHECKSUMS: nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb + url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b PODFILE CHECKSUM: bd29822c3d5baf6b44b726f00ea3293a19339ef2 diff --git a/mobile/ios/Runner.xcodeproj/project.pbxproj b/mobile/ios/Runner.xcodeproj/project.pbxproj index ead3b0739..7629e276b 100644 --- a/mobile/ios/Runner.xcodeproj/project.pbxproj +++ b/mobile/ios/Runner.xcodeproj/project.pbxproj @@ -107,7 +107,6 @@ 7CF2415588E96D5723581BA9 /* Pods-RunnerTests.release.xcconfig */, 529B9B84AD8748153EB60BCF /* Pods-RunnerTests.profile.xcconfig */, ); - name = Pods; path = Pods; sourceTree = ""; }; @@ -493,7 +492,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = JMTDPW9CG3; + DEVELOPMENT_TEAM = L36K5BLDZJ; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -676,7 +675,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = JMTDPW9CG3; + DEVELOPMENT_TEAM = L36K5BLDZJ; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -699,7 +698,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = JMTDPW9CG3; + DEVELOPMENT_TEAM = L36K5BLDZJ; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( diff --git a/mobile/ios/Runner/Info.plist b/mobile/ios/Runner/Info.plist index 895b41172..553bae963 100644 --- a/mobile/ios/Runner/Info.plist +++ b/mobile/ios/Runner/Info.plist @@ -26,6 +26,12 @@ $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS + NSCameraUsageDescription + Sprout uses the camera to scan pairing QR codes so you can link this device to your account. + NSMicrophoneUsageDescription + Sprout does not record audio. The system may request microphone access while the camera is in use for QR scanning. + NSLocalNetworkUsageDescription + Sprout connects to your Sprout relay on the local network to sync messages in real time. UIApplicationSceneManifest UIApplicationSupportsMultipleScenes diff --git a/mobile/lib/features/pairing/pairing_provider.dart b/mobile/lib/features/pairing/pairing_provider.dart index f639f07a9..2d1a59c98 100644 --- a/mobile/lib/features/pairing/pairing_provider.dart +++ b/mobile/lib/features/pairing/pairing_provider.dart @@ -133,9 +133,11 @@ class PairingNotifier extends Notifier { return; } - // Block private and link-local IPs. + // Block private and link-local IPs in production. In debug mode we + // intentionally allow them so developers can pair to a relay running on + // their LAN (e.g. http://192.168.1.23:3000) from a physical device. final ip = Uri.tryParse('http://$host')?.host ?? host; - if (_isPrivateHost(ip)) { + if (_isPrivateHost(ip) && !kDebugMode) { throw const FormatException( 'Relay URL cannot target private network addresses', );