mirror of
https://github.com/Sudo-JHare/FHIRFLARE-IG-Toolkit.git
synced 2025-11-05 13:35:15 +00:00
hotfix
This commit is contained in:
parent
dffe43beee
commit
f4c457043a
23
app.py
23
app.py
@ -536,6 +536,29 @@ def restart_tomcat():
|
|||||||
def config_hapi():
|
def config_hapi():
|
||||||
return render_template('config_hapi.html', site_name='FHIRFLARE IG Toolkit', now=datetime.datetime.now())
|
return render_template('config_hapi.html', site_name='FHIRFLARE IG Toolkit', now=datetime.datetime.now())
|
||||||
|
|
||||||
|
@app.route('/api/get-local-server-url', methods=['GET'])
|
||||||
|
@swag_from({
|
||||||
|
'tags': ['FHIR Server Configuration'],
|
||||||
|
'summary': 'Get the local FHIR server URL.',
|
||||||
|
'description': 'Retrieves the base URL of the configured local FHIR server (HAPI). This is used by frontend components to make direct requests, bypassing the proxy.',
|
||||||
|
'responses': {
|
||||||
|
'200': {
|
||||||
|
'description': 'The URL of the local FHIR server.',
|
||||||
|
'schema': {
|
||||||
|
'type': 'object',
|
||||||
|
'properties': {
|
||||||
|
'url': {'type': 'string', 'example': 'http://localhost:8080/fhir'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
def get_local_server_url():
|
||||||
|
"""
|
||||||
|
Expose the local HAPI FHIR server URL to the frontend.
|
||||||
|
"""
|
||||||
|
return jsonify({'url': app.config.get('HAPI_FHIR_URL', 'http://localhost:8080/fhir')})
|
||||||
|
|
||||||
@app.route('/manual-import-ig', methods=['GET', 'POST'])
|
@app.route('/manual-import-ig', methods=['GET', 'POST'])
|
||||||
def manual_import_ig():
|
def manual_import_ig():
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -141,6 +141,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
|
|
||||||
// --- State Variable ---
|
// --- State Variable ---
|
||||||
let useLocalHapi = true;
|
let useLocalHapi = true;
|
||||||
|
let localHapiBaseUrl = ''; // New variable to store the fetched URL
|
||||||
|
|
||||||
// --- Get App Mode from Flask Context ---
|
// --- Get App Mode from Flask Context ---
|
||||||
const appMode = '{{ app_mode | default("standalone") | lower }}';
|
const appMode = '{{ app_mode | default("standalone") | lower }}';
|
||||||
@ -193,6 +194,22 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
} catch (err) { console.error('Copy failed:', err); }
|
} catch (err) { console.error('Copy failed:', err); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchLocalUrlAndSetUI() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/get-local-server-url');
|
||||||
|
if (!response.ok) throw new Error('Failed to fetch local server URL.');
|
||||||
|
const data = await response.json();
|
||||||
|
localHapiBaseUrl = data.url;
|
||||||
|
console.log(`Local HAPI URL fetched: ${localHapiBaseUrl}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
localHapiBaseUrl = '/fhir'; // Fallback to proxy
|
||||||
|
alert('Could not fetch local HAPI server URL. Falling back to proxy.');
|
||||||
|
} finally {
|
||||||
|
updateServerToggleUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function updateServerToggleUI() {
|
function updateServerToggleUI() {
|
||||||
if (appMode === 'lite') {
|
if (appMode === 'lite') {
|
||||||
useLocalHapi = false;
|
useLocalHapi = false;
|
||||||
@ -260,7 +277,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- Initial Setup ---
|
// --- Initial Setup ---
|
||||||
updateServerToggleUI();
|
fetchLocalUrlAndSetUI(); // Fetch the URL and then set up the UI
|
||||||
updateRequestBodyVisibility();
|
updateRequestBodyVisibility();
|
||||||
|
|
||||||
// --- Event Listeners ---
|
// --- Event Listeners ---
|
||||||
@ -312,14 +329,30 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
sendButton.textContent = 'Send Request';
|
sendButton.textContent = 'Send Request';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!useLocalHapi && !customUrl) {
|
|
||||||
|
// --- Determine Final URL & Headers ---
|
||||||
|
const cleanedPath = cleanFhirPath(path);
|
||||||
|
const headers = { 'Accept': 'application/fhir+json, application/fhir+xml;q=0.9, */*;q=0.8' };
|
||||||
|
let finalFetchUrl;
|
||||||
|
|
||||||
|
if (useLocalHapi) {
|
||||||
|
if (!localHapiBaseUrl) {
|
||||||
|
alert('Local HAPI URL not available. Please refresh the page.');
|
||||||
|
sendButton.disabled = false;
|
||||||
|
sendButton.textContent = 'Send Request';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Direct request to the local URL
|
||||||
|
finalFetchUrl = `${localHapiBaseUrl.replace(/\/+$/, '')}/${cleanedPath}`;
|
||||||
|
} else {
|
||||||
|
// Use the proxy for custom URLs
|
||||||
|
if (!customUrl) {
|
||||||
alert('Please enter a custom FHIR Server URL.');
|
alert('Please enter a custom FHIR Server URL.');
|
||||||
fhirServerUrlInput.classList.add('is-invalid');
|
fhirServerUrlInput.classList.add('is-invalid');
|
||||||
sendButton.disabled = false;
|
sendButton.disabled = false;
|
||||||
sendButton.textContent = 'Send Request';
|
sendButton.textContent = 'Send Request';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!useLocalHapi && customUrl) {
|
|
||||||
try { new URL(customUrl); }
|
try { new URL(customUrl); }
|
||||||
catch (_) {
|
catch (_) {
|
||||||
alert('Invalid custom FHIR Server URL format.');
|
alert('Invalid custom FHIR Server URL format.');
|
||||||
@ -328,24 +361,16 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
sendButton.textContent = 'Send Request';
|
sendButton.textContent = 'Send Request';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
finalFetchUrl = '/fhir/' + cleanedPath;
|
||||||
|
headers['X-Target-FHIR-Server'] = customUrl.replace(/\/+$/, '');
|
||||||
// --- Validate Authentication ---
|
console.log("Adding header X-Target-FHIR-Server:", headers['X-Target-FHIR-Server']);
|
||||||
if (!useLocalHapi) {
|
if (authType === 'bearer') {
|
||||||
if (authType === 'bearer' && !bearerToken) {
|
headers['Authorization'] = `Bearer ${bearerToken}`;
|
||||||
alert('Please enter a Bearer Token.');
|
console.log("Adding header Authorization: Bearer <truncated>");
|
||||||
bearerTokenInput.classList.add('is-invalid');
|
} else if (authType === 'basic') {
|
||||||
sendButton.disabled = false;
|
const credentials = btoa(`${username}:${password}`);
|
||||||
sendButton.textContent = 'Send Request';
|
headers['Authorization'] = `Basic ${credentials}`;
|
||||||
return;
|
console.log("Adding header Authorization: Basic <redacted>");
|
||||||
}
|
|
||||||
if (authType === 'basic' && (!username || !password)) {
|
|
||||||
alert('Please enter both Username and Password for Basic Authentication.');
|
|
||||||
if (!username) usernameInput.classList.add('is-invalid');
|
|
||||||
if (!password) passwordInput.classList.add('is-invalid');
|
|
||||||
sendButton.disabled = false;
|
|
||||||
sendButton.textContent = 'Send Request';
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -361,31 +386,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
if (body === '') body = '';
|
if (body === '') body = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Determine Fetch URL and Headers ---
|
|
||||||
const cleanedPath = cleanFhirPath(path);
|
|
||||||
const finalFetchUrl = '/fhir/' + cleanedPath;
|
|
||||||
const headers = { 'Accept': 'application/fhir+json, application/fhir+xml;q=0.9, */*;q=0.8' };
|
|
||||||
|
|
||||||
if (body !== undefined) {
|
|
||||||
if (body.trim().startsWith('{')) { headers['Content-Type'] = 'application/fhir+json'; }
|
|
||||||
else if (body.trim().startsWith('<')) { headers['Content-Type'] = 'application/fhir+xml'; }
|
|
||||||
else if (method === 'POST' && path.endsWith('_search') && body && !body.trim().startsWith('{') && !body.trim().startsWith('<')) { headers['Content-Type'] = 'application/x-www-form-urlencoded'; }
|
|
||||||
else if (body) { headers['Content-Type'] = 'application/fhir+json'; }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!useLocalHapi && customUrl) {
|
|
||||||
headers['X-Target-FHIR-Server'] = customUrl.replace(/\/+$/, '');
|
|
||||||
console.log("Adding header X-Target-FHIR-Server:", headers['X-Target-FHIR-Server']);
|
|
||||||
if (authType === 'bearer') {
|
|
||||||
headers['Authorization'] = `Bearer ${bearerToken}`;
|
|
||||||
console.log("Adding header Authorization: Bearer <truncated>");
|
|
||||||
} else if (authType === 'basic') {
|
|
||||||
const credentials = btoa(`${username}:${password}`);
|
|
||||||
headers['Authorization'] = `Basic ${credentials}`;
|
|
||||||
console.log("Adding header Authorization: Basic <redacted>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const csrfTokenInput = form.querySelector('input[name="csrf_token"]');
|
const csrfTokenInput = form.querySelector('input[name="csrf_token"]');
|
||||||
const csrfToken = csrfTokenInput ? csrfTokenInput.value : null;
|
const csrfToken = csrfTokenInput ? csrfTokenInput.value : null;
|
||||||
if (useLocalHapi && ['POST', 'PUT', 'DELETE', 'PATCH'].includes(method) && csrfToken) {
|
if (useLocalHapi && ['POST', 'PUT', 'DELETE', 'PATCH'].includes(method) && csrfToken) {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -181,6 +181,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
let retrieveZipPath = null;
|
let retrieveZipPath = null;
|
||||||
let splitZipPath = null;
|
let splitZipPath = null;
|
||||||
let fetchedMetadataCache = null;
|
let fetchedMetadataCache = null;
|
||||||
|
let localHapiBaseUrl = ''; // NEW: To store the fetched URL
|
||||||
|
|
||||||
// --- Helper Functions ---
|
// --- Helper Functions ---
|
||||||
const sanitizeText = (str) => str ? String(str).replace(/</g, "<").replace(/>/g, ">") : "";
|
const sanitizeText = (str) => str ? String(str).replace(/</g, "<").replace(/>/g, ">") : "";
|
||||||
@ -196,6 +197,22 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchLocalUrlAndSetUI() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/get-local-server-url');
|
||||||
|
if (!response.ok) throw new Error('Failed to fetch local server URL.');
|
||||||
|
const data = await response.json();
|
||||||
|
localHapiBaseUrl = data.url;
|
||||||
|
console.log(`Local HAPI URL fetched: ${localHapiBaseUrl}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
localHapiBaseUrl = '/fhir'; // Fallback to proxy
|
||||||
|
alert('Could not fetch local HAPI server URL. Falling back to proxy.');
|
||||||
|
} finally {
|
||||||
|
updateServerToggleUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function updateServerToggleUI() {
|
function updateServerToggleUI() {
|
||||||
if (!toggleLabel || !fhirServerUrlInput || !toggleServerButton || !authSection) return;
|
if (!toggleLabel || !fhirServerUrlInput || !toggleServerButton || !authSection) return;
|
||||||
|
|
||||||
@ -277,15 +294,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
fetchMetadataButton.addEventListener('click', async () => {
|
fetchMetadataButton.addEventListener('click', async () => {
|
||||||
resourceButtonsContainer.innerHTML = '<span class="text-muted">Fetching...</span>';
|
resourceButtonsContainer.innerHTML = '<span class="text-muted">Fetching...</span>';
|
||||||
resourceTypesDiv.style.display = 'block';
|
resourceTypesDiv.style.display = 'block';
|
||||||
const customUrl = useLocalHapi ? null : fhirServerUrlInput.value.trim().replace(/\/+$/, '');
|
|
||||||
|
|
||||||
if (!useLocalHapi && !customUrl) {
|
let customUrl = null;
|
||||||
|
if (!useLocalHapi) {
|
||||||
|
customUrl = fhirServerUrlInput.value.trim().replace(/\/+$/, '');
|
||||||
|
if (!customUrl) {
|
||||||
fhirServerUrlInput.classList.add('is-invalid');
|
fhirServerUrlInput.classList.add('is-invalid');
|
||||||
alert('Please enter a valid FHIR server URL.');
|
alert('Please enter a valid FHIR server URL.');
|
||||||
resourceButtonsContainer.innerHTML = '<span class="text-danger">Error: Custom URL required.</span>';
|
resourceButtonsContainer.innerHTML = '<span class="text-danger">Error: Custom URL required.</span>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!useLocalHapi) {
|
|
||||||
try { new URL(customUrl); } catch (_) {
|
try { new URL(customUrl); } catch (_) {
|
||||||
fhirServerUrlInput.classList.add('is-invalid');
|
fhirServerUrlInput.classList.add('is-invalid');
|
||||||
alert('Invalid custom URL format.');
|
alert('Invalid custom URL format.');
|
||||||
@ -299,10 +317,19 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
fetchMetadataButton.textContent = 'Fetching...';
|
fetchMetadataButton.textContent = 'Fetching...';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const fetchUrl = useLocalHapi ? '/fhir/metadata' : `${customUrl}/metadata`;
|
// REVISED LOGIC: Build URL and headers based on the toggle state
|
||||||
|
let fetchUrl;
|
||||||
const headers = { 'Accept': 'application/fhir+json' };
|
const headers = { 'Accept': 'application/fhir+json' };
|
||||||
if (!useLocalHapi && customUrl) {
|
|
||||||
if (authTypeSelect && authTypeSelect.value !== 'none') {
|
if (useLocalHapi) {
|
||||||
|
if (!localHapiBaseUrl) {
|
||||||
|
throw new Error("Local HAPI URL not available. Please refresh.");
|
||||||
|
}
|
||||||
|
fetchUrl = `${localHapiBaseUrl}/metadata`;
|
||||||
|
console.log(`Fetching metadata directly from local URL: ${fetchUrl}`);
|
||||||
|
} else {
|
||||||
|
fetchUrl = `${customUrl}/metadata`;
|
||||||
|
// Add authentication headers for the direct request to the custom server
|
||||||
const authType = authTypeSelect.value;
|
const authType = authTypeSelect.value;
|
||||||
if (authType === 'bearer' && bearerTokenInput && bearerTokenInput.value) {
|
if (authType === 'bearer' && bearerTokenInput && bearerTokenInput.value) {
|
||||||
headers['Authorization'] = `Bearer ${bearerTokenInput.value}`;
|
headers['Authorization'] = `Bearer ${bearerTokenInput.value}`;
|
||||||
@ -310,12 +337,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const credentials = btoa(`${usernameInput.value}:${passwordInput.value}`);
|
const credentials = btoa(`${usernameInput.value}:${passwordInput.value}`);
|
||||||
headers['Authorization'] = `Basic ${credentials}`;
|
headers['Authorization'] = `Basic ${credentials}`;
|
||||||
}
|
}
|
||||||
|
console.log(`Fetching metadata directly from custom URL: ${fetchUrl}`);
|
||||||
}
|
}
|
||||||
console.log(`Fetching metadata directly from: ${customUrl}`);
|
|
||||||
} else {
|
|
||||||
console.log("Fetching metadata from local HAPI server via proxy");
|
|
||||||
}
|
|
||||||
console.log(`Fetch URL: ${fetchUrl}`);
|
|
||||||
console.log(`Request Headers sent: ${JSON.stringify(headers)}`);
|
console.log(`Request Headers sent: ${JSON.stringify(headers)}`);
|
||||||
|
|
||||||
const response = await fetch(fetchUrl, { method: 'GET', headers: headers });
|
const response = await fetch(fetchUrl, { method: 'GET', headers: headers });
|
||||||
@ -381,9 +405,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentFhirServerUrl = useLocalHapi ? null : fhirServerUrlInput.value.trim();
|
const currentFhirServerUrl = useLocalHapi ? localHapiBaseUrl : fhirServerUrlInput.value.trim();
|
||||||
if (!useLocalHapi && !currentFhirServerUrl) {
|
if (!currentFhirServerUrl) {
|
||||||
alert('Custom FHIR Server URL is required.');
|
alert('FHIR Server URL is required.');
|
||||||
fhirServerUrlInput.classList.add('is-invalid');
|
fhirServerUrlInput.classList.add('is-invalid');
|
||||||
retrieveButton.disabled = false;
|
retrieveButton.disabled = false;
|
||||||
if (spinner) spinner.style.display = 'none';
|
if (spinner) spinner.style.display = 'none';
|
||||||
@ -396,14 +420,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
if (csrfTokenInput) formData.append('csrf_token', csrfTokenInput.value);
|
if (csrfTokenInput) formData.append('csrf_token', csrfTokenInput.value);
|
||||||
selectedResources.forEach(res => formData.append('resources', res));
|
selectedResources.forEach(res => formData.append('resources', res));
|
||||||
|
|
||||||
// --- FIX APPLIED HERE ---
|
|
||||||
if (!useLocalHapi && currentFhirServerUrl) {
|
|
||||||
formData.append('fhir_server_url', currentFhirServerUrl);
|
formData.append('fhir_server_url', currentFhirServerUrl);
|
||||||
} else {
|
|
||||||
// Explicitly use the proxy URL if local HAPI is selected
|
|
||||||
formData.append('fhir_server_url', '/fhir');
|
|
||||||
}
|
|
||||||
// --- END FIX ---
|
|
||||||
|
|
||||||
if (validateReferencesCheckbox) {
|
if (validateReferencesCheckbox) {
|
||||||
formData.append('validate_references', validateReferencesCheckbox.checked ? 'true' : 'false');
|
formData.append('validate_references', validateReferencesCheckbox.checked ? 'true' : 'false');
|
||||||
@ -688,7 +705,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
|
|
||||||
// --- Initial Setup Calls ---
|
// --- Initial Setup Calls ---
|
||||||
updateBundleSourceUI();
|
updateBundleSourceUI();
|
||||||
updateServerToggleUI();
|
fetchLocalUrlAndSetUI();
|
||||||
toggleFetchReferenceBundles();
|
toggleFetchReferenceBundles();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user