Files
basedbank/app/src/main/java/sh/sar/basedbank/BasedBankApp.kt
Shihaam Abdul Rahman 6d48c27391
All checks were successful
Auto Tag on Version Change / check-version (push) Successful in 4s
huge refactor.. might need to revert later
2026-05-20 22:43:29 +05:00

121 lines
5.5 KiB
Kotlin

package sh.sar.basedbank
import android.app.Application
import androidx.appcompat.app.AppCompatDelegate
import com.google.android.material.color.DynamicColors
import kotlinx.coroutines.sync.Mutex
import sh.sar.basedbank.api.bml.BmlLoginFlow
import sh.sar.basedbank.api.bml.BmlProfile
import sh.sar.basedbank.api.bml.BmlSession
import sh.sar.basedbank.api.fahipay.FahipaySession
import sh.sar.basedbank.api.models.BankAccount
import sh.sar.basedbank.api.mib.MibLoginFlow
import sh.sar.basedbank.api.mib.MibProfile
import sh.sar.basedbank.api.mib.MibSession
import sh.sar.basedbank.util.CredentialStore
class BasedBankApp : Application() {
// Held in memory after successful login; cleared on logout
var accounts: List<BankAccount> = emptyList()
var fullName: String = ""
/** Active MIB sessions keyed by loginId (= MIB username). */
val mibSessions: MutableMap<String, MibSession> = mutableMapOf()
val mibProfilesMap: MutableMap<String, List<MibProfile>> = mutableMapOf()
val mibLoginFlows: MutableMap<String, MibLoginFlow> = mutableMapOf()
var mibAccounts: List<BankAccount> = emptyList()
/**
* Active BML sessions keyed by profileId (a globally unique GUID per BML profile).
* Use [bmlSessionFor] to look up the session for an account.
*/
val bmlSessions: MutableMap<String, BmlSession> = mutableMapOf()
/** BML profiles per loginId (= BML username). */
val bmlProfilesMap: MutableMap<String, List<BmlProfile>> = mutableMapOf()
/** BML login flows per loginId — hold the web session (cookies) needed for profile activation. */
val bmlLoginFlows: MutableMap<String, BmlLoginFlow> = mutableMapOf()
var bmlAccounts: List<BankAccount> = emptyList()
/** Active Fahipay sessions keyed by loginId (= profileId). */
val fahipaySessions: MutableMap<String, FahipaySession> = mutableMapOf()
var fahipayAccounts: List<BankAccount> = emptyList()
// ─── MIB helpers ──────────────────────────────────────────────────────────
/** Returns the MIB session for the given account (matched via loginTag). */
fun mibSessionFor(account: BankAccount): MibSession? =
mibSessions[account.loginTag.removePrefix("mib_")]
/** Returns any available MIB session. */
fun anyMibSession(): MibSession? = mibSessions.values.firstOrNull()
/** Returns all MIB profiles across all logins. */
fun allMibProfiles(): List<MibProfile> = mibProfilesMap.values.flatten()
/** Returns the MibLoginFlow for a given loginId, creating and caching it if needed. */
fun mibFlowFor(loginId: String): MibLoginFlow =
mibLoginFlows.getOrPut(loginId) {
MibLoginFlow(CredentialStore(this)).also { flow ->
flow.onSessionRefreshed = { session, profiles ->
mibSessions[loginId] = session
mibProfilesMap[loginId] = profiles
}
}
}
/** Returns any available MibLoginFlow. */
fun anyMibFlow(): MibLoginFlow? = mibLoginFlows.values.firstOrNull()
// ─── BML helpers ──────────────────────────────────────────────────────────
/**
* Returns the BML session for the given account.
* Looks up by profileId first (multi-profile), falls back to loginId (legacy single-profile).
*/
fun bmlSessionFor(account: BankAccount): BmlSession? {
val byProfile = if (account.profileId.isNotBlank()) bmlSessions[account.profileId] else null
return byProfile ?: bmlSessions[account.loginTag.removePrefix("bml_")]
}
/** Returns any available BML session (for non-account-specific operations). */
fun anyBmlSession(): BmlSession? = bmlSessions.values.firstOrNull()
/**
* Returns any active BML session for the given loginId.
* Tries all profiles for that login; falls back to legacy loginId key.
*/
fun anyBmlSessionFor(loginId: String): BmlSession? {
val profiles = bmlProfilesMap[loginId]
if (!profiles.isNullOrEmpty()) {
return profiles.firstNotNullOfOrNull { bmlSessions[it.profileId] }
}
return bmlSessions[loginId]
}
/** Returns the BmlLoginFlow for a given loginId, creating and caching it if needed. */
fun bmlFlowFor(loginId: String): BmlLoginFlow =
bmlLoginFlows.getOrPut(loginId) { BmlLoginFlow() }
// ─── Fahipay helpers ──────────────────────────────────────────────────────
/** Returns the Fahipay session for the given account (matched via loginTag = "fahipay_${profileId}"). */
fun fahipaySessionFor(account: BankAccount): FahipaySession? =
fahipaySessions[account.loginTag.removePrefix("fahipay_")]
/** Serialises all MIB profile-switch + request sequences to prevent session corruption. */
val mibMutex = Mutex()
override fun onCreate() {
super.onCreate()
DynamicColors.applyToActivitiesIfAvailable(this)
val theme = getSharedPreferences("prefs", MODE_PRIVATE).getString("theme", "system")
AppCompatDelegate.setDefaultNightMode(when (theme) {
"dark" -> AppCompatDelegate.MODE_NIGHT_YES
"light" -> AppCompatDelegate.MODE_NIGHT_NO
else -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
})
}
}