All checks were successful
Auto Tag on Version Change / check-version (push) Successful in 5s
165 lines
4.5 KiB
Markdown
165 lines
4.5 KiB
Markdown
# Business Profile OTP
|
||
|
||
When activating a business profile (where `profile_type` is `"business"`), the server requires SMS or email OTP verification before issuing the `blaze_identity` cookie. This is a two-step process: request an OTP to a chosen channel, then submit the received code.
|
||
|
||
---
|
||
|
||
## Prerequisites
|
||
|
||
- Completed [Login Steps 1–5](01-login.md) (web session cookies are active)
|
||
- Received a `302` redirect to `/web/profile/2fa/business` after `GET /web/profile/{profile_id}`
|
||
|
||
---
|
||
|
||
## Step 1 — Fetch Available OTP Channels
|
||
|
||
```
|
||
GET https://www.bankofmaldives.com.mv/internetbanking/web/profile/2fa/business
|
||
```
|
||
|
||
Fetches the HTML page for the business 2FA screen. This also refreshes the `XSRF-TOKEN` cookie needed for the POST requests below.
|
||
|
||
```bash
|
||
curl --request GET \
|
||
--url 'https://www.bankofmaldives.com.mv/internetbanking/web/profile/2fa/business' \
|
||
--header 'User-Agent: Mozilla/5.0 (Android 14; Mobile; rv:150.0) Gecko/150.0 Firefox/150.0' \
|
||
--cookie 'XSRF-TOKEN=<xsrf_token>; blaze_session=<session>; blaze_identity=<identity>'
|
||
```
|
||
|
||
### Response
|
||
|
||
`200 OK` — HTML with an Inertia.js `data-page` payload. After [extracting the Inertia JSON](README.md#inertiajs-response-format):
|
||
|
||
```json
|
||
{
|
||
"props": {
|
||
"channels": [
|
||
{
|
||
"channel": "sms",
|
||
"description": "SMS",
|
||
"masked": "+960 9XX XXXX"
|
||
},
|
||
{
|
||
"channel": "email",
|
||
"description": "Email",
|
||
"masked": "m****@example.com"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
| Field | Type | Description |
|
||
|---|---|---|
|
||
| `channel` | `string` | Channel identifier — use in Step 2 and Step 3 |
|
||
| `description` | `string` | Human-readable channel name |
|
||
| `masked` | `string` | Partially masked destination (for display to user) |
|
||
|
||
Present the `masked` values to the user so they can choose where to receive their OTP.
|
||
|
||
---
|
||
|
||
## Step 2 — Request OTP
|
||
|
||
```
|
||
POST https://www.bankofmaldives.com.mv/internetbanking/web/profile/2fa/business
|
||
```
|
||
|
||
Send an empty `code` to trigger OTP dispatch to the chosen channel.
|
||
|
||
### Request
|
||
|
||
**Content-Type:** `application/json`
|
||
|
||
```json
|
||
{
|
||
"code": "",
|
||
"channel": "sms"
|
||
}
|
||
```
|
||
|
||
| Field | Value | Notes |
|
||
|---|---|---|
|
||
| `code` | `""` | Empty — signals OTP dispatch, not submission |
|
||
| `channel` | `"sms"` or `"email"` | Channel from Step 1 |
|
||
|
||
```bash
|
||
curl --request POST \
|
||
--url 'https://www.bankofmaldives.com.mv/internetbanking/web/profile/2fa/business' \
|
||
--header 'Content-Type: application/json' \
|
||
--header 'User-Agent: Mozilla/5.0 (Android 14; Mobile; rv:150.0) Gecko/150.0 Firefox/150.0' \
|
||
--header 'X-XSRF-TOKEN: <xsrf_token>' \
|
||
--cookie 'XSRF-TOKEN=<xsrf_token>; blaze_session=<session>' \
|
||
--data '{"code":"","channel":"sms"}'
|
||
```
|
||
|
||
### Response
|
||
|
||
**Success:** `302` redirect — OTP has been sent.
|
||
|
||
**Failure:** Any non-`302` — request failed; check session cookies and retry.
|
||
|
||
---
|
||
|
||
## Step 3 — Submit OTP
|
||
|
||
```
|
||
POST https://www.bankofmaldives.com.mv/internetbanking/web/profile/2fa/business
|
||
```
|
||
|
||
Before submitting, refresh the XSRF token by making a fresh `GET /web/profile/2fa/business` (repeat Step 1). This ensures the token is valid for the confirmation POST.
|
||
|
||
### Request
|
||
|
||
**Content-Type:** `application/json`
|
||
|
||
```json
|
||
{
|
||
"code": "123456",
|
||
"channel": "sms"
|
||
}
|
||
```
|
||
|
||
| Field | Value | Notes |
|
||
|---|---|---|
|
||
| `code` | `"123456"` | OTP received via SMS/email |
|
||
| `channel` | `"sms"` or `"email"` | Same channel used in Step 2 |
|
||
|
||
```bash
|
||
curl --request POST \
|
||
--url 'https://www.bankofmaldives.com.mv/internetbanking/web/profile/2fa/business' \
|
||
--header 'Content-Type: application/json' \
|
||
--header 'User-Agent: Mozilla/5.0 (Android 14; Mobile; rv:150.0) Gecko/150.0 Firefox/150.0' \
|
||
--header 'X-XSRF-TOKEN: <xsrf_token_fresh>' \
|
||
--cookie 'XSRF-TOKEN=<xsrf_token_fresh>; blaze_session=<session>' \
|
||
--data '{"code":"123456","channel":"sms"}'
|
||
```
|
||
|
||
### Response — Success
|
||
|
||
`302` redirect to `/web/redirect` or `409 Conflict`. Both mean the OTP was accepted and the `blaze_identity` cookie is now set for the business profile.
|
||
|
||
Proceed to [OAuth Token Exchange](03-oauth-token.md).
|
||
|
||
### Response — Invalid OTP
|
||
|
||
`302` redirect to any path other than `/web/redirect`. The OTP was wrong. Retry Step 3 with a new code (re-requesting is not usually needed unless the OTP expired).
|
||
|
||
### Response — Other failure
|
||
|
||
Non-`302` HTTP status — session has likely expired. Return to the full [login flow](01-login.md).
|
||
|
||
---
|
||
|
||
## Next Steps
|
||
|
||
After the `blaze_identity` cookie is set → proceed to **[OAuth Token Exchange](03-oauth-token.md)**
|
||
|
||
---
|
||
|
||
|
||
|
||
---
|
||
|
||
[← Login](01-login.md) **Next →** [OAuth Token](03-oauth-token.md)
|