Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 10 additions & 13 deletions multiplatform-lib/src/commonMain/kotlin/AuthenticatorFacade.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ import com.infomaniak.auth.lib.internal.managers.MigrationManager
import com.infomaniak.auth.lib.internal.network.ApiClientProvider
import com.infomaniak.auth.lib.internal.network.ApiRoutes
import com.infomaniak.auth.lib.internal.repositories.AccountsRepository
import com.infomaniak.auth.lib.internal.repositories.WebAuthnRepository
import com.infomaniak.auth.lib.internal.requests.AuthenticatorRequest
import com.infomaniak.auth.lib.internal.requests.WebAuthnRequests
import com.infomaniak.auth.lib.models.migration.user.SharedUserProfile
import com.infomaniak.auth.lib.network.interfaces.AuthenticatorBridge
import com.infomaniak.auth.lib.network.interfaces.CrashReportInterface
Expand Down Expand Up @@ -75,27 +74,25 @@ abstract class AuthenticatorFacade internal constructor() {
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
): AuthenticatorFacade {
val routes = ApiRoutes(apiHost)
val webAuthnRepository = WebAuthnRepository(
authenticatorRequest = AuthenticatorRequest(
httpClient = ApiClientProvider(
scope = scope,
userAgent = userAgent,
routes = routes,
crashReport = crashReport,
).httpClient,
val webAuthnRequests = WebAuthnRequests(
httpClient = ApiClientProvider(
scope = scope,
userAgent = userAgent,
routes = routes,
)
crashReport = crashReport,
).httpClient,
routes = routes,
)
val accountsDatabase = getAccountsRoomDatabase(databaseNameOrPath)
val accountsRepository = AccountsRepository(accountsDatabase)
val authenticatorManager = AuthenticatorManager(
webAuthnRepository = webAuthnRepository,
webAuthnRequests = webAuthnRequests,
accountsRepository = accountsRepository
).also { it.keyPairManager.ensureKeyPairsAreMoved() }
val migrationManager = MigrationManager(
accountsDatabase = accountsDatabase,
authenticatorManager = authenticatorManager,
webAuthnRepository = webAuthnRepository,
webAuthnRequests = webAuthnRequests,
clientId = clientId,
)
return AuthenticatorFacadeImpl(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ import com.infomaniak.auth.lib.internal.KeyPairManager.MatchOn
import com.infomaniak.auth.lib.internal.db.AccountEntity
import com.infomaniak.auth.lib.internal.db.AccountsDatabase
import com.infomaniak.auth.lib.internal.extensions.firstOrElse
import com.infomaniak.auth.lib.internal.repositories.WebAuthnRepository
import com.infomaniak.auth.lib.internal.requests.WebAuthnRequests
import com.infomaniak.auth.lib.models.migration.SharedApiToken

internal class AccountRestorer(
accountsDatabase: AccountsDatabase,
private val authenticatorManager: AuthenticatorManager,
private val webAuthnRepository: WebAuthnRepository,
private val webAuthnRequests: WebAuthnRequests,
private val clientId: String,
) {

Expand All @@ -51,7 +51,7 @@ internal class AccountRestorer(
val previousRestorationAborted = existingKeyIds.size == 2
if (previousRestorationAborted) {
val newKeyIdToDrop = existingKeyIds.last()
webAuthnRepository.deletePasskeyIfExists(tokenFromOldPasskey.accessToken, newKeyIdToDrop)
webAuthnRequests.deletePasskeyIfExists(tokenFromOldPasskey.accessToken, newKeyIdToDrop)
val _ = keyPairManager.deleteKeysMatching(MatchOn.PasskeyId(newKeyIdToDrop))
}
// Register a new passkey
Expand All @@ -72,7 +72,7 @@ internal class AccountRestorer(
persistToken(account.id, tokenWithNewPassKey)
// We can safely delete the old passkey, as the new one is working and the old token won't be valid anymore
oldKeyId?.let { keyId ->
webAuthnRepository.deletePasskeyIfExists(tokenWithNewPassKey.accessToken, keyId)
webAuthnRequests.deletePasskeyIfExists(tokenWithNewPassKey.accessToken, keyId)
val _ = keyPairManager.deleteKeysMatching(MatchOn.PasskeyId(keyId))
}
dao.upsert(account.copy(status = AccountEntity.Status.LoggedIn))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import com.infomaniak.auth.lib.internal.models.ClientExtensionResults
import com.infomaniak.auth.lib.internal.models.VerifyAuthenticationData
import com.infomaniak.auth.lib.internal.models.VerifyResponse
import com.infomaniak.auth.lib.internal.repositories.AccountsRepository
import com.infomaniak.auth.lib.internal.repositories.WebAuthnRepository
import com.infomaniak.auth.lib.internal.requests.WebAuthnRequests
import com.infomaniak.auth.lib.internal.utils.SignUtils
import com.infomaniak.auth.lib.internal.utils.Xor
import com.infomaniak.auth.lib.models.migration.SharedApiToken
Expand All @@ -35,7 +35,7 @@ import kotlinx.serialization.json.Json
import okio.ByteString.Companion.toByteString

internal class AuthenticatorManager(
private val webAuthnRepository: WebAuthnRepository,
private val webAuthnRequests: WebAuthnRequests,
private val accountsRepository: AccountsRepository,
) {

Expand All @@ -44,10 +44,10 @@ internal class AuthenticatorManager(

private val base64NoPadding get() = cryptoObjectsBuilder.base64UrlSafeNoPadding

suspend fun getUserProfile(token: String) = webAuthnRepository.getUserProfile(token)
suspend fun getUserProfile(token: String) = webAuthnRequests.getUserProfile(token)

suspend fun registerPasskey(token: String, userId: Long): String {
val passkeysOptions = webAuthnRepository.getPasskeysOptions(token).data
val passkeysOptions = webAuthnRequests.getPasskeysOptions(token)
val keyIds = cryptoObjectsBuilder.getKeyIds()
val keyIdAsByteArray = keyIds.first
val keyIdAsString = keyIds.second
Expand All @@ -65,7 +65,7 @@ internal class AuthenticatorManager(
id = keyIdAsString,
)

webAuthnRepository.registerPasskey(token, registerPasskey)
webAuthnRequests.registerPasskey(token, registerPasskey)

return keyIdAsString
}
Expand All @@ -78,7 +78,7 @@ internal class AuthenticatorManager(
val keyId = keyIdOrDefault ?: keyPairManager.findKeyIdFor(MatchOn.UserId(userId))
?: return Xor.Second(Failure.KeyManagement.KeyNotFound("No key found for user $userId"))

val authenticationOptions = webAuthnRepository.challenge(clientId)
val authenticationOptions = webAuthnRequests.challenge(clientId)
val publicKey = keyPairManager.retrievePublicKey(userId, keyId).firstOrNull()
?: return Xor.Second(Failure.KeyManagement.KeyNotFound("No public key found for $userId"))
val rawAuthenticatorData = cryptoObjectsBuilder.generateAuthenticatorData(
Expand Down Expand Up @@ -114,7 +114,7 @@ internal class AuthenticatorManager(
clientExtensionResults = ClientExtensionResults,
authenticatorAttachment = "platform",
)
val verifyAuthData = webAuthnRepository.verify(verifyAuthenticationData)
val verifyAuthData = webAuthnRequests.verify(verifyAuthenticationData)
val apiToken = SharedApiToken(
accessToken = verifyAuthData.accessToken,
tokenType = verifyAuthData.tokenType,
Expand All @@ -129,7 +129,7 @@ internal class AuthenticatorManager(

if (passkeyId != null) {
// If we have a passkey for this account, revoke it against the backend and delete it
webAuthnRepository.deletePasskeyIfExists(token, passkeyId)
webAuthnRequests.deletePasskeyIfExists(token, passkeyId)
val _ = keyPairManager.deleteKeysMatching(MatchOn.PasskeyId(passkeyId))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import com.infomaniak.auth.lib.internal.otp.deleteLegacyDB
import com.infomaniak.auth.lib.internal.otp.getLegacyAccounts
import com.infomaniak.auth.lib.internal.otp.getSecretFor
import com.infomaniak.auth.lib.internal.otp.needMigration
import com.infomaniak.auth.lib.internal.repositories.WebAuthnRepository
import com.infomaniak.auth.lib.internal.requests.WebAuthnRequests
import com.infomaniak.auth.lib.models.migration.SharedApiToken
import com.infomaniak.auth.lib.models.migration.user.SharedUserProfile
import com.infomaniak.auth.lib.network.exceptions.ApiException
Expand All @@ -46,7 +46,7 @@ import kotlin.uuid.Uuid
internal class MigrationManager(
private val accountsDatabase: AccountsDatabase,
private val authenticatorManager: AuthenticatorManager,
private val webAuthnRepository: WebAuthnRepository,
private val webAuthnRequests: WebAuthnRequests,
private val clientId: String,
) {

Expand All @@ -65,7 +65,7 @@ internal class MigrationManager(
val restorer = AccountRestorer(
accountsDatabase = accountsDatabase,
authenticatorManager = authenticatorManager,
webAuthnRepository = webAuthnRepository,
webAuthnRequests = webAuthnRequests,
clientId = clientId
)
restorer.restore(account, persistToken)
Expand Down Expand Up @@ -93,7 +93,7 @@ internal class MigrationManager(
@OptIn(ExperimentalUuidApi::class)
val deviceId = Uuid.random().toHexDashString()
val secret = checkNotNull(getSecretFor(userId)) { "Couldn't find the secret for user $userId" }
val migrationOptions = webAuthnRepository.getMigrationOptions(
val migrationOptions = webAuthnRequests.getMigrationOptions(
deviceId = deviceId,
userId = userId,
)
Expand All @@ -110,7 +110,7 @@ internal class MigrationManager(
}

runCatching {
webAuthnRepository.getTokenForMigration(
webAuthnRequests.getTokenForMigration(
sessionId = migrationOptions.session,
otpPayload = OtpPayload(
deviceId = deviceId,
Expand Down Expand Up @@ -145,7 +145,7 @@ internal class MigrationManager(
}
persistUser(userProfile)

webAuthnRepository.completeMigration(
webAuthnRequests.completeMigration(
token = apiTokenFromPasskey.accessToken,
sessionId = migrationOptions.session,
deviceId = deviceId
Expand Down

This file was deleted.

Loading
Loading