mirror of
https://github.com/Sudo-JHare/FHIRFLARE-IG-Toolkit.git
synced 2025-06-15 13:09:59 +00:00
incremental
fhir-ui-operations - origin/proxy url protection checks and warnings fixed
This commit is contained in:
parent
8e769bd126
commit
a28ecec025
@ -1,6 +1,6 @@
|
|||||||
#FileLock
|
#FileLock
|
||||||
#Sat Apr 19 22:16:34 UTC 2025
|
#Sat Apr 19 23:58:47 UTC 2025
|
||||||
server=172.18.0.2\:46549
|
server=172.18.0.2\:33791
|
||||||
hostName=5fcfaca62eed
|
hostName=edfd6b88589d
|
||||||
method=file
|
method=file
|
||||||
id=196501fef4b8f140e4827bc0866757e1c405fd48a82
|
id=196507d8451106de1bd0820c05fb574d4e048158077
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -345,94 +345,87 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
let operationDefinitionCache = {}; // <<< ADD THIS LINE: Cache for fetched OperationDefinitions
|
let operationDefinitionCache = {}; // <<< ADD THIS LINE: Cache for fetched OperationDefinitions
|
||||||
|
|
||||||
// <<< REFINED fetchOperationDefinition >>>
|
// <<< REFINED fetchOperationDefinition >>>
|
||||||
|
// <<< REFINED fetchOperationDefinition (v3 - Handles Local Proxy Target Correctly) >>>
|
||||||
async function fetchOperationDefinition(definitionUrl) {
|
async function fetchOperationDefinition(definitionUrl) {
|
||||||
if (!definitionUrl) return null;
|
if (!definitionUrl) return null;
|
||||||
|
|
||||||
if (operationDefinitionCache.hasOwnProperty(definitionUrl)) {
|
if (operationDefinitionCache.hasOwnProperty(definitionUrl)) {
|
||||||
// console.log(`Using cached OperationDefinition: ${definitionUrl}`);
|
|
||||||
return operationDefinitionCache[definitionUrl];
|
return operationDefinitionCache[definitionUrl];
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Determine Fetch URL (Allow Same-Origin Absolute, Prevent External) ---
|
|
||||||
let fetchUrl;
|
let fetchUrl;
|
||||||
const currentBaseUrl = isUsingLocalHapi ? '/fhir' : (fhirServerUrlInput.value.trim().replace(/\/+$/, '') || '/fhir');
|
const currentBaseUrl = isUsingLocalHapi ? '/fhir' : (fhirServerUrlInput.value.trim().replace(/\/+$/, '') || '/fhir');
|
||||||
let currentOrigin = '';
|
const expectedHapiBase = 'http://localhost:8080/fhir/'; // Define the expected proxied server base
|
||||||
// Determine the origin of the current FHIR server target
|
|
||||||
try {
|
|
||||||
// For the local proxy '/fhir', the origin is the app's origin
|
|
||||||
if (isUsingLocalHapi || currentBaseUrl.startsWith('/')) {
|
|
||||||
currentOrigin = window.location.origin;
|
|
||||||
} else {
|
|
||||||
currentOrigin = new URL(currentBaseUrl).origin;
|
|
||||||
}
|
|
||||||
} catch(e) {
|
|
||||||
console.error("Could not determine origin for current FHIR base URL:", currentBaseUrl, e);
|
|
||||||
// Fallback: Treat as different origin to be safe
|
|
||||||
currentOrigin = window.location.origin; // Or potentially block all absolute URLs if this fails
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Check if definitionUrl is an absolute HTTP/S URL
|
// Check if definitionUrl is an absolute HTTP/S URL
|
||||||
if (definitionUrl.startsWith('http://') || definitionUrl.startsWith('https://')) {
|
if (definitionUrl.startsWith('http://') || definitionUrl.startsWith('https://')) {
|
||||||
const definitionOrigin = new URL(definitionUrl).origin;
|
// --- Logic when using Local HAPI Proxy ---
|
||||||
// ALLOW fetch if definition URL origin MATCHES the current FHIR target origin
|
if (isUsingLocalHapi) {
|
||||||
if (definitionOrigin === currentOrigin) {
|
// If the absolute URL starts with the expected HAPI base, rewrite it for the proxy
|
||||||
// It's an absolute URL, but points to the same server target.
|
if (definitionUrl.startsWith(expectedHapiBase)) {
|
||||||
// If using local HAPI proxy, we need to rewrite the URL
|
const relativePath = definitionUrl.substring(expectedHapiBase.length);
|
||||||
// to go through the proxy.
|
fetchUrl = `${currentBaseUrl}/${relativePath}`; // Use '/fhir/...' proxy path
|
||||||
if (isUsingLocalHapi) {
|
console.log(`Fetching same-origin absolute OpDef via proxy: ${fetchUrl} (Original: ${definitionUrl})`);
|
||||||
// Extract path after base URL/port
|
} else {
|
||||||
const urlParts = definitionUrl.split('/');
|
// Absolute URL, using proxy, but NOT pointing to expected HAPI base -> Skip (likely external)
|
||||||
// Find the part after the hostname/port (usually index 3)
|
console.warn(`Skipping fetch for external absolute URL while using proxy: ${definitionUrl}`);
|
||||||
const pathIndex = urlParts.findIndex((part, index) => index > 2 && part);
|
operationDefinitionCache[definitionUrl] = null; return null;
|
||||||
const relativePath = pathIndex !== -1 ? urlParts.slice(pathIndex).join('/') : '';
|
}
|
||||||
|
}
|
||||||
|
// --- Logic when using Custom URL ---
|
||||||
|
else {
|
||||||
|
let currentOrigin = '';
|
||||||
|
try { currentOrigin = new URL(currentBaseUrl).origin; } catch(e) { currentOrigin = window.location.origin; } // Determine custom server origin
|
||||||
|
const definitionOrigin = new URL(definitionUrl).origin;
|
||||||
|
|
||||||
if (relativePath) {
|
if (definitionOrigin === currentOrigin) {
|
||||||
fetchUrl = `${currentBaseUrl}/${relativePath}`; // Use '/fhir/...'
|
// Same origin as custom URL - fetch directly
|
||||||
console.log(`Workspaceing same-origin absolute OperationDefinition via proxy: ${fetchUrl} (Original: ${definitionUrl})`);
|
fetchUrl = definitionUrl;
|
||||||
} else {
|
console.log(`Fetching same-origin absolute OpDef directly: ${fetchUrl}`);
|
||||||
console.warn(`Could not determine relative path for same-origin absolute URL: ${definitionUrl}. Skipping.`);
|
} else {
|
||||||
operationDefinitionCache[definitionUrl] = null; return null;
|
// Different origin than custom URL - skip
|
||||||
}
|
console.warn(`Skipping fetch for external absolute URL (different origin): ${definitionUrl}`);
|
||||||
} else {
|
operationDefinitionCache[definitionUrl] = null; return null;
|
||||||
// If using a custom URL, fetch it directly
|
}
|
||||||
fetchUrl = definitionUrl;
|
}
|
||||||
console.log(`Workspaceing same-origin absolute OperationDefinition directly: ${fetchUrl}`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Absolute URL pointing to a DIFFERENT origin - skip due to CORS
|
|
||||||
console.warn(`Skipping fetch for absolute external OperationDefinition URL: ${definitionUrl}`);
|
|
||||||
operationDefinitionCache[definitionUrl] = null; // Cache failure
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Not an absolute HTTP/S URL - treat as relative
|
|
||||||
fetchUrl = `${currentBaseUrl}/${definitionUrl.startsWith('/') ? definitionUrl.substring(1) : definitionUrl}`;
|
|
||||||
console.log(`Workspaceing relative OperationDefinition: ${fetchUrl} (Original: ${definitionUrl})`);
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
// --- Logic for Relative URLs ---
|
||||||
// If definitionUrl parsing failed (e.g., "Patient/$everything"), treat as relative
|
else {
|
||||||
|
// Not an absolute HTTP/S URL - treat as relative to currentBaseUrl
|
||||||
|
fetchUrl = `${currentBaseUrl}/${definitionUrl.startsWith('/') ? definitionUrl.substring(1) : definitionUrl}`;
|
||||||
|
console.log(`Fetching relative OperationDefinition: ${fetchUrl} (Original: ${definitionUrl})`);
|
||||||
|
}
|
||||||
|
} catch (e) { // Catch errors during URL parsing/logic above
|
||||||
|
console.error(`Error determining fetch URL for ${definitionUrl}: ${e}. Treating as relative.`);
|
||||||
fetchUrl = `${currentBaseUrl}/${definitionUrl.startsWith('/') ? definitionUrl.substring(1) : definitionUrl}`;
|
fetchUrl = `${currentBaseUrl}/${definitionUrl.startsWith('/') ? definitionUrl.substring(1) : definitionUrl}`;
|
||||||
console.log(`Workspaceing relative OperationDefinition (parse failed): ${fetchUrl} (Original: ${definitionUrl})`);
|
console.log(`Fetching relative OperationDefinition (fallback): ${fetchUrl} (Original: ${definitionUrl})`);
|
||||||
}
|
}
|
||||||
// --- End URL Determination ---
|
// --- End URL Determination ---
|
||||||
|
|
||||||
console.log(`Attempting to fetch OperationDefinition from: ${fetchUrl}`);
|
if (!fetchUrl) {
|
||||||
|
console.error(`Could not determine a valid fetchUrl for OperationDefinition: ${definitionUrl}`);
|
||||||
|
operationDefinitionCache[definitionUrl] = null; return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Attempting to fetch OperationDefinition from final URL: ${fetchUrl}`);
|
||||||
try {
|
try {
|
||||||
const response = await fetch(fetchUrl, {
|
const response = await fetch(fetchUrl, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: { 'Accept': 'application/fhir+json' }
|
headers: { 'Accept': 'application/fhir+json' }
|
||||||
});
|
});
|
||||||
if (!response.ok) { /* ... handle HTTP error ... */ console.error(`HTTP ${response.status} fetching OperationDefinition ${fetchUrl}`); operationDefinitionCache[definitionUrl] = null; return null; }
|
if (!response.ok) { console.error(`HTTP ${response.status} fetching OpDef ${fetchUrl}`); operationDefinitionCache[definitionUrl] = null; return null; }
|
||||||
const definition = await response.json();
|
const definition = await response.json();
|
||||||
if (definition.resourceType !== 'OperationDefinition') { /* ... handle wrong type ... */ console.error(`Expected OperationDefinition, got ${definition.resourceType} from ${fetchUrl}`); operationDefinitionCache[definitionUrl] = null; return null; }
|
if (definition.resourceType !== 'OperationDefinition') { console.error(`Expected OpDef, got ${definition.resourceType} from ${fetchUrl}`); operationDefinitionCache[definitionUrl] = null; return null; }
|
||||||
console.log(`Successfully fetched and parsed OperationDefinition: ${fetchUrl}`);
|
console.log(`Successfully fetched and parsed OperationDefinition: ${fetchUrl}`);
|
||||||
operationDefinitionCache[definitionUrl] = definition;
|
operationDefinitionCache[definitionUrl] = definition;
|
||||||
return definition;
|
return definition;
|
||||||
} catch (error) { /* ... handle fetch/parse error ... */ console.error(`Failed to fetch or parse OperationDefinition ${fetchUrl}:`, error); operationDefinitionCache[definitionUrl] = null; return null; }
|
} catch (error) {
|
||||||
|
console.error(`Failed to fetch or parse OperationDefinition ${fetchUrl}:`, error);
|
||||||
|
operationDefinitionCache[definitionUrl] = null; return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// <<< END REFINED fetchOperationDefinition >>>
|
// <<< END REFINED fetchOperationDefinition (v3) >>>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user