mirror of
https://github.com/ProtonMail/protoncore_android.git
synced 2026-05-15 09:50:41 +00:00
refactor(user-settings, auth, observability): Refactor to use SecondFactorProof instead of the duplicate SecondFactorFido.kt.
This commit is contained in:
@@ -157,7 +157,10 @@ public final class me/proton/core/auth/fido/domain/entity/Fido2RegisteredKey$Com
|
||||
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/fido/domain/entity/SecondFactorFido {
|
||||
public abstract class me/proton/core/auth/fido/domain/entity/SecondFactorProof {
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/fido/domain/entity/SecondFactorProof$Fido2 : me/proton/core/auth/fido/domain/entity/SecondFactorProof {
|
||||
public fun <init> (Lme/proton/core/auth/fido/domain/entity/Fido2PublicKeyCredentialRequestOptions;[B[B[B[B)V
|
||||
public final fun getAuthenticatorData ()[B
|
||||
public final fun getClientData ()[B
|
||||
@@ -166,6 +169,32 @@ public final class me/proton/core/auth/fido/domain/entity/SecondFactorFido {
|
||||
public final fun getSignature ()[B
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/fido/domain/entity/SecondFactorProof$SecondFactorCode : me/proton/core/auth/fido/domain/entity/SecondFactorProof {
|
||||
public fun <init> (Ljava/lang/String;)V
|
||||
public final fun component1 ()Ljava/lang/String;
|
||||
public final fun copy (Ljava/lang/String;)Lme/proton/core/auth/fido/domain/entity/SecondFactorProof$SecondFactorCode;
|
||||
public static synthetic fun copy$default (Lme/proton/core/auth/fido/domain/entity/SecondFactorProof$SecondFactorCode;Ljava/lang/String;ILjava/lang/Object;)Lme/proton/core/auth/fido/domain/entity/SecondFactorProof$SecondFactorCode;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getCode ()Ljava/lang/String;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/fido/domain/entity/SecondFactorProof$SecondFactorSignature : me/proton/core/auth/fido/domain/entity/SecondFactorProof {
|
||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
||||
public final fun component1 ()Ljava/lang/String;
|
||||
public final fun component2 ()Ljava/lang/String;
|
||||
public final fun component3 ()Ljava/lang/String;
|
||||
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lme/proton/core/auth/fido/domain/entity/SecondFactorProof$SecondFactorSignature;
|
||||
public static synthetic fun copy$default (Lme/proton/core/auth/fido/domain/entity/SecondFactorProof$SecondFactorSignature;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lme/proton/core/auth/fido/domain/entity/SecondFactorProof$SecondFactorSignature;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getClientData ()Ljava/lang/String;
|
||||
public final fun getKeyHandle ()Ljava/lang/String;
|
||||
public final fun getSignatureData ()Ljava/lang/String;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/fido/domain/ext/Fido2AuthenticationExtensionsClientInputsExtKt {
|
||||
public static final fun toJson (Lme/proton/core/auth/fido/domain/entity/Fido2AuthenticationExtensionsClientInputs;)Lkotlinx/serialization/json/JsonObject;
|
||||
}
|
||||
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Proton Technologies AG
|
||||
* This file is part of Proton AG and ProtonCore.
|
||||
*
|
||||
* ProtonCore is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ProtonCore is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.auth.fido.domain.entity
|
||||
|
||||
public class SecondFactorFido(
|
||||
public val publicKeyOptions: Fido2PublicKeyCredentialRequestOptions,
|
||||
public val clientData: ByteArray,
|
||||
public val authenticatorData: ByteArray,
|
||||
public val signature: ByteArray,
|
||||
public val credentialID: ByteArray
|
||||
)
|
||||
+10
-12
@@ -16,30 +16,28 @@
|
||||
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.auth.domain.entity
|
||||
package me.proton.core.auth.fido.domain.entity
|
||||
|
||||
import me.proton.core.auth.fido.domain.entity.Fido2PublicKeyCredentialRequestOptions
|
||||
|
||||
sealed class SecondFactorProof {
|
||||
public sealed class SecondFactorProof {
|
||||
|
||||
/**
|
||||
* The 2FA code here is string, because the same will be used for recovery code (which happens on the same route).
|
||||
*/
|
||||
data class SecondFactorCode(
|
||||
public data class SecondFactorCode(
|
||||
val code: String
|
||||
) : SecondFactorProof()
|
||||
|
||||
data class SecondFactorSignature(
|
||||
public data class SecondFactorSignature(
|
||||
val keyHandle: String,
|
||||
val clientData: String,
|
||||
val signatureData: String
|
||||
) : SecondFactorProof()
|
||||
|
||||
class Fido2(
|
||||
val publicKeyOptions: Fido2PublicKeyCredentialRequestOptions,
|
||||
val clientData: ByteArray,
|
||||
val authenticatorData: ByteArray,
|
||||
val signature: ByteArray,
|
||||
val credentialID: ByteArray
|
||||
public class Fido2(
|
||||
public val publicKeyOptions: Fido2PublicKeyCredentialRequestOptions,
|
||||
public val clientData: ByteArray,
|
||||
public val authenticatorData: ByteArray,
|
||||
public val signature: ByteArray,
|
||||
public val credentialID: ByteArray
|
||||
) : SecondFactorProof()
|
||||
}
|
||||
@@ -474,7 +474,9 @@ public final class me/proton/core/auth/data/api/request/SecondFactorRequest$Comp
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/data/api/request/SecondFactorRequestKt {
|
||||
public static final fun toFido2Request (Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;)Lme/proton/core/auth/data/api/request/Fido2Request;
|
||||
public static final fun toFido2Request (Lme/proton/core/auth/fido/domain/entity/SecondFactorProof$Fido2;)Lme/proton/core/auth/data/api/request/Fido2Request;
|
||||
public static final fun toSecondFactorCode (Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;)Ljava/lang/String;
|
||||
public static final fun toSecondFactorFido (Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;)Lme/proton/core/auth/data/api/request/Fido2Request;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/data/api/request/UniversalTwoFactorRequest {
|
||||
@@ -823,7 +825,6 @@ public final class me/proton/core/auth/data/api/response/SessionResponse$Compani
|
||||
|
||||
public final class me/proton/core/auth/data/feature/IsFido2EnabledImpl : me/proton/core/featureflag/data/IsFeatureFlagEnabledImpl, me/proton/core/auth/domain/feature/IsFido2Enabled {
|
||||
public fun <init> (Landroid/content/Context;Lme/proton/core/featureflag/domain/FeatureFlagManager;Ljava/util/Optional;)V
|
||||
public fun invoke (Lme/proton/core/domain/entity/UserId;)Z
|
||||
public fun isLocalEnabled ()Z
|
||||
}
|
||||
|
||||
@@ -843,7 +844,7 @@ public final class me/proton/core/auth/data/repository/AuthRepositoryImpl : me/p
|
||||
public fun performLogin (Ljava/lang/String;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun performLoginLess (Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun performLoginSso (Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun performSecondFactor (Lme/proton/core/network/domain/session/SessionId;Lme/proton/core/auth/domain/entity/SecondFactorProof;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun performSecondFactor (Lme/proton/core/network/domain/session/SessionId;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun randomModulus (Lme/proton/core/network/domain/session/SessionId;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun refreshSession (Lme/proton/core/network/domain/session/Session;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun requestSession (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
|
||||
@@ -29,7 +29,7 @@ protonBuild {
|
||||
}
|
||||
|
||||
protonCoverage {
|
||||
branchCoveragePercentage.set(60)
|
||||
branchCoveragePercentage.set(57)
|
||||
lineCoveragePercentage.set(60)
|
||||
}
|
||||
|
||||
|
||||
+8
-2
@@ -24,7 +24,7 @@ import kotlinx.serialization.Serializable
|
||||
import me.proton.core.auth.data.api.fido2.AuthenticationOptionsData
|
||||
import me.proton.core.auth.data.api.fido2.PublicKeyCredentialDescriptorData
|
||||
import me.proton.core.auth.data.api.fido2.PublicKeyCredentialRequestOptionsResponse
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.auth.fido.domain.ext.toJson
|
||||
|
||||
@Serializable
|
||||
@@ -87,7 +87,7 @@ data class Fido2Request(
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
fun SecondFactorFido.toFido2Request(): Fido2Request {
|
||||
fun SecondFactorProof.Fido2.toFido2Request(): Fido2Request {
|
||||
val optionsData = AuthenticationOptionsData(
|
||||
PublicKeyCredentialRequestOptionsResponse(
|
||||
challenge = publicKeyOptions.challenge,
|
||||
@@ -114,3 +114,9 @@ fun SecondFactorFido.toFido2Request(): Fido2Request {
|
||||
}
|
||||
|
||||
private fun ByteArray.toBase64(): String = Base64.encodeToString(this, Base64.NO_WRAP)
|
||||
|
||||
fun SecondFactorProof?.toSecondFactorCode(): String? = if (this is SecondFactorProof.SecondFactorCode) code else null
|
||||
|
||||
fun SecondFactorProof?.toSecondFactorFido(): Fido2Request? =
|
||||
if (this is SecondFactorProof.Fido2) toFido2Request() else null
|
||||
|
||||
|
||||
@@ -40,10 +40,10 @@ import me.proton.core.auth.domain.entity.AuthInfo
|
||||
import me.proton.core.auth.domain.entity.AuthIntent
|
||||
import me.proton.core.auth.domain.entity.Modulus
|
||||
import me.proton.core.auth.domain.entity.ScopeInfo
|
||||
import me.proton.core.auth.domain.entity.SecondFactorProof
|
||||
import me.proton.core.auth.domain.entity.SessionInfo
|
||||
import me.proton.core.auth.domain.repository.AuthRepository
|
||||
import me.proton.core.auth.domain.usecase.ValidateServerProof
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.challenge.data.frame.ChallengeFrame
|
||||
import me.proton.core.challenge.domain.entity.ChallengeFrameDetails
|
||||
import me.proton.core.challenge.domain.framePrefix
|
||||
|
||||
+1
-1
@@ -33,11 +33,11 @@ import me.proton.core.auth.data.api.response.SecondFactorResponse
|
||||
import me.proton.core.auth.data.api.response.SessionResponse
|
||||
import me.proton.core.auth.domain.entity.AuthInfo
|
||||
import me.proton.core.auth.domain.entity.ScopeInfo
|
||||
import me.proton.core.auth.domain.entity.SecondFactorProof
|
||||
import me.proton.core.auth.domain.entity.SessionInfo
|
||||
import me.proton.core.auth.domain.exception.InvalidServerAuthenticationException
|
||||
import me.proton.core.auth.domain.usecase.ValidateServerProof
|
||||
import me.proton.core.auth.fido.domain.entity.Fido2PublicKeyCredentialRequestOptions
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.challenge.data.frame.ChallengeFrame
|
||||
import me.proton.core.challenge.domain.entity.ChallengeFrameDetails
|
||||
import me.proton.core.crypto.common.srp.SrpProofs
|
||||
|
||||
@@ -143,44 +143,6 @@ public final class me/proton/core/auth/domain/entity/SecondFactorMethod : java/l
|
||||
public static fun values ()[Lme/proton/core/auth/domain/entity/SecondFactorMethod;
|
||||
}
|
||||
|
||||
public abstract class me/proton/core/auth/domain/entity/SecondFactorProof {
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/domain/entity/SecondFactorProof$Fido2 : me/proton/core/auth/domain/entity/SecondFactorProof {
|
||||
public fun <init> (Lme/proton/core/auth/fido/domain/entity/Fido2PublicKeyCredentialRequestOptions;[B[B[B[B)V
|
||||
public final fun getAuthenticatorData ()[B
|
||||
public final fun getClientData ()[B
|
||||
public final fun getCredentialID ()[B
|
||||
public final fun getPublicKeyOptions ()Lme/proton/core/auth/fido/domain/entity/Fido2PublicKeyCredentialRequestOptions;
|
||||
public final fun getSignature ()[B
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/domain/entity/SecondFactorProof$SecondFactorCode : me/proton/core/auth/domain/entity/SecondFactorProof {
|
||||
public fun <init> (Ljava/lang/String;)V
|
||||
public final fun component1 ()Ljava/lang/String;
|
||||
public final fun copy (Ljava/lang/String;)Lme/proton/core/auth/domain/entity/SecondFactorProof$SecondFactorCode;
|
||||
public static synthetic fun copy$default (Lme/proton/core/auth/domain/entity/SecondFactorProof$SecondFactorCode;Ljava/lang/String;ILjava/lang/Object;)Lme/proton/core/auth/domain/entity/SecondFactorProof$SecondFactorCode;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getCode ()Ljava/lang/String;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/domain/entity/SecondFactorProof$SecondFactorSignature : me/proton/core/auth/domain/entity/SecondFactorProof {
|
||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
||||
public final fun component1 ()Ljava/lang/String;
|
||||
public final fun component2 ()Ljava/lang/String;
|
||||
public final fun component3 ()Ljava/lang/String;
|
||||
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lme/proton/core/auth/domain/entity/SecondFactorProof$SecondFactorSignature;
|
||||
public static synthetic fun copy$default (Lme/proton/core/auth/domain/entity/SecondFactorProof$SecondFactorSignature;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lme/proton/core/auth/domain/entity/SecondFactorProof$SecondFactorSignature;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getClientData ()Ljava/lang/String;
|
||||
public final fun getKeyHandle ()Ljava/lang/String;
|
||||
public final fun getSignatureData ()Ljava/lang/String;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/domain/entity/SessionDetailsExtKt {
|
||||
public static final fun getFido2AuthenticationOptions (Lme/proton/core/account/domain/entity/SessionDetails;)Lme/proton/core/auth/fido/domain/entity/Fido2AuthenticationOptions;
|
||||
}
|
||||
@@ -240,7 +202,7 @@ public abstract interface class me/proton/core/auth/domain/repository/AuthReposi
|
||||
public abstract fun performLogin (Ljava/lang/String;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun performLoginLess (Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun performLoginSso (Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun performSecondFactor (Lme/proton/core/network/domain/session/SessionId;Lme/proton/core/auth/domain/entity/SecondFactorProof;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun performSecondFactor (Lme/proton/core/network/domain/session/SessionId;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun randomModulus (Lme/proton/core/network/domain/session/SessionId;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun refreshSession (Lme/proton/core/network/domain/session/Session;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun requestSession (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
@@ -352,7 +314,7 @@ public final class me/proton/core/auth/domain/usecase/PerformLogout {
|
||||
|
||||
public final class me/proton/core/auth/domain/usecase/PerformSecondFactor {
|
||||
public fun <init> (Lme/proton/core/auth/domain/repository/AuthRepository;)V
|
||||
public final fun invoke (Lme/proton/core/network/domain/session/SessionId;Lme/proton/core/auth/domain/entity/SecondFactorProof;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public final fun invoke (Lme/proton/core/network/domain/session/SessionId;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/domain/usecase/PostLoginAccountSetup {
|
||||
@@ -574,7 +536,7 @@ public final class me/proton/core/auth/domain/usecase/scopes/ObtainLockedScope {
|
||||
|
||||
public final class me/proton/core/auth/domain/usecase/scopes/ObtainPasswordScope {
|
||||
public fun <init> (Lme/proton/core/auth/domain/repository/AuthRepository;Lme/proton/core/user/domain/repository/UserRepository;Lme/proton/core/crypto/common/context/CryptoContext;)V
|
||||
public final fun invoke (Lme/proton/core/domain/entity/UserId;Lme/proton/core/network/domain/session/SessionId;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public final fun invoke (Lme/proton/core/domain/entity/UserId;Lme/proton/core/network/domain/session/SessionId;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/domain/usecase/scopes/RemoveSecurityScopes {
|
||||
|
||||
@@ -21,8 +21,8 @@ package me.proton.core.auth.domain.repository
|
||||
import me.proton.core.auth.domain.entity.AuthInfo
|
||||
import me.proton.core.auth.domain.entity.Modulus
|
||||
import me.proton.core.auth.domain.entity.ScopeInfo
|
||||
import me.proton.core.auth.domain.entity.SecondFactorProof
|
||||
import me.proton.core.auth.domain.entity.SessionInfo
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.challenge.domain.entity.ChallengeFrameDetails
|
||||
import me.proton.core.crypto.common.srp.SrpProofs
|
||||
import me.proton.core.network.domain.ApiResult
|
||||
|
||||
+1
-1
@@ -19,8 +19,8 @@
|
||||
package me.proton.core.auth.domain.usecase
|
||||
|
||||
import me.proton.core.auth.domain.entity.ScopeInfo
|
||||
import me.proton.core.auth.domain.entity.SecondFactorProof
|
||||
import me.proton.core.auth.domain.repository.AuthRepository
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.network.domain.session.SessionId
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
+3
-5
@@ -19,7 +19,7 @@
|
||||
package me.proton.core.auth.domain.usecase.scopes
|
||||
|
||||
import me.proton.core.auth.domain.repository.AuthRepository
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.context.CryptoContext
|
||||
import me.proton.core.crypto.common.keystore.EncryptedString
|
||||
import me.proton.core.crypto.common.keystore.decrypt
|
||||
@@ -39,8 +39,7 @@ class ObtainPasswordScope @Inject constructor(
|
||||
sessionId: SessionId,
|
||||
username: String,
|
||||
password: EncryptedString,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?
|
||||
secondFactorProof: SecondFactorProof?
|
||||
): Boolean {
|
||||
val authInfo = authRepository.getAuthInfoSrp(
|
||||
sessionId = sessionId,
|
||||
@@ -59,8 +58,7 @@ class ObtainPasswordScope @Inject constructor(
|
||||
userId,
|
||||
clientProofs,
|
||||
authInfo.srpSession,
|
||||
secondFactorCode = secondFactorCode,
|
||||
secondFactorFido = secondFactorFido
|
||||
secondFactorProof
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -23,8 +23,8 @@ import io.mockk.coVerify
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import me.proton.core.auth.domain.entity.ScopeInfo
|
||||
import me.proton.core.auth.domain.entity.SecondFactorProof
|
||||
import me.proton.core.auth.domain.repository.AuthRepository
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.network.domain.ApiException
|
||||
import me.proton.core.network.domain.ApiResult
|
||||
import me.proton.core.network.domain.session.SessionId
|
||||
|
||||
+9
-13
@@ -25,6 +25,7 @@ import io.mockk.mockk
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import me.proton.core.auth.domain.entity.AuthInfo
|
||||
import me.proton.core.auth.domain.repository.AuthRepository
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.context.CryptoContext
|
||||
import me.proton.core.crypto.common.keystore.KeyStoreCrypto
|
||||
import me.proton.core.crypto.common.srp.SrpCrypto
|
||||
@@ -56,7 +57,7 @@ class ObtainPasswordScopeTest {
|
||||
private val testUsername = "test-username"
|
||||
private val testPassword = "test-password"
|
||||
private val testPasswordEncrypted = "test-password-encrypted"
|
||||
private val test2FACode = "test-2fa"
|
||||
private val test2FACode = SecondFactorProof.SecondFactorCode("test-2fa")
|
||||
private val testUserId = UserId(testUserIdString)
|
||||
private val testSessionId = SessionId(testSessionIdString)
|
||||
private val testModulus = "test-modulus"
|
||||
@@ -102,7 +103,6 @@ class ObtainPasswordScopeTest {
|
||||
testUserId,
|
||||
testSrpProofs,
|
||||
authInfoResult.srpSession,
|
||||
null,
|
||||
null
|
||||
)
|
||||
} returns true
|
||||
@@ -111,7 +111,7 @@ class ObtainPasswordScopeTest {
|
||||
|
||||
@Test
|
||||
fun testUnlockingPasswordNo2FASuccess() = runTest {
|
||||
val result = useCase.invoke(testUserId, testSessionId, testUsername, testPasswordEncrypted, null, null)
|
||||
val result = useCase.invoke(testUserId, testSessionId, testUsername, testPasswordEncrypted, null)
|
||||
|
||||
coVerify { authRepository.getAuthInfoSrp(testSessionId, testUsername) }
|
||||
assertTrue(result)
|
||||
@@ -124,11 +124,10 @@ class ObtainPasswordScopeTest {
|
||||
testUserId,
|
||||
testSrpProofs,
|
||||
authInfoResult.srpSession,
|
||||
test2FACode,
|
||||
null
|
||||
test2FACode
|
||||
)
|
||||
} returns true
|
||||
val result = useCase.invoke(testUserId, testSessionId, testUsername, testPasswordEncrypted, test2FACode, null)
|
||||
val result = useCase.invoke(testUserId, testSessionId, testUsername, testPasswordEncrypted, test2FACode)
|
||||
|
||||
coVerify { authRepository.getAuthInfoSrp(testSessionId, testUsername) }
|
||||
assertTrue(result)
|
||||
@@ -141,11 +140,10 @@ class ObtainPasswordScopeTest {
|
||||
testUserId,
|
||||
testSrpProofs,
|
||||
authInfoResult.srpSession,
|
||||
null,
|
||||
null
|
||||
)
|
||||
} returns false
|
||||
val result = useCase.invoke(testUserId, testSessionId, testUsername, testPasswordEncrypted, null, null)
|
||||
val result = useCase.invoke(testUserId, testSessionId, testUsername, testPasswordEncrypted, null)
|
||||
|
||||
coVerify { authRepository.getAuthInfoSrp(testSessionId, testUsername) }
|
||||
assertFalse(result)
|
||||
@@ -158,11 +156,10 @@ class ObtainPasswordScopeTest {
|
||||
testUserId,
|
||||
testSrpProofs,
|
||||
authInfoResult.srpSession,
|
||||
test2FACode,
|
||||
null
|
||||
test2FACode
|
||||
)
|
||||
} returns false
|
||||
val result = useCase.invoke(testUserId, testSessionId, testUsername, testPasswordEncrypted, test2FACode, null)
|
||||
val result = useCase.invoke(testUserId, testSessionId, testUsername, testPasswordEncrypted, test2FACode)
|
||||
|
||||
coVerify { authRepository.getAuthInfoSrp(testSessionId, testUsername) }
|
||||
assertFalse(result)
|
||||
@@ -175,7 +172,6 @@ class ObtainPasswordScopeTest {
|
||||
testUserId,
|
||||
testSrpProofs,
|
||||
authInfoResult.srpSession,
|
||||
null,
|
||||
null
|
||||
)
|
||||
} throws ApiException(
|
||||
@@ -188,7 +184,7 @@ class ObtainPasswordScopeTest {
|
||||
|
||||
// WHEN
|
||||
val throwable = assertFailsWith(ApiException::class) {
|
||||
useCase.invoke(testUserId, testSessionId, testUsername, testPasswordEncrypted, null, null)
|
||||
useCase.invoke(testUserId, testSessionId, testUsername, testPasswordEncrypted, null)
|
||||
}
|
||||
|
||||
// THEN
|
||||
|
||||
@@ -435,7 +435,7 @@ public final class me/proton/core/auth/presentation/alert/TwoFAInputDialog : and
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/alert/TwoFAInputDialog$Companion {
|
||||
public final fun invoke (Ljava/lang/String;Ljava/lang/String;)Lme/proton/core/auth/presentation/alert/TwoFAInputDialog;
|
||||
public final fun invoke (Lme/proton/core/auth/presentation/viewmodel/Source;Ljava/lang/String;)Lme/proton/core/auth/presentation/alert/TwoFAInputDialog;
|
||||
}
|
||||
|
||||
public abstract interface class me/proton/core/auth/presentation/alert/TwoFAInputDialog_GeneratedInjector {
|
||||
@@ -1024,14 +1024,14 @@ public final class me/proton/core/auth/presentation/entity/ChooseAddressResult$U
|
||||
public final fun newArray (I)[Lme/proton/core/auth/presentation/entity/ChooseAddressResult$UserCheckError;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsParcelable : android/os/Parcelable {
|
||||
public final class me/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsEntity : android/os/Parcelable {
|
||||
public static final field CREATOR Landroid/os/Parcelable$Creator;
|
||||
public fun <init> (Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;)V
|
||||
public final fun component1 ()Ljava/lang/String;
|
||||
public final fun component2 ()Ljava/lang/Boolean;
|
||||
public final fun component3 ()Ljava/lang/Boolean;
|
||||
public final fun copy (Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;)Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsParcelable;
|
||||
public static synthetic fun copy$default (Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsParcelable;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;ILjava/lang/Object;)Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsParcelable;
|
||||
public final fun copy (Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;)Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsEntity;
|
||||
public static synthetic fun copy$default (Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsEntity;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Boolean;ILjava/lang/Object;)Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsEntity;
|
||||
public fun describeContents ()I
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getAppId ()Ljava/lang/String;
|
||||
@@ -1042,22 +1042,22 @@ public final class me/proton/core/auth/presentation/entity/Fido2AuthenticationEx
|
||||
public fun writeToParcel (Landroid/os/Parcel;I)V
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsParcelable$Creator : android/os/Parcelable$Creator {
|
||||
public final class me/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsEntity$Creator : android/os/Parcelable$Creator {
|
||||
public fun <init> ()V
|
||||
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
|
||||
public final fun createFromParcel (Landroid/os/Parcel;)Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsParcelable;
|
||||
public final fun createFromParcel (Landroid/os/Parcel;)Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsEntity;
|
||||
public synthetic fun newArray (I)[Ljava/lang/Object;
|
||||
public final fun newArray (I)[Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsParcelable;
|
||||
public final fun newArray (I)[Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsEntity;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorParcelable : android/os/Parcelable {
|
||||
public final class me/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorEntity : android/os/Parcelable {
|
||||
public static final field CREATOR Landroid/os/Parcelable$Creator;
|
||||
public synthetic fun <init> (Ljava/lang/String;[BLjava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun component1 ()Ljava/lang/String;
|
||||
public final fun component2-TcUX1vc ()[B
|
||||
public final fun component3 ()Ljava/util/List;
|
||||
public final fun copy-Coi6ktg (Ljava/lang/String;[BLjava/util/List;)Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorParcelable;
|
||||
public static synthetic fun copy-Coi6ktg$default (Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorParcelable;Ljava/lang/String;[BLjava/util/List;ILjava/lang/Object;)Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorParcelable;
|
||||
public final fun copy-Coi6ktg (Ljava/lang/String;[BLjava/util/List;)Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorEntity;
|
||||
public static synthetic fun copy-Coi6ktg$default (Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorEntity;Ljava/lang/String;[BLjava/util/List;ILjava/lang/Object;)Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorEntity;
|
||||
public fun describeContents ()I
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getId-TcUX1vc ()[B
|
||||
@@ -1068,31 +1068,31 @@ public final class me/proton/core/auth/presentation/entity/Fido2PublicKeyCredent
|
||||
public fun writeToParcel (Landroid/os/Parcel;I)V
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorParcelable$Creator : android/os/Parcelable$Creator {
|
||||
public final class me/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorEntity$Creator : android/os/Parcelable$Creator {
|
||||
public fun <init> ()V
|
||||
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
|
||||
public final fun createFromParcel (Landroid/os/Parcel;)Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorParcelable;
|
||||
public final fun createFromParcel (Landroid/os/Parcel;)Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorEntity;
|
||||
public synthetic fun newArray (I)[Ljava/lang/Object;
|
||||
public final fun newArray (I)[Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorParcelable;
|
||||
public final fun newArray (I)[Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorEntity;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsParcelable : android/os/Parcelable {
|
||||
public final class me/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsEntity : android/os/Parcelable {
|
||||
public static final field CREATOR Landroid/os/Parcelable$Creator;
|
||||
public synthetic fun <init> ([BLkotlin/ULong;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsParcelable;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public synthetic fun <init> ([BLkotlin/ULong;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsParcelable;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public synthetic fun <init> ([BLkotlin/ULong;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsEntity;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public synthetic fun <init> ([BLkotlin/ULong;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsEntity;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun component1-TcUX1vc ()[B
|
||||
public final fun component2-6VbMDqA ()Lkotlin/ULong;
|
||||
public final fun component3 ()Ljava/lang/String;
|
||||
public final fun component4 ()Ljava/util/List;
|
||||
public final fun component5 ()Ljava/lang/String;
|
||||
public final fun component6 ()Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsParcelable;
|
||||
public final fun copy-ebjZ_cE ([BLkotlin/ULong;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsParcelable;)Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsParcelable;
|
||||
public static synthetic fun copy-ebjZ_cE$default (Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsParcelable;[BLkotlin/ULong;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsParcelable;ILjava/lang/Object;)Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsParcelable;
|
||||
public final fun component6 ()Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsEntity;
|
||||
public final fun copy-ebjZ_cE ([BLkotlin/ULong;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsEntity;)Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsEntity;
|
||||
public static synthetic fun copy-ebjZ_cE$default (Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsEntity;[BLkotlin/ULong;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsEntity;ILjava/lang/Object;)Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsEntity;
|
||||
public fun describeContents ()I
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getAllowCredentials ()Ljava/util/List;
|
||||
public final fun getChallenge-TcUX1vc ()[B
|
||||
public final fun getExtensions ()Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsParcelable;
|
||||
public final fun getExtensions ()Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsEntity;
|
||||
public final fun getRpId ()Ljava/lang/String;
|
||||
public final fun getTimeout-6VbMDqA ()Lkotlin/ULong;
|
||||
public final fun getUserVerification ()Ljava/lang/String;
|
||||
@@ -1101,12 +1101,12 @@ public final class me/proton/core/auth/presentation/entity/Fido2PublicKeyCredent
|
||||
public fun writeToParcel (Landroid/os/Parcel;I)V
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsParcelable$Creator : android/os/Parcelable$Creator {
|
||||
public final class me/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsEntity$Creator : android/os/Parcelable$Creator {
|
||||
public fun <init> ()V
|
||||
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
|
||||
public final fun createFromParcel (Landroid/os/Parcel;)Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsParcelable;
|
||||
public final fun createFromParcel (Landroid/os/Parcel;)Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsEntity;
|
||||
public synthetic fun newArray (I)[Ljava/lang/Object;
|
||||
public final fun newArray (I)[Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsParcelable;
|
||||
public final fun newArray (I)[Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsEntity;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/LoginInput : android/os/Parcelable {
|
||||
@@ -1252,16 +1252,6 @@ public final class me/proton/core/auth/presentation/entity/PasswordInput$Creator
|
||||
public final fun newArray (I)[Lme/proton/core/auth/presentation/entity/PasswordInput;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/PasswordInputKt {
|
||||
public static final fun fromParcelable (Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsParcelable;)Lme/proton/core/auth/fido/domain/entity/Fido2AuthenticationExtensionsClientInputs;
|
||||
public static final fun fromParcelable (Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorParcelable;)Lme/proton/core/auth/fido/domain/entity/Fido2PublicKeyCredentialDescriptor;
|
||||
public static final fun fromParcelable (Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsParcelable;)Lme/proton/core/auth/fido/domain/entity/Fido2PublicKeyCredentialRequestOptions;
|
||||
public static final fun fromParcelable (Lme/proton/core/auth/presentation/entity/TwoFaFido;)Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;
|
||||
public static final fun toParcelable (Lme/proton/core/auth/fido/domain/entity/Fido2AuthenticationExtensionsClientInputs;)Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsParcelable;
|
||||
public static final fun toParcelable (Lme/proton/core/auth/fido/domain/entity/Fido2PublicKeyCredentialDescriptor;)Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorParcelable;
|
||||
public static final fun toParcelable (Lme/proton/core/auth/fido/domain/entity/Fido2PublicKeyCredentialRequestOptions;)Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsParcelable;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/SecondFactorInput : android/os/Parcelable {
|
||||
public static final field CREATOR Landroid/os/Parcelable$Creator;
|
||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Lme/proton/core/account/domain/entity/AccountType;Z)V
|
||||
@@ -1290,6 +1280,88 @@ public final class me/proton/core/auth/presentation/entity/SecondFactorInput$Cre
|
||||
public final fun newArray (I)[Lme/proton/core/auth/presentation/entity/SecondFactorInput;
|
||||
}
|
||||
|
||||
public abstract class me/proton/core/auth/presentation/entity/SecondFactorProofEntity : android/os/Parcelable {
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/SecondFactorProofEntity$Fido2Entity : me/proton/core/auth/presentation/entity/SecondFactorProofEntity {
|
||||
public static final field CREATOR Landroid/os/Parcelable$Creator;
|
||||
public fun <init> (Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsEntity;[B[B[B[B)V
|
||||
public fun describeContents ()I
|
||||
public final fun getAuthenticatorData ()[B
|
||||
public final fun getClientData ()[B
|
||||
public final fun getCredentialID ()[B
|
||||
public final fun getPublicKeyOptions ()Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsEntity;
|
||||
public final fun getSignature ()[B
|
||||
public fun writeToParcel (Landroid/os/Parcel;I)V
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/SecondFactorProofEntity$Fido2Entity$Creator : android/os/Parcelable$Creator {
|
||||
public fun <init> ()V
|
||||
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
|
||||
public final fun createFromParcel (Landroid/os/Parcel;)Lme/proton/core/auth/presentation/entity/SecondFactorProofEntity$Fido2Entity;
|
||||
public synthetic fun newArray (I)[Ljava/lang/Object;
|
||||
public final fun newArray (I)[Lme/proton/core/auth/presentation/entity/SecondFactorProofEntity$Fido2Entity;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/SecondFactorProofEntity$SecondFactorCodeEntity : me/proton/core/auth/presentation/entity/SecondFactorProofEntity {
|
||||
public static final field CREATOR Landroid/os/Parcelable$Creator;
|
||||
public fun <init> (Ljava/lang/String;)V
|
||||
public final fun component1 ()Ljava/lang/String;
|
||||
public final fun copy (Ljava/lang/String;)Lme/proton/core/auth/presentation/entity/SecondFactorProofEntity$SecondFactorCodeEntity;
|
||||
public static synthetic fun copy$default (Lme/proton/core/auth/presentation/entity/SecondFactorProofEntity$SecondFactorCodeEntity;Ljava/lang/String;ILjava/lang/Object;)Lme/proton/core/auth/presentation/entity/SecondFactorProofEntity$SecondFactorCodeEntity;
|
||||
public fun describeContents ()I
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getCode ()Ljava/lang/String;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
public fun writeToParcel (Landroid/os/Parcel;I)V
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/SecondFactorProofEntity$SecondFactorCodeEntity$Creator : android/os/Parcelable$Creator {
|
||||
public fun <init> ()V
|
||||
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
|
||||
public final fun createFromParcel (Landroid/os/Parcel;)Lme/proton/core/auth/presentation/entity/SecondFactorProofEntity$SecondFactorCodeEntity;
|
||||
public synthetic fun newArray (I)[Ljava/lang/Object;
|
||||
public final fun newArray (I)[Lme/proton/core/auth/presentation/entity/SecondFactorProofEntity$SecondFactorCodeEntity;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/SecondFactorProofEntity$SecondFactorSignatureEntity : me/proton/core/auth/presentation/entity/SecondFactorProofEntity {
|
||||
public static final field CREATOR Landroid/os/Parcelable$Creator;
|
||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
||||
public final fun component1 ()Ljava/lang/String;
|
||||
public final fun component2 ()Ljava/lang/String;
|
||||
public final fun component3 ()Ljava/lang/String;
|
||||
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lme/proton/core/auth/presentation/entity/SecondFactorProofEntity$SecondFactorSignatureEntity;
|
||||
public static synthetic fun copy$default (Lme/proton/core/auth/presentation/entity/SecondFactorProofEntity$SecondFactorSignatureEntity;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lme/proton/core/auth/presentation/entity/SecondFactorProofEntity$SecondFactorSignatureEntity;
|
||||
public fun describeContents ()I
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getClientData ()Ljava/lang/String;
|
||||
public final fun getKeyHandle ()Ljava/lang/String;
|
||||
public final fun getSignatureData ()Ljava/lang/String;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
public fun writeToParcel (Landroid/os/Parcel;I)V
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/SecondFactorProofEntity$SecondFactorSignatureEntity$Creator : android/os/Parcelable$Creator {
|
||||
public fun <init> ()V
|
||||
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
|
||||
public final fun createFromParcel (Landroid/os/Parcel;)Lme/proton/core/auth/presentation/entity/SecondFactorProofEntity$SecondFactorSignatureEntity;
|
||||
public synthetic fun newArray (I)[Ljava/lang/Object;
|
||||
public final fun newArray (I)[Lme/proton/core/auth/presentation/entity/SecondFactorProofEntity$SecondFactorSignatureEntity;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/SecondFactorProofEntityKt {
|
||||
public static final fun fromEntity (Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsEntity;)Lme/proton/core/auth/fido/domain/entity/Fido2AuthenticationExtensionsClientInputs;
|
||||
public static final fun fromEntity (Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorEntity;)Lme/proton/core/auth/fido/domain/entity/Fido2PublicKeyCredentialDescriptor;
|
||||
public static final fun fromEntity (Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsEntity;)Lme/proton/core/auth/fido/domain/entity/Fido2PublicKeyCredentialRequestOptions;
|
||||
public static final fun fromEntity (Lme/proton/core/auth/presentation/entity/SecondFactorProofEntity$Fido2Entity;)Lme/proton/core/auth/fido/domain/entity/SecondFactorProof$Fido2;
|
||||
public static final fun fromEntity (Lme/proton/core/auth/presentation/entity/SecondFactorProofEntity;)Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;
|
||||
public static final fun toEntity (Lme/proton/core/auth/fido/domain/entity/Fido2AuthenticationExtensionsClientInputs;)Lme/proton/core/auth/presentation/entity/Fido2AuthenticationExtensionsClientInputsEntity;
|
||||
public static final fun toEntity (Lme/proton/core/auth/fido/domain/entity/Fido2PublicKeyCredentialDescriptor;)Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialDescriptorEntity;
|
||||
public static final fun toEntity (Lme/proton/core/auth/fido/domain/entity/Fido2PublicKeyCredentialRequestOptions;)Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsEntity;
|
||||
}
|
||||
|
||||
public abstract class me/proton/core/auth/presentation/entity/SecondFactorResult : android/os/Parcelable {
|
||||
}
|
||||
|
||||
@@ -1389,32 +1461,6 @@ public final class me/proton/core/auth/presentation/entity/SessionResult$Creator
|
||||
public final fun newArray (I)[Lme/proton/core/auth/presentation/entity/SessionResult;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/TwoFAInput : android/os/Parcelable {
|
||||
public static final field CREATOR Landroid/os/Parcelable$Creator;
|
||||
public fun <init> ()V
|
||||
public fun <init> (Ljava/lang/String;Lme/proton/core/auth/presentation/entity/TwoFaFido;)V
|
||||
public synthetic fun <init> (Ljava/lang/String;Lme/proton/core/auth/presentation/entity/TwoFaFido;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun component1 ()Ljava/lang/String;
|
||||
public final fun component2 ()Lme/proton/core/auth/presentation/entity/TwoFaFido;
|
||||
public final fun copy (Ljava/lang/String;Lme/proton/core/auth/presentation/entity/TwoFaFido;)Lme/proton/core/auth/presentation/entity/TwoFAInput;
|
||||
public static synthetic fun copy$default (Lme/proton/core/auth/presentation/entity/TwoFAInput;Ljava/lang/String;Lme/proton/core/auth/presentation/entity/TwoFaFido;ILjava/lang/Object;)Lme/proton/core/auth/presentation/entity/TwoFAInput;
|
||||
public fun describeContents ()I
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getTwoFA ()Ljava/lang/String;
|
||||
public final fun getTwoFAFido ()Lme/proton/core/auth/presentation/entity/TwoFaFido;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
public fun writeToParcel (Landroid/os/Parcel;I)V
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/TwoFAInput$Creator : android/os/Parcelable$Creator {
|
||||
public fun <init> ()V
|
||||
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
|
||||
public final fun createFromParcel (Landroid/os/Parcel;)Lme/proton/core/auth/presentation/entity/TwoFAInput;
|
||||
public synthetic fun newArray (I)[Ljava/lang/Object;
|
||||
public final fun newArray (I)[Lme/proton/core/auth/presentation/entity/TwoFAInput;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/TwoFAMechanisms : java/lang/Enum {
|
||||
public static final field Companion Lme/proton/core/auth/presentation/entity/TwoFAMechanisms$Companion;
|
||||
public static final field ONE_TIME_CODE Lme/proton/core/auth/presentation/entity/TwoFAMechanisms;
|
||||
@@ -1430,36 +1476,6 @@ public final class me/proton/core/auth/presentation/entity/TwoFAMechanisms$Compa
|
||||
public final fun getMap ()Ljava/util/Map;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/TwoFaFido : android/os/Parcelable {
|
||||
public static final field CREATOR Landroid/os/Parcelable$Creator;
|
||||
public fun <init> (Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsParcelable;[B[B[B[B)V
|
||||
public final fun component1 ()Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsParcelable;
|
||||
public final fun component2 ()[B
|
||||
public final fun component3 ()[B
|
||||
public final fun component4 ()[B
|
||||
public final fun component5 ()[B
|
||||
public final fun copy (Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsParcelable;[B[B[B[B)Lme/proton/core/auth/presentation/entity/TwoFaFido;
|
||||
public static synthetic fun copy$default (Lme/proton/core/auth/presentation/entity/TwoFaFido;Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsParcelable;[B[B[B[BILjava/lang/Object;)Lme/proton/core/auth/presentation/entity/TwoFaFido;
|
||||
public fun describeContents ()I
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getAuthenticatorData ()[B
|
||||
public final fun getClientData ()[B
|
||||
public final fun getCredentialID ()[B
|
||||
public final fun getPublicKeyOptions ()Lme/proton/core/auth/presentation/entity/Fido2PublicKeyCredentialRequestOptionsParcelable;
|
||||
public final fun getSignature ()[B
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
public fun writeToParcel (Landroid/os/Parcel;I)V
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/TwoFaFido$Creator : android/os/Parcelable$Creator {
|
||||
public fun <init> ()V
|
||||
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
|
||||
public final fun createFromParcel (Landroid/os/Parcel;)Lme/proton/core/auth/presentation/entity/TwoFaFido;
|
||||
public synthetic fun newArray (I)[Ljava/lang/Object;
|
||||
public final fun newArray (I)[Lme/proton/core/auth/presentation/entity/TwoFaFido;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/entity/TwoPassModeInput : android/os/Parcelable {
|
||||
public static final field CREATOR Landroid/os/Parcelable$Creator;
|
||||
public fun <init> (Ljava/lang/String;Lme/proton/core/account/domain/entity/AccountType;)V
|
||||
@@ -2627,8 +2643,8 @@ public final class me/proton/core/auth/presentation/viewmodel/ConfirmPasswordDia
|
||||
public fun onResultEnqueueObservability (Lme/proton/core/util/kotlin/coroutine/ResultCollector;Ljava/lang/String;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public final fun onSignResult (Lme/proton/core/auth/fido/domain/usecase/PerformTwoFaWithSecurityKey$Result;)V
|
||||
public final fun setFido2Info (Lme/proton/core/auth/domain/entity/Fido2Info;)V
|
||||
public final fun unlock (Lme/proton/core/domain/entity/UserId;Lme/proton/core/network/domain/scopes/Scope;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;)Lkotlinx/coroutines/Job;
|
||||
public static synthetic fun unlock$default (Lme/proton/core/auth/presentation/viewmodel/ConfirmPasswordDialogViewModel;Lme/proton/core/domain/entity/UserId;Lme/proton/core/network/domain/scopes/Scope;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||
public final fun unlock (Lme/proton/core/domain/entity/UserId;Lme/proton/core/network/domain/scopes/Scope;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;)Lkotlinx/coroutines/Job;
|
||||
public static synthetic fun unlock$default (Lme/proton/core/auth/presentation/viewmodel/ConfirmPasswordDialogViewModel;Lme/proton/core/domain/entity/UserId;Lme/proton/core/network/domain/scopes/Scope;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||
}
|
||||
|
||||
public abstract class me/proton/core/auth/presentation/viewmodel/ConfirmPasswordDialogViewModel$State {
|
||||
@@ -2894,7 +2910,7 @@ public final class me/proton/core/auth/presentation/viewmodel/SecondFactorViewMo
|
||||
public fun onResultEnqueueObservability (Lme/proton/core/util/kotlin/coroutine/ResultCollector;Ljava/lang/String;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public final fun setup (Lme/proton/core/domain/entity/UserId;)Lkotlinx/coroutines/Job;
|
||||
public final fun startSecondFactorFlow (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/account/domain/entity/AccountType;ZLjava/lang/String;)Lkotlinx/coroutines/Job;
|
||||
public final fun startSecondFactorFlow (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/account/domain/entity/AccountType;ZLme/proton/core/auth/domain/entity/SecondFactorProof;)Lkotlinx/coroutines/Job;
|
||||
public final fun startSecondFactorFlow (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/account/domain/entity/AccountType;ZLme/proton/core/auth/fido/domain/entity/SecondFactorProof;)Lkotlinx/coroutines/Job;
|
||||
public final fun stopSecondFactorFlow (Lme/proton/core/domain/entity/UserId;)Lkotlinx/coroutines/Job;
|
||||
}
|
||||
|
||||
@@ -2982,14 +2998,24 @@ public final class me/proton/core/auth/presentation/viewmodel/SecondFactorViewMo
|
||||
public static fun provide ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/viewmodel/Source : java/lang/Enum {
|
||||
public static final field changePassword Lme/proton/core/auth/presentation/viewmodel/Source;
|
||||
public static final field changeRecoveryEmail Lme/proton/core/auth/presentation/viewmodel/Source;
|
||||
public final class me/proton/core/auth/presentation/viewmodel/Source : java/lang/Enum, android/os/Parcelable {
|
||||
public static final field CREATOR Landroid/os/Parcelable$Creator;
|
||||
public static final field ChangePassword Lme/proton/core/auth/presentation/viewmodel/Source;
|
||||
public static final field ChangeRecoveryEmail Lme/proton/core/auth/presentation/viewmodel/Source;
|
||||
public fun describeContents ()I
|
||||
public static fun getEntries ()Lkotlin/enums/EnumEntries;
|
||||
public final fun getValue ()Ljava/lang/String;
|
||||
public final fun toScreenId ()Lme/proton/core/observability/domain/metrics/ChangePasswordOrRecoveryEmailFidoLaunchResultTotal$ScreenId;
|
||||
public final fun toScreenId ()Lme/proton/core/observability/domain/metrics/common/TwoFaDialogScreenId;
|
||||
public static fun valueOf (Ljava/lang/String;)Lme/proton/core/auth/presentation/viewmodel/Source;
|
||||
public static fun values ()[Lme/proton/core/auth/presentation/viewmodel/Source;
|
||||
public fun writeToParcel (Landroid/os/Parcel;I)V
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/viewmodel/Source$Creator : android/os/Parcelable$Creator {
|
||||
public fun <init> ()V
|
||||
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
|
||||
public final fun createFromParcel (Landroid/os/Parcel;)Lme/proton/core/auth/presentation/viewmodel/Source;
|
||||
public synthetic fun newArray (I)[Ljava/lang/Object;
|
||||
public final fun newArray (I)[Lme/proton/core/auth/presentation/viewmodel/Source;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/viewmodel/TwoFAInputDialogViewModel : me/proton/core/presentation/viewmodel/ProtonViewModel, me/proton/core/observability/domain/ObservabilityContext {
|
||||
@@ -3015,6 +3041,16 @@ public abstract class me/proton/core/auth/presentation/viewmodel/TwoFAInputDialo
|
||||
|
||||
public final class me/proton/core/auth/presentation/viewmodel/TwoFAInputDialogViewModel$State$Error$InvalidAccount : me/proton/core/auth/presentation/viewmodel/TwoFAInputDialogViewModel$State$Error {
|
||||
public static final field INSTANCE Lme/proton/core/auth/presentation/viewmodel/TwoFAInputDialogViewModel$State$Error$InvalidAccount;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/viewmodel/TwoFAInputDialogViewModel$State$Error$SetupError : me/proton/core/auth/presentation/viewmodel/TwoFAInputDialogViewModel$State$Error {
|
||||
public static final field INSTANCE Lme/proton/core/auth/presentation/viewmodel/TwoFAInputDialogViewModel$State$Error$SetupError;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/viewmodel/TwoFAInputDialogViewModel$State$Idle : me/proton/core/auth/presentation/viewmodel/TwoFAInputDialogViewModel$State {
|
||||
@@ -3028,6 +3064,13 @@ public final class me/proton/core/auth/presentation/viewmodel/TwoFAInputDialogVi
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/viewmodel/TwoFAInputDialogViewModel$State$Loading : me/proton/core/auth/presentation/viewmodel/TwoFAInputDialogViewModel$State {
|
||||
public static final field INSTANCE Lme/proton/core/auth/presentation/viewmodel/TwoFAInputDialogViewModel$State$Loading;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class me/proton/core/auth/presentation/viewmodel/TwoFAInputDialogViewModel_Factory : dagger/internal/Factory {
|
||||
public fun <init> (Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;)V
|
||||
public static fun create (Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;Ljavax/inject/Provider;)Lme/proton/core/auth/presentation/viewmodel/TwoFAInputDialogViewModel_Factory;
|
||||
|
||||
@@ -31,7 +31,7 @@ protonBuild {
|
||||
}
|
||||
|
||||
protonCoverage {
|
||||
branchCoveragePercentage.set(43)
|
||||
branchCoveragePercentage.set(42)
|
||||
lineCoveragePercentage.set(60)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ fun FragmentManager.showTwoFAEnterDialog(
|
||||
userId: UserId
|
||||
) {
|
||||
findFragmentByTag(TAG_TWO_FA_ENTER_DIALOG) ?: run {
|
||||
val fragment = TwoFAInputDialog(source.value, userId.id)
|
||||
val fragment = TwoFAInputDialog(source, userId.id)
|
||||
if (largeLayout) {
|
||||
// For large screens (tablets), we show the fragment as a dialog
|
||||
fragment.show(this, TAG_TWO_FA_ENTER_DIALOG)
|
||||
|
||||
+81
-56
@@ -40,14 +40,13 @@ import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import me.proton.core.auth.fido.domain.entity.Fido2PublicKeyCredentialRequestOptions
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.auth.fido.domain.usecase.PerformTwoFaWithSecurityKey
|
||||
import me.proton.core.auth.presentation.LogTag
|
||||
import me.proton.core.auth.presentation.databinding.Dialog2faInputBinding
|
||||
import me.proton.core.auth.presentation.entity.TwoFAInput
|
||||
import me.proton.core.auth.presentation.entity.SecondFactorProofEntity
|
||||
import me.proton.core.auth.presentation.entity.TwoFAMechanisms
|
||||
import me.proton.core.auth.presentation.entity.TwoFaFido
|
||||
import me.proton.core.auth.presentation.entity.toParcelable
|
||||
import me.proton.core.auth.presentation.entity.toEntity
|
||||
import me.proton.core.auth.presentation.util.setTextWithAnnotatedLink
|
||||
import me.proton.core.auth.presentation.viewmodel.Source
|
||||
import me.proton.core.auth.presentation.viewmodel.TwoFAInputDialogViewModel
|
||||
@@ -55,6 +54,7 @@ import me.proton.core.domain.entity.UserId
|
||||
import me.proton.core.presentation.R
|
||||
import me.proton.core.presentation.utils.ProtectScreenConfiguration
|
||||
import me.proton.core.presentation.utils.ScreenContentProtector
|
||||
import me.proton.core.presentation.utils.SnackbarLength
|
||||
import me.proton.core.presentation.utils.errorSnack
|
||||
import me.proton.core.presentation.utils.errorToast
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
@@ -78,7 +78,7 @@ class TwoFAInputDialog : DialogFragment(), TabLayout.OnTabSelectedListener {
|
||||
const val KEY_2FA_SET = "key.2fa_set"
|
||||
const val BUNDLE_KEY_2FA_DATA = "bundle.2fa_data"
|
||||
|
||||
operator fun invoke(source: String, userId: String) = TwoFAInputDialog().apply {
|
||||
operator fun invoke(source: Source, userId: String) = TwoFAInputDialog().apply {
|
||||
arguments = bundleOf(
|
||||
ARG_SOURCE to source,
|
||||
ARG_USER_ID to userId
|
||||
@@ -93,11 +93,14 @@ class TwoFAInputDialog : DialogFragment(), TabLayout.OnTabSelectedListener {
|
||||
}
|
||||
|
||||
private val source by lazy {
|
||||
Source.valueOf(requireNotNull(requireArguments().getString(ARG_SOURCE)))
|
||||
requireArguments().let {
|
||||
it.classLoader = Source::class.java.classLoader
|
||||
requireNotNull(it.getParcelable<Source>(ARG_SOURCE))
|
||||
}
|
||||
}
|
||||
|
||||
private val binding by lazy {
|
||||
Dialog2faInputBinding.inflate(LayoutInflater.from(requireContext()))
|
||||
Dialog2faInputBinding.inflate(layoutInflater)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -111,36 +114,57 @@ class TwoFAInputDialog : DialogFragment(), TabLayout.OnTabSelectedListener {
|
||||
|
||||
binding.tabLayout.addOnTabSelectedListener(this@TwoFAInputDialog)
|
||||
|
||||
val builder = MaterialAlertDialogBuilder(requireContext())
|
||||
val alertDialog = MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.presentation_authenticate)
|
||||
// passing null to the listeners is a workaround to prevent the dialog to auto-dismiss on button click
|
||||
.setPositiveButton(R.string.presentation_alert_enter, null)
|
||||
.setNegativeButton(R.string.presentation_alert_cancel, null)
|
||||
.setView(binding.root)
|
||||
val alertDialog = builder.create()
|
||||
.create()
|
||||
|
||||
viewModel.state
|
||||
.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
|
||||
.distinctUntilChanged()
|
||||
.onEach {
|
||||
when (it) {
|
||||
is TwoFAInputDialogViewModel.State.Idle -> with(binding) {
|
||||
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = true
|
||||
progressLayout.isVisible = false
|
||||
tabLayout.isVisible = it.showSecurityKey
|
||||
if (it.showSecurityKey) {
|
||||
selectSecurityKeyTab()
|
||||
} else {
|
||||
selectOneTimeCodeTab()
|
||||
}
|
||||
}
|
||||
|
||||
is TwoFAInputDialogViewModel.State.Loading -> {
|
||||
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = false
|
||||
binding.oneTimeCodeGroup.isVisible = false
|
||||
binding.securityKeyGroup.isVisible = false
|
||||
binding.tabLayout.isVisible = false
|
||||
binding.progressLayout.isVisible = true
|
||||
}
|
||||
|
||||
is TwoFAInputDialogViewModel.State.Error.InvalidAccount -> {
|
||||
requireContext().errorToast(getString(R.string.presentation_error_general))
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
|
||||
is TwoFAInputDialogViewModel.State.Error.SetupError -> binding.root.errorSnack(
|
||||
R.string.presentation_error_general,
|
||||
length = SnackbarLength.INDEFINITE
|
||||
) {
|
||||
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = false
|
||||
binding.progressLayout.isVisible = false
|
||||
setAction(R.string.presentation_retry) {
|
||||
viewModel.setup(userId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.launchIn(lifecycleScope)
|
||||
|
||||
return alertDialog.apply {
|
||||
viewModel.state
|
||||
.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
|
||||
.distinctUntilChanged()
|
||||
.onEach {
|
||||
when (it) {
|
||||
is TwoFAInputDialogViewModel.State.Idle -> with(binding){
|
||||
progressLayout.isVisible = false
|
||||
it.showSecurityKey
|
||||
tabLayout.isVisible = it.showSecurityKey
|
||||
if (it.showSecurityKey) {
|
||||
selectSecurityKeyTab()
|
||||
} else {
|
||||
selectOneTimeCodeTab()
|
||||
}
|
||||
}
|
||||
|
||||
is TwoFAInputDialogViewModel.State.Error.InvalidAccount ->
|
||||
requireContext().errorToast(getString(R.string.presentation_error_general))
|
||||
}
|
||||
}.launchIn(lifecycleScope)
|
||||
|
||||
setOnShowListener {
|
||||
viewModel.setup(userId)
|
||||
|
||||
@@ -148,19 +172,9 @@ class TwoFAInputDialog : DialogFragment(), TabLayout.OnTabSelectedListener {
|
||||
getButton(AlertDialog.BUTTON_POSITIVE).apply {
|
||||
isAllCaps = false
|
||||
onClick {
|
||||
with(binding) {
|
||||
when (selectedTwoFAOption()) {
|
||||
TwoFAMechanisms.SECURITY_KEY -> onSecurityKeySubmitted()
|
||||
|
||||
TwoFAMechanisms.ONE_TIME_CODE -> {
|
||||
parentFragmentManager.setFragmentResult(
|
||||
KEY_2FA_SET, bundleOf(
|
||||
BUNDLE_KEY_2FA_DATA to TwoFAInput(twoFA.text.toString())
|
||||
)
|
||||
)
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
when (selectedTwoFAOption()) {
|
||||
TwoFAMechanisms.SECURITY_KEY -> onSecurityKeySubmitted()
|
||||
TwoFAMechanisms.ONE_TIME_CODE -> onOneTimeCodeSubmitted()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,9 +203,9 @@ class TwoFAInputDialog : DialogFragment(), TabLayout.OnTabSelectedListener {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTabUnselected(p0: TabLayout.Tab?) { }
|
||||
override fun onTabUnselected(p0: TabLayout.Tab?) = Unit
|
||||
|
||||
override fun onTabReselected(p0: TabLayout.Tab?) { }
|
||||
override fun onTabReselected(p0: TabLayout.Tab?) = Unit
|
||||
|
||||
private fun onTwoFaWithSecurityKeyResult(
|
||||
result: PerformTwoFaWithSecurityKey.Result,
|
||||
@@ -200,7 +214,7 @@ class TwoFAInputDialog : DialogFragment(), TabLayout.OnTabSelectedListener {
|
||||
viewModel.onSignResult(source, result)
|
||||
when (result) {
|
||||
is PerformTwoFaWithSecurityKey.Result.Success -> {
|
||||
val secondFactorFido = SecondFactorFido(
|
||||
val secondFactorFido = SecondFactorProof.Fido2(
|
||||
publicKeyOptions = options,
|
||||
clientData = result.response.clientDataJSON,
|
||||
authenticatorData = result.response.authenticatorData,
|
||||
@@ -210,16 +224,17 @@ class TwoFAInputDialog : DialogFragment(), TabLayout.OnTabSelectedListener {
|
||||
|
||||
parentFragmentManager.setFragmentResult(
|
||||
KEY_2FA_SET, bundleOf(
|
||||
BUNDLE_KEY_2FA_DATA to TwoFAInput(twoFAFido = TwoFaFido(
|
||||
secondFactorFido.publicKeyOptions.toParcelable(),
|
||||
BUNDLE_KEY_2FA_DATA to SecondFactorProofEntity.Fido2Entity(
|
||||
secondFactorFido.publicKeyOptions.toEntity(),
|
||||
secondFactorFido.clientData,
|
||||
secondFactorFido.authenticatorData,
|
||||
secondFactorFido.signature,
|
||||
secondFactorFido.credentialID
|
||||
))
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
is PerformTwoFaWithSecurityKey.Result.Cancelled -> Unit
|
||||
is PerformTwoFaWithSecurityKey.Result.EmptyResult -> binding.root.errorSnack(
|
||||
getString(me.proton.core.auth.presentation.R.string.auth_login_general_error)
|
||||
@@ -236,16 +251,19 @@ class TwoFAInputDialog : DialogFragment(), TabLayout.OnTabSelectedListener {
|
||||
}
|
||||
}
|
||||
|
||||
private fun selectSecurityKeyTab() = with (binding) {
|
||||
private fun selectSecurityKeyTab() = with(binding) {
|
||||
oneTimeCodeGroup.isVisible = false
|
||||
securityKeyGroup.isVisible = true
|
||||
|
||||
securityKeyText.setTextWithAnnotatedLink(me.proton.core.auth.presentation.R.string.auth_2fa_insert_security_key, "more") {
|
||||
securityKeyText.setTextWithAnnotatedLink(
|
||||
me.proton.core.auth.presentation.R.string.auth_2fa_insert_security_key,
|
||||
"more"
|
||||
) {
|
||||
context?.openBrowserLink(getString(me.proton.core.auth.presentation.R.string.confirm_password_2fa_security_key))
|
||||
}
|
||||
}
|
||||
|
||||
private fun selectOneTimeCodeTab() = with (binding) {
|
||||
private fun selectOneTimeCodeTab() = with(binding) {
|
||||
oneTimeCodeGroup.isVisible = true
|
||||
securityKeyGroup.isVisible = false
|
||||
}
|
||||
@@ -253,8 +271,16 @@ class TwoFAInputDialog : DialogFragment(), TabLayout.OnTabSelectedListener {
|
||||
private fun selectedTwoFAOption(): TwoFAMechanisms =
|
||||
if (binding.tabLayout.isVisible) {
|
||||
TwoFAMechanisms.enumOf(binding.tabLayout.selectedTabPosition)
|
||||
}
|
||||
else TwoFAMechanisms.ONE_TIME_CODE
|
||||
} else TwoFAMechanisms.ONE_TIME_CODE
|
||||
|
||||
private fun onOneTimeCodeSubmitted() {
|
||||
parentFragmentManager.setFragmentResult(
|
||||
KEY_2FA_SET, bundleOf(
|
||||
BUNDLE_KEY_2FA_DATA to SecondFactorProofEntity.SecondFactorCodeEntity(binding.twoFA.text.toString())
|
||||
)
|
||||
)
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
|
||||
private fun onSecurityKeySubmitted() {
|
||||
val performTwoFaWithSecurityKey = performTwoFaWithSecurityKey.getOrNull() ?: return
|
||||
@@ -271,8 +297,7 @@ class TwoFAInputDialog : DialogFragment(), TabLayout.OnTabSelectedListener {
|
||||
)
|
||||
}
|
||||
|
||||
is PerformTwoFaWithSecurityKey.LaunchResult.Success,
|
||||
null -> Unit
|
||||
is PerformTwoFaWithSecurityKey.LaunchResult.Success -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -37,7 +37,7 @@ import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import me.proton.core.auth.domain.entity.SecondFactorMethod
|
||||
import me.proton.core.auth.fido.domain.entity.Fido2PublicKeyCredentialRequestOptions
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.auth.fido.domain.usecase.PerformTwoFaWithSecurityKey
|
||||
import me.proton.core.auth.presentation.LogTag
|
||||
import me.proton.core.auth.presentation.R
|
||||
@@ -155,8 +155,8 @@ class ConfirmPasswordDialog : DialogFragment() {
|
||||
|
||||
private fun onTotpSubmitted() {
|
||||
val password = viewController.password.orEmpty()
|
||||
val twoFactorCode = viewController.twoFactorCode
|
||||
viewModel.unlock(userId, missingScope, password, secondFactorCode = twoFactorCode)
|
||||
val twoFactorCode = viewController.twoFactorCode.orEmpty()
|
||||
viewModel.unlock(userId, missingScope, password, secondFactorProof = SecondFactorProof.SecondFactorCode(twoFactorCode))
|
||||
}
|
||||
|
||||
private fun onSecurityKeySubmitted() {
|
||||
@@ -256,7 +256,7 @@ class ConfirmPasswordDialog : DialogFragment() {
|
||||
userId = userId,
|
||||
missingScope = missingScope,
|
||||
password = password,
|
||||
secondFactorFido = SecondFactorFido(
|
||||
secondFactorProof = SecondFactorProof.Fido2(
|
||||
publicKeyOptions = options,
|
||||
clientData = result.response.clientDataJSON,
|
||||
authenticatorData = result.response.authenticatorData,
|
||||
|
||||
-101
@@ -20,110 +20,9 @@ package me.proton.core.auth.presentation.entity
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import me.proton.core.auth.fido.domain.entity.Fido2AuthenticationExtensionsClientInputs
|
||||
import me.proton.core.auth.fido.domain.entity.Fido2PublicKeyCredentialDescriptor
|
||||
import me.proton.core.auth.fido.domain.entity.Fido2PublicKeyCredentialRequestOptions
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
|
||||
@Parcelize
|
||||
data class PasswordInput(
|
||||
val password: String
|
||||
): Parcelable
|
||||
|
||||
@Parcelize
|
||||
data class TwoFAInput(
|
||||
val twoFA: String? = null,
|
||||
val twoFAFido: TwoFaFido? = null
|
||||
): Parcelable
|
||||
|
||||
@Parcelize
|
||||
data class TwoFaFido(
|
||||
val publicKeyOptions: Fido2PublicKeyCredentialRequestOptionsParcelable,
|
||||
val clientData: ByteArray,
|
||||
val authenticatorData: ByteArray,
|
||||
val signature: ByteArray,
|
||||
val credentialID: ByteArray
|
||||
): Parcelable
|
||||
|
||||
@Parcelize
|
||||
data class Fido2PublicKeyCredentialRequestOptionsParcelable(
|
||||
val challenge: UByteArray,
|
||||
val timeout: ULong? = null, // milliseconds
|
||||
val rpId: String? = null,
|
||||
val allowCredentials: List<Fido2PublicKeyCredentialDescriptorParcelable>? = null,
|
||||
val userVerification: String? = null,
|
||||
val extensions: Fido2AuthenticationExtensionsClientInputsParcelable? = null
|
||||
): Parcelable
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
fun Fido2PublicKeyCredentialRequestOptionsParcelable.fromParcelable() =
|
||||
Fido2PublicKeyCredentialRequestOptions(
|
||||
challenge = challenge,
|
||||
timeout = timeout,
|
||||
rpId = rpId,
|
||||
allowCredentials = allowCredentials?.map { it.fromParcelable() },
|
||||
userVerification = userVerification,
|
||||
extensions = extensions?.fromParcelable()
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
@Parcelize
|
||||
data class Fido2PublicKeyCredentialDescriptorParcelable(
|
||||
val type: String,
|
||||
val id: UByteArray,
|
||||
val transports: List<String>?
|
||||
): Parcelable
|
||||
|
||||
@Parcelize
|
||||
data class Fido2AuthenticationExtensionsClientInputsParcelable(
|
||||
val appId: String?,
|
||||
val thirdPartyPayment: Boolean?,
|
||||
val uvm: Boolean?,
|
||||
): Parcelable
|
||||
|
||||
fun TwoFaFido.fromParcelable() =
|
||||
SecondFactorFido(
|
||||
publicKeyOptions = publicKeyOptions.fromParcelable(),
|
||||
clientData = clientData,
|
||||
authenticatorData = authenticatorData,
|
||||
signature = signature,
|
||||
credentialID = credentialID
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
fun Fido2PublicKeyCredentialDescriptorParcelable.fromParcelable() =
|
||||
Fido2PublicKeyCredentialDescriptor(
|
||||
type = type,
|
||||
id = id,
|
||||
transports = transports
|
||||
)
|
||||
|
||||
fun Fido2AuthenticationExtensionsClientInputsParcelable.fromParcelable() =
|
||||
Fido2AuthenticationExtensionsClientInputs(
|
||||
appId = appId,
|
||||
thirdPartyPayment = thirdPartyPayment,
|
||||
uvm = uvm
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
fun Fido2PublicKeyCredentialRequestOptions.toParcelable() = Fido2PublicKeyCredentialRequestOptionsParcelable(
|
||||
challenge = challenge,
|
||||
timeout = timeout,
|
||||
rpId = rpId,
|
||||
allowCredentials = allowCredentials?.map { it.toParcelable() },
|
||||
userVerification = userVerification,
|
||||
extensions = extensions?.toParcelable()
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
fun Fido2PublicKeyCredentialDescriptor.toParcelable() = Fido2PublicKeyCredentialDescriptorParcelable(
|
||||
type = type,
|
||||
id = id,
|
||||
transports = transports
|
||||
)
|
||||
|
||||
fun Fido2AuthenticationExtensionsClientInputs.toParcelable() = Fido2AuthenticationExtensionsClientInputsParcelable(
|
||||
appId = appId,
|
||||
thirdPartyPayment = thirdPartyPayment,
|
||||
uvm = uvm
|
||||
)
|
||||
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Proton Technologies AG
|
||||
* This file is part of Proton Technologies AG and ProtonCore.
|
||||
*
|
||||
* ProtonCore is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ProtonCore is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.auth.presentation.entity
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import me.proton.core.auth.fido.domain.entity.Fido2AuthenticationExtensionsClientInputs
|
||||
import me.proton.core.auth.fido.domain.entity.Fido2PublicKeyCredentialDescriptor
|
||||
import me.proton.core.auth.fido.domain.entity.Fido2PublicKeyCredentialRequestOptions
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
|
||||
sealed class SecondFactorProofEntity : Parcelable {
|
||||
|
||||
@Parcelize
|
||||
data class SecondFactorCodeEntity(
|
||||
val code: String
|
||||
) : SecondFactorProofEntity()
|
||||
|
||||
@Parcelize
|
||||
data class SecondFactorSignatureEntity(
|
||||
val keyHandle: String,
|
||||
val clientData: String,
|
||||
val signatureData: String
|
||||
) : SecondFactorProofEntity()
|
||||
|
||||
@Parcelize
|
||||
class Fido2Entity(
|
||||
val publicKeyOptions: Fido2PublicKeyCredentialRequestOptionsEntity,
|
||||
val clientData: ByteArray,
|
||||
val authenticatorData: ByteArray,
|
||||
val signature: ByteArray,
|
||||
val credentialID: ByteArray
|
||||
) : SecondFactorProofEntity()
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
data class Fido2PublicKeyCredentialRequestOptionsEntity(
|
||||
val challenge: UByteArray,
|
||||
val timeout: ULong? = null, // milliseconds
|
||||
val rpId: String? = null,
|
||||
val allowCredentials: List<Fido2PublicKeyCredentialDescriptorEntity>? = null,
|
||||
val userVerification: String? = null,
|
||||
val extensions: Fido2AuthenticationExtensionsClientInputsEntity? = null
|
||||
): Parcelable
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
@Parcelize
|
||||
data class Fido2PublicKeyCredentialDescriptorEntity(
|
||||
val type: String,
|
||||
val id: UByteArray,
|
||||
val transports: List<String>?
|
||||
): Parcelable
|
||||
|
||||
@Parcelize
|
||||
data class Fido2AuthenticationExtensionsClientInputsEntity(
|
||||
val appId: String?,
|
||||
val thirdPartyPayment: Boolean?,
|
||||
val uvm: Boolean?,
|
||||
): Parcelable
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
fun Fido2PublicKeyCredentialRequestOptionsEntity.fromEntity() =
|
||||
Fido2PublicKeyCredentialRequestOptions(
|
||||
challenge = challenge,
|
||||
timeout = timeout,
|
||||
rpId = rpId,
|
||||
allowCredentials = allowCredentials?.map { it.fromEntity() },
|
||||
userVerification = userVerification,
|
||||
extensions = extensions?.fromEntity()
|
||||
)
|
||||
|
||||
fun SecondFactorProofEntity.fromEntity() =
|
||||
when (this) {
|
||||
is SecondFactorProofEntity.SecondFactorCodeEntity -> SecondFactorProof.SecondFactorCode(code)
|
||||
is SecondFactorProofEntity.SecondFactorSignatureEntity -> SecondFactorProof.SecondFactorSignature(keyHandle, clientData, signatureData)
|
||||
is SecondFactorProofEntity.Fido2Entity -> fromEntity()
|
||||
}
|
||||
|
||||
fun SecondFactorProofEntity.Fido2Entity.fromEntity() =
|
||||
SecondFactorProof.Fido2(
|
||||
publicKeyOptions = publicKeyOptions.fromEntity(),
|
||||
clientData = clientData,
|
||||
authenticatorData = authenticatorData,
|
||||
signature = signature,
|
||||
credentialID = credentialID
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
fun Fido2PublicKeyCredentialDescriptorEntity.fromEntity() =
|
||||
Fido2PublicKeyCredentialDescriptor(
|
||||
type = type,
|
||||
id = id,
|
||||
transports = transports
|
||||
)
|
||||
|
||||
fun Fido2AuthenticationExtensionsClientInputsEntity.fromEntity() =
|
||||
Fido2AuthenticationExtensionsClientInputs(
|
||||
appId = appId,
|
||||
thirdPartyPayment = thirdPartyPayment,
|
||||
uvm = uvm
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
fun Fido2PublicKeyCredentialRequestOptions.toEntity() = Fido2PublicKeyCredentialRequestOptionsEntity(
|
||||
challenge = challenge,
|
||||
timeout = timeout,
|
||||
rpId = rpId,
|
||||
allowCredentials = allowCredentials?.map { it.toEntity() },
|
||||
userVerification = userVerification,
|
||||
extensions = extensions?.toEntity()
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
fun Fido2PublicKeyCredentialDescriptor.toEntity() = Fido2PublicKeyCredentialDescriptorEntity(
|
||||
type = type,
|
||||
id = id,
|
||||
transports = transports
|
||||
)
|
||||
|
||||
fun Fido2AuthenticationExtensionsClientInputs.toEntity() = Fido2AuthenticationExtensionsClientInputsEntity(
|
||||
appId = appId,
|
||||
thirdPartyPayment = thirdPartyPayment,
|
||||
uvm = uvm
|
||||
)
|
||||
+1
-1
@@ -34,10 +34,10 @@ import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import me.proton.core.auth.domain.entity.SecondFactorProof
|
||||
import me.proton.core.auth.domain.usecase.PostLoginAccountSetup
|
||||
import me.proton.core.auth.fido.domain.entity.Fido2AuthenticationOptions
|
||||
import me.proton.core.auth.fido.domain.entity.Fido2PublicKeyCredentialRequestOptions
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.auth.fido.domain.usecase.PerformTwoFaWithSecurityKey
|
||||
import me.proton.core.auth.presentation.LogTag
|
||||
import me.proton.core.auth.presentation.R
|
||||
|
||||
+7
-14
@@ -39,9 +39,9 @@ import me.proton.core.auth.domain.feature.IsFido2Enabled
|
||||
import me.proton.core.auth.domain.usecase.GetAuthInfoSrp
|
||||
import me.proton.core.auth.domain.usecase.scopes.ObtainLockedScope
|
||||
import me.proton.core.auth.domain.usecase.scopes.ObtainPasswordScope
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.auth.fido.domain.usecase.PerformTwoFaWithSecurityKey
|
||||
import me.proton.core.auth.fido.domain.usecase.toStatus
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.crypto.common.keystore.KeyStoreCrypto
|
||||
import me.proton.core.crypto.common.keystore.encrypt
|
||||
import me.proton.core.domain.entity.UserId
|
||||
@@ -120,15 +120,10 @@ class ConfirmPasswordDialogViewModel @Inject constructor(
|
||||
userId: UserId,
|
||||
missingScope: Scope,
|
||||
password: String,
|
||||
secondFactorCode: String? = null,
|
||||
secondFactorFido: SecondFactorFido? = null
|
||||
secondFactorProof: SecondFactorProof? = null
|
||||
) = flowWithResultContext {
|
||||
check(secondFactorCode == null || secondFactorFido == null) {
|
||||
"Cannot unlock ${missingScope.value} scope using both 2FA code and security key."
|
||||
}
|
||||
|
||||
it.onResultEnqueueObservability("unlockUserForPasswordScope") {
|
||||
toConfirmPasswordSubmissionTotal(secondFactorCode, secondFactorFido)
|
||||
toConfirmPasswordSubmissionTotal(secondFactorProof)
|
||||
}
|
||||
|
||||
send(State.ProcessingObtainScope)
|
||||
@@ -145,8 +140,7 @@ class ConfirmPasswordDialogViewModel @Inject constructor(
|
||||
sessionId = requireNotNull(account.sessionId),
|
||||
username = requireNotNull(account.username),
|
||||
password = password.encrypt(keyStoreCrypto),
|
||||
secondFactorCode = secondFactorCode?.takeIfNotEmpty(),
|
||||
secondFactorFido = secondFactorFido
|
||||
secondFactorProof = secondFactorProof
|
||||
)
|
||||
|
||||
Scope.LOCKED -> obtainLockedScope(
|
||||
@@ -185,12 +179,11 @@ class ConfirmPasswordDialogViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
private fun Result<*>.toConfirmPasswordSubmissionTotal(
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?
|
||||
secondFactorProof: SecondFactorProof?
|
||||
): ConfirmPasswordSubmissionTotal {
|
||||
val secondFactorProofType = when {
|
||||
secondFactorCode != null -> SecondFactorProofType.totp
|
||||
secondFactorFido != null -> SecondFactorProofType.securityKey
|
||||
secondFactorProof is SecondFactorProof.SecondFactorCode -> SecondFactorProofType.totp
|
||||
secondFactorProof is SecondFactorProof.Fido2 -> SecondFactorProofType.securityKey
|
||||
else -> SecondFactorProofType.none
|
||||
}
|
||||
return if (exceptionOrNull() is InvalidServerAuthenticationException) {
|
||||
|
||||
+1
-1
@@ -32,13 +32,13 @@ import kotlinx.coroutines.launch
|
||||
import me.proton.core.account.domain.entity.AccountType
|
||||
import me.proton.core.accountmanager.domain.AccountManager
|
||||
import me.proton.core.accountmanager.domain.AccountWorkflowHandler
|
||||
import me.proton.core.auth.domain.entity.SecondFactorProof
|
||||
import me.proton.core.auth.domain.entity.fido2AuthenticationOptions
|
||||
import me.proton.core.auth.domain.feature.IsFido2Enabled
|
||||
import me.proton.core.auth.domain.usecase.PerformSecondFactor
|
||||
import me.proton.core.auth.domain.usecase.PostLoginAccountSetup
|
||||
import me.proton.core.auth.domain.usecase.primaryKeyExists
|
||||
import me.proton.core.auth.fido.domain.entity.Fido2AuthenticationOptions
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.auth.fido.domain.usecase.PerformTwoFaWithSecurityKey
|
||||
import me.proton.core.auth.fido.domain.usecase.toStatus
|
||||
import me.proton.core.auth.presentation.LogTag
|
||||
|
||||
+13
-7
@@ -18,6 +18,7 @@
|
||||
|
||||
package me.proton.core.auth.presentation.viewmodel
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
@@ -27,6 +28,7 @@ import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import me.proton.core.accountmanager.domain.AccountManager
|
||||
import me.proton.core.auth.domain.entity.Fido2Info
|
||||
import me.proton.core.auth.domain.entity.SecondFactor
|
||||
@@ -61,13 +63,16 @@ class TwoFAInputDialogViewModel @Inject constructor(
|
||||
|
||||
sealed class State {
|
||||
data class Idle(val showSecurityKey: Boolean) : State()
|
||||
data object Loading: State()
|
||||
|
||||
sealed class Error : State() {
|
||||
object InvalidAccount : Error()
|
||||
data object InvalidAccount : Error()
|
||||
data object SetupError : Error()
|
||||
}
|
||||
}
|
||||
|
||||
fun setup(userId: UserId) = flow {
|
||||
emit(State.Loading)
|
||||
when {
|
||||
!isFido2Enabled(userId) -> emit(State.Idle(false))
|
||||
else -> {
|
||||
@@ -86,7 +91,7 @@ class TwoFAInputDialogViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
}.catch { _ ->
|
||||
emit(State.Idle(false))
|
||||
emit(State.Error.SetupError)
|
||||
}.onEach { state ->
|
||||
_state.tryEmit(state)
|
||||
}.launchIn(viewModelScope)
|
||||
@@ -100,13 +105,14 @@ class TwoFAInputDialogViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
enum class Source(val value: String) {
|
||||
changePassword("changePassword"),
|
||||
changeRecoveryEmail("changeRecoveryEmail");
|
||||
@Parcelize
|
||||
enum class Source: Parcelable {
|
||||
ChangePassword,
|
||||
ChangeRecoveryEmail;
|
||||
|
||||
fun toScreenId() = when (this) {
|
||||
changePassword -> TwoFaDialogScreenId.changePassword
|
||||
changeRecoveryEmail -> TwoFaDialogScreenId.changeRecoveryEmail
|
||||
ChangePassword -> TwoFaDialogScreenId.changePassword
|
||||
ChangeRecoveryEmail -> TwoFaDialogScreenId.changeRecoveryEmail
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -97,13 +97,9 @@
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/progressLayout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:windowBackground"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:elevation="3dp"
|
||||
tools:visibility="gone">
|
||||
|
||||
|
||||
+4
-7
@@ -36,6 +36,7 @@ import me.proton.core.auth.domain.feature.IsFido2Enabled
|
||||
import me.proton.core.auth.domain.usecase.GetAuthInfoSrp
|
||||
import me.proton.core.auth.domain.usecase.scopes.ObtainLockedScope
|
||||
import me.proton.core.auth.domain.usecase.scopes.ObtainPasswordScope
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.keystore.KeyStoreCrypto
|
||||
import me.proton.core.domain.entity.UserId
|
||||
import me.proton.core.network.domain.ApiException
|
||||
@@ -79,7 +80,7 @@ class ConfirmPasswordDialogViewModelTest :
|
||||
private val testUsername = "test-username"
|
||||
private val testPassword = "test-password"
|
||||
private val testPasswordEncrypted = "test-password-encrypted"
|
||||
private val test2FACode = "test-2fa"
|
||||
private val test2FACode = SecondFactorProof.SecondFactorCode("test-2fa")
|
||||
private val testUserId = UserId(testUserIdString)
|
||||
private val testSessionId = SessionId("test-sessionId")
|
||||
|
||||
@@ -200,7 +201,6 @@ class ConfirmPasswordDialogViewModelTest :
|
||||
testSessionId,
|
||||
testUsername,
|
||||
testPasswordEncrypted,
|
||||
null,
|
||||
null
|
||||
)
|
||||
} returns true
|
||||
@@ -226,7 +226,6 @@ class ConfirmPasswordDialogViewModelTest :
|
||||
testSessionId,
|
||||
testUsername,
|
||||
testPasswordEncrypted,
|
||||
null,
|
||||
null
|
||||
)
|
||||
} throws ApiException(
|
||||
@@ -260,8 +259,7 @@ class ConfirmPasswordDialogViewModelTest :
|
||||
testSessionId,
|
||||
testUsername,
|
||||
testPasswordEncrypted,
|
||||
test2FACode,
|
||||
null
|
||||
test2FACode
|
||||
)
|
||||
} returns true
|
||||
flowTest(viewModel.state) {
|
||||
@@ -286,8 +284,7 @@ class ConfirmPasswordDialogViewModelTest :
|
||||
testSessionId,
|
||||
testUsername,
|
||||
testPasswordEncrypted,
|
||||
test2FACode,
|
||||
null
|
||||
test2FACode
|
||||
)
|
||||
} throws ApiException(
|
||||
ApiResult.Error.Http(
|
||||
|
||||
+1
-1
@@ -29,10 +29,10 @@ import me.proton.core.account.domain.entity.AccountType
|
||||
import me.proton.core.accountmanager.domain.AccountManager
|
||||
import me.proton.core.accountmanager.domain.AccountWorkflowHandler
|
||||
import me.proton.core.auth.domain.entity.ScopeInfo
|
||||
import me.proton.core.auth.domain.entity.SecondFactorProof
|
||||
import me.proton.core.auth.domain.feature.IsFido2Enabled
|
||||
import me.proton.core.auth.domain.usecase.PerformSecondFactor
|
||||
import me.proton.core.auth.domain.usecase.PostLoginAccountSetup
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.auth.presentation.entity.SessionResult
|
||||
import me.proton.core.domain.entity.UserId
|
||||
import me.proton.core.network.domain.session.SessionId
|
||||
|
||||
@@ -1175,7 +1175,7 @@ public final class me/proton/core/key/data/repository/PrivateKeyRepositoryImpl :
|
||||
public fun createAddressKey (Lme/proton/core/domain/entity/UserId;Lme/proton/core/key/domain/entity/key/PrivateAddressKey;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun reactivatePrivateKey (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/key/domain/entity/key/PrivateKey;Ljava/util/List;Ljava/util/Map;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun setupInitialKeys (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lme/proton/core/crypto/common/srp/Auth;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updatePrivateKeys (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lme/proton/core/crypto/common/srp/Auth;Ljava/util/List;Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updatePrivateKeys (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lme/proton/core/crypto/common/srp/Auth;Ljava/util/List;Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class me/proton/core/key/data/repository/PublicAddressRepositoryImpl : me/proton/core/key/domain/repository/PublicAddressRepository {
|
||||
|
||||
+6
-6
@@ -18,10 +18,11 @@
|
||||
|
||||
package me.proton.core.key.data.repository
|
||||
|
||||
import me.proton.core.auth.data.api.request.toFido2Request
|
||||
import me.proton.core.auth.data.api.request.toSecondFactorCode
|
||||
import me.proton.core.auth.data.api.request.toSecondFactorFido
|
||||
import me.proton.core.auth.data.api.response.isSuccess
|
||||
import me.proton.core.auth.domain.usecase.ValidateServerProof
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.pgp.Armored
|
||||
import me.proton.core.crypto.common.srp.Auth
|
||||
import me.proton.core.crypto.common.srp.SrpProofs
|
||||
@@ -102,8 +103,7 @@ class PrivateKeyRepositoryImpl @Inject constructor(
|
||||
keySalt: String,
|
||||
srpProofs: SrpProofs,
|
||||
srpSession: String,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?,
|
||||
secondFactorProof: SecondFactorProof?,
|
||||
auth: Auth?,
|
||||
keys: List<Key>?,
|
||||
userKeys: List<Key>?
|
||||
@@ -115,8 +115,8 @@ class PrivateKeyRepositoryImpl @Inject constructor(
|
||||
clientEphemeral = srpProofs.clientEphemeral,
|
||||
clientProof = srpProofs.clientProof,
|
||||
srpSession = srpSession,
|
||||
twoFactorCode = secondFactorCode,
|
||||
fido2 = secondFactorFido?.toFido2Request(),
|
||||
twoFactorCode = secondFactorProof.toSecondFactorCode(),
|
||||
fido2 = secondFactorProof.toSecondFactorFido(),
|
||||
auth = if (auth != null) AuthRequest.from(auth) else null,
|
||||
keys = keys?.map {
|
||||
PrivateKeyRequest(privateKey = it.privateKey, id = it.keyId.id)
|
||||
|
||||
+2
-2
@@ -26,6 +26,7 @@ import kotlinx.coroutines.test.runTest
|
||||
import me.proton.core.auth.data.api.response.SRPAuthenticationResponse
|
||||
import me.proton.core.auth.domain.exception.InvalidServerAuthenticationException
|
||||
import me.proton.core.auth.domain.usecase.ValidateServerProof
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.keystore.EncryptedByteArray
|
||||
import me.proton.core.crypto.common.srp.Auth
|
||||
import me.proton.core.crypto.common.srp.SrpProofs
|
||||
@@ -106,8 +107,7 @@ class PrivateKeyRepositoryImplTest {
|
||||
keySalt = "test-key-salt",
|
||||
srpProofs = testSrpProofs,
|
||||
srpSession = "test-srp-session",
|
||||
secondFactorCode = "test-2fa-code",
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = SecondFactorProof.SecondFactorCode("test-2fa-code"),
|
||||
auth = mockk(relaxed = true),
|
||||
keys = listOf(mockk(relaxed = true)),
|
||||
userKeys = listOf(mockk(relaxed = true))
|
||||
|
||||
@@ -714,11 +714,11 @@ public abstract interface class me/proton/core/key/domain/repository/PrivateKeyR
|
||||
public abstract fun createAddressKey (Lme/proton/core/domain/entity/UserId;Lme/proton/core/key/domain/entity/key/PrivateAddressKey;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun reactivatePrivateKey (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/key/domain/entity/key/PrivateKey;Ljava/util/List;Ljava/util/Map;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun setupInitialKeys (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lme/proton/core/crypto/common/srp/Auth;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updatePrivateKeys (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lme/proton/core/crypto/common/srp/Auth;Ljava/util/List;Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updatePrivateKeys (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lme/proton/core/crypto/common/srp/Auth;Ljava/util/List;Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class me/proton/core/key/domain/repository/PrivateKeyRepository$DefaultImpls {
|
||||
public static synthetic fun updatePrivateKeys$default (Lme/proton/core/key/domain/repository/PrivateKeyRepository;Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lme/proton/core/crypto/common/srp/Auth;Ljava/util/List;Ljava/util/List;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
||||
public static synthetic fun updatePrivateKeys$default (Lme/proton/core/key/domain/repository/PrivateKeyRepository;Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lme/proton/core/crypto/common/srp/Auth;Ljava/util/List;Ljava/util/List;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public abstract interface class me/proton/core/key/domain/repository/PublicAddressRepository {
|
||||
|
||||
+2
-3
@@ -18,7 +18,7 @@
|
||||
|
||||
package me.proton.core.key.domain.repository
|
||||
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.pgp.Armored
|
||||
import me.proton.core.crypto.common.srp.Auth
|
||||
import me.proton.core.crypto.common.srp.SrpProofs
|
||||
@@ -56,8 +56,7 @@ interface PrivateKeyRepository {
|
||||
keySalt: String,
|
||||
srpProofs: SrpProofs,
|
||||
srpSession: String,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?,
|
||||
secondFactorProof: SecondFactorProof?,
|
||||
auth: Auth?,
|
||||
keys: List<Key>? = null,
|
||||
userKeys: List<Key>? = null
|
||||
|
||||
@@ -70,8 +70,8 @@ public final class me/proton/core/usersettings/data/api/UserSettingsRemoteDataSo
|
||||
public fun fetch (Lme/proton/core/domain/entity/UserId;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun setRecoverySecret (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun setUsername (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updateLoginPassword (Lme/proton/core/domain/entity/UserId;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lme/proton/core/crypto/common/srp/Auth;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updateRecoveryEmail (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updateLoginPassword (Lme/proton/core/domain/entity/UserId;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lme/proton/core/crypto/common/srp/Auth;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updateRecoveryEmail (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updateUserSettings (Lme/proton/core/domain/entity/UserId;Lme/proton/core/usersettings/domain/entity/UserSettingsProperty;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
@@ -973,8 +973,8 @@ public final class me/proton/core/usersettings/data/repository/UserSettingsRepos
|
||||
public fun markAsStale (Lme/proton/core/domain/entity/UserId;)V
|
||||
public fun setUsername (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updateCrashReports (Lme/proton/core/domain/entity/UserId;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updateLoginPassword (Lme/proton/core/domain/entity/UserId;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lme/proton/core/crypto/common/srp/Auth;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updateRecoveryEmail (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updateLoginPassword (Lme/proton/core/domain/entity/UserId;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lme/proton/core/crypto/common/srp/Auth;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updateRecoveryEmail (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updateTelemetry (Lme/proton/core/domain/entity/UserId;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updateUserSettings (Lme/proton/core/usersettings/domain/entity/UserSettings;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
+9
-10
@@ -18,9 +18,10 @@
|
||||
|
||||
package me.proton.core.usersettings.data.api
|
||||
|
||||
import me.proton.core.auth.data.api.request.toFido2Request
|
||||
import me.proton.core.auth.data.api.request.toSecondFactorCode
|
||||
import me.proton.core.auth.data.api.request.toSecondFactorFido
|
||||
import me.proton.core.auth.domain.entity.ServerProof
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.pgp.Based64Encoded
|
||||
import me.proton.core.crypto.common.pgp.EncryptedSignature
|
||||
import me.proton.core.crypto.common.srp.Auth
|
||||
@@ -82,16 +83,15 @@ class UserSettingsRemoteDataSourceImpl @Inject constructor(
|
||||
email: String,
|
||||
srpProofs: SrpProofs,
|
||||
srpSession: String,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?
|
||||
secondFactorProof: SecondFactorProof?
|
||||
): Pair<UserSettings, ServerProof> =
|
||||
result("updateRecoveryEmail") {
|
||||
apiProvider.get<UserSettingsApi>(sessionUserId).invoke {
|
||||
updateRecoveryEmail(
|
||||
UpdateRecoveryEmailRequest(
|
||||
email = email,
|
||||
twoFactorCode = secondFactorCode,
|
||||
fido2 = secondFactorFido?.toFido2Request(),
|
||||
twoFactorCode = secondFactorProof.toSecondFactorCode(),
|
||||
fido2 = secondFactorProof.toSecondFactorFido(),
|
||||
clientEphemeral = srpProofs.clientEphemeral,
|
||||
clientProof = srpProofs.clientProof,
|
||||
srpSession = srpSession
|
||||
@@ -106,16 +106,15 @@ class UserSettingsRemoteDataSourceImpl @Inject constructor(
|
||||
sessionUserId: SessionUserId,
|
||||
srpProofs: SrpProofs,
|
||||
srpSession: String,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?,
|
||||
secondFactorProof: SecondFactorProof?,
|
||||
auth: Auth
|
||||
): Pair<UserSettings, ServerProof> =
|
||||
result("updateLoginPassword") {
|
||||
apiProvider.get<UserSettingsApi>(sessionUserId).invoke {
|
||||
updateLoginPassword(
|
||||
UpdateLoginPasswordRequest(
|
||||
twoFactorCode = secondFactorCode,
|
||||
fido2 = secondFactorFido?.toFido2Request(),
|
||||
twoFactorCode = secondFactorProof.toSecondFactorCode(),
|
||||
fido2 = secondFactorProof.toSecondFactorFido(),
|
||||
clientEphemeral = srpProofs.clientEphemeral,
|
||||
clientProof = srpProofs.clientProof,
|
||||
srpSession = srpSession,
|
||||
|
||||
+5
-9
@@ -27,7 +27,7 @@ import com.dropbox.android.external.store4.StoreRequest
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import me.proton.core.auth.domain.usecase.ValidateServerProof
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.srp.Auth
|
||||
import me.proton.core.crypto.common.srp.SrpProofs
|
||||
import me.proton.core.data.arch.buildProtonStore
|
||||
@@ -87,16 +87,14 @@ class UserSettingsRepositoryImpl @Inject constructor(
|
||||
email: String,
|
||||
srpProofs: SrpProofs,
|
||||
srpSession: String,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?
|
||||
secondFactorProof: SecondFactorProof?,
|
||||
): UserSettings {
|
||||
val (userSettings, serverProof) = remoteDataSource.updateRecoveryEmail(
|
||||
sessionUserId = sessionUserId,
|
||||
email = email,
|
||||
srpProofs = srpProofs,
|
||||
srpSession = srpSession,
|
||||
secondFactorCode = secondFactorCode,
|
||||
secondFactorFido = secondFactorFido
|
||||
secondFactorProof = secondFactorProof
|
||||
)
|
||||
validateServerProof(serverProof, srpProofs.expectedServerProof) { "recovery email update failed" }
|
||||
localDataSource.insertOrUpdate(userSettings)
|
||||
@@ -107,16 +105,14 @@ class UserSettingsRepositoryImpl @Inject constructor(
|
||||
sessionUserId: SessionUserId,
|
||||
srpProofs: SrpProofs,
|
||||
srpSession: String,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?,
|
||||
secondFactorProof: SecondFactorProof?,
|
||||
auth: Auth
|
||||
): UserSettings {
|
||||
val (userSettings, serverProof) = remoteDataSource.updateLoginPassword(
|
||||
sessionUserId = sessionUserId,
|
||||
srpProofs = srpProofs,
|
||||
srpSession = srpSession,
|
||||
secondFactorCode = secondFactorCode,
|
||||
secondFactorFido = secondFactorFido,
|
||||
secondFactorProof = secondFactorProof,
|
||||
auth = auth
|
||||
)
|
||||
validateServerProof(serverProof, srpProofs.expectedServerProof) { "password change failed" }
|
||||
|
||||
+5
-8
@@ -31,6 +31,7 @@ import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import me.proton.core.auth.domain.exception.InvalidServerAuthenticationException
|
||||
import me.proton.core.auth.domain.usecase.ValidateServerProof
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.srp.Auth
|
||||
import me.proton.core.crypto.common.srp.SrpProofs
|
||||
import me.proton.core.domain.entity.UserId
|
||||
@@ -157,8 +158,7 @@ class UserSettingsRepositoryImplTest {
|
||||
email = "test-email2",
|
||||
srpProofs = testSrpProofs,
|
||||
srpSession = "test-srp-session",
|
||||
secondFactorCode = "",
|
||||
secondFactorFido = null
|
||||
secondFactorProof = SecondFactorProof.SecondFactorCode("")
|
||||
)
|
||||
// THEN
|
||||
assertNotNull(response)
|
||||
@@ -179,8 +179,7 @@ class UserSettingsRepositoryImplTest {
|
||||
email = "test-email2",
|
||||
srpProofs = testSrpProofs,
|
||||
srpSession = "test-srp-session",
|
||||
secondFactorCode = "",
|
||||
secondFactorFido = null
|
||||
secondFactorProof = SecondFactorProof.SecondFactorCode("")
|
||||
)
|
||||
}
|
||||
assertEquals(
|
||||
@@ -222,8 +221,7 @@ class UserSettingsRepositoryImplTest {
|
||||
sessionUserId = UserId(testUserId),
|
||||
srpProofs = testSrpProofs,
|
||||
srpSession = "test-srp-session",
|
||||
secondFactorCode = "",
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = SecondFactorProof.SecondFactorCode(""),
|
||||
auth = testAuth
|
||||
)
|
||||
// THEN
|
||||
@@ -244,8 +242,7 @@ class UserSettingsRepositoryImplTest {
|
||||
sessionUserId = UserId(testUserId),
|
||||
srpProofs = testSrpProofs,
|
||||
srpSession = "test-srp-session",
|
||||
secondFactorCode = "",
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = SecondFactorProof.SecondFactorCode(""),
|
||||
auth = testAuth
|
||||
)
|
||||
}
|
||||
|
||||
@@ -347,8 +347,8 @@ public abstract interface class me/proton/core/usersettings/domain/repository/Us
|
||||
public abstract fun fetch (Lme/proton/core/domain/entity/UserId;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun setRecoverySecret (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun setUsername (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updateLoginPassword (Lme/proton/core/domain/entity/UserId;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lme/proton/core/crypto/common/srp/Auth;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updateRecoveryEmail (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updateLoginPassword (Lme/proton/core/domain/entity/UserId;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lme/proton/core/crypto/common/srp/Auth;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updateRecoveryEmail (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updateUserSettings (Lme/proton/core/domain/entity/UserId;Lme/proton/core/usersettings/domain/entity/UserSettingsProperty;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
@@ -358,8 +358,8 @@ public abstract interface class me/proton/core/usersettings/domain/repository/Us
|
||||
public abstract fun markAsStale (Lme/proton/core/domain/entity/UserId;)V
|
||||
public abstract fun setUsername (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updateCrashReports (Lme/proton/core/domain/entity/UserId;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updateLoginPassword (Lme/proton/core/domain/entity/UserId;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lme/proton/core/crypto/common/srp/Auth;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updateRecoveryEmail (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updateLoginPassword (Lme/proton/core/domain/entity/UserId;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lme/proton/core/crypto/common/srp/Auth;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updateRecoveryEmail (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updateTelemetry (Lme/proton/core/domain/entity/UserId;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updateUserSettings (Lme/proton/core/usersettings/domain/entity/UserSettings;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
@@ -415,12 +415,12 @@ public final class me/proton/core/usersettings/domain/usecase/PerformUpdateCrash
|
||||
|
||||
public final class me/proton/core/usersettings/domain/usecase/PerformUpdateLoginPassword {
|
||||
public fun <init> (Lme/proton/core/crypto/common/context/CryptoContext;Lme/proton/core/account/domain/repository/AccountRepository;Lme/proton/core/auth/domain/repository/AuthRepository;Lme/proton/core/user/domain/repository/UserRepository;Lme/proton/core/usersettings/domain/repository/UserSettingsRepository;)V
|
||||
public final fun invoke (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public final fun invoke (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class me/proton/core/usersettings/domain/usecase/PerformUpdateRecoveryEmail {
|
||||
public fun <init> (Lme/proton/core/account/domain/repository/AccountRepository;Lme/proton/core/auth/domain/repository/AuthRepository;Lme/proton/core/user/domain/repository/UserRepository;Lme/proton/core/usersettings/domain/repository/UserSettingsRepository;Lme/proton/core/crypto/common/srp/SrpCrypto;Lme/proton/core/crypto/common/keystore/KeyStoreCrypto;)V
|
||||
public final fun invoke (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public final fun invoke (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class me/proton/core/usersettings/domain/usecase/PerformUpdateTelemetry {
|
||||
@@ -430,7 +430,7 @@ public final class me/proton/core/usersettings/domain/usecase/PerformUpdateTelem
|
||||
|
||||
public final class me/proton/core/usersettings/domain/usecase/PerformUpdateUserPassword {
|
||||
public fun <init> (Lme/proton/core/crypto/common/context/CryptoContext;Lme/proton/core/account/domain/repository/AccountRepository;Lme/proton/core/auth/domain/repository/AuthRepository;Lme/proton/core/user/domain/UserManager;Lme/proton/core/user/domain/repository/UserRepository;)V
|
||||
public final fun invoke (ZLme/proton/core/domain/entity/UserId;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public final fun invoke (ZLme/proton/core/domain/entity/UserId;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class me/proton/core/usersettings/domain/usecase/SetupUsername {
|
||||
|
||||
+3
-5
@@ -19,7 +19,7 @@
|
||||
package me.proton.core.usersettings.domain.repository
|
||||
|
||||
import me.proton.core.auth.domain.entity.ServerProof
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.pgp.Based64Encoded
|
||||
import me.proton.core.crypto.common.pgp.EncryptedSignature
|
||||
import me.proton.core.crypto.common.srp.Auth
|
||||
@@ -39,16 +39,14 @@ interface UserSettingsRemoteDataSource {
|
||||
email: String,
|
||||
srpProofs: SrpProofs,
|
||||
srpSession: String,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?
|
||||
secondFactorProof: SecondFactorProof?
|
||||
): Pair<UserSettings, ServerProof>
|
||||
|
||||
suspend fun updateLoginPassword(
|
||||
sessionUserId: SessionUserId,
|
||||
srpProofs: SrpProofs,
|
||||
srpSession: String,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?,
|
||||
secondFactorProof: SecondFactorProof?,
|
||||
auth: Auth
|
||||
): Pair<UserSettings, ServerProof>
|
||||
|
||||
|
||||
+3
-5
@@ -19,7 +19,7 @@
|
||||
package me.proton.core.usersettings.domain.repository
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.srp.Auth
|
||||
import me.proton.core.crypto.common.srp.SrpProofs
|
||||
import me.proton.core.domain.arch.DataResult
|
||||
@@ -69,8 +69,7 @@ interface UserSettingsRepository {
|
||||
email: String,
|
||||
srpProofs: SrpProofs,
|
||||
srpSession: String,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?
|
||||
secondFactorProof: SecondFactorProof?
|
||||
): UserSettings
|
||||
|
||||
/**
|
||||
@@ -80,8 +79,7 @@ interface UserSettingsRepository {
|
||||
sessionUserId: SessionUserId,
|
||||
srpProofs: SrpProofs,
|
||||
srpSession: String,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?,
|
||||
secondFactorProof: SecondFactorProof?,
|
||||
auth: Auth
|
||||
): UserSettings
|
||||
|
||||
|
||||
+3
-5
@@ -20,7 +20,7 @@ package me.proton.core.usersettings.domain.usecase
|
||||
|
||||
import me.proton.core.account.domain.repository.AccountRepository
|
||||
import me.proton.core.auth.domain.repository.AuthRepository
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.context.CryptoContext
|
||||
import me.proton.core.crypto.common.keystore.EncryptedString
|
||||
import me.proton.core.crypto.common.keystore.decrypt
|
||||
@@ -47,8 +47,7 @@ class PerformUpdateLoginPassword @Inject constructor(
|
||||
userId: UserId,
|
||||
password: EncryptedString,
|
||||
newPassword: EncryptedString,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?
|
||||
secondFactorProof: SecondFactorProof?
|
||||
): UserSettings {
|
||||
val user = userRepository.getUser(userId)
|
||||
val username = user.nameNotNull()
|
||||
@@ -76,8 +75,7 @@ class PerformUpdateLoginPassword @Inject constructor(
|
||||
sessionUserId = userId,
|
||||
srpProofs = clientProofs,
|
||||
srpSession = loginInfo.srpSession,
|
||||
secondFactorCode = secondFactorCode,
|
||||
secondFactorFido = secondFactorFido,
|
||||
secondFactorProof = secondFactorProof,
|
||||
auth = auth
|
||||
)
|
||||
}
|
||||
|
||||
+3
-5
@@ -20,7 +20,7 @@ package me.proton.core.usersettings.domain.usecase
|
||||
|
||||
import me.proton.core.account.domain.repository.AccountRepository
|
||||
import me.proton.core.auth.domain.repository.AuthRepository
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.keystore.EncryptedString
|
||||
import me.proton.core.crypto.common.keystore.KeyStoreCrypto
|
||||
import me.proton.core.crypto.common.keystore.decrypt
|
||||
@@ -46,8 +46,7 @@ class PerformUpdateRecoveryEmail @Inject constructor(
|
||||
sessionUserId: SessionUserId,
|
||||
newRecoveryEmail: String,
|
||||
password: EncryptedString,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?
|
||||
secondFactorProof: SecondFactorProof?
|
||||
): UserSettings {
|
||||
val user = userRepository.getUser(sessionUserId)
|
||||
val username = user.nameNotNull()
|
||||
@@ -67,8 +66,7 @@ class PerformUpdateRecoveryEmail @Inject constructor(
|
||||
email = newRecoveryEmail,
|
||||
srpProofs = clientProofs,
|
||||
srpSession = loginInfo.srpSession,
|
||||
secondFactorCode = secondFactorCode,
|
||||
secondFactorFido = secondFactorFido
|
||||
secondFactorProof = secondFactorProof
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-5
@@ -20,7 +20,7 @@ package me.proton.core.usersettings.domain.usecase
|
||||
|
||||
import me.proton.core.account.domain.repository.AccountRepository
|
||||
import me.proton.core.auth.domain.repository.AuthRepository
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.context.CryptoContext
|
||||
import me.proton.core.crypto.common.keystore.EncryptedString
|
||||
import me.proton.core.crypto.common.keystore.decrypt
|
||||
@@ -49,8 +49,7 @@ class PerformUpdateUserPassword @Inject constructor(
|
||||
userId: UserId,
|
||||
loginPassword: EncryptedString,
|
||||
newPassword: EncryptedString,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?
|
||||
secondFactorProof: SecondFactorProof?
|
||||
): Boolean {
|
||||
val user = userRepository.getUser(userId)
|
||||
val username = user.nameNotNull()
|
||||
@@ -84,8 +83,7 @@ class PerformUpdateUserPassword @Inject constructor(
|
||||
return userManager.changePassword(
|
||||
userId = userId,
|
||||
newPassword = newPassword,
|
||||
secondFactorCode = secondFactorCode,
|
||||
secondFactorFido = secondFactorFido,
|
||||
secondFactorProof = secondFactorProof,
|
||||
proofs = clientProofs,
|
||||
srpSession = loginInfo.srpSession,
|
||||
auth = auth
|
||||
|
||||
+8
-15
@@ -22,14 +22,12 @@ import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.spyk
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import me.proton.core.account.domain.repository.AccountRepository
|
||||
import me.proton.core.auth.domain.entity.AuthInfo
|
||||
import me.proton.core.auth.domain.entity.Modulus
|
||||
import me.proton.core.auth.domain.repository.AuthRepository
|
||||
import me.proton.core.auth.fido.domain.entity.Fido2PublicKeyCredentialRequestOptions
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.context.CryptoContext
|
||||
import me.proton.core.crypto.common.keystore.KeyStoreCrypto
|
||||
import me.proton.core.crypto.common.srp.Auth
|
||||
@@ -63,7 +61,7 @@ class PerformUpdateLoginPasswordTest {
|
||||
private val testUserId = UserId("test-user-id")
|
||||
private val testUsername = "test-username"
|
||||
private val testPassword = "test-password"
|
||||
private val testSecondFactor = "123456"
|
||||
private val testSecondFactor = SecondFactorProof.SecondFactorCode("123456")
|
||||
private val testSrpSession = "test-srp-session"
|
||||
private val testModulus = "test-modulus"
|
||||
private val testServerEphemeral = "test-server-ephemeral"
|
||||
@@ -140,8 +138,7 @@ class PerformUpdateLoginPasswordTest {
|
||||
sessionUserId = testUserId,
|
||||
srpProofs = any(),
|
||||
srpSession = any(),
|
||||
secondFactorCode = testSecondFactor,
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = testSecondFactor,
|
||||
auth = testAuth
|
||||
)
|
||||
} returns testUserSettingsResponse
|
||||
@@ -194,8 +191,7 @@ class PerformUpdateLoginPasswordTest {
|
||||
userId = testUserId,
|
||||
password = keyStoreCrypto.encrypt(testPassword),
|
||||
newPassword = keyStoreCrypto.encrypt(testNewPassword),
|
||||
secondFactorCode = testSecondFactor,
|
||||
secondFactorFido = null
|
||||
secondFactorProof = testSecondFactor,
|
||||
)
|
||||
// THEN
|
||||
coVerify(exactly = 1) {
|
||||
@@ -203,8 +199,7 @@ class PerformUpdateLoginPasswordTest {
|
||||
sessionUserId = testUserId,
|
||||
srpProofs = any(),
|
||||
srpSession = any(),
|
||||
secondFactorCode = testSecondFactor,
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = testSecondFactor,
|
||||
auth = testAuth
|
||||
)
|
||||
}
|
||||
@@ -214,15 +209,14 @@ class PerformUpdateLoginPasswordTest {
|
||||
@Test
|
||||
fun `update login password with fido2 returns success`() = runTest {
|
||||
// GIVEN
|
||||
val testSecondFactorFido = mockk<SecondFactorFido>(relaxed = true)
|
||||
val testSecondFactorFido = mockk<SecondFactorProof.Fido2>(relaxed = true)
|
||||
|
||||
// WHEN
|
||||
val result = useCase.invoke(
|
||||
userId = testUserId,
|
||||
password = keyStoreCrypto.encrypt(testPassword),
|
||||
newPassword = keyStoreCrypto.encrypt(testNewPassword),
|
||||
secondFactorCode = null,
|
||||
secondFactorFido = testSecondFactorFido
|
||||
secondFactorProof = testSecondFactorFido
|
||||
)
|
||||
// THEN
|
||||
coVerify(exactly = 1) {
|
||||
@@ -230,8 +224,7 @@ class PerformUpdateLoginPasswordTest {
|
||||
sessionUserId = testUserId,
|
||||
srpProofs = any(),
|
||||
srpSession = any(),
|
||||
secondFactorCode = null,
|
||||
secondFactorFido = testSecondFactorFido,
|
||||
secondFactorProof = testSecondFactorFido,
|
||||
auth = testAuth
|
||||
)
|
||||
}
|
||||
|
||||
+6
-10
@@ -26,6 +26,7 @@ import kotlinx.coroutines.test.runTest
|
||||
import me.proton.core.account.domain.repository.AccountRepository
|
||||
import me.proton.core.auth.domain.entity.AuthInfo
|
||||
import me.proton.core.auth.domain.repository.AuthRepository
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.keystore.KeyStoreCrypto
|
||||
import me.proton.core.crypto.common.srp.SrpCrypto
|
||||
import me.proton.core.domain.entity.UserId
|
||||
@@ -55,7 +56,7 @@ class PerformUpdateRecoveryEmailTest {
|
||||
private val testUserId = UserId("test-user-id")
|
||||
private val testUsername = "test-username"
|
||||
private val testPassword = "test-password"
|
||||
private val testSecondFactor = "123456"
|
||||
private val testSecondFactor = SecondFactorProof.SecondFactorCode("123456")
|
||||
private val testSrpSession = "test-srp-session"
|
||||
private val testModulus = "test-modulus"
|
||||
private val testServerEphemeral = "test-server-ephemeral"
|
||||
@@ -105,7 +106,6 @@ class PerformUpdateRecoveryEmailTest {
|
||||
any(),
|
||||
any(),
|
||||
any(),
|
||||
any(),
|
||||
any()
|
||||
)
|
||||
} returns testUserSettingsResponse
|
||||
@@ -144,8 +144,7 @@ class PerformUpdateRecoveryEmailTest {
|
||||
sessionUserId = testUserId,
|
||||
newRecoveryEmail = "",
|
||||
password = keyStoreCrypto.encrypt(testPassword),
|
||||
secondFactorCode = testSecondFactor,
|
||||
secondFactorFido = null
|
||||
secondFactorProof = testSecondFactor
|
||||
)
|
||||
coVerify(exactly = 1) {
|
||||
userSettingsRepository.updateRecoveryEmail(
|
||||
@@ -153,8 +152,7 @@ class PerformUpdateRecoveryEmailTest {
|
||||
email = "",
|
||||
srpProofs = any(),
|
||||
srpSession = any(),
|
||||
secondFactorCode = testSecondFactor,
|
||||
secondFactorFido = null
|
||||
secondFactorProof = testSecondFactor
|
||||
)
|
||||
}
|
||||
assertNotNull(result)
|
||||
@@ -189,8 +187,7 @@ class PerformUpdateRecoveryEmailTest {
|
||||
sessionUserId = testUserId,
|
||||
newRecoveryEmail = "",
|
||||
password = testPassword,
|
||||
secondFactorCode = testSecondFactor,
|
||||
secondFactorFido = null
|
||||
secondFactorProof = testSecondFactor
|
||||
)
|
||||
coVerify(exactly = 1) {
|
||||
userSettingsRepository.updateRecoveryEmail(
|
||||
@@ -198,8 +195,7 @@ class PerformUpdateRecoveryEmailTest {
|
||||
email = "",
|
||||
srpProofs = any(),
|
||||
srpSession = any(),
|
||||
secondFactorCode = testSecondFactor,
|
||||
secondFactorFido = null
|
||||
secondFactorProof = testSecondFactor
|
||||
)
|
||||
}
|
||||
assertNotNull(result)
|
||||
|
||||
+7
-11
@@ -26,7 +26,7 @@ import me.proton.core.account.domain.repository.AccountRepository
|
||||
import me.proton.core.auth.domain.entity.AuthInfo
|
||||
import me.proton.core.auth.domain.entity.Modulus
|
||||
import me.proton.core.auth.domain.repository.AuthRepository
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.context.CryptoContext
|
||||
import me.proton.core.crypto.common.keystore.KeyStoreCrypto
|
||||
import me.proton.core.crypto.common.pgp.PGPCrypto
|
||||
@@ -58,7 +58,7 @@ class PerformUpdateUserPasswordTest {
|
||||
private val testSessionId = SessionId("test-session-id")
|
||||
private val testUserId = UserId("test-user-id")
|
||||
private val testUsername = "test-username"
|
||||
private val testSecondFactor = "123456"
|
||||
private val testSecondFactorCode = SecondFactorProof.SecondFactorCode("123456")
|
||||
private val testKeySalt = "test-keysalt"
|
||||
private val testSrpSession = "test-srp-session"
|
||||
private val testLoginPassword = "test-login-password"
|
||||
@@ -118,8 +118,7 @@ class PerformUpdateUserPasswordTest {
|
||||
userManager.changePassword(
|
||||
userId = testUserId,
|
||||
newPassword = any(),
|
||||
secondFactorCode = any(),
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = any(),
|
||||
proofs = any(),
|
||||
srpSession = any(),
|
||||
auth = any()
|
||||
@@ -180,8 +179,7 @@ class PerformUpdateUserPasswordTest {
|
||||
assertFailsWith(IllegalArgumentException::class) {
|
||||
useCase.invoke(
|
||||
userId = testUserId,
|
||||
secondFactorCode = testSecondFactor,
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = testSecondFactorCode,
|
||||
loginPassword = keyStoreCrypto.encrypt(testLoginPassword),
|
||||
newPassword = keyStoreCrypto.encrypt(testNewMailboxPassword),
|
||||
twoPasswordMode = false
|
||||
@@ -192,14 +190,13 @@ class PerformUpdateUserPasswordTest {
|
||||
@Test
|
||||
fun `update mailbox password fido2`() = runTest {
|
||||
coEvery { userRepository.getUser(testUserId) } returns testUser
|
||||
val secondFactorFido = mockk<SecondFactorFido>(relaxed = true)
|
||||
val secondFactorFido = mockk<SecondFactorProof.Fido2>(relaxed = true)
|
||||
|
||||
coEvery {
|
||||
userManager.changePassword(
|
||||
userId = testUserId,
|
||||
newPassword = any(),
|
||||
secondFactorCode = null,
|
||||
secondFactorFido = secondFactorFido,
|
||||
secondFactorProof = secondFactorFido,
|
||||
proofs = any(),
|
||||
srpSession = any(),
|
||||
auth = any()
|
||||
@@ -208,8 +205,7 @@ class PerformUpdateUserPasswordTest {
|
||||
|
||||
val result = useCase.invoke(
|
||||
userId = testUserId,
|
||||
secondFactorCode = null,
|
||||
secondFactorFido = secondFactorFido,
|
||||
secondFactorProof = secondFactorFido,
|
||||
loginPassword = keyStoreCrypto.encrypt(testLoginPassword),
|
||||
newPassword = keyStoreCrypto.encrypt(testNewMailboxPassword),
|
||||
twoPasswordMode = false
|
||||
|
||||
@@ -171,17 +171,16 @@ public final class me/proton/core/usersettings/presentation/entity/SettingsInput
|
||||
public final class me/proton/core/usersettings/presentation/entity/TwoFaDialogArguments : android/os/Parcelable {
|
||||
public static final field $stable I
|
||||
public static final field CREATOR Landroid/os/Parcelable$Creator;
|
||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;)V
|
||||
public fun <init> (Ljava/lang/String;Lme/proton/core/auth/presentation/viewmodel/Source;)V
|
||||
public final fun component1 ()Ljava/lang/String;
|
||||
public final fun component2 ()Ljava/lang/String;
|
||||
public final fun copy (Ljava/lang/String;Ljava/lang/String;)Lme/proton/core/usersettings/presentation/entity/TwoFaDialogArguments;
|
||||
public static synthetic fun copy$default (Lme/proton/core/usersettings/presentation/entity/TwoFaDialogArguments;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lme/proton/core/usersettings/presentation/entity/TwoFaDialogArguments;
|
||||
public final fun component2 ()Lme/proton/core/auth/presentation/viewmodel/Source;
|
||||
public final fun copy (Ljava/lang/String;Lme/proton/core/auth/presentation/viewmodel/Source;)Lme/proton/core/usersettings/presentation/entity/TwoFaDialogArguments;
|
||||
public static synthetic fun copy$default (Lme/proton/core/usersettings/presentation/entity/TwoFaDialogArguments;Ljava/lang/String;Lme/proton/core/auth/presentation/viewmodel/Source;ILjava/lang/Object;)Lme/proton/core/usersettings/presentation/entity/TwoFaDialogArguments;
|
||||
public fun describeContents ()I
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getSource ()Lme/proton/core/auth/presentation/viewmodel/Source;
|
||||
public final fun getSourceString ()Ljava/lang/String;
|
||||
public final fun getUser ()Lme/proton/core/domain/entity/UserId;
|
||||
public final fun getUserId ()Ljava/lang/String;
|
||||
public final fun getUserId ()Lme/proton/core/domain/entity/UserId;
|
||||
public final fun getUserIdString ()Ljava/lang/String;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
public fun writeToParcel (Landroid/os/Parcel;I)V
|
||||
@@ -350,7 +349,7 @@ public final class me/proton/core/usersettings/presentation/ui/StartTwoFAInputDi
|
||||
public synthetic fun createIntent (Landroid/content/Context;Ljava/lang/Object;)Landroid/content/Intent;
|
||||
public fun createIntent (Landroid/content/Context;Lme/proton/core/usersettings/presentation/entity/TwoFaDialogArguments;)Landroid/content/Intent;
|
||||
public synthetic fun parseResult (ILandroid/content/Intent;)Ljava/lang/Object;
|
||||
public fun parseResult (ILandroid/content/Intent;)Lme/proton/core/auth/presentation/entity/TwoFAInput;
|
||||
public fun parseResult (ILandroid/content/Intent;)Lme/proton/core/auth/presentation/entity/SecondFactorProofEntity;
|
||||
}
|
||||
|
||||
public final class me/proton/core/usersettings/presentation/ui/StartUpdateRecoveryEmail : androidx/activity/result/contract/ActivityResultContract {
|
||||
@@ -455,15 +454,13 @@ public final class me/proton/core/usersettings/presentation/viewmodel/PasswordMa
|
||||
|
||||
public final class me/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$Action$SetTwoFactor : me/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$Action {
|
||||
public static final field $stable I
|
||||
public fun <init> (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;)V
|
||||
public fun <init> (Lme/proton/core/domain/entity/UserId;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;)V
|
||||
public final fun component1 ()Lme/proton/core/domain/entity/UserId;
|
||||
public final fun component2 ()Ljava/lang/String;
|
||||
public final fun component3 ()Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;
|
||||
public final fun copy (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;)Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$Action$SetTwoFactor;
|
||||
public static synthetic fun copy$default (Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$Action$SetTwoFactor;Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;ILjava/lang/Object;)Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$Action$SetTwoFactor;
|
||||
public final fun component2 ()Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;
|
||||
public final fun copy (Lme/proton/core/domain/entity/UserId;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;)Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$Action$SetTwoFactor;
|
||||
public static synthetic fun copy$default (Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$Action$SetTwoFactor;Lme/proton/core/domain/entity/UserId;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;ILjava/lang/Object;)Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$Action$SetTwoFactor;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getCode ()Ljava/lang/String;
|
||||
public final fun getTwoFAFido ()Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;
|
||||
public final fun getSecondFactorProof ()Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;
|
||||
public fun getUserId ()Lme/proton/core/domain/entity/UserId;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
@@ -471,21 +468,19 @@ public final class me/proton/core/usersettings/presentation/viewmodel/PasswordMa
|
||||
|
||||
public final class me/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$Action$UpdatePassword : me/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$Action {
|
||||
public static final field $stable I
|
||||
public fun <init> (Lme/proton/core/domain/entity/UserId;Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$PasswordType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;)V
|
||||
public synthetic fun <init> (Lme/proton/core/domain/entity/UserId;Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$PasswordType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public fun <init> (Lme/proton/core/domain/entity/UserId;Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$PasswordType;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;)V
|
||||
public synthetic fun <init> (Lme/proton/core/domain/entity/UserId;Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$PasswordType;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun component1 ()Lme/proton/core/domain/entity/UserId;
|
||||
public final fun component2 ()Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$PasswordType;
|
||||
public final fun component3 ()Ljava/lang/String;
|
||||
public final fun component4 ()Ljava/lang/String;
|
||||
public final fun component5 ()Ljava/lang/String;
|
||||
public final fun component6 ()Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;
|
||||
public final fun copy (Lme/proton/core/domain/entity/UserId;Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$PasswordType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;)Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$Action$UpdatePassword;
|
||||
public static synthetic fun copy$default (Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$Action$UpdatePassword;Lme/proton/core/domain/entity/UserId;Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$PasswordType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;ILjava/lang/Object;)Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$Action$UpdatePassword;
|
||||
public final fun component5 ()Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;
|
||||
public final fun copy (Lme/proton/core/domain/entity/UserId;Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$PasswordType;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;)Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$Action$UpdatePassword;
|
||||
public static synthetic fun copy$default (Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$Action$UpdatePassword;Lme/proton/core/domain/entity/UserId;Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$PasswordType;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;ILjava/lang/Object;)Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$Action$UpdatePassword;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getNewPassword ()Ljava/lang/String;
|
||||
public final fun getPassword ()Ljava/lang/String;
|
||||
public final fun getSecondFactorCode ()Ljava/lang/String;
|
||||
public final fun getSecondFactorFido ()Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;
|
||||
public final fun getSecondFactorProof ()Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;
|
||||
public final fun getType ()Lme/proton/core/usersettings/presentation/viewmodel/PasswordManagementViewModel$PasswordType;
|
||||
public fun getUserId ()Lme/proton/core/domain/entity/UserId;
|
||||
public fun hashCode ()I
|
||||
@@ -610,7 +605,7 @@ public final class me/proton/core/usersettings/presentation/viewmodel/UpdateReco
|
||||
public final fun getState ()Lkotlinx/coroutines/flow/StateFlow;
|
||||
public final fun setNewRecoveryEmail (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;)V
|
||||
public final fun setPassword (Ljava/lang/String;)V
|
||||
public final fun setSecondFactor (Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;)V
|
||||
public final fun setSecondFactor (Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;)V
|
||||
}
|
||||
|
||||
public abstract class me/proton/core/usersettings/presentation/viewmodel/UpdateRecoveryEmailViewModel$State {
|
||||
|
||||
@@ -31,7 +31,7 @@ protonBuild {
|
||||
|
||||
protonCoverage {
|
||||
branchCoveragePercentage.set(42)
|
||||
lineCoveragePercentage.set(53)
|
||||
lineCoveragePercentage.set(55)
|
||||
}
|
||||
|
||||
publishOption.shouldBePublishedAsLib = true
|
||||
|
||||
+4
-6
@@ -26,11 +26,9 @@ import me.proton.core.domain.entity.UserId
|
||||
|
||||
@Parcelize
|
||||
data class TwoFaDialogArguments(
|
||||
val userId: String,
|
||||
val sourceString: String
|
||||
val userIdString: String,
|
||||
val source: Source
|
||||
) : Parcelable {
|
||||
@IgnoredOnParcel
|
||||
val user = UserId(userId)
|
||||
@IgnoredOnParcel
|
||||
val source = Source.valueOf(sourceString)
|
||||
}
|
||||
val userId = UserId(userIdString)
|
||||
}
|
||||
|
||||
+3
-3
@@ -22,7 +22,7 @@ import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.activity.result.contract.ActivityResultContract
|
||||
import me.proton.core.auth.presentation.entity.TwoFAInput
|
||||
import me.proton.core.auth.presentation.entity.SecondFactorProofEntity
|
||||
import me.proton.core.usersettings.presentation.entity.SettingsInput
|
||||
import me.proton.core.usersettings.presentation.entity.PasswordManagementResult
|
||||
import me.proton.core.usersettings.presentation.entity.TwoFaDialogArguments
|
||||
@@ -53,14 +53,14 @@ class StartPasswordManagement : ActivityResultContract<SettingsInput, PasswordMa
|
||||
}
|
||||
}
|
||||
|
||||
class StartTwoFAInputDialog : ActivityResultContract<TwoFaDialogArguments, TwoFAInput?>() {
|
||||
class StartTwoFAInputDialog : ActivityResultContract<TwoFaDialogArguments, SecondFactorProofEntity?>() {
|
||||
|
||||
override fun createIntent(context: Context, input: TwoFaDialogArguments): Intent =
|
||||
Intent(context, TwoFaInputActivity::class.java).apply {
|
||||
putExtra(TwoFaInputActivity.ARG_INPUT, input)
|
||||
}
|
||||
|
||||
override fun parseResult(resultCode: Int, intent: Intent?): TwoFAInput? {
|
||||
override fun parseResult(resultCode: Int, intent: Intent?): SecondFactorProofEntity? {
|
||||
if (resultCode != Activity.RESULT_OK) return null
|
||||
return intent?.getParcelableExtra(TwoFaInputActivity.ARG_RESULT)
|
||||
}
|
||||
|
||||
+3
-3
@@ -39,7 +39,7 @@ import me.proton.core.accountrecovery.presentation.compose.ui.AccountRecoveryDia
|
||||
import me.proton.core.accountrecovery.presentation.compose.ui.PasswordResetDialogActivity
|
||||
import me.proton.core.accountrecovery.presentation.compose.view.AccountRecoveryInfo
|
||||
import me.proton.core.auth.domain.IsCommonPasswordCheckEnabled
|
||||
import me.proton.core.auth.presentation.entity.fromParcelable
|
||||
import me.proton.core.auth.presentation.entity.fromEntity
|
||||
import me.proton.core.auth.presentation.viewmodel.Source
|
||||
import me.proton.core.compose.theme.ProtonTheme
|
||||
import me.proton.core.domain.entity.UserId
|
||||
@@ -86,7 +86,7 @@ class PasswordManagementFragment :
|
||||
|
||||
private val twoFactorLauncher = registerForActivityResult(StartTwoFAInputDialog()) { result ->
|
||||
if (result != null) {
|
||||
viewModel.perform(Action.SetTwoFactor(userId, result.twoFA, result.twoFAFido?.fromParcelable()))
|
||||
viewModel.perform(Action.SetTwoFactor(userId, result.fromEntity()))
|
||||
} else {
|
||||
viewModel.perform(Action.CancelTwoFactor(userId))
|
||||
}
|
||||
@@ -175,7 +175,7 @@ class PasswordManagementFragment :
|
||||
}
|
||||
|
||||
is PasswordManagementViewModel.State.TwoFactorNeeded -> {
|
||||
twoFactorLauncher.launch(TwoFaDialogArguments(userId.id, Source.changePassword.value))
|
||||
twoFactorLauncher.launch(TwoFaDialogArguments(userId.id, Source.ChangePassword))
|
||||
}
|
||||
|
||||
is PasswordManagementViewModel.State.Success -> {
|
||||
|
||||
+3
-3
@@ -26,7 +26,7 @@ import me.proton.core.auth.presentation.alert.TwoFAInputDialog
|
||||
import me.proton.core.auth.presentation.alert.showPasswordEnterDialog
|
||||
import me.proton.core.auth.presentation.alert.showTwoFAEnterDialog
|
||||
import me.proton.core.auth.presentation.entity.PasswordInput
|
||||
import me.proton.core.auth.presentation.entity.TwoFAInput
|
||||
import me.proton.core.auth.presentation.entity.SecondFactorProofEntity
|
||||
import me.proton.core.auth.presentation.viewmodel.Source
|
||||
import me.proton.core.domain.entity.UserId
|
||||
import me.proton.core.presentation.ui.alert.FragmentDialogResultLauncher
|
||||
@@ -61,7 +61,7 @@ fun FragmentManager.registerShowTwoFADialogResultLauncher(
|
||||
context: ComponentActivity,
|
||||
source: Source,
|
||||
userId: UserId,
|
||||
onResult: (TwoFAInput?) -> Unit
|
||||
onResult: (SecondFactorProofEntity?) -> Unit
|
||||
): FragmentDialogResultLauncher<Unit> {
|
||||
|
||||
setFragmentResultListener(
|
||||
@@ -69,7 +69,7 @@ fun FragmentManager.registerShowTwoFADialogResultLauncher(
|
||||
context
|
||||
) { _, bundle ->
|
||||
val result =
|
||||
bundle.getParcelable<TwoFAInput>(TwoFAInputDialog.BUNDLE_KEY_2FA_DATA)
|
||||
bundle.getParcelable<SecondFactorProofEntity>(TwoFAInputDialog.BUNDLE_KEY_2FA_DATA)
|
||||
onResult(result)
|
||||
}
|
||||
|
||||
|
||||
+1
-3
@@ -22,8 +22,6 @@ import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import me.proton.core.auth.presentation.viewmodel.Source
|
||||
import me.proton.core.domain.entity.UserId
|
||||
import me.proton.core.presentation.ui.ProtonActivity
|
||||
import me.proton.core.usersettings.presentation.entity.TwoFaDialogArguments
|
||||
|
||||
@@ -39,7 +37,7 @@ class TwoFaInputActivity : ProtonActivity() {
|
||||
}
|
||||
|
||||
private val userId by lazy {
|
||||
twoFaDialogArguments.user
|
||||
twoFaDialogArguments.userId
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
+5
-3
@@ -28,7 +28,7 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import me.proton.core.auth.presentation.entity.fromParcelable
|
||||
import me.proton.core.auth.presentation.entity.fromEntity
|
||||
import me.proton.core.auth.presentation.viewmodel.Source
|
||||
import me.proton.core.domain.entity.UserId
|
||||
import me.proton.core.presentation.ui.ProtonFragment
|
||||
@@ -59,7 +59,7 @@ class UpdateRecoveryEmailFragment : ProtonFragment(R.layout.fragment_update_reco
|
||||
private lateinit var showPasswordDialogResultLauncher: FragmentDialogResultLauncher<Unit>
|
||||
private val showTwoFADialogResultLauncher = registerForActivityResult(StartTwoFAInputDialog()) { result ->
|
||||
if (result != null) {
|
||||
viewModel.setSecondFactor(result.twoFA, result.twoFAFido?.fromParcelable())
|
||||
viewModel.setSecondFactor(result.fromEntity())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,9 @@ class UpdateRecoveryEmailFragment : ProtonFragment(R.layout.fragment_update_reco
|
||||
showPasswordDialogResultLauncher.show(Unit)
|
||||
}
|
||||
is UpdateRecoveryEmailViewModel.State.SecondFactorNeeded -> {
|
||||
showTwoFADialogResultLauncher.launch(TwoFaDialogArguments(userId.id, Source.changeRecoveryEmail.value))
|
||||
showTwoFADialogResultLauncher.launch(
|
||||
TwoFaDialogArguments(userId.id, Source.ChangeRecoveryEmail)
|
||||
)
|
||||
}
|
||||
}.exhaustive
|
||||
}.launchIn(viewLifecycleOwner.lifecycleScope)
|
||||
|
||||
+7
-12
@@ -34,7 +34,7 @@ import kotlinx.coroutines.flow.stateIn
|
||||
import me.proton.core.accountrecovery.domain.IsAccountRecoveryResetEnabled
|
||||
import me.proton.core.accountrecovery.domain.usecase.ObserveUserRecovery
|
||||
import me.proton.core.accountrecovery.domain.usecase.ObserveUserRecoverySelfInitiated
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.compose.viewmodel.stopTimeoutMillis
|
||||
import me.proton.core.crypto.common.keystore.KeyStoreCrypto
|
||||
import me.proton.core.crypto.common.keystore.encrypt
|
||||
@@ -135,8 +135,7 @@ class PasswordManagementViewModel @Inject constructor(
|
||||
userId = action.userId,
|
||||
password = encryptedPassword,
|
||||
newPassword = encryptedNewPassword,
|
||||
secondFactorCode = action.secondFactorCode,
|
||||
secondFactorFido = action.secondFactorFido
|
||||
secondFactorProof = action.secondFactorProof
|
||||
)
|
||||
emit(State.Success)
|
||||
}
|
||||
@@ -150,8 +149,7 @@ class PasswordManagementViewModel @Inject constructor(
|
||||
userId = action.userId,
|
||||
loginPassword = encryptedLoginPassword,
|
||||
newPassword = encryptedNewMailboxPassword,
|
||||
secondFactorCode = action.secondFactorCode,
|
||||
secondFactorFido = action.secondFactorFido
|
||||
secondFactorProof = action.secondFactorProof
|
||||
)
|
||||
emit(State.Success)
|
||||
}
|
||||
@@ -165,8 +163,7 @@ class PasswordManagementViewModel @Inject constructor(
|
||||
userId = action.userId,
|
||||
loginPassword = encryptedLoginPassword,
|
||||
newPassword = encryptedNewMailboxPassword,
|
||||
secondFactorCode = action.secondFactorCode,
|
||||
secondFactorFido = action.secondFactorFido
|
||||
secondFactorProof = action.secondFactorProof
|
||||
)
|
||||
emit(State.Success)
|
||||
}
|
||||
@@ -184,7 +181,7 @@ class PasswordManagementViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
private suspend fun setTwoFactor(action: Action.SetTwoFactor): Flow<State> {
|
||||
val passwordAction = requireNotNull(pendingUpdate?.copy(secondFactorCode = action.code, secondFactorFido = action.twoFAFido))
|
||||
val passwordAction = requireNotNull(pendingUpdate?.copy(secondFactorProof = action.secondFactorProof))
|
||||
return updatePassword(passwordAction)
|
||||
}
|
||||
|
||||
@@ -258,14 +255,12 @@ class PasswordManagementViewModel @Inject constructor(
|
||||
val type: PasswordType,
|
||||
val password: String,
|
||||
val newPassword: String,
|
||||
val secondFactorCode: String? = "",
|
||||
val secondFactorFido: SecondFactorFido? = null
|
||||
val secondFactorProof: SecondFactorProof? = null
|
||||
) : Action(userId)
|
||||
|
||||
data class SetTwoFactor(
|
||||
override val userId: UserId,
|
||||
val code: String?,
|
||||
val twoFAFido: SecondFactorFido?
|
||||
val secondFactorProof: SecondFactorProof?
|
||||
) : Action(userId)
|
||||
|
||||
data class CancelTwoFactor(
|
||||
|
||||
+5
-7
@@ -26,7 +26,7 @@ import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.keystore.EncryptedString
|
||||
import me.proton.core.crypto.common.keystore.KeyStoreCrypto
|
||||
import me.proton.core.crypto.common.keystore.encrypt
|
||||
@@ -83,8 +83,8 @@ class UpdateRecoveryEmailViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun setSecondFactor(secondFactorCode: String?, secondFactorFido: SecondFactorFido?) {
|
||||
updateRecoveryEmail(secondFactorCode, secondFactorFido)
|
||||
fun setSecondFactor(secondFactorProof: SecondFactorProof?) {
|
||||
updateRecoveryEmail(secondFactorProof)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,16 +106,14 @@ class UpdateRecoveryEmailViewModel @Inject constructor(
|
||||
* Updates (replaces) the user's recovery email address.
|
||||
*/
|
||||
private fun updateRecoveryEmail(
|
||||
secondFactorCode: String? = null,
|
||||
secondFactorFido: SecondFactorFido? = null
|
||||
secondFactorProof: SecondFactorProof? = null
|
||||
) = flow {
|
||||
emit(State.UpdatingCurrent)
|
||||
val updateRecoveryEmailResult = performUpdateRecoveryEmail(
|
||||
sessionUserId = checkNotNull(userId),
|
||||
newRecoveryEmail = checkNotNull(recoveryEmail),
|
||||
password = checkNotNull(inputPassword),
|
||||
secondFactorCode = secondFactorCode,
|
||||
secondFactorFido = secondFactorFido
|
||||
secondFactorProof = secondFactorProof
|
||||
)
|
||||
emit(State.UpdatingSuccess(updateRecoveryEmailResult.email?.value))
|
||||
}.catch { error ->
|
||||
|
||||
+7
-9
@@ -27,6 +27,7 @@ import kotlinx.coroutines.flow.flowOf
|
||||
import me.proton.core.accountrecovery.domain.IsAccountRecoveryResetEnabled
|
||||
import me.proton.core.accountrecovery.domain.usecase.ObserveUserRecovery
|
||||
import me.proton.core.accountrecovery.domain.usecase.ObserveUserRecoverySelfInitiated
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.keystore.KeyStoreCrypto
|
||||
import me.proton.core.domain.entity.Product
|
||||
import me.proton.core.domain.entity.UserId
|
||||
@@ -190,7 +191,7 @@ class PasswordManagementViewModelTest : ArchTest by ArchTest(), CoroutinesTest b
|
||||
)
|
||||
)
|
||||
|
||||
coEvery { performUpdateMailboxPassword.invoke(any(), testUserId, any(), any(), any(), any()) } returns true
|
||||
coEvery { performUpdateMailboxPassword.invoke(any(), testUserId, any(), any(), any()) } returns true
|
||||
|
||||
flowTest(viewModel.state) {
|
||||
// WHEN
|
||||
@@ -210,8 +211,7 @@ class PasswordManagementViewModelTest : ArchTest by ArchTest(), CoroutinesTest b
|
||||
userId = testUserId,
|
||||
loginPassword = "encrypted-test-password",
|
||||
newPassword = "encrypted-test-new-password",
|
||||
secondFactorCode = "",
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = null,
|
||||
twoPasswordMode = false
|
||||
)
|
||||
}
|
||||
@@ -235,7 +235,7 @@ class PasswordManagementViewModelTest : ArchTest by ArchTest(), CoroutinesTest b
|
||||
)
|
||||
)
|
||||
|
||||
coEvery { performUpdateMailboxPassword.invoke(any(), any(), any(), any(), any(), any()) } returns true
|
||||
coEvery { performUpdateMailboxPassword.invoke(any(), any(), any(), any(), any()) } returns true
|
||||
|
||||
flowTest(viewModel.state) {
|
||||
// WHEN
|
||||
@@ -255,8 +255,7 @@ class PasswordManagementViewModelTest : ArchTest by ArchTest(), CoroutinesTest b
|
||||
userId = testUserId,
|
||||
loginPassword = "encrypted-test-password",
|
||||
newPassword = "encrypted-test-new-password",
|
||||
secondFactorCode = "",
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = null,
|
||||
twoPasswordMode = true
|
||||
)
|
||||
}
|
||||
@@ -280,7 +279,7 @@ class PasswordManagementViewModelTest : ArchTest by ArchTest(), CoroutinesTest b
|
||||
)
|
||||
)
|
||||
|
||||
coEvery { performUpdateMailboxPassword.invoke(any(), any(), any(), any(), any(), any()) } returns true
|
||||
coEvery { performUpdateMailboxPassword.invoke(any(), any(), any(), any(), any()) } returns true
|
||||
|
||||
flowTest(viewModel.state) {
|
||||
// WHEN
|
||||
@@ -300,8 +299,7 @@ class PasswordManagementViewModelTest : ArchTest by ArchTest(), CoroutinesTest b
|
||||
userId = testUserId,
|
||||
loginPassword = "encrypted-test-password",
|
||||
newPassword = "encrypted-test-new-password",
|
||||
secondFactorCode = "",
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = null,
|
||||
twoPasswordMode = false
|
||||
)
|
||||
}
|
||||
|
||||
+6
-9
@@ -21,6 +21,7 @@ package me.proton.core.usersettings.presentation.viewmodel
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.keystore.EncryptedString
|
||||
import me.proton.core.crypto.common.keystore.KeyStoreCrypto
|
||||
import me.proton.core.domain.entity.UserId
|
||||
@@ -145,8 +146,7 @@ class UpdateRecoveryEmailViewModelTest : ArchTest by ArchTest(), CoroutinesTest
|
||||
sessionUserId = testUserId,
|
||||
newRecoveryEmail = "",
|
||||
password = "encrypted-test-password",
|
||||
secondFactorCode = null,
|
||||
secondFactorFido = null
|
||||
secondFactorProof = null
|
||||
)
|
||||
} returns testUserSettingsResponse.copy(email = RecoverySetting("", 1, notify = true, reset = true))
|
||||
|
||||
@@ -174,8 +174,7 @@ class UpdateRecoveryEmailViewModelTest : ArchTest by ArchTest(), CoroutinesTest
|
||||
sessionUserId = testUserId,
|
||||
newRecoveryEmail = "new-email",
|
||||
password = "encrypted-test-password",
|
||||
secondFactorCode = null,
|
||||
secondFactorFido = null
|
||||
secondFactorProof = null
|
||||
)
|
||||
} returns testUserSettingsResponse.copy(email = RecoverySetting("new-email", 1, notify = true, reset = true))
|
||||
|
||||
@@ -203,8 +202,7 @@ class UpdateRecoveryEmailViewModelTest : ArchTest by ArchTest(), CoroutinesTest
|
||||
sessionUserId = testUserId,
|
||||
newRecoveryEmail = "new-email",
|
||||
password = "encrypted-test-password",
|
||||
secondFactorCode = "123456",
|
||||
secondFactorFido = null
|
||||
secondFactorProof = SecondFactorProof.SecondFactorCode("123456")
|
||||
)
|
||||
} returns testUserSettingsResponse.copy(
|
||||
email = RecoverySetting("new-email", 1, notify = true, reset = true)
|
||||
@@ -233,7 +231,7 @@ class UpdateRecoveryEmailViewModelTest : ArchTest by ArchTest(), CoroutinesTest
|
||||
assertIs<UpdateRecoveryEmailViewModel.State.PasswordNeeded>(awaitItem())
|
||||
viewModel.setPassword(testPassword)
|
||||
assertIs<UpdateRecoveryEmailViewModel.State.SecondFactorNeeded>(awaitItem())
|
||||
viewModel.setSecondFactor("123456", null)
|
||||
viewModel.setSecondFactor(SecondFactorProof.SecondFactorCode("123456"))
|
||||
assertIs<UpdateRecoveryEmailViewModel.State.UpdatingCurrent>(awaitItem())
|
||||
val result = awaitItem()
|
||||
assertTrue(result is UpdateRecoveryEmailViewModel.State.UpdatingSuccess)
|
||||
@@ -248,8 +246,7 @@ class UpdateRecoveryEmailViewModelTest : ArchTest by ArchTest(), CoroutinesTest
|
||||
sessionUserId = testUserId,
|
||||
newRecoveryEmail = "new-email",
|
||||
password = "encrypted-test-password",
|
||||
secondFactorCode = null,
|
||||
secondFactorFido = null
|
||||
secondFactorProof = null
|
||||
)
|
||||
} throws ApiException(
|
||||
ApiResult.Error.Http(
|
||||
|
||||
@@ -189,7 +189,7 @@ public final class me/proton/core/user/data/UserEvents$Companion {
|
||||
public final class me/proton/core/user/data/UserManagerImpl : me/proton/core/user/domain/UserManager {
|
||||
public fun <init> (Lme/proton/core/user/domain/repository/UserRepository;Lme/proton/core/user/domain/repository/UserAddressRepository;Lme/proton/core/user/domain/repository/PassphraseRepository;Lme/proton/core/key/domain/repository/KeySaltRepository;Lme/proton/core/key/domain/repository/PrivateKeyRepository;Lme/proton/core/accountrecovery/domain/repository/AccountRecoveryRepository;Lme/proton/core/user/data/UserAddressKeySecretProvider;Lme/proton/core/crypto/common/context/CryptoContext;Lme/proton/core/user/data/usecase/GenerateSignedKeyList;Ljava/util/Optional;)V
|
||||
public fun addUser (Lme/proton/core/user/domain/entity/User;Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun changePassword (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/crypto/common/srp/Auth;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun changePassword (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/crypto/common/srp/Auth;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun getAddresses (Lme/proton/core/domain/entity/UserId;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun getUser (Lme/proton/core/domain/entity/UserId;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun lock (Lme/proton/core/domain/entity/UserId;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
@@ -1002,7 +1002,7 @@ public final class me/proton/core/user/data/repository/UserRepositoryImpl : me/p
|
||||
public fun removeLockedAndPasswordScopes (Lme/proton/core/domain/entity/UserId;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun setPassphrase (Lme/proton/core/domain/entity/UserId;Lme/proton/core/crypto/common/keystore/EncryptedByteArray;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun unlockUserForLockedScope (Lme/proton/core/domain/entity/UserId;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun unlockUserForPasswordScope (Lme/proton/core/domain/entity/UserId;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun unlockUserForPasswordScope (Lme/proton/core/domain/entity/UserId;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updateUser (Lme/proton/core/user/domain/entity/User;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updateUserUsedBaseSpace (Lme/proton/core/domain/entity/UserId;JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun updateUserUsedDriveSpace (Lme/proton/core/domain/entity/UserId;JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
|
||||
+2
-4
@@ -209,8 +209,7 @@ class UserManagerPasswordTests {
|
||||
keySalt = any(),
|
||||
srpProofs = any(),
|
||||
srpSession = any(),
|
||||
secondFactorCode = null,
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = null,
|
||||
auth = any(),
|
||||
keys = null,
|
||||
userKeys = emptyList()
|
||||
@@ -228,8 +227,7 @@ class UserManagerPasswordTests {
|
||||
),
|
||||
srpSession = "test-srp-session",
|
||||
auth = mockk(),
|
||||
secondFactorCode = null,
|
||||
secondFactorFido = null
|
||||
secondFactorProof = null
|
||||
)
|
||||
|
||||
// THEN
|
||||
|
||||
+3
-6
@@ -42,7 +42,7 @@ import me.proton.core.auth.domain.exception.InvalidServerAuthenticationException
|
||||
import me.proton.core.auth.domain.usecase.ValidateServerProof
|
||||
import me.proton.core.auth.fido.domain.entity.Fido2PublicKeyCredentialDescriptor
|
||||
import me.proton.core.auth.fido.domain.entity.Fido2PublicKeyCredentialRequestOptions
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.challenge.domain.entity.ChallengeFrameDetails
|
||||
import me.proton.core.crypto.android.context.AndroidCryptoContext
|
||||
import me.proton.core.crypto.common.context.CryptoContext
|
||||
@@ -483,7 +483,6 @@ class UserRepositoryImplTests {
|
||||
TestUsers.User1.id,
|
||||
testSrpProofs,
|
||||
"test-srp-session",
|
||||
null,
|
||||
null
|
||||
)
|
||||
assertNotNull(response)
|
||||
@@ -514,8 +513,7 @@ class UserRepositoryImplTests {
|
||||
TestUsers.User1.id,
|
||||
testSrpProofs,
|
||||
"test-srp-session",
|
||||
"test-2fa",
|
||||
null
|
||||
SecondFactorProof.SecondFactorCode("test-2fa")
|
||||
)
|
||||
assertNotNull(response)
|
||||
assertTrue(response)
|
||||
@@ -544,8 +542,7 @@ class UserRepositoryImplTests {
|
||||
TestUsers.User1.id,
|
||||
testSrpProofs,
|
||||
"test-srp-session",
|
||||
null,
|
||||
SecondFactorFido(
|
||||
SecondFactorProof.Fido2(
|
||||
publicKeyOptions = Fido2PublicKeyCredentialRequestOptions(
|
||||
challenge = challenge,
|
||||
allowCredentials = listOf(
|
||||
|
||||
@@ -20,7 +20,7 @@ package me.proton.core.user.data
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import me.proton.core.accountrecovery.domain.repository.AccountRecoveryRepository
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.context.CryptoContext
|
||||
import me.proton.core.crypto.common.keystore.EncryptedByteArray
|
||||
import me.proton.core.crypto.common.keystore.EncryptedString
|
||||
@@ -142,8 +142,7 @@ class UserManagerImpl @Inject constructor(
|
||||
override suspend fun changePassword(
|
||||
userId: UserId,
|
||||
newPassword: EncryptedString,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?,
|
||||
secondFactorProof: SecondFactorProof?,
|
||||
proofs: SrpProofs,
|
||||
srpSession: String,
|
||||
auth: Auth?
|
||||
@@ -169,8 +168,7 @@ class UserManagerImpl @Inject constructor(
|
||||
keySalt = keySalt,
|
||||
srpProofs = proofs,
|
||||
srpSession = srpSession,
|
||||
secondFactorCode = secondFactorCode,
|
||||
secondFactorFido = secondFactorFido,
|
||||
secondFactorProof = secondFactorProof,
|
||||
auth = auth,
|
||||
keys = updatedKeys,
|
||||
userKeys = updatedUserKeys
|
||||
|
||||
@@ -27,10 +27,11 @@ import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import me.proton.core.auth.data.api.request.toFido2Request
|
||||
import me.proton.core.auth.data.api.request.toSecondFactorCode
|
||||
import me.proton.core.auth.data.api.request.toSecondFactorFido
|
||||
import me.proton.core.auth.data.api.response.isSuccess
|
||||
import me.proton.core.auth.domain.usecase.ValidateServerProof
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.challenge.data.frame.ChallengeFrame
|
||||
import me.proton.core.challenge.domain.entity.ChallengeFrameDetails
|
||||
import me.proton.core.challenge.domain.framePrefix
|
||||
@@ -200,16 +201,15 @@ class UserRepositoryImpl @Inject constructor(
|
||||
sessionUserId: SessionUserId,
|
||||
srpProofs: SrpProofs,
|
||||
srpSession: String,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?
|
||||
secondFactorProof: SecondFactorProof?
|
||||
): Boolean = result("unlockUserForPasswordScope") {
|
||||
provider.get<UserApi>(sessionUserId).invoke {
|
||||
val request = UnlockPasswordRequest(
|
||||
srpProofs.clientEphemeral,
|
||||
srpProofs.clientProof,
|
||||
srpSession,
|
||||
secondFactorCode,
|
||||
secondFactorFido?.toFido2Request()
|
||||
clientEphemeral = srpProofs.clientEphemeral,
|
||||
clientProof = srpProofs.clientProof,
|
||||
srpSession = srpSession,
|
||||
twoFactorCode = secondFactorProof.toSecondFactorCode(),
|
||||
fido2 = secondFactorProof.toSecondFactorFido()
|
||||
)
|
||||
val response = unlockPasswordScope(request)
|
||||
validateServerProof(
|
||||
|
||||
@@ -28,6 +28,7 @@ import io.mockk.unmockkStatic
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import me.proton.core.accountrecovery.domain.repository.AccountRecoveryRepository
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.context.CryptoContext
|
||||
import me.proton.core.crypto.common.keystore.EncryptedByteArray
|
||||
import me.proton.core.crypto.common.keystore.PlainByteArray
|
||||
@@ -269,8 +270,7 @@ class UserManagerImplTest {
|
||||
val result = spyManager.changePassword(
|
||||
userId = userIdMigrated,
|
||||
newPassword = "encrypted",
|
||||
secondFactorCode = "code",
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = SecondFactorProof.SecondFactorCode("code"),
|
||||
proofs = mockk(),
|
||||
srpSession = "srp",
|
||||
auth = mockk(),
|
||||
@@ -291,8 +291,7 @@ class UserManagerImplTest {
|
||||
manager.changePassword(
|
||||
userId = userIdMigrated,
|
||||
newPassword = "encrypted",
|
||||
secondFactorCode = "code",
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = SecondFactorProof.SecondFactorCode("code"),
|
||||
proofs = mockk(),
|
||||
srpSession = "srp",
|
||||
auth = mockk(),
|
||||
@@ -304,8 +303,7 @@ class UserManagerImplTest {
|
||||
keySalt = any(),
|
||||
srpProofs = any(),
|
||||
srpSession = any(),
|
||||
secondFactorCode = any(),
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = any(),
|
||||
auth = any(),
|
||||
keys = null,
|
||||
userKeys = expectedUserKeys,
|
||||
@@ -322,8 +320,7 @@ class UserManagerImplTest {
|
||||
manager.changePassword(
|
||||
userId = userIdNotMigrated,
|
||||
newPassword = "encrypted",
|
||||
secondFactorCode = "code",
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = SecondFactorProof.SecondFactorCode("code"),
|
||||
proofs = mockk(),
|
||||
srpSession = "srp",
|
||||
auth = mockk(),
|
||||
@@ -335,8 +332,7 @@ class UserManagerImplTest {
|
||||
keySalt = any(),
|
||||
srpProofs = any(),
|
||||
srpSession = any(),
|
||||
secondFactorCode = any(),
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = any(),
|
||||
auth = any(),
|
||||
keys = expectedUserKeys + expectedAddressKeys,
|
||||
userKeys = null,
|
||||
@@ -350,8 +346,7 @@ class UserManagerImplTest {
|
||||
manager.changePassword(
|
||||
userId = userIdMigrated,
|
||||
newPassword = "encrypted",
|
||||
secondFactorCode = "code",
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = SecondFactorProof.SecondFactorCode("code"),
|
||||
proofs = mockk(),
|
||||
srpSession = "srp",
|
||||
auth = mockk(),
|
||||
@@ -363,8 +358,7 @@ class UserManagerImplTest {
|
||||
keySalt = any(),
|
||||
srpProofs = any(),
|
||||
srpSession = any(),
|
||||
secondFactorCode = any(),
|
||||
secondFactorFido = null,
|
||||
secondFactorProof = any(),
|
||||
auth = any(),
|
||||
keys = any(),
|
||||
userKeys = any(),
|
||||
|
||||
@@ -51,7 +51,7 @@ public final class me/proton/core/user/domain/UserAddressManager$DefaultImpls {
|
||||
|
||||
public abstract interface class me/proton/core/user/domain/UserManager {
|
||||
public abstract fun addUser (Lme/proton/core/user/domain/entity/User;Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun changePassword (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/crypto/common/srp/Auth;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun changePassword (Lme/proton/core/domain/entity/UserId;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/crypto/common/srp/Auth;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun getAddresses (Lme/proton/core/domain/entity/UserId;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun getUser (Lme/proton/core/domain/entity/UserId;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun lock (Lme/proton/core/domain/entity/UserId;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
@@ -550,7 +550,7 @@ public abstract interface class me/proton/core/user/domain/repository/UserReposi
|
||||
public abstract fun observeUser (Lme/proton/core/domain/entity/UserId;Z)Lkotlinx/coroutines/flow/Flow;
|
||||
public abstract fun removeLockedAndPasswordScopes (Lme/proton/core/domain/entity/UserId;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun unlockUserForLockedScope (Lme/proton/core/domain/entity/UserId;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun unlockUserForPasswordScope (Lme/proton/core/domain/entity/UserId;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorFido;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun unlockUserForPasswordScope (Lme/proton/core/domain/entity/UserId;Lme/proton/core/crypto/common/srp/SrpProofs;Ljava/lang/String;Lme/proton/core/auth/fido/domain/entity/SecondFactorProof;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updateUser (Lme/proton/core/user/domain/entity/User;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updateUserUsedBaseSpace (Lme/proton/core/domain/entity/UserId;JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun updateUserUsedDriveSpace (Lme/proton/core/domain/entity/UserId;JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
package me.proton.core.user.domain
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.crypto.common.keystore.EncryptedByteArray
|
||||
import me.proton.core.crypto.common.keystore.EncryptedString
|
||||
import me.proton.core.crypto.common.keystore.PlainByteArray
|
||||
@@ -135,8 +135,7 @@ interface UserManager {
|
||||
suspend fun changePassword(
|
||||
userId: UserId,
|
||||
newPassword: EncryptedString,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?,
|
||||
secondFactorProof: SecondFactorProof?,
|
||||
proofs: SrpProofs,
|
||||
srpSession: String,
|
||||
auth: Auth?
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
package me.proton.core.user.domain.repository
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorFido
|
||||
import me.proton.core.auth.fido.domain.entity.SecondFactorProof
|
||||
import me.proton.core.challenge.domain.entity.ChallengeFrameDetails
|
||||
import me.proton.core.crypto.common.keystore.EncryptedString
|
||||
import me.proton.core.crypto.common.srp.Auth
|
||||
@@ -153,8 +153,7 @@ interface UserRepository : PassphraseRepository {
|
||||
sessionUserId: SessionUserId,
|
||||
srpProofs: SrpProofs,
|
||||
srpSession: String,
|
||||
secondFactorCode: String?,
|
||||
secondFactorFido: SecondFactorFido?
|
||||
secondFactorProof: SecondFactorProof?
|
||||
): Boolean
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user