diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/DataStoreAccess.kt b/app/src/main/java/com/greenart7c3/nostrsigner/DataStoreAccess.kt index 74e4f778..6575f027 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/DataStoreAccess.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/DataStoreAccess.kt @@ -26,8 +26,21 @@ object DataStoreAccess { ) } + @Volatile + private var appDataStore: DataStore? = null + + private fun getAppDataStore(context: Context): DataStore = appDataStore ?: synchronized(this) { + appDataStore ?: PreferenceDataStoreFactory.create( + scope = Amber.instance.applicationIOScope, + produceFile = { + context.applicationContext.preferencesDataStoreFile("app_datastore") + }, + ).also { appDataStore = it } + } + val NOSTR_PRIVKEY = stringPreferencesKey("nostr_privkey") val SEED_WORDS = stringPreferencesKey("seed_words") + val PIN = stringPreferencesKey("pin") suspend fun saveEncryptedKey(context: Context, npub: String, key: Preferences.Key, value: String) { val encrypted = SecureCryptoHelper.encrypt(value) @@ -52,4 +65,20 @@ object DataStoreAccess { prefs.clear() } } + + suspend fun savePin(context: Context, pin: String?) { + getAppDataStore(context).edit { prefs -> + if (pin == null) { + prefs.remove(PIN) + } else { + prefs[PIN] = SecureCryptoHelper.encrypt(pin) + } + } + } + + suspend fun loadPin(context: Context): String? { + val prefs = getAppDataStore(context).data.first() + val encrypted = prefs[PIN] ?: return null + return SecureCryptoHelper.decrypt(encrypted) + } } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/LocalPreferences.kt b/app/src/main/java/com/greenart7c3/nostrsigner/LocalPreferences.kt index 58c48e4f..dc6cbc2f 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/LocalPreferences.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/LocalPreferences.kt @@ -159,20 +159,18 @@ object LocalPreferences { fun loadPinFromEncryptedStorage(): String? { val context = Amber.instance - return sharedPrefs(context).getString(SettingsKeys.PIN.key, null) + // Migration: move PIN from plain SharedPreferences to encrypted DataStore + val legacyPin = sharedPrefs(context).getString(SettingsKeys.PIN.key, null) + if (legacyPin != null) { + runBlocking { DataStoreAccess.savePin(context, legacyPin) } + sharedPrefs(context).edit { remove(SettingsKeys.PIN.key) } + } + return runBlocking { DataStoreAccess.loadPin(context) } } fun savePinToEncryptedStorage(pin: String?) { val context = Amber.instance - sharedPrefs(context).edit { - apply { - if (pin == null) { - remove(SettingsKeys.PIN.key) - } else { - putString(SettingsKeys.PIN.key, pin) - } - } - } + runBlocking { DataStoreAccess.savePin(context, pin) } } suspend fun reloadApp() {