Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/auth/webid-tls.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ function parseKeyObject(keyObj) {
async function fetchProfileKeys(webId) {
const response = await fetchWithTimeout(webId, {
headers: {
'Accept': 'application/ld+json, text/turtle, application/json'
'Accept': 'text/html'
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restricting the Accept header to only 'text/html' could break WebID-TLS authentication for profiles served exclusively as Turtle or JSON-LD. While this may work around conneg issues with HTML profiles, the code at lines 155-169 still handles multiple content types in the response. Consider using 'text/html, application/ld+json;q=0.9, text/turtle;q=0.8' to indicate HTML preference while maintaining backward compatibility with non-HTML profiles. Alternatively, if HTML-only is intentional, remove the dead code paths for handling Turtle and JSON-LD content types.

Suggested change
'Accept': 'text/html'
'Accept': 'text/html, application/ld+json;q=0.9, text/turtle;q=0.8'

Copilot uses AI. Check for mistakes.
}
});

Expand All @@ -157,7 +157,7 @@ async function fetchProfileKeys(webId) {
jsonLd = await turtleToJsonLd(text, webId);
} else if (contentType.includes('text/html')) {
// Try to extract JSON-LD from HTML data island
const jsonLdMatch = text.match(/<script\s+type=["']application\/ld\+json["']\s*>([\s\S]*?)<\/script>/i);
const jsonLdMatch = text.match(/<script[^>]*type=["']application\/ld\+json["'][^>]*>([\s\S]*?)<\/script>/i);
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The updated regex pattern for extracting JSON-LD from HTML profiles lacks test coverage. Since this change fixes authentication failures, consider adding tests that verify the regex correctly matches script tags with additional attributes (e.g., <script type="application/ld+json" id="me">) as well as the original format. This would prevent future regressions and validate the fix.

Copilot uses AI. Check for mistakes.
if (jsonLdMatch) {
jsonLd = JSON.parse(jsonLdMatch[1]);
} else {
Expand Down
50 changes: 50 additions & 0 deletions test/webid-tls.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,56 @@ describe('WebID-TLS', () => {
});
});

describe('HTML JSON-LD extraction regex', () => {
// Test the regex pattern used to extract JSON-LD from HTML profiles
const jsonLdRegex = /<script[^>]*type=["']application\/ld\+json["'][^>]*>([\s\S]*?)<\/script>/i;

it('should match basic script tag', () => {
const html = '<script type="application/ld+json">{"@id": "#me"}</script>';
const match = html.match(jsonLdRegex);
assert.ok(match, 'Should match basic script tag');
assert.strictEqual(match[1], '{"@id": "#me"}');
});

it('should match script tag with additional attributes', () => {
const html = '<script type="application/ld+json" id="me">{"@id": "#me"}</script>';
const match = html.match(jsonLdRegex);
assert.ok(match, 'Should match script tag with id attribute');
assert.strictEqual(match[1], '{"@id": "#me"}');
});

it('should match script tag with attributes before type', () => {
const html = '<script id="profile" type="application/ld+json">{"@id": "#me"}</script>';
const match = html.match(jsonLdRegex);
assert.ok(match, 'Should match script tag with id before type');
assert.strictEqual(match[1], '{"@id": "#me"}');
});

it('should match script tag with single quotes', () => {
const html = "<script type='application/ld+json'>{'@id': '#me'}</script>";
const match = html.match(jsonLdRegex);
assert.ok(match, 'Should match script tag with single quotes');
});

it('should match script tag with newlines in content', () => {
const html = `<script type="application/ld+json">
{
"@id": "#me",
"name": "Test"
}
</script>`;
const match = html.match(jsonLdRegex);
assert.ok(match, 'Should match script tag with multiline content');
assert.ok(match[1].includes('"@id": "#me"'));
});

it('should not match non-jsonld script tags', () => {
const html = '<script type="text/javascript">console.log("test")</script>';
const match = html.match(jsonLdRegex);
assert.strictEqual(match, null, 'Should not match JavaScript script tag');
});
});

describe('SAN format variations', () => {
it('should handle lowercase uri prefix', () => {
// Some certs might have lowercase
Expand Down