ABDM Gateway settings: add admin UI toggle for SSL certificate verification
Adds a 'Verify SSL Certificate' switch on Admin -> ABDM Gateway page, persisted as hospital_setting.ABDM_BRIDGE_SSL_VERIFY (default ON/secure). Wired into M3HiuGatewayClient, EAtriaBridgeConnector, and the settings page's own Test Connection check. Per-machine ABDM_BRIDGE_SSL_VERIFY env var still overrides this DB setting for deployments needing a quick local-only workaround. Verification stays on by default everywhere; disabling it is an explicit, visible opt-in with an on-page warning.
This commit is contained in:
parent
b26920c6f4
commit
a5219bca2d
|
|
@ -20,6 +20,8 @@ class AbdmGatewaySettings extends BaseController
|
|||
$hmsName = $this->readSettingValue('ABDM_HMS_NAME');
|
||||
$gwUrl = $this->readSettingValue('EATRIA_BRIDGE_URL') ?: 'https://abdm-bridge.e-atria.in/api';
|
||||
$bridgeHospitalId = $this->readSettingValue('ABDM_BRIDGE_HOSPITAL_ID');
|
||||
$sslVerifyRaw = strtolower(trim($this->readSettingValue('ABDM_BRIDGE_SSL_VERIFY')));
|
||||
$sslVerify = ! in_array($sslVerifyRaw, ['0', 'false', 'no', 'off'], true);
|
||||
|
||||
return view('Setting/Admin/abdm_gateway_settings', [
|
||||
'gateway_url' => $gwUrl,
|
||||
|
|
@ -30,6 +32,7 @@ class AbdmGatewaySettings extends BaseController
|
|||
'token_exists' => $token !== '',
|
||||
'connector' => $this->readSettingValue('ABDM_CONNECTOR') ?: 'eatria_bridge',
|
||||
'abdm_sync_provider' => $this->readSettingValue('ABDM_SYNC_PROVIDER') ?: 'eatria',
|
||||
'ssl_verify' => $sslVerify,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -51,6 +54,8 @@ class AbdmGatewaySettings extends BaseController
|
|||
$token = $this->sanitizeBearerToken((string) $this->request->getPost('api_token'));
|
||||
$hfrId = trim((string) $this->request->getPost('hfr_id'));
|
||||
$hmsName = trim((string) $this->request->getPost('hms_name'));
|
||||
$sslVerifyPosted = $this->request->getPost('ssl_verify');
|
||||
$sslVerify = $sslVerifyPosted === null ? true : (bool) (int) $sslVerifyPosted;
|
||||
|
||||
// Validate gateway URL format
|
||||
if ($gwUrl !== '' && ! filter_var($gwUrl, FILTER_VALIDATE_URL)) {
|
||||
|
|
@ -87,6 +92,7 @@ class AbdmGatewaySettings extends BaseController
|
|||
// Always set connector to eatria_bridge when saving from this page
|
||||
$this->upsertSettingValue('ABDM_CONNECTOR', 'eatria_bridge');
|
||||
$this->upsertSettingValue('ABDM_SYNC_PROVIDER', 'eatria');
|
||||
$this->upsertSettingValue('ABDM_BRIDGE_SSL_VERIFY', $sslVerify ? '1' : '0');
|
||||
|
||||
if ($saved === 0) {
|
||||
return $this->response->setJSON([
|
||||
|
|
@ -104,6 +110,7 @@ class AbdmGatewaySettings extends BaseController
|
|||
'error_text' => 'ABDM Gateway settings saved.',
|
||||
'token_exists' => $storedToken !== '',
|
||||
'token_masked' => $this->maskKey($storedToken),
|
||||
'ssl_verify' => $sslVerify,
|
||||
'csrfName' => csrf_token(),
|
||||
'csrfHash' => csrf_hash(),
|
||||
]);
|
||||
|
|
@ -139,6 +146,16 @@ class AbdmGatewaySettings extends BaseController
|
|||
|
||||
$gwUrl = rtrim($gwUrl, '/');
|
||||
|
||||
// ssl_verify: prefer explicitly posted value (from the unsaved form state),
|
||||
// else fall back to the stored setting. Defaults to secure (verify ON).
|
||||
$sslVerifyPosted = $this->request->getPost('ssl_verify');
|
||||
if ($sslVerifyPosted !== null) {
|
||||
$sslVerify = (bool) (int) $sslVerifyPosted;
|
||||
} else {
|
||||
$sslVerifyRaw = strtolower(trim($this->readSettingValue('ABDM_BRIDGE_SSL_VERIFY')));
|
||||
$sslVerify = ! in_array($sslVerifyRaw, ['0', 'false', 'no', 'off'], true);
|
||||
}
|
||||
|
||||
// ── Step 1: Health check — include Bearer if available (gateway may require auth even on /health) ──
|
||||
$healthUrl = $gwUrl . '/v3/health' . ($hfrId !== '' ? '?hfr_id=' . urlencode($hfrId) : '');
|
||||
$healthHeaders = ['Accept: application/json'];
|
||||
|
|
@ -150,7 +167,8 @@ class AbdmGatewaySettings extends BaseController
|
|||
CURLOPT_URL => $healthUrl,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_TIMEOUT => 10,
|
||||
CURLOPT_SSL_VERIFYPEER => true,
|
||||
CURLOPT_SSL_VERIFYPEER => $sslVerify,
|
||||
CURLOPT_SSL_VERIFYHOST => $sslVerify ? 2 : 0,
|
||||
CURLOPT_HTTPHEADER => $healthHeaders,
|
||||
]);
|
||||
$rawHealth = (string) curl_exec($ch);
|
||||
|
|
@ -222,7 +240,8 @@ class AbdmGatewaySettings extends BaseController
|
|||
CURLOPT_URL => $statusUrl,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_TIMEOUT => 10,
|
||||
CURLOPT_SSL_VERIFYPEER => true,
|
||||
CURLOPT_SSL_VERIFYPEER => $sslVerify,
|
||||
CURLOPT_SSL_VERIFYHOST => $sslVerify ? 2 : 0,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
'Accept: application/json',
|
||||
'Authorization: Bearer ' . $token,
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ class EAtriaBridgeConnector implements AbdmConnectorInterface
|
|||
private string $hfrId;
|
||||
private string $bridgeHospitalId;
|
||||
private int $timeoutSec;
|
||||
private bool $sslVerify = true;
|
||||
/** @var array<int, string> */
|
||||
private array $tokenCandidates = [];
|
||||
/** @var array<string, string> */
|
||||
|
|
@ -76,6 +77,7 @@ class EAtriaBridgeConnector implements AbdmConnectorInterface
|
|||
'ABDM_HOSPITAL_HFR_ID',
|
||||
'ABDM_BRIDGE_HOSPITAL_ID',
|
||||
'EATRIA_BRIDGE_HOSPITAL_ID',
|
||||
'ABDM_BRIDGE_SSL_VERIFY',
|
||||
]);
|
||||
|
||||
// Ensure deterministic override when duplicate setting rows exist.
|
||||
|
|
@ -147,6 +149,15 @@ class EAtriaBridgeConnector implements AbdmConnectorInterface
|
|||
if ($dbBridgeHospitalId !== '') {
|
||||
$this->bridgeHospitalId = $dbBridgeHospitalId;
|
||||
}
|
||||
|
||||
// SSL verification stays ON by default (secure). Admin → ABDM Gateway
|
||||
// page can opt out per-deployment for servers with a stale local CA
|
||||
// bundle (cURL error 60); an env override on that specific machine
|
||||
// takes precedence over the DB setting.
|
||||
$dbSslVerifyRaw = strtolower(trim((string) ($dbSettings['ABDM_BRIDGE_SSL_VERIFY'] ?? '')));
|
||||
if ($dbSslVerifyRaw !== '') {
|
||||
$this->sslVerify = ! in_array($dbSslVerifyRaw, ['0', 'false', 'no', 'off'], true);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
log_message('warning', '[EAtriaBridge] refreshRuntimeSettingsFromDb failed: ' . $e->getMessage());
|
||||
}
|
||||
|
|
@ -308,10 +319,13 @@ class EAtriaBridgeConnector implements AbdmConnectorInterface
|
|||
// SSL verification stays ON by default. Some local WAMP/XAMPP
|
||||
// installs ship a stale bundled cacert.pem, causing cURL error 60
|
||||
// on outbound HTTPS calls. Fix that by updating curl.cainfo in
|
||||
// php.ini on the affected machine; only as a last resort can a
|
||||
// specific deployment opt out via ABDM_BRIDGE_SSL_VERIFY=false.
|
||||
$sslVerifyRaw = strtolower(trim((string) (getenv('ABDM_BRIDGE_SSL_VERIFY') ?: '')));
|
||||
$sslVerify = ! in_array($sslVerifyRaw, ['0', 'false', 'no', 'off'], true);
|
||||
// php.ini on the affected machine, or opt out for this specific
|
||||
// deployment via Admin → ABDM Gateway (or ABDM_BRIDGE_SSL_VERIFY=false
|
||||
// in that machine's .env, which takes precedence).
|
||||
$sslVerifyEnvRaw = strtolower(trim((string) (getenv('ABDM_BRIDGE_SSL_VERIFY') ?: '')));
|
||||
$sslVerify = $sslVerifyEnvRaw !== ''
|
||||
? ! in_array($sslVerifyEnvRaw, ['0', 'false', 'no', 'off'], true)
|
||||
: $this->sslVerify;
|
||||
|
||||
$ch = curl_init();
|
||||
$curlOptions = [
|
||||
|
|
|
|||
|
|
@ -19,16 +19,26 @@ class M3HiuGatewayClient
|
|||
* WAMP/XAMPP/Laragon installs ship a stale bundled cacert.pem which makes
|
||||
* outbound HTTPS calls fail with cURL error 60 (SSL certificate problem).
|
||||
* Rather than disabling verification for everyone, allow an explicit,
|
||||
* per-deployment opt-out via env for that specific broken environment:
|
||||
* ABDM_BRIDGE_SSL_VERIFY=false
|
||||
* The correct long-term fix on the affected machine is to update PHP's
|
||||
* CA bundle (curl.cainfo in php.ini), not to disable verification.
|
||||
* per-deployment opt-out configured in Admin → ABDM Gateway
|
||||
* (hospital_setting.ABDM_BRIDGE_SSL_VERIFY), or via env for that specific
|
||||
* machine (ABDM_BRIDGE_SSL_VERIFY=false, takes precedence over the DB
|
||||
* setting). The correct long-term fix on the affected machine is to
|
||||
* update PHP's CA bundle (curl.cainfo in php.ini), not to disable
|
||||
* verification.
|
||||
*/
|
||||
private function sslVerifyEnabled(): bool
|
||||
private function sslVerifyEnabled(string $dbSetting = ''): bool
|
||||
{
|
||||
$raw = strtolower(trim((string) (getenv('ABDM_BRIDGE_SSL_VERIFY') ?: '')));
|
||||
$envRaw = strtolower(trim((string) (getenv('ABDM_BRIDGE_SSL_VERIFY') ?: '')));
|
||||
if ($envRaw !== '') {
|
||||
return ! in_array($envRaw, ['0', 'false', 'no', 'off'], true);
|
||||
}
|
||||
|
||||
return ! in_array($raw, ['0', 'false', 'no', 'off'], true);
|
||||
$dbRaw = strtolower(trim($dbSetting));
|
||||
if ($dbRaw !== '') {
|
||||
return ! in_array($dbRaw, ['0', 'false', 'no', 'off'], true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function sanitizeBearerToken(string $token): string
|
||||
|
|
@ -105,7 +115,7 @@ class M3HiuGatewayClient
|
|||
$headers[] = 'X-Hospital-Id: ' . $hospitalId;
|
||||
}
|
||||
|
||||
$sslVerify = $this->sslVerifyEnabled();
|
||||
$sslVerify = $this->sslVerifyEnabled((string) ($settings['ssl_verify'] ?? ''));
|
||||
$ch = curl_init();
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => $url,
|
||||
|
|
@ -285,7 +295,7 @@ class M3HiuGatewayClient
|
|||
$url .= '?' . http_build_query($cleanQuery);
|
||||
}
|
||||
|
||||
$sslVerify = $this->sslVerifyEnabled();
|
||||
$sslVerify = $this->sslVerifyEnabled((string) ($settings['ssl_verify'] ?? ''));
|
||||
$ch = curl_init();
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => $url,
|
||||
|
|
@ -408,6 +418,7 @@ class M3HiuGatewayClient
|
|||
'ABDM_BRIDGE_HOSPITAL_ID',
|
||||
'EATRIA_BRIDGE_HOSPITAL_ID',
|
||||
'EATRIA_BRIDGE_URL',
|
||||
'ABDM_BRIDGE_SSL_VERIFY',
|
||||
]);
|
||||
if ($orderCol !== null) {
|
||||
$rowsBuilder->orderBy($orderCol, 'DESC');
|
||||
|
|
@ -452,6 +463,7 @@ class M3HiuGatewayClient
|
|||
'hfr_id' => $hfrId,
|
||||
'hospital_id' => $hospitalId,
|
||||
'base_url' => $baseUrl,
|
||||
'ssl_verify' => (string) ($kv['ABDM_BRIDGE_SSL_VERIFY'] ?? ''),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,27 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SSL Verification -->
|
||||
<div class="mb-3">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="abdm_ssl_verify"
|
||||
<?= (! isset($ssl_verify) || $ssl_verify) ? 'checked' : '' ?>>
|
||||
<label class="form-check-label fw-semibold" for="abdm_ssl_verify">Verify SSL Certificate</label>
|
||||
</div>
|
||||
<div class="form-text">
|
||||
Keep this <strong>ON</strong> (default). Only turn it <strong>OFF</strong> if this server's local PHP
|
||||
has an outdated CA certificate bundle causing "SSL certificate problem" (cURL error 60) errors when
|
||||
calling the gateway — this is a local server issue, not a gateway issue. Disabling verification
|
||||
removes protection against man-in-the-middle attacks, so use it only as a temporary workaround on a
|
||||
trusted network while the server's CA bundle is updated.
|
||||
</div>
|
||||
<div class="alert alert-warning py-1 px-2 mt-1 d-none" id="abdm_ssl_verify_warning" style="font-size:12px">
|
||||
<i class="bi bi-exclamation-triangle me-1"></i>SSL verification is OFF. Health data will still be
|
||||
encrypted in transit, but the gateway's certificate identity won't be checked. Turn this back on once
|
||||
the server's CA bundle is fixed.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- API Key -->
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-semibold">API Key (Bearer Token)</label>
|
||||
|
|
@ -90,6 +111,13 @@
|
|||
<?= esc($gateway_url ?? 'https://abdm-bridge.e-atria.in/api') ?>
|
||||
</a>
|
||||
</span>
|
||||
<span><strong>SSL Verify:</strong>
|
||||
<?php if (! isset($ssl_verify) || $ssl_verify) : ?>
|
||||
<span class="badge bg-success">ON</span>
|
||||
<?php else : ?>
|
||||
<span class="badge bg-warning text-dark">OFF</span>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -180,10 +208,17 @@
|
|||
gateway_url: ($('#abdm_gateway_url').val() || '').trim(),
|
||||
api_token: ($('#abdm_api_token').val() || '').trim(),
|
||||
hfr_id: ($('#abdm_hfr_id').val() || '').trim(),
|
||||
hms_name: ($('#abdm_hms_name').val() || '').trim()
|
||||
hms_name: ($('#abdm_hms_name').val() || '').trim(),
|
||||
ssl_verify: $('#abdm_ssl_verify').is(':checked') ? 1 : 0
|
||||
};
|
||||
}
|
||||
|
||||
function updateSslWarning() {
|
||||
$('#abdm_ssl_verify_warning').toggleClass('d-none', $('#abdm_ssl_verify').is(':checked'));
|
||||
}
|
||||
updateSslWarning();
|
||||
$('#abdm_ssl_verify').on('change', updateSslWarning);
|
||||
|
||||
// Toggle show/hide API key
|
||||
$('#btn_toggle_abdm_token').on('click', function () {
|
||||
var inp = document.getElementById('abdm_api_token');
|
||||
|
|
|
|||
5
check_ssl_setting.php
Normal file
5
check_ssl_setting.php
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
$db = new mysqli('localhost', 'root', '', 'hms_data_ci4');
|
||||
$res = $db->query("SELECT s_name, s_value FROM hospital_setting WHERE s_name = 'ABDM_BRIDGE_SSL_VERIFY'");
|
||||
while ($row = $res->fetch_assoc()) { print_r($row); }
|
||||
$db->close();
|
||||
Loading…
Reference in New Issue
Block a user