fix(patches): extend internal URL rewrite to microsub, activitypub, and @rmdes posts
The localhost rewrite only covered endpoint-syndicate and endpoint-share. Add coverage for 4 more files that also self-fetch via the public URL: - @rmdes/indiekit-endpoint-microsub reader.js (2 fetch calls) - @rmdes/indiekit-endpoint-activitypub compose.js (2 fetch calls) - @rmdes/indiekit-endpoint-posts utils.js and endpoint.js Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,14 @@
|
|||||||
/**
|
/**
|
||||||
* Patch: rewrite micropub self-fetch URLs to localhost in endpoint-syndicate
|
* Patch: rewrite micropub/microsub self-fetch URLs to localhost.
|
||||||
* and endpoint-share.
|
|
||||||
*
|
*
|
||||||
* Same issue as endpoint-posts: behind a reverse proxy (nginx in a separate
|
* Behind a reverse proxy (nginx in a separate FreeBSD jail), Node can't
|
||||||
* FreeBSD jail), Node can't reach its own public HTTPS URL because port 443
|
* reach its own public HTTPS URL because port 443 only exists on the
|
||||||
* only exists on the nginx jail.
|
* nginx jail. Rewrites self-referential fetch URLs to use
|
||||||
*
|
|
||||||
* Rewrites fetch(application.micropubEndpoint, ...) to use
|
|
||||||
* http://localhost:<PORT> instead.
|
* http://localhost:<PORT> instead.
|
||||||
|
*
|
||||||
|
* Covers: endpoint-syndicate, endpoint-share, endpoint-microsub reader,
|
||||||
|
* endpoint-activitypub compose, endpoint-posts utils, and the @rmdes
|
||||||
|
* endpoint-posts endpoint.js copy.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { access, readFile, writeFile } from "node:fs/promises";
|
import { access, readFile, writeFile } from "node:fs/promises";
|
||||||
@@ -29,20 +30,136 @@ function _toInternalUrl(url) {
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
// Each target defines one or more string replacements in a single file.
|
||||||
|
// The helper block is inserted after the last import statement.
|
||||||
const targets = [
|
const targets = [
|
||||||
|
// --- endpoint-syndicate ---
|
||||||
{
|
{
|
||||||
paths: [
|
paths: [
|
||||||
"node_modules/@indiekit/endpoint-syndicate/lib/controllers/syndicate.js",
|
"node_modules/@indiekit/endpoint-syndicate/lib/controllers/syndicate.js",
|
||||||
],
|
],
|
||||||
oldSnippet: ` const micropubResponse = await fetch(application.micropubEndpoint, {`,
|
replacements: [
|
||||||
newSnippet: ` const micropubResponse = await fetch(_toInternalUrl(application.micropubEndpoint), {`,
|
{
|
||||||
|
old: ` const micropubResponse = await fetch(application.micropubEndpoint, {`,
|
||||||
|
new: ` const micropubResponse = await fetch(_toInternalUrl(application.micropubEndpoint), {`,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
|
// --- endpoint-share ---
|
||||||
{
|
{
|
||||||
paths: [
|
paths: [
|
||||||
"node_modules/@indiekit/endpoint-share/lib/controllers/share.js",
|
"node_modules/@indiekit/endpoint-share/lib/controllers/share.js",
|
||||||
],
|
],
|
||||||
oldSnippet: ` const micropubResponse = await fetch(application.micropubEndpoint, {`,
|
replacements: [
|
||||||
newSnippet: ` const micropubResponse = await fetch(_toInternalUrl(application.micropubEndpoint), {`,
|
{
|
||||||
|
old: ` const micropubResponse = await fetch(application.micropubEndpoint, {`,
|
||||||
|
new: ` const micropubResponse = await fetch(_toInternalUrl(application.micropubEndpoint), {`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// --- microsub reader: URL construction + 2 fetch calls ---
|
||||||
|
{
|
||||||
|
paths: [
|
||||||
|
"node_modules/@rmdes/indiekit-endpoint-microsub/lib/controllers/reader.js",
|
||||||
|
],
|
||||||
|
replacements: [
|
||||||
|
// getSyndicationTargets: rewrite the built micropubUrl
|
||||||
|
{
|
||||||
|
old: ` const micropubUrl = micropubEndpoint.startsWith("http")
|
||||||
|
? micropubEndpoint
|
||||||
|
: new URL(micropubEndpoint, application.url).href;
|
||||||
|
|
||||||
|
const configUrl = \`\${micropubUrl}?q=config\`;
|
||||||
|
const configResponse = await fetch(configUrl, {`,
|
||||||
|
new: ` const micropubUrl = _toInternalUrl(micropubEndpoint.startsWith("http")
|
||||||
|
? micropubEndpoint
|
||||||
|
: new URL(micropubEndpoint, application.url).href);
|
||||||
|
|
||||||
|
const configUrl = \`\${micropubUrl}?q=config\`;
|
||||||
|
const configResponse = await fetch(configUrl, {`,
|
||||||
|
},
|
||||||
|
// createPost: rewrite the built micropubUrl
|
||||||
|
{
|
||||||
|
old: ` const micropubUrl = micropubEndpoint.startsWith("http")
|
||||||
|
? micropubEndpoint
|
||||||
|
: new URL(micropubEndpoint, application.url).href;`,
|
||||||
|
new: ` const micropubUrl = _toInternalUrl(micropubEndpoint.startsWith("http")
|
||||||
|
? micropubEndpoint
|
||||||
|
: new URL(micropubEndpoint, application.url).href);`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// --- activitypub compose: URL construction + 2 fetch calls ---
|
||||||
|
{
|
||||||
|
paths: [
|
||||||
|
"node_modules/@rmdes/indiekit-endpoint-activitypub/lib/controllers/compose.js",
|
||||||
|
],
|
||||||
|
replacements: [
|
||||||
|
// getSyndicationTargets
|
||||||
|
{
|
||||||
|
old: ` const micropubUrl = micropubEndpoint.startsWith("http")
|
||||||
|
? micropubEndpoint
|
||||||
|
: new URL(micropubEndpoint, application.url).href;
|
||||||
|
|
||||||
|
const configUrl = \`\${micropubUrl}?q=config\`;
|
||||||
|
const configResponse = await fetch(configUrl, {`,
|
||||||
|
new: ` const micropubUrl = _toInternalUrl(micropubEndpoint.startsWith("http")
|
||||||
|
? micropubEndpoint
|
||||||
|
: new URL(micropubEndpoint, application.url).href);
|
||||||
|
|
||||||
|
const configUrl = \`\${micropubUrl}?q=config\`;
|
||||||
|
const configResponse = await fetch(configUrl, {`,
|
||||||
|
},
|
||||||
|
// post handler: rewrite the built micropubUrl
|
||||||
|
{
|
||||||
|
old: ` const micropubUrl = micropubEndpoint.startsWith("http")
|
||||||
|
? micropubEndpoint
|
||||||
|
: new URL(micropubEndpoint, application.url).href;`,
|
||||||
|
new: ` const micropubUrl = _toInternalUrl(micropubEndpoint.startsWith("http")
|
||||||
|
? micropubEndpoint
|
||||||
|
: new URL(micropubEndpoint, application.url).href);`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// --- @rmdes endpoint-posts utils.js: URL built from micropubEndpoint ---
|
||||||
|
{
|
||||||
|
paths: [
|
||||||
|
"node_modules/@rmdes/indiekit-endpoint-posts/lib/utils.js",
|
||||||
|
],
|
||||||
|
replacements: [
|
||||||
|
{
|
||||||
|
old: ` const micropubUrl = new URL(micropubEndpoint);`,
|
||||||
|
new: ` const micropubUrl = new URL(_toInternalUrl(micropubEndpoint));`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// --- @rmdes endpoint-posts endpoint.js (separate copy from @indiekit override) ---
|
||||||
|
{
|
||||||
|
paths: [
|
||||||
|
"node_modules/@rmdes/indiekit-endpoint-posts/lib/endpoint.js",
|
||||||
|
],
|
||||||
|
replacements: [
|
||||||
|
{
|
||||||
|
old: ` const endpointResponse = await fetch(url, {
|
||||||
|
headers: {
|
||||||
|
accept: "application/json",
|
||||||
|
authorization: \`Bearer \${accessToken}\`,
|
||||||
|
},
|
||||||
|
});`,
|
||||||
|
new: ` const endpointResponse = await fetch(_toInternalUrl(url), {
|
||||||
|
headers: {
|
||||||
|
accept: "application/json",
|
||||||
|
authorization: \`Bearer \${accessToken}\`,
|
||||||
|
},
|
||||||
|
});`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
old: ` const endpointResponse = await fetch(url, {
|
||||||
|
method: "POST",`,
|
||||||
|
new: ` const endpointResponse = await fetch(_toInternalUrl(url), {
|
||||||
|
method: "POST",`,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -67,22 +184,23 @@ for (const target of targets) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!source.includes(target.oldSnippet)) {
|
// Check that all old snippets exist before patching
|
||||||
console.warn(`[postinstall] micropub-fetch-internal-url: snippet not found in ${filePath} — skipping`);
|
const allFound = target.replacements.every((r) => source.includes(r.old));
|
||||||
|
if (!allFound) {
|
||||||
|
const missing = target.replacements
|
||||||
|
.filter((r) => !source.includes(r.old))
|
||||||
|
.map((r) => r.old.slice(0, 60) + "...");
|
||||||
|
console.warn(`[postinstall] micropub-fetch-internal-url: snippet not found in ${filePath} — skipping (${missing.length} missing)`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert helper block after the last import statement.
|
// Insert helper block after the last import statement
|
||||||
// Find the last "from" keyword followed by a string and semicolon,
|
|
||||||
// which marks the end of the last import.
|
|
||||||
const importEndPattern = /;\s*\n/g;
|
|
||||||
const allImportMatches = [...source.matchAll(/^import\s/gm)];
|
const allImportMatches = [...source.matchAll(/^import\s/gm)];
|
||||||
if (allImportMatches.length === 0) {
|
if (allImportMatches.length === 0) {
|
||||||
console.warn(`[postinstall] micropub-fetch-internal-url: no imports found in ${filePath} — skipping`);
|
console.warn(`[postinstall] micropub-fetch-internal-url: no imports found in ${filePath} — skipping`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the semicolon+newline that ends the last import block
|
|
||||||
const lastImportStart = allImportMatches.at(-1).index;
|
const lastImportStart = allImportMatches.at(-1).index;
|
||||||
const afterLastImport = source.slice(lastImportStart);
|
const afterLastImport = source.slice(lastImportStart);
|
||||||
const fromMatch = afterLastImport.match(/from\s+["'][^"']+["']\s*;\s*\n/);
|
const fromMatch = afterLastImport.match(/from\s+["'][^"']+["']\s*;\s*\n/);
|
||||||
@@ -97,8 +215,10 @@ for (const target of targets) {
|
|||||||
|
|
||||||
let updated = beforeHelper + "\n" + helperBlock + "\n" + afterHelper;
|
let updated = beforeHelper + "\n" + helperBlock + "\n" + afterHelper;
|
||||||
|
|
||||||
// Now replace the fetch call
|
// Apply all replacements
|
||||||
updated = updated.replace(target.oldSnippet, target.newSnippet);
|
for (const r of target.replacements) {
|
||||||
|
updated = updated.replace(r.old, r.new);
|
||||||
|
}
|
||||||
|
|
||||||
await writeFile(filePath, updated, "utf8");
|
await writeFile(filePath, updated, "utf8");
|
||||||
console.log(`[postinstall] Patched micropub-fetch-internal-url in ${filePath}`);
|
console.log(`[postinstall] Patched micropub-fetch-internal-url in ${filePath}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user