diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b6f0a3789..ecf951334 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -47,6 +47,7 @@ dependencies { implementation(projects.format.common) implementation(projects.passgen.diceware) implementation(projects.passgen.random) + implementation(projects.passkeys) implementation(projects.ui.compose) implementation(libs.androidx.activity) implementation(libs.androidx.activity.compose) diff --git a/passkeys/build.gradle.kts b/passkeys/build.gradle.kts index c2df2b859..7a69dadbb 100644 --- a/passkeys/build.gradle.kts +++ b/passkeys/build.gradle.kts @@ -7,15 +7,10 @@ plugins { id("com.github.android-password-store.android-library") id("com.github.android-password-store.kotlin-android") - id("com.github.android-password-store.psl-plugin") } android { - defaultConfig { - minSdk = 23 - consumerProguardFiles("consumer-rules.pro") - } - sourceSets { getByName("test") { resources.srcDir("src/main/assets") } } + buildFeatures { androidResources = true } namespace = "app.passwordstore.passkeys" } @@ -23,7 +18,6 @@ dependencies { implementation(libs.androidx.annotation) implementation(libs.androidx.core.ktx) implementation(libs.androidx.credentials) - implementation(libs.androidx.credentials.play.services) implementation(libs.kotlinx.coroutines.core) implementation(libs.thirdparty.logcat) testImplementation(libs.bundles.testDependencies) diff --git a/passkeys/lint-baseline.xml b/passkeys/lint-baseline.xml new file mode 100644 index 000000000..aa3bc042b --- /dev/null +++ b/passkeys/lint-baseline.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + diff --git a/passkeys/src/main/AndroidManifest.xml b/passkeys/src/main/AndroidManifest.xml index 7a44af6ed..0436b9035 100644 --- a/passkeys/src/main/AndroidManifest.xml +++ b/passkeys/src/main/AndroidManifest.xml @@ -1,12 +1,21 @@ - + - - - + + + + + + + + \ No newline at end of file diff --git a/passkeys/src/main/java/app/passwordstore/passkeys/APSCredentialProviderService.kt b/passkeys/src/main/java/app/passwordstore/passkeys/APSCredentialProviderService.kt new file mode 100644 index 000000000..b9711a404 --- /dev/null +++ b/passkeys/src/main/java/app/passwordstore/passkeys/APSCredentialProviderService.kt @@ -0,0 +1,103 @@ +package app.passwordstore.passkeys + +import android.app.PendingIntent +import android.content.Intent +import android.os.Build +import android.os.CancellationSignal +import android.os.OutcomeReceiver +import androidx.annotation.RequiresApi +import androidx.credentials.exceptions.ClearCredentialException +import androidx.credentials.exceptions.CreateCredentialException +import androidx.credentials.exceptions.CreateCredentialUnknownException +import androidx.credentials.exceptions.GetCredentialException +import androidx.credentials.provider.BeginCreateCredentialRequest +import androidx.credentials.provider.BeginCreateCredentialResponse +import androidx.credentials.provider.BeginCreatePublicKeyCredentialRequest +import androidx.credentials.provider.BeginGetCredentialRequest +import androidx.credentials.provider.BeginGetCredentialResponse +import androidx.credentials.provider.CreateEntry +import androidx.credentials.provider.CredentialProviderService +import androidx.credentials.provider.ProviderClearCredentialStateRequest + +@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) +public class APSCredentialProviderService : CredentialProviderService() { + + override fun onBeginCreateCredentialRequest( + request: BeginCreateCredentialRequest, + cancellationSignal: CancellationSignal, + callback: OutcomeReceiver, + ) { + val response: BeginCreateCredentialResponse? = processCreateCredentialRequest(request) + if (response != null) { + callback.onResult(response) + } else { + callback.onError(CreateCredentialUnknownException()) + } + } + + override fun onBeginGetCredentialRequest( + request: BeginGetCredentialRequest, + cancellationSignal: CancellationSignal, + callback: OutcomeReceiver + ) {} + + override fun onClearCredentialStateRequest( + request: ProviderClearCredentialStateRequest, + cancellationSignal: CancellationSignal, + callback: OutcomeReceiver, + ) {} + + private fun processCreateCredentialRequest( + request: BeginCreateCredentialRequest + ): BeginCreateCredentialResponse? { + return when (request) { + is BeginCreatePublicKeyCredentialRequest -> { + // Request is passkey type + handleCreatePasskeyQuery(request) + } + // Request not supported + else -> null + } + } + + private fun handleCreatePasskeyQuery( + @Suppress("UNUSED_PARAMETER") request: BeginCreatePublicKeyCredentialRequest + ): BeginCreateCredentialResponse { + val createEntries: MutableList = mutableListOf() + println(request.requestJson) + createEntries.add( + CreateEntry( + DEFAULT_ACCOUNT_NAME, + createNewPendingIntent(DEFAULT_ACCOUNT_NAME, CREATE_PASSKEY_INTENT_ACTION) + ) + ) + + return BeginCreateCredentialResponse(createEntries) + } + + private fun createNewPendingIntent(accountId: String, action: String): PendingIntent { + val intent = Intent(action).setPackage(packageName) + // Add your local account ID as an extra to the intent, so that when + // user selects this entry, the credential can be saved to this + // account + intent.putExtra(EXTRA_KEY_ACCOUNT_ID, accountId) + + return PendingIntent.getActivity( + applicationContext, + REQUEST_CODE, + intent, + (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT), + ) + } + + internal companion object { + + // These intent actions are specified for corresponding activities + // that are to be invoked through the PendingIntent(s) + const val REQUEST_CODE = 1010101 + const val EXTRA_KEY_ACCOUNT_ID = "EXTRA_KEY_ACCOUNT_ID" + const val DEFAULT_ACCOUNT_NAME = "Default Password Store" + const val CREATE_PASSKEY_INTENT_ACTION = "app.passwordstore.CREATE_PASSKEY" + const val GET_PASSKEY_INTENT_ACTION = "PACKAGE_NAME.GET_PASSKEY" + } +} diff --git a/passkeys/src/main/res/drawable/ic_launcher_background.xml b/passkeys/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 140f82946..000000000 --- a/passkeys/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/passkeys/src/main/res/drawable/ic_launcher_foreground.xml b/passkeys/src/main/res/drawable/ic_launcher_foreground.xml deleted file mode 100644 index 5c3bfcd6c..000000000 --- a/passkeys/src/main/res/drawable/ic_launcher_foreground.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/passkeys/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/passkeys/src/main/res/mipmap-anydpi-v26/ic_launcher.xml deleted file mode 100644 index 5ad9ce157..000000000 --- a/passkeys/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/passkeys/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/passkeys/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index 5ad9ce157..000000000 --- a/passkeys/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/passkeys/src/main/res/mipmap-hdpi/ic_launcher.webp b/passkeys/src/main/res/mipmap-hdpi/ic_launcher.webp deleted file mode 100644 index c209e78ec..000000000 Binary files a/passkeys/src/main/res/mipmap-hdpi/ic_launcher.webp and /dev/null differ diff --git a/passkeys/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/passkeys/src/main/res/mipmap-hdpi/ic_launcher_round.webp deleted file mode 100644 index b2dfe3d1b..000000000 Binary files a/passkeys/src/main/res/mipmap-hdpi/ic_launcher_round.webp and /dev/null differ diff --git a/passkeys/src/main/res/mipmap-mdpi/ic_launcher.webp b/passkeys/src/main/res/mipmap-mdpi/ic_launcher.webp deleted file mode 100644 index 4f0f1d64e..000000000 Binary files a/passkeys/src/main/res/mipmap-mdpi/ic_launcher.webp and /dev/null differ diff --git a/passkeys/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/passkeys/src/main/res/mipmap-mdpi/ic_launcher_round.webp deleted file mode 100644 index 62b611da0..000000000 Binary files a/passkeys/src/main/res/mipmap-mdpi/ic_launcher_round.webp and /dev/null differ diff --git a/passkeys/src/main/res/mipmap-xhdpi/ic_launcher.webp b/passkeys/src/main/res/mipmap-xhdpi/ic_launcher.webp deleted file mode 100644 index 948a3070f..000000000 Binary files a/passkeys/src/main/res/mipmap-xhdpi/ic_launcher.webp and /dev/null differ diff --git a/passkeys/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/passkeys/src/main/res/mipmap-xhdpi/ic_launcher_round.webp deleted file mode 100644 index 1b9a6956b..000000000 Binary files a/passkeys/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/passkeys/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/passkeys/src/main/res/mipmap-xxhdpi/ic_launcher.webp deleted file mode 100644 index 28d4b77f9..000000000 Binary files a/passkeys/src/main/res/mipmap-xxhdpi/ic_launcher.webp and /dev/null differ diff --git a/passkeys/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/passkeys/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp deleted file mode 100644 index 9287f5083..000000000 Binary files a/passkeys/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/passkeys/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/passkeys/src/main/res/mipmap-xxxhdpi/ic_launcher.webp deleted file mode 100644 index aa7d6427e..000000000 Binary files a/passkeys/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and /dev/null differ diff --git a/passkeys/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/passkeys/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp deleted file mode 100644 index 9126ae37c..000000000 Binary files a/passkeys/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/passkeys/src/main/res/values-night/themes.xml b/passkeys/src/main/res/values-night/themes.xml deleted file mode 100644 index f0a927fb0..000000000 --- a/passkeys/src/main/res/values-night/themes.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - \ No newline at end of file diff --git a/passkeys/src/main/res/values/colors.xml b/passkeys/src/main/res/values/colors.xml deleted file mode 100644 index 09837df62..000000000 --- a/passkeys/src/main/res/values/colors.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - #FFBB86FC - #FF6200EE - #FF3700B3 - #FF03DAC5 - #FF018786 - #FF000000 - #FFFFFFFF - \ No newline at end of file diff --git a/passkeys/src/main/res/values/strings.xml b/passkeys/src/main/res/values/strings.xml deleted file mode 100644 index 485ed0280..000000000 --- a/passkeys/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - passkeys - \ No newline at end of file diff --git a/passkeys/src/main/res/values/themes.xml b/passkeys/src/main/res/values/themes.xml deleted file mode 100644 index 4210ce7de..000000000 --- a/passkeys/src/main/res/values/themes.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - \ No newline at end of file diff --git a/passkeys/src/main/res/xml/provider.xml b/passkeys/src/main/res/xml/provider.xml new file mode 100644 index 000000000..99d41c9b5 --- /dev/null +++ b/passkeys/src/main/res/xml/provider.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file