mirror of
https://github.com/bitwarden/android.git
synced 2024-11-21 17:05:44 +03:00
adding MainViewModel navigation to LoginApprovalViewModel
This commit is contained in:
parent
5ea17700b3
commit
114982d64a
6 changed files with 65 additions and 17 deletions
|
@ -25,6 +25,7 @@ import com.x8bit.bitwarden.ui.platform.composition.LocalManagerProvider
|
|||
import com.x8bit.bitwarden.ui.platform.feature.debugmenu.manager.DebugMenuLaunchManager
|
||||
import com.x8bit.bitwarden.ui.platform.feature.debugmenu.navigateToDebugMenuScreen
|
||||
import com.x8bit.bitwarden.ui.platform.feature.rootnav.RootNavScreen
|
||||
import com.x8bit.bitwarden.ui.platform.feature.settings.accountsecurity.loginapproval.navigateToLoginApproval
|
||||
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
|
@ -94,6 +95,13 @@ class MainActivity : AppCompatActivity() {
|
|||
)
|
||||
.show()
|
||||
}
|
||||
|
||||
is MainEvent.NavigateToLoginApproval -> {
|
||||
navController.navigateToLoginApproval(
|
||||
fingerprint = "",
|
||||
requestId = event.requestId,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
updateScreenCapture(isScreenCaptureAllowed = state.isScreenCaptureAllowed)
|
||||
|
|
|
@ -273,13 +273,16 @@ class MainViewModel @Inject constructor(
|
|||
authRepository.switchAccount(passwordlessRequestData.userId)
|
||||
}
|
||||
}
|
||||
specialCircumstanceManager.specialCircumstance =
|
||||
SpecialCircumstance.PasswordlessRequest(
|
||||
passwordlessRequestData = passwordlessRequestData,
|
||||
// Allow users back into the already-running app when completing the
|
||||
// autofill task when this is not the first intent.
|
||||
shouldFinishWhenComplete = isFirstIntent,
|
||||
)
|
||||
|
||||
sendEvent(MainEvent.NavigateToLoginApproval(passwordlessRequestData.loginRequestId))
|
||||
|
||||
// specialCircumstanceManager.specialCircumstance =
|
||||
// SpecialCircumstance.PasswordlessRequest(
|
||||
// passwordlessRequestData = passwordlessRequestData,
|
||||
// // Allow users back into the already-running app when completing the
|
||||
// // autofill task when this is not the first intent.
|
||||
// shouldFinishWhenComplete = isFirstIntent,
|
||||
// )
|
||||
}
|
||||
|
||||
completeRegistrationData != null -> {
|
||||
|
@ -518,4 +521,11 @@ sealed class MainEvent {
|
|||
* Show a toast with the given [message].
|
||||
*/
|
||||
data class ShowToast(val message: Text) : MainEvent()
|
||||
|
||||
/**
|
||||
* Navigates to the Login Approval screen with the given fingerprint.
|
||||
*/
|
||||
data class NavigateToLoginApproval(
|
||||
val requestId: String,
|
||||
) : MainEvent()
|
||||
}
|
||||
|
|
|
@ -12,8 +12,10 @@ import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
|
|||
import com.x8bit.bitwarden.data.auth.util.createPasswordlessRequestDataIntent
|
||||
import com.x8bit.bitwarden.data.autofill.util.toPendingIntentMutabilityFlag
|
||||
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
|
||||
import com.x8bit.bitwarden.data.platform.manager.AppStateManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.PushManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.AppForegroundState
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.PasswordlessRequestData
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
|
@ -28,6 +30,7 @@ class AuthRequestNotificationManagerImpl(
|
|||
private val authDiskSource: AuthDiskSource,
|
||||
pushManager: PushManager,
|
||||
dispatcherManager: DispatcherManager,
|
||||
private val appStateManager: AppStateManager,
|
||||
) : AuthRequestNotificationManager {
|
||||
private val ioScope = CoroutineScope(dispatcherManager.io)
|
||||
|
||||
|
@ -40,6 +43,13 @@ class AuthRequestNotificationManagerImpl(
|
|||
|
||||
@SuppressLint("MissingPermission")
|
||||
private fun handlePasswordlessRequestData(data: PasswordlessRequestData) {
|
||||
|
||||
val pendingIntent = createContentIntent(data)
|
||||
if (appStateManager.appForegroundStateFlow.value == AppForegroundState.FOREGROUNDED) {
|
||||
pendingIntent.send()
|
||||
return
|
||||
}
|
||||
|
||||
val notificationManager = NotificationManagerCompat.from(context)
|
||||
// Construct the channel, calling this more than once is safe
|
||||
notificationManager.createNotificationChannel(
|
||||
|
@ -54,7 +64,7 @@ class AuthRequestNotificationManagerImpl(
|
|||
if (!notificationManager.areNotificationsEnabled(NOTIFICATION_CHANNEL_ID)) return
|
||||
// Create the notification
|
||||
val builder = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
|
||||
.setContentIntent(createContentIntent(data))
|
||||
.setContentIntent(pendingIntent)
|
||||
.setContentTitle(context.getString(R.string.log_in_requested))
|
||||
.setContentText(
|
||||
authDiskSource
|
||||
|
|
|
@ -21,6 +21,7 @@ import com.x8bit.bitwarden.data.auth.manager.UserLogoutManager
|
|||
import com.x8bit.bitwarden.data.auth.manager.UserLogoutManagerImpl
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.PushDiskSource
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.SettingsDiskSource
|
||||
import com.x8bit.bitwarden.data.platform.manager.AppStateManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.PushManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
|
||||
import com.x8bit.bitwarden.data.tools.generator.datasource.disk.GeneratorDiskSource
|
||||
|
@ -49,12 +50,14 @@ object AuthManagerModule {
|
|||
authDiskSource: AuthDiskSource,
|
||||
pushManager: PushManager,
|
||||
dispatcherManager: DispatcherManager,
|
||||
appStateManager: AppStateManager,
|
||||
): AuthRequestNotificationManager =
|
||||
AuthRequestNotificationManagerImpl(
|
||||
context = context,
|
||||
authDiskSource = authDiskSource,
|
||||
pushManager = pushManager,
|
||||
dispatcherManager = dispatcherManager,
|
||||
appStateManager = appStateManager,
|
||||
)
|
||||
|
||||
@Provides
|
||||
|
|
|
@ -10,16 +10,19 @@ import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
|
|||
import com.x8bit.bitwarden.ui.platform.base.util.composableWithSlideTransitions
|
||||
|
||||
private const val FINGERPRINT: String = "fingerprint"
|
||||
private const val REQUEST_ID: String = "requestId"
|
||||
private const val LOGIN_APPROVAL_PREFIX = "login_approval"
|
||||
private const val LOGIN_APPROVAL_ROUTE = "$LOGIN_APPROVAL_PREFIX?$FINGERPRINT={$FINGERPRINT}"
|
||||
private const val LOGIN_APPROVAL_ROUTE =
|
||||
"$LOGIN_APPROVAL_PREFIX?$FINGERPRINT={$FINGERPRINT}&$REQUEST_ID={$REQUEST_ID}"
|
||||
|
||||
/**
|
||||
* Class to retrieve login approval arguments from the [SavedStateHandle].
|
||||
*/
|
||||
@OmitFromCoverage
|
||||
data class LoginApprovalArgs(val fingerprint: String?) {
|
||||
data class LoginApprovalArgs(val fingerprint: String?, val requestId: String?) {
|
||||
constructor(savedStateHandle: SavedStateHandle) : this(
|
||||
fingerprint = savedStateHandle.get<String>(FINGERPRINT),
|
||||
requestId = savedStateHandle.get<String>(REQUEST_ID),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -37,6 +40,11 @@ fun NavGraphBuilder.loginApprovalDestination(
|
|||
nullable = true
|
||||
defaultValue = null
|
||||
},
|
||||
navArgument(REQUEST_ID) {
|
||||
type = NavType.StringType
|
||||
nullable = true
|
||||
defaultValue = null
|
||||
},
|
||||
),
|
||||
) {
|
||||
LoginApprovalScreen(
|
||||
|
@ -50,7 +58,8 @@ fun NavGraphBuilder.loginApprovalDestination(
|
|||
*/
|
||||
fun NavController.navigateToLoginApproval(
|
||||
fingerprint: String?,
|
||||
requestId: String? = null,
|
||||
navOptions: NavOptions? = null,
|
||||
) {
|
||||
navigate("$LOGIN_APPROVAL_PREFIX?$FINGERPRINT=$fingerprint", navOptions)
|
||||
navigate("$LOGIN_APPROVAL_PREFIX?$FINGERPRINT=$fingerprint&$REQUEST_ID=$requestId", navOptions)
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ class LoginApprovalViewModel @Inject constructor(
|
|||
?: requireNotNull(LoginApprovalArgs(savedStateHandle).fingerprint),
|
||||
masterPasswordHash = null,
|
||||
publicKey = "",
|
||||
requestId = "",
|
||||
requestId = LoginApprovalArgs(savedStateHandle).requestId.orEmpty(),
|
||||
viewState = LoginApprovalState.ViewState.Loading,
|
||||
dialogState = null,
|
||||
)
|
||||
|
@ -86,11 +86,19 @@ class LoginApprovalViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
?: run {
|
||||
authRepository
|
||||
.getAuthRequestByFingerprintFlow(state.fingerprint)
|
||||
.map { LoginApprovalAction.Internal.AuthRequestResultReceive(it) }
|
||||
.onEach(::sendAction)
|
||||
.launchIn(viewModelScope)
|
||||
if (state.requestId.isNotEmpty()) {
|
||||
authRepository
|
||||
.getAuthRequestByIdFlow(state.requestId)
|
||||
.map { LoginApprovalAction.Internal.AuthRequestResultReceive(it) }
|
||||
.onEach(::sendAction)
|
||||
.launchIn(viewModelScope)
|
||||
} else {
|
||||
authRepository
|
||||
.getAuthRequestByIdFlow(state.fingerprint)
|
||||
.map { LoginApprovalAction.Internal.AuthRequestResultReceive(it) }
|
||||
.onEach(::sendAction)
|
||||
.launchIn(viewModelScope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue