react-router 7.18.2 → 7.18.3

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/development/{browser-DBmQ1yAR.d.mts → browser-BR5QG7ZC.d.mts} +1 -1
  3. package/dist/development/{browser-B2PdsXXH.d.ts → browser-eq4RgLsD.d.ts} +1 -1
  4. package/dist/development/{chunk-HHGH3NKS.js → chunk-7SIULPXI.js} +117 -18
  5. package/dist/development/{chunk-62JRHF6Z.mjs → chunk-BV7QT456.mjs} +112 -13
  6. package/dist/development/{chunk-ZA36QIGN.mjs → chunk-HT4INDD5.mjs} +13 -6
  7. package/dist/{production/chunk-VJZ67BZE.js → development/chunk-QPXIKN46.js} +7 -7
  8. package/dist/development/{chunk-7XGYIT3M.js → chunk-YRTY65LJ.js} +103 -103
  9. package/dist/{production/context-CeD5LmaF.d.mts → development/context-nqAapj74.d.mts} +9 -0
  10. package/dist/development/dom-export.d.mts +2 -2
  11. package/dist/development/dom-export.d.ts +2 -2
  12. package/dist/development/dom-export.js +45 -32
  13. package/dist/development/dom-export.mjs +17 -4
  14. package/dist/{production/index-react-server-client-3ykjivgQ.d.ts → development/index-react-server-client-BjY-eKuf.d.ts} +2 -1
  15. package/dist/{production/index-react-server-client-CACgcj2J.d.mts → development/index-react-server-client-K63fpMH4.d.mts} +1 -1
  16. package/dist/development/index-react-server-client.d.mts +2 -2
  17. package/dist/development/index-react-server-client.d.ts +2 -2
  18. package/dist/development/index-react-server-client.js +4 -4
  19. package/dist/development/index-react-server-client.mjs +2 -2
  20. package/dist/development/index-react-server.d.mts +8 -0
  21. package/dist/development/index-react-server.d.ts +8 -0
  22. package/dist/development/index-react-server.js +25 -9
  23. package/dist/development/index-react-server.mjs +25 -9
  24. package/dist/development/index.d.mts +6 -6
  25. package/dist/development/index.d.ts +6 -6
  26. package/dist/development/index.js +101 -94
  27. package/dist/development/index.mjs +3 -3
  28. package/dist/{production/instrumentation-Dkmpzd13.d.ts → development/instrumentation-B7w3_Eo9.d.ts} +8 -0
  29. package/dist/development/lib/types/internal.js +1 -1
  30. package/dist/development/lib/types/internal.mjs +1 -1
  31. package/dist/production/{browser-DBmQ1yAR.d.mts → browser-BR5QG7ZC.d.mts} +1 -1
  32. package/dist/production/{browser-B2PdsXXH.d.ts → browser-eq4RgLsD.d.ts} +1 -1
  33. package/dist/production/{chunk-TP6EHSSF.js → chunk-6XRGXNVQ.js} +117 -18
  34. package/dist/production/{chunk-YBLPXYCV.mjs → chunk-EFMJ2SG4.mjs} +112 -13
  35. package/dist/production/{chunk-FDTIF24W.js → chunk-LNBCQR6O.js} +103 -103
  36. package/dist/{development/chunk-3UVS743K.js → production/chunk-SJHDA7OG.js} +7 -7
  37. package/dist/production/{chunk-SJTG3J2Q.mjs → chunk-UODOIDHR.mjs} +13 -6
  38. package/dist/{development/context-CeD5LmaF.d.mts → production/context-nqAapj74.d.mts} +9 -0
  39. package/dist/production/dom-export.d.mts +2 -2
  40. package/dist/production/dom-export.d.ts +2 -2
  41. package/dist/production/dom-export.js +45 -32
  42. package/dist/production/dom-export.mjs +17 -4
  43. package/dist/{development/index-react-server-client-3ykjivgQ.d.ts → production/index-react-server-client-BjY-eKuf.d.ts} +2 -1
  44. package/dist/{development/index-react-server-client-CACgcj2J.d.mts → production/index-react-server-client-K63fpMH4.d.mts} +1 -1
  45. package/dist/production/index-react-server-client.d.mts +2 -2
  46. package/dist/production/index-react-server-client.d.ts +2 -2
  47. package/dist/production/index-react-server-client.js +4 -4
  48. package/dist/production/index-react-server-client.mjs +2 -2
  49. package/dist/production/index-react-server.d.mts +8 -0
  50. package/dist/production/index-react-server.d.ts +8 -0
  51. package/dist/production/index-react-server.js +25 -9
  52. package/dist/production/index-react-server.mjs +25 -9
  53. package/dist/production/index.d.mts +6 -6
  54. package/dist/production/index.d.ts +6 -6
  55. package/dist/production/index.js +101 -94
  56. package/dist/production/index.mjs +3 -3
  57. package/dist/{development/instrumentation-Dkmpzd13.d.ts → production/instrumentation-B7w3_Eo9.d.ts} +8 -0
  58. package/dist/production/lib/types/internal.js +1 -1
  59. package/dist/production/lib/types/internal.mjs +1 -1
  60. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # `react-router`
2
2
 
3
+ ## v7.18.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Improve route matching performance for long paths ([#15423](https://github.com/remix-run/react-router/pull/15423))
8
+ - Improve validation of action request origins ([#15420](https://github.com/remix-run/react-router/pull/15420))
9
+ - Add additional URL validation on client side navigations/redirects ([#15446](https://github.com/remix-run/react-router/pull/15446))
10
+
3
11
  ## v7.18.2
4
12
 
5
13
  ### Patch Changes
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { R as RouterInit } from './context-CeD5LmaF.mjs';
2
+ import { R as RouterInit } from './context-nqAapj74.mjs';
3
3
  import { L as Location, C as ClientActionFunction, a as ClientLoaderFunction, b as LinksFunction, M as MetaFunction, S as ShouldRevalidateFunction, P as Params, c as RouterContextProvider, A as ActionFunction, H as HeadersFunction, d as LoaderFunction } from './data-DEjBmEfD.mjs';
4
4
 
5
5
  declare function getRequest(): Request;
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { R as RouterInit } from './instrumentation-Dkmpzd13.js';
2
+ import { R as RouterInit } from './instrumentation-B7w3_Eo9.js';
3
3
  import { L as Location, C as ClientActionFunction, a as ClientLoaderFunction, b as LinksFunction, M as MetaFunction, S as ShouldRevalidateFunction, P as Params, c as RouterContextProvider, A as ActionFunction, H as HeadersFunction, d as LoaderFunction } from './data-CjO11-hU.js';
4
4
 
5
5
  declare function getRequest(): Request;
@@ -1,5 +1,5 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }/**
2
- * react-router v7.18.2
2
+ * react-router v7.18.3
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -784,13 +784,16 @@ function matchPathImpl(pattern, pathname, matcher, compiledParams) {
784
784
  let match = pathname.match(matcher);
785
785
  if (!match) return null;
786
786
  let matchedPathname = match[0];
787
- let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1");
787
+ let pathnameBase = removeTrailingSlash(matchedPathname, 1);
788
788
  let captureGroups = match.slice(1);
789
789
  let params = compiledParams.reduce(
790
790
  (memo2, { paramName, isOptional }, index) => {
791
791
  if (paramName === "*") {
792
792
  let splatValue = captureGroups[index] || "";
793
- pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1");
793
+ pathnameBase = removeTrailingSlash(
794
+ matchedPathname.slice(0, matchedPathname.length - splatValue.length),
795
+ 1
796
+ );
794
797
  }
795
798
  const value = captureGroups[index];
796
799
  if (isOptional && !value) {
@@ -880,7 +883,7 @@ function resolvePath(to, fromPathname = "/") {
880
883
  let pathname;
881
884
  if (toPathname) {
882
885
  toPathname = removeDoubleSlashes(toPathname);
883
- if (toPathname.startsWith("/")) {
886
+ if (toPathname.startsWith("/") || toPathname.startsWith("\\")) {
884
887
  pathname = resolvePathname(toPathname.substring(1), "/");
885
888
  } else {
886
889
  pathname = resolvePathname(toPathname, fromPathname);
@@ -968,7 +971,13 @@ function resolveTo(toArg, routePathnames, locationPathname, isPathRelative = fal
968
971
  }
969
972
  var removeDoubleSlashes = (path) => path.replace(/[\\/]{2,}/g, "/");
970
973
  var joinPaths = (paths) => removeDoubleSlashes(paths.join("/"));
971
- var removeTrailingSlash = (path) => path.replace(/\/+$/, "");
974
+ function removeTrailingSlash(path, minLength = 0) {
975
+ let end = path.length;
976
+ while (end > minLength && path.charCodeAt(end - 1) === 47) {
977
+ end--;
978
+ }
979
+ return end === path.length ? path : path.slice(0, end);
980
+ }
972
981
  var normalizePathname = (pathname) => removeTrailingSlash(pathname).replace(/^\/*/, "/");
973
982
  var normalizeSearch = (search) => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search;
974
983
  var normalizeHash = (hash) => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash;
@@ -1341,6 +1350,51 @@ function isPlainObject(thing) {
1341
1350
  return proto === Object.prototype || proto === null || Object.getOwnPropertyNames(proto).sort().join("\0") === objectProtoNames;
1342
1351
  }
1343
1352
 
1353
+ // lib/router/navigation.ts
1354
+ var DEFAULT_NAVIGATION_URL = new URL("http://localhost");
1355
+ function getNavigatorCurrentUrl(navigator) {
1356
+ if (navigator.createURL) {
1357
+ return navigator.createURL("/");
1358
+ }
1359
+ try {
1360
+ return new URL(navigator.createHref("/"), DEFAULT_NAVIGATION_URL);
1361
+ } catch (e2) {
1362
+ return DEFAULT_NAVIGATION_URL;
1363
+ }
1364
+ }
1365
+ function isSameOrigin(a, b) {
1366
+ return a.origin === b.origin && (a.origin !== "null" || a.protocol === b.protocol && a.host === b.host);
1367
+ }
1368
+ function isExplicitUrl(destination, target) {
1369
+ if (destination.startsWith("//")) {
1370
+ return true;
1371
+ }
1372
+ let protocol = target.protocol.toLowerCase();
1373
+ if (!destination.toLowerCase().startsWith(protocol)) {
1374
+ return false;
1375
+ }
1376
+ return target.host === "" || destination.slice(protocol.length).startsWith("//");
1377
+ }
1378
+ function validateNavigationTarget(original, resolved, currentUrl, externalPolicy) {
1379
+ let originalUrl = null;
1380
+ try {
1381
+ originalUrl = original == null ? null : new URL(original, currentUrl);
1382
+ } catch (e3) {
1383
+ }
1384
+ let resolvedUrl = new URL(resolved, currentUrl);
1385
+ let originalIsExternal = originalUrl != null && !isSameOrigin(originalUrl, currentUrl);
1386
+ let resolvedIsExternal = !isSameOrigin(resolvedUrl, currentUrl);
1387
+ if (externalPolicy === "reject") {
1388
+ if (originalIsExternal || resolvedIsExternal) {
1389
+ throw new Error("External navigation is not allowed");
1390
+ }
1391
+ } else if (resolvedIsExternal) {
1392
+ if (originalUrl == null || !isExplicitUrl(original, originalUrl) || !isSameOrigin(originalUrl, resolvedUrl)) {
1393
+ throw new Error("External navigation is not allowed");
1394
+ }
1395
+ }
1396
+ }
1397
+
1344
1398
  // lib/router/router.ts
1345
1399
  var validMutationMethodsArr = [
1346
1400
  "POST",
@@ -1852,11 +1906,21 @@ function createRouter(init) {
1852
1906
  ...opts.mask
1853
1907
  };
1854
1908
  maskPath = {
1855
- pathname: "",
1856
- search: "",
1857
- hash: "",
1858
- ...partialPath
1909
+ pathname: _nullishCoalesce(partialPath.pathname, () => ( "")),
1910
+ search: _nullishCoalesce(partialPath.search, () => ( "")),
1911
+ hash: _nullishCoalesce(partialPath.hash, () => ( ""))
1859
1912
  };
1913
+ if (PROTOCOL_RELATIVE_URL_REGEX.test(maskPath.pathname)) {
1914
+ throw new Error("External navigation is not allowed");
1915
+ } else if (maskPath.pathname.startsWith("\\")) {
1916
+ maskPath.pathname = maskPath.pathname.replace(/^\\+/, "/");
1917
+ }
1918
+ validateNavigationTarget(
1919
+ typeof opts.mask === "string" ? opts.mask : createPath(opts.mask),
1920
+ createPath(maskPath),
1921
+ init.history.createURL("/"),
1922
+ "reject"
1923
+ );
1860
1924
  }
1861
1925
  let currentLocation = state.location;
1862
1926
  let nextLocation = createLocation(
@@ -1870,6 +1934,12 @@ function createRouter(init) {
1870
1934
  ...nextLocation,
1871
1935
  ...init.history.encodeLocation(nextLocation)
1872
1936
  };
1937
+ validateNavigationTarget(
1938
+ to == null ? init.history.createHref(state.location) : typeof to === "string" ? to : createPath(to),
1939
+ init.history.createHref(nextLocation.mask || nextLocation),
1940
+ init.history.createURL("/"),
1941
+ "reject"
1942
+ );
1873
1943
  let userReplace = opts && opts.replace != null ? opts.replace : void 0;
1874
1944
  let historyAction = "PUSH" /* Push */;
1875
1945
  if (userReplace === true) {
@@ -2880,12 +2950,20 @@ function createRouter(init) {
2880
2950
  }
2881
2951
  let location = redirect2.response.headers.get("Location");
2882
2952
  invariant(location, "Expected a Location header on the redirect Response");
2953
+ let originalLocation = location;
2954
+ let currentUrl = new URL(request.url);
2883
2955
  location = normalizeRedirectLocation(
2884
2956
  location,
2885
- new URL(request.url),
2957
+ currentUrl,
2886
2958
  basename,
2887
2959
  init.history
2888
2960
  );
2961
+ validateNavigationTarget(
2962
+ originalLocation,
2963
+ location,
2964
+ currentUrl,
2965
+ "allow-explicit"
2966
+ );
2889
2967
  let redirectLocation = createLocation(state.location, location, {
2890
2968
  _isRedirect: true
2891
2969
  });
@@ -3404,6 +3482,7 @@ function createRouter(init) {
3404
3482
  // Passthrough to history-aware createHref used by useHref so we get proper
3405
3483
  // hash-aware URLs in DOM paths
3406
3484
  createHref: (to) => init.history.createHref(to),
3485
+ createURL: (to) => init.history.createURL(to),
3407
3486
  encodeLocation: (to) => init.history.encodeLocation(to),
3408
3487
  getFetcher,
3409
3488
  resetFetcher,
@@ -5244,7 +5323,7 @@ var invalidProtocols = [
5244
5323
  function hasInvalidProtocol(location) {
5245
5324
  try {
5246
5325
  return invalidProtocols.includes(new URL(location).protocol);
5247
- } catch (e2) {
5326
+ } catch (e4) {
5248
5327
  return false;
5249
5328
  }
5250
5329
  }
@@ -7085,7 +7164,7 @@ function decodeRedirectErrorDigest(digest) {
7085
7164
  if (typeof parsed === "object" && parsed && typeof parsed.status === "number" && typeof parsed.statusText === "string" && typeof parsed.location === "string" && typeof parsed.reloadDocument === "boolean" && typeof parsed.replace === "boolean") {
7086
7165
  return parsed;
7087
7166
  }
7088
- } catch (e3) {
7167
+ } catch (e5) {
7089
7168
  }
7090
7169
  }
7091
7170
  }
@@ -7102,7 +7181,7 @@ function decodeRouteErrorResponseDigest(digest) {
7102
7181
  parsed.data
7103
7182
  );
7104
7183
  }
7105
- } catch (e4) {
7184
+ } catch (e6) {
7106
7185
  }
7107
7186
  }
7108
7187
  }
@@ -7195,6 +7274,12 @@ function useNavigateUnstable() {
7195
7274
  if (dataRouterContext == null && basename !== "/") {
7196
7275
  path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]);
7197
7276
  }
7277
+ validateNavigationTarget(
7278
+ typeof to === "string" ? to : createPath(to),
7279
+ navigator.createHref(path),
7280
+ getNavigatorCurrentUrl(navigator),
7281
+ "reject"
7282
+ );
7198
7283
  (!!options.replace ? navigator.replace : navigator.push)(
7199
7284
  path,
7200
7285
  options.state,
@@ -7436,7 +7521,7 @@ function RSCErrorHandler({
7436
7521
  children,
7437
7522
  error
7438
7523
  }) {
7439
- let { basename } = React3.useContext(NavigationContext);
7524
+ let { basename, navigator } = React3.useContext(NavigationContext);
7440
7525
  if (typeof error === "object" && error && "digest" in error && typeof error.digest === "string") {
7441
7526
  let redirect2 = decodeRedirectErrorDigest(error.digest);
7442
7527
  if (redirect2) {
@@ -7444,6 +7529,12 @@ function RSCErrorHandler({
7444
7529
  if (existingRedirect) throw existingRedirect;
7445
7530
  let parsed = parseToInfo(redirect2.location, basename);
7446
7531
  let target = parsed.absoluteURL || parsed.to;
7532
+ validateNavigationTarget(
7533
+ redirect2.location,
7534
+ target,
7535
+ getNavigatorCurrentUrl(navigator),
7536
+ "allow-explicit"
7537
+ );
7447
7538
  if (hasInvalidProtocol(target)) {
7448
7539
  throw new Error("Invalid redirect location");
7449
7540
  }
@@ -8685,7 +8776,7 @@ async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, ro
8685
8776
  return;
8686
8777
  }
8687
8778
  sessionStorage.setItem(MANIFEST_VERSION_STORAGE_KEY, manifest.version);
8688
- } catch (e5) {
8779
+ } catch (e7) {
8689
8780
  }
8690
8781
  window.location.href = errorReloadPath;
8691
8782
  console.warn("Detected manifest version mismatch, reloading...");
@@ -8696,7 +8787,7 @@ async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, ro
8696
8787
  }
8697
8788
  try {
8698
8789
  sessionStorage.removeItem(MANIFEST_VERSION_STORAGE_KEY);
8699
- } catch (e6) {
8790
+ } catch (e8) {
8700
8791
  }
8701
8792
  serverPatches = await res.json();
8702
8793
  } catch (e) {
@@ -9730,6 +9821,7 @@ function RouterProvider({
9730
9821
  let navigator = React9.useMemo(() => {
9731
9822
  return {
9732
9823
  createHref: router.createHref,
9824
+ createURL: router.createURL,
9733
9825
  encodeLocation: router.encodeLocation,
9734
9826
  go: (n) => router.navigate(n),
9735
9827
  push: (to, state2, opts) => router.navigate(to, {
@@ -9862,7 +9954,7 @@ function Navigate({
9862
9954
  // the router loaded. We can help them understand how to avoid that.
9863
9955
  `<Navigate> may be used only in the context of a <Router> component.`
9864
9956
  );
9865
- let { static: isStatic } = React9.useContext(NavigationContext);
9957
+ let { static: isStatic, navigator } = React9.useContext(NavigationContext);
9866
9958
  warning(
9867
9959
  !isStatic,
9868
9960
  `<Navigate> must not be used on the initial render in a <StaticRouter>. This is a no-op, but you should modify your code so the <Navigate> is only ever rendered in response to some user interaction or state change.`
@@ -9876,6 +9968,12 @@ function Navigate({
9876
9968
  locationPathname,
9877
9969
  relative === "path"
9878
9970
  );
9971
+ validateNavigationTarget(
9972
+ typeof to === "string" ? to : createPath(to),
9973
+ navigator.createHref(path),
9974
+ getNavigatorCurrentUrl(navigator),
9975
+ "reject"
9976
+ );
9879
9977
  let jsonPath = JSON.stringify(path);
9880
9978
  React9.useEffect(() => {
9881
9979
  navigate(JSON.parse(jsonPath), { replace: replace2, state, relative });
@@ -10304,4 +10402,5 @@ function withErrorBoundaryProps(ErrorBoundary) {
10304
10402
 
10305
10403
 
10306
10404
 
10307
- exports.ABSOLUTE_URL_REGEX = ABSOLUTE_URL_REGEX; exports.PROTOCOL_RELATIVE_URL_REGEX = PROTOCOL_RELATIVE_URL_REGEX; exports.Action = Action; exports.createMemoryHistory = createMemoryHistory; exports.createBrowserHistory = createBrowserHistory; exports.createHashHistory = createHashHistory; exports.invariant = invariant; exports.warning = warning; exports.createPath = createPath; exports.parsePath = parsePath; exports.createContext = createContext; exports.RouterContextProvider = RouterContextProvider; exports.convertRoutesToDataRoutes = convertRoutesToDataRoutes; exports.matchRoutes = matchRoutes; exports.matchRoutesImpl = matchRoutesImpl; exports.generatePath = generatePath; exports.matchPath = matchPath; exports.stripBasename = stripBasename; exports.resolvePath = resolvePath; exports.resolveTo = resolveTo; exports.joinPaths = joinPaths; exports.data = data; exports.redirect = redirect; exports.redirectDocument = redirectDocument; exports.replace = replace; exports.SUPPORTED_ERROR_TYPES = SUPPORTED_ERROR_TYPES; exports.ErrorResponseImpl = ErrorResponseImpl; exports.isRouteErrorResponse = isRouteErrorResponse; exports.parseToInfo = parseToInfo; exports.escapeHtml = escapeHtml; exports.encode = encode; exports.instrumentHandler = instrumentHandler; exports.IDLE_NAVIGATION = IDLE_NAVIGATION; exports.IDLE_FETCHER = IDLE_FETCHER; exports.IDLE_BLOCKER = IDLE_BLOCKER; exports.createRouter = createRouter; exports.createStaticHandler = createStaticHandler; exports.getStaticContextFromError = getStaticContextFromError; exports.hasInvalidProtocol = hasInvalidProtocol; exports.isDataWithResponseInit = isDataWithResponseInit; exports.isResponse = isResponse; exports.isRedirectStatusCode = isRedirectStatusCode; exports.isRedirectResponse = isRedirectResponse; exports.isMutationMethod = isMutationMethod; exports.createRequestInit = createRequestInit; exports.SingleFetchRedirectSymbol = SingleFetchRedirectSymbol; exports.SINGLE_FETCH_REDIRECT_STATUS = SINGLE_FETCH_REDIRECT_STATUS; exports.NO_BODY_STATUS_CODES = NO_BODY_STATUS_CODES; exports.StreamTransfer = StreamTransfer; exports.getTurboStreamSingleFetchDataStrategy = getTurboStreamSingleFetchDataStrategy; exports.getSingleFetchDataStrategyImpl = getSingleFetchDataStrategyImpl; exports.stripIndexParam = stripIndexParam; exports.singleFetchUrl = singleFetchUrl; exports.decodeViaTurboStream = decodeViaTurboStream; exports.DataRouterContext = DataRouterContext; exports.DataRouterStateContext = DataRouterStateContext; exports.RSCRouterContext = RSCRouterContext; exports.ViewTransitionContext = ViewTransitionContext; exports.FetchersContext = FetchersContext; exports.AwaitContextProvider = AwaitContextProvider; exports.NavigationContext = NavigationContext; exports.LocationContext = LocationContext; exports.RouteContext = RouteContext; exports.ENABLE_DEV_WARNINGS = ENABLE_DEV_WARNINGS; exports.warnOnce = warnOnce; exports.decodeRedirectErrorDigest = decodeRedirectErrorDigest; exports.decodeRouteErrorResponseDigest = decodeRouteErrorResponseDigest; exports.useHref = useHref; exports.useInRouterContext = useInRouterContext; exports.useLocation = useLocation; exports.useNavigationType = useNavigationType; exports.useMatch = useMatch; exports.useNavigate = useNavigate; exports.useOutletContext = useOutletContext; exports.useOutlet = useOutlet; exports.useParams = useParams; exports.useResolvedPath = useResolvedPath; exports.useRoutes = useRoutes; exports.useRouteId = useRouteId; exports.useNavigation = useNavigation; exports.useRevalidator = useRevalidator; exports.useMatches = useMatches; exports.useLoaderData = useLoaderData; exports.useRouteLoaderData = useRouteLoaderData; exports.useActionData = useActionData; exports.useRouteError = useRouteError; exports.useAsyncValue = useAsyncValue; exports.useAsyncError = useAsyncError; exports.useBlocker = useBlocker; exports.useRoute = useRoute; exports.useRouterState = useRouterState; exports.RemixErrorBoundary = RemixErrorBoundary; exports.createServerRoutes = createServerRoutes; exports.createClientRoutesWithHMRRevalidationOptOut = createClientRoutesWithHMRRevalidationOptOut; exports.noActionDefinedError = noActionDefinedError; exports.createClientRoutes = createClientRoutes; exports.shouldHydrateRouteLoader = shouldHydrateRouteLoader; exports.URL_LIMIT = URL_LIMIT; exports.getPathsWithAncestors = getPathsWithAncestors; exports.getPatchRoutesOnNavigationFunction = getPatchRoutesOnNavigationFunction; exports.useFogOFWarDiscovery = useFogOFWarDiscovery; exports.getManifestPath = getManifestPath; exports.FrameworkContext = FrameworkContext; exports.usePrefetchBehavior = usePrefetchBehavior; exports.CRITICAL_CSS_DATA_ATTRIBUTE = CRITICAL_CSS_DATA_ATTRIBUTE; exports.Links = Links; exports.PrefetchPageLinks = PrefetchPageLinks; exports.Meta = Meta; exports.setIsHydrated = setIsHydrated; exports.Scripts = Scripts; exports.mergeRefs = mergeRefs; exports.mapRouteProperties = mapRouteProperties; exports.hydrationRouteProperties = hydrationRouteProperties; exports.createMemoryRouter = createMemoryRouter; exports.RouterProvider = RouterProvider; exports.DataRoutes = DataRoutes2; exports.MemoryRouter = MemoryRouter; exports.Navigate = Navigate; exports.Outlet = Outlet; exports.Route = Route; exports.Router = Router; exports.Routes = Routes; exports.Await = Await; exports.createRoutesFromChildren = createRoutesFromChildren; exports.createRoutesFromElements = createRoutesFromElements; exports.renderMatches = renderMatches; exports.WithComponentProps = WithComponentProps; exports.withComponentProps = withComponentProps; exports.WithHydrateFallbackProps = WithHydrateFallbackProps; exports.withHydrateFallbackProps = withHydrateFallbackProps; exports.WithErrorBoundaryProps = WithErrorBoundaryProps; exports.withErrorBoundaryProps = withErrorBoundaryProps;
10405
+
10406
+ exports.ABSOLUTE_URL_REGEX = ABSOLUTE_URL_REGEX; exports.PROTOCOL_RELATIVE_URL_REGEX = PROTOCOL_RELATIVE_URL_REGEX; exports.Action = Action; exports.createMemoryHistory = createMemoryHistory; exports.createBrowserHistory = createBrowserHistory; exports.createHashHistory = createHashHistory; exports.invariant = invariant; exports.warning = warning; exports.createPath = createPath; exports.parsePath = parsePath; exports.createContext = createContext; exports.RouterContextProvider = RouterContextProvider; exports.convertRoutesToDataRoutes = convertRoutesToDataRoutes; exports.matchRoutes = matchRoutes; exports.matchRoutesImpl = matchRoutesImpl; exports.generatePath = generatePath; exports.matchPath = matchPath; exports.stripBasename = stripBasename; exports.resolvePath = resolvePath; exports.resolveTo = resolveTo; exports.joinPaths = joinPaths; exports.data = data; exports.redirect = redirect; exports.redirectDocument = redirectDocument; exports.replace = replace; exports.SUPPORTED_ERROR_TYPES = SUPPORTED_ERROR_TYPES; exports.ErrorResponseImpl = ErrorResponseImpl; exports.isRouteErrorResponse = isRouteErrorResponse; exports.parseToInfo = parseToInfo; exports.escapeHtml = escapeHtml; exports.encode = encode; exports.instrumentHandler = instrumentHandler; exports.validateNavigationTarget = validateNavigationTarget; exports.IDLE_NAVIGATION = IDLE_NAVIGATION; exports.IDLE_FETCHER = IDLE_FETCHER; exports.IDLE_BLOCKER = IDLE_BLOCKER; exports.createRouter = createRouter; exports.createStaticHandler = createStaticHandler; exports.getStaticContextFromError = getStaticContextFromError; exports.hasInvalidProtocol = hasInvalidProtocol; exports.isDataWithResponseInit = isDataWithResponseInit; exports.isResponse = isResponse; exports.isRedirectStatusCode = isRedirectStatusCode; exports.isRedirectResponse = isRedirectResponse; exports.isMutationMethod = isMutationMethod; exports.createRequestInit = createRequestInit; exports.SingleFetchRedirectSymbol = SingleFetchRedirectSymbol; exports.SINGLE_FETCH_REDIRECT_STATUS = SINGLE_FETCH_REDIRECT_STATUS; exports.NO_BODY_STATUS_CODES = NO_BODY_STATUS_CODES; exports.StreamTransfer = StreamTransfer; exports.getTurboStreamSingleFetchDataStrategy = getTurboStreamSingleFetchDataStrategy; exports.getSingleFetchDataStrategyImpl = getSingleFetchDataStrategyImpl; exports.stripIndexParam = stripIndexParam; exports.singleFetchUrl = singleFetchUrl; exports.decodeViaTurboStream = decodeViaTurboStream; exports.DataRouterContext = DataRouterContext; exports.DataRouterStateContext = DataRouterStateContext; exports.RSCRouterContext = RSCRouterContext; exports.ViewTransitionContext = ViewTransitionContext; exports.FetchersContext = FetchersContext; exports.AwaitContextProvider = AwaitContextProvider; exports.NavigationContext = NavigationContext; exports.LocationContext = LocationContext; exports.RouteContext = RouteContext; exports.ENABLE_DEV_WARNINGS = ENABLE_DEV_WARNINGS; exports.warnOnce = warnOnce; exports.decodeRedirectErrorDigest = decodeRedirectErrorDigest; exports.decodeRouteErrorResponseDigest = decodeRouteErrorResponseDigest; exports.useHref = useHref; exports.useInRouterContext = useInRouterContext; exports.useLocation = useLocation; exports.useNavigationType = useNavigationType; exports.useMatch = useMatch; exports.useNavigate = useNavigate; exports.useOutletContext = useOutletContext; exports.useOutlet = useOutlet; exports.useParams = useParams; exports.useResolvedPath = useResolvedPath; exports.useRoutes = useRoutes; exports.useRouteId = useRouteId; exports.useNavigation = useNavigation; exports.useRevalidator = useRevalidator; exports.useMatches = useMatches; exports.useLoaderData = useLoaderData; exports.useRouteLoaderData = useRouteLoaderData; exports.useActionData = useActionData; exports.useRouteError = useRouteError; exports.useAsyncValue = useAsyncValue; exports.useAsyncError = useAsyncError; exports.useBlocker = useBlocker; exports.useRoute = useRoute; exports.useRouterState = useRouterState; exports.RemixErrorBoundary = RemixErrorBoundary; exports.createServerRoutes = createServerRoutes; exports.createClientRoutesWithHMRRevalidationOptOut = createClientRoutesWithHMRRevalidationOptOut; exports.noActionDefinedError = noActionDefinedError; exports.createClientRoutes = createClientRoutes; exports.shouldHydrateRouteLoader = shouldHydrateRouteLoader; exports.URL_LIMIT = URL_LIMIT; exports.getPathsWithAncestors = getPathsWithAncestors; exports.getPatchRoutesOnNavigationFunction = getPatchRoutesOnNavigationFunction; exports.useFogOFWarDiscovery = useFogOFWarDiscovery; exports.getManifestPath = getManifestPath; exports.FrameworkContext = FrameworkContext; exports.usePrefetchBehavior = usePrefetchBehavior; exports.CRITICAL_CSS_DATA_ATTRIBUTE = CRITICAL_CSS_DATA_ATTRIBUTE; exports.Links = Links; exports.PrefetchPageLinks = PrefetchPageLinks; exports.Meta = Meta; exports.setIsHydrated = setIsHydrated; exports.Scripts = Scripts; exports.mergeRefs = mergeRefs; exports.mapRouteProperties = mapRouteProperties; exports.hydrationRouteProperties = hydrationRouteProperties; exports.createMemoryRouter = createMemoryRouter; exports.RouterProvider = RouterProvider; exports.DataRoutes = DataRoutes2; exports.MemoryRouter = MemoryRouter; exports.Navigate = Navigate; exports.Outlet = Outlet; exports.Route = Route; exports.Router = Router; exports.Routes = Routes; exports.Await = Await; exports.createRoutesFromChildren = createRoutesFromChildren; exports.createRoutesFromElements = createRoutesFromElements; exports.renderMatches = renderMatches; exports.WithComponentProps = WithComponentProps; exports.withComponentProps = withComponentProps; exports.WithHydrateFallbackProps = WithHydrateFallbackProps; exports.withHydrateFallbackProps = withHydrateFallbackProps; exports.WithErrorBoundaryProps = WithErrorBoundaryProps; exports.withErrorBoundaryProps = withErrorBoundaryProps;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v7.18.2
2
+ * react-router v7.18.3
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -784,13 +784,16 @@ function matchPathImpl(pattern, pathname, matcher, compiledParams) {
784
784
  let match = pathname.match(matcher);
785
785
  if (!match) return null;
786
786
  let matchedPathname = match[0];
787
- let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1");
787
+ let pathnameBase = removeTrailingSlash(matchedPathname, 1);
788
788
  let captureGroups = match.slice(1);
789
789
  let params = compiledParams.reduce(
790
790
  (memo2, { paramName, isOptional }, index) => {
791
791
  if (paramName === "*") {
792
792
  let splatValue = captureGroups[index] || "";
793
- pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1");
793
+ pathnameBase = removeTrailingSlash(
794
+ matchedPathname.slice(0, matchedPathname.length - splatValue.length),
795
+ 1
796
+ );
794
797
  }
795
798
  const value = captureGroups[index];
796
799
  if (isOptional && !value) {
@@ -880,7 +883,7 @@ function resolvePath(to, fromPathname = "/") {
880
883
  let pathname;
881
884
  if (toPathname) {
882
885
  toPathname = removeDoubleSlashes(toPathname);
883
- if (toPathname.startsWith("/")) {
886
+ if (toPathname.startsWith("/") || toPathname.startsWith("\\")) {
884
887
  pathname = resolvePathname(toPathname.substring(1), "/");
885
888
  } else {
886
889
  pathname = resolvePathname(toPathname, fromPathname);
@@ -968,7 +971,13 @@ function resolveTo(toArg, routePathnames, locationPathname, isPathRelative = fal
968
971
  }
969
972
  var removeDoubleSlashes = (path) => path.replace(/[\\/]{2,}/g, "/");
970
973
  var joinPaths = (paths) => removeDoubleSlashes(paths.join("/"));
971
- var removeTrailingSlash = (path) => path.replace(/\/+$/, "");
974
+ function removeTrailingSlash(path, minLength = 0) {
975
+ let end = path.length;
976
+ while (end > minLength && path.charCodeAt(end - 1) === 47) {
977
+ end--;
978
+ }
979
+ return end === path.length ? path : path.slice(0, end);
980
+ }
972
981
  var normalizePathname = (pathname) => removeTrailingSlash(pathname).replace(/^\/*/, "/");
973
982
  var normalizeSearch = (search) => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search;
974
983
  var normalizeHash = (hash) => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash;
@@ -1341,6 +1350,51 @@ function isPlainObject(thing) {
1341
1350
  return proto === Object.prototype || proto === null || Object.getOwnPropertyNames(proto).sort().join("\0") === objectProtoNames;
1342
1351
  }
1343
1352
 
1353
+ // lib/router/navigation.ts
1354
+ var DEFAULT_NAVIGATION_URL = new URL("http://localhost");
1355
+ function getNavigatorCurrentUrl(navigator) {
1356
+ if (navigator.createURL) {
1357
+ return navigator.createURL("/");
1358
+ }
1359
+ try {
1360
+ return new URL(navigator.createHref("/"), DEFAULT_NAVIGATION_URL);
1361
+ } catch {
1362
+ return DEFAULT_NAVIGATION_URL;
1363
+ }
1364
+ }
1365
+ function isSameOrigin(a, b) {
1366
+ return a.origin === b.origin && (a.origin !== "null" || a.protocol === b.protocol && a.host === b.host);
1367
+ }
1368
+ function isExplicitUrl(destination, target) {
1369
+ if (destination.startsWith("//")) {
1370
+ return true;
1371
+ }
1372
+ let protocol = target.protocol.toLowerCase();
1373
+ if (!destination.toLowerCase().startsWith(protocol)) {
1374
+ return false;
1375
+ }
1376
+ return target.host === "" || destination.slice(protocol.length).startsWith("//");
1377
+ }
1378
+ function validateNavigationTarget(original, resolved, currentUrl, externalPolicy) {
1379
+ let originalUrl = null;
1380
+ try {
1381
+ originalUrl = original == null ? null : new URL(original, currentUrl);
1382
+ } catch {
1383
+ }
1384
+ let resolvedUrl = new URL(resolved, currentUrl);
1385
+ let originalIsExternal = originalUrl != null && !isSameOrigin(originalUrl, currentUrl);
1386
+ let resolvedIsExternal = !isSameOrigin(resolvedUrl, currentUrl);
1387
+ if (externalPolicy === "reject") {
1388
+ if (originalIsExternal || resolvedIsExternal) {
1389
+ throw new Error("External navigation is not allowed");
1390
+ }
1391
+ } else if (resolvedIsExternal) {
1392
+ if (originalUrl == null || !isExplicitUrl(original, originalUrl) || !isSameOrigin(originalUrl, resolvedUrl)) {
1393
+ throw new Error("External navigation is not allowed");
1394
+ }
1395
+ }
1396
+ }
1397
+
1344
1398
  // lib/router/router.ts
1345
1399
  var validMutationMethodsArr = [
1346
1400
  "POST",
@@ -1852,11 +1906,21 @@ function createRouter(init) {
1852
1906
  ...opts.mask
1853
1907
  };
1854
1908
  maskPath = {
1855
- pathname: "",
1856
- search: "",
1857
- hash: "",
1858
- ...partialPath
1909
+ pathname: partialPath.pathname ?? "",
1910
+ search: partialPath.search ?? "",
1911
+ hash: partialPath.hash ?? ""
1859
1912
  };
1913
+ if (PROTOCOL_RELATIVE_URL_REGEX.test(maskPath.pathname)) {
1914
+ throw new Error("External navigation is not allowed");
1915
+ } else if (maskPath.pathname.startsWith("\\")) {
1916
+ maskPath.pathname = maskPath.pathname.replace(/^\\+/, "/");
1917
+ }
1918
+ validateNavigationTarget(
1919
+ typeof opts.mask === "string" ? opts.mask : createPath(opts.mask),
1920
+ createPath(maskPath),
1921
+ init.history.createURL("/"),
1922
+ "reject"
1923
+ );
1860
1924
  }
1861
1925
  let currentLocation = state.location;
1862
1926
  let nextLocation = createLocation(
@@ -1870,6 +1934,12 @@ function createRouter(init) {
1870
1934
  ...nextLocation,
1871
1935
  ...init.history.encodeLocation(nextLocation)
1872
1936
  };
1937
+ validateNavigationTarget(
1938
+ to == null ? init.history.createHref(state.location) : typeof to === "string" ? to : createPath(to),
1939
+ init.history.createHref(nextLocation.mask || nextLocation),
1940
+ init.history.createURL("/"),
1941
+ "reject"
1942
+ );
1873
1943
  let userReplace = opts && opts.replace != null ? opts.replace : void 0;
1874
1944
  let historyAction = "PUSH" /* Push */;
1875
1945
  if (userReplace === true) {
@@ -2880,12 +2950,20 @@ function createRouter(init) {
2880
2950
  }
2881
2951
  let location = redirect2.response.headers.get("Location");
2882
2952
  invariant(location, "Expected a Location header on the redirect Response");
2953
+ let originalLocation = location;
2954
+ let currentUrl = new URL(request.url);
2883
2955
  location = normalizeRedirectLocation(
2884
2956
  location,
2885
- new URL(request.url),
2957
+ currentUrl,
2886
2958
  basename,
2887
2959
  init.history
2888
2960
  );
2961
+ validateNavigationTarget(
2962
+ originalLocation,
2963
+ location,
2964
+ currentUrl,
2965
+ "allow-explicit"
2966
+ );
2889
2967
  let redirectLocation = createLocation(state.location, location, {
2890
2968
  _isRedirect: true
2891
2969
  });
@@ -3404,6 +3482,7 @@ function createRouter(init) {
3404
3482
  // Passthrough to history-aware createHref used by useHref so we get proper
3405
3483
  // hash-aware URLs in DOM paths
3406
3484
  createHref: (to) => init.history.createHref(to),
3485
+ createURL: (to) => init.history.createURL(to),
3407
3486
  encodeLocation: (to) => init.history.encodeLocation(to),
3408
3487
  getFetcher,
3409
3488
  resetFetcher,
@@ -5945,6 +6024,12 @@ function useNavigateUnstable() {
5945
6024
  if (dataRouterContext == null && basename !== "/") {
5946
6025
  path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]);
5947
6026
  }
6027
+ validateNavigationTarget(
6028
+ typeof to === "string" ? to : createPath(to),
6029
+ navigator.createHref(path),
6030
+ getNavigatorCurrentUrl(navigator),
6031
+ "reject"
6032
+ );
5948
6033
  (!!options.replace ? navigator.replace : navigator.push)(
5949
6034
  path,
5950
6035
  options.state,
@@ -6186,7 +6271,7 @@ function RSCErrorHandler({
6186
6271
  children,
6187
6272
  error
6188
6273
  }) {
6189
- let { basename } = React2.useContext(NavigationContext);
6274
+ let { basename, navigator } = React2.useContext(NavigationContext);
6190
6275
  if (typeof error === "object" && error && "digest" in error && typeof error.digest === "string") {
6191
6276
  let redirect2 = decodeRedirectErrorDigest(error.digest);
6192
6277
  if (redirect2) {
@@ -6194,6 +6279,12 @@ function RSCErrorHandler({
6194
6279
  if (existingRedirect) throw existingRedirect;
6195
6280
  let parsed = parseToInfo(redirect2.location, basename);
6196
6281
  let target = parsed.absoluteURL || parsed.to;
6282
+ validateNavigationTarget(
6283
+ redirect2.location,
6284
+ target,
6285
+ getNavigatorCurrentUrl(navigator),
6286
+ "allow-explicit"
6287
+ );
6197
6288
  if (hasInvalidProtocol(target)) {
6198
6289
  throw new Error("Invalid redirect location");
6199
6290
  }
@@ -6871,6 +6962,7 @@ function RouterProvider({
6871
6962
  let navigator = React3.useMemo(() => {
6872
6963
  return {
6873
6964
  createHref: router.createHref,
6965
+ createURL: router.createURL,
6874
6966
  encodeLocation: router.encodeLocation,
6875
6967
  go: (n) => router.navigate(n),
6876
6968
  push: (to, state2, opts) => router.navigate(to, {
@@ -7003,7 +7095,7 @@ function Navigate({
7003
7095
  // the router loaded. We can help them understand how to avoid that.
7004
7096
  `<Navigate> may be used only in the context of a <Router> component.`
7005
7097
  );
7006
- let { static: isStatic } = React3.useContext(NavigationContext);
7098
+ let { static: isStatic, navigator } = React3.useContext(NavigationContext);
7007
7099
  warning(
7008
7100
  !isStatic,
7009
7101
  `<Navigate> must not be used on the initial render in a <StaticRouter>. This is a no-op, but you should modify your code so the <Navigate> is only ever rendered in response to some user interaction or state change.`
@@ -7017,6 +7109,12 @@ function Navigate({
7017
7109
  locationPathname,
7018
7110
  relative === "path"
7019
7111
  );
7112
+ validateNavigationTarget(
7113
+ typeof to === "string" ? to : createPath(to),
7114
+ navigator.createHref(path),
7115
+ getNavigatorCurrentUrl(navigator),
7116
+ "reject"
7117
+ );
7020
7118
  let jsonPath = JSON.stringify(path);
7021
7119
  React3.useEffect(() => {
7022
7120
  navigate(JSON.parse(jsonPath), { replace: replace2, state, relative });
@@ -10307,7 +10405,7 @@ var isBrowser2 = typeof window !== "undefined" && typeof window.document !== "un
10307
10405
  try {
10308
10406
  if (isBrowser2) {
10309
10407
  window.__reactRouterVersion = // @ts-expect-error
10310
- "7.18.2";
10408
+ "7.18.3";
10311
10409
  }
10312
10410
  } catch (e) {
10313
10411
  }
@@ -11481,6 +11579,7 @@ export {
11481
11579
  ErrorResponseImpl,
11482
11580
  isRouteErrorResponse,
11483
11581
  instrumentHandler,
11582
+ validateNavigationTarget,
11484
11583
  IDLE_NAVIGATION,
11485
11584
  IDLE_FETCHER,
11486
11585
  IDLE_BLOCKER,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v7.18.2
2
+ * react-router v7.18.3
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -55,7 +55,7 @@ import {
55
55
  withComponentProps,
56
56
  withErrorBoundaryProps,
57
57
  withHydrateFallbackProps
58
- } from "./chunk-62JRHF6Z.mjs";
58
+ } from "./chunk-BV7QT456.mjs";
59
59
 
60
60
  // lib/dom/ssr/server.tsx
61
61
  import * as React from "react";
@@ -747,18 +747,25 @@ function prependCookies(parentHeaders, childHeaders) {
747
747
  function throwIfPotentialCSRFAttack(request, allowedActionOrigins) {
748
748
  let originHeader = request.headers.get("origin");
749
749
  let originDomain = null;
750
+ let originUrl = null;
750
751
  try {
751
- originDomain = typeof originHeader === "string" && originHeader !== "null" ? new URL(originHeader).host : originHeader;
752
+ if (typeof originHeader === "string" && originHeader !== "null") {
753
+ originUrl = new URL(originHeader);
754
+ originDomain = originUrl.host;
755
+ } else {
756
+ originDomain = originHeader;
757
+ }
752
758
  } catch {
753
759
  throw new Error(
754
760
  `\`origin\` header is not a valid URL. Aborting the action.`
755
761
  );
756
762
  }
757
- let host = new URL(request.url).host;
758
- if (originDomain && originDomain !== host) {
763
+ let requestUrl = new URL(request.url);
764
+ let originMatchesRequest = originUrl ? originUrl.origin === requestUrl.origin : originDomain === requestUrl.host;
765
+ if (originDomain && !originMatchesRequest) {
759
766
  if (!isAllowedOrigin(originDomain, allowedActionOrigins)) {
760
767
  throw new Error(
761
- "The `request.url` host does not match `origin` header from a forwarded action request. Aborting the action."
768
+ "The `request.url` origin does not match `origin` header from a forwarded action request. Aborting the action."
762
769
  );
763
770
  }
764
771
  }