PM-35444: bug: Pass org identifier and email directly into continueKeyConnectorLogin function (#6817)

This commit is contained in:
David Perez
2026-04-21 18:53:24 -05:00
committed by GitHub
parent 308a1f98b7
commit 72cd8f5abc
6 changed files with 53 additions and 27 deletions

View File

@@ -230,7 +230,10 @@ interface AuthRepository :
/**
* Continue the previously halted login attempt.
*/
suspend fun continueKeyConnectorLogin(): LoginResult
suspend fun continueKeyConnectorLogin(
orgIdentifier: String,
email: String,
): LoginResult
/**
* Cancel the previously halted login attempt.

View File

@@ -676,15 +676,18 @@ class AuthRepositoryImpl(
error = MissingPropertyException("Identity Token Auth Model"),
)
override suspend fun continueKeyConnectorLogin(): LoginResult {
override suspend fun continueKeyConnectorLogin(
orgIdentifier: String,
email: String,
): LoginResult {
val response = keyConnectorResponse ?: return LoginResult.Error(
errorMessage = null,
error = MissingPropertyException("Key Connector Response"),
)
return handleLoginCommonSuccess(
loginResponse = response,
email = rememberedEmailAddress.orEmpty(),
orgIdentifier = rememberedOrgIdentifier,
email = email,
orgIdentifier = orgIdentifier,
password = null,
deviceData = null,
userConfirmedKeyConnector = true,

View File

@@ -52,6 +52,7 @@ class EnterpriseSignOnViewModel @Inject constructor(
?: EnterpriseSignOnState(
dialogState = null,
orgIdentifierInput = "",
emailAddress = savedStateHandle.toEnterpriseSignOnArgs().emailAddress,
),
) {
@@ -231,7 +232,7 @@ class EnterpriseSignOnViewModel @Inject constructor(
mutableStateFlow.update {
it.copy(
dialogState = null,
orgIdentifierInput = authRepository.rememberedOrgIdentifier ?: "",
orgIdentifierInput = authRepository.rememberedOrgIdentifier.orEmpty(),
)
}
}
@@ -249,7 +250,7 @@ class EnterpriseSignOnViewModel @Inject constructor(
mutableStateFlow.update {
it.copy(
dialogState = null,
orgIdentifierInput = authRepository.rememberedOrgIdentifier ?: "",
orgIdentifierInput = authRepository.rememberedOrgIdentifier.orEmpty(),
)
}
return
@@ -456,7 +457,10 @@ class EnterpriseSignOnViewModel @Inject constructor(
private fun handleConfirmKeyConnectorDomainClick() {
showLoading()
viewModelScope.launch {
val result = authRepository.continueKeyConnectorLogin()
val result = authRepository.continueKeyConnectorLogin(
orgIdentifier = state.orgIdentifierInput,
email = state.emailAddress,
)
sendAction(EnterpriseSignOnAction.Internal.OnLoginResult(result))
}
}
@@ -474,6 +478,7 @@ class EnterpriseSignOnViewModel @Inject constructor(
data class EnterpriseSignOnState(
val dialogState: DialogState?,
val orgIdentifierInput: String,
val emailAddress: String,
) : Parcelable {
/**
* Represents the current state of any dialogs on the screen.

View File

@@ -4007,7 +4007,6 @@ class AuthRepositoryTest {
environmentUrlData = EnvironmentUrlDataJson.DEFAULT_US,
)
} returns SINGLE_USER_STATE_1
repository.rememberedOrgIdentifier = ORGANIZATION_IDENTIFIER
val result = repository.login(
email = EMAIL,
@@ -4019,7 +4018,10 @@ class AuthRepositoryTest {
assertEquals(LoginResult.ConfirmKeyConnectorDomain(keyConnectorUrl), result)
val continueResult = repository.continueKeyConnectorLogin()
val continueResult = repository.continueKeyConnectorLogin(
orgIdentifier = ORGANIZATION_IDENTIFIER,
email = EMAIL,
)
assertEquals(LoginResult.Error(errorMessage = null, error = error), continueResult)
fakeAuthDiskSource.assertPrivateKey(userId = USER_ID_1, privateKey = null)
fakeAuthDiskSource.assertAccountKeys(userId = USER_ID_1, accountKeys = null)
@@ -4117,7 +4119,6 @@ class AuthRepositoryTest {
environmentUrlData = EnvironmentUrlDataJson.DEFAULT_US,
)
} returns SINGLE_USER_STATE_1
repository.rememberedOrgIdentifier = ORGANIZATION_IDENTIFIER
val result = repository.login(
email = EMAIL,
ssoCode = SSO_CODE,
@@ -4128,7 +4129,10 @@ class AuthRepositoryTest {
assertEquals(LoginResult.ConfirmKeyConnectorDomain(keyConnectorUrl), result)
val continueResult = repository.continueKeyConnectorLogin()
val continueResult = repository.continueKeyConnectorLogin(
orgIdentifier = ORGANIZATION_IDENTIFIER,
email = EMAIL,
)
assertEquals(LoginResult.Success, continueResult)
assertEquals(AuthState.Authenticated(ACCESS_TOKEN), repository.authStateFlow.value)
fakeAuthDiskSource.assertPrivateKey(userId = USER_ID_1, privateKey = PRIVATE_KEY)
@@ -4291,8 +4295,6 @@ class AuthRepositoryTest {
)
} returns VaultUnlockResult.Success
repository.rememberedOrgIdentifier = ORGANIZATION_IDENTIFIER
val loginResult = repository.login(
email = EMAIL,
ssoCode = SSO_CODE,
@@ -4302,7 +4304,10 @@ class AuthRepositoryTest {
)
assertEquals(LoginResult.ConfirmKeyConnectorDomain(keyConnectorUrl), loginResult)
val result = repository.continueKeyConnectorLogin()
val result = repository.continueKeyConnectorLogin(
orgIdentifier = ORGANIZATION_IDENTIFIER,
email = EMAIL,
)
assertEquals(LoginResult.Success, result)
assertEquals(AuthState.Authenticated(ACCESS_TOKEN), repository.authStateFlow.value)
fakeAuthDiskSource.assertPrivateKey(userId = USER_ID_1, privateKey = "privateKey")
@@ -7511,7 +7516,10 @@ class AuthRepositoryTest {
@Test
fun `continueKeyConnectorLogin returns error if keyConnectorResponse is null`() =
runTest {
val continueResult = repository.continueKeyConnectorLogin()
val continueResult = repository.continueKeyConnectorLogin(
orgIdentifier = ORGANIZATION_IDENTIFIER,
email = EMAIL,
)
assertEquals(
LoginResult.Error(
errorMessage = null,

View File

@@ -282,11 +282,10 @@ class EnterpriseSignOnScreenTest : BitwardenComposeTest() {
.performClick()
verify { viewModel.trySendAction(EnterpriseSignOnAction.CancelKeyConnectorDomainClick) }
}
companion object {
private val DEFAULT_STATE = EnterpriseSignOnState(
dialogState = null,
orgIdentifierInput = "",
)
}
}
private val DEFAULT_STATE = EnterpriseSignOnState(
dialogState = null,
orgIdentifierInput = "",
emailAddress = "test@gmail.com",
)

View File

@@ -1150,14 +1150,18 @@ class EnterpriseSignOnViewModelTest : BaseViewModelTest() {
@Test
fun `ConfirmKeyConnectorDomainClick with login Success should show loading dialog and hide it`() =
runTest {
val orgIdentifier = "Bitwarden"
coEvery {
authRepository.continueKeyConnectorLogin()
authRepository.continueKeyConnectorLogin(
orgIdentifier = orgIdentifier,
email = DEFAULT_EMAIL,
)
} returns LoginResult.Success
coEvery {
authRepository.rememberedOrgIdentifier
} returns "Bitwarden"
} returns orgIdentifier
val initialState = DEFAULT_STATE.copy(orgIdentifierInput = "Bitwarden")
val initialState = DEFAULT_STATE.copy(orgIdentifierInput = orgIdentifier)
val viewModel = createViewModel(
initialState = initialState,
ssoData = DEFAULT_SSO_DATA,
@@ -1187,7 +1191,10 @@ class EnterpriseSignOnViewModelTest : BaseViewModelTest() {
}
coVerify(exactly = 1) {
authRepository.continueKeyConnectorLogin()
authRepository.continueKeyConnectorLogin(
orgIdentifier = orgIdentifier,
email = DEFAULT_EMAIL,
)
}
}
@@ -1271,13 +1278,14 @@ class EnterpriseSignOnViewModelTest : BaseViewModelTest() {
}
}
private const val DEFAULT_EMAIL = "test@gmail.com"
private val DEFAULT_STATE = EnterpriseSignOnState(
dialogState = null,
orgIdentifierInput = "",
emailAddress = DEFAULT_EMAIL,
)
private val DEFAULT_SSO_DATA = SsoResponseData(
redirectUri = "https://bitwarden.com/sso-callback",
state = "abc",
codeVerifier = "def",
)
private const val DEFAULT_EMAIL = "test@gmail.com"