From 570e6b750bc9a0d246cca698fa82c0f17d910a94 Mon Sep 17 00:00:00 2001 From: Shihaam Abdul Rahman Date: Wed, 10 Jun 2026 13:34:26 +0500 Subject: [PATCH] rever commit/4b1c2419 but keeping contact picker fix --- .../basedbank/api/mib/MibContactsClient.kt | 2 +- .../sh/sar/basedbank/api/mib/MibLoginFlow.kt | 22 +------ .../sh/sar/basedbank/ui/home/HomeActivity.kt | 66 +------------------ .../sh/sar/basedbank/util/CredentialStore.kt | 32 --------- 4 files changed, 6 insertions(+), 116 deletions(-) diff --git a/app/src/main/java/sh/sar/basedbank/api/mib/MibContactsClient.kt b/app/src/main/java/sh/sar/basedbank/api/mib/MibContactsClient.kt index dc0f9a0..d685eb1 100644 --- a/app/src/main/java/sh/sar/basedbank/api/mib/MibContactsClient.kt +++ b/app/src/main/java/sh/sar/basedbank/api/mib/MibContactsClient.kt @@ -19,7 +19,7 @@ class MibContactsClient { private fun cookieHeader(session: MibSession) = "mbmodel=IOS-1.0; xxid=${session.xxid}; IBSID=${session.xxid}; " + - "mbnonce=${MibNonce.generate(session.nonceGenerator)}; time-tracker=597" + "mbnonce=${session.nonceGenerator}; time-tracker=597" private fun Request.Builder.withSessionHeaders(session: MibSession): Request.Builder = this .header("Cookie", cookieHeader(session)) diff --git a/app/src/main/java/sh/sar/basedbank/api/mib/MibLoginFlow.kt b/app/src/main/java/sh/sar/basedbank/api/mib/MibLoginFlow.kt index 429c392..4979253 100644 --- a/app/src/main/java/sh/sar/basedbank/api/mib/MibLoginFlow.kt +++ b/app/src/main/java/sh/sar/basedbank/api/mib/MibLoginFlow.kt @@ -52,18 +52,6 @@ class MibLoginFlow(private val credentialStore: CredentialStore) { // ─── Public entry point ─────────────────────────────────────────────────── - /** - * Restores a previously persisted session without any network call. Sets the session and - * stored credentials so that doRequest() can do an automatic re-login on 419 if needed. - */ - fun restoreSession(session: MibSession, username: String, passwordHash: String, otpSeed: String) { - loginId = username - storedUsername = username - storedPasswordHash = passwordHash - storedOtpSeed = otpSeed - lastSession = session - } - /** * Full login flow. Automatically handles first-time device registration * vs. subsequent logins using stored key1/key2. @@ -257,14 +245,10 @@ class MibLoginFlow(private val credentialStore: CredentialStore) { "" // fall through to recovery below } - // Detect expired session: HTTP 419 (empty response), reasonCode 505, or digestFail - // (digestFail / reasonCode 501 means the nonce is invalid for this session — happens - // when a persisted session is loaded after the server has already expired it) + // Detect expired session: HTTP 419 (empty response) or JSON with reasonCode 505 val isExpired = response.isEmpty() || - (response.trimStart().startsWith("{") && run { - val obj = JSONObject(response) - obj.optString("reasonCode") == "505" || obj.optBoolean("digestFail", false) - }) + (response.trimStart().startsWith("{") && + JSONObject(response).optString("reasonCode") == "505") if (isExpired && inRelogin.compareAndSet(false, true)) { try { diff --git a/app/src/main/java/sh/sar/basedbank/ui/home/HomeActivity.kt b/app/src/main/java/sh/sar/basedbank/ui/home/HomeActivity.kt index 409689c..f21729d 100644 --- a/app/src/main/java/sh/sar/basedbank/ui/home/HomeActivity.kt +++ b/app/src/main/java/sh/sar/basedbank/ui/home/HomeActivity.kt @@ -734,75 +734,13 @@ fun applyNavLabelVisibility() { val mibJobs = mibLoginIds.mapNotNull { loginId -> val creds = store.loadMibCredentials(loginId) ?: return@mapNotNull null loginId to async(Dispatchers.IO) { - val app = application as BasedBankApp - - // Prefer in-memory session; fall back to persisted session on restart. - var existingSession = app.mibSessions[loginId] - var existingFlow = app.mibLoginFlows[loginId] - val cachedProfiles = app.mibProfilesMap[loginId]?.takeIf { it.isNotEmpty() } - ?: store.loadMibProfiles(loginId) - - if (existingSession == null) { - val persisted = store.loadMibSession(loginId) - if (persisted != null && cachedProfiles.isNotEmpty()) { - val flow = MibLoginFlow(CredentialStore(this@HomeActivity)) - flow.restoreSession(persisted, creds.username, creds.passwordHash, creds.otpSeed) - existingSession = persisted - existingFlow = flow - app.mibSessions[loginId] = persisted - app.mibLoginFlows[loginId] = flow - app.mibProfilesMap[loginId] = cachedProfiles - } - } - - // Try the existing session first — avoids a full re-login on every refresh. - // doRequest() inside fetchAllProfiles() handles 419 (session expired) by - // automatically re-logging in and retrying, so this is safe to call directly. - if (existingSession != null && existingFlow != null && cachedProfiles.isNotEmpty()) { - existingFlow.onSessionRefreshed = { newSession, newProfiles -> - app.mibSessions[loginId] = newSession - app.mibProfilesMap[loginId] = newProfiles - store.saveMibSession(loginId, newSession) - store.saveMibProfiles(loginId, newProfiles) - } - try { - val visibleProfiles = cachedProfiles.filterVisibleProfiles(loginId) - val accounts = existingFlow.fetchAllProfiles(existingSession, visibleProfiles, "mib_${creds.username}") - val freshSession = existingFlow.lastSession ?: existingSession - app.mibSessions[loginId] = freshSession - store.saveMibSession(loginId, freshSession) - if (existingFlow.lastProfiles.isNotEmpty()) { - app.mibProfilesMap[loginId] = existingFlow.lastProfiles - store.saveMibProfiles(loginId, existingFlow.lastProfiles) - } - AccountCache.save(this@HomeActivity, accounts) - return@async accounts - } catch (e: java.io.IOException) { - refreshErrors.add("NO_INTERNET") - return@async AccountCache.load(this@HomeActivity).filter { it.loginTag == "mib_$loginId" } - } catch (e: BankServerException) { - refreshErrors.add("SERVER:${e.bankName}") - return@async AccountCache.load(this@HomeActivity).filter { it.loginTag == "mib_$loginId" } - } catch (_: Exception) { - // Session completely unrecoverable — fall through to full re-login - } - } - - // Full re-login: first start with no persisted session, or unrecoverable above try { val flow = MibLoginFlow(CredentialStore(this@HomeActivity)) - flow.onSessionRefreshed = { newSession, newProfiles -> - app.mibSessions[loginId] = newSession - app.mibProfilesMap[loginId] = newProfiles - store.saveMibSession(loginId, newSession) - store.saveMibProfiles(loginId, newProfiles) - } val accounts = flow.login(creds.username, creds.passwordHash, creds.otpSeed) - val newSession = flow.lastSession!! - app.mibSessions[loginId] = newSession + val app = application as BasedBankApp + app.mibSessions[loginId] = flow.lastSession!! app.mibProfilesMap[loginId] = flow.lastProfiles app.mibLoginFlows[loginId] = flow - store.saveMibSession(loginId, newSession) store.saveMibProfiles(loginId, flow.lastProfiles) accounts } catch (e: java.io.IOException) { diff --git a/app/src/main/java/sh/sar/basedbank/util/CredentialStore.kt b/app/src/main/java/sh/sar/basedbank/util/CredentialStore.kt index 85417c8..095c07e 100644 --- a/app/src/main/java/sh/sar/basedbank/util/CredentialStore.kt +++ b/app/src/main/java/sh/sar/basedbank/util/CredentialStore.kt @@ -79,41 +79,9 @@ class CredentialStore(context: Context) { .remove("mib_${loginId}_enc_profile") .remove("mib_${loginId}_enc_full_name") .remove("mib_${loginId}_hidden_profile_ids") - .remove("mib_${loginId}_enc_session") .apply() } - // ── MIB active session (xxid + sessionKey + nonceGenerator) ───────────────── - - fun saveMibSession(loginId: String, session: sh.sar.basedbank.api.mib.MibSession) { - val json = JSONObject().apply { - put("xxid", session.xxid) - put("sessionKey", session.sessionKey) - put("nonceGenerator", session.nonceGenerator) - put("appId", session.appId) - }.toString() - val key = getOrCreateKey() - prefs.edit().putString("mib_${loginId}_enc_session", encrypt(json, key)).apply() - } - - fun loadMibSession(loginId: String): sh.sar.basedbank.api.mib.MibSession? { - val key = getOrCreateKey() - val enc = prefs.getString("mib_${loginId}_enc_session", null) ?: return null - return try { - val o = JSONObject(decrypt(enc, key)) - sh.sar.basedbank.api.mib.MibSession( - appId = o.getString("appId"), - xxid = o.getString("xxid"), - nonceGenerator = o.getString("nonceGenerator"), - sessionKey = o.getString("sessionKey") - ) - } catch (_: Exception) { null } - } - - fun clearMibSession(loginId: String) { - prefs.edit().remove("mib_${loginId}_enc_session").apply() - } - // ── MIB session keys (key1/key2) and app ID (per loginId) ──────────────── fun saveMibKeys(loginId: String, key1: String, key2: String) {