update mib api docs
Auto Tag on Version Change / check-version (push) Successful in 6s

This commit is contained in:
2026-10-23 05:38:33 +05:00
parent 740030e061
commit 2764c6e452
10 changed files with 662 additions and 658 deletions
+84 -59
View File
@@ -1,92 +1,117 @@
# Personal Profile
This document covers two unrelated profile-adjacent surfaces:
This document covers two profile-adjacent surfaces:
1. **Personal profile** — an HTML page on the WebView host, scraped for display.
1. **Personal details** — full name, email, mobile number and National ID, shown on the login details screen.
2. **Profile image management** — three encrypted-API endpoints (`P40`/`P41`/`P42`) that fetch, upload, and delete the avatar.
---
## 1. Personal Profile (HTML scrape)
## 1. Personal Details
Fetch the user's personal profile details. This endpoint returns an HTML page; data is extracted via HTML scraping.
The details come from two sources and are fetched once at login, then cached (`MibProfileClient.kt`).
### Endpoint
| Field | Source |
|---|---|
| Full name | `A41` login init response — `fullName` |
| Email | Alias suggestions — type `1` (falls back to `A41` `email`) |
| Mobile number | Alias suggestions — type `0` |
| National ID | Alias suggestions — type `3` |
```
GET https://faisamobilex-wv.mib.com.mv/personalProfile
### Full name — `A41`
The `A41` login init response (see [02-login.md](02-login.md)) carries the user's details at the root:
```json
{
"fullName": "Mohamed Ali",
"email": "user@example.com",
"lastLoginTime": "2026-05-16 15:10:25",
"customerImgHash": "<image hash>",
"roleName": "Consumer Premium"
}
```
### Authentication
Session cookies only — no additional AJAX headers required.
### Alias Suggestions — `getAliasTypes`
```
Cookie: mbmodel=IOS-1.0; xxid=<session_xxid>; IBSID=<session_xxid>; mbnonce=<nonceGenerator>; time-tracker=597
POST https://faisamobilex-wv-v2.mib.com.mv/ajaxAlias/getAliasTypes
```
### Response
WebView session cookies and AJAX headers (see [README](README.md)). Empty POST body.
**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:
```html
<h5 class="mb-1 text-dark fw-semibold">Mohamed Ali</h5>
```
Referer: https://faisamobilex-wv-v2.mib.com.mv/Alias/Alias?dashurl=1
```
Regex:
```kotlin
Regex("""<h5 class="mb-1 text-dark fw-semibold">\s*([^<]+)\s*</h5>""")
The suggestions belong to the **currently selected** profile and differ between personal and business profiles. Select the personal profile (`profileType: "0"`) with `P47` first (see [03-accounts.md](03-accounts.md)).
#### Response
```json
{
"success": true,
"responseCode": "2",
"reasonCode": "203",
"reasonText": "Alias Types Search Success.",
"data": [
{ "id": 0, "aliasTypeName": "Mobile Number", "suggestedAlias": "+9609600001" },
{ "id": 1, "aliasTypeName": "E-Mail", "suggestedAlias": "user@example.com" },
{ "id": 3, "aliasTypeName": "National ID", "suggestedAlias": "A000001" }
]
}
```
**Labelled fields** — each follows this pattern:
```html
<span ...><b ...>Username:</b ...>...<span ...>myusername</span>
```
Regex (used for each label):
```kotlin
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 |
| `id` | `aliasTypeName` | Used as |
|---|---|---|
| `Username:` | `username` | Login username |
| `Email:` | `email` | Registered email address |
| `Mobile no:` | `mobile` | Registered mobile number |
| `Enrolled:` | `enrolled` | Enrollment date or status |
| `0` | Mobile Number | Mobile number (with `+960` prefix) |
| `1` | E-Mail | Email |
| `3` | National ID | ID card number |
Combined with the `fullName` from the `<h5>`:
A type may be missing from `data` when the user has no value for it.
```kotlin
data class MibPersonalProfile(
val fullName: String,
val username: String,
val email: String,
val mobile: String,
val enrolled: String
)
### Registered Aliases — `ajaxAlias/main`
```
POST https://faisamobilex-wv-v2.mib.com.mv/ajaxAlias/main
```
### Notes
Lists the user's registered Favara aliases. Not consumed by the app.
- 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.
Body: `page=1&search=&searchAccount=&searchAliasType=&sort=AlsId&sortDir=asc&start=1&end=20&includeCount=1`
```json
{
"success": true,
"reasonText": "Favara ID Search Success.",
"data": [
{
"AlsBfy": { "Tp": "MSISDN", "Id": "+9609600001" },
"BfyNm": "Mohamed",
"BfySnm": "Ali",
"CdtrAcct": { "Acct": "90100000000000000", "FinInstnId": "MADVMVMV" },
"AcctHldrId": "A000001",
"AcctHldrIdTp": "IDENTITY_NUMBER",
"AcctHldrTp": "INDIVIDUAL",
"AdrLine": "<address>",
"Ctry": "MDV",
"RegDtTm": "2026-05-12T20:07:44",
"AlsSt": "ACTIVE",
"PhneNb": "+9609600001",
"EmailAdr": "user@example.com"
}
],
"Pg": { "Size": 20, "TtlElms": 1, "TtlPgs": 1, "Nmb": 0 }
}
```
`AlsBfy.Tp` is the alias type, e.g. `MSISDN` or `NATIONAL_ID`.
---
## 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`).
The avatar lives on the **encrypted API** (`faisamobilex-smvc-v2.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 |
|---|---|---|
@@ -101,10 +126,10 @@ The same conceptual value — "the hash that identifies a customer's avatar" —
| Source endpoint | Field name |
|---|---|
| `A41` login init (`operatingProfiles[]`) | `customerImage` |
| `A41` login init (root) | `customerImgHash` |
| `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.
Both are non-empty hash strings that can be passed straight into `P41` as `imageHash`. Treat them as the same value with two names. Contact photos use a separate route, `B46` (see [09-contacts.md](09-contacts.md)).
### Fetch — `routePath: P41`