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