# Personal Profile This document covers two unrelated profile-adjacent surfaces: 1. **Personal profile** — an HTML page on the WebView host, scraped for display. 2. **Profile image management** — three encrypted-API endpoints (`P40`/`P41`/`P42`) that fetch, upload, and delete the avatar. --- ## 1. Personal Profile (HTML scrape) Fetch the user's personal profile details. This endpoint returns an HTML page; data is extracted via HTML scraping. ### Endpoint ``` GET https://faisamobilex-wv.mib.com.mv/personalProfile ``` ### Authentication Session cookies only — no additional AJAX headers required. ``` Cookie: mbmodel=IOS-1.0; xxid=; IBSID=; mbnonce=; time-tracker=597 ``` ### Response **Content-Type:** `text/html; charset=UTF-8` The page contains an `
` with the user's full name and `` elements with labelled fields. ### Parsing Strategy **Full name** — extracted from: ```html
Mohamed Ali
``` Regex: ```kotlin Regex("""
\s*([^<]+)\s*
""") ``` **Labelled fields** — each follows this pattern: ```html Username:...myusername ``` Regex (used for each label): ```kotlin Regex( """]*>\s*]*>\s*$label\s*]*>.*?]*>([^<]+)""", setOf(RegexOption.DOT_MATCHES_ALL, RegexOption.IGNORE_CASE) ) ``` ### Extracted Fields | Label in HTML | Field | Description | |---|---|---| | `Username:` | `username` | Login username | | `Email:` | `email` | Registered email address | | `Mobile no:` | `mobile` | Registered mobile number | | `Enrolled:` | `enrolled` | Enrollment date or status | Combined with the `fullName` from the `
`: ```kotlin data class MibPersonalProfile( val fullName: String, val username: String, val email: String, val mobile: String, val enrolled: String ) ``` ### Notes - Returns `null` if the response cannot be parsed (network error or unexpected HTML structure). - This endpoint does not have a JSON equivalent — scraping is the only method. --- ## 2. Profile Image Management The avatar lives on the **encrypted API** (`faisanet.mib.com.mv`), not the WebView host. Three `sfunc=n` route paths cover fetch, upload, and delete. All three follow the standard encrypted-request format (see [01-encryption.md](01-encryption.md) and [02-login.md](02-login.md)) and include the standard `baseData` fields (`nonce`, `appId`, `sodium`, `routePath`, `xxid`). | `routePath` | Operation | Source | |---|---|---| | `P41` | Fetch image by hash | `MibLoginFlow.kt:368-375` | | `P40` | Upload new image | `MibLoginFlow.kt:382-391` | | `P42` | Delete current image | `MibLoginFlow.kt:397-403` | ### Image-hash field naming The same conceptual value — "the hash that identifies a customer's avatar" — is exposed under **two different field names** depending on which endpoint returned it: | Source endpoint | Field name | |---|---| | `A41` login init (`operatingProfiles[]`) | `customerImage` | | `C41` registration init (root) | `customerImgHash` | | `ajaxBeneficiary/main` (contacts list) | `customerImgHash` | Both are non-empty hash strings that can be passed straight into `P41` as `imageHash`. Treat them as the same value with two names. ### Fetch — `routePath: P41` **Request** (encrypted payload): ```json { "sfunc": "n", "xxid": "", "data": { "imageHash": "", "nonce": "", "appId": "", "sodium": "", "routePath": "P41", "xxid": "" } } ``` **Response**: ```json { "success": true, "reasonCode": "201", "profileImage": "" } ``` `profileImage` is raw base64 with no data URI prefix. ### Upload — `routePath: P40` **Request** (encrypted payload): ```json { "sfunc": "n", "xxid": "", "data": { "profileId": "", "profileImage": "", "nonce": "", "appId": "", "sodium": "", "routePath": "P40", "xxid": "" } } ``` **Response**: ```json { "success": true, "imageHash": "", "customerImage": "" } ``` The server may populate either `imageHash` or `customerImage` for the new hash — the client reads both (`MibLoginFlow.kt:389-390`) and prefers `imageHash` when present. ### Delete — `routePath: P42` **Request** (encrypted payload): ```json { "sfunc": "n", "xxid": "", "data": { "profileId": "", "nonce": "", "appId": "", "sodium": "", "routePath": "P42", "xxid": "" } } ``` **Response**: ```json { "success": true } ``` After a successful delete, the `customerImage` field on subsequent `A41` responses is blank. > Note: BML and Fahipay profile images are stored locally on-device only (`util/ProfileImageStore.kt`). Only MIB persists avatars server-side via these endpoints. ---   --- [← Financing](06-financing.md)     **Next →** [Transfer](08-transfer.md)