Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions app/src/main/java/app/gamenative/service/SteamAuthenticator.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package app.gamenative.service

import app.gamenative.enums.LoginResult
import app.gamenative.enums.LoginScreen
import app.gamenative.ui.data.UserLoginState
import `in`.dragonbra.javasteam.steam.authentication.IAuthenticator
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import timber.log.Timber
import kotlinx.coroutines.channels.Channel
import java.util.concurrent.CompletableFuture

class SteamAuthenticator(var loginState : MutableStateFlow<UserLoginState>,
var submitChannel : Channel<String>,
var viewModelScope : CoroutineScope) : IAuthenticator {

var useGuardTotp: Boolean = false

override fun acceptDeviceConfirmation(): CompletableFuture<Boolean> {
Timber.tag("UserLoginViewModel").i("Two-Factor, device confirmation")

if (useGuardTotp) {
useGuardTotp = false
return CompletableFuture.completedFuture(false)
}

loginState.update { currentState ->
currentState.copy(
loginResult = LoginResult.DeviceConfirm,
loginScreen = LoginScreen.TWO_FACTOR,
isLoggingIn = false,
lastTwoFactorMethod = "steam_guard",
)
}

return CompletableFuture.completedFuture(true)
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

override fun getDeviceCode(previousCodeWasIncorrect: Boolean): CompletableFuture<String> {
Timber.tag("UserLoginViewModel").d("Two-Factor, device code")

loginState.update { currentState ->
currentState.copy(
loginResult = LoginResult.DeviceAuth,
loginScreen = LoginScreen.TWO_FACTOR,
isLoggingIn = false,
previousCodeIncorrect = previousCodeWasIncorrect,
lastTwoFactorMethod = "authenticator_code",
)
}

return CompletableFuture<String>().apply {
viewModelScope.launch {
Comment thread
peanut250 marked this conversation as resolved.
val code = submitChannel.receive()
complete(code)
}
}
}

override fun getEmailCode(
email: String?,
previousCodeWasIncorrect: Boolean,
): CompletableFuture<String> {
Timber.tag("UserLoginViewModel").d("Two-Factor, asking for email code")

loginState.update { currentState ->
currentState.copy(
loginResult = LoginResult.EmailAuth,
loginScreen = LoginScreen.TWO_FACTOR,
isLoggingIn = false,
email = email,
previousCodeIncorrect = previousCodeWasIncorrect,
lastTwoFactorMethod = "email_code",
)
}

return CompletableFuture<String>().apply {
viewModelScope.launch {
val code = submitChannel.receive()
complete(code)
}
}
}
}
81 changes: 17 additions & 64 deletions app/src/main/java/app/gamenative/ui/model/UserLoginViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ import app.gamenative.enums.LoginResult
import app.gamenative.enums.LoginScreen
import app.gamenative.events.AndroidEvent
import app.gamenative.events.SteamEvent
import app.gamenative.service.SteamAuthenticator
import app.gamenative.service.SteamService
import app.gamenative.ui.data.UserLoginState
import app.gamenative.PrefManager
import com.posthog.PostHog
import `in`.dragonbra.javasteam.steam.authentication.IAuthenticator
import java.util.concurrent.CompletableFuture
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
Expand All @@ -32,68 +31,7 @@ class UserLoginViewModel : ViewModel() {

private val submitChannel = Channel<String>()

private val authenticator = object : IAuthenticator {
override fun acceptDeviceConfirmation(): CompletableFuture<Boolean> {
Timber.tag("UserLoginViewModel").i("Two-Factor, device confirmation")

_loginState.update { currentState ->
currentState.copy(
loginResult = LoginResult.DeviceConfirm,
loginScreen = LoginScreen.TWO_FACTOR,
isLoggingIn = false,
lastTwoFactorMethod = "steam_guard",
)
}

return CompletableFuture.completedFuture(true)
}

override fun getDeviceCode(previousCodeWasIncorrect: Boolean): CompletableFuture<String> {
Timber.tag("UserLoginViewModel").d("Two-Factor, device code")

_loginState.update { currentState ->
currentState.copy(
loginResult = LoginResult.DeviceAuth,
loginScreen = LoginScreen.TWO_FACTOR,
isLoggingIn = false,
previousCodeIncorrect = previousCodeWasIncorrect,
lastTwoFactorMethod = "authenticator_code",
)
}

return CompletableFuture<String>().apply {
viewModelScope.launch {
val code = submitChannel.receive()
complete(code)
}
}
}

override fun getEmailCode(
email: String?,
previousCodeWasIncorrect: Boolean,
): CompletableFuture<String> {
Timber.tag("UserLoginViewModel").d("Two-Factor, asking for email code")

_loginState.update { currentState ->
currentState.copy(
loginResult = LoginResult.EmailAuth,
loginScreen = LoginScreen.TWO_FACTOR,
isLoggingIn = false,
email = email,
previousCodeIncorrect = previousCodeWasIncorrect,
lastTwoFactorMethod = "email_code",
)
}

return CompletableFuture<String>().apply {
viewModelScope.launch {
val code = submitChannel.receive()
complete(code)
}
}
}
}
Comment on lines -35 to -96
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was the reason to pull this out into a file?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just organizational taste/readability since it is slightly expanded to allow for the TOTP code method.

private val authenticator = SteamAuthenticator(_loginState, submitChannel, viewModelScope)

private val onSteamConnected: (SteamEvent.Connected) -> Unit = {
Timber.i("Received is connected")
Expand Down Expand Up @@ -321,6 +259,21 @@ class UserLoginViewModel : ViewModel() {
}
}

fun useGuardTotp() {
authenticator.useGuardTotp = true
Comment thread
peanut250 marked this conversation as resolved.

with(_loginState.value) {
viewModelScope.launch {
SteamService.startLoginWithCredentials(
username = username,
password = password,
rememberSession = rememberSession,
authenticator = authenticator,
)
}
}
}
Comment thread
peanut250 marked this conversation as resolved.

fun retryConnection(context: Context) {
// Reset error/login state if needed
_loginState.update { currentState ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.compose.material3.OutlinedTextFieldDefaults
import app.gamenative.ui.component.NoExtractOutlinedTextField
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
Expand Down Expand Up @@ -49,6 +50,7 @@ fun TwoFactorAuthScreenContent(
userLoginState: UserLoginState,
message: String,
onSetTwoFactor: (String) -> Unit,
onUseGuardTotp: () -> Unit,
onLogin: () -> Unit,
) {
Column(
Expand All @@ -69,6 +71,12 @@ fun TwoFactorAuthScreenContent(

if (userLoginState.loginResult == LoginResult.DeviceConfirm) {
LinearProgressIndicator(modifier = Modifier.fillMaxWidth())
Spacer(modifier = Modifier.height(16.dp))
TextButton(
onClick = onUseGuardTotp
) {
Text(stringResource(R.string.steam_2fa_use_guard_totp))
}
} else if (userLoginState.loginResult == LoginResult.EmailAuth ||
userLoginState.loginResult == LoginResult.DeviceAuth
) {
Expand Down Expand Up @@ -188,6 +196,9 @@ private fun Preview_TwoFactorAuthScreen(
onSetTwoFactor = { value ->
currentState = currentState.copy(twoFactorCode = value)
},
onUseGuardTotp = {
currentState = currentState.copy(twoFactorCode = "")
},
onLogin = {
currentState = currentState.copy(twoFactorCode = "")
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ fun UserLoginScreen(
onTwoFactorLogin = viewModel::submit,
onQrRetry = viewModel::onQrRetry,
onSetTwoFactor = viewModel::setTwoFactorCode,
onUseGuardTotp = viewModel::useGuardTotp,
onRetryConnection = onRetryConnection,
onContinueOffline = onContinueOffline,
onLaunchGog = { gogOAuthLauncher.launch(Intent(context, GOGOAuthActivity::class.java)) },
Expand All @@ -316,6 +317,7 @@ private fun UserLoginScreenContent(
onTwoFactorLogin: () -> Unit,
onQrRetry: () -> Unit,
onSetTwoFactor: (String) -> Unit,
onUseGuardTotp: () -> Unit,
onRetryConnection: () -> Unit,
onContinueOffline: () -> Unit,
onLaunchGog: () -> Unit,
Expand Down Expand Up @@ -448,6 +450,7 @@ private fun UserLoginScreenContent(
else -> ""
},
onSetTwoFactor = onSetTwoFactor,
onUseGuardTotp = onUseGuardTotp,
onLogin = onTwoFactorLogin,
)
} else {
Expand Down Expand Up @@ -977,6 +980,7 @@ private fun Preview_UserLoginScreen(
onTwoFactorLogin = { },
onQrRetry = { },
onSetTwoFactor = { },
onUseGuardTotp = { },
onShowLoginScreen = { },
onRetryConnection = { },
onContinueOffline = { },
Expand Down Expand Up @@ -1013,6 +1017,7 @@ private fun Preview_UserLoginScreen_Landscape(
onTwoFactorLogin = { },
onQrRetry = { },
onSetTwoFactor = { },
onUseGuardTotp = { },
onShowLoginScreen = { },
onRetryConnection = { },
onContinueOffline = { },
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-da/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,7 @@

<!-- TODO: Manual review - New strings from latest pull -->
<!-- Steam-specific dialogs -->
<string name="steam_2fa_use_guard_totp">Eller brug 2-faktor-godkendelseskoden</string>
<string name="steam_install_space_prompt">Appen der installeres har følgende pladskrav. Vil du fortsætte?\n\n\tDownload-størrelse: %1$s\n\tStørrelse på disk: %2$s\n\tTilgængelig plads: %3$s</string>
<string name="steam_install_space">Download-størrelse: %1$s\nStørrelse på disk: %2$s\nTilgængelig plads: %3$s</string>
<string name="steam_install_not_enough_space">Appen der installeres har brug for %1$s plads, men der er kun %2$s tilbage på denne enhed</string>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<string name="steam_2fa_confirmation">Bitte bestätige die Anmeldung in der Steam Mobile App…</string>
<string name="steam_2fa_device">Bitte gib deinen Zwei-Faktor-Code aus deiner Authenticator-App ein.</string>
<string name="steam_2fa_email">Bitte gib den Authentifizierungscode ein, der an die E-Mail-Adresse %s gesendet wurde</string>
<string name="steam_2fa_use_guard_totp">Oder verwende den Code für die Zwei-Faktor-Authentifizierung</string>
<string name="steam_install_space_prompt">Die App benötigt folgenden Speicherplatz. Möchtest du fortfahren?\n\n\tDownloadgröße: %1$s\n\tBelegter Speicher: %2$s\n\tVerfügbarer Speicher: %3$s</string>
<string name="steam_install_not_enough_space">Diese App benötigt %1$s Speicherplatz, aber auf diesem Gerät sind nur noch %2$s frei</string>
<string name="steam_cancel_download_message">Bist du sicher, dass du den Download der App abbrechen möchtest?</string>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<string name="steam_2fa_confirmation">Usa la aplicación móvil de Steam para confirmar tu inicio de sesión…</string>
<string name="steam_2fa_device">Introduce el código de autenticación de dos factores desde tu aplicación de autenticación.</string>
<string name="steam_2fa_email">Introduce el código de autenticación enviado al correo %s.</string>
<string name="steam_2fa_use_guard_totp">O utiliza el código de autenticación de dos factores</string>
<string name="steam_install_space_prompt">La aplicación a instalar requiere el siguiente espacio. ¿Deseas continuar?\n\n\tTamaño de descarga: %1$s\n\tTamaño en disco: %2$s\n\tEspacio disponible: %3$s</string>
<string name="steam_install_space">Tamaño de descarga: %1$s\nTamaño en disco: %2$s\nEspacio disponible: %3$s</string>
<string name="steam_install_not_enough_space">La aplicación a instalar requiere %1$s de espacio, pero solo quedan %2$s en este dispositivo.</string>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<string name="steam_2fa_confirmation">Utilisez l\'application mobile Steam pour confirmer votre connexion…</string>
<string name="steam_2fa_device">Veuillez entrer votre code d\'authentification à deux facteurs depuis votre application d\'authentification.</string>
<string name="steam_2fa_email">Veuillez entrer le code d\'authentification envoyé à l\'adresse %s</string>
<string name="steam_2fa_use_guard_totp">Ou utilisez le code d\'authentification à deux facteurs</string>
<string name="steam_install_space_prompt">L\'application en cours d\'installation nécessite l\'espace suivant. Voulez-vous continuer ?\n\n\tTaille du téléchargement : %1$s\n\tTaille sur le disque : %2$s\n\tEspace disponible : %3$s</string>
<string name="steam_install_space">Taille du téléchargement : %1$s\nTaille sur le disque : %2$s\nEspace disponible : %3$s</string>
<string name="steam_install_not_enough_space">L\'application en cours d\'installation nécessite %1$s d\'espace mais il ne reste que %2$s sur cet appareil</string>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-it/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<string name="steam_2fa_confirmation">Usa l\'app mobile di Steam per confermare l\'accesso…</string>
<string name="steam_2fa_device">Inserisci il codice di autenticazione a due fattori dalla tua app di autenticazione.</string>
<string name="steam_2fa_email">Inserisci il codice di autenticazione inviato all\'email %s</string>
<string name="steam_2fa_use_guard_totp">Oppure usa il codice di autenticazione a due fattori</string>
<string name="steam_install_space_prompt">L\'app che stai installando ha i seguenti requisiti di spazio. Vuoi procedere?\n\n\tDimensione Download: %1$s\n\tDimensione su Disco: %2$s\n\tSpazio Disponibile: %3$s</string>
<string name="steam_install_space">Dimensione Download: %1$s\nSpazio su Disco: %2$s\nSpazio Disponibile: %3$s</string>
<string name="steam_install_not_enough_space">L\'app che stai installando richiede %1$s di spazio ma sono rimasti solo %2$s su questo dispositivo</string>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-ko/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<string name="steam_2fa_confirmation">Steam 모바일 앱을 사용하여 로그인을 확인하세요…</string>
<string name="steam_2fa_device">인증 앱에서 2단계 인증 코드를 입력하세요.</string>
<string name="steam_2fa_email">%s 이메일로 전송된 인증 코드를 입력하세요</string>
<string name="steam_2fa_use_guard_totp">또는 2단계 인증 코드를 사용하세요</string>
<string name="steam_install_space_prompt">설치할 앱의 공간 요구사항은 다음과 같습니다. 계속하시겠습니까?\n\n\t다운로드 크기: %1$s\n\t디스크 사용량: %2$s\n\t사용 가능한 공간: %3$s</string>
<string name="steam_install_space">다운로드 크기: %1$s\n디스크 사용량: %2$s\n사용 가능한 공간: %3$s</string>
<string name="steam_install_not_enough_space">설치할 앱에 %1$s의 공간이 필요하지만 이 기기에는 %2$s만 남아있습니다</string>
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/res/values-pl/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<string name="steam_2fa_confirmation">Użyj aplikacji mobilnej Steam, aby potwierdzić logowanie…</string>
<string name="steam_2fa_device">Podaj kod uwierzytelniania dwuskładnikowego z aplikacji uwierzytelniającej.</string>
<string name="steam_2fa_email">Podaj kod uwierzytelniający wysłany na e-mail %s</string>
<string name="steam_2fa_use_guard_totp">Lub użyj kodu do uwierzytelniania dwuskładnikowego</string>
<string name="steam_install_space_prompt">Instalowana aplikacja ma następujące wymagania dotyczące miejsca. Czy chcesz kontynuować?\n\n\tRozmiar pobierania: %1$s\n\tRozmiar na dysku: %2$s\n\tDostępne miejsce: %3$s</string>
<string name="steam_install_space">Rozmiar pobierania: %1$s\nRozmiar na dysku: %2$s\nDostępne miejsce: %3$s</string>
<string name="steam_install_not_enough_space">Instalowana aplikacja wymaga %1$s miejsca, ale na tym urządzeniu pozostało tylko %2$s</string>
Expand Down Expand Up @@ -866,7 +867,7 @@
<string name="driver_manager">Menedżer sterowników</string>
<string name="select_a_driver">Wybierz sterownik</string>
<string name="import_zip_from_device">Importuj ZIP z urządzenia</string>

<!-- Contents Manager -->
<string name="contents_manager">Menedżer zawartości</string>
<string name="import_wcp_from_device">Importuj .wcp z urządzenia</string>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-pt-rBR/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,7 @@

<!-- TODO: Revisão manual - Novas strings do último pull -->
<!-- Diálogos específicos do Steam -->
<string name="steam_2fa_use_guard_totp">Ou use o código de autenticação de dois fatores</string>
<string name="steam_install_space_prompt">O aplicativo sendo instalado tem os seguintes requisitos de espaço. Deseja continuar?\n\n\tTamanho do download: %1$s\n\tTamanho no disco: %2$s\n\tEspaço disponível: %3$s</string>
<string name="steam_install_space">Tamanho do download: %1$s\nTamanho no disco: %2$s\nEspaço disponível: %3$s</string>
<string name="steam_install_not_enough_space">O aplicativo sendo instalado precisa de %1$s de espaço, mas há apenas %2$s restante neste dispositivo</string>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-ro/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<string name="steam_2fa_confirmation">Folosește aplicația Steam Mobile pentru a confirma autentificarea…</string>
<string name="steam_2fa_device">Introdu codul de autentificare din aplicația ta de autentificare.</string>
<string name="steam_2fa_email">Introdu codul trimis la adresa de email %s</string>
<string name="steam_2fa_use_guard_totp">Sau folosește codul de autentificare în doi pași</string>
<string name="steam_install_space_prompt">Aplicația ce urmează să fie instalată are următoarele cerințe de spațiu. Vrei să continui?\n\n\tDimensiune descărcare: %1$s\n\tSpațiu pe disc: %2$s\n\tSpațiu disponibil: %3$s</string>
<string name="steam_install_space">Dimensiune descărcare: %1$s\nSpațiu pe disc: %2$s\nSpațiu disponibil: %3$s</string>
<string name="steam_install_not_enough_space">Aplicația necesită %1$s spațiu, dar pe dispozitiv sunt disponibile doar %2$s</string>
Expand Down
Loading