Improve existing APIs
This commit is contained in:
parent
abb9959789
commit
175bada0df
7 changed files with 140 additions and 14 deletions
|
|
@ -47,12 +47,19 @@ fun Activity.openUrlInChromeCustomTab(
|
|||
true -> CustomTabsIntent.COLOR_SCHEME_DARK
|
||||
}
|
||||
)
|
||||
.setShareIdentityEnabled(false)
|
||||
// Note: setting close button icon does not work
|
||||
// .setCloseButtonIcon(BitmapFactory.decodeResource(context.resources, R.drawable.ic_back_24dp))
|
||||
// .setStartAnimations(context, R.anim.enter_fade_in, R.anim.exit_fade_out)
|
||||
// .setExitAnimations(context, R.anim.enter_fade_in, R.anim.exit_fade_out)
|
||||
.apply { session?.let { setSession(it) } }
|
||||
.build()
|
||||
.apply {
|
||||
// Disable download button
|
||||
intent.putExtra("org.chromium.chrome.browser.customtabs.EXTRA_DISABLE_DOWNLOAD_BUTTON", true)
|
||||
// Disable bookmark button
|
||||
intent.putExtra("org.chromium.chrome.browser.customtabs.EXTRA_DISABLE_START_BUTTON", true)
|
||||
}
|
||||
.launchUrl(this, Uri.parse(url))
|
||||
} catch (activityNotFoundException: ActivityNotFoundException) {
|
||||
// TODO context.toast(R.string.error_no_external_application_found)
|
||||
|
|
|
|||
|
|
@ -64,16 +64,52 @@ interface EncryptionService {
|
|||
*/
|
||||
suspend fun deviceEd25519(): String?
|
||||
|
||||
/**
|
||||
* Starts the identity reset process. This will return a handle that can be used to reset the identity.
|
||||
*/
|
||||
suspend fun startIdentityReset(): Result<IdentityResetHandle?>
|
||||
}
|
||||
|
||||
interface IdentityResetHandle
|
||||
/**
|
||||
* A handle to reset the user's identity.
|
||||
*/
|
||||
interface IdentityResetHandle {
|
||||
/**
|
||||
* Cancel the reset process and drops the existing handle in the SDK.
|
||||
*/
|
||||
suspend fun cancel()
|
||||
}
|
||||
|
||||
/**
|
||||
* A handle to reset the user's identity with a password login type.
|
||||
*/
|
||||
interface IdentityPasswordResetHandle : IdentityResetHandle {
|
||||
/**
|
||||
* Reset the password of the user.
|
||||
*
|
||||
* This method will block the coroutine it's running on and keep polling indefinitely until either the coroutine is cancelled, the [cancel] method is
|
||||
* called, or the identity is reset.
|
||||
*
|
||||
* @param userId the user id of the user to reset the password for.
|
||||
* @param password the current password, which will be validated before the process takes place.
|
||||
*/
|
||||
suspend fun resetPassword(userId: UserId, password: String): Result<Unit>
|
||||
}
|
||||
|
||||
/**
|
||||
* A handle to reset the user's identity with an OIDC login type.
|
||||
*/
|
||||
interface IdentityOidcResetHandle : IdentityResetHandle {
|
||||
/**
|
||||
* The URL to open in a webview/custom tab to reset the identity.
|
||||
*/
|
||||
val url: String
|
||||
|
||||
/**
|
||||
* Reset the identity using the OIDC flow.
|
||||
*
|
||||
* This method will block the coroutine it's running on and keep polling indefinitely until either the coroutine is cancelled, the [cancel] method is
|
||||
* called, or the identity is reset.
|
||||
*/
|
||||
suspend fun resetOidc(): Result<Unit>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ class RustPasswordIdentityResetHandle(
|
|||
override suspend fun resetPassword(userId: UserId, password: String): Result<Unit> {
|
||||
return runCatching { identityResetHandle.reset(AuthData.Password(AuthDataPasswordDetails(userId.value, password))) }
|
||||
}
|
||||
|
||||
override suspend fun cancel() {
|
||||
identityResetHandle.cancelAndDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
class RustOidcIdentityResetHandle(
|
||||
|
|
@ -51,4 +55,13 @@ class RustOidcIdentityResetHandle(
|
|||
override suspend fun resetOidc(): Result<Unit> {
|
||||
return runCatching { identityResetHandle.reset(null) }
|
||||
}
|
||||
|
||||
override suspend fun cancel() {
|
||||
identityResetHandle.cancelAndDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun org.matrix.rustcomponents.sdk.IdentityResetHandle.cancelAndDestroy() {
|
||||
cancel()
|
||||
destroy()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,17 +22,27 @@ import io.element.android.libraries.matrix.api.encryption.IdentityPasswordResetH
|
|||
|
||||
class FakeIdentityOidcResetHandle(
|
||||
override val url: String = "",
|
||||
var resetOidcLambda: () -> Result<Unit> = { error("Not implemented") }
|
||||
var resetOidcLambda: () -> Result<Unit> = { error("Not implemented") },
|
||||
var cancelLambda: () -> Unit = { error("Not implemented") },
|
||||
) : IdentityOidcResetHandle {
|
||||
override suspend fun resetOidc(): Result<Unit> {
|
||||
return resetOidcLambda()
|
||||
}
|
||||
|
||||
override suspend fun cancel() {
|
||||
cancelLambda()
|
||||
}
|
||||
}
|
||||
|
||||
class FakeIdentityPasswordResetHandle(
|
||||
var resetPasswordLambda: (UserId, String) -> Result<Unit> = { _, _ -> error("Not implemented") }
|
||||
var resetPasswordLambda: (UserId, String) -> Result<Unit> = { _, _ -> error("Not implemented") },
|
||||
var cancelLambda: () -> Unit = { error("Not implemented") },
|
||||
) : IdentityPasswordResetHandle {
|
||||
override suspend fun resetPassword(userId: UserId, password: String): Result<Unit> {
|
||||
return resetPasswordLambda(userId, password)
|
||||
}
|
||||
|
||||
override suspend fun cancel() {
|
||||
cancelLambda()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,11 @@
|
|||
|
||||
package io.element.android.libraries.oidc.impl.webview
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.webkit.WebView
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.statusBarsPadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
|
|
@ -30,10 +31,14 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
|
|||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import io.element.android.libraries.core.bool.orFalse
|
||||
import io.element.android.libraries.designsystem.components.async.AsyncActionView
|
||||
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.oidc.impl.OidcUrlParser
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun OidcView(
|
||||
state: OidcState,
|
||||
|
|
@ -55,7 +60,7 @@ fun OidcView(
|
|||
OidcWebViewClient(::shouldOverrideUrl)
|
||||
}
|
||||
|
||||
BackHandler {
|
||||
fun onBack() {
|
||||
if (webView?.canGoBack().orFalse()) {
|
||||
webView?.goBack()
|
||||
} else {
|
||||
|
|
@ -64,11 +69,32 @@ fun OidcView(
|
|||
}
|
||||
}
|
||||
|
||||
Box(modifier = modifier.statusBarsPadding()) {
|
||||
BackHandler { onBack() }
|
||||
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = {},
|
||||
navigationIcon = {
|
||||
BackButton(onClick = ::onBack)
|
||||
},
|
||||
)
|
||||
}
|
||||
) { contentPadding ->
|
||||
AndroidView(
|
||||
modifier = Modifier.padding(contentPadding),
|
||||
factory = { context ->
|
||||
WebView(context).apply {
|
||||
webViewClient = oidcWebViewClient
|
||||
settings.apply {
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
javaScriptEnabled = true
|
||||
allowContentAccess = true
|
||||
allowFileAccess = true
|
||||
databaseEnabled = true
|
||||
domStorageEnabled = true
|
||||
}
|
||||
loadUrl(state.oidcDetails.url)
|
||||
}.also {
|
||||
webView = it
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue