5.1 KiB
Personal Profile
This document covers two unrelated profile-adjacent surfaces:
- Personal profile — an HTML page on the WebView host, scraped for display.
- 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=<session_xxid>; IBSID=<session_xxid>; mbnonce=<nonceGenerator>; time-tracker=597
Response
Content-Type: text/html; charset=UTF-8
The page contains an <h5> with the user's full name and <span> elements with labelled fields.
Parsing Strategy
Full name — extracted from:
<h5 class="mb-1 text-dark fw-semibold">Mohamed Ali</h5>
Regex:
Regex("""<h5 class="mb-1 text-dark fw-semibold">\s*([^<]+)\s*</h5>""")
Labelled fields — each follows this pattern:
<span ...><b ...>Username:</b ...>...<span ...>myusername</span>
Regex (used for each label):
Regex(
"""<span[^>]*>\s*<b[^>]*>\s*$label\s*</b[^>]*>.*?<span[^>]*>([^<]+)</span>""",
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 <h5>:
data class MibPersonalProfile(
val fullName: String,
val username: String,
val email: String,
val mobile: String,
val enrolled: String
)
Notes
- Returns
nullif 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 and 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):
{
"sfunc": "n",
"xxid": "<session xxid>",
"data": {
"imageHash": "<customerImage or customerImgHash>",
"nonce": "<computed nonce>",
"appId": "<appId>",
"sodium": "<random>",
"routePath": "P41",
"xxid": "<session xxid>"
}
}
Response:
{
"success": true,
"reasonCode": "201",
"profileImage": "<base64-encoded JPEG>"
}
profileImage is raw base64 with no data URI prefix.
Upload — routePath: P40
Request (encrypted payload):
{
"sfunc": "n",
"xxid": "<session xxid>",
"data": {
"profileId": "<active profile ID>",
"profileImage": "<base64-encoded JPEG>",
"nonce": "<computed nonce>",
"appId": "<appId>",
"sodium": "<random>",
"routePath": "P40",
"xxid": "<session xxid>"
}
}
Response:
{
"success": true,
"imageHash": "<new hash>",
"customerImage": "<new hash, alternate field name>"
}
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):
{
"sfunc": "n",
"xxid": "<session xxid>",
"data": {
"profileId": "<active profile ID>",
"nonce": "<computed nonce>",
"appId": "<appId>",
"sodium": "<random>",
"routePath": "P42",
"xxid": "<session xxid>"
}
}
Response:
{ "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 Next → Transfer