Add KDoc to matrix API authentication and device linking interfaces

Document MatrixAuthenticationService, OAuthRedirectUrlProvider, the two QR code
login data interfaces, and the four device linking interfaces, along with their
members and parameters.

The docs record the ordering constraints a caller has to respect: setHomeserver
must precede any login attempt, the link handlers report their outcome through
their step flow rather than through a return value, and ContinuationMessageSender
expects exactly one of cancel or confirm.

The oauth package holds only a sealed interface, so it is out of scope here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benoit Marty
2026-08-13 19:14:00 +02:00
parent fa01166197
commit 0b2d6eafc3
8 changed files with 92 additions and 1 deletions
@@ -16,23 +16,41 @@ import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeLoginStep
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.core.UserId
/**
* Creates and restores sessions: password login, OAuth login, QR code login, and importing a session from another client.
*
* [setHomeserver] must be called before any login attempt, since it is what tells the SDK which server to authenticate against.
* Every successful login stores the session and notifies the listeners registered through [listenToNewMatrixClients].
*/
interface MatrixAuthenticationService {
/**
* Restore a session from a [sessionId].
* Do not restore anything it the access token is not valid anymore.
* Generally this method should not be used directly, prefer using [MatrixClientProvider.getOrRestore] instead.
*
* @param sessionId the session to restore.
*/
suspend fun restoreSession(sessionId: SessionId): Result<MatrixClient>
/**
* Set the homeserver to use for authentication, and return its details.
*
* @param homeserver the homeserver URL or server name to authenticate against.
*/
suspend fun setHomeserver(homeserver: String): Result<MatrixHomeServerDetails>
/**
* Logs in with a password on the homeserver previously set through [setHomeserver].
*
* @param username the user id or its local part.
* @param password the account password.
*/
suspend fun login(username: String, password: String): Result<SessionId>
/**
* Import a session that was created using another client, for instance Element Web.
*
* @param externalSession the tokens and identifiers of the session to import.
*/
suspend fun importCreatedSession(externalSession: ExternalSession): Result<SessionId>
@@ -42,6 +60,9 @@ interface MatrixAuthenticationService {
/**
* Get the OAuth url to display to the user.
*
* @param prompt whether the authentication server should show the sign-in or the account-creation page.
* @param loginHint the user identifier to pre-fill on that page, or `null` to leave it empty.
*/
suspend fun getOAuthUrl(
prompt: OAuthPrompt,
@@ -55,11 +76,17 @@ interface MatrixAuthenticationService {
/**
* Set the existing data about Element Classic session, if any.
*
* @param session the session found in a local Element Classic install, or `null` when there is none to migrate.
*/
fun setElementClassicSession(session: ElementClassicSession?)
/**
* Check if the provided secrets from Element Classic session contain a key backup.
*
* @param userId the user the secrets belong to.
* @param secrets the raw secrets exported from Element Classic.
* @param backupInfo the raw backup description exported alongside them.
*/
fun doSecretsContainBackupKey(
userId: UserId,
@@ -69,11 +96,23 @@ interface MatrixAuthenticationService {
/**
* Attempt to log in using the [callbackUrl] provided by the OAuth page.
*
* @param callbackUrl the redirect URL the authentication server sent the user back to, carrying the authorization code.
*/
suspend fun loginWithOAuth(callbackUrl: String): Result<SessionId>
/**
* Logs in by acting on a QR code shown by an already signed in device, reporting each step of the exchange as it happens.
*
* @param qrCodeData the decoded QR code, obtained from [io.element.android.libraries.matrix.api.auth.qrlogin.MatrixQrCodeLoginDataFactory].
* @param progress called on every step of the flow, so the UI can follow along.
*/
suspend fun loginWithQrCode(qrCodeData: MatrixQrCodeLoginData, progress: (QrCodeLoginStep) -> Unit): Result<SessionId>
/** Listen to new Matrix clients being created on authentication. */
/**
* Listen to new Matrix clients being created on authentication.
*
* @param lambda called with each client created by a successful login or session restore.
*/
fun listenToNewMatrixClients(lambda: (MatrixClient) -> Unit)
}
@@ -8,6 +8,10 @@
package io.element.android.libraries.matrix.api.auth
/**
* Provides the redirect URL registered for OAuth login, which the authentication server sends the user back to once they have signed in.
*/
interface OAuthRedirectUrlProvider {
/** Returns the redirect URL, built from the app's custom URL scheme so that the system hands the callback back to the app. */
fun provide(): String
}
@@ -8,6 +8,12 @@
package io.element.android.libraries.matrix.api.auth.qrlogin
/**
* The decoded content of a login QR code, as produced by [MatrixQrCodeLoginDataFactory].
*
* The underlying data is opaque to the app: it is passed back to the SDK to perform the login.
*/
interface MatrixQrCodeLoginData {
/** The homeserver advertised by the QR code, or `null` when it does not carry one. */
fun serverName(): String?
}
@@ -8,6 +8,14 @@
package io.element.android.libraries.matrix.api.auth.qrlogin
/**
* Decodes the raw bytes of a scanned QR code into login data the SDK can use.
*/
interface MatrixQrCodeLoginDataFactory {
/**
* Parses the scanned bytes, failing with a [QrCodeDecodeException] when they are not a valid Matrix login QR code.
*
* @param data the raw content read from the QR code.
*/
fun parseQrCodeData(data: ByteArray): Result<MatrixQrCodeLoginData>
}
@@ -7,6 +7,9 @@
package io.element.android.libraries.matrix.api.linknewdevice
/**
* Lets the user confirm the two-digit check code displayed by the device being linked, which proves the channel is not being intercepted.
*/
interface CheckCodeSender {
/**
* Validates the given [code]. Returns true if the code is valid, false otherwise.
@@ -7,7 +7,15 @@
package io.element.android.libraries.matrix.api.linknewdevice
/**
* Lets the user confirm or refuse a device linking request once they have approved it in the browser.
*
* Handed out with the step that is waiting for authorisation; exactly one of the two methods is meant to be called.
*/
interface ContinuationMessageSender {
/** Tells the other device that the user refused the linking, which ends the flow. */
suspend fun cancel(): Result<Unit>
/** Tells the other device that the user approved the linking, so the flow can carry on. */
suspend fun confirm(): Result<Unit>
}
@@ -10,8 +10,22 @@ package io.element.android.libraries.matrix.api.linknewdevice
import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeDecodeException
import kotlinx.coroutines.flow.StateFlow
/**
* Drives the linking of a new device that cannot scan a QR code, such as a desktop: this device scans the code the other one displays.
*
* Progress is reported entirely through [linkDesktopStep]; there is one handler per attempt, obtained from
* [io.element.android.libraries.matrix.api.MatrixClient.createLinkDesktopHandler].
*/
interface LinkDesktopHandler {
/** Each step of the flow, from establishing the secure channel to syncing the secrets to the new device. */
val linkDesktopStep: StateFlow<LinkDesktopStep>
/**
* Runs the whole flow from the QR code just scanned, suspending until it finishes or fails.
* A code that cannot be decoded is reported as an invalid-QR-code step rather than as a thrown error.
*
* @param data the raw content read from the QR code shown by the other device.
*/
suspend fun handleScannedQrCode(data: ByteArray)
}
@@ -9,8 +9,17 @@ package io.element.android.libraries.matrix.api.linknewdevice
import kotlinx.coroutines.flow.Flow
/**
* Drives the linking of a new device that is able to scan a QR code, by showing one on this already signed in device.
*
* Progress is reported entirely through [linkMobileStep]; there is one handler per attempt, obtained from
* [io.element.android.libraries.matrix.api.MatrixClient.createLinkMobileHandler].
*/
interface LinkMobileHandler {
/** Each step of the flow, from generating the QR code to syncing the secrets to the new device. */
val linkMobileStep: Flow<LinkMobileStep>
/** Runs the whole flow, suspending until it finishes or fails; the outcome is reported through [linkMobileStep]. */
suspend fun start()
}