diff --git a/kotlin/android/PortalMock/server.rb b/kotlin/android/PortalMock/server.rb index 1098a609d..267467900 100755 --- a/kotlin/android/PortalMock/server.rb +++ b/kotlin/android/PortalMock/server.rb @@ -7,14 +7,14 @@ require 'sinatra' set :bind, '0.0.0.0' set :port, 4568 -get '/auth' do +get '/:slug/sign_in' do csrfToken = params['client_csrf_token'] - dest = params['dest'] - ERB.new("

Auth page

Proceed").result(binding) + ERB.new("

Auth page

Proceed") + .result(binding) end get '/redirect' do - dest = params['dest'] + dest = 'https://app.firez.one/handle_client_auth_callback' csrfToken = params['client_csrf_token'] authToken = File.read(File.join(__dir__, 'data', 'jwt')) redirect "#{dest}?client_csrf_token=#{csrfToken}&client_auth_token=#{authToken}" diff --git a/kotlin/android/app/src/main/AndroidManifest.xml b/kotlin/android/app/src/main/AndroidManifest.xml index 35244bec4..d2659f1fe 100644 --- a/kotlin/android/app/src/main/AndroidManifest.xml +++ b/kotlin/android/app/src/main/AndroidManifest.xml @@ -46,27 +46,14 @@ android:exported="true" android:launchMode="singleTop"> - - - - - - - + @@ -78,16 +65,15 @@ - + + + + + + + diff --git a/kotlin/android/app/src/main/java/dev/firezone/android/core/di/AppModule.kt b/kotlin/android/app/src/main/java/dev/firezone/android/core/di/AppModule.kt index 2f1acb0e9..3c0d2aa91 100644 --- a/kotlin/android/app/src/main/java/dev/firezone/android/core/di/AppModule.kt +++ b/kotlin/android/app/src/main/java/dev/firezone/android/core/di/AppModule.kt @@ -42,10 +42,4 @@ object AppModule { internal fun provideSessionManager( sharedPreferences: SharedPreferences ): SessionManager = SessionManager(sharedPreferences) - - @Provides - internal fun provideBroadcastReceiver( - @MainImmediateDispatcher coroutineDispatcher: CoroutineDispatcher, - sessionManager: SessionManager, - ): BootShutdownReceiver = BootShutdownReceiver(coroutineDispatcher, sessionManager) } diff --git a/kotlin/android/app/src/main/java/dev/firezone/android/features/applink/presentation/AppLinkHandlerActivity.kt b/kotlin/android/app/src/main/java/dev/firezone/android/features/applink/presentation/AppLinkHandlerActivity.kt index 012f3b6b5..f81134dfa 100644 --- a/kotlin/android/app/src/main/java/dev/firezone/android/features/applink/presentation/AppLinkHandlerActivity.kt +++ b/kotlin/android/app/src/main/java/dev/firezone/android/features/applink/presentation/AppLinkHandlerActivity.kt @@ -2,6 +2,7 @@ package dev.firezone.android.features.applink.presentation import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.util.Log import androidx.activity.viewModels import androidx.appcompat.app.AlertDialog import dagger.hilt.android.AndroidEntryPoint @@ -27,6 +28,7 @@ class AppLinkHandlerActivity : AppCompatActivity(R.layout.activity_app_link_hand when (action) { is AppLinkViewAction.AuthFlowComplete -> { // Continue with onboarding + Log.d("AppLinkHandlerActivity", "AuthFlowComplete") } is AppLinkViewAction.ShowError -> showError() else -> {} diff --git a/kotlin/android/app/src/main/java/dev/firezone/android/features/applink/presentation/AppLinkViewModel.kt b/kotlin/android/app/src/main/java/dev/firezone/android/features/applink/presentation/AppLinkViewModel.kt index e1c9a7c76..0e5ea8b4e 100644 --- a/kotlin/android/app/src/main/java/dev/firezone/android/features/applink/presentation/AppLinkViewModel.kt +++ b/kotlin/android/app/src/main/java/dev/firezone/android/features/applink/presentation/AppLinkViewModel.kt @@ -1,6 +1,7 @@ package dev.firezone.android.features.applink.presentation import android.content.Intent +import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel @@ -24,7 +25,7 @@ internal class AppLinkViewModel @Inject constructor( fun parseAppLink(intent: Intent) { viewModelScope.launch { when (intent.data?.lastPathSegment) { - "callback" -> { + "handle_client_auth_callback" -> { intent.data?.getQueryParameter("client_csrf_token")?.let { csrfToken -> if (validateCsrfTokenUseCase(csrfToken).firstOrNull() == true) { val jwtToken = intent.data?.getQueryParameter("client_auth_token") ?: "" @@ -34,7 +35,9 @@ internal class AppLinkViewModel @Inject constructor( } } } - else -> {} + else -> { + Log.d("AppLink", "Unknown path segment: ${intent.data?.lastPathSegment}") + } } } } diff --git a/kotlin/android/app/src/main/java/dev/firezone/android/features/auth/domain/AuthRepositoryImpl.kt b/kotlin/android/app/src/main/java/dev/firezone/android/features/auth/domain/AuthRepositoryImpl.kt index f0fea744d..1a6320279 100644 --- a/kotlin/android/app/src/main/java/dev/firezone/android/features/auth/domain/AuthRepositoryImpl.kt +++ b/kotlin/android/app/src/main/java/dev/firezone/android/features/auth/domain/AuthRepositoryImpl.kt @@ -8,7 +8,7 @@ import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOn import java.util.Base64 import javax.inject.Inject -import kotlin.random.Random +import java.security.SecureRandom internal class AuthRepositoryImpl @Inject constructor( private val coroutineDispatcher: CoroutineDispatcher, @@ -16,11 +16,10 @@ internal class AuthRepositoryImpl @Inject constructor( ) : AuthRepository { override fun generateCsrfToken(): Flow = flow { - val str = (1..CSRF_LENGTH) - .map { Random.nextInt(0, chars.size).let { chars[it] } } - .joinToString("") - - val encodedStr: String = Base64.getEncoder().encodeToString(str.toByteArray()) + val random = SecureRandom.getInstanceStrong() + val bytes = ByteArray(CSRF_LENGTH) + random.nextBytes(bytes) + val encodedStr: String = Base64.getEncoder().encodeToString(bytes) sharedPreferences .edit() @@ -33,6 +32,5 @@ internal class AuthRepositoryImpl @Inject constructor( companion object { private const val CSRF_KEY = "csrf" private const val CSRF_LENGTH = 24 - private val chars : List = ('a'..'z') + ('A'..'Z') + ('0'..'9') } } diff --git a/kotlin/android/app/src/main/java/dev/firezone/android/features/auth/presentation/AuthViewModel.kt b/kotlin/android/app/src/main/java/dev/firezone/android/features/auth/presentation/AuthViewModel.kt index d6fc1ccf3..f4d7de64c 100644 --- a/kotlin/android/app/src/main/java/dev/firezone/android/features/auth/presentation/AuthViewModel.kt +++ b/kotlin/android/app/src/main/java/dev/firezone/android/features/auth/presentation/AuthViewModel.kt @@ -32,7 +32,7 @@ internal class AuthViewModel @Inject constructor( actionMutableLiveData.postValue( AuthViewAction.LaunchAuthFlow( - url = "${config.portalUrl}/auth?client_csrf_token=$token&dest=https://${BuildConfig.AUTH_DEST}/callback" + url = "${config.portalUrl}/sign_in?client_csrf_token=$token&client_platform=android" ) ) } diff --git a/kotlin/android/app/src/main/java/dev/firezone/android/features/session/backend/BootShutdownReceiver.kt b/kotlin/android/app/src/main/java/dev/firezone/android/features/session/backend/BootShutdownReceiver.kt index d408f47a0..f04991f4d 100644 --- a/kotlin/android/app/src/main/java/dev/firezone/android/features/session/backend/BootShutdownReceiver.kt +++ b/kotlin/android/app/src/main/java/dev/firezone/android/features/session/backend/BootShutdownReceiver.kt @@ -1,21 +1,22 @@ package dev.firezone.android.features.session.backend import android.content.BroadcastReceiver +import android.util.Log import android.content.Context import android.content.Intent import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher -internal class BootShutdownReceiver @Inject constructor( - private val coroutineDispatcher: CoroutineDispatcher, - private val sessionManager: SessionManager -) : BroadcastReceiver() { - +internal class BootShutdownReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (Intent.ACTION_BOOT_COMPLETED == intent.action) { - sessionManager.connect() + Log.d("BootShutdownReceiver", "Boot completed. Attempting to connect.") + // TODO: Retrieve the session manager from the application context. + //sessionManager.connect() } else if (Intent.ACTION_SHUTDOWN == intent.action) { - sessionManager.disconnect() + Log.d("BootShutdownReceiver", "Shutting down. Attempting to disconnect.") + // TODO: Retrieve the session manager from the application context. + // sessionManager.disconnect() } } } diff --git a/kotlin/android/app/src/main/java/dev/firezone/android/features/session/presentation/SessionFragment.kt b/kotlin/android/app/src/main/java/dev/firezone/android/features/session/presentation/SessionFragment.kt index 8abffe1fa..a082f3a30 100644 --- a/kotlin/android/app/src/main/java/dev/firezone/android/features/session/presentation/SessionFragment.kt +++ b/kotlin/android/app/src/main/java/dev/firezone/android/features/session/presentation/SessionFragment.kt @@ -2,6 +2,7 @@ package dev.firezone.android.features.session.presentation import android.os.Bundle import android.view.View +import android.util.Log import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels @@ -22,7 +23,7 @@ internal class SessionFragment : Fragment(R.layout.fragment_session) { setupButtonListeners() setupActionObservers() - + Log.d("SessionViewModel", "Starting session...") viewModel.startSession() } diff --git a/kotlin/android/app/src/main/java/dev/firezone/android/features/webview/presentation/WebViewViewModel.kt b/kotlin/android/app/src/main/java/dev/firezone/android/features/webview/presentation/WebViewViewModel.kt index 4376e5e19..4f2c07476 100644 --- a/kotlin/android/app/src/main/java/dev/firezone/android/features/webview/presentation/WebViewViewModel.kt +++ b/kotlin/android/app/src/main/java/dev/firezone/android/features/webview/presentation/WebViewViewModel.kt @@ -40,7 +40,7 @@ internal class WebViewViewModel @Inject constructor( .collect { actionMutableLiveData.postValue( WebViewViewAction.FillPortalUrl( - url = "${it.portalUrl}/auth" + url = "${it.portalUrl}/sign_in" ) ) } diff --git a/rust/connlib/clients/android/src/lib.rs b/rust/connlib/clients/android/src/lib.rs index 6e563834c..d12152200 100644 --- a/rust/connlib/clients/android/src/lib.rs +++ b/rust/connlib/clients/android/src/lib.rs @@ -125,7 +125,7 @@ impl Callbacks for CallbackHandler { &mut env, &self.callback_handler, "onSetInterfaceConfig", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", &[ JValue::from(&tunnel_address_v4), JValue::from(&tunnel_address_v6), @@ -138,7 +138,13 @@ impl Callbacks for CallbackHandler { fn on_tunnel_ready(&self) -> Result<(), Self::Error> { self.env(|mut env| { - call_method(&mut env, &self.callback_handler, "onTunnelReady", "()", &[]) + call_method( + &mut env, + &self.callback_handler, + "onTunnelReady", + "()Z", + &[], + ) }) } @@ -154,7 +160,7 @@ impl Callbacks for CallbackHandler { &mut env, &self.callback_handler, "onAddRoute", - "(Ljava/lang/String;)", + "(Ljava/lang/String;)V", &[JValue::from(&route)], ) }) @@ -172,7 +178,7 @@ impl Callbacks for CallbackHandler { &mut env, &self.callback_handler, "onRemoveRoute", - "(Ljava/lang/String;)", + "(Ljava/lang/String;)V", &[JValue::from(&route)], ) }) @@ -193,7 +199,7 @@ impl Callbacks for CallbackHandler { &mut env, &self.callback_handler, "onUpdateResources", - "(Ljava/lang/String;)", + "(Ljava/lang/String;)V", &[JValue::from(&resource_list)], ) }) @@ -211,7 +217,7 @@ impl Callbacks for CallbackHandler { &mut env, &self.callback_handler, "onDisconnect", - "(Ljava/lang/String;)", + "(Ljava/lang/String;)Z", &[JValue::from(&error)], ) }) @@ -229,7 +235,7 @@ impl Callbacks for CallbackHandler { &mut env, &self.callback_handler, "onError", - "(Ljava/lang/String;)", + "(Ljava/lang/String;)Z", &[JValue::from(&error)], ) })