From 86e1e66a20324556efd1c6ed69dcb956191055ca Mon Sep 17 00:00:00 2001 From: Shihaam Abdul Rahman Date: Sat, 30 May 2026 19:33:15 +0500 Subject: [PATCH] update docs --- docs/bmlapi/13-qr-payment.md | 4 +- docs/ooredooapi/01-number-validation.md | 38 ++-- docs/thijooree/00-app-overview.md | 143 ++++++++++++++ docs/thijooree/01-onboarding.md | 83 +++++++++ docs/thijooree/02-lock-screen.md | 82 ++++++++ docs/thijooree/03-login.md | 96 ++++++++++ docs/thijooree/04-accounts.md | 68 +++++++ docs/thijooree/05-account-history.md | 72 +++++++ docs/thijooree/06-transfer-history.md | 55 ++++++ docs/thijooree/07-transfer.md | 106 +++++++++++ docs/thijooree/08-contacts.md | 80 ++++++++ docs/thijooree/09-activities.md | 65 +++++++ docs/thijooree/10-otp-screen.md | 62 ++++++ docs/thijooree/11-paymv-qr-screen.md | 66 +++++++ docs/thijooree/12-bml-qr-pay.md | 87 +++++++++ docs/thijooree/13-financing.md | 62 ++++++ docs/thijooree/14-settings.md | 71 +++++++ docs/thijooree/15-settings-security.md | 59 ++++++ docs/thijooree/16-settings-appearance.md | 86 +++++++++ docs/thijooree/17-settings-storage.md | 59 ++++++ docs/thijooree/18-paymv-qr-format.md | 176 ++++++++++++++++++ docs/thijooree/{PARSERS.md => 19-parsers.md} | 6 + ...transfer-flows.md => 20-transfer-flows.md} | 2 +- docs/thijooree/AI_SECURITY_CHECK.md | 6 + docs/thijooree/README.md | 30 ++- 25 files changed, 1646 insertions(+), 18 deletions(-) create mode 100644 docs/thijooree/00-app-overview.md create mode 100644 docs/thijooree/01-onboarding.md create mode 100644 docs/thijooree/02-lock-screen.md create mode 100644 docs/thijooree/03-login.md create mode 100644 docs/thijooree/04-accounts.md create mode 100644 docs/thijooree/05-account-history.md create mode 100644 docs/thijooree/06-transfer-history.md create mode 100644 docs/thijooree/07-transfer.md create mode 100644 docs/thijooree/08-contacts.md create mode 100644 docs/thijooree/09-activities.md create mode 100644 docs/thijooree/10-otp-screen.md create mode 100644 docs/thijooree/11-paymv-qr-screen.md create mode 100644 docs/thijooree/12-bml-qr-pay.md create mode 100644 docs/thijooree/13-financing.md create mode 100644 docs/thijooree/14-settings.md create mode 100644 docs/thijooree/15-settings-security.md create mode 100644 docs/thijooree/16-settings-appearance.md create mode 100644 docs/thijooree/17-settings-storage.md create mode 100644 docs/thijooree/18-paymv-qr-format.md rename docs/thijooree/{PARSERS.md => 19-parsers.md} (97%) rename docs/thijooree/{01-transfer-flows.md => 20-transfer-flows.md} (99%) diff --git a/docs/bmlapi/13-qr-payment.md b/docs/bmlapi/13-qr-payment.md index 6558182..99ffc4c 100644 --- a/docs/bmlapi/13-qr-payment.md +++ b/docs/bmlapi/13-qr-payment.md @@ -43,7 +43,7 @@ PayMV QRs (static, PayMV-native) use a decimal TLV encoding (not BER-TLV): <2-digit decimal tag><2-digit decimal length>... ``` -### Root-level tags +### Root-level tags (key fields for scanning) | Tag | Field | |---|---| @@ -59,6 +59,8 @@ PayMV QRs (static, PayMV-native) use a decimal TLV encoding (not BER-TLV): | `26` | `03` | Account number | | `62` | `08` | Payment purpose / reference | +> For the full PayMV QR format spec including generation (receive-payment QRs), acquirer BIC mapping, CRC algorithm, and all tags — see [PayMV QR Format](../thijooree/18-paymv-qr-format.md). + --- ## Step 1 — Resolve QR to Merchant Details diff --git a/docs/ooredooapi/01-number-validation.md b/docs/ooredooapi/01-number-validation.md index c760083..663fb49 100644 --- a/docs/ooredooapi/01-number-validation.md +++ b/docs/ooredooapi/01-number-validation.md @@ -32,19 +32,23 @@ curl --request GET \ ## Responses +All responses wrap the result in a top-level `data` object. + ### Success — Prepaid ```json { - "custType": "PRE", - "msisdn": "9609654321" + "data": { + "custType": "PRE", + "msisdn": "9609654321" + } } ``` | Field | Type | Description | |---|---|---| -| `custType` | `string` | `"PRE"` = prepaid customer | -| `msisdn` | `string` | The MSISDN that was queried | +| `data.custType` | `string` | `"PRE"` = prepaid customer | +| `data.msisdn` | `string` | The MSISDN that was queried | → Offer **Raastas** top-up only. @@ -54,8 +58,10 @@ curl --request GET \ ```json { - "custType": "POST", - "msisdn": "9609123456" + "data": { + "custType": "POST", + "msisdn": "9609123456" + } } ``` @@ -67,8 +73,10 @@ curl --request GET \ ```json { - "custType": "HYBRID", - "msisdn": "9609789012" + "data": { + "custType": "HYBRID", + "msisdn": "9609789012" + } } ``` @@ -80,18 +88,20 @@ curl --request GET \ ```json { - "custType": null, - "errorMessage": "Data Not Found", - "msisdn": "9609000000" + "data": { + "custType": null, + "errorMessage": "Data Not Found", + "msisdn": "9609000000" + } } ``` | Field | Type | Description | |---|---|---| -| `custType` | `null` | Number is not an Ooredoo subscriber | -| `errorMessage` | `string` | `"Data Not Found"` | +| `data.custType` | `null` | Number is not an Ooredoo subscriber | +| `data.errorMessage` | `string` | `"Data Not Found"` | -Treat `custType: null` as unsupported — fall back to Dhiraagu lookup. +Treat `custType: null` or absent as unsupported — fall back to Dhiraagu lookup. --- diff --git a/docs/thijooree/00-app-overview.md b/docs/thijooree/00-app-overview.md new file mode 100644 index 0000000..ae60b12 --- /dev/null +++ b/docs/thijooree/00-app-overview.md @@ -0,0 +1,143 @@ +# App Overview + +Architecture overview of the app's entry point, main container, navigation system, and global session lifecycle. + +--- + +## Entry Point — `MainActivity` + +`MainActivity` is a transparent trampoline activity. On `onCreate` it reads app state and immediately forwards to the correct destination with no visible UI of its own: + +| Condition | Destination | +|---|---| +| Onboarding not done | `OnboardingActivity` | +| No saved credentials | `LoginActivity` | +| Security lock configured | `LockActivity` | +| All checks pass | `HomeActivity` | + +### Intent Actions + +External intents (from NFC, shortcuts, or notifications) are passed through to `HomeActivity` via the same forwarding intent: + +| Action | Effect | +|---|---| +| `OPEN_TRANSFER` | Opens transfer screen | +| `OPEN_SCAN_QR` | Opens QR scanner | +| `OPEN_PAY_WITH_CARD` | Opens BML card QR payment | +| `TAP_TO_PAY` | Opens BML tap-to-pay NFC flow | + +`BmlTapToPayActivity` is a dedicated NFC entry point registered in the manifest. It immediately re-fires a `TAP_TO_PAY` intent to `MainActivity` and finishes. + +--- + +## Main Container — `HomeActivity` + +`HomeActivity` is the persistent shell containing all in-app screens. It owns: + +- The `NavHostFragment` and `NavController` +- The `DrawerLayout` and `NavigationView` +- The `BottomNavigationView` +- The toolbar (lock icon + hide-amounts eye icon) +- The connectivity banner +- The autolock timer +- The MIB session keepAlive scheduler + +### Toolbar + +| Icon | Behavior | +|---|---| +| Lock icon | Immediately locks the app → `LockActivity` (animated with scale + alpha) | +| Eye icon | Toggles `hideAmounts` in `HomeViewModel`; all balance displays redact to `••••` | + +### Auto-refresh + +On launch and after unlock `HomeActivity.autoRefresh()` fires parallel login refresh calls for all banks with active sessions. Each bank runs independently — a failure in one bank does not block the others. + +### Connectivity Banner + +A persistent banner appears at the top of `HomeActivity` when network connectivity is lost. It disappears automatically when connectivity is restored. Per-bank connectivity errors (e.g., session expired) are surfaced via `HomeViewModel.connectivityErrors`. + +--- + +## Navigation Modes + +The user can choose between two navigation modes in Settings → Appearance: + +### Drawer (default) + +A slide-out navigation drawer containing up to 10 configurable nav items. The hamburger icon in the toolbar opens it. + +### Bottom Navigation + +A bottom bar with 3 configurable slots plus a fixed **Dashboard** tab (always leftmost) and a **More** tab (always rightmost). Tapping **More** opens `NavMoreSheetFragment` — a bottom sheet listing all items not assigned to the 3 visible slots. + +--- + +## Navigation Slots + +10 possible navigation destinations can be assigned to slots. The user reorders them via drag-and-drop in Settings → Appearance. + +| Destination | Default slot | +|---|---| +| Accounts | 1 | +| Transfer | 2 | +| Activities | 3 | +| Contacts | 4 | +| Financing | 5 | +| OTP | 6 | +| PayMV QR | 7 | +| BML QR Pay | 8 | +| Transfer History | 9 | +| Settings | 10 | + +Two **Quick Action** slots appear as FAB-style buttons on the dashboard and are independently configurable. + +--- + +## Autolock + +Autolock fires after a configurable period of user inactivity. Any touch event resets the timer. + +| Timeout option | +|---| +| 30 seconds | +| 1 minute | +| 3 minutes | +| 5 minutes | +| Never | + +When the timeout expires a 10-second countdown warning dialog appears. If dismissed, the timer resets. If ignored, the app calls `LockActivity` and clears `app.isUnlocked`. + +--- + +## Global State — `BasedBankApp` + +`BasedBankApp` holds all in-memory session data. Nothing is stored to disk except encrypted credentials. + +| Field | Description | +|---|---| +| `isUnlocked` | Set to `true` after successful lock-screen auth; guards against process-restart bypass | +| `mibSessions` | Map of MIB profile ID → active session (cookies + DH key) | +| `bmlSessions` | Map of BML profile ID → OAuth token pair | +| `fahipaySessions` | Map of Fahipay login ID → authID + session cookie | +| `mibLoginFlows` | Active `MibLoginFlow` instances per profile | +| `bmlLoginFlows` | Active `BmlLoginFlow` instances per profile | +| `mibMutex` | Coroutine mutex — serializes all MIB API calls to prevent session corruption | + +### Profile Visibility + +Each stored profile has a visibility flag. Hidden profiles are excluded from the accounts list and from all API refresh cycles until re-enabled in Settings → Logins. + +--- + +## MIB Session KeepAlive + +MIB web sessions expire after approximately 30 seconds of inactivity. `HomeActivity` schedules a coroutine that calls the MIB keepAlive endpoint every 25 seconds for each active MIB session while the app is in the foreground. + +--- + +  + +--- + +[← README](README.md)     **Next →** [Onboarding](01-onboarding.md) diff --git a/docs/thijooree/01-onboarding.md b/docs/thijooree/01-onboarding.md new file mode 100644 index 0000000..08937c3 --- /dev/null +++ b/docs/thijooree/01-onboarding.md @@ -0,0 +1,83 @@ +# Onboarding + +Shown once on first launch. Walks the user through language selection, security setup, and appearance configuration before creating any credentials. + +--- + +## Activity — `OnboardingActivity` + +`OnboardingActivity` hosts three sequential fragments managed by a `ViewPager2` with manual paging (swipe disabled). Progress dots are shown below the pager. + +Each fragment has a **Continue** button that is only enabled after the user satisfies a completion requirement. Scrolling to the bottom of a slide is required before Continue activates on content slides. + +--- + +## Slide 1 — Language & Welcome (`OnboardingFragment`) + +- Displays a welcome illustration and app name +- Language selector chip group (English / Dhivehi) +- Selecting a language immediately updates the app locale +- Continue button becomes active once a language is selected (or immediately if system locale is already supported) + +--- + +## Slide 2 — Security Setup (`SecuritySetupFragment`) + +The user chooses a lock method to protect the app. + +### Lock Methods + +| Method | Description | +|---|---| +| PIN | 4–8 digit numeric PIN | +| Pattern | Grid pattern draw (minimum 4 nodes) | + +### PIN Entry + +- Two `EditText` fields: PIN + confirm PIN +- Continue activates only when both fields match and length ≥ 4 + +### Pattern Entry + +- Custom `PatternView` widget +- Draws connecting lines between touched grid nodes in real time +- Two-phase: draw → confirm (must match first drawing) +- Continue activates after a valid matching pattern is confirmed + +### Key Derivation + +The chosen PIN or pattern string is hardened with **PBKDF2-HMAC-SHA256** (100 000 iterations, random 16-byte salt) before storage. The derived key is stored in encrypted `SharedPreferences` via `CredentialStore`. + +### Biometric Option + +After setting a PIN or pattern an optional **Enable Biometrics** toggle appears. If enabled, biometric authentication (fingerprint / face — `BIOMETRIC_WEAK`) can be used as an alternative to the PIN/pattern at the lock screen and optionally for transfer confirmation. + +--- + +## Slide 3 — Configure (`OnboardingConfigureFragment`) + +Appearance and navigation preferences, set before first login. + +### Options + +| Setting | Choices | +|---|---| +| Navigation mode | Drawer / Bottom Navigation | +| Theme | System default / Light / Dark | +| Accent colour | Chip selector (several Material colours) | + +All preferences are written to `CredentialStore` / `SharedPreferences` immediately on selection so that `HomeActivity` inherits them on first launch. + +--- + +## Completion + +When the user taps Continue on slide 3, `OnboardingActivity` sets the `onboardingDone` flag and finishes. `MainActivity` then routes to `LoginActivity` (no credentials yet) on the next launch or immediately via `startActivity`. + +--- + +  + +--- + +[← App Overview](00-app-overview.md)     **Next →** [Lock Screen](02-lock-screen.md) diff --git a/docs/thijooree/02-lock-screen.md b/docs/thijooree/02-lock-screen.md new file mode 100644 index 0000000..efaa871 --- /dev/null +++ b/docs/thijooree/02-lock-screen.md @@ -0,0 +1,82 @@ +# Lock Screen + +`LockActivity` is shown whenever the app is locked — on cold start (when credentials exist), after the autolock timer fires, or when the user taps the lock icon in the toolbar. + +--- + +## Authentication Methods + +The app attempts authentication in priority order: + +1. **Biometrics** — if enrolled and enabled, `BiometricPrompt` is presented automatically on open +2. **PIN** — numeric keypad +3. **Pattern** — `PatternView` grid + +The user can switch between biometric and PIN/pattern manually. + +--- + +## Biometric Authentication + +Uses Android `BiometricPrompt` with `BIOMETRIC_WEAK` (fingerprint or face depending on device). A successful biometric result sets `app.isUnlocked = true` and calls `MainActivity` to route to `HomeActivity`. + +On biometric failure or cancellation the screen falls back to PIN/pattern entry. + +--- + +## PIN Entry + +- A custom on-screen numeric keypad (0–9 + backspace + confirm) +- The entered digits are shown as filled/unfilled circles (no digit echo) +- Confirm fires verification immediately when the correct number of digits is entered + +--- + +## Pattern Entry + +- The same `PatternView` widget used in onboarding, in verify-only mode +- The drawn pattern is hashed and compared against the stored derived key + +--- + +## Verification + +The entered PIN or pattern is run through **PBKDF2-HMAC-SHA256** with the stored salt and compared to the stored hash. On match: + +1. `app.isUnlocked = true` +2. `LockActivity` finishes +3. `MainActivity` routes to `HomeActivity` + +On mismatch the attempt counter increments and an error shake animation plays. + +--- + +## Brute-Force Protection + +| Threshold | Behaviour | +|---|---| +| 1–4 wrong attempts | Error label shown, counter visible | +| 5 wrong attempts | 30-second lockout; keypad/pattern disabled | +| After lockout | Counter resets; user may try again | + +The attempt counter and lockout timestamp are stored in **plain** `SharedPreferences` (not encrypted) — a known limitation documented in the security audit. The app does not wipe credentials after repeated failures. + +--- + +## `app.isUnlocked` Guard + +`app.isUnlocked` is an in-memory flag that is `false` on every process start. Even if an attacker bypasses `LockActivity` via `adb`, `HomeActivity` checks this flag and re-fires `LockActivity` on resume if it is `false`. This prevents cold-start bypass. + +--- + +## Screenshot Protection + +`FLAG_SECURE` is set on `LockActivity`'s window, preventing screenshots and screen recording. This is always on for the lock screen regardless of the user's global screenshots setting. + +--- + +  + +--- + +[← Onboarding](01-onboarding.md)     **Next →** [Login](03-login.md) diff --git a/docs/thijooree/03-login.md b/docs/thijooree/03-login.md new file mode 100644 index 0000000..24b07e2 --- /dev/null +++ b/docs/thijooree/03-login.md @@ -0,0 +1,96 @@ +# Login + +`LoginActivity` handles adding bank accounts. It is shown on first launch (after onboarding) and also opened from Settings → Logins → Add Account. + +--- + +## Fragment Flow + +``` +LoginActivity + └─ BankSelectionFragment ← pick a bank + └─ CredentialsFragment ← enter credentials for that bank +``` + +--- + +## Bank Selection — `BankSelectionFragment` + +A scrollable list of supported banks presented as selectable cards: + +| Bank | Notes | +|---|---| +| MIB (Maldives Islamic Bank) | Username + password | +| BML (Bank of Maldives) | Username + password | +| Fahipay | Mobile number + password | + +Tapping a card navigates to `CredentialsFragment` with the selected bank pre-set. + +--- + +## Credentials — `CredentialsFragment` + +### MIB Login + +Fields: +- Username +- Password + +Flow on submit: +1. `MibLoginFlow.login()` — performs Diffie-Hellman key exchange, then authenticates with Blowfish/ECB-encrypted credentials +2. On success, fetches `operatingProfiles` — the list of CIF profiles (Individual, Sole Propr, etc.) +3. Each profile is stored as a `MibAccount` with `bank = "MIB"` and `cifType` from the API +4. Sessions are stored in `BasedBankApp.mibSessions` + +### BML Login + +Fields: +- Username (customer ID) +- Password + +Flow on submit: +1. `BmlLoginFlow.login()` — OAuth password grant → access token + refresh token +2. Fetches dashboard → list of CASA accounts + cards +3. Each account/card stored as `MibAccount` with `bank = "BML"` +4. Tokens stored in `BasedBankApp.bmlSessions` + +### Fahipay Login + +Fields: +- Mobile number (7-digit local, auto-prefixed with +960) +- Password + +Flow on submit: +1. `FahipayLoginFlow.login()` — authenticates against Fahipay API +2. On success, stores `authID` + `__Secure-sess` cookie +3. Single wallet account stored with `bank = "FAHIPAY"` + +--- + +## Multi-Profile Support + +Each MIB login can have multiple CIF profiles (e.g., an individual and a business account under the same username). Each profile appears as a separate entry in the accounts list and can be toggled independently in Settings → Logins. + +BML and Fahipay each yield a single profile per login. + +Adding the same bank login a second time merges its profiles into the existing login rather than creating a duplicate. + +--- + +## Credential Storage + +All credentials (username, password, tokens, session cookies) are encrypted via `CredentialStore`, which uses Android `EncryptedSharedPreferences` backed by a hardware-keystore key where available. + +--- + +## After Login + +`CredentialsFragment` calls `app.autoRefresh()` after a successful login, then navigates back to `LoginActivity`'s result which routes to `HomeActivity` (or back to Settings if called from there). + +--- + +  + +--- + +[← Lock Screen](02-lock-screen.md)     **Next →** [Accounts](04-accounts.md) diff --git a/docs/thijooree/04-accounts.md b/docs/thijooree/04-accounts.md new file mode 100644 index 0000000..f8b0ba6 --- /dev/null +++ b/docs/thijooree/04-accounts.md @@ -0,0 +1,68 @@ +# Accounts + +The accounts screen is typically the default home destination. It shows all active bank accounts and cards grouped by bank and profile. + +--- + +## Fragment — `AccountsFragment` + +Hosts a `RecyclerView` driven by `AccountsAdapter`. Observes `HomeViewModel.accounts` (a `LiveData>`). The list is filtered to only include accounts whose profile visibility flag is enabled. + +A **pull-to-refresh** gesture triggers `HomeActivity.autoRefresh()`, which re-fetches all bank dashboards in parallel. + +--- + +## List Structure — `AccountsAdapter` + +The adapter renders a mixed list of section headers and account rows. + +### Section Headers + +Accounts are grouped by bank + CIF type (for MIB) or bank name (for BML/Fahipay). Each group starts with a header row showing: +- Bank name and logo +- For MIB: `cifType` (e.g., `"Individual"`, `"Sole Propr"`) — never hardcoded, always from API +- Profile image (circular avatar, if set) + +### Account / Card Rows + +Each row is bound from an `AccountListDisplay` object produced by `AccountListParser.from(account)`. See [Account Parser Architecture](PARSERS.md) for mapping details. + +| Field | Row element | +|---|---| +| `name` | Account or card name | +| `number` | Masked account/card number | +| `typeLabel` | Product type chip (e.g., `"Savings"`, `"Visa Platinum"`) | +| `balance` | Balance string (hidden as `••••` when hide-amounts is active) | +| `isCard` | Switches between account layout and card layout | +| `cardBrandIcon` | Visa / Mastercard / Amex logo drawable | +| `statusLabel` | Shown as an amber chip if non-null (e.g., `"Inactive"`) | + +### Quick-Transfer Shortcut + +Each account row has a **Send** button. Tapping it opens `TransferFragment` with the source account pre-selected. + +--- + +## Account Tap — History + +Tapping any account row navigates to `AccountHistoryFragment` for that account. + +--- + +## Hide Amounts + +When the toolbar eye icon is toggled (or `HomeViewModel.hideAmounts` is `true`), all balance strings in the adapter are replaced with `"••••"` without re-fetching data. + +--- + +## Empty State + +If no accounts are loaded (either no credentials or all profiles hidden), the screen shows an empty-state illustration with a prompt to add an account. + +--- + +  + +--- + +[← Login](03-login.md)     **Next →** [Account History](05-account-history.md) diff --git a/docs/thijooree/05-account-history.md b/docs/thijooree/05-account-history.md new file mode 100644 index 0000000..9ed59a7 --- /dev/null +++ b/docs/thijooree/05-account-history.md @@ -0,0 +1,72 @@ +# Account History + +Displays the transaction history for a single account. Opened by tapping an account row in the accounts list. + +--- + +## Fragment — `AccountHistoryFragment` + +Receives the selected `MibAccount` via navigation arguments. + +--- + +## Data Loading + +On open, the fragment calls the appropriate bank API to fetch the first page of transactions: + +| Bank | API | +|---|---| +| MIB | MIB transaction history endpoint (Blowfish-encrypted) | +| BML | BML transaction history endpoint (OAuth Bearer) | +| Fahipay | Fahipay wallet transaction list | + +Results are mapped to a common display model and shown in a `RecyclerView`. + +--- + +## Infinite Scroll + +The list supports **infinite scroll** (pagination). When the user scrolls near the bottom of the loaded items, the next page is automatically fetched and appended. A loading spinner appears at the bottom while a page is in flight. + +Page state (current page, total pages) is tracked in the fragment's `ViewModel`. If the last page has been reached the spinner is hidden and no further requests are made. + +--- + +## Search / Filter + +A search bar at the top of the screen filters the loaded transaction list by: +- Description / narrative text +- Amount string + +Filtering is performed locally on already-loaded pages — it does not trigger a new API call. Clearing the search bar restores the full list. + +--- + +## Transaction Rows + +Each row shows: +- Transaction date and time +- Description / merchant name +- Debit or credit indicator +- Amount (hidden as `••••` when hide-amounts is active) +- Running balance (where available from the bank API) + +--- + +## Image Loading + +Some MIB transaction entries include merchant logo URLs. These are loaded asynchronously into the row's image view with a generic fallback icon. Images are cached in memory for the session. + +--- + +## Empty State + +If no transactions exist (new account or API returned empty list) an empty-state message is shown. + +--- + +  + +--- + +[← Accounts](04-accounts.md)     **Next →** [Transfer History](06-transfer-history.md) diff --git a/docs/thijooree/06-transfer-history.md b/docs/thijooree/06-transfer-history.md new file mode 100644 index 0000000..cf44f34 --- /dev/null +++ b/docs/thijooree/06-transfer-history.md @@ -0,0 +1,55 @@ +# Transfer History + +Shows a merged, chronologically sorted list of outgoing transfers across all connected bank accounts. + +--- + +## Fragment — `TransferHistoryFragment` + +Observes `HomeViewModel` for loaded account data and triggers parallel history fetches. + +--- + +## Data Loading + +On open, the fragment launches parallel coroutines — one per active bank session — to fetch transfer/payment history from each bank's API. Results arrive independently and are merged into a single sorted list as each bank completes. + +| Bank | Source | +|---|---| +| MIB | MIB transfer history endpoint | +| BML | BML payment history endpoint | +| Fahipay | Fahipay payment history | + +A per-bank loading indicator is shown while that bank's data is in flight. If one bank fails (session expired, network error) its section shows an error row rather than crashing the whole list. + +--- + +## List Display + +The merged list is sorted by date descending (newest first). Each row shows: + +- Bank logo / icon +- Recipient name or account number +- Date and time +- Amount (hidden as `••••` when hide-amounts is active) +- Transfer status (where available) + +--- + +## Pull-to-Refresh + +A pull-to-refresh gesture re-fires all parallel fetches and rebuilds the merged list. + +--- + +## Empty State + +If no transfers are found across any bank, an empty-state illustration is shown. + +--- + +  + +--- + +[← Account History](05-account-history.md)     **Next →** [Transfer](07-transfer.md) diff --git a/docs/thijooree/07-transfer.md b/docs/thijooree/07-transfer.md new file mode 100644 index 0000000..eef0070 --- /dev/null +++ b/docs/thijooree/07-transfer.md @@ -0,0 +1,106 @@ +# Transfer + +The transfer screen initiates account-to-account fund transfers. It supports MIB, BML, and Fahipay as source banks and handles all bank-specific authentication and OTP steps. + +--- + +## Fragment — `TransferFragment` + +Opened via: +- Navigation menu +- Quick-transfer button on an account row (source pre-selected) +- `OPEN_TRANSFER` intent action +- QR scan result (recipient and optional amount pre-filled) + +--- + +## Source Account Selection + +A dropdown lists all visible accounts parsed via `AccountListParser.from(acc)?.balance`. The selected source account determines which bank's transfer flow is used. + +--- + +## Recipient Entry + +The user can specify a recipient in three ways: + +1. **Manual entry** — type an account number directly +2. **Contact picker** — opens `ContactPickerSheetFragment` to select a saved contact +3. **QR scan** — opens the camera scanner; a PayMV QR result pre-fills the account number, amount, and remarks + +--- + +## Fields + +| Field | Notes | +|---|---| +| Source account | Dropdown; balance shown below | +| Recipient account number | Text input or filled from contact/QR | +| Recipient name | Auto-looked up from bank API after account number entry | +| Amount | Numeric; pre-filled from QR if available | +| Remarks / purpose | Free text; pre-filled from QR if available | + +--- + +## Recipient Lookup + +After the user finishes entering a recipient account number, the app calls the source bank's name-lookup API: + +- **MIB**: account name lookup via MIB API +- **BML**: beneficiary lookup via BML API +- **Fahipay**: account name resolution via Fahipay API + +The resolved name is displayed below the account number field for the user to confirm. + +--- + +## Biometric Gate + +If biometric-for-transfers is enabled in Settings → Security, `BiometricPrompt` is shown before the transfer is submitted. A failed or cancelled biometric blocks submission. + +--- + +## Bank-Specific Flows + +### MIB Transfer + +1. Validates fields +2. (If biometric gate) prompts biometrics +3. Submits transfer via `MibLoginFlow` using active MIB session (serialized through `mibMutex`) +4. On success, shows `TransferReceiptFragment` + +### BML Transfer + +1. Validates fields +2. (If biometric gate) prompts biometrics +3. Initiates BML transfer — server responds with OTP required +4. Navigates to `OtpFragment` to collect the TOTP +5. Re-submits with OTP +6. On success, shows `TransferReceiptFragment` + +### Fahipay Transfer + +1. Validates fields +2. (If biometric gate) prompts biometrics +3. Submits via Fahipay API using stored `authID` + session cookie +4. On success, shows `TransferReceiptFragment` + +--- + +## Transfer Receipt + +On success the fragment navigates to `TransferReceiptFragment` passing the completed transfer details. + +--- + +## Error Handling + +All bank API errors are shown as a `Snackbar` or inline error message. Session expiry triggers a re-authentication prompt rather than a crash. + +--- + +  + +--- + +[← Transfer History](06-transfer-history.md)     **Next →** [Contacts](08-contacts.md) diff --git a/docs/thijooree/08-contacts.md b/docs/thijooree/08-contacts.md new file mode 100644 index 0000000..0a3d7d5 --- /dev/null +++ b/docs/thijooree/08-contacts.md @@ -0,0 +1,80 @@ +# Contacts + +The contacts screen stores and manages frequently used transfer recipients. Contacts are local to the app and never synced externally. + +--- + +## Fragment — `ContactsFragment` + +Displays the full contact list as a `RecyclerView`. Observes `HomeViewModel.contacts` and `HomeViewModel.contactCategories`. + +--- + +## Contact List + +Each contact row shows: +- Circular avatar (profile image if set, otherwise initials placeholder) +- Display name +- Account number(s) +- Category chip (if assigned) + +Tapping a contact row opens `AddContactSheetFragment` in edit mode. + +Tapping the **Transfer** button on a contact row opens `TransferFragment` with the recipient pre-filled. + +--- + +## Categories + +Contacts can be assigned to user-defined categories (e.g., "Family", "Business"). Categories appear as filter chips at the top of the list. Tapping a chip filters the list to that category. Tapping again clears the filter. + +--- + +## Add Contact — `AddContactSheetFragment` + +A bottom sheet for creating or editing a contact. + +### Fields + +| Field | Notes | +|---|---| +| Name | Display name | +| Account number | Primary transfer account number | +| Bank | Optional — for display only | +| Category | Optional; selectable from existing categories or create new | +| Profile image | Optional; select from gallery or camera | + +### Profile Image + +The pencil icon next to the avatar opens a chooser: +- **Gallery** — pick from device gallery +- **Camera** — capture a new photo (temp file in `cacheDir`) + +The image is stored locally in `filesDir/profile_images/` via `ProfileImageStore` with key `"contact_{id}"`. + +### Save + +On save, the contact is persisted to the local database and `HomeViewModel.contacts` is refreshed. + +### Delete + +A delete button (with confirmation dialog) removes the contact and its profile image. + +--- + +## Contact Picker — `ContactPickerSheetFragment` + +A compact bottom sheet version of the contact list, used by `TransferFragment` when the user taps **Choose Contact**. + +- Shows all contacts with avatar and name +- Search bar filters by name or account number +- Tapping a contact returns the selection to `TransferFragment` and dismisses the sheet +- Profile images use a `"local:{key}"` synthetic hash prefix to identify locally stored images + +--- + +  + +--- + +[← Transfer](07-transfer.md)     **Next →** [Activities](09-activities.md) diff --git a/docs/thijooree/09-activities.md b/docs/thijooree/09-activities.md new file mode 100644 index 0000000..cb14ce9 --- /dev/null +++ b/docs/thijooree/09-activities.md @@ -0,0 +1,65 @@ +# Activities + +The activities screen shows a local log of completed transfers initiated within the app, along with receipt viewing and sharing. + +--- + +## Fragment — `ActivitiesFragment` + +Displays a chronological `RecyclerView` of locally stored transfer records. These records are written by the app at transfer completion time — they are not fetched from bank APIs. + +--- + +## Activity List + +Each row shows: +- Bank logo +- Recipient name and account number +- Transfer amount (hidden as `••••` when hide-amounts is active) +- Date and time +- Status badge (Completed / Failed) + +Tapping a row opens `TransferReceiptFragment` for that record. + +--- + +## Transfer Receipt — `TransferReceiptFragment` + +A full-screen receipt view shown immediately after a successful transfer and accessible later from the activities list. + +### Receipt Fields + +| Field | Notes | +|---|---| +| Bank | Source bank logo and name | +| From account | Sender account number | +| To account | Recipient account number | +| Recipient name | As resolved at transfer time | +| Amount | Formatted with currency | +| Remarks | Transfer purpose text | +| Reference number | Bank-issued transaction reference | +| Date and time | Transfer timestamp | +| Status | Completed / Failed | + +### Actions + +- **Share** — generates a text or image summary of the receipt and opens the system share sheet +- **Save to Gallery** — renders the receipt as a bitmap and saves it to the device's Pictures folder (requires `WRITE_EXTERNAL_STORAGE` on API < 29, or `MediaStore` on API 29+) + +### Screenshot Note + +If `FLAG_SECURE` is active (user has enabled the screenshots restriction), the Save to Gallery action uses an off-screen rendering path that bypasses the restriction for the explicit save action only. + +--- + +## Empty State + +If no local transfer records exist, an empty-state illustration is shown with a prompt to make a transfer. + +--- + +  + +--- + +[← Contacts](08-contacts.md)     **Next →** [OTP Screen](10-otp-screen.md) diff --git a/docs/thijooree/10-otp-screen.md b/docs/thijooree/10-otp-screen.md new file mode 100644 index 0000000..4a64d3d --- /dev/null +++ b/docs/thijooree/10-otp-screen.md @@ -0,0 +1,62 @@ +# OTP Screen + +Displays the current TOTP (Time-based One-Time Password) code for each enrolled bank authenticator. Used when confirming transfers, QR payments, or other 2FA-protected operations. + +--- + +## Fragment — `OtpFragment` + +Hosts one card per enrolled bank authenticator. Banks with no stored TOTP seed are not shown. + +--- + +## TOTP Display + +Each card shows: +- Bank logo and name +- The current 6-digit TOTP code (large text) +- A circular countdown ring showing time remaining in the current 30-second window +- The code refreshes automatically when the window expires — no user interaction needed + +### Algorithm + +Standard RFC 6238 TOTP: +- Hash: SHA-1 +- Window: 30 seconds +- Digits: 6 +- Seed: stored per-bank in `CredentialStore` (encrypted) + +--- + +## Supported Banks + +| Bank | Seed source | +|---|---| +| BML | Enrolled via BML app setup; seed stored in `CredentialStore` | +| MIB | MIB business/corporate OTP seed (if applicable) | + +--- + +## Background Name Refresh + +When the screen opens, the fragment may fire a background API call to refresh the account holder name associated with each seed. This is a best-effort call — failure does not affect OTP display. + +--- + +## Usage + +The OTP screen is informational — the user copies the displayed code manually and enters it wherever required (e.g., in `TransferFragment`'s OTP dialog, or in an external portal). The code is never submitted automatically from this screen. + +--- + +## Security + +The TOTP seeds are stored encrypted in `CredentialStore`. They are never logged or included in error reports. + +--- + +  + +--- + +[← Activities](09-activities.md)     **Next →** [PayMV QR Screen](11-paymv-qr-screen.md) diff --git a/docs/thijooree/11-paymv-qr-screen.md b/docs/thijooree/11-paymv-qr-screen.md new file mode 100644 index 0000000..4550f52 --- /dev/null +++ b/docs/thijooree/11-paymv-qr-screen.md @@ -0,0 +1,66 @@ +# PayMV QR Screen + +Handles both sides of PayMV/Favara QR payments: generating a receive-payment QR code and scanning a QR code to initiate a transfer. + +--- + +## Fragment — `PayMvQrFragment` + +Two tabs: **Receive** (generate QR) and **Send** (scan QR). + +--- + +## Receive Tab — Generate QR + +Generates a static PayMV QR code that others can scan to pay the user. + +### Fields + +| Field | Notes | +|---|---| +| Source account | Dropdown of all visible accounts; determines acquirer BIC | +| Amount | Optional — leave blank for open-amount QR | +| Purpose | Optional free-text payment purpose | +| Name | Auto-filled from the selected account's holder name | + +### Generation + +On tap **Generate**, the fragment builds a decimal TLV payload per the [PayMV QR Format](18-paymv-qr-format.md) spec: + +1. Assembles all TLV fields (format indicator, point-of-initiation, tag 26 container, MCC, currency, amount if set, country, name, tag 62 container, tag 80 container) +2. Selects the acquirer BIC from the source account's bank (`MALBMVMV` / `MADVMVMV` / `FAHIMVMV`) +3. Appends `"6304"` and computes CRC-16/CCITT-FALSE over the full string +4. Renders the complete string as a QR code bitmap using the ZXing encoder +5. Displays the QR code full-screen with the account number and name below + +### Share + +A **Share** button exports the QR bitmap via the system share sheet (image/png). + +--- + +## Send Tab — Scan QR + +Scans a QR code and pre-fills the transfer screen. + +### Scanner + +Opens the device camera with a QR viewfinder overlay. Supported QR formats: + +| QR type | Handling | +|---|---| +| PayMV / Favara decimal TLV | Parse account number (tag 26→03), amount (tag 54), name (tag 59), purpose (tag 62→08); navigate to `TransferFragment` pre-filled | +| BML plain URL (`https://pay.bml.com.mv/app/...`) | Navigate to `BmlQrPayFragment` | +| BML embedded in combined QR (root tag 35 → sub 20 → sub-sub 01) | Extract URL; navigate to `BmlQrPayFragment` | + +### Error Handling + +If the scanned code is not a recognized format, a `Snackbar` error is shown and the scanner remains open. + +--- + +  + +--- + +[← OTP Screen](10-otp-screen.md)     **Next →** [BML QR Pay](12-bml-qr-pay.md) diff --git a/docs/thijooree/12-bml-qr-pay.md b/docs/thijooree/12-bml-qr-pay.md new file mode 100644 index 0000000..9bed8e0 --- /dev/null +++ b/docs/thijooree/12-bml-qr-pay.md @@ -0,0 +1,87 @@ +# BML QR Pay + +Handles BML gateway QR payments — scanning a merchant QR code and completing the 3-step TOTP-authenticated payment flow. + +--- + +## Fragment — `BmlQrPayFragment` + +Opened via: +- Scanning a BML plain URL QR in `PayMvQrFragment` +- Scanning a combined Fahipay/PayMV QR that embeds a BML gateway URL +- The `OPEN_PAY_WITH_CARD` intent action + +--- + +## Step 1 — Resolve QR + +The fragment receives a BML gateway URL (e.g., `https://pay.bml.com.mv/app/`). + +It calls the BML `payrequest` lookup API (see [QR Payment](../bmlapi/13-qr-payment.md)) to resolve the URL to merchant details: + +- Merchant name (narrative1) +- Merchant address (narrative2, narrative3) +- Amount (`"0.00"` for static QRS, or preset amount for QRR) +- Currency + +The resolved details are displayed on screen for the user to review before paying. + +--- + +## Source Account Selection + +A dropdown lists all BML accounts. The selected account's internal UUID (`internalId`) is used as `debitAccount` in the payment request. + +--- + +## Amount Entry + +- If the QR is a **static QRS** (amount `"0.00"`), the amount field is editable and required +- If the QR is a **dynamic QRR**, the amount is pre-filled and read-only + +--- + +## Step 2 — TOTP Payment + +The payment uses the standard 3-step BML TOTP flow: + +### 2a — Initiate + +POST to `/walletpayments/pay` with `action: "approve"`, `debitAccount`, `requestId` (the `trxn_hash`), `amount`, `currency`. Expected response: `code: 99` (OTP required). + +> This step may be skipped if the gateway already indicates OTP is required. + +### 2b — Request OTP Channel + +Same POST with `channel: "token"` added. Expected response: `code: 22` (OTP generated and sent to the authenticator). + +### 2c — Confirm with TOTP + +The fragment presents an OTP input dialog. The user opens the [OTP Screen](12-otp-screen.md) or reads the TOTP from their authenticator app, then enters the 6-digit code. + +Same POST with `channel: "token"` and `otp: ""`. On success: `code: 0` with merchant and amount in `payload`. + +--- + +## Success + +On successful payment a confirmation card is shown: +- Merchant name +- Amount paid +- Currency + +A **Done** button dismisses the fragment. + +--- + +## Error Handling + +Failed payments (`success: false`) display the `message` field from the API response. The user may retry with a fresh TOTP code. + +--- + +  + +--- + +[← PayMV QR Screen](11-paymv-qr-screen.md)     **Next →** [Financing](13-financing.md) diff --git a/docs/thijooree/13-financing.md b/docs/thijooree/13-financing.md new file mode 100644 index 0000000..8be9da2 --- /dev/null +++ b/docs/thijooree/13-financing.md @@ -0,0 +1,62 @@ +# Financing + +Aggregates financing products across banks — MIB promotional deals and BML loan details — in a single screen. + +--- + +## Fragment — `FinancingFragment` + +Observes `HomeViewModel.financing` (MIB deals) and `HomeViewModel.bmlLoanDetails`. + +--- + +## MIB Deals Section + +Displays current MIB promotional financing offers fetched from the MIB API. Each deal card shows: +- Deal name / product title +- Key terms (profit rate, tenure, minimum/maximum amount) +- A **Learn More** action that opens the deal detail in an in-app WebView or external browser + +Data is loaded once on fragment creation and refreshed on pull-to-refresh. + +--- + +## BML Loans Section + +Displays the user's active BML loan/financing accounts. Each card shows: +- Loan product name +- Outstanding balance +- Next instalment amount and due date +- Loan account number + +Data comes from `HomeViewModel.bmlLoanDetails`, which is fetched from the BML loans API using the active BML session. + +--- + +## Card Limits Section (BML) + +`HomeViewModel.bmlLimits` provides credit card limit information for BML card accounts. Displayed alongside the loan section: +- Card name +- Total limit +- Available limit +- Used amount + +--- + +## Pull-to-Refresh + +Refreshes both MIB deals and BML loan/limit data independently. Each section shows its own loading indicator. + +--- + +## Empty State + +If no MIB session is active or no BML financing accounts exist, the respective section shows an empty-state message with a prompt to add the corresponding bank account. + +--- + +  + +--- + +[← BML QR Pay](12-bml-qr-pay.md)     **Next →** [Settings](14-settings.md) diff --git a/docs/thijooree/14-settings.md b/docs/thijooree/14-settings.md new file mode 100644 index 0000000..0718aee --- /dev/null +++ b/docs/thijooree/14-settings.md @@ -0,0 +1,71 @@ +# Settings + +The settings hub and the logins management screen. + +--- + +## Settings Hub — `SettingsFragment` + +A simple preference-list screen with navigation links to sub-sections: + +| Entry | Destination | +|---|---| +| Logins | `SettingsLoginsFragment` | +| Security | `SettingsSecurityFragment` | +| Appearance | `SettingsAppearanceFragment` | +| Storage | `SettingsStorageFragment` | + +--- + +## Logins — `SettingsLoginsFragment` + +Manages all connected bank accounts and profiles. + +### Account List + +Each connected login is shown as a card. Within each login card, individual profiles (CIF profiles for MIB, or the single account for BML/Fahipay) are listed. + +Each profile entry shows: +- Profile name / CIF type +- Account number(s) +- Profile image (circular avatar) +- Visibility toggle switch + +### Visibility Toggle + +Toggling a profile off hides it from the accounts list and excludes it from API refresh cycles. The session is kept alive — the profile can be re-enabled without re-logging in. + +### Profile Image + +A pencil icon (`ic_edit`) next to each profile opens an image chooser: +- **Gallery** — pick from device photo library +- **Camera** — capture via device camera (temp file: `cacheDir/profile_photo_tmp.jpg`) + +Profile images are stored locally via `ProfileImageStore`: +- BML: key `bml_{profileId}` +- Fahipay: key `fahipay_{loginId}` +- MIB: uploaded to the MIB server via profile image API (P40); retrieved via hash (P41); deleted via P42 + +### Add Account + +A **+** (Add) button navigates to `LoginActivity` → `BankSelectionFragment` to add a new bank login. + +### Logout + +A **Logout** button on each login card shows a confirmation dialog. On confirm: +- Session tokens are revoked where supported +- Credentials are removed from `CredentialStore` +- All associated `MibAccount` objects are removed from `BasedBankApp` +- The accounts list is refreshed + +### Business OTP Seed (MIB) + +For MIB corporate/business profiles, an **OTP Seed** entry allows importing a TOTP seed string. The seed is stored encrypted in `CredentialStore` and used by the [OTP Screen](12-otp-screen.md). + +--- + +  + +--- + +[← Financing](13-financing.md)     **Next →** [Settings — Security](15-settings-security.md) diff --git a/docs/thijooree/15-settings-security.md b/docs/thijooree/15-settings-security.md new file mode 100644 index 0000000..ef9f85a --- /dev/null +++ b/docs/thijooree/15-settings-security.md @@ -0,0 +1,59 @@ +# Settings — Security + +Controls the app lock method, biometric options, auto-lock timeout, and screenshot restriction. + +--- + +## Fragment — `SettingsSecurityFragment` + +--- + +## Change Lock Method + +A **Change PIN** or **Change Pattern** button (label reflects current method) opens the security setup flow (same `SecuritySetupFragment` as onboarding) in change-mode. The user must first authenticate with the current PIN/pattern/biometric before the new one is accepted. + +--- + +## Biometrics + +A toggle to enable or disable biometric authentication (fingerprint / face — `BIOMETRIC_WEAK`). + +- When enabled, `BiometricPrompt` is offered at the lock screen as an alternative to PIN/pattern +- A secondary toggle controls whether biometrics are also required for transfer confirmation + +Biometric availability is checked via `BiometricManager.canAuthenticate()`. The toggle is disabled with an explanatory message if the device has no enrolled biometrics. + +--- + +## Auto-Lock Timeout + +A radio group or dropdown to set the inactivity timeout: + +| Option | Timeout | +|---|---| +| 30 seconds | 30 s | +| 1 minute | 60 s | +| 3 minutes | 180 s | +| 5 minutes | 300 s | +| Never | Disabled | + +The selection is stored in `SharedPreferences` and read by `HomeActivity` on each timer reset. + +--- + +## Screenshots + +A toggle for `FLAG_SECURE` on `HomeActivity`'s window. + +- **On (default)**: screenshots and screen recording are blocked system-wide while the app is in the foreground +- **Off**: screenshots are allowed + +The lock screen always has `FLAG_SECURE` regardless of this setting. + +--- + +  + +--- + +[← Settings](14-settings.md)     **Next →** [Settings — Appearance](16-settings-appearance.md) diff --git a/docs/thijooree/16-settings-appearance.md b/docs/thijooree/16-settings-appearance.md new file mode 100644 index 0000000..1383793 --- /dev/null +++ b/docs/thijooree/16-settings-appearance.md @@ -0,0 +1,86 @@ +# Settings — Appearance + +Controls navigation mode, nav slot assignment, theme, accent colour, and language. + +--- + +## Fragment — `SettingsAppearanceFragment` + +--- + +## Navigation Mode + +A toggle/radio group: + +| Mode | Description | +|---|---| +| Drawer | Slide-out navigation drawer (default) | +| Bottom Navigation | Bottom bar with 3 visible slots + Dashboard + More | + +Changing mode takes effect immediately; `HomeActivity` recreates its navigation structure. + +--- + +## Navigation Slot Customisation — `NavCustomization` + +A drag-and-drop list of all 10 navigation destinations. The user reorders items to assign them to slots. + +### Drawer Mode + +All 10 items appear in the drawer in the configured order. + +### Bottom Navigation Mode + +- Slots 1–3 appear in the bottom bar +- Slot 4–10 appear in the **More** bottom sheet (`NavMoreSheetFragment`) +- Dashboard is always pinned as the first tab and is not part of the 10-item pool + +### Quick Action Slots + +Two dedicated quick-action slots are configured separately at the bottom of the customisation screen. These map to FAB-style buttons shown on the dashboard card. + +### Persistence + +The ordered list is serialised to `SharedPreferences` as a comma-separated string of destination IDs. + +--- + +## Theme + +A three-way selector: + +| Option | Behaviour | +|---|---| +| System default | Follows the device's dark/light mode | +| Light | Forces light theme | +| Dark | Forces dark theme | + +Applied via `AppCompatDelegate.setDefaultNightMode()`. + +--- + +## Accent Colour + +A horizontal chip row with several Material colour options. The selected accent is applied to the app's `MaterialTheme` colour scheme (primary / secondary). + +--- + +## Language + +A dropdown or chip selector: + +| Option | +|---| +| System default | +| English | +| Dhivehi | + +Applied via `AppCompatDelegate` locale override. Takes effect immediately (activity recreate). + +--- + +  + +--- + +[← Settings — Security](15-settings-security.md)     **Next →** [Settings — Storage](17-settings-storage.md) diff --git a/docs/thijooree/17-settings-storage.md b/docs/thijooree/17-settings-storage.md new file mode 100644 index 0000000..16b1f72 --- /dev/null +++ b/docs/thijooree/17-settings-storage.md @@ -0,0 +1,59 @@ +# Settings — Storage + +Manages locally cached data and profile images. + +--- + +## Fragment — `SettingsStorageFragment` + +Displays an overview of locally stored data categories with clear actions for each. + +--- + +## Stored Data Categories + +| Category | Location | Description | +|---|---|---| +| Profile images | `filesDir/profile_images/` | BML and Fahipay profile photos stored by `ProfileImageStore` | +| Contact images | `filesDir/profile_images/` | Contact avatar photos | +| Transaction image cache | In-memory / HTTP cache | Merchant logos loaded in account history | +| Camera temp file | `cacheDir/profile_photo_tmp.jpg` | Temp file from camera capture; automatically overwritten on next camera use | +| Transfer receipts | Local database | Completed transfer records shown in Activities | + +--- + +## Clear Actions + +### Clear Profile Images + +Deletes all files in `filesDir/profile_images/` for BML and Fahipay profiles. MIB profile images are stored server-side and are not affected. After clearing, avatars fall back to the initials placeholder. + +### Clear Contact Images + +Deletes all contact profile images. Contact records are preserved. + +### Clear All Caches + +Clears: +- `cacheDir` contents (including camera temp file and HTTP response cache) +- In-memory image caches + +Does **not** clear credentials, sessions, or transfer records. + +### Clear Transfer History + +Deletes all locally stored transfer receipt records from the database. This action is irreversible and requires a confirmation dialog. + +--- + +## Storage Usage + +The screen may show an approximate size for each category (calculated by summing file sizes in the respective directories). + +--- + +  + +--- + +[← Settings — Appearance](16-settings-appearance.md) diff --git a/docs/thijooree/18-paymv-qr-format.md b/docs/thijooree/18-paymv-qr-format.md new file mode 100644 index 0000000..dd2d4a2 --- /dev/null +++ b/docs/thijooree/18-paymv-qr-format.md @@ -0,0 +1,176 @@ +# PayMV QR Format + +Documents the decimal TLV QR format used by the PayMV/Favara payment network in the Maldives — both generation (to receive payment) and parsing (to initiate a transfer by scanning). + +--- + +## Encoding + +PayMV QRs use a **decimal TLV** encoding — not binary BER-TLV. Every field is represented as ASCII text: + +``` +<2-digit decimal tag><2-digit decimal length>... +``` + +Example — tag `59`, value `"AHMED ALI"` (9 chars): +``` +5909AHMED ALI +``` + +Tags and lengths are always exactly 2 decimal digits. Fields are concatenated directly with no separator. + +--- + +## Root-Level Tags + +| Tag | Field | Notes | +|---|---|---| +| `00` | Format indicator | Always `"01"` | +| `01` | Point-of-initiation method | `"11"` = static QR, `"12"` = dynamic QR | +| `26` | Merchant account information | Container — see sub-tags below | +| `35` | BML/gateway merchant info | Container — present in combined EMV+BML QRs only | +| `52` | Merchant category code | `"0000"` (generic) | +| `53` | Transaction currency | `"462"` = MVR (ISO 4217 numeric) | +| `54` | Transaction amount | Decimal string (e.g. `"1.50"`); absent for open-amount QRs | +| `58` | Country code | `"MV"` | +| `59` | Merchant / recipient name | Max 25 characters | +| `62` | Additional data field | Container — see sub-tags below | +| `63` | CRC | `6304` prefix + 4-char hex checksum — always last | +| `80` | Supplementary data | Container — timestamp and domain | + +--- + +## Merchant Account Info — Tag `26` Sub-Tags + +| Sub-Tag | Field | Example value | +|---|---|---| +| `00` | Domain | `"mv.favara.mpqr"` | +| `01` | Acquirer BIC | `"MALBMVMV"` (see table below) | +| `02` | Acquirer BIC (repeated) | Same as `01` | +| `03` | Account number | Beneficiary account number | +| `05` | Mobile number | E.164 format (e.g. `"+9607654321"`); optional | +| `10` | Network indicator | `"IPAY"` | + +### Acquirer BIC Mapping + +| Bank | Acquirer BIC | +|---|---| +| BML | `MALBMVMV` | +| MIB | `MADVMVMV` | +| Fahipay | `FAHIMVMV` | + +--- + +## Additional Data — Tag `62` Sub-Tags + +| Sub-Tag | Field | Notes | +|---|---|---| +| `05` | Reference / bill number | 9 random uppercase alphanumeric characters | +| `08` | Payment purpose | Free-form text entered by the payee | + +--- + +## Supplementary Data — Tag `80` Sub-Tags + +| Sub-Tag | Field | Notes | +|---|---|---| +| `00` | Domain | `"mv.favara.mpqr"` | +| `01` | Timestamp | ISO 8601 format: `"yyyy-MM-dd'T'HH:mm:ss.00000"` | + +--- + +## CRC-16 + +The checksum uses **CRC-16/CCITT-FALSE** (polynomial `0x1021`, initial value `0xFFFF`). The CRC is computed over the entire payload string up to and including `"6304"`, then the 4-digit uppercase hex result is appended. + +```python +def crc16(data: str) -> str: + crc = 0xFFFF + for c in data: + crc ^= (ord(c) & 0xFF) << 8 + for _ in range(8): + if crc & 0x8000: + crc = ((crc << 1) & 0xFFFF) ^ 0x1021 + else: + crc = (crc << 1) & 0xFFFF + return format(crc, '04X') +``` + +--- + +## Generating a Receive-Payment QR + +To create a QR that others can scan to pay you: + +``` +00 02 01 ← Format indicator +01 02 11 ← Static QR +26 ← Merchant account info + 00 15 mv.favara.mpqr + 01 08 MALBMVMV ← Acquirer BIC (BML example) + 02 08 MALBMVMV ← Repeated + 03 + 05 <+960XXXXXXX> ← Optional phone + 10 04 IPAY +52 04 0000 ← MCC +53 03 462 ← MVR +54 ← Omit tag entirely if open-amount +58 02 MV +59 +62 + 05 09 <9 random alphanum chars> ← Reference + 08 +80 + 00 15 mv.favara.mpqr + 01 ← Timestamp +6304 +``` + +--- + +## Parsing a PayMV QR (Incoming Scan) + +When scanning a QR code, extract the relevant fields: + +| Field | TLV path | Used for | +|---|---|---| +| Account number | root→`26`→`03` | Transfer destination | +| Amount | root→`54` | Pre-fill transfer amount (may be absent) | +| Merchant name | root→`59` | Display recipient name | +| Purpose | root→`62`→`08` | Pre-fill transfer remarks | + +--- + +## Extracting a BML Gateway URL from a Combined QR + +Combined QRs (e.g. Fahipay card QRs that embed a BML gateway payment URL) encode the BML URL at a fixed TLV path: + +``` +root tag 35 → sub-tag 20 → sub-sub-tag 01 +``` + +The value at sub-sub-tag `01` is a full `https://pay.bml.com.mv/app/...` URL. Extract it and hand off to the [BML QR Payment flow](../bmlapi/13-qr-payment.md). + +Plain BML QR codes (not combined) start with `https://pay.bml.com.mv/app/` directly. + +--- + +## Example Payload + +Static QR for account `7700000000123`, holder `"AHMED ALI"`, open amount, purpose `"Rent"`: + +``` +000201010211268...520400005303462 +5802MV5909AHMED ALI6225050912345ABCDEF0804Rent +80...63044A2B +``` + +(values abbreviated for clarity — actual tags are concatenated with no whitespace) + +--- + +  + +--- + +[← README](README.md)     **Next →** [Account Parser Architecture](19-parsers.md) diff --git a/docs/thijooree/PARSERS.md b/docs/thijooree/19-parsers.md similarity index 97% rename from docs/thijooree/PARSERS.md rename to docs/thijooree/19-parsers.md index c34fbde..83b7350 100644 --- a/docs/thijooree/PARSERS.md +++ b/docs/thijooree/19-parsers.md @@ -83,3 +83,9 @@ Handles both CASA accounts and prepaid/credit cards. `AccountsAdapter` calls `AccountListParser.from(account)` once per item (skipping `null` results) and binds the resulting `AccountListDisplay` directly. The adapter has zero bank-specific logic. The transfer screen dropdown (`TransferFragment`) also uses `AccountListParser.from(acc)?.balance` for the source account balance display. + +  + +--- + +[← PayMV QR Format](18-paymv-qr-format.md)     **Next →** [Transfer Flows](20-transfer-flows.md) diff --git a/docs/thijooree/01-transfer-flows.md b/docs/thijooree/20-transfer-flows.md similarity index 99% rename from docs/thijooree/01-transfer-flows.md rename to docs/thijooree/20-transfer-flows.md index a4bb464..da6616d 100644 --- a/docs/thijooree/01-transfer-flows.md +++ b/docs/thijooree/20-transfer-flows.md @@ -244,4 +244,4 @@ The transfer button is only enabled when all of the following are true: --- -[Back to app docs index](README.md) +[← Account Parser Architecture](19-parsers.md) diff --git a/docs/thijooree/AI_SECURITY_CHECK.md b/docs/thijooree/AI_SECURITY_CHECK.md index e44f109..7a26320 100644 --- a/docs/thijooree/AI_SECURITY_CHECK.md +++ b/docs/thijooree/AI_SECURITY_CHECK.md @@ -373,3 +373,9 @@ _None._ - **MIB Blowfish/ECB** — inherited upstream protocol weakness, not actionable without server-side changes. - **DhiraaguClient JSON string interpolation** — low real-world risk given numeric-only input validation upstream. - **`android:allowBackup="true"`** — flagged by automated scanners but effectively mitigated by the exclusion rules. + +  + +--- + +[← Account Parser Architecture](19-parsers.md) diff --git a/docs/thijooree/README.md b/docs/thijooree/README.md index e842ec1..76441a4 100644 --- a/docs/thijooree/README.md +++ b/docs/thijooree/README.md @@ -4,8 +4,34 @@ Documentation for app-specific logic — UI flows, routing decisions, and busine --- +## UI Flows + | Document | Description | |---|---| -| [01 — Transfer Flows](01-transfer-flows.md) | TransferFragment entry points, recipient lookup, transfer type routing, rejected combinations, BML business OTP flow, BML QR merchant payments | -| [Parsers](PARSERS.md) | Account display parser architecture — how raw bank API data is normalised into a unified `AccountListDisplay` model | +| [00 — App Overview](00-app-overview.md) | MainActivity routing, HomeActivity, navigation modes, autolock, global session state | +| [01 — Onboarding](01-onboarding.md) | Language selection, security setup (PIN/pattern), appearance configuration | +| [02 — Lock Screen](02-lock-screen.md) | LockActivity, PIN/pattern/biometric unlock, brute-force protection | +| [03 — Login](03-login.md) | Bank selection, credential entry, MIB/BML/Fahipay login flows, multi-profile support | +| [04 — Accounts](04-accounts.md) | Account list grouped display, AccountsAdapter, profile images, quick-transfer shortcut | +| [05 — Account History](05-account-history.md) | Paginated transaction history, search, infinite scroll | +| [06 — Transfer History](06-transfer-history.md) | Multi-bank merged transfer history, parallel loading | +| [07 — Transfer](07-transfer.md) | Recipient lookup, MIB/BML/Fahipay transfer flows, QR, biometric gate, BML OTP | +| [08 — Contacts](08-contacts.md) | Contact list, add/edit/delete, categories, contact picker sheet | +| [09 — Activities](09-activities.md) | Local transfer log, TransferReceiptFragment, share/save receipt | +| [10 — OTP Screen](10-otp-screen.md) | TOTP display, real-time countdown, enrolled bank authenticators | +| [11 — PayMV QR Screen](11-paymv-qr-screen.md) | Generate receive-payment QR, scan QR to initiate transfer | +| [12 — BML QR Pay](12-bml-qr-pay.md) | Scan BML merchant QR, merchant lookup, 3-step TOTP payment | +| [13 — Financing](13-financing.md) | MIB promotional deals, BML loans and card limits | +| [14 — Settings](14-settings.md) | Settings hub, logins management, profile images, add/logout accounts | +| [15 — Settings: Security](15-settings-security.md) | Change lock method, biometrics, auto-lock timeout, screenshots | +| [16 — Settings: Appearance](16-settings-appearance.md) | Navigation mode, slot drag-reorder, theme, accent colour, language | +| [17 — Settings: Storage](17-settings-storage.md) | Clear caches, profile images, transfer history | + +## Reference + +| Document | Description | +|---|---| +| [18 — PayMV QR Format](18-paymv-qr-format.md) | Decimal TLV encoding, all tags, CRC-16, QR generation recipe, parsing reference | +| [19 — Parsers](19-parsers.md) | Account display parser architecture — how raw bank API data is normalised into a unified `AccountListDisplay` model | +| [20 — Transfer Flows](20-transfer-flows.md) | TransferFragment entry points, recipient lookup, transfer type routing, rejected combinations, BML business OTP flow, BML QR merchant payments | | [AI Security Audit](AI_SECURITY_CHECK.md) | Full source security audit — credential storage, network layer, manifest, data privacy |