Skip to content

Commit fa4e4a7

Browse files
authored
fix(auth): Update exception handling for devices that don't support passkeys (#3044)
1 parent ed8389b commit fa4e4a7

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

aws-auth-cognito/src/main/java/com/amplifyframework/auth/cognito/exceptions/webauthn/WebAuthnNotSupportedException.kt

+7-2
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,19 @@ package com.amplifyframework.auth.cognito.exceptions.webauthn
1717

1818
/**
1919
* Exception that is thrown because WebAuthn is not supported on the device. This indicates that either the device
20-
* did not ship with WebAuthn support, or that your application is missing a required dependency or service.
20+
* is too old or it did not ship with WebAuthn support, or that your application is missing a required dependency
21+
* or service.
2122
*/
2223
class WebAuthnNotSupportedException internal constructor(
2324
message: String,
2425
cause: Throwable? = null
2526
) : WebAuthnFailedException(
2627
message = message,
27-
recoverySuggestion = TODO_RECOVERY_SUGGESTION,
28+
recoverySuggestion = if (cause != null) {
29+
RECOVERY_SUGGESTION_WITH_THROWABLE
30+
} else {
31+
TODO_RECOVERY_SUGGESTION
32+
},
2833
cause = cause
2934
) {
3035
internal constructor(

aws-auth-cognito/src/main/java/com/amplifyframework/auth/cognito/helpers/WebAuthnHelper.kt

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import androidx.credentials.exceptions.GetCredentialUnsupportedException
3636
import androidx.credentials.exceptions.domerrors.DataError
3737
import androidx.credentials.exceptions.domerrors.InvalidStateError
3838
import androidx.credentials.exceptions.domerrors.NotAllowedError
39+
import androidx.credentials.exceptions.domerrors.NotSupportedError
3940
import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
4041
import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialException
4142
import androidx.credentials.exceptions.publickeycredential.GetPublicKeyCredentialDomException
@@ -123,6 +124,7 @@ internal class WebAuthnHelper(
123124
is NotAllowedError -> userCancelledException()
124125
is InvalidStateError -> alreadyExists()
125126
is DataError -> rpMismatch()
127+
is NotSupportedError -> notSupported()
126128
else -> unknownException()
127129
}
128130
}
@@ -137,6 +139,7 @@ internal class WebAuthnHelper(
137139
when (this.domError) {
138140
is NotAllowedError -> userCancelledException()
139141
is DataError -> rpMismatch()
142+
is NotSupportedError -> notSupported()
140143
else -> unknownException()
141144
}
142145
}

aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/helpers/WebAuthnHelperTest.kt

+36
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,18 @@ package com.amplifyframework.auth.cognito.helpers
1717

1818
import android.app.Activity
1919
import android.content.Context
20+
import androidx.credentials.CreatePublicKeyCredentialRequest
2021
import androidx.credentials.CreatePublicKeyCredentialResponse
2122
import androidx.credentials.CredentialManager
2223
import androidx.credentials.GetCredentialRequest
2324
import androidx.credentials.GetCredentialResponse
2425
import androidx.credentials.PublicKeyCredential
26+
import androidx.credentials.exceptions.domerrors.NotSupportedError
27+
import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
28+
import androidx.credentials.exceptions.publickeycredential.GetPublicKeyCredentialDomException
29+
import com.amplifyframework.auth.cognito.exceptions.webauthn.WebAuthnNotSupportedException
30+
import io.kotest.assertions.throwables.shouldThrow
31+
import io.kotest.assertions.throwables.shouldThrowWithMessage
2532
import io.kotest.matchers.shouldBe
2633
import io.mockk.coEvery
2734
import io.mockk.coVerify
@@ -31,6 +38,7 @@ import kotlinx.coroutines.test.runTest
3138
import org.junit.Test
3239
import org.junit.runner.RunWith
3340
import org.robolectric.RobolectricTestRunner
41+
import org.robolectric.annotation.Config
3442

3543
@RunWith(RobolectricTestRunner::class)
3644
class WebAuthnHelperTest {
@@ -72,9 +80,37 @@ class WebAuthnHelperTest {
7280
}
7381
}
7482

83+
@Test
84+
fun `throws WebAuthnNotSupportedException for NotSupported error for get`() = runTest {
85+
coEvery { credentialManager.getCredential(any(), any<GetCredentialRequest>()) } throws
86+
GetPublicKeyCredentialDomException(NotSupportedError())
87+
88+
shouldThrow<WebAuthnNotSupportedException> {
89+
helper.getCredential(requestJson, mockk())
90+
}
91+
}
92+
7593
@Test
7694
fun `creates credential`() = runTest {
7795
val result = helper.createCredential(requestJson, mockk())
7896
result shouldBe responseJson
7997
}
98+
99+
@Test
100+
fun `throws WebAuthnNotSupportedException for NotSupported error for create`() = runTest {
101+
coEvery { credentialManager.createCredential(any(), any<CreatePublicKeyCredentialRequest>()) } throws
102+
CreatePublicKeyCredentialDomException(NotSupportedError())
103+
104+
shouldThrow<WebAuthnNotSupportedException> {
105+
helper.createCredential(requestJson, mockk())
106+
}
107+
}
108+
109+
@Config(sdk = [27])
110+
@Test
111+
fun `throws WebAuthnNotSupportedException for devices below API 28`() = runTest {
112+
shouldThrowWithMessage<WebAuthnNotSupportedException>("Passkeys are only supported on API 28 and above") {
113+
helper.createCredential(requestJson, mockk())
114+
}
115+
}
80116
}

0 commit comments

Comments
 (0)