next-csrf
Version:
CSRF mitigation library for Next.js
1 lines • 16.2 kB
JSON
{"ast":null,"code":"\"use strict\";\n\nvar _defineProperty = require(\"@babel/runtime/helpers/defineProperty\");\n\nvar _slicedToArray = require(\"@babel/runtime/helpers/slicedToArray\");\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === \"undefined\" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === \"number\") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it[\"return\"] != null) it[\"return\"](); } finally { if (didErr) throw err; } } }; }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nexports.__esModule = true;\nexports[\"default\"] = prepareDestination;\n\nvar _querystring = require(\"./querystring\");\n\nvar _parseRelativeUrl = require(\"./parse-relative-url\");\n\nvar pathToRegexp = _interopRequireWildcard(require(\"next/dist/compiled/path-to-regexp\"));\n\nfunction _getRequireWildcardCache() {\n if (typeof WeakMap !== \"function\") return null;\n var cache = new WeakMap();\n\n _getRequireWildcardCache = function _getRequireWildcardCache() {\n return cache;\n };\n\n return cache;\n}\n\nfunction _interopRequireWildcard(obj) {\n if (obj && obj.__esModule) {\n return obj;\n }\n\n if (obj === null || typeof obj !== \"object\" && typeof obj !== \"function\") {\n return {\n \"default\": obj\n };\n }\n\n var cache = _getRequireWildcardCache();\n\n if (cache && cache.has(obj)) {\n return cache.get(obj);\n }\n\n var newObj = {};\n var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;\n\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;\n\n if (desc && (desc.get || desc.set)) {\n Object.defineProperty(newObj, key, desc);\n } else {\n newObj[key] = obj[key];\n }\n }\n }\n\n newObj[\"default\"] = obj;\n\n if (cache) {\n cache.set(obj, newObj);\n }\n\n return newObj;\n}\n\nfunction prepareDestination(destination, params, query, appendParamsToQuery, basePath) {\n var parsedDestination = {};\n\n if (destination.startsWith('/')) {\n parsedDestination = (0, _parseRelativeUrl.parseRelativeUrl)(destination);\n } else {\n var _URL = new URL(destination),\n pathname = _URL.pathname,\n searchParams = _URL.searchParams,\n hash = _URL.hash,\n hostname = _URL.hostname,\n port = _URL.port,\n protocol = _URL.protocol,\n search = _URL.search,\n href = _URL.href;\n\n parsedDestination = {\n pathname: pathname,\n searchParams: searchParams,\n hash: hash,\n protocol: protocol,\n hostname: hostname,\n port: port,\n search: search,\n href: href\n };\n }\n\n parsedDestination.query = (0, _querystring.searchParamsToUrlQuery)(parsedDestination.searchParams);\n var destQuery = parsedDestination.query;\n var destPath = \"\".concat(parsedDestination.pathname).concat(parsedDestination.hash || '');\n var destPathParamKeys = [];\n pathToRegexp.pathToRegexp(destPath, destPathParamKeys);\n var destPathParams = destPathParamKeys.map(function (key) {\n return key.name;\n });\n var destinationCompiler = pathToRegexp.compile(destPath, // we don't validate while compiling the destination since we should\n // have already validated before we got to this point and validating\n // breaks compiling destinations with named pattern params from the source\n // e.g. /something:hello(.*) -> /another/:hello is broken with validation\n // since compile validation is meant for reversing and not for inserting\n // params from a separate path-regex into another\n {\n validate: false\n });\n var newUrl; // update any params in query values\n\n for (var _i = 0, _Object$entries = Object.entries(destQuery); _i < _Object$entries.length; _i++) {\n var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),\n key = _Object$entries$_i[0],\n strOrArray = _Object$entries$_i[1];\n\n var value = Array.isArray(strOrArray) ? strOrArray[0] : strOrArray;\n\n if (value) {\n // the value needs to start with a forward-slash to be compiled\n // correctly\n value = \"/\".concat(value);\n var queryCompiler = pathToRegexp.compile(value, {\n validate: false\n });\n value = queryCompiler(params).substr(1);\n }\n\n destQuery[key] = value;\n } // add path params to query if it's not a redirect and not\n // already defined in destination query or path\n\n\n var paramKeys = Object.keys(params);\n\n if (appendParamsToQuery && !paramKeys.some(function (key) {\n return destPathParams.includes(key);\n })) {\n var _iterator = _createForOfIteratorHelper(paramKeys),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var _key = _step.value;\n\n if (!(_key in destQuery)) {\n destQuery[_key] = params[_key];\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n\n var shouldAddBasePath = destination.startsWith('/') && basePath;\n\n try {\n newUrl = \"\".concat(shouldAddBasePath ? basePath : '').concat(encodeURI(destinationCompiler(params)));\n\n var _newUrl$split = newUrl.split('#'),\n _newUrl$split2 = _slicedToArray(_newUrl$split, 2),\n _pathname = _newUrl$split2[0],\n _hash = _newUrl$split2[1];\n\n parsedDestination.pathname = _pathname;\n parsedDestination.hash = \"\".concat(_hash ? '#' : '').concat(_hash || '');\n delete parsedDestination.search;\n delete parsedDestination.searchParams;\n } catch (err) {\n if (err.message.match(/Expected .*? to not repeat, but got an array/)) {\n throw new Error(\"To use a multi-match in the destination you must add `*` at the end of the param name to signify it should repeat. https://err.sh/vercel/next.js/invalid-multi-match\");\n }\n\n throw err;\n } // Query merge order lowest priority to highest\n // 1. initial URL query values\n // 2. path segment values\n // 3. destination specified query values\n\n\n parsedDestination.query = _objectSpread(_objectSpread({}, query), parsedDestination.query);\n return {\n newUrl: newUrl,\n parsedDestination: parsedDestination\n };\n}","map":{"version":3,"sources":["../../../../../next-server/lib/router/utils/prepare-destination.ts"],"names":["parsedDestination","destination","pathname","searchParams","hash","protocol","hostname","port","search","href","destQuery","destPath","destPathParamKeys","pathToRegexp","destPathParams","key","destinationCompiler","validate","Object","value","Array","strOrArray","queryCompiler","paramKeys","appendParamsToQuery","params","shouldAddBasePath","newUrl","encodeURI","err"],"mappings":"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","sourcesContent":["import { ParsedUrlQuery } from 'querystring'\nimport { searchParamsToUrlQuery } from './querystring'\nimport { parseRelativeUrl } from './parse-relative-url'\nimport * as pathToRegexp from 'next/dist/compiled/path-to-regexp'\n\ntype Params = { [param: string]: any }\n\nexport default function prepareDestination(\n destination: string,\n params: Params,\n query: ParsedUrlQuery,\n appendParamsToQuery: boolean,\n basePath: string\n) {\n let parsedDestination: {\n query?: ParsedUrlQuery\n protocol?: string\n hostname?: string\n port?: string\n } & ReturnType<typeof parseRelativeUrl> = {} as any\n\n if (destination.startsWith('/')) {\n parsedDestination = parseRelativeUrl(destination)\n } else {\n const {\n pathname,\n searchParams,\n hash,\n hostname,\n port,\n protocol,\n search,\n href,\n } = new URL(destination)\n\n parsedDestination = {\n pathname,\n searchParams,\n hash,\n protocol,\n hostname,\n port,\n search,\n href,\n }\n }\n\n parsedDestination.query = searchParamsToUrlQuery(\n parsedDestination.searchParams\n )\n const destQuery = parsedDestination.query\n const destPath = `${parsedDestination.pathname!}${\n parsedDestination.hash || ''\n }`\n const destPathParamKeys: pathToRegexp.Key[] = []\n pathToRegexp.pathToRegexp(destPath, destPathParamKeys)\n\n const destPathParams = destPathParamKeys.map((key) => key.name)\n\n let destinationCompiler = pathToRegexp.compile(\n destPath,\n // we don't validate while compiling the destination since we should\n // have already validated before we got to this point and validating\n // breaks compiling destinations with named pattern params from the source\n // e.g. /something:hello(.*) -> /another/:hello is broken with validation\n // since compile validation is meant for reversing and not for inserting\n // params from a separate path-regex into another\n { validate: false }\n )\n let newUrl\n\n // update any params in query values\n for (const [key, strOrArray] of Object.entries(destQuery)) {\n let value = Array.isArray(strOrArray) ? strOrArray[0] : strOrArray\n if (value) {\n // the value needs to start with a forward-slash to be compiled\n // correctly\n value = `/${value}`\n const queryCompiler = pathToRegexp.compile(value, { validate: false })\n value = queryCompiler(params).substr(1)\n }\n destQuery[key] = value\n }\n\n // add path params to query if it's not a redirect and not\n // already defined in destination query or path\n const paramKeys = Object.keys(params)\n\n if (\n appendParamsToQuery &&\n !paramKeys.some((key) => destPathParams.includes(key))\n ) {\n for (const key of paramKeys) {\n if (!(key in destQuery)) {\n destQuery[key] = params[key]\n }\n }\n }\n\n const shouldAddBasePath = destination.startsWith('/') && basePath\n\n try {\n newUrl = `${shouldAddBasePath ? basePath : ''}${encodeURI(\n destinationCompiler(params)\n )}`\n\n const [pathname, hash] = newUrl.split('#')\n parsedDestination.pathname = pathname\n parsedDestination.hash = `${hash ? '#' : ''}${hash || ''}`\n delete parsedDestination.search\n delete parsedDestination.searchParams\n } catch (err) {\n if (err.message.match(/Expected .*? to not repeat, but got an array/)) {\n throw new Error(\n `To use a multi-match in the destination you must add \\`*\\` at the end of the param name to signify it should repeat. https://err.sh/vercel/next.js/invalid-multi-match`\n )\n }\n throw err\n }\n\n // Query merge order lowest priority to highest\n // 1. initial URL query values\n // 2. path segment values\n // 3. destination specified query values\n parsedDestination.query = {\n ...query,\n ...parsedDestination.query,\n }\n\n return {\n newUrl,\n parsedDestination,\n }\n}\n"]},"metadata":{},"sourceType":"script"}