Merge pull request #3355 from element-hq/feature/bma/resetIdentityIteration2
[Identity reset] Remove instruction to reset identity on another client.
This commit is contained in:
commit
0d6b4bc3c2
36 changed files with 67 additions and 247 deletions
|
|
@ -1,5 +1,5 @@
|
|||
appId: ${MAESTRO_APP_ID}
|
||||
---
|
||||
- extendedWaitUntil:
|
||||
visible: "Confirm that it's you"
|
||||
visible: "Confirm your identity"
|
||||
timeout: 20000
|
||||
|
|
|
|||
|
|
@ -32,9 +32,6 @@ interface SecureBackupEntryPoint : FeatureEntryPoint {
|
|||
@Parcelize
|
||||
data object EnterRecoveryKey : InitialTarget
|
||||
|
||||
@Parcelize
|
||||
data object CreateNewRecoveryKey : InitialTarget
|
||||
|
||||
@Parcelize
|
||||
data object ResetIdentity : InitialTarget
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ import dagger.assisted.Assisted
|
|||
import dagger.assisted.AssistedInject
|
||||
import io.element.android.anvilannotations.ContributesNode
|
||||
import io.element.android.features.securebackup.api.SecureBackupEntryPoint
|
||||
import io.element.android.features.securebackup.impl.createkey.CreateNewRecoveryKeyNode
|
||||
import io.element.android.features.securebackup.impl.disable.SecureBackupDisableNode
|
||||
import io.element.android.features.securebackup.impl.enable.SecureBackupEnableNode
|
||||
import io.element.android.features.securebackup.impl.enter.SecureBackupEnterRecoveryKeyNode
|
||||
|
|
@ -52,7 +51,6 @@ class SecureBackupFlowNode @AssistedInject constructor(
|
|||
initialElement = when (plugins.filterIsInstance<SecureBackupEntryPoint.Params>().first().initialElement) {
|
||||
SecureBackupEntryPoint.InitialTarget.Root -> NavTarget.Root
|
||||
SecureBackupEntryPoint.InitialTarget.EnterRecoveryKey -> NavTarget.EnterRecoveryKey
|
||||
SecureBackupEntryPoint.InitialTarget.CreateNewRecoveryKey -> NavTarget.CreateNewRecoveryKey
|
||||
is SecureBackupEntryPoint.InitialTarget.ResetIdentity -> NavTarget.ResetIdentity
|
||||
},
|
||||
savedStateMap = buildContext.savedStateMap,
|
||||
|
|
@ -79,9 +77,6 @@ class SecureBackupFlowNode @AssistedInject constructor(
|
|||
@Parcelize
|
||||
data object EnterRecoveryKey : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data object CreateNewRecoveryKey : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data object ResetIdentity : NavTarget
|
||||
}
|
||||
|
|
@ -141,16 +136,9 @@ class SecureBackupFlowNode @AssistedInject constructor(
|
|||
backstack.pop()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateNewRecoveryKey() {
|
||||
backstack.push(NavTarget.CreateNewRecoveryKey)
|
||||
}
|
||||
}
|
||||
createNode<SecureBackupEnterRecoveryKeyNode>(buildContext, plugins = listOf(callback))
|
||||
}
|
||||
NavTarget.CreateNewRecoveryKey -> {
|
||||
createNode<CreateNewRecoveryKeyNode>(buildContext)
|
||||
}
|
||||
is NavTarget.ResetIdentity -> {
|
||||
val callback = object : ResetIdentityFlowNode.Callback {
|
||||
override fun onDone() {
|
||||
|
|
|
|||
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.createkey
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
import io.element.android.anvilannotations.ContributesNode
|
||||
import io.element.android.libraries.core.meta.BuildMeta
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
|
||||
@ContributesNode(SessionScope::class)
|
||||
class CreateNewRecoveryKeyNode @AssistedInject constructor(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
private val buildMeta: BuildMeta,
|
||||
) : Node(buildContext, plugins = plugins) {
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
CreateNewRecoveryKeyView(
|
||||
desktopApplicationName = buildMeta.desktopApplicationName,
|
||||
modifier = modifier,
|
||||
onBackClick = ::navigateUp,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.createkey
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.features.securebackup.impl.R
|
||||
import io.element.android.libraries.designsystem.atomic.organisms.NumberedListOrganism
|
||||
import io.element.android.libraries.designsystem.components.BigIcon
|
||||
import io.element.android.libraries.designsystem.components.PageTitle
|
||||
import io.element.android.libraries.designsystem.components.button.BackButton
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.Scaffold
|
||||
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
||||
import io.element.android.libraries.designsystem.utils.annotatedTextWithBold
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun CreateNewRecoveryKeyView(
|
||||
desktopApplicationName: String,
|
||||
onBackClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
topBar = {
|
||||
TopAppBar(title = {}, navigationIcon = { BackButton(onClick = onBackClick) })
|
||||
}
|
||||
) { padding ->
|
||||
Column(
|
||||
modifier = Modifier.padding(padding)
|
||||
) {
|
||||
PageTitle(
|
||||
modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 40.dp),
|
||||
title = stringResource(R.string.screen_create_new_recovery_key_title),
|
||||
iconStyle = BigIcon.Style.Default(CompoundIcons.Computer())
|
||||
)
|
||||
Content(desktopApplicationName = desktopApplicationName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Content(desktopApplicationName: String) {
|
||||
val listItems = buildList {
|
||||
add(AnnotatedString(stringResource(R.string.screen_create_new_recovery_key_list_item_1, desktopApplicationName)))
|
||||
add(AnnotatedString(stringResource(R.string.screen_create_new_recovery_key_list_item_2)))
|
||||
add(
|
||||
annotatedTextWithBold(
|
||||
text = stringResource(
|
||||
id = R.string.screen_create_new_recovery_key_list_item_3,
|
||||
stringResource(R.string.screen_create_new_recovery_key_list_item_3_reset_all)
|
||||
),
|
||||
boldText = stringResource(R.string.screen_create_new_recovery_key_list_item_3_reset_all)
|
||||
)
|
||||
)
|
||||
add(AnnotatedString(stringResource(R.string.screen_create_new_recovery_key_list_item_4)))
|
||||
add(AnnotatedString(stringResource(R.string.screen_create_new_recovery_key_list_item_5)))
|
||||
}
|
||||
NumberedListOrganism(modifier = Modifier.padding(horizontal = 16.dp), items = listItems.toImmutableList())
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun CreateNewRecoveryKeyViewPreview() {
|
||||
ElementPreview {
|
||||
CreateNewRecoveryKeyView(
|
||||
desktopApplicationName = "Element",
|
||||
onBackClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -35,7 +35,6 @@ class SecureBackupEnterRecoveryKeyNode @AssistedInject constructor(
|
|||
) : Node(buildContext, plugins = plugins) {
|
||||
interface Callback : Plugin {
|
||||
fun onEnterRecoveryKeySuccess()
|
||||
fun onCreateNewRecoveryKey()
|
||||
}
|
||||
|
||||
private val callback = plugins<Callback>().first()
|
||||
|
|
@ -48,7 +47,6 @@ class SecureBackupEnterRecoveryKeyNode @AssistedInject constructor(
|
|||
modifier = modifier,
|
||||
onSuccess = callback::onEnterRecoveryKeySuccess,
|
||||
onBackClick = ::navigateUp,
|
||||
onCreateNewRecoveryKey = callback::onCreateNewRecoveryKey
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ import io.element.android.libraries.designsystem.components.async.AsyncActionVie
|
|||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.Button
|
||||
import io.element.android.libraries.designsystem.theme.components.TextButton
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Composable
|
||||
|
|
@ -41,7 +40,6 @@ fun SecureBackupEnterRecoveryKeyView(
|
|||
state: SecureBackupEnterRecoveryKeyState,
|
||||
onSuccess: () -> Unit,
|
||||
onBackClick: () -> Unit,
|
||||
onCreateNewRecoveryKey: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
AsyncActionView(
|
||||
|
|
@ -60,7 +58,7 @@ fun SecureBackupEnterRecoveryKeyView(
|
|||
iconStyle = BigIcon.Style.Default(CompoundIcons.KeySolid()),
|
||||
title = stringResource(id = R.string.screen_recovery_key_confirm_title),
|
||||
subTitle = stringResource(id = R.string.screen_recovery_key_confirm_description),
|
||||
buttons = { Buttons(state = state, onCreateRecoveryKey = onCreateNewRecoveryKey) }
|
||||
buttons = { Buttons(state = state) }
|
||||
) {
|
||||
Content(state = state)
|
||||
}
|
||||
|
|
@ -86,7 +84,6 @@ private fun Content(
|
|||
@Composable
|
||||
private fun ColumnScope.Buttons(
|
||||
state: SecureBackupEnterRecoveryKeyState,
|
||||
onCreateRecoveryKey: () -> Unit,
|
||||
) {
|
||||
Button(
|
||||
text = stringResource(id = CommonStrings.action_continue),
|
||||
|
|
@ -97,12 +94,6 @@ private fun ColumnScope.Buttons(
|
|||
state.eventSink.invoke(SecureBackupEnterRecoveryKeyEvents.Submit)
|
||||
}
|
||||
)
|
||||
TextButton(
|
||||
text = stringResource(id = R.string.screen_recovery_key_confirm_lost_recovery_key),
|
||||
enabled = !state.submitAction.isLoading(),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = onCreateRecoveryKey,
|
||||
)
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
|
|
@ -114,6 +105,5 @@ internal fun SecureBackupEnterRecoveryKeyViewPreview(
|
|||
state = state,
|
||||
onSuccess = {},
|
||||
onBackClick = {},
|
||||
onCreateNewRecoveryKey = {},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ class ResetIdentityFlowManager @Inject constructor(
|
|||
@SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope,
|
||||
private val sessionVerificationService: SessionVerificationService,
|
||||
) {
|
||||
private val resetHandleFlow: MutableStateFlow<AsyncData<IdentityResetHandle>> = MutableStateFlow(AsyncData.Uninitialized)
|
||||
val currentHandleFlow: StateFlow<AsyncData<IdentityResetHandle>> = resetHandleFlow
|
||||
private val resetHandleFlow: MutableStateFlow<AsyncData<IdentityResetHandle?>> = MutableStateFlow(AsyncData.Uninitialized)
|
||||
val currentHandleFlow: StateFlow<AsyncData<IdentityResetHandle?>> = resetHandleFlow
|
||||
private var whenResetIsDoneWaitingJob: Job? = null
|
||||
|
||||
fun whenResetIsDone(block: () -> Unit) {
|
||||
|
|
@ -47,7 +47,7 @@ class ResetIdentityFlowManager @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun getResetHandle(): StateFlow<AsyncData<IdentityResetHandle>> {
|
||||
fun getResetHandle(): StateFlow<AsyncData<IdentityResetHandle?>> {
|
||||
return if (resetHandleFlow.value.isLoading() || resetHandleFlow.value.isSuccess()) {
|
||||
resetHandleFlow
|
||||
} else {
|
||||
|
|
@ -56,13 +56,11 @@ class ResetIdentityFlowManager @Inject constructor(
|
|||
sessionCoroutineScope.launch {
|
||||
matrixClient.encryptionService().startIdentityReset()
|
||||
.onSuccess { handle ->
|
||||
resetHandleFlow.value = if (handle != null) {
|
||||
AsyncData.Success(handle)
|
||||
} else {
|
||||
AsyncData.Failure(IllegalStateException("Could not get a reset identity handle"))
|
||||
}
|
||||
resetHandleFlow.value = AsyncData.Success(handle)
|
||||
}
|
||||
.onFailure {
|
||||
resetHandleFlow.value = AsyncData.Failure(it)
|
||||
}
|
||||
.onFailure { resetHandleFlow.value = AsyncData.Failure(it) }
|
||||
}
|
||||
|
||||
resetHandleFlow
|
||||
|
|
|
|||
|
|
@ -140,6 +140,9 @@ class ResetIdentityFlowNode @AssistedInject constructor(
|
|||
}
|
||||
is AsyncData.Success -> {
|
||||
when (val handle = state.data) {
|
||||
null -> {
|
||||
Timber.d("No reset handle return, the reset is done.")
|
||||
}
|
||||
is IdentityOidcResetHandle -> {
|
||||
if (oidcEntryPoint.canUseCustomTab()) {
|
||||
activity.openUrlInChromeCustomTab(null, false, handle.url)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
<string name="screen_encryption_reset_bullet_2">"You will lose your existing message history"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"You will need to verify all your existing devices and contacts again"</string>
|
||||
<string name="screen_encryption_reset_footer">"Only reset your identity if you don’t have access to another signed-in device and you’ve lost your recovery key."</string>
|
||||
<string name="screen_encryption_reset_subtitle">"If you’re not signed in to any other devices and you’ve lost your recovery key, then you’ll need to reset your identity to continue using the app. "</string>
|
||||
<string name="screen_encryption_reset_subtitle">"If you’re not signed in to any other devices and you’ve lost your recovery key, then you’ll need to reset your identity to continue using the app."</string>
|
||||
<string name="screen_encryption_reset_title">"Reset your identity in case you can’t confirm another way"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Turn off"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"You will lose your encrypted messages if you are signed out of all devices."</string>
|
||||
|
|
|
|||
|
|
@ -101,18 +101,6 @@ class SecureBackupEnterRecoveryKeyViewTest {
|
|||
recorder.assertSingle(SecureBackupEnterRecoveryKeyEvents.Submit)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `tapping on Lost your recovery key - calls onCreateNewRecoveryKey`() {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setSecureBackupEnterRecoveryKeyView(
|
||||
aSecureBackupEnterRecoveryKeyState(),
|
||||
onCreateNewRecoveryKey = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_recovery_key_confirm_lost_recovery_key)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when submit action succeeds - calls onDone`() {
|
||||
ensureCalledOnce { callback ->
|
||||
|
|
@ -127,14 +115,12 @@ class SecureBackupEnterRecoveryKeyViewTest {
|
|||
state: SecureBackupEnterRecoveryKeyState,
|
||||
onDone: () -> Unit = EnsureNeverCalled(),
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
onCreateNewRecoveryKey: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
setContent {
|
||||
SecureBackupEnterRecoveryKeyView(
|
||||
state = state,
|
||||
onSuccess = onDone,
|
||||
onBackClick = onBackClick,
|
||||
onCreateNewRecoveryKey = onCreateNewRecoveryKey
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,14 +66,16 @@ class ResetIdentityFlowManagerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `getResetHandle - will fail if it receives a null reset handle`() = runTest {
|
||||
fun `getResetHandle - will success if it receives a null reset handle`() = runTest {
|
||||
val startResetLambda = lambdaRecorder<Result<IdentityResetHandle?>> { Result.success(null) }
|
||||
val encryptionService = FakeEncryptionService(startIdentityResetLambda = startResetLambda)
|
||||
val flowManager = createFlowManager(encryptionService = encryptionService)
|
||||
|
||||
flowManager.getResetHandle().test {
|
||||
assertThat(awaitItem().isLoading()).isTrue()
|
||||
assertThat(awaitItem().isFailure()).isTrue()
|
||||
val finalItem = awaitItem()
|
||||
assertThat(finalItem.isSuccess()).isTrue()
|
||||
assertThat(finalItem.dataOrNull()).isNull()
|
||||
startResetLambda.assertions().isCalledOnce()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<string name="screen_identity_confirmation_cannot_confirm">"Can\'t confirm?"</string>
|
||||
<string name="screen_identity_confirmation_create_new_recovery_key">"Create a new recovery key"</string>
|
||||
<string name="screen_identity_confirmation_subtitle">"Verify this device to set up secure messaging."</string>
|
||||
<string name="screen_identity_confirmation_title">"Confirm that it\'s you"</string>
|
||||
<string name="screen_identity_confirmation_title">"Confirm your identity"</string>
|
||||
<string name="screen_identity_confirmation_use_another_device">"Use another device"</string>
|
||||
<string name="screen_identity_confirmation_use_recovery_key">"Use recovery key"</string>
|
||||
<string name="screen_identity_confirmed_subtitle">"Now you can read or send messages securely, and anyone you chat with can also trust this device."</string>
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ interface EncryptionService {
|
|||
/**
|
||||
* A handle to reset the user's identity.
|
||||
*/
|
||||
interface IdentityResetHandle {
|
||||
sealed interface IdentityResetHandle {
|
||||
/**
|
||||
* Cancel the reset process and drops the existing handle in the SDK.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package io.element.android.libraries.matrix.impl.encryption
|
||||
|
||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||
import io.element.android.libraries.core.extensions.flatMap
|
||||
import io.element.android.libraries.core.extensions.mapFailure
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.matrix.api.encryption.BackupState
|
||||
|
|
@ -204,9 +205,9 @@ internal class RustEncryptionService(
|
|||
|
||||
override suspend fun startIdentityReset(): Result<IdentityResetHandle?> {
|
||||
return runCatching {
|
||||
service.resetIdentity()?.let { handle ->
|
||||
RustIdentityResetHandleFactory.create(sessionId, handle)
|
||||
}?.getOrNull()
|
||||
service.resetIdentity()
|
||||
}.flatMap { handle ->
|
||||
RustIdentityResetHandleFactory.create(sessionId, handle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,13 +27,15 @@ import org.matrix.rustcomponents.sdk.CrossSigningResetAuthType
|
|||
object RustIdentityResetHandleFactory {
|
||||
fun create(
|
||||
userId: UserId,
|
||||
identityResetHandle: org.matrix.rustcomponents.sdk.IdentityResetHandle
|
||||
): Result<IdentityResetHandle> {
|
||||
identityResetHandle: org.matrix.rustcomponents.sdk.IdentityResetHandle?
|
||||
): Result<IdentityResetHandle?> {
|
||||
return runCatching {
|
||||
when (val authType = identityResetHandle.authType()) {
|
||||
is CrossSigningResetAuthType.Oidc -> RustOidcIdentityResetHandle(identityResetHandle, authType.info.approvalUrl)
|
||||
// User interactive authentication (user + password)
|
||||
CrossSigningResetAuthType.Uiaa -> RustPasswordIdentityResetHandle(userId, identityResetHandle)
|
||||
identityResetHandle?.let {
|
||||
when (val authType = identityResetHandle.authType()) {
|
||||
is CrossSigningResetAuthType.Oidc -> RustOidcIdentityResetHandle(identityResetHandle, authType.info.approvalUrl)
|
||||
// User interactive authentication (user + password)
|
||||
CrossSigningResetAuthType.Uiaa -> RustPasswordIdentityResetHandle(userId, identityResetHandle)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d3d1bbc0c03ac483d0047bc4711eb63741c2071f013ee5962a1184e6112bef0c
|
||||
size 60386
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b2162a49d87b23c25251c6a8c322ec62eee2eb34e802ab5ce2ecacb637735554
|
||||
size 59189
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:485585964998ee6bb7bb6ba208f2f465795a1b1ef59b3e44535b2d60ba9ef8a4
|
||||
size 37761
|
||||
oid sha256:ed7c737e5e7cfa37f588f17723be581ad24d217e8f5fe8ce52de85ac32753641
|
||||
size 33292
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:95a05799a39675cfbb8c2df269131e5dd236c3298a1dadafe15b7c89a62be962
|
||||
size 49077
|
||||
oid sha256:48077b5e8a98b426335219721e8da6b378c702cb0b0b3902656b22df24a50b6d
|
||||
size 44792
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:254973e1b41987fb6dd9db63b5acae4557467e2541867a4fb9448b88851e5fe4
|
||||
size 46993
|
||||
oid sha256:8217fdb69d5fba3e7bf2241d32a2821c72c9c628b0f97f77154ea53ff4a7bba7
|
||||
size 43206
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:cb58ee8ee32d1e308b898980f27317193bff4b0e00f800037834b02793b34dce
|
||||
size 41111
|
||||
oid sha256:49f3902dbf6a146506166469ae727bc2925af6e19f1a9a6d65bf029467685f3d
|
||||
size 37444
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2d2fc075202325aece0e74f962e5e6a387934d7782a1b39a9226c2b529ecf0b1
|
||||
size 36809
|
||||
oid sha256:2a3f34a36986bf00253ec1d85ec440d3b823853559863076784379cb08aa0060
|
||||
size 32393
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6909fcc10374f46d14ed628a4c1df0f4aba1fba874d2aa1b5554a74409dae861
|
||||
size 47737
|
||||
oid sha256:78a85eb229e35238976a5dffa8afa2647fee534a205dc1621ce60eb82d1e5a06
|
||||
size 43530
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:48e95b0eac9a83ce6abf5d82e904faf4081496d399eed9f8e4d806393f042a14
|
||||
size 46286
|
||||
oid sha256:28d59abaa2ac4185e3f2cd926557fd2a75cf7f60911d0af971fbbb34f8edd921
|
||||
size 42539
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:83c91d4e1bc3b9021c91d353b63a63c1893fdc79de57f91d8a6446b84bae657a
|
||||
size 38441
|
||||
oid sha256:704f7d76ec2617a7cacecd5d6b3379f856c9e0d65cc8d328e9845435e3b5329c
|
||||
size 34787
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e9b7a1e2d20171a78da4ce4f590372e1d84f9624c4d56a011e74f91105c09f36
|
||||
size 79989
|
||||
oid sha256:45293f2b31c12ae11e2972e502618bad0a2cd78957ac0d80780ed43dff3b5727
|
||||
size 79919
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c3c38d62929774fe6e6e003f656efbeec1f675b5dbb9994a917c4978f64d61a9
|
||||
size 78280
|
||||
oid sha256:be591f829e9deed65671eb9273ffa4319c0fcc6d7c155a83fdc4b8b0dee7048f
|
||||
size 78322
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ee9c90a91ef8703c4878ea9314121ad8343dd3392c051e7e3e3079198a32ef99
|
||||
size 30555
|
||||
oid sha256:711074ce017e2909ae1cb610925bf7be96e182095cb08de5ca1d57b4dd206c92
|
||||
size 30834
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a4b44b23029dd1ff76a082a29c0b39584a1e20c92795eb4815d632608abd2858
|
||||
size 22702
|
||||
oid sha256:4643c1011d807a1cb728b8cebab2c8c16276b680ccdd795a64fe449d1da80c7c
|
||||
size 22982
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ce48c81c355317abd6b9de4600e86492c3acde2807ca3572e064b61abc06239c
|
||||
size 29426
|
||||
oid sha256:c242503ced2d16da2fd8c738e198689b60d00d40d423b52820aa01a622acd39a
|
||||
size 29695
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4d9810f3b326a05492c870ef22dbceec19112dba8beaa000066504cc96d1387a
|
||||
size 23913
|
||||
oid sha256:d8d6fedd34ea54f9492bdc74f784aac902717328e3eda83f97d06e1eef970424
|
||||
size 24201
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:453cab91aa056f3536c899354a2fb5de21519e7dce3d5675b1cbca702000e2c1
|
||||
size 29602
|
||||
oid sha256:df4be3e3577698e939dc02ebc0819768c04525a6b6cc67386e33501610dff5b2
|
||||
size 29959
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f468a4a9140c4dc23ab3d394049f59b86f0ca2f332bee50abf8eaa0acce166b5
|
||||
size 22030
|
||||
oid sha256:76d12c58b8b1c60295a137136af5a6eed8d665600fb4f3e6feeaff714aa207ac
|
||||
size 22396
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c21120a08c871c7f64952c20be2c90b28590901f8e52893702775b6b2f176892
|
||||
size 28524
|
||||
oid sha256:a229523ad1f17f957adaffb47e8a64679bc3636ab94641bc492f98b7f5d3fe3d
|
||||
size 28861
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1e46ffc3c3679eb5490d01c34d02314bae5611a7b10fb3c758331a28ae78f065
|
||||
size 23267
|
||||
oid sha256:b090b019f8d0a98b9e0ec4e4bd53628af15737eb441f36f40ba4abceb4c75608
|
||||
size 23622
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue