From f97efea681424d8a3f301360cfb24cd930738d0e Mon Sep 17 00:00:00 2001 From: Leendert de Borst Date: Mon, 27 Oct 2025 10:28:52 +0100 Subject: [PATCH] Add backup rules for CredentialIdentityStore kotlin implementation (#520) --- .../android/app/src/main/AndroidManifest.xml | 2 +- .../CredentialIdentityStore.kt | 23 ++++++++++++++++++ .../app/src/main/res/xml/backup_rules.xml | 18 ++++++++++++++ .../main/res/xml/data_extraction_rules.xml | 24 +++++++++++++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 apps/mobile-app/android/app/src/main/res/xml/backup_rules.xml create mode 100644 apps/mobile-app/android/app/src/main/res/xml/data_extraction_rules.xml diff --git a/apps/mobile-app/android/app/src/main/AndroidManifest.xml b/apps/mobile-app/android/app/src/main/AndroidManifest.xml index 8d7910bac..98637ee82 100644 --- a/apps/mobile-app/android/app/src/main/AndroidManifest.xml +++ b/apps/mobile-app/android/app/src/main/AndroidManifest.xml @@ -12,7 +12,7 @@ - + diff --git a/apps/mobile-app/android/app/src/main/java/net/aliasvault/app/credentialprovider/CredentialIdentityStore.kt b/apps/mobile-app/android/app/src/main/java/net/aliasvault/app/credentialprovider/CredentialIdentityStore.kt index bd975d55d..df694568f 100644 --- a/apps/mobile-app/android/app/src/main/java/net/aliasvault/app/credentialprovider/CredentialIdentityStore.kt +++ b/apps/mobile-app/android/app/src/main/java/net/aliasvault/app/credentialprovider/CredentialIdentityStore.kt @@ -16,6 +16,12 @@ import org.json.JSONObject * This class stores passkey metadata (rpId, userName, displayName, credentialId, userHandle) * in SharedPreferences so that passkeys can be displayed without unlocking the vault. * + * Security features: + * - Uses MODE_PRIVATE for app-private storage (no other apps can access) + * - Excluded from device backups (see backup_rules.xml and data_extraction_rules.xml) + * - Contains no passwords, only metadata (usernames, rpIds, displayNames) + * - Cleared when credential provider is disabled by user + * * Similar to iOS ASCredentialIdentityStore, but using SharedPreferences as Android's * Credential Manager API doesn't provide a system-level identity store. */ @@ -41,6 +47,8 @@ class CredentialIdentityStore private constructor(context: Context) { } } + // MODE_PRIVATE ensures only this app can access the data + // Backup exclusion rules prevent data from being backed up private val prefs: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) /** @@ -154,6 +162,21 @@ class CredentialIdentityStore private constructor(context: Context) { .apply() } + /** + * Check if the credential identity store is empty. + * This is used to determine if initial sync is needed. + * @return true if the store has no credential identities + */ + fun isStoreEmpty(): Boolean { + return try { + val jsonString = prefs.getString(KEY_PASSKEY_IDENTITIES, null) + jsonString == null || JSONArray(jsonString).length() == 0 + } catch (e: Exception) { + Log.e(TAG, "Error checking if store is empty", e) + true // Assume empty if we can't read + } + } + /** * Create a PasskeyIdentity from a Passkey and its parent Credential. */ diff --git a/apps/mobile-app/android/app/src/main/res/xml/backup_rules.xml b/apps/mobile-app/android/app/src/main/res/xml/backup_rules.xml new file mode 100644 index 000000000..3b3bb8923 --- /dev/null +++ b/apps/mobile-app/android/app/src/main/res/xml/backup_rules.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/apps/mobile-app/android/app/src/main/res/xml/data_extraction_rules.xml b/apps/mobile-app/android/app/src/main/res/xml/data_extraction_rules.xml new file mode 100644 index 000000000..1fca8d9a5 --- /dev/null +++ b/apps/mobile-app/android/app/src/main/res/xml/data_extraction_rules.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + +