feat(account-recovery): Added AccountRecovery Start/Reset metrics.

This commit is contained in:
Neil Marietta
2024-03-13 18:24:51 +01:00
parent 974f17d4df
commit 1e272664cd
13 changed files with 293 additions and 114 deletions
@@ -76,7 +76,7 @@ public class AccountRecoveryRepositoryImpl @Inject constructor(
organizationKey: String?,
userKeys: List<Key>?,
auth: Auth?
): Boolean =
): Boolean = result("account_recovery.reset") {
apiProvider.get<AccountRecoveryApi>(sessionUserId).invoke {
val request = ResetPasswordRequest(
keySalt = keySalt,
@@ -88,4 +88,5 @@ public class AccountRecoveryRepositoryImpl @Inject constructor(
)
resetPassword(request).isSuccess()
}.valueOrThrow
}
}
@@ -44,6 +44,11 @@ public interface AccountRecoveryRepository {
userId: UserId
)
/**
* Reset the password without using old password, during account recovery process.
*
* Note: Old data cannot be decrypted without old password. 2FA will be disabled.
*/
public suspend fun resetPassword(
sessionUserId: UserId,
keySalt: String,
@@ -103,12 +103,6 @@ private fun PasswordResetDialog(
title = stringResource(R.string.account_recovery_reset_dialog_title),
text = {
Column {
Icon(
modifier = Modifier.align(Alignment.CenterHorizontally),
painter = painterResource(id = R.drawable.recovery_reset),
contentDescription = stringResource(R.string.account_recovery_reset_dialog_title),
tint = Color.Unspecified
)
Spacer(modifier = Modifier.size(ProtonDimens.DefaultSpacing))
ProtonAlertDialogText(
stringResource(R.string.account_recovery_reset_dialog_text, email)
@@ -40,8 +40,10 @@ import me.proton.core.compose.viewmodel.stopTimeoutMillis
import me.proton.core.domain.entity.UserId
import me.proton.core.observability.domain.ObservabilityContext
import me.proton.core.observability.domain.ObservabilityManager
import me.proton.core.observability.domain.metrics.AccountRecoveryStartTotal
import me.proton.core.user.domain.entity.User
import me.proton.core.user.domain.usecase.ObserveUser
import me.proton.core.util.kotlin.coroutine.flowWithResultContext
import javax.inject.Inject
@HiltViewModel
@@ -77,10 +79,12 @@ class PasswordResetDialogViewModel @Inject constructor(
emitAll(currentUser.filterNotNull().mapLatest { State.Ready(it.getEmail()) })
}
private fun requestReset(): Flow<State> = flow {
emit(State.Loading(currentUser.value?.getEmail()))
private suspend fun requestReset(): Flow<State> = flowWithResultContext {
it.onResultEnqueueObservability("account_recovery.start") { AccountRecoveryStartTotal(this) }
send(State.Loading(currentUser.value?.getEmail()))
startRecovery(userId)
emit(State.ResetRequested)
send(State.ResetRequested)
}
fun perform(action: Action) = currentAction.tryEmit(action)
@@ -1,83 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="277dp"
android:height="156dp"
android:viewportWidth="277"
android:viewportHeight="156">
<group>
<path
android:fillColor="#372580"
android:pathData="M216.5,135H60.5V42.83C60.5,37.97 64.33,34 69.02,34H207.98C212.67,34 216.5,37.97 216.5,42.83V135Z" />
<path
android:fillColor="#ffffff"
android:pathData="M209.5,135H67.5V43.16C67.5,41.97 68.42,41 69.56,41H207.37C208.51,41 209.43,41.97 209.43,43.16V135H209.5Z" />
<path
android:fillColor="#EAE8E5"
android:pathData="M233.57,138H43.43C41.78,138 40.5,136.63 40.5,134.88V133.12C40.5,131.37 41.78,130 43.43,130H233.57C235.22,130 236.5,131.37 236.5,133.12V134.88C236.5,136.63 235.14,138 233.57,138Z" />
<path
android:fillColor="#D1CFCD"
android:pathData="M148.09,134H128.91C126.43,134 124.5,132.18 124.5,130H152.5C152.5,132.18 150.57,134 148.09,134Z" />
<path
android:fillColor="#ffffff"
android:pathData="M80.2,86C80.2,81.97 83.47,78.7 87.5,78.7H189.5C193.53,78.7 196.8,81.97 196.8,86V96C196.8,100.03 193.53,103.3 189.5,103.3H87.5C83.47,103.3 80.2,100.03 80.2,96V86Z"
android:strokeWidth="1.4"
android:strokeColor="#F0ECE6" />
<path
android:fillColor="#706D6B"
android:pathData="M94.98,90.66H92.76L94.33,89.09C94.41,88.99 94.45,88.86 94.45,88.73C94.44,88.6 94.39,88.47 94.29,88.38C94.2,88.29 94.08,88.23 93.95,88.23C93.82,88.22 93.69,88.27 93.59,88.35L92.02,89.92V87.7C92.02,87.56 91.96,87.43 91.87,87.33C91.77,87.23 91.63,87.18 91.5,87.18C91.36,87.18 91.22,87.23 91.12,87.33C91.03,87.43 90.97,87.56 90.97,87.7V89.92L89.41,88.35C89.36,88.29 89.3,88.24 89.24,88.21C89.17,88.18 89.1,88.16 89.03,88.15C88.95,88.15 88.88,88.16 88.81,88.19C88.74,88.21 88.68,88.25 88.63,88.31C88.58,88.36 88.53,88.42 88.51,88.49C88.48,88.56 88.47,88.63 88.47,88.71C88.48,88.78 88.5,88.85 88.53,88.92C88.57,88.98 88.61,89.04 88.67,89.09L90.24,90.66H88.02C87.89,90.66 87.75,90.71 87.65,90.81C87.56,90.91 87.5,91.04 87.5,91.18C87.5,91.32 87.56,91.45 87.65,91.55C87.75,91.65 87.89,91.7 88.02,91.7H90.24L88.67,93.27C88.61,93.32 88.57,93.38 88.54,93.44C88.5,93.51 88.49,93.58 88.48,93.65C88.48,93.72 88.49,93.8 88.52,93.86C88.54,93.93 88.58,93.99 88.63,94.04C88.69,94.1 88.75,94.14 88.82,94.16C88.88,94.19 88.96,94.2 89.03,94.2C89.1,94.19 89.17,94.18 89.24,94.14C89.3,94.11 89.36,94.07 89.41,94.01L90.97,92.44V94.66C90.97,94.79 91.03,94.93 91.12,95.03C91.22,95.12 91.36,95.18 91.5,95.18C91.63,95.18 91.77,95.12 91.87,95.03C91.96,94.93 92.02,94.79 92.02,94.66V92.44L93.59,94.01C93.63,94.07 93.69,94.11 93.76,94.14C93.82,94.18 93.89,94.19 93.97,94.2C94.04,94.2 94.11,94.19 94.18,94.16C94.25,94.14 94.31,94.1 94.36,94.04C94.41,93.99 94.45,93.93 94.48,93.86C94.5,93.8 94.52,93.72 94.51,93.65C94.51,93.58 94.49,93.51 94.46,93.44C94.43,93.38 94.38,93.32 94.33,93.27L92.76,91.7H94.98C95.11,91.7 95.25,91.65 95.35,91.55C95.44,91.45 95.5,91.32 95.5,91.18C95.5,91.04 95.44,90.91 95.35,90.81C95.25,90.71 95.11,90.66 94.98,90.66Z" />
<path
android:fillColor="#706D6B"
android:pathData="M110.64,90.66H108.43L109.99,89.09C110.08,88.99 110.12,88.86 110.11,88.73C110.11,88.6 110.05,88.47 109.96,88.38C109.87,88.29 109.74,88.23 109.61,88.23C109.48,88.22 109.36,88.27 109.25,88.35L107.69,89.92V87.7C107.69,87.56 107.63,87.43 107.53,87.33C107.43,87.23 107.3,87.18 107.16,87.18C107.02,87.18 106.89,87.23 106.79,87.33C106.69,87.43 106.64,87.56 106.64,87.7V89.92L105.07,88.35C105.03,88.29 104.97,88.24 104.9,88.21C104.84,88.18 104.77,88.16 104.69,88.15C104.62,88.15 104.55,88.16 104.48,88.19C104.41,88.21 104.35,88.25 104.29,88.31C104.24,88.36 104.2,88.42 104.18,88.49C104.15,88.56 104.14,88.63 104.14,88.71C104.14,88.78 104.17,88.85 104.2,88.92C104.23,88.98 104.28,89.04 104.34,89.09L105.9,90.66H103.69C103.55,90.66 103.42,90.71 103.32,90.81C103.22,90.91 103.17,91.04 103.17,91.18C103.17,91.32 103.22,91.45 103.32,91.55C103.42,91.65 103.55,91.7 103.69,91.7H105.9L104.34,93.27C104.28,93.32 104.24,93.38 104.2,93.44C104.17,93.51 104.15,93.58 104.15,93.65C104.14,93.72 104.16,93.8 104.18,93.86C104.21,93.93 104.25,93.99 104.3,94.04C104.35,94.1 104.41,94.14 104.48,94.16C104.55,94.19 104.62,94.2 104.69,94.2C104.77,94.19 104.84,94.18 104.9,94.14C104.97,94.11 105.03,94.07 105.07,94.01L106.64,92.44V94.66C106.64,94.79 106.69,94.93 106.79,95.03C106.89,95.12 107.02,95.18 107.16,95.18C107.3,95.18 107.43,95.12 107.53,95.03C107.63,94.93 107.69,94.79 107.69,94.66V92.44L109.25,94.01C109.3,94.07 109.36,94.11 109.42,94.14C109.49,94.18 109.56,94.19 109.63,94.2C109.71,94.2 109.78,94.19 109.85,94.16C109.91,94.14 109.98,94.1 110.03,94.04C110.08,93.99 110.12,93.93 110.14,93.86C110.17,93.8 110.18,93.72 110.18,93.65C110.18,93.58 110.16,93.51 110.13,93.44C110.09,93.38 110.05,93.32 109.99,93.27L108.43,91.7H110.64C110.78,91.7 110.92,91.65 111.01,91.55C111.11,91.45 111.17,91.32 111.17,91.18C111.17,91.04 111.11,90.91 111.01,90.81C110.92,90.71 110.78,90.66 110.64,90.66Z" />
<path
android:fillColor="#706D6B"
android:pathData="M126.31,90.66H124.1L125.66,89.09C125.74,88.99 125.79,88.86 125.78,88.73C125.77,88.6 125.72,88.47 125.63,88.38C125.54,88.29 125.41,88.23 125.28,88.23C125.15,88.22 125.02,88.27 124.92,88.35L123.35,89.92V87.7C123.35,87.56 123.3,87.43 123.2,87.33C123.1,87.23 122.97,87.18 122.83,87.18C122.69,87.18 122.56,87.23 122.46,87.33C122.36,87.43 122.31,87.56 122.31,87.7V89.92L120.74,88.35C120.69,88.29 120.64,88.24 120.57,88.21C120.51,88.18 120.43,88.16 120.36,88.15C120.29,88.15 120.21,88.16 120.14,88.19C120.08,88.21 120.01,88.25 119.96,88.31C119.91,88.36 119.87,88.42 119.84,88.49C119.82,88.56 119.8,88.63 119.81,88.71C119.81,88.78 119.83,88.85 119.86,88.92C119.9,88.98 119.95,89.04 120,89.09L121.57,90.66H119.36C119.22,90.66 119.08,90.71 118.99,90.81C118.89,90.91 118.83,91.04 118.83,91.18C118.83,91.32 118.89,91.45 118.99,91.55C119.08,91.65 119.22,91.7 119.36,91.7H121.57L120,93.27C119.95,93.32 119.9,93.38 119.87,93.44C119.84,93.51 119.82,93.58 119.82,93.65C119.81,93.72 119.82,93.8 119.85,93.86C119.88,93.93 119.92,93.99 119.97,94.04C120.02,94.1 120.08,94.14 120.15,94.16C120.22,94.19 120.29,94.2 120.36,94.2C120.43,94.19 120.51,94.18 120.57,94.14C120.64,94.11 120.69,94.07 120.74,94.01L122.31,92.44V94.66C122.31,94.79 122.36,94.93 122.46,95.03C122.56,95.12 122.69,95.18 122.83,95.18C122.97,95.18 123.1,95.12 123.2,95.03C123.3,94.93 123.35,94.79 123.35,94.66V92.44L124.92,94.01C124.97,94.07 125.03,94.11 125.09,94.14C125.16,94.18 125.23,94.19 125.3,94.2C125.37,94.2 125.44,94.19 125.51,94.16C125.58,94.14 125.64,94.1 125.69,94.04C125.75,93.99 125.79,93.93 125.81,93.86C125.84,93.8 125.85,93.72 125.85,93.65C125.84,93.58 125.82,93.51 125.79,93.44C125.76,93.38 125.71,93.32 125.66,93.27L124.1,91.7H126.31C126.45,91.7 126.58,91.65 126.68,91.55C126.78,91.45 126.83,91.32 126.83,91.18C126.83,91.04 126.78,90.91 126.68,90.81C126.58,90.71 126.45,90.66 126.31,90.66Z" />
<path
android:fillColor="#706D6B"
android:pathData="M141.98,90.66H139.76L141.33,89.09C141.41,88.99 141.45,88.86 141.45,88.73C141.44,88.6 141.39,88.47 141.29,88.38C141.2,88.29 141.08,88.23 140.95,88.23C140.82,88.22 140.69,88.27 140.59,88.35L139.02,89.92V87.7C139.02,87.56 138.96,87.43 138.87,87.33C138.77,87.23 138.63,87.18 138.49,87.18C138.36,87.18 138.22,87.23 138.13,87.33C138.03,87.43 137.97,87.56 137.97,87.7V89.92L136.41,88.35C136.36,88.29 136.3,88.24 136.24,88.21C136.17,88.18 136.1,88.16 136.03,88.15C135.95,88.15 135.88,88.16 135.81,88.19C135.74,88.21 135.68,88.25 135.63,88.31C135.57,88.36 135.54,88.42 135.51,88.49C135.48,88.56 135.47,88.63 135.48,88.71C135.48,88.78 135.5,88.85 135.53,88.92C135.57,88.98 135.61,89.04 135.67,89.09L137.24,90.66H135.02C134.88,90.66 134.75,90.71 134.65,90.81C134.55,90.91 134.5,91.04 134.5,91.18C134.5,91.32 134.55,91.45 134.65,91.55C134.75,91.65 134.88,91.7 135.02,91.7H137.24L135.67,93.27C135.61,93.32 135.57,93.38 135.54,93.44C135.5,93.51 135.49,93.58 135.48,93.65C135.48,93.72 135.49,93.8 135.52,93.86C135.54,93.93 135.58,93.99 135.63,94.04C135.69,94.1 135.75,94.14 135.82,94.16C135.88,94.19 135.96,94.2 136.03,94.2C136.1,94.19 136.17,94.18 136.24,94.14C136.3,94.11 136.36,94.07 136.41,94.01L137.97,92.44V94.66C137.97,94.79 138.03,94.93 138.13,95.03C138.22,95.12 138.36,95.18 138.49,95.18C138.63,95.18 138.77,95.12 138.87,95.03C138.96,94.93 139.02,94.79 139.02,94.66V92.44L140.59,94.01C140.63,94.07 140.69,94.11 140.76,94.14C140.82,94.18 140.89,94.19 140.97,94.2C141.04,94.2 141.11,94.19 141.18,94.16C141.25,94.14 141.31,94.1 141.36,94.04C141.41,93.99 141.45,93.93 141.48,93.86C141.51,93.8 141.52,93.72 141.51,93.65C141.51,93.58 141.49,93.51 141.46,93.44C141.43,93.38 141.38,93.32 141.33,93.27L139.76,91.7H141.98C142.12,91.7 142.25,91.65 142.35,91.55C142.45,91.45 142.5,91.32 142.5,91.18C142.5,91.04 142.45,90.91 142.35,90.81C142.25,90.71 142.12,90.66 141.98,90.66Z" />
<path
android:fillColor="#706D6B"
android:pathData="M157.64,90.66H155.43L156.99,89.09C157.08,88.99 157.12,88.86 157.11,88.73C157.11,88.6 157.05,88.47 156.96,88.38C156.87,88.29 156.74,88.23 156.61,88.23C156.48,88.22 156.35,88.27 156.25,88.35L154.69,89.92V87.7C154.69,87.56 154.63,87.43 154.53,87.33C154.43,87.23 154.3,87.18 154.16,87.18C154.02,87.18 153.89,87.23 153.79,87.33C153.69,87.43 153.64,87.56 153.64,87.7V89.92L152.07,88.35C152.03,88.29 151.97,88.24 151.9,88.21C151.84,88.18 151.77,88.16 151.69,88.15C151.62,88.15 151.55,88.16 151.48,88.19C151.41,88.21 151.35,88.25 151.29,88.31C151.24,88.36 151.2,88.42 151.18,88.49C151.15,88.56 151.14,88.63 151.14,88.71C151.15,88.78 151.16,88.85 151.2,88.92C151.23,88.98 151.28,89.04 151.34,89.09L152.9,90.66H150.69C150.55,90.66 150.42,90.71 150.32,90.81C150.22,90.91 150.17,91.04 150.17,91.18C150.17,91.32 150.22,91.45 150.32,91.55C150.42,91.65 150.55,91.7 150.69,91.7H152.9L151.34,93.27C151.28,93.32 151.24,93.38 151.2,93.44C151.17,93.51 151.15,93.58 151.15,93.65C151.15,93.72 151.16,93.8 151.18,93.86C151.21,93.93 151.25,93.99 151.3,94.04C151.35,94.1 151.41,94.14 151.48,94.16C151.55,94.19 151.62,94.2 151.7,94.2C151.77,94.19 151.84,94.18 151.9,94.14C151.97,94.11 152.03,94.07 152.07,94.01L153.64,92.44V94.66C153.64,94.79 153.69,94.93 153.79,95.03C153.89,95.12 154.02,95.18 154.16,95.18C154.3,95.18 154.43,95.12 154.53,95.03C154.63,94.93 154.69,94.79 154.69,94.66V92.44L156.25,94.01C156.3,94.07 156.36,94.11 156.42,94.14C156.49,94.18 156.56,94.19 156.63,94.2C156.71,94.2 156.78,94.19 156.85,94.16C156.91,94.14 156.98,94.1 157.03,94.04C157.08,93.99 157.12,93.93 157.15,93.86C157.17,93.8 157.18,93.72 157.18,93.65C157.18,93.58 157.16,93.51 157.13,93.44C157.09,93.38 157.05,93.32 156.99,93.27L155.43,91.7H157.64C157.78,91.7 157.91,91.65 158.01,91.55C158.11,91.45 158.17,91.32 158.17,91.18C158.17,91.04 158.11,90.91 158.01,90.81C157.91,90.71 157.78,90.66 157.64,90.66Z" />
<path
android:fillColor="#706D6B"
android:pathData="M173.31,90.66H171.1L172.66,89.09C172.74,88.99 172.79,88.86 172.78,88.73C172.77,88.6 172.72,88.47 172.63,88.38C172.54,88.29 172.41,88.23 172.28,88.23C172.15,88.22 172.02,88.27 171.92,88.35L170.35,89.92V87.7C170.35,87.56 170.3,87.43 170.2,87.33C170.1,87.23 169.97,87.18 169.83,87.18C169.69,87.18 169.56,87.23 169.46,87.33C169.36,87.43 169.3,87.56 169.3,87.7V89.92L167.74,88.35C167.7,88.29 167.64,88.24 167.57,88.21C167.51,88.18 167.43,88.16 167.36,88.15C167.29,88.15 167.21,88.16 167.15,88.19C167.08,88.21 167.01,88.25 166.96,88.31C166.91,88.36 166.87,88.42 166.84,88.49C166.82,88.56 166.8,88.63 166.81,88.71C166.81,88.78 166.83,88.85 166.87,88.92C166.9,88.98 166.95,89.04 167,89.09L168.57,90.66H166.36C166.22,90.66 166.09,90.71 165.99,90.81C165.89,90.91 165.83,91.04 165.83,91.18C165.83,91.32 165.89,91.45 165.99,91.55C166.09,91.65 166.22,91.7 166.36,91.7H168.57L167,93.27C166.95,93.32 166.9,93.38 166.87,93.44C166.84,93.51 166.82,93.58 166.82,93.65C166.81,93.72 166.82,93.8 166.85,93.86C166.88,93.93 166.92,93.99 166.97,94.04C167.02,94.1 167.08,94.14 167.15,94.16C167.22,94.19 167.29,94.2 167.36,94.2C167.43,94.19 167.51,94.18 167.57,94.14C167.64,94.11 167.7,94.07 167.74,94.01L169.3,92.44V94.66C169.3,94.79 169.36,94.93 169.46,95.03C169.56,95.12 169.69,95.18 169.83,95.18C169.97,95.18 170.1,95.12 170.2,95.03C170.3,94.93 170.35,94.79 170.35,94.66V92.44L171.92,94.01C171.97,94.07 172.03,94.11 172.09,94.14C172.16,94.18 172.23,94.19 172.3,94.2C172.37,94.2 172.45,94.19 172.51,94.16C172.58,94.14 172.64,94.1 172.69,94.04C172.75,93.99 172.79,93.93 172.81,93.86C172.84,93.8 172.85,93.72 172.85,93.65C172.84,93.58 172.82,93.51 172.79,93.44C172.76,93.38 172.71,93.32 172.66,93.27L171.1,91.7H173.31C173.45,91.7 173.58,91.65 173.68,91.55C173.78,91.45 173.83,91.32 173.83,91.18C173.83,91.04 173.78,90.91 173.68,90.81C173.58,90.71 173.45,90.66 173.31,90.66Z" />
<path
android:fillColor="#706D6B"
android:pathData="M188.98,90.66H186.76L188.33,89.09C188.41,88.99 188.45,88.86 188.45,88.73C188.44,88.6 188.39,88.47 188.29,88.38C188.2,88.29 188.08,88.23 187.95,88.23C187.82,88.22 187.69,88.27 187.59,88.35L186.02,89.92V87.7C186.02,87.56 185.96,87.43 185.87,87.33C185.77,87.23 185.63,87.18 185.49,87.18C185.36,87.18 185.22,87.23 185.13,87.33C185.03,87.43 184.97,87.56 184.97,87.7V89.92L183.41,88.35C183.36,88.29 183.3,88.24 183.24,88.21C183.17,88.18 183.1,88.16 183.03,88.15C182.95,88.15 182.88,88.16 182.81,88.19C182.74,88.21 182.68,88.25 182.63,88.31C182.57,88.36 182.54,88.42 182.51,88.49C182.48,88.56 182.47,88.63 182.48,88.71C182.48,88.78 182.5,88.85 182.53,88.92C182.57,88.98 182.61,89.04 182.67,89.09L184.24,90.66H182.02C181.88,90.66 181.75,90.71 181.65,90.81C181.55,90.91 181.5,91.04 181.5,91.18C181.5,91.32 181.55,91.45 181.65,91.55C181.75,91.65 181.88,91.7 182.02,91.7H184.24L182.67,93.27C182.61,93.32 182.57,93.38 182.54,93.44C182.5,93.51 182.49,93.58 182.48,93.65C182.48,93.72 182.49,93.8 182.52,93.86C182.54,93.93 182.58,93.99 182.63,94.04C182.69,94.1 182.75,94.14 182.82,94.16C182.88,94.19 182.96,94.2 183.03,94.2C183.1,94.19 183.17,94.18 183.24,94.14C183.3,94.11 183.36,94.07 183.41,94.01L184.97,92.44V94.66C184.97,94.79 185.03,94.93 185.13,95.03C185.22,95.12 185.36,95.18 185.49,95.18C185.63,95.18 185.77,95.12 185.87,95.03C185.96,94.93 186.02,94.79 186.02,94.66V92.44L187.59,94.01C187.63,94.07 187.69,94.11 187.76,94.14C187.82,94.18 187.89,94.19 187.97,94.2C188.04,94.2 188.11,94.19 188.18,94.16C188.25,94.14 188.31,94.1 188.36,94.04C188.41,93.99 188.45,93.93 188.48,93.86C188.51,93.8 188.52,93.72 188.51,93.65C188.51,93.58 188.49,93.51 188.46,93.44C188.43,93.38 188.38,93.32 188.33,93.27L186.76,91.7H188.98C189.12,91.7 189.25,91.65 189.35,91.55C189.45,91.45 189.5,91.32 189.5,91.18C189.5,91.04 189.45,90.91 189.35,90.81C189.25,90.71 189.12,90.66 188.98,90.66Z" />
<group>
<path
android:fillAlpha="0.2"
android:fillColor="#221548"
android:pathData="M236.54,68.98L225.53,88.05L203.51,88.05L192.5,68.98L203.51,49.91L225.53,49.91L236.54,68.98Z"
android:strokeAlpha="0.2" />
</group>
<path
android:fillColor="#FFFF8E4F"
android:pathData="M14.5,76C14.5,65.51 23.01,57 33.5,57C43.99,57 52.5,65.51 52.5,76V95H33.5C23.01,95 14.5,86.49 14.5,76Z" />
<path
android:fillColor="#ffffff"
android:pathData="M38.45,70.28V72.12H40.32C40.96,72.12 41.5,72.61 41.5,73.25V82.87C41.5,83.48 40.98,84 40.32,84H27.68C27.04,84 26.5,83.5 26.5,82.87V73.25C26.5,72.64 27.02,72.12 27.68,72.12H29.53V70.28C29.53,67.91 31.52,66 33.99,66C36.45,66 38.45,67.91 38.45,70.28ZM36.57,70.28V72.12H31.46V70.28C31.46,68.57 32.81,67.82 34.01,67.82C35.21,67.82 36.57,68.57 36.57,70.28ZM34,75C34.83,75 35.5,75.67 35.5,76.51C35.5,77.08 35.19,77.58 34.71,77.82L35.33,80.5H32.67L33.29,77.82C32.81,77.56 32.5,77.08 32.5,76.51C32.5,75.67 33.17,75 34,75Z" />
<path
android:fillAlpha="0.2"
android:fillColor="#1F1548"
android:pathData="M119.5,95C119.5,85.06 127.56,77 137.5,77H139.5C149.44,77 157.5,85.06 157.5,95C157.5,104.94 149.44,113 139.5,113H137.5C127.56,113 119.5,104.94 119.5,95Z"
android:strokeAlpha="0.2" />
<path
android:fillColor="#FFECEAE6"
android:pathData="M138.5,63L138.5,63A24,24 0,0 1,162.5 87L162.5,87A24,24 0,0 1,138.5 111L138.5,111A24,24 0,0 1,114.5 87L114.5,87A24,24 0,0 1,138.5 63z" />
<path
android:fillColor="#FF4F4F4F"
android:pathData="M138.5,87m-20,0a20,20 0,1 1,40 0a20,20 0,1 1,-40 0" />
<path
android:fillColor="#00000000"
android:pathData="M138.96,75V87.11L133.5,93.55"
android:strokeWidth="2"
android:strokeColor="#ffffff"
android:strokeLineCap="round"
android:strokeLineJoin="round" />
<path
android:fillColor="#FFE63757"
android:pathData="M239.22,63.53C239.89,64.72 239.89,66.18 239.22,67.37L229.84,84.03C229.17,85.22 227.93,85.95 226.59,85.95H207.83C206.49,85.95 205.25,85.22 204.58,84.03L195.2,67.37C194.53,66.18 194.53,64.72 195.2,63.53L204.58,46.87C205.25,45.68 206.49,44.95 207.83,44.95L226.59,44.95C227.93,44.95 229.17,45.68 229.84,46.87L239.22,63.53Z" />
<path
android:fillColor="#ffffff"
android:pathData="M218.14,53.2C217.35,53.2 216.71,53.86 216.71,54.68V63.68C216.71,63.9 216.54,64.07 216.34,64.07C216.13,64.07 215.96,63.9 215.96,63.68V55.66C215.96,54.85 215.32,54.19 214.53,54.19C213.74,54.19 213.11,54.85 213.11,55.66V64.71C213.11,64.93 212.94,65.11 212.73,65.11C212.52,65.11 212.35,64.93 212.35,64.71V58.51C212.35,57.7 211.71,57.04 210.92,57.04C210.14,57.04 209.5,57.7 209.5,58.51V72H209.52C209.76,75.24 212.38,77.8 215.57,77.8C220.01,77.8 222.71,77.8 217.01,77.8C221.78,77.8 223.09,75.52 224.91,72.61L224.91,72.6C225.05,72.37 225.2,72.14 225.35,71.9L227.92,67.29C228.43,66.39 228.13,65.24 227.26,64.72C226.39,64.2 225.28,64.51 224.78,65.41L223.61,67.5C223.49,67.72 223.17,67.63 223.17,67.38V56.5C223.17,55.68 222.53,55.02 221.75,55.02C220.96,55.02 220.32,55.68 220.32,56.5V63.68C220.32,63.9 220.15,64.07 219.94,64.07C219.73,64.07 219.56,63.9 219.56,63.68V54.68C219.56,53.86 218.93,53.2 218.14,53.2Z" />
</group>
</vector>
@@ -64,7 +64,7 @@
<string name="account_recovery_info_insecure_description">Didn\'t make this request?\n\nIf you didn\'t ask to reset your password, cancel the request now.</string>
<!-- Password Reset Dialog -->
<string name="account_recovery_reset_dialog_title">Reset Password</string>
<string name="account_recovery_reset_dialog_title">Reset Password?</string>
<string name="account_recovery_reset_dialog_text">"For security reasons, youll have to wait 72 hours before you can change the password for %1s.\n\nIf you have a recovery method set up, try account recovery instead. This will allow you to change your password straight away."</string>
<string name="account_recovery_reset_dialog_action_request_reset">Request password reset</string>
<string name="account_recovery_reset_dialog_action_use_recovery">Use recovery method</string>
@@ -149,6 +149,83 @@ public final class me/proton/core/observability/domain/metrics/AccountRecoveryCa
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}
public final class me/proton/core/observability/domain/metrics/AccountRecoveryResetTotal : me/proton/core/observability/domain/metrics/CoreObservabilityData {
public static final field Companion Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$Companion;
public fun <init> (Ljava/lang/Object;)V
public fun <init> (Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;)V
public fun <init> (Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$LabelsData;J)V
public synthetic fun <init> (Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$LabelsData;JILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$LabelsData;
public final fun component2 ()J
public final fun copy (Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$LabelsData;J)Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal;
public static synthetic fun copy$default (Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal;Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$LabelsData;JILjava/lang/Object;)Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal;
public fun equals (Ljava/lang/Object;)Z
public synthetic fun getLabels ()Ljava/lang/Object;
public fun getLabels ()Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$LabelsData;
public fun getValue ()J
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class me/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$$serializer;
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal;
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}
public final class me/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus : java/lang/Enum {
public static final field cancellation Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;
public static final field connectionError Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;
public static final field http1xx Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;
public static final field http2xx Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;
public static final field http3xx Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;
public static final field http4xx Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;
public static final field http5xx Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;
public static final field notConnected Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;
public static final field parseError Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;
public static final field sslError Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;
public static final field unknown Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public static fun valueOf (Ljava/lang/String;)Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;
public static fun values ()[Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;
}
public final class me/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}
public final class me/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$LabelsData {
public static final field Companion Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$LabelsData$Companion;
public fun <init> (Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;)V
public final fun component1 ()Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;
public final fun copy (Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;)Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$LabelsData;
public static synthetic fun copy$default (Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$LabelsData;Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;ILjava/lang/Object;)Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$LabelsData;
public fun equals (Ljava/lang/Object;)Z
public final fun getStatus ()Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$ApiStatus;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class me/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$LabelsData$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$LabelsData$$serializer;
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$LabelsData;
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lme/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$LabelsData;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}
public final class me/proton/core/observability/domain/metrics/AccountRecoveryResetTotal$LabelsData$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}
public final class me/proton/core/observability/domain/metrics/AccountRecoveryScreenViewTotal : me/proton/core/observability/domain/metrics/CoreObservabilityData {
public static final field Companion Lme/proton/core/observability/domain/metrics/AccountRecoveryScreenViewTotal$Companion;
public fun <init> (Lme/proton/core/observability/domain/metrics/AccountRecoveryScreenViewTotal$LabelsData;J)V
@@ -219,6 +296,83 @@ public final class me/proton/core/observability/domain/metrics/AccountRecoverySc
public static fun values ()[Lme/proton/core/observability/domain/metrics/AccountRecoveryScreenViewTotal$ScreenId;
}
public final class me/proton/core/observability/domain/metrics/AccountRecoveryStartTotal : me/proton/core/observability/domain/metrics/CoreObservabilityData {
public static final field Companion Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$Companion;
public fun <init> (Ljava/lang/Object;)V
public fun <init> (Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;)V
public fun <init> (Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$LabelsData;J)V
public synthetic fun <init> (Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$LabelsData;JILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$LabelsData;
public final fun component2 ()J
public final fun copy (Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$LabelsData;J)Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal;
public static synthetic fun copy$default (Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal;Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$LabelsData;JILjava/lang/Object;)Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal;
public fun equals (Ljava/lang/Object;)Z
public synthetic fun getLabels ()Ljava/lang/Object;
public fun getLabels ()Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$LabelsData;
public fun getValue ()J
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class me/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$$serializer;
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal;
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}
public final class me/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus : java/lang/Enum {
public static final field cancellation Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;
public static final field connectionError Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;
public static final field http1xx Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;
public static final field http2xx Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;
public static final field http3xx Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;
public static final field http4xx Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;
public static final field http5xx Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;
public static final field notConnected Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;
public static final field parseError Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;
public static final field sslError Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;
public static final field unknown Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public static fun valueOf (Ljava/lang/String;)Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;
public static fun values ()[Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;
}
public final class me/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}
public final class me/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$LabelsData {
public static final field Companion Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$LabelsData$Companion;
public fun <init> (Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;)V
public final fun component1 ()Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;
public final fun copy (Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;)Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$LabelsData;
public static synthetic fun copy$default (Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$LabelsData;Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;ILjava/lang/Object;)Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$LabelsData;
public fun equals (Ljava/lang/Object;)Z
public final fun getStatus ()Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$ApiStatus;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class me/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$LabelsData$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$LabelsData$$serializer;
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$LabelsData;
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lme/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$LabelsData;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}
public final class me/proton/core/observability/domain/metrics/AccountRecoveryStartTotal$LabelsData$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}
public final class me/proton/core/observability/domain/metrics/CheckoutBillingSubscribeTotal : me/proton/core/observability/domain/metrics/CoreObservabilityData {
public static final field Companion Lme/proton/core/observability/domain/metrics/CheckoutBillingSubscribeTotal$Companion;
public fun <init> (Lme/proton/core/observability/domain/metrics/CheckoutBillingSubscribeTotal$LabelsData;J)V
+2 -2
View File
@@ -26,8 +26,8 @@ plugins {
}
protonCoverage {
branchCoveragePercentage.set(53)
lineCoveragePercentage.set(46)
branchCoveragePercentage.set(49)
lineCoveragePercentage.set(42)
}
publishOption.shouldBePublishedAsLib = true
@@ -0,0 +1,54 @@
package me.proton.core.observability.domain.metrics
import io.swagger.v3.oas.annotations.media.Schema
import kotlinx.serialization.Required
import kotlinx.serialization.Serializable
import me.proton.core.observability.domain.entity.SchemaId
import me.proton.core.observability.domain.metrics.common.HttpApiStatus
import me.proton.core.observability.domain.metrics.common.toHttpApiStatus
@Serializable
@Schema(description = "Reset password during account recovery process (state = Insecure).")
@SchemaId("https://proton.me/android_core_accountRecovery_reset_total_v1.schema.json")
public data class AccountRecoveryResetTotal(
override val Labels: LabelsData,
@Required override val Value: Long = 1,
) : CoreObservabilityData() {
public constructor(result: Result<*>) : this(result.toHttpApiStatus().toApiStatus())
public constructor(status: ApiStatus) : this(LabelsData(status))
@Serializable
public data class LabelsData constructor(
val status: ApiStatus
)
@Suppress("EnumNaming", "EnumEntryName")
public enum class ApiStatus {
http1xx,
http2xx,
http3xx,
http4xx,
http5xx,
connectionError,
notConnected,
parseError,
sslError,
cancellation,
unknown
}
}
private fun HttpApiStatus.toApiStatus(): AccountRecoveryResetTotal.ApiStatus = when (this) {
HttpApiStatus.http1xx -> AccountRecoveryResetTotal.ApiStatus.http1xx
HttpApiStatus.http2xx -> AccountRecoveryResetTotal.ApiStatus.http2xx
HttpApiStatus.http3xx -> AccountRecoveryResetTotal.ApiStatus.http3xx
HttpApiStatus.http4xx -> AccountRecoveryResetTotal.ApiStatus.http4xx
HttpApiStatus.http5xx -> AccountRecoveryResetTotal.ApiStatus.http5xx
HttpApiStatus.connectionError -> AccountRecoveryResetTotal.ApiStatus.connectionError
HttpApiStatus.notConnected -> AccountRecoveryResetTotal.ApiStatus.notConnected
HttpApiStatus.parseError -> AccountRecoveryResetTotal.ApiStatus.parseError
HttpApiStatus.sslError -> AccountRecoveryResetTotal.ApiStatus.sslError
HttpApiStatus.cancellation -> AccountRecoveryResetTotal.ApiStatus.cancellation
HttpApiStatus.unknown -> AccountRecoveryResetTotal.ApiStatus.unknown
}
@@ -0,0 +1,54 @@
package me.proton.core.observability.domain.metrics
import io.swagger.v3.oas.annotations.media.Schema
import kotlinx.serialization.Required
import kotlinx.serialization.Serializable
import me.proton.core.observability.domain.entity.SchemaId
import me.proton.core.observability.domain.metrics.common.HttpApiStatus
import me.proton.core.observability.domain.metrics.common.toHttpApiStatus
@Serializable
@Schema(description = "Start an account recovery process.")
@SchemaId("https://proton.me/android_core_accountRecovery_start_total_v1.schema.json")
public data class AccountRecoveryStartTotal(
override val Labels: LabelsData,
@Required override val Value: Long = 1,
) : CoreObservabilityData() {
public constructor(result: Result<*>) : this(result.toHttpApiStatus().toApiStatus())
public constructor(status: ApiStatus) : this(LabelsData(status))
@Serializable
public data class LabelsData constructor(
val status: ApiStatus
)
@Suppress("EnumNaming", "EnumEntryName")
public enum class ApiStatus {
http1xx,
http2xx,
http3xx,
http4xx,
http5xx,
connectionError,
notConnected,
parseError,
sslError,
cancellation,
unknown
}
}
private fun HttpApiStatus.toApiStatus(): AccountRecoveryStartTotal.ApiStatus = when (this) {
HttpApiStatus.http1xx -> AccountRecoveryStartTotal.ApiStatus.http1xx
HttpApiStatus.http2xx -> AccountRecoveryStartTotal.ApiStatus.http2xx
HttpApiStatus.http3xx -> AccountRecoveryStartTotal.ApiStatus.http3xx
HttpApiStatus.http4xx -> AccountRecoveryStartTotal.ApiStatus.http4xx
HttpApiStatus.http5xx -> AccountRecoveryStartTotal.ApiStatus.http5xx
HttpApiStatus.connectionError -> AccountRecoveryStartTotal.ApiStatus.connectionError
HttpApiStatus.notConnected -> AccountRecoveryStartTotal.ApiStatus.notConnected
HttpApiStatus.parseError -> AccountRecoveryStartTotal.ApiStatus.parseError
HttpApiStatus.sslError -> AccountRecoveryStartTotal.ApiStatus.sslError
HttpApiStatus.cancellation -> AccountRecoveryStartTotal.ApiStatus.cancellation
HttpApiStatus.unknown -> AccountRecoveryStartTotal.ApiStatus.unknown
}
@@ -25,16 +25,9 @@ import me.proton.core.crypto.common.keystore.EncryptedString
import me.proton.core.crypto.common.keystore.decrypt
import me.proton.core.crypto.common.keystore.use
import me.proton.core.domain.entity.UserId
import me.proton.core.key.domain.extension.updatePrivateKeyPassphraseOrNull
import me.proton.core.key.domain.repository.PrivateKeyRepository
import me.proton.core.user.domain.UserManager
import me.proton.core.user.domain.extension.hasMigratedKey
import me.proton.core.user.domain.extension.isOrganizationAdmin
import me.proton.core.user.domain.extension.nameNotNull
import me.proton.core.user.domain.repository.UserAddressRepository
import me.proton.core.user.domain.repository.UserRepository
import me.proton.core.usersettings.domain.repository.OrganizationRepository
import me.proton.core.util.kotlin.takeIfNotEmpty
import javax.inject.Inject
class PerformResetUserPassword @Inject constructor(
@@ -42,8 +35,7 @@ class PerformResetUserPassword @Inject constructor(
private val userManager: UserManager,
private val accountRepository: AccountRepository,
private val authRepository: AuthRepository,
private val userRepository: UserRepository,
private val userAddressRepository: UserAddressRepository
private val userRepository: UserRepository
) {
private val keyStore = context.keyStoreCrypto
private val srp = context.srpCrypto
@@ -36,7 +36,6 @@ import me.proton.core.user.domain.UserManager
import me.proton.core.user.domain.entity.Role
import me.proton.core.user.domain.entity.Type
import me.proton.core.user.domain.entity.User
import me.proton.core.user.domain.repository.UserAddressRepository
import me.proton.core.user.domain.repository.UserRepository
import me.proton.core.usersettings.domain.repository.OrganizationRepository
import org.junit.Before
@@ -50,7 +49,6 @@ class PerformResetUserPasswordTest {
private val accountRepository = mockk<AccountRepository>(relaxed = true)
private val authRepository = mockk<AuthRepository>(relaxed = true)
private val userRepository = mockk<UserRepository>(relaxed = true)
private val userAddressRepository = mockk<UserAddressRepository>(relaxed = true)
private val organizationRepository = mockk<OrganizationRepository>(relaxed = true)
private val srpCrypto = mockk<SrpCrypto>(relaxed = true)
private val keyStoreCrypto = mockk<KeyStoreCrypto>(relaxed = true)
@@ -140,7 +138,6 @@ class PerformResetUserPasswordTest {
accountRepository = accountRepository,
authRepository = authRepository,
userRepository = userRepository,
userAddressRepository = userAddressRepository
)
}
@@ -38,12 +38,16 @@ import me.proton.core.compose.viewmodel.stopTimeoutMillis
import me.proton.core.crypto.common.keystore.KeyStoreCrypto
import me.proton.core.crypto.common.keystore.encrypt
import me.proton.core.domain.entity.UserId
import me.proton.core.observability.domain.ObservabilityContext
import me.proton.core.observability.domain.ObservabilityManager
import me.proton.core.observability.domain.metrics.AccountRecoveryResetTotal
import me.proton.core.presentation.viewmodel.ProtonViewModel
import me.proton.core.user.domain.entity.UserRecovery
import me.proton.core.usersettings.domain.usecase.ObserveUserSettings
import me.proton.core.usersettings.domain.usecase.PerformUpdateLoginPassword
import me.proton.core.usersettings.domain.usecase.PerformUpdateUserPassword
import me.proton.core.usersettings.domain.usecase.PerformResetUserPassword
import me.proton.core.util.kotlin.coroutine.flowWithResultContext
import javax.inject.Inject
@HiltViewModel
@@ -56,7 +60,8 @@ class PasswordManagementViewModel @Inject constructor(
private val performUpdateUserPassword: PerformUpdateUserPassword,
private val performResetPassword: PerformResetUserPassword,
private val isAccountRecoveryResetEnabled: IsAccountRecoveryResetEnabled,
) : ProtonViewModel() {
override val observabilityManager: ObservabilityManager,
) : ProtonViewModel(), ObservabilityContext {
private var pendingUpdate: Action.UpdatePassword? = null
@@ -94,7 +99,7 @@ class PasswordManagementViewModel @Inject constructor(
currentUserId.emit(userId)
}
private fun updatePassword(action: Action.UpdatePassword): Flow<State> = when {
private suspend fun updatePassword(action: Action.UpdatePassword): Flow<State> = when {
pendingUpdate == null && userSettings?.twoFA?.enabled == true -> {
pendingUpdate = action
flowOf(State.TwoFactorNeeded)
@@ -155,17 +160,19 @@ class PasswordManagementViewModel @Inject constructor(
emit(State.Success)
}
private fun resetPassword(action: Action.UpdatePassword): Flow<State> = flow {
emit(State.UpdatingPassword)
private suspend fun resetPassword(action: Action.UpdatePassword): Flow<State> = flowWithResultContext {
it.onResultEnqueueObservability("account_recovery.reset") { AccountRecoveryResetTotal(this) }
send(State.UpdatingPassword)
val encryptedNewPassword = action.newPassword.encrypt(keyStoreCrypto)
performResetPassword(
userId = action.userId,
newPassword = encryptedNewPassword,
)
emit(State.Success)
send(State.Success)
}
private fun setTwoFactor(action: Action.SetTwoFactor): Flow<State> {
private suspend fun setTwoFactor(action: Action.SetTwoFactor): Flow<State> {
val passwordAction = requireNotNull(pendingUpdate?.copy(secondFactorCode = action.code))
return updatePassword(passwordAction)
}