fix(abdm): isolate Aadhaar mobile from ABHA registered mobile and sanitize asterisk placeholders in verification flow
This commit is contained in:
parent
fd492a2aa2
commit
7c573403b2
|
|
@ -2764,6 +2764,13 @@ class Abha extends BaseController
|
|||
?? $account['phone']
|
||||
?? ''
|
||||
));
|
||||
$aadhaarMaskedMobile = $this->maskAbhaMobile((string) (
|
||||
$data['aadhaar_masked_mobile']
|
||||
?? $data['aadhaarMaskedMobile']
|
||||
?? $account['aadhaar_masked_mobile']
|
||||
?? $account['aadhaarMaskedMobile']
|
||||
?? ''
|
||||
));
|
||||
return $this->response->setJSON([
|
||||
'ok' => 1,
|
||||
'status' => $status,
|
||||
|
|
@ -2772,11 +2779,13 @@ class Abha extends BaseController
|
|||
'auth_methods' => array_values(array_unique(array_map(static fn($method): string => strtoupper(trim((string) $method)), $authMethods))),
|
||||
'blocked_auth_methods' => is_array($blockedMethods) ? array_values($blockedMethods) : [],
|
||||
'masked_mobile' => $maskedMobile,
|
||||
'aadhaar_masked_mobile' => $aadhaarMaskedMobile,
|
||||
'account' => [
|
||||
'name' => trim((string) ($account['name'] ?? $account['fullName'] ?? $account['full_name'] ?? $data['name'] ?? $data['fullName'] ?? $data['full_name'] ?? '')),
|
||||
'abha_number' => trim((string) ($account['ABHANumber'] ?? $account['abhaNumber'] ?? $account['abha_id'] ?? $account['healthIdNumber'] ?? $data['ABHANumber'] ?? $data['healthIdNumber'] ?? $data['abha_id'] ?? '')),
|
||||
'abha_address' => trim((string) ($account['abhaAddress'] ?? $account['preferredAddress'] ?? $account['preferredAbhaAddress'] ?? $account['abha_address'] ?? $data['abhaAddress'] ?? $data['preferredAddress'] ?? $data['preferredAbhaAddress'] ?? $data['abha_address'] ?? '')),
|
||||
'masked_mobile' => $maskedMobile,
|
||||
'aadhaar_masked_mobile' => $aadhaarMaskedMobile,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
|
@ -2784,7 +2793,11 @@ class Abha extends BaseController
|
|||
private function maskAbhaMobile(string $value): string
|
||||
{
|
||||
$value = trim($value);
|
||||
if ($value === '' || preg_match('/\*/', $value) === 1) {
|
||||
if ($value === '' || preg_match('/\d/', $value) !== 1) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (preg_match('/\*/', $value) === 1) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
|
@ -2833,8 +2846,22 @@ class Abha extends BaseController
|
|||
}
|
||||
|
||||
$data = is_array($result['data'] ?? null) ? $result['data'] : [];
|
||||
$maskedMobile = trim((string) ($data['masked_mobile'] ?? $data['maskedMobile'] ?? $data['mobile'] ?? ''));
|
||||
$deliveryMessage = trim((string) ($result['message'] ?? $data['message'] ?? ''));
|
||||
$maskedMobile = trim((string) (
|
||||
$result['masked_mobile']
|
||||
?? $result['maskedMobile']
|
||||
?? $data['masked_mobile']
|
||||
?? $data['maskedMobile']
|
||||
?? $data['mobile']
|
||||
?? $data['mobile_number']
|
||||
?? ''
|
||||
));
|
||||
$deliveryMessage = trim((string) (
|
||||
$result['message']
|
||||
?? $data['message']
|
||||
?? $result['details']['message']
|
||||
?? $data['details']['message']
|
||||
?? ''
|
||||
));
|
||||
if ($maskedMobile === '' && preg_match('/(\d{4})(?!.*\d)/', $deliveryMessage, $mobileEnding) === 1) {
|
||||
$maskedMobile = '******' . $mobileEnding[1];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -656,8 +656,19 @@ class EAtriaBridgeConnector implements AbdmConnectorInterface
|
|||
?? $firstAccount['masked_mobile'] ?? $firstAccount['maskedMobile'] ?? $firstAccount['mobile']
|
||||
?? $firstAccount['mobile_number'] ?? $firstAccount['phone'] ?? $firstAccount['phone_number'] ?? ''
|
||||
));
|
||||
if ($maskedMobile !== '') {
|
||||
if ($maskedMobile !== '' && preg_match('/\d/', $maskedMobile) === 1) {
|
||||
$result['masked_mobile'] = $maskedMobile;
|
||||
} else {
|
||||
unset($result['masked_mobile'], $result['maskedMobile']);
|
||||
}
|
||||
|
||||
$aadhaarMaskedMobile = trim((string) (
|
||||
$result['aadhaar_masked_mobile'] ?? $result['aadhaarMaskedMobile']
|
||||
?? $data['aadhaar_masked_mobile'] ?? $data['aadhaarMaskedMobile']
|
||||
?? $firstAccount['aadhaar_masked_mobile'] ?? $firstAccount['aadhaarMaskedMobile'] ?? ''
|
||||
));
|
||||
if ($aadhaarMaskedMobile !== '' && preg_match('/\d/', $aadhaarMaskedMobile) === 1) {
|
||||
$result['aadhaar_masked_mobile'] = $aadhaarMaskedMobile;
|
||||
}
|
||||
|
||||
// HMS callers expect a status-like field; treat successful search as VALID when absent.
|
||||
|
|
|
|||
|
|
@ -161,8 +161,21 @@ window.AbhaVerifyModal = (function () {
|
|||
var label = authLabel(method);
|
||||
var disabled = blocked.indexOf(method) !== -1;
|
||||
var checked = availableMethods[0] === method;
|
||||
var mobile = response.masked_mobile || (response.account && response.account.masked_mobile) || '';
|
||||
var destination = mobile ? ' (' + escapeHtml(mobile) + ')' : '';
|
||||
var targetMobile = '';
|
||||
if (method === 'MOBILE_OTP') {
|
||||
var m = response.masked_mobile || (response.account && response.account.masked_mobile) || '';
|
||||
if (typeof m === 'string' && /\d/.test(m)) {
|
||||
targetMobile = m;
|
||||
}
|
||||
} else if (method === 'AADHAAR_OTP') {
|
||||
// Aadhaar mobile is registered with UIDAI and not exposed by ABDM during search.
|
||||
// Only show if the Bridge explicitly returned an Aadhaar-specific masked mobile.
|
||||
var am = response.aadhaar_masked_mobile || (response.account && response.account.aadhaar_masked_mobile) || '';
|
||||
if (typeof am === 'string' && /\d/.test(am)) {
|
||||
targetMobile = am;
|
||||
}
|
||||
}
|
||||
var destination = targetMobile ? ' (' + escapeHtml(targetMobile) + ')' : '';
|
||||
html += '<label class="abha-auth-option' + (disabled ? ' opacity-50' : '') + '"><span class="d-flex align-items-center gap-3"><input class="form-check-input mt-0" type="radio" name="abhaVerifyAuth" value="' + method + '" ' + (checked ? 'checked' : '') + ' ' + (disabled ? 'disabled' : '') + '><i class="bi ' + label.icon + ' fs-4 text-primary"></i><span><strong>' + label.title + destination + '</strong><small class="d-block text-muted">' + label.detail + '</small></span></span></label>';
|
||||
});
|
||||
$('#abhaVerifyAuthOptions').html(html || '<div class="alert alert-warning mb-0">This ABHA account did not return a supported OTP method. The Bridge must return MOBILE_OTP or AADHAAR_OTP.</div>');
|
||||
|
|
@ -200,7 +213,10 @@ window.AbhaVerifyModal = (function () {
|
|||
lookupResponse.txn_id = response.txn_id || lookupResponse.txn_id;
|
||||
lookupResponse.auth_method = method;
|
||||
var label = authLabel(method);
|
||||
$('#abhaVerifyOtpHint').text('OTP sent using ' + label.title + (response.masked_mobile ? ' (' + response.masked_mobile + ')' : '') + '.');
|
||||
var otpDest = (response.masked_mobile && /\d/.test(response.masked_mobile))
|
||||
? ' (' + escapeHtml(response.masked_mobile) + ')'
|
||||
: '';
|
||||
$('#abhaVerifyOtpHint').text('OTP sent using ' + label.title + otpDest + '.');
|
||||
$('#abhaVerifyOtp').val('');
|
||||
showStep(3);
|
||||
startResendTimer(response.resend_after);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ Required success response:
|
|||
"authMethods": ["MOBILE_OTP", "AADHAAR_OTP"],
|
||||
"blockedAuthMethods": [],
|
||||
"maskedMobile": "******1369",
|
||||
"aadhaar_masked_mobile": null,
|
||||
"accounts": [
|
||||
{
|
||||
"name": "Ashish Soni",
|
||||
|
|
@ -60,7 +61,11 @@ Required success response:
|
|||
}
|
||||
```
|
||||
|
||||
The search transaction must remain valid for the next OTP request. Do not replace it with a new mobile-search transaction.
|
||||
Rules:
|
||||
- When ABDM returns `mobile: "************"` (all asterisks), the Bridge sanitizes `mobile`, `masked_mobile`, and `maskedMobile` to `null`.
|
||||
- If the patient has a previously verified record with genuine digits, the Bridge returns `maskedMobile: "******XXXX"`. Genuine ABDM numbers (e.g. `78*****379`) are passed through.
|
||||
- `aadhaar_masked_mobile` is explicitly `null` during search (compliant with UIDAI/ABDM guidelines preventing harvesting). Aadhaar mobile is resolved only upon OTP dispatch.
|
||||
- The search transaction must remain valid for the next OTP request. Do not replace it with a new mobile-search transaction.
|
||||
|
||||
## 2. Request Account-Bound OTP
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user