fahipay serialized multi-login added
Auto Tag on Version Change / check-version (push) Successful in 4s
Auto Tag on Version Change / check-version (push) Successful in 4s
This commit is contained in:
@@ -9,9 +9,8 @@ object AccountCache {
|
||||
|
||||
private const val PREFS = "account_cache"
|
||||
private const val KEY_MIB = "mib_accounts"
|
||||
private const val KEY_FAHIPAY = "fahipay_accounts"
|
||||
|
||||
private fun bmlKey(loginId: String) = "bml_accounts_$loginId"
|
||||
private fun fahipayKey(loginId: String) = "fahipay_accounts_$loginId"
|
||||
|
||||
fun save(context: Context, accounts: List<MibAccount>) {
|
||||
val arr = JSONArray()
|
||||
@@ -93,7 +92,7 @@ object AccountCache {
|
||||
fun loadBml(context: Context, loginIds: List<String>): List<MibAccount> =
|
||||
loginIds.flatMap { loadBml(context, it) }
|
||||
|
||||
fun saveFahipay(context: Context, accounts: List<MibAccount>) {
|
||||
fun saveFahipay(context: Context, loginId: String, accounts: List<MibAccount>) {
|
||||
val arr = JSONArray()
|
||||
for (acc in accounts) {
|
||||
arr.put(JSONObject().apply {
|
||||
@@ -113,12 +112,12 @@ object AccountCache {
|
||||
})
|
||||
}
|
||||
context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
|
||||
.edit().putString(KEY_FAHIPAY, CacheEncryption.encrypt(arr.toString())).apply()
|
||||
.edit().putString(fahipayKey(loginId), CacheEncryption.encrypt(arr.toString())).apply()
|
||||
}
|
||||
|
||||
fun loadFahipay(context: Context): List<MibAccount> {
|
||||
fun loadFahipay(context: Context, loginId: String): List<MibAccount> {
|
||||
val raw = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
|
||||
.getString(KEY_FAHIPAY, null) ?: return emptyList()
|
||||
.getString(fahipayKey(loginId), null) ?: return emptyList()
|
||||
return try {
|
||||
val arr = JSONArray(CacheEncryption.decrypt(raw))
|
||||
(0 until arr.length()).map { i ->
|
||||
@@ -144,6 +143,9 @@ object AccountCache {
|
||||
} catch (_: Exception) { emptyList() }
|
||||
}
|
||||
|
||||
fun loadFahipay(context: Context, loginIds: List<String>): List<MibAccount> =
|
||||
loginIds.flatMap { loadFahipay(context, it) }
|
||||
|
||||
fun clear(context: Context) {
|
||||
context.getSharedPreferences(PREFS, Context.MODE_PRIVATE).edit().clear().apply()
|
||||
}
|
||||
|
||||
@@ -25,11 +25,14 @@ object ContactManager {
|
||||
}
|
||||
|
||||
private fun deleteMib(contact: ContactDisplay, app: BasedBankApp): Boolean {
|
||||
val sess = app.mibSession ?: return false
|
||||
val sess = app.anyMibSession() ?: return false
|
||||
return try {
|
||||
if (contact.profileId.isNotBlank()) {
|
||||
val profile = app.mibProfiles.firstOrNull { it.profileId == contact.profileId }
|
||||
if (profile != null) app.mibLoginFlow.switchProfile(sess, profile)
|
||||
val (loginId, profile) = app.mibProfilesMap.entries
|
||||
.firstNotNullOfOrNull { (id, profiles) ->
|
||||
profiles.firstOrNull { it.profileId == contact.profileId }?.let { id to it }
|
||||
} ?: (null to null)
|
||||
if (profile != null && loginId != null) app.mibFlowFor(loginId).switchProfile(sess, profile)
|
||||
}
|
||||
MibContactsClient().deleteContact(sess, contact.id)
|
||||
} catch (_: Exception) { false }
|
||||
|
||||
@@ -21,75 +21,131 @@ class CredentialStore(context: Context) {
|
||||
data class BmlCredentials(val username: String, val password: String, val otpSeed: String)
|
||||
data class FahipayCredentials(val idCard: String, val password: String)
|
||||
|
||||
// ── MIB login credentials ─────────────────────────────────────────────────
|
||||
// ── MIB login credentials (multi-login, keyed by loginId = username) ─────
|
||||
|
||||
fun hasMibCredentials(): Boolean = prefs.contains("mib_enc_username")
|
||||
fun hasFahipayCredentials(): Boolean = prefs.contains("fahipay_enc_id_card")
|
||||
fun getMibLoginIds(): List<String> {
|
||||
maybeMigrateLegacyMib()
|
||||
val json = prefs.getString("mib_login_ids", null) ?: return emptyList()
|
||||
return try {
|
||||
val arr = org.json.JSONArray(json)
|
||||
(0 until arr.length()).map { arr.getString(it) }
|
||||
} catch (_: Exception) { emptyList() }
|
||||
}
|
||||
|
||||
fun saveMibCredentials(username: String, passwordHash: String, otpSeed: String) {
|
||||
fun hasMibCredentials(): Boolean = getMibLoginIds().isNotEmpty()
|
||||
|
||||
private fun addMibLoginId(loginId: String) {
|
||||
val ids = getMibLoginIds().toMutableList()
|
||||
if (loginId !in ids) {
|
||||
ids.add(loginId)
|
||||
prefs.edit().putString("mib_login_ids", org.json.JSONArray(ids).toString()).apply()
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeMibLoginId(loginId: String) {
|
||||
val ids = getMibLoginIds().toMutableList()
|
||||
if (ids.remove(loginId))
|
||||
prefs.edit().putString("mib_login_ids", org.json.JSONArray(ids).toString()).apply()
|
||||
}
|
||||
|
||||
fun saveMibCredentials(loginId: String, username: String, passwordHash: String, otpSeed: String) {
|
||||
addMibLoginId(loginId)
|
||||
val key = getOrCreateKey()
|
||||
prefs.edit()
|
||||
.putString("mib_enc_username", encrypt(username, key))
|
||||
.putString("mib_enc_password_hash", encrypt(passwordHash, key))
|
||||
.putString("mib_enc_otp_seed", encrypt(otpSeed, key))
|
||||
.putString("mib_${loginId}_enc_password_hash", encrypt(passwordHash, key))
|
||||
.putString("mib_${loginId}_enc_otp_seed", encrypt(otpSeed, key))
|
||||
.apply()
|
||||
}
|
||||
|
||||
fun loadMibCredentials(): MibCredentials? {
|
||||
fun loadMibCredentials(loginId: String): MibCredentials? {
|
||||
val key = getOrCreateKey()
|
||||
val encUsername = prefs.getString("mib_enc_username", null) ?: return null
|
||||
val encHash = prefs.getString("mib_enc_password_hash", null) ?: return null
|
||||
val encSeed = prefs.getString("mib_enc_otp_seed", null) ?: return null
|
||||
val encHash = prefs.getString("mib_${loginId}_enc_password_hash", null) ?: return null
|
||||
val encSeed = prefs.getString("mib_${loginId}_enc_otp_seed", null) ?: return null
|
||||
return try {
|
||||
MibCredentials(
|
||||
decrypt(encUsername, key),
|
||||
decrypt(encHash, key),
|
||||
decrypt(encSeed, key)
|
||||
)
|
||||
MibCredentials(loginId, decrypt(encHash, key), decrypt(encSeed, key))
|
||||
} catch (_: Exception) { null }
|
||||
}
|
||||
|
||||
fun clearMibCredentials() {
|
||||
fun clearMibCredentials(loginId: String) {
|
||||
removeMibLoginId(loginId)
|
||||
prefs.edit()
|
||||
.remove("mib_enc_username")
|
||||
.remove("mib_enc_password_hash")
|
||||
.remove("mib_enc_otp_seed")
|
||||
.remove("mib_enc_key1")
|
||||
.remove("mib_enc_key2")
|
||||
.remove("mib_enc_app_id")
|
||||
.remove("mib_${loginId}_enc_password_hash")
|
||||
.remove("mib_${loginId}_enc_otp_seed")
|
||||
.remove("mib_${loginId}_enc_key1")
|
||||
.remove("mib_${loginId}_enc_key2")
|
||||
.remove("mib_${loginId}_enc_app_id")
|
||||
.remove("mib_${loginId}_all_profiles")
|
||||
.remove("mib_${loginId}_enc_profile")
|
||||
.remove("mib_${loginId}_enc_full_name")
|
||||
.remove("mib_${loginId}_hidden_profile_ids")
|
||||
.apply()
|
||||
}
|
||||
|
||||
// ── MIB session keys (key1/key2) and app ID ───────────────────────────────
|
||||
// ── MIB session keys (key1/key2) and app ID (per loginId) ────────────────
|
||||
|
||||
fun saveMibKeys(key1: String, key2: String) {
|
||||
fun saveMibKeys(loginId: String, key1: String, key2: String) {
|
||||
val key = getOrCreateKey()
|
||||
prefs.edit()
|
||||
.putString("mib_enc_key1", encrypt(key1, key))
|
||||
.putString("mib_enc_key2", encrypt(key2, key))
|
||||
.putString("mib_${loginId}_enc_key1", encrypt(key1, key))
|
||||
.putString("mib_${loginId}_enc_key2", encrypt(key2, key))
|
||||
.apply()
|
||||
}
|
||||
|
||||
fun loadMibKeys(): Pair<String, String>? {
|
||||
fun loadMibKeys(loginId: String): Pair<String, String>? {
|
||||
val key = getOrCreateKey()
|
||||
val encKey1 = prefs.getString("mib_enc_key1", null) ?: return null
|
||||
val encKey2 = prefs.getString("mib_enc_key2", null) ?: return null
|
||||
val encKey1 = prefs.getString("mib_${loginId}_enc_key1", null) ?: return null
|
||||
val encKey2 = prefs.getString("mib_${loginId}_enc_key2", null) ?: return null
|
||||
return try {
|
||||
Pair(decrypt(encKey1, key), decrypt(encKey2, key))
|
||||
} catch (_: Exception) { null }
|
||||
}
|
||||
|
||||
fun saveMibAppId(id: String) {
|
||||
fun saveMibAppId(loginId: String, id: String) {
|
||||
val key = getOrCreateKey()
|
||||
prefs.edit().putString("mib_enc_app_id", encrypt(id, key)).apply()
|
||||
prefs.edit().putString("mib_${loginId}_enc_app_id", encrypt(id, key)).apply()
|
||||
}
|
||||
|
||||
fun loadMibAppId(): String? {
|
||||
fun loadMibAppId(loginId: String): String? {
|
||||
val key = getOrCreateKey()
|
||||
val enc = prefs.getString("mib_enc_app_id", null) ?: return null
|
||||
val enc = prefs.getString("mib_${loginId}_enc_app_id", null) ?: return null
|
||||
return try { decrypt(enc, key) } catch (_: Exception) { null }
|
||||
}
|
||||
|
||||
/** One-time migration: if old single-login MIB data exists, move it to per-loginId storage. */
|
||||
private var migrationChecked = false
|
||||
private fun maybeMigrateLegacyMib() {
|
||||
if (migrationChecked) return
|
||||
migrationChecked = true
|
||||
if (prefs.contains("mib_login_ids")) return // already migrated
|
||||
val encUsername = prefs.getString("mib_enc_username", null) ?: return
|
||||
val key = try { getOrCreateKey() } catch (_: Exception) { return }
|
||||
val loginId = try { decrypt(encUsername, key) } catch (_: Exception) { return }
|
||||
val editor = prefs.edit()
|
||||
// Migrate credentials
|
||||
prefs.getString("mib_enc_password_hash", null)?.let { editor.putString("mib_${loginId}_enc_password_hash", it) }
|
||||
prefs.getString("mib_enc_otp_seed", null)?.let { editor.putString("mib_${loginId}_enc_otp_seed", it) }
|
||||
prefs.getString("mib_enc_key1", null)?.let { editor.putString("mib_${loginId}_enc_key1", it) }
|
||||
prefs.getString("mib_enc_key2", null)?.let { editor.putString("mib_${loginId}_enc_key2", it) }
|
||||
prefs.getString("mib_enc_app_id", null)?.let { editor.putString("mib_${loginId}_enc_app_id", it) }
|
||||
prefs.getString("mib_all_profiles", null)?.let { editor.putString("mib_${loginId}_all_profiles", it) }
|
||||
prefs.getString("mib_enc_profile", null)?.let { editor.putString("mib_${loginId}_enc_profile", it) }
|
||||
prefs.getString("mib_enc_full_name", null)?.let { editor.putString("mib_${loginId}_enc_full_name", it) }
|
||||
prefs.getStringSet("mib_hidden_profile_ids", null)?.let { editor.putStringSet("mib_${loginId}_hidden_profile_ids", it) }
|
||||
// Register the login ID and clear legacy keys
|
||||
editor.putString("mib_login_ids", org.json.JSONArray(listOf(loginId)).toString())
|
||||
editor.remove("mib_enc_username")
|
||||
editor.remove("mib_enc_password_hash")
|
||||
editor.remove("mib_enc_otp_seed")
|
||||
editor.remove("mib_enc_key1")
|
||||
editor.remove("mib_enc_key2")
|
||||
editor.remove("mib_enc_app_id")
|
||||
editor.remove("mib_all_profiles")
|
||||
editor.remove("mib_enc_profile")
|
||||
editor.remove("mib_enc_full_name")
|
||||
editor.remove("mib_hidden_profile_ids")
|
||||
editor.apply()
|
||||
}
|
||||
|
||||
// ── BML login credentials (multi-login, keyed by loginId = username) ────────
|
||||
|
||||
fun getBmlLoginIds(): List<String> {
|
||||
@@ -171,58 +227,81 @@ class CredentialStore(context: Context) {
|
||||
.apply()
|
||||
}
|
||||
|
||||
// ── Fahipay login credentials ─────────────────────────────────────────────
|
||||
// ── Fahipay login credentials (multi-login, keyed by loginId = profileId) ──
|
||||
|
||||
fun saveFahipayCredentials(idCard: String, password: String) {
|
||||
fun getFahipayLoginIds(): List<String> {
|
||||
maybeMigrateLegacyFahipay()
|
||||
val json = prefs.getString("fahipay_login_ids", null) ?: return emptyList()
|
||||
return try {
|
||||
val arr = org.json.JSONArray(json)
|
||||
(0 until arr.length()).map { arr.getString(it) }
|
||||
} catch (_: Exception) { emptyList() }
|
||||
}
|
||||
|
||||
fun hasFahipayCredentials(): Boolean = getFahipayLoginIds().isNotEmpty()
|
||||
|
||||
private fun addFahipayLoginId(loginId: String) {
|
||||
val ids = getFahipayLoginIds().toMutableList()
|
||||
if (loginId !in ids) {
|
||||
ids.add(loginId)
|
||||
prefs.edit().putString("fahipay_login_ids", org.json.JSONArray(ids).toString()).apply()
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeFahipayLoginId(loginId: String) {
|
||||
val ids = getFahipayLoginIds().toMutableList()
|
||||
if (ids.remove(loginId))
|
||||
prefs.edit().putString("fahipay_login_ids", org.json.JSONArray(ids).toString()).apply()
|
||||
}
|
||||
|
||||
fun saveFahipayCredentials(loginId: String, idCard: String, password: String) {
|
||||
addFahipayLoginId(loginId)
|
||||
val key = getOrCreateKey()
|
||||
prefs.edit()
|
||||
.putString("fahipay_enc_id_card", encrypt(idCard, key))
|
||||
.putString("fahipay_enc_password", encrypt(password, key))
|
||||
.putString("fahipay_${loginId}_enc_id_card", encrypt(idCard, key))
|
||||
.putString("fahipay_${loginId}_enc_password", encrypt(password, key))
|
||||
.apply()
|
||||
}
|
||||
|
||||
fun loadFahipayCredentials(): FahipayCredentials? {
|
||||
fun loadFahipayCredentials(loginId: String): FahipayCredentials? {
|
||||
val key = getOrCreateKey()
|
||||
val encId = prefs.getString("fahipay_enc_id_card", null) ?: return null
|
||||
val encPw = prefs.getString("fahipay_enc_password", null) ?: return null
|
||||
val encId = prefs.getString("fahipay_${loginId}_enc_id_card", null) ?: return null
|
||||
val encPw = prefs.getString("fahipay_${loginId}_enc_password", null) ?: return null
|
||||
return try {
|
||||
FahipayCredentials(decrypt(encId, key), decrypt(encPw, key))
|
||||
} catch (_: Exception) { null }
|
||||
}
|
||||
|
||||
fun clearFahipayCredentials() {
|
||||
fun clearFahipayCredentials(loginId: String) {
|
||||
removeFahipayLoginId(loginId)
|
||||
prefs.edit()
|
||||
.remove("fahipay_enc_id_card")
|
||||
.remove("fahipay_enc_password")
|
||||
.remove("fahipay_${loginId}_enc_id_card")
|
||||
.remove("fahipay_${loginId}_enc_password")
|
||||
.remove("fahipay_${loginId}_enc_auth_id")
|
||||
.remove("fahipay_${loginId}_enc_session_cookie")
|
||||
.remove("fahipay_${loginId}_enc_profile")
|
||||
.apply()
|
||||
}
|
||||
|
||||
// ── Fahipay session (authId + __Secure-sess cookie) ───────────────────────
|
||||
// ── Fahipay session (authId + __Secure-sess cookie) (per loginId) ─────────
|
||||
|
||||
fun saveFahipaySession(authId: String, sessionCookie: String) {
|
||||
fun saveFahipaySession(loginId: String, authId: String, sessionCookie: String) {
|
||||
val key = getOrCreateKey()
|
||||
prefs.edit()
|
||||
.putString("fahipay_enc_auth_id", encrypt(authId, key))
|
||||
.putString("fahipay_enc_session_cookie", encrypt(sessionCookie, key))
|
||||
.putString("fahipay_${loginId}_enc_auth_id", encrypt(authId, key))
|
||||
.putString("fahipay_${loginId}_enc_session_cookie", encrypt(sessionCookie, key))
|
||||
.apply()
|
||||
}
|
||||
|
||||
fun loadFahipaySession(): Pair<String, String>? {
|
||||
fun loadFahipaySession(loginId: String): Pair<String, String>? {
|
||||
val key = getOrCreateKey()
|
||||
val encAuth = prefs.getString("fahipay_enc_auth_id", null) ?: return null
|
||||
val encCookie = prefs.getString("fahipay_enc_session_cookie", null) ?: return null
|
||||
val encAuth = prefs.getString("fahipay_${loginId}_enc_auth_id", null) ?: return null
|
||||
val encCookie = prefs.getString("fahipay_${loginId}_enc_session_cookie", null) ?: return null
|
||||
return try {
|
||||
Pair(decrypt(encAuth, key), decrypt(encCookie, key))
|
||||
} catch (_: Exception) { null }
|
||||
}
|
||||
|
||||
fun clearFahipaySession() {
|
||||
prefs.edit()
|
||||
.remove("fahipay_enc_auth_id")
|
||||
.remove("fahipay_enc_session_cookie")
|
||||
.apply()
|
||||
}
|
||||
|
||||
// ── Fahipay device UUID (generated once, shared across all Fahipay accounts) ─
|
||||
|
||||
fun getOrCreateFahipayDeviceUuid(): String {
|
||||
@@ -236,7 +315,7 @@ class CredentialStore(context: Context) {
|
||||
return uuid
|
||||
}
|
||||
|
||||
// ── Fahipay user profile ──────────────────────────────────────────────────
|
||||
// ── Fahipay user profile (per loginId) ────────────────────────────────────
|
||||
|
||||
data class FahipayUserProfile(
|
||||
val fullName: String,
|
||||
@@ -248,7 +327,7 @@ class CredentialStore(context: Context) {
|
||||
val linkedAccounts: String
|
||||
)
|
||||
|
||||
fun saveFahipayUserProfile(p: FahipayUserProfile) {
|
||||
fun saveFahipayUserProfile(loginId: String, p: FahipayUserProfile) {
|
||||
val json = org.json.JSONObject().apply {
|
||||
put("fullName", p.fullName)
|
||||
put("email", p.email)
|
||||
@@ -259,12 +338,12 @@ class CredentialStore(context: Context) {
|
||||
put("linkedAccounts", p.linkedAccounts)
|
||||
}.toString()
|
||||
val key = getOrCreateKey()
|
||||
prefs.edit().putString("fahipay_enc_profile", encrypt(json, key)).apply()
|
||||
prefs.edit().putString("fahipay_${loginId}_enc_profile", encrypt(json, key)).apply()
|
||||
}
|
||||
|
||||
fun loadFahipayUserProfile(): FahipayUserProfile? {
|
||||
fun loadFahipayUserProfile(loginId: String): FahipayUserProfile? {
|
||||
val key = getOrCreateKey()
|
||||
val enc = prefs.getString("fahipay_enc_profile", null) ?: return null
|
||||
val enc = prefs.getString("fahipay_${loginId}_enc_profile", null) ?: return null
|
||||
return try {
|
||||
val o = org.json.JSONObject(decrypt(enc, key))
|
||||
FahipayUserProfile(
|
||||
@@ -279,6 +358,33 @@ class CredentialStore(context: Context) {
|
||||
} catch (_: Exception) { null }
|
||||
}
|
||||
|
||||
/** One-time migration: if old single-login Fahipay data exists, move it to per-loginId storage. */
|
||||
private var fahipayMigrationChecked = false
|
||||
private fun maybeMigrateLegacyFahipay() {
|
||||
if (fahipayMigrationChecked) return
|
||||
fahipayMigrationChecked = true
|
||||
if (prefs.contains("fahipay_login_ids")) return // already migrated
|
||||
val encProfile = prefs.getString("fahipay_enc_profile", null) ?: return
|
||||
val key = try { getOrCreateKey() } catch (_: Exception) { return }
|
||||
val loginId = try {
|
||||
val o = org.json.JSONObject(decrypt(encProfile, key))
|
||||
o.optString("profileId").takeIf { it.isNotBlank() }
|
||||
} catch (_: Exception) { null } ?: return
|
||||
val editor = prefs.edit()
|
||||
prefs.getString("fahipay_enc_id_card", null)?.let { editor.putString("fahipay_${loginId}_enc_id_card", it) }
|
||||
prefs.getString("fahipay_enc_password", null)?.let { editor.putString("fahipay_${loginId}_enc_password", it) }
|
||||
prefs.getString("fahipay_enc_auth_id", null)?.let { editor.putString("fahipay_${loginId}_enc_auth_id", it) }
|
||||
prefs.getString("fahipay_enc_session_cookie", null)?.let { editor.putString("fahipay_${loginId}_enc_session_cookie", it) }
|
||||
editor.putString("fahipay_${loginId}_enc_profile", encProfile)
|
||||
editor.putString("fahipay_login_ids", org.json.JSONArray(listOf(loginId)).toString())
|
||||
editor.remove("fahipay_enc_id_card")
|
||||
editor.remove("fahipay_enc_password")
|
||||
editor.remove("fahipay_enc_auth_id")
|
||||
editor.remove("fahipay_enc_session_cookie")
|
||||
editor.remove("fahipay_enc_profile")
|
||||
editor.apply()
|
||||
}
|
||||
|
||||
// ── Security credential (PIN / pattern hash) ──────────────────────────────
|
||||
|
||||
/**
|
||||
@@ -329,9 +435,9 @@ class CredentialStore(context: Context) {
|
||||
val birthdate: String
|
||||
)
|
||||
|
||||
// ── MIB operating profiles (all profiles, regardless of visibility) ───────
|
||||
// ── MIB operating profiles (per loginId) ─────────────────────────────────
|
||||
|
||||
fun saveMibProfiles(profiles: List<sh.sar.basedbank.api.mib.MibProfile>) {
|
||||
fun saveMibProfiles(loginId: String, profiles: List<sh.sar.basedbank.api.mib.MibProfile>) {
|
||||
val arr = org.json.JSONArray()
|
||||
for (p in profiles) {
|
||||
arr.put(org.json.JSONObject().apply {
|
||||
@@ -342,11 +448,11 @@ class CredentialStore(context: Context) {
|
||||
put("color", p.color)
|
||||
})
|
||||
}
|
||||
prefs.edit().putString("mib_all_profiles", arr.toString()).apply()
|
||||
prefs.edit().putString("mib_${loginId}_all_profiles", arr.toString()).apply()
|
||||
}
|
||||
|
||||
fun loadMibProfiles(): List<sh.sar.basedbank.api.mib.MibProfile> {
|
||||
val raw = prefs.getString("mib_all_profiles", null) ?: return emptyList()
|
||||
fun loadMibProfiles(loginId: String): List<sh.sar.basedbank.api.mib.MibProfile> {
|
||||
val raw = prefs.getString("mib_${loginId}_all_profiles", null) ?: return emptyList()
|
||||
return try {
|
||||
val arr = org.json.JSONArray(raw)
|
||||
(0 until arr.length()).map { i ->
|
||||
@@ -366,19 +472,18 @@ class CredentialStore(context: Context) {
|
||||
} catch (_: Exception) { emptyList() }
|
||||
}
|
||||
|
||||
fun saveMibFullName(name: String) {
|
||||
fun saveMibFullName(loginId: String, name: String) {
|
||||
val key = getOrCreateKey()
|
||||
prefs.edit().putString("mib_enc_full_name", encrypt(name, key)).apply()
|
||||
prefs.edit().putString("mib_${loginId}_enc_full_name", encrypt(name, key)).apply()
|
||||
}
|
||||
|
||||
fun loadMibFullName(): String? {
|
||||
fun loadMibFullName(loginId: String): String? {
|
||||
val key = getOrCreateKey()
|
||||
val enc = prefs.getString("mib_enc_full_name", null) ?: return null
|
||||
val enc = prefs.getString("mib_${loginId}_enc_full_name", null) ?: return null
|
||||
return try { decrypt(enc, key) } catch (_: Exception) { null }
|
||||
}
|
||||
|
||||
|
||||
fun saveMibUserProfile(p: MibUserProfile) {
|
||||
fun saveMibUserProfile(loginId: String, p: MibUserProfile) {
|
||||
val json = JSONObject().apply {
|
||||
put("fullName", p.fullName)
|
||||
put("username", p.username)
|
||||
@@ -387,14 +492,13 @@ class CredentialStore(context: Context) {
|
||||
put("enrolled", p.enrolled)
|
||||
}.toString()
|
||||
val key = getOrCreateKey()
|
||||
prefs.edit().putString("mib_enc_profile", encrypt(json, key)).apply()
|
||||
// Keep the name in sync with the fast-path field
|
||||
prefs.edit().putString("mib_enc_full_name", encrypt(p.fullName, key)).apply()
|
||||
prefs.edit().putString("mib_${loginId}_enc_profile", encrypt(json, key)).apply()
|
||||
prefs.edit().putString("mib_${loginId}_enc_full_name", encrypt(p.fullName, key)).apply()
|
||||
}
|
||||
|
||||
fun loadMibUserProfile(): MibUserProfile? {
|
||||
fun loadMibUserProfile(loginId: String): MibUserProfile? {
|
||||
val key = getOrCreateKey()
|
||||
val enc = prefs.getString("mib_enc_profile", null) ?: return null
|
||||
val enc = prefs.getString("mib_${loginId}_enc_profile", null) ?: return null
|
||||
return try {
|
||||
val o = JSONObject(decrypt(enc, key))
|
||||
MibUserProfile(
|
||||
@@ -436,14 +540,14 @@ class CredentialStore(context: Context) {
|
||||
} catch (_: Exception) { null }
|
||||
}
|
||||
|
||||
// ── MIB profile visibility ────────────────────────────────────────────────
|
||||
// ── MIB profile visibility (per loginId) ─────────────────────────────────
|
||||
|
||||
/** Returns the set of MIB profile IDs the user has chosen to hide from the app. */
|
||||
fun getHiddenMibProfileIds(): Set<String> =
|
||||
prefs.getStringSet("mib_hidden_profile_ids", emptySet()) ?: emptySet()
|
||||
/** Returns the set of MIB profile IDs the user has chosen to hide (for a given loginId). */
|
||||
fun getHiddenMibProfileIds(loginId: String): Set<String> =
|
||||
prefs.getStringSet("mib_${loginId}_hidden_profile_ids", emptySet()) ?: emptySet()
|
||||
|
||||
fun setHiddenMibProfileIds(ids: Set<String>) =
|
||||
prefs.edit().putStringSet("mib_hidden_profile_ids", ids).apply()
|
||||
fun setHiddenMibProfileIds(loginId: String, ids: Set<String>) =
|
||||
prefs.edit().putStringSet("mib_${loginId}_hidden_profile_ids", ids).apply()
|
||||
|
||||
// ── Crypto primitives ─────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ class HistoryFetcher(private val account: MibAccount) {
|
||||
}
|
||||
|
||||
private fun fetchFahipay(app: BasedBankApp): List<Transaction> {
|
||||
val session = app.fahipaySession ?: return emptyList()
|
||||
val session = app.fahipaySessionFor(account) ?: return emptyList()
|
||||
val flow = FahipayLoginFlow()
|
||||
flow.setSessionCookie(session.sessionCookie)
|
||||
val (list, total) = flow.fetchHistory(
|
||||
@@ -69,9 +69,11 @@ class HistoryFetcher(private val account: MibAccount) {
|
||||
}
|
||||
|
||||
private fun fetchMib(app: BasedBankApp, pageSize: Int): List<Transaction> {
|
||||
val session = app.mibSession ?: return emptyList()
|
||||
val profile = app.mibProfiles.firstOrNull { it.profileId == account.profileId }
|
||||
if (profile != null) app.mibLoginFlow.switchProfile(session, profile)
|
||||
val loginId = account.loginTag.removePrefix("mib_")
|
||||
val session = app.mibSessions[loginId] ?: return emptyList()
|
||||
val profiles = app.mibProfilesMap[loginId] ?: emptyList()
|
||||
val profile = profiles.firstOrNull { it.profileId == account.profileId }
|
||||
if (profile != null) app.mibFlowFor(loginId).switchProfile(session, profile)
|
||||
val (list, total) = MibHistoryClient().fetchHistory(
|
||||
session = session,
|
||||
accountNo = account.accountNumber,
|
||||
|
||||
Reference in New Issue
Block a user