Link new device using QrCode.
This commit is contained in:
parent
5ebb615751
commit
a073117d62
94 changed files with 4431 additions and 36 deletions
|
|
@ -19,6 +19,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
|
||||
|
|
@ -195,6 +197,21 @@ interface MatrixClient {
|
|||
*/
|
||||
suspend fun markRoomAsFullyRead(roomId: RoomId, eventId: EventId): Result<Unit>
|
||||
|
||||
/**
|
||||
* Check if linking a new device using QrCode is supported by the server.
|
||||
*/
|
||||
suspend fun canLinkNewDevice(): Result<Boolean>
|
||||
|
||||
/**
|
||||
* Create a handler to link a new mobile device, i.e. a device capable of scanning QrCodes.
|
||||
*/
|
||||
fun createLinkMobileHandler(): Result<LinkMobileHandler>
|
||||
|
||||
/**
|
||||
* Create a handler to link a new desktop device, i.e. a device not capable of scanning QrCodes.
|
||||
*/
|
||||
fun createLinkDesktopHandler(): Result<LinkDesktopHandler>
|
||||
|
||||
suspend fun performDatabaseVacuum(): Result<Unit>
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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.api.linknewdevice
|
||||
|
||||
interface CheckCodeSender {
|
||||
/**
|
||||
* Validates the given [code]. Returns true if the code is valid, false otherwise.
|
||||
* This method can be called multiple times to validate different codes.
|
||||
*/
|
||||
suspend fun validate(code: UByte): Boolean
|
||||
|
||||
/**
|
||||
* Sends the given [code].
|
||||
* This method can be called only once.
|
||||
*/
|
||||
suspend fun send(code: UByte): Result<Unit>
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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.api.linknewdevice
|
||||
|
||||
sealed class ErrorType(message: String) : Exception(message) {
|
||||
/**
|
||||
* The requested device ID is already in use.
|
||||
*/
|
||||
class DeviceIdAlreadyInUse(message: String) : ErrorType(message)
|
||||
|
||||
/**
|
||||
* The check code was incorrect.
|
||||
*/
|
||||
class InvalidCheckCode(message: String) : ErrorType(message)
|
||||
|
||||
/**
|
||||
* The other client proposed an unsupported protocol.
|
||||
*/
|
||||
class UnsupportedProtocol(message: String) : ErrorType(message)
|
||||
|
||||
/**
|
||||
* Secrets backup not set up properly.
|
||||
*/
|
||||
class MissingSecretsBackup(message: String) : ErrorType(message)
|
||||
|
||||
/**
|
||||
* The rendezvous session was not found and might have expired.
|
||||
*/
|
||||
class NotFound(message: String) : ErrorType(message)
|
||||
|
||||
/**
|
||||
* The device could not be created.
|
||||
*/
|
||||
class UnableToCreateDevice(message: String) : ErrorType(message)
|
||||
|
||||
/**
|
||||
* An unknown error has happened.
|
||||
*/
|
||||
class Unknown(message: String) : ErrorType(message)
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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.api.linknewdevice
|
||||
|
||||
import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeDecodeException
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
interface LinkDesktopHandler {
|
||||
val linkDesktopStep: StateFlow<LinkDesktopStep>
|
||||
suspend fun handleScannedQrCode(data: ByteArray)
|
||||
}
|
||||
|
||||
sealed interface LinkDesktopStep {
|
||||
data object Uninitialized : LinkDesktopStep
|
||||
data object Starting : LinkDesktopStep
|
||||
data class WaitingForAuth(
|
||||
val verificationUri: String,
|
||||
) : LinkDesktopStep
|
||||
|
||||
data class EstablishingSecureChannel(
|
||||
val checkCode: UByte,
|
||||
val checkCodeString: String,
|
||||
) : LinkDesktopStep
|
||||
|
||||
data class InvalidQrCode(
|
||||
val error: QrCodeDecodeException,
|
||||
) : LinkDesktopStep
|
||||
|
||||
data class Error(
|
||||
val errorType: ErrorType,
|
||||
) : LinkDesktopStep
|
||||
|
||||
data object SyncingSecrets : LinkDesktopStep
|
||||
|
||||
data object Done : LinkDesktopStep
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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.api.linknewdevice
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface LinkMobileHandler {
|
||||
val linkMobileStep: Flow<LinkMobileStep>
|
||||
suspend fun start()
|
||||
}
|
||||
|
||||
sealed interface LinkMobileStep {
|
||||
data object Uninitialized : LinkMobileStep
|
||||
data object Starting : LinkMobileStep
|
||||
data class QrReady(val data: String) : LinkMobileStep
|
||||
data class WaitingForAuth(val verificationUri: String) : LinkMobileStep
|
||||
data class QrScanned(val checkCodeSender: CheckCodeSender) : LinkMobileStep
|
||||
data class Error(val errorType: ErrorType) : LinkMobileStep
|
||||
data object SyncingSecrets : LinkMobileStep
|
||||
data object Done : LinkMobileStep
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* 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.api.logs
|
||||
|
||||
import io.element.android.libraries.core.log.logger.LoggerTag
|
||||
|
||||
object LoggerTags {
|
||||
val linkNewDevice = LoggerTag("LinkNewDevice")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue