Skip to content
Merged
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
24 changes: 23 additions & 1 deletion src/aggregator.js
Original file line number Diff line number Diff line change
Expand Up @@ -1425,7 +1425,29 @@ async function processArticle(article, sourceName, tags, category, feedLang) {
},
{
name: 'scribe.rip',
transform: (u) => u.includes('medium.com') ? u.replace('medium.com', 'scribe.rip') : null
transform: (u) => {
try {
const parsedUrl = new URL(u);
// Safely check if this is a medium.com URL by parsing the hostname
if (parsedUrl.hostname === 'medium.com' || parsedUrl.hostname.endsWith('.medium.com')) {
return u.replace(parsedUrl.hostname, 'scribe.rip');
}
} catch (_) {}
return null;
}
Comment on lines +1428 to +1437
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

This hostname validation should use the existing hostnameMatches() helper function (defined at line 584) for consistency with the rest of the codebase. The helper is already used throughout the file (lines 597-608) for the same purpose of checking if a hostname matches a domain including its subdomains.

The current implementation duplicates the logic of hostnameMatches() inline. Instead, extract the hostname once and use the helper:

try {
  const parsedUrl = new URL(u);
  const hostname = parsedUrl.hostname;
  if (hostnameMatches(hostname, 'medium.com')) {
    return u.replace(parsedUrl.hostname, 'scribe.rip');
  }
} catch (_) {}

This improves maintainability and ensures consistent security checks across the codebase.

Copilot uses AI. Check for mistakes.
},
{
name: 'freedium',
transform: (u) => {
try {
const parsedUrl = new URL(u);
// Safely check if this is a medium.com URL
if (parsedUrl.hostname === 'medium.com' || parsedUrl.hostname.endsWith('.medium.com')) {
return u.replace(parsedUrl.hostname, 'freedium.app');
}
} catch (_) {}
return null;
}
Comment on lines +1441 to +1450
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

This hostname validation should use the existing hostnameMatches() helper function (defined at line 584) for consistency with the rest of the codebase. The helper is already used throughout the file (lines 597-608) for the same purpose.

The current implementation duplicates the logic inline. Extract the hostname once and use the helper:

try {
  const parsedUrl = new URL(u);
  const hostname = parsedUrl.hostname;
  if (hostnameMatches(hostname, 'medium.com')) {
    return u.replace(parsedUrl.hostname, 'freedium.app');
  }
} catch (_) {}

This ensures consistent security checks across the codebase and improves maintainability.

Copilot uses AI. Check for mistakes.
Comment on lines +1440 to +1450
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

There's an inconsistency between the proactive Medium bypass and this reactive bypass. The codebase already has a proactive Medium paywall bypass at line 260 that uses freedium.cloud, but this PR adds a reactive bypass using freedium.app.

Consider:

  1. Using the same domain (freedium.cloud or freedium.app) in both places for consistency
  2. Evaluating whether both proactive (line 260) and reactive (this code) approaches are needed, or if the proactive approach should be the primary method

The proactive approach is generally more reliable as it bypasses the paywall before any content extraction issues occur, as noted in the stored memory about paywall handling.

Copilot uses AI. Check for mistakes.
},
{
name: 'web.archive.org',
Expand Down
Loading