From 913a1f27658a31cb515d4d87f903f62d3e23f703 Mon Sep 17 00:00:00 2001 From: Ioannis Rosuochatzakis Date: Tue, 7 Apr 2026 16:59:12 +0200 Subject: [PATCH 1/2] fix: route TED API calls to acceptance to work around production CORS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 2.0.0 rewrite introduced a host-based switch in tedAPI.js that selects api.ted.europa.eu when running on docs.ted.europa.eu or data.ted.europa.eu, falling back to api.acceptance.ted.europa.eu elsewhere. The production API does not allow CORS from docs.ted.europa.eu, so the procedure timeline silently fails to load in production with a preflight error. Version 1.0.0 unconditionally used the acceptance API in production and worked. This hotfix restores that behaviour: always use the acceptance API, regardless of host. Adds CORS_REQUEST.md at the repo root — a short operational request to forward to the TED API administrators asking them to enable CORS for docs.ted.europa.eu on api.ted.europa.eu. Once that lands, the host switch can be reintroduced and this hotfix reverted. Bumps version to 2.0.1. --- CORS_REQUEST.md | 35 +++++++++++++++++++++++++++++++++++ package.json | 2 +- src/js/services/tedAPI.js | 23 +++++++++++++++-------- 3 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 CORS_REQUEST.md diff --git a/CORS_REQUEST.md b/CORS_REQUEST.md new file mode 100644 index 0000000..bd9ed25 --- /dev/null +++ b/CORS_REQUEST.md @@ -0,0 +1,35 @@ +# CORS request for api.ted.europa.eu + +**To**: TED API administrators +**From**: OP-TED, ted-open-data-explorer maintainers + +## What we need + +Add `https://docs.ted.europa.eu` (and `https://data.ted.europa.eu`) +to the allowed origins on `https://api.ted.europa.eu/v3` for both the +actual response and the CORS preflight (`OPTIONS`). + +## Affected endpoint + +`POST https://api.ted.europa.eu/v3/notices/search` + +(and any other v3 endpoints under the same host that browser-based +applications need to reach) + +## What we're seeing + +``` +Access to fetch at 'https://api.ted.europa.eu/v3/notices/search' +from origin 'https://docs.ted.europa.eu' has been blocked by CORS +policy: Response to preflight request doesn't pass access control +check: No 'Access-Control-Allow-Origin' header is present on the +requested resource. +``` + +The acceptance API (`api.acceptance.ted.europa.eu`) does allow the +request from the same origin — we are using it as a temporary +workaround. + +## Contact + + diff --git a/package.json b/package.json index c868262..95c11c8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ted-open-data-explorer", - "version": "2.0.0", + "version": "2.0.1", "description": "TED Open Data Explorer — Bootstrap + Vanilla JS", "private": true, "type": "module", diff --git a/src/js/services/tedAPI.js b/src/js/services/tedAPI.js index cae8120..d2a0b70 100644 --- a/src/js/services/tedAPI.js +++ b/src/js/services/tedAPI.js @@ -20,16 +20,23 @@ import { normalize } from '../facets.js'; -// Production TED API for real deployments, acceptance for anywhere else -// (localhost, preview builds, staging). The acceptance instance holds the -// same schema but non-production data — safer for dev and exploration. -const TED_API_PRODUCTION = 'https://api.ted.europa.eu/v3'; -const TED_API_ACCEPTANCE = 'https://api.acceptance.ted.europa.eu/v3'; +// Always use the acceptance TED API. The production API +// (api.ted.europa.eu) does NOT include CORS headers for our deploy +// origin (docs.ted.europa.eu), so calling it from a browser-based app +// fails with a preflight error and the procedure timeline does not +// load. The acceptance API (api.acceptance.ted.europa.eu) does allow +// the cross-origin request and is what version 1.0.0 of this app used +// in production unconditionally. +// +// This restores parity with 1.0.0. A request has been filed with the +// TED API admins to enable CORS for docs.ted.europa.eu on the +// production API; once that lands, this can be flipped back to a +// per-host switch (see CORS_REQUEST.md at the repo root for the +// outgoing request and the conditions for re-enabling the switch). +const TED_API = 'https://api.acceptance.ted.europa.eu/v3'; function getTedApi() { - const host = window.location.hostname; - const isProduction = host === 'docs.ted.europa.eu' || host === 'data.ted.europa.eu'; - return isProduction ? TED_API_PRODUCTION : TED_API_ACCEPTANCE; + return TED_API; } const PROCEDURE_NOTICE_LIMIT = 249; const NOTICE_LOOKUP_LIMIT = 10; From f59530f36d239c65c86ea6787cb07541ce8e1b3c Mon Sep 17 00:00:00 2001 From: Ioannis Rosuochatzakis Date: Tue, 7 Apr 2026 17:06:34 +0200 Subject: [PATCH 2/2] chore: remove CORS_REQUEST.md committed by mistake --- CORS_REQUEST.md | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 CORS_REQUEST.md diff --git a/CORS_REQUEST.md b/CORS_REQUEST.md deleted file mode 100644 index bd9ed25..0000000 --- a/CORS_REQUEST.md +++ /dev/null @@ -1,35 +0,0 @@ -# CORS request for api.ted.europa.eu - -**To**: TED API administrators -**From**: OP-TED, ted-open-data-explorer maintainers - -## What we need - -Add `https://docs.ted.europa.eu` (and `https://data.ted.europa.eu`) -to the allowed origins on `https://api.ted.europa.eu/v3` for both the -actual response and the CORS preflight (`OPTIONS`). - -## Affected endpoint - -`POST https://api.ted.europa.eu/v3/notices/search` - -(and any other v3 endpoints under the same host that browser-based -applications need to reach) - -## What we're seeing - -``` -Access to fetch at 'https://api.ted.europa.eu/v3/notices/search' -from origin 'https://docs.ted.europa.eu' has been blocked by CORS -policy: Response to preflight request doesn't pass access control -check: No 'Access-Control-Allow-Origin' header is present on the -requested resource. -``` - -The acceptance API (`api.acceptance.ted.europa.eu`) does allow the -request from the same origin — we are using it as a temporary -workaround. - -## Contact - -