Link new device using QrCode.
This commit is contained in:
parent
5ebb615751
commit
a073117d62
94 changed files with 4431 additions and 36 deletions
|
|
@ -18,6 +18,8 @@ import io.element.android.libraries.matrix.api.core.SessionId
|
|||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters
|
||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||
import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopHandler
|
||||
import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileHandler
|
||||
import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
|
||||
import io.element.android.libraries.matrix.api.media.MediaPreviewService
|
||||
import io.element.android.libraries.matrix.api.notification.NotificationService
|
||||
|
|
@ -95,6 +97,9 @@ class FakeMatrixClient(
|
|||
private val deactivateAccountResult: (String, Boolean) -> Result<Unit> = { _, _ -> lambdaError() },
|
||||
private val currentSlidingSyncVersionLambda: () -> Result<SlidingSyncVersion> = { lambdaError() },
|
||||
private val ignoreUserResult: (UserId) -> Result<Unit> = { lambdaError() },
|
||||
private val canLinkNewDeviceResult: () -> Result<Boolean> = { lambdaError() },
|
||||
private val createLinkMobileHandlerResult: () -> Result<LinkMobileHandler> = { lambdaError() },
|
||||
private val createLinkDesktopHandlerResult: () -> Result<LinkDesktopHandler> = { lambdaError() },
|
||||
private var unIgnoreUserResult: (UserId) -> Result<Unit> = { Result.success(Unit) },
|
||||
private val canReportRoomLambda: () -> Boolean = { false },
|
||||
private val isLivekitRtcSupportedLambda: () -> Boolean = { false },
|
||||
|
|
@ -356,4 +361,16 @@ class FakeMatrixClient(
|
|||
override suspend fun performDatabaseVacuum(): Result<Unit> {
|
||||
return performDatabaseVacuumLambda()
|
||||
}
|
||||
|
||||
override suspend fun canLinkNewDevice(): Result<Boolean> = simulateLongTask {
|
||||
return canLinkNewDeviceResult()
|
||||
}
|
||||
|
||||
override fun createLinkDesktopHandler(): Result<LinkDesktopHandler> {
|
||||
return createLinkDesktopHandlerResult()
|
||||
}
|
||||
|
||||
override fun createLinkMobileHandler(): Result<LinkMobileHandler> {
|
||||
return createLinkMobileHandlerResult()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,3 +100,31 @@ const val A_LOGIN_HINT = "mxid:@alice:example.org"
|
|||
|
||||
@ColorInt
|
||||
const val A_COLOR_INT: Int = 0xFFFF0000.toInt()
|
||||
|
||||
// From https://github.com/matrix-org/matrix-rust-sdk/blob/3a63838cdb50cde3d74da920186fbae0a2e6db37/crates/matrix-sdk-crypto/src/types/qr_login.rs#L275
|
||||
// Test vector for the QR code data, copied from the MSC.
|
||||
@Suppress("ktlint:standard:argument-list-wrapping")
|
||||
val QR_CODE_DATA = listOf(
|
||||
0x4D, 0x41, 0x54, 0x52, 0x49, 0x58, 0x02, 0x03, 0xd8, 0x86, 0x68, 0x6a, 0xb2, 0x19, 0x7b,
|
||||
0x78, 0x0e, 0x30, 0x0a, 0x9d, 0x4a, 0x21, 0x47, 0x48, 0x07, 0x00, 0xd7, 0x92, 0x9f, 0x39,
|
||||
0xab, 0x31, 0xb9, 0xe5, 0x14, 0x37, 0x02, 0x48, 0xed, 0x6b, 0x00, 0x47, 0x68, 0x74, 0x74,
|
||||
0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x7a, 0x76, 0x6f, 0x75, 0x73,
|
||||
0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x64, 0x65,
|
||||
0x76, 0x2f, 0x65, 0x38, 0x64, 0x61, 0x36, 0x33, 0x35, 0x35, 0x2d, 0x35, 0x35, 0x30, 0x62,
|
||||
0x2d, 0x34, 0x61, 0x33, 0x32, 0x2d, 0x61, 0x31, 0x39, 0x33, 0x2d, 0x31, 0x36, 0x31, 0x39,
|
||||
0x64, 0x39, 0x38, 0x33, 0x30, 0x36, 0x36, 0x38,
|
||||
).map { it.toByte() }.toByteArray()
|
||||
|
||||
// Test vector for the QR code data, copied from the MSC, with the mode set to reciprocate.
|
||||
@Suppress("ktlint:standard:argument-list-wrapping")
|
||||
val QR_CODE_DATA_RECIPROCATE = listOf(
|
||||
0x4D, 0x41, 0x54, 0x52, 0x49, 0x58, 0x02, 0x04, 0xd8, 0x86, 0x68, 0x6a, 0xb2, 0x19, 0x7b,
|
||||
0x78, 0x0e, 0x30, 0x0a, 0x9d, 0x4a, 0x21, 0x47, 0x48, 0x07, 0x00, 0xd7, 0x92, 0x9f, 0x39,
|
||||
0xab, 0x31, 0xb9, 0xe5, 0x14, 0x37, 0x02, 0x48, 0xed, 0x6b, 0x00, 0x47, 0x68, 0x74, 0x74,
|
||||
0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x7a, 0x76, 0x6f, 0x75, 0x73,
|
||||
0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x64, 0x65,
|
||||
0x76, 0x2f, 0x65, 0x38, 0x64, 0x61, 0x36, 0x33, 0x35, 0x35, 0x2d, 0x35, 0x35, 0x30, 0x62,
|
||||
0x2d, 0x34, 0x61, 0x33, 0x32, 0x2d, 0x61, 0x31, 0x39, 0x33, 0x2d, 0x31, 0x36, 0x31, 0x39,
|
||||
0x64, 0x39, 0x38, 0x33, 0x30, 0x36, 0x36, 0x38, 0x00, 0x0A, 0x6d, 0x61, 0x74, 0x72, 0x69,
|
||||
0x78, 0x2e, 0x6f, 0x72, 0x67,
|
||||
).map { it.toByte() }.toByteArray()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.matrix.test.linknewdevice
|
||||
|
||||
import io.element.android.libraries.matrix.api.linknewdevice.CheckCodeSender
|
||||
import io.element.android.tests.testutils.lambda.lambdaError
|
||||
import io.element.android.tests.testutils.simulateLongTask
|
||||
|
||||
class FakeCheckCodeSender(
|
||||
private val validateResult: (UByte) -> Boolean = { lambdaError() },
|
||||
private val sendResult: (UByte) -> Result<Unit> = { lambdaError() },
|
||||
) : CheckCodeSender {
|
||||
override suspend fun validate(code: UByte): Boolean = simulateLongTask {
|
||||
validateResult(code)
|
||||
}
|
||||
|
||||
override suspend fun send(code: UByte): Result<Unit> = simulateLongTask {
|
||||
sendResult(code)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.matrix.test.linknewdevice
|
||||
|
||||
import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopHandler
|
||||
import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopStep
|
||||
import io.element.android.tests.testutils.lambda.lambdaError
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
class FakeLinkDesktopHandler(
|
||||
private val handleScannedQrCodeResult: (ByteArray) -> Unit = { lambdaError() },
|
||||
) : LinkDesktopHandler {
|
||||
private val mutableLinkDesktopStep: MutableStateFlow<LinkDesktopStep> = MutableStateFlow(LinkDesktopStep.Uninitialized)
|
||||
override val linkDesktopStep: StateFlow<LinkDesktopStep>
|
||||
get() = mutableLinkDesktopStep.asStateFlow()
|
||||
|
||||
override suspend fun handleScannedQrCode(data: ByteArray) {
|
||||
handleScannedQrCodeResult(data)
|
||||
}
|
||||
|
||||
suspend fun emitStep(step: LinkDesktopStep) {
|
||||
mutableLinkDesktopStep.emit(step)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.matrix.test.linknewdevice
|
||||
|
||||
import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileHandler
|
||||
import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileStep
|
||||
import io.element.android.tests.testutils.lambda.lambdaError
|
||||
import io.element.android.tests.testutils.simulateLongTask
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
class FakeLinkMobileHandler(
|
||||
private val startResult: () -> Unit = { lambdaError() },
|
||||
) : LinkMobileHandler {
|
||||
private val mutableLinkMobileStep: MutableStateFlow<LinkMobileStep> = MutableStateFlow(LinkMobileStep.Uninitialized)
|
||||
override val linkMobileStep: StateFlow<LinkMobileStep>
|
||||
get() = mutableLinkMobileStep.asStateFlow()
|
||||
|
||||
override suspend fun start() = simulateLongTask {
|
||||
startResult()
|
||||
}
|
||||
|
||||
suspend fun emitStep(step: LinkMobileStep) {
|
||||
mutableLinkMobileStep.emit(step)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue