@fedify/vocab-runtime 2.3.13 → 2.3.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deno.json +1 -1
- package/dist/mod.cjs +2 -1
- package/dist/mod.js +2 -1
- package/dist/tests/{body-DZC-BUmp.mjs → body-DMMAC8hw.mjs} +1 -1
- package/dist/tests/{body-BzkzlcFe.cjs → body-DfWmIUIQ.cjs} +1 -1
- package/dist/tests/body.test.cjs +1 -1
- package/dist/tests/body.test.mjs +1 -1
- package/dist/tests/decimal.test.cjs +1 -1
- package/dist/tests/decimal.test.mjs +1 -1
- package/dist/tests/{docloader-DtJnwB0I.mjs → docloader-Bx4CBPlL.mjs} +3 -2
- package/dist/tests/{docloader-BMxfYjxN.cjs → docloader-zzQIwiJk.cjs} +3 -2
- package/dist/tests/docloader.test.cjs +48 -2
- package/dist/tests/docloader.test.mjs +48 -2
- package/dist/tests/{request-DkWzsggq.mjs → request-BBCe2UzV.mjs} +1 -1
- package/dist/tests/{request-C4XcOfmB.cjs → request-Bgv8wfpZ.cjs} +1 -1
- package/dist/tests/request.test.cjs +1 -1
- package/dist/tests/request.test.mjs +1 -1
- package/package.json +1 -1
- package/src/docloader.test.ts +84 -0
- package/src/docloader.ts +5 -0
package/deno.json
CHANGED
package/dist/mod.cjs
CHANGED
|
@@ -4537,7 +4537,7 @@ const preloadedContexts = {
|
|
|
4537
4537
|
//#endregion
|
|
4538
4538
|
//#region deno.json
|
|
4539
4539
|
var name = "@fedify/vocab-runtime";
|
|
4540
|
-
var version = "2.3.
|
|
4540
|
+
var version = "2.3.14";
|
|
4541
4541
|
//#endregion
|
|
4542
4542
|
//#region src/request.ts
|
|
4543
4543
|
/**
|
|
@@ -5200,6 +5200,7 @@ function getDocumentLoader({ allowPrivateAddress, maxRedirection, skipPreloadedC
|
|
|
5200
5200
|
options?.signal?.throwIfAborted();
|
|
5201
5201
|
const parsedUrl = new URL(url);
|
|
5202
5202
|
if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") throw new UrlError(`Unsupported protocol: ${parsedUrl.protocol}`);
|
|
5203
|
+
if (parsedUrl.username !== "" || parsedUrl.password !== "") throw new UrlError("URLs with credentials are not allowed");
|
|
5203
5204
|
const currentUrl = parsedUrl.href;
|
|
5204
5205
|
if (!skipPreloadedContexts && currentUrl in preloadedContexts) {
|
|
5205
5206
|
logger.debug("Using preloaded context: {url}.", { url: currentUrl });
|
package/dist/mod.js
CHANGED
|
@@ -4532,7 +4532,7 @@ const preloadedContexts = {
|
|
|
4532
4532
|
//#endregion
|
|
4533
4533
|
//#region deno.json
|
|
4534
4534
|
var name = "@fedify/vocab-runtime";
|
|
4535
|
-
var version = "2.3.
|
|
4535
|
+
var version = "2.3.14";
|
|
4536
4536
|
//#endregion
|
|
4537
4537
|
//#region src/request.ts
|
|
4538
4538
|
/**
|
|
@@ -5195,6 +5195,7 @@ function getDocumentLoader({ allowPrivateAddress, maxRedirection, skipPreloadedC
|
|
|
5195
5195
|
options?.signal?.throwIfAborted();
|
|
5196
5196
|
const parsedUrl = new URL(url);
|
|
5197
5197
|
if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") throw new UrlError(`Unsupported protocol: ${parsedUrl.protocol}`);
|
|
5198
|
+
if (parsedUrl.username !== "" || parsedUrl.password !== "") throw new UrlError("URLs with credentials are not allowed");
|
|
5198
5199
|
const currentUrl = parsedUrl.href;
|
|
5199
5200
|
if (!skipPreloadedContexts && currentUrl in preloadedContexts) {
|
|
5200
5201
|
logger.debug("Using preloaded context: {url}.", { url: currentUrl });
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
require("./chunk-C2EiDwsr.cjs");
|
|
2
|
-
const require_request = require("./request-
|
|
2
|
+
const require_request = require("./request-Bgv8wfpZ.cjs");
|
|
3
3
|
let _logtape_logtape = require("@logtape/logtape");
|
|
4
4
|
//#region src/body.ts
|
|
5
5
|
/** Decoded JSON body limit: 16 MiB. @internal */
|
package/dist/tests/body.test.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
require("./chunk-C2EiDwsr.cjs");
|
|
2
|
-
const require_body = require("./body-
|
|
2
|
+
const require_body = require("./body-DfWmIUIQ.cjs");
|
|
3
3
|
let node_assert_strict = require("node:assert/strict");
|
|
4
4
|
let node_test = require("node:test");
|
|
5
5
|
let node_zlib = require("node:zlib");
|
package/dist/tests/body.test.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as readBoundedText, t as BodyTooLargeError } from "./body-
|
|
1
|
+
import { r as readBoundedText, t as BodyTooLargeError } from "./body-DMMAC8hw.mjs";
|
|
2
2
|
import { deepStrictEqual, ok, rejects } from "node:assert/strict";
|
|
3
3
|
import { test } from "node:test";
|
|
4
4
|
import { gunzipSync, gzipSync } from "node:zlib";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as name, i as logRequest, n as createActivityPubRequest, o as version, t as FetchError } from "./request-
|
|
2
|
-
import { n as MAX_BODY_SIZE, r as readBoundedText } from "./body-
|
|
1
|
+
import { a as name, i as logRequest, n as createActivityPubRequest, o as version, t as FetchError } from "./request-BBCe2UzV.mjs";
|
|
2
|
+
import { n as MAX_BODY_SIZE, r as readBoundedText } from "./body-DMMAC8hw.mjs";
|
|
3
3
|
import { t as HttpHeaderLink } from "./link-CYszIegt.mjs";
|
|
4
4
|
import { o as validatePublicUrl, t as UrlError } from "./url-3fyJuqC0.mjs";
|
|
5
5
|
import { getLogger } from "@logtape/logtape";
|
|
@@ -4655,6 +4655,7 @@ function getDocumentLoader({ allowPrivateAddress, maxRedirection, skipPreloadedC
|
|
|
4655
4655
|
options?.signal?.throwIfAborted();
|
|
4656
4656
|
const parsedUrl = new URL(url);
|
|
4657
4657
|
if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") throw new UrlError(`Unsupported protocol: ${parsedUrl.protocol}`);
|
|
4658
|
+
if (parsedUrl.username !== "" || parsedUrl.password !== "") throw new UrlError("URLs with credentials are not allowed");
|
|
4658
4659
|
const currentUrl = parsedUrl.href;
|
|
4659
4660
|
if (!skipPreloadedContexts && currentUrl in preloadedContexts) {
|
|
4660
4661
|
logger.debug("Using preloaded context: {url}.", { url: currentUrl });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require("./chunk-C2EiDwsr.cjs");
|
|
2
|
-
const require_request = require("./request-
|
|
3
|
-
const require_body = require("./body-
|
|
2
|
+
const require_request = require("./request-Bgv8wfpZ.cjs");
|
|
3
|
+
const require_body = require("./body-DfWmIUIQ.cjs");
|
|
4
4
|
const require_link = require("./link-qDTmjPw_.cjs");
|
|
5
5
|
const require_url = require("./url-4PAkYhZC.cjs");
|
|
6
6
|
let _logtape_logtape = require("@logtape/logtape");
|
|
@@ -4656,6 +4656,7 @@ function getDocumentLoader({ allowPrivateAddress, maxRedirection, skipPreloadedC
|
|
|
4656
4656
|
options?.signal?.throwIfAborted();
|
|
4657
4657
|
const parsedUrl = new URL(url);
|
|
4658
4658
|
if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") throw new require_url.UrlError(`Unsupported protocol: ${parsedUrl.protocol}`);
|
|
4659
|
+
if (parsedUrl.username !== "" || parsedUrl.password !== "") throw new require_url.UrlError("URLs with credentials are not allowed");
|
|
4659
4660
|
const currentUrl = parsedUrl.href;
|
|
4660
4661
|
if (!skipPreloadedContexts && currentUrl in preloadedContexts) {
|
|
4661
4662
|
logger.debug("Using preloaded context: {url}.", { url: currentUrl });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-C2EiDwsr.cjs");
|
|
2
|
-
const require_request = require("./request-
|
|
3
|
-
const require_docloader = require("./docloader-
|
|
2
|
+
const require_request = require("./request-Bgv8wfpZ.cjs");
|
|
3
|
+
const require_docloader = require("./docloader-zzQIwiJk.cjs");
|
|
4
4
|
const require_url = require("./url-4PAkYhZC.cjs");
|
|
5
5
|
let node_zlib = require("node:zlib");
|
|
6
6
|
let _logtape_logtape = require("@logtape/logtape");
|
|
@@ -2014,6 +2014,52 @@ const unsupportedUrls = [
|
|
|
2014
2014
|
"file:///collection",
|
|
2015
2015
|
`data:application/ld+json,${encodeURIComponent(JSON.stringify({ id: "https://example.com/data" }))}`
|
|
2016
2016
|
];
|
|
2017
|
+
function isCredentialUrlError(error) {
|
|
2018
|
+
return error instanceof require_url.UrlError && error.reason === "disallowed" && error.message === "URLs with credentials are not allowed";
|
|
2019
|
+
}
|
|
2020
|
+
(0, _fedify_fixture.test)("getDocumentLoader() rejects URLs with credentials", async (t) => {
|
|
2021
|
+
const start = "https://8.8.8.8/start";
|
|
2022
|
+
const target = "https://user:pass@8.8.8.8/document";
|
|
2023
|
+
for (const allowPrivateAddress of [false, true]) {
|
|
2024
|
+
const loader = require_docloader.getDocumentLoader({ allowPrivateAddress });
|
|
2025
|
+
for (const path of [
|
|
2026
|
+
"direct",
|
|
2027
|
+
"redirect",
|
|
2028
|
+
"Link",
|
|
2029
|
+
"HTML"
|
|
2030
|
+
]) await t.step(`${path}, allowPrivateAddress=${allowPrivateAddress}`, async () => {
|
|
2031
|
+
await withFetchStub((url) => {
|
|
2032
|
+
if (url !== start) return Response.json({});
|
|
2033
|
+
if (path === "redirect") return Response.redirect(target, 302);
|
|
2034
|
+
if (path === "HTML") return new Response(`<link rel="alternate" type="application/activity+json" href="${target}">`, { headers: { "Content-Type": "text/html" } });
|
|
2035
|
+
return new Response("", { headers: {
|
|
2036
|
+
"Content-Type": "text/plain",
|
|
2037
|
+
Link: `<${target}>; rel="alternate"; type="application/activity+json"`
|
|
2038
|
+
} });
|
|
2039
|
+
}, async (fetched) => {
|
|
2040
|
+
await (0, node_assert.rejects)(loader(path === "direct" ? target : start), isCredentialUrlError);
|
|
2041
|
+
(0, node_assert.deepStrictEqual)(fetched, path === "direct" ? [] : [start]);
|
|
2042
|
+
});
|
|
2043
|
+
});
|
|
2044
|
+
for (const url of [
|
|
2045
|
+
"https://user@8.8.8.8/document",
|
|
2046
|
+
"https://:pass@8.8.8.8/document",
|
|
2047
|
+
"https://%75ser:p%40ss@8.8.8.8/document",
|
|
2048
|
+
"http://user:pass@8.8.8.8/document"
|
|
2049
|
+
]) await t.step(`${url}, allowPrivateAddress=${allowPrivateAddress}`, async () => {
|
|
2050
|
+
await withFetchStub(() => Response.json({}), async (fetched) => {
|
|
2051
|
+
await (0, node_assert.rejects)(loader(url), isCredentialUrlError);
|
|
2052
|
+
(0, node_assert.deepStrictEqual)(fetched, []);
|
|
2053
|
+
});
|
|
2054
|
+
});
|
|
2055
|
+
for (const url of ["https://:@8.8.8.8/document", "https://8.8.8.8/@user?q=@pass"]) await t.step(`allows ${url}, allowPrivateAddress=${allowPrivateAddress}`, async () => {
|
|
2056
|
+
await withFetchStub(() => Response.json({ done: true }), async (fetched) => {
|
|
2057
|
+
(0, node_assert.deepStrictEqual)((await loader(url)).document, { done: true });
|
|
2058
|
+
(0, node_assert.deepStrictEqual)(fetched, [new URL(url).href]);
|
|
2059
|
+
});
|
|
2060
|
+
});
|
|
2061
|
+
}
|
|
2062
|
+
});
|
|
2017
2063
|
function isUnsupportedProtocolError(error, url) {
|
|
2018
2064
|
return error instanceof require_url.UrlError && error.message === `Unsupported protocol: ${new URL(url).protocol}` && error.reason === "disallowed";
|
|
2019
2065
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as FetchError } from "./request-
|
|
2
|
-
import { i as cid_v1_default, n as getRemoteDocument, r as preloadedContexts, t as getDocumentLoader } from "./docloader-
|
|
1
|
+
import { t as FetchError } from "./request-BBCe2UzV.mjs";
|
|
2
|
+
import { i as cid_v1_default, n as getRemoteDocument, r as preloadedContexts, t as getDocumentLoader } from "./docloader-Bx4CBPlL.mjs";
|
|
3
3
|
import { t as UrlError } from "./url-3fyJuqC0.mjs";
|
|
4
4
|
import { gzipSync } from "node:zlib";
|
|
5
5
|
import { configure, reset } from "@logtape/logtape";
|
|
@@ -2031,6 +2031,52 @@ const unsupportedUrls = [
|
|
|
2031
2031
|
"file:///collection",
|
|
2032
2032
|
`data:application/ld+json,${encodeURIComponent(JSON.stringify({ id: "https://example.com/data" }))}`
|
|
2033
2033
|
];
|
|
2034
|
+
function isCredentialUrlError(error) {
|
|
2035
|
+
return error instanceof UrlError && error.reason === "disallowed" && error.message === "URLs with credentials are not allowed";
|
|
2036
|
+
}
|
|
2037
|
+
test("getDocumentLoader() rejects URLs with credentials", async (t) => {
|
|
2038
|
+
const start = "https://8.8.8.8/start";
|
|
2039
|
+
const target = "https://user:pass@8.8.8.8/document";
|
|
2040
|
+
for (const allowPrivateAddress of [false, true]) {
|
|
2041
|
+
const loader = getDocumentLoader({ allowPrivateAddress });
|
|
2042
|
+
for (const path of [
|
|
2043
|
+
"direct",
|
|
2044
|
+
"redirect",
|
|
2045
|
+
"Link",
|
|
2046
|
+
"HTML"
|
|
2047
|
+
]) await t.step(`${path}, allowPrivateAddress=${allowPrivateAddress}`, async () => {
|
|
2048
|
+
await withFetchStub((url) => {
|
|
2049
|
+
if (url !== start) return Response.json({});
|
|
2050
|
+
if (path === "redirect") return Response.redirect(target, 302);
|
|
2051
|
+
if (path === "HTML") return new Response(`<link rel="alternate" type="application/activity+json" href="${target}">`, { headers: { "Content-Type": "text/html" } });
|
|
2052
|
+
return new Response("", { headers: {
|
|
2053
|
+
"Content-Type": "text/plain",
|
|
2054
|
+
Link: `<${target}>; rel="alternate"; type="application/activity+json"`
|
|
2055
|
+
} });
|
|
2056
|
+
}, async (fetched) => {
|
|
2057
|
+
await rejects(loader(path === "direct" ? target : start), isCredentialUrlError);
|
|
2058
|
+
deepStrictEqual(fetched, path === "direct" ? [] : [start]);
|
|
2059
|
+
});
|
|
2060
|
+
});
|
|
2061
|
+
for (const url of [
|
|
2062
|
+
"https://user@8.8.8.8/document",
|
|
2063
|
+
"https://:pass@8.8.8.8/document",
|
|
2064
|
+
"https://%75ser:p%40ss@8.8.8.8/document",
|
|
2065
|
+
"http://user:pass@8.8.8.8/document"
|
|
2066
|
+
]) await t.step(`${url}, allowPrivateAddress=${allowPrivateAddress}`, async () => {
|
|
2067
|
+
await withFetchStub(() => Response.json({}), async (fetched) => {
|
|
2068
|
+
await rejects(loader(url), isCredentialUrlError);
|
|
2069
|
+
deepStrictEqual(fetched, []);
|
|
2070
|
+
});
|
|
2071
|
+
});
|
|
2072
|
+
for (const url of ["https://:@8.8.8.8/document", "https://8.8.8.8/@user?q=@pass"]) await t.step(`allows ${url}, allowPrivateAddress=${allowPrivateAddress}`, async () => {
|
|
2073
|
+
await withFetchStub(() => Response.json({ done: true }), async (fetched) => {
|
|
2074
|
+
deepStrictEqual((await loader(url)).document, { done: true });
|
|
2075
|
+
deepStrictEqual(fetched, [new URL(url).href]);
|
|
2076
|
+
});
|
|
2077
|
+
});
|
|
2078
|
+
}
|
|
2079
|
+
});
|
|
2034
2080
|
function isUnsupportedProtocolError(error, url) {
|
|
2035
2081
|
return error instanceof UrlError && error.message === `Unsupported protocol: ${new URL(url).protocol}` && error.reason === "disallowed";
|
|
2036
2082
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-C2EiDwsr.cjs");
|
|
2
|
-
const require_request = require("./request-
|
|
2
|
+
const require_request = require("./request-Bgv8wfpZ.cjs");
|
|
3
3
|
let node_test = require("node:test");
|
|
4
4
|
let node_process = require("node:process");
|
|
5
5
|
node_process = require_chunk.__toESM(node_process, 1);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as version, r as getUserAgent } from "./request-
|
|
1
|
+
import { o as version, r as getUserAgent } from "./request-BBCe2UzV.mjs";
|
|
2
2
|
import { test } from "node:test";
|
|
3
3
|
import process from "node:process";
|
|
4
4
|
import { deepStrictEqual } from "node:assert";
|
package/package.json
CHANGED
package/src/docloader.test.ts
CHANGED
|
@@ -1112,6 +1112,90 @@ const unsupportedUrls = [
|
|
|
1112
1112
|
}`,
|
|
1113
1113
|
];
|
|
1114
1114
|
|
|
1115
|
+
function isCredentialUrlError(error: unknown): boolean {
|
|
1116
|
+
return error instanceof UrlError && error.reason === "disallowed" &&
|
|
1117
|
+
error.message === "URLs with credentials are not allowed";
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
test("getDocumentLoader() rejects URLs with credentials", async (t) => {
|
|
1121
|
+
const start = "https://8.8.8.8/start";
|
|
1122
|
+
const target = "https://user:pass@8.8.8.8/document";
|
|
1123
|
+
for (const allowPrivateAddress of [false, true]) {
|
|
1124
|
+
const loader = getDocumentLoader({ allowPrivateAddress });
|
|
1125
|
+
for (const path of ["direct", "redirect", "Link", "HTML"]) {
|
|
1126
|
+
await t.step(
|
|
1127
|
+
`${path}, allowPrivateAddress=${allowPrivateAddress}`,
|
|
1128
|
+
async () => {
|
|
1129
|
+
await withFetchStub(
|
|
1130
|
+
(url) => {
|
|
1131
|
+
if (url !== start) return Response.json({});
|
|
1132
|
+
if (path === "redirect") return Response.redirect(target, 302);
|
|
1133
|
+
if (path === "HTML") {
|
|
1134
|
+
return new Response(
|
|
1135
|
+
`<link rel="alternate" type="application/activity+json" href="${target}">`,
|
|
1136
|
+
{ headers: { "Content-Type": "text/html" } },
|
|
1137
|
+
);
|
|
1138
|
+
}
|
|
1139
|
+
return new Response("", {
|
|
1140
|
+
headers: {
|
|
1141
|
+
"Content-Type": "text/plain",
|
|
1142
|
+
Link:
|
|
1143
|
+
`<${target}>; rel="alternate"; type="application/activity+json"`,
|
|
1144
|
+
},
|
|
1145
|
+
});
|
|
1146
|
+
},
|
|
1147
|
+
async (fetched) => {
|
|
1148
|
+
await rejects(
|
|
1149
|
+
loader(path === "direct" ? target : start),
|
|
1150
|
+
isCredentialUrlError,
|
|
1151
|
+
);
|
|
1152
|
+
deepStrictEqual(fetched, path === "direct" ? [] : [start]);
|
|
1153
|
+
},
|
|
1154
|
+
);
|
|
1155
|
+
},
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
1158
|
+
for (
|
|
1159
|
+
const url of [
|
|
1160
|
+
"https://user@8.8.8.8/document",
|
|
1161
|
+
"https://:pass@8.8.8.8/document",
|
|
1162
|
+
"https://%75ser:p%40ss@8.8.8.8/document",
|
|
1163
|
+
"http://user:pass@8.8.8.8/document",
|
|
1164
|
+
]
|
|
1165
|
+
) {
|
|
1166
|
+
await t.step(
|
|
1167
|
+
`${url}, allowPrivateAddress=${allowPrivateAddress}`,
|
|
1168
|
+
async () => {
|
|
1169
|
+
await withFetchStub(() => Response.json({}), async (fetched) => {
|
|
1170
|
+
await rejects(loader(url), isCredentialUrlError);
|
|
1171
|
+
deepStrictEqual(fetched, []);
|
|
1172
|
+
});
|
|
1173
|
+
},
|
|
1174
|
+
);
|
|
1175
|
+
}
|
|
1176
|
+
for (
|
|
1177
|
+
const url of [
|
|
1178
|
+
"https://:@8.8.8.8/document",
|
|
1179
|
+
"https://8.8.8.8/@user?q=@pass",
|
|
1180
|
+
]
|
|
1181
|
+
) {
|
|
1182
|
+
await t.step(
|
|
1183
|
+
`allows ${url}, allowPrivateAddress=${allowPrivateAddress}`,
|
|
1184
|
+
async () => {
|
|
1185
|
+
await withFetchStub(
|
|
1186
|
+
() => Response.json({ done: true }),
|
|
1187
|
+
async (fetched) => {
|
|
1188
|
+
const document = await loader(url);
|
|
1189
|
+
deepStrictEqual(document.document, { done: true });
|
|
1190
|
+
deepStrictEqual(fetched, [new URL(url).href]);
|
|
1191
|
+
},
|
|
1192
|
+
);
|
|
1193
|
+
},
|
|
1194
|
+
);
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
});
|
|
1198
|
+
|
|
1115
1199
|
function isUnsupportedProtocolError(error: unknown, url: string): boolean {
|
|
1116
1200
|
return error instanceof UrlError &&
|
|
1117
1201
|
error.message === `Unsupported protocol: ${new URL(url).protocol}` &&
|
package/src/docloader.ts
CHANGED
|
@@ -315,6 +315,11 @@ export function getDocumentLoader(
|
|
|
315
315
|
if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") {
|
|
316
316
|
throw new UrlError(`Unsupported protocol: ${parsedUrl.protocol}`);
|
|
317
317
|
}
|
|
318
|
+
// When merging forward, keep this guard independent of allowPrivateAddress:
|
|
319
|
+
// private-address opt-in must not permit credentials on any followed URL.
|
|
320
|
+
if (parsedUrl.username !== "" || parsedUrl.password !== "") {
|
|
321
|
+
throw new UrlError("URLs with credentials are not allowed");
|
|
322
|
+
}
|
|
318
323
|
const currentUrl = parsedUrl.href;
|
|
319
324
|
if (!skipPreloadedContexts && currentUrl in preloadedContexts) {
|
|
320
325
|
logger.debug("Using preloaded context: {url}.", { url: currentUrl });
|