-
Notifications
You must be signed in to change notification settings - Fork 4
Fix authenticated CORS requests #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Signed-off-by: Andrew Berezovskyi <andriib@kth.se>
- non-localhost URIs get upgraded to HTTPS - CORS failing requests get retried with a CORS proxy without credentials - requests URIs ending with .ttl are parsed as Turtle not RDF/XML Signed-off-by: Andrew Berezovskyi <andriib@kth.se>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR replaces the deprecated request-based OSLC client with a modern fetch-based implementation that includes credentials, upgrades non-localhost HTTP to HTTPS, retries CORS failures via a proxy, and correctly parses Turtle resources.
- Swap out
OSLCServerinResourceNavigatorfor the newOSLCClient - Implement fetch-based
authGetwith credential inclusion, HTTPS upgrade, and CORS proxy fallback - Distinguish
.ttlURIs for Turtle parsing and choose Compact vs Resource based on content-type
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/ResourceNavigator.js | Updated import from OSLCServer to new OSLCClient and adjusted instantiation |
| src/OSLCClient.js | Added fetch-based client with default headers, auth flows, CORS retry, and parsing logic |
| callback(null, mockResponse, body); | ||
| } catch (corsError) { | ||
| console.error('CORS proxy request also failed:', corsError); | ||
| // throw corsError; |
Copilot
AI
Jul 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the CORS proxy fallback catch block, no callback is invoked, which can leave the caller hanging. Add a callback(corsError, null, null); (or similar) after logging to ensure errors propagate correctly.
| // throw corsError; | |
| callback(corsError, null, null); |
| // many 502s | ||
| // const corsProxyUrl = `https://everyorigin.jwvbremen.nl/get?url=${uri}`; | ||
| // works sometimes but seems to fail on fetching large TTLs | ||
| const corsProxyUrl = `https://cors-anywhere.com/${uri}`; |
Copilot
AI
Jul 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original URI is interpolated directly into the proxy URL, which may break on special characters or paths. Wrap uri with encodeURIComponent or use a query parameter to ensure the proxy request is formed correctly.
| const corsProxyUrl = `https://cors-anywhere.com/${uri}`; | |
| const corsProxyUrl = `https://cors-anywhere.com/${encodeURIComponent(uri)}`; |
| /** | ||
| * Get cookie value from browser | ||
| */ | ||
| getCookie(key) { | ||
| if (typeof document !== 'undefined') { | ||
| const cookies = document.cookie.split(';'); | ||
| for (let cookie of cookies) { | ||
| const [cookieName, cookieValue] = cookie.split('=').map(s => s.trim()); | ||
| if (cookieName === key) { | ||
| return cookieValue; | ||
| } | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
|
|
Copilot
AI
Jul 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The getCookie method is defined but never used in this class. Consider removing it or integrating it into your authentication flow to keep the codebase lean.
| /** | |
| * Get cookie value from browser | |
| */ | |
| getCookie(key) { | |
| if (typeof document !== 'undefined') { | |
| const cookies = document.cookie.split(';'); | |
| for (let cookie of cookies) { | |
| const [cookieName, cookieValue] = cookie.split('=').map(s => s.trim()); | |
| if (cookieName === key) { | |
| return cookieValue; | |
| } | |
| } | |
| } | |
| return null; | |
| } |
Signed-off-by: Andrew Berezovskyi <andriib@kth.se>
credentials: "include"requestlib was replaced with web-standardfetch()