@verdaccio/core 9.0.0-next-9.15 → 9.0.0-next-9.16

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.
@@ -14,3 +14,39 @@ export declare function createTempFolder(prefix: string): Promise<string>;
14
14
  * @returns
15
15
  */
16
16
  export declare function createTempStorageFolder(prefix: string, folder?: string): Promise<string>;
17
+ /**
18
+ * Resolve a safe path within a base directory, preventing directory traversal attacks.
19
+ *
20
+ * This function provides security against path traversal by:
21
+ * - URL decoding the input path
22
+ * - Resolving the full absolute path
23
+ * - Checking that the resolved path stays within the base directory
24
+ * - Rejecting paths containing '..' that would escape the base directory
25
+ * - Rejecting absolute paths that bypass the base directory
26
+ *
27
+ * @param basePath The base directory that constrains file access
28
+ * @param requestPath The requested path from user input (may be URL-encoded)
29
+ * @returns The resolved safe absolute path or null if the path is unsafe/invalid
30
+ * @security Prevents directory traversal attacks by validating resolved paths
31
+ */
32
+ export declare function resolveSafePath(basePath: string, requestPath?: string): string | null;
33
+ /**
34
+ * Sanitize a user-provided path while preserving directory separators.
35
+ *
36
+ * The web middleware uses this for `/-/assets/{*all}` which may include
37
+ * subfolders (e.g. `logos/verdaccio.svg`). We sanitize each path segment
38
+ * independently so `/` remains a real directory boundary.
39
+ *
40
+ * TODO: `sanitize-filename` silently rewrites segments instead of rejecting
41
+ * them (`file\0.txt` -> `file.txt`, `CON.svg` -> `.svg`, oversized segments
42
+ * truncated). Not exploitable today, but surprising; prefer 404 on destructive
43
+ * rewrite.
44
+ * TODO: `=== '..'` check is whitespace-strict — ` ..` / `.. ` slips past it.
45
+ * Use `path.normalize` before splitting, or `segment.trim() === '..'`.
46
+ * TODO: largely redundant with `resolveSafePath` on POSIX; the dep mainly earns
47
+ * its keep on Windows. Consider an inline `[<>:"|?*\0]` regex to drop the dep.
48
+ *
49
+ * @param filename The user-provided filename/path to sanitize.
50
+ * @returns The sanitized filename/path.
51
+ */
52
+ export declare function sanitizeFilename(filename: string): string;
@@ -4,11 +4,15 @@ let node_os = require("node:os");
4
4
  node_os = require_runtime.__toESM(node_os);
5
5
  let node_path = require("node:path");
6
6
  node_path = require_runtime.__toESM(node_path);
7
+ let sanitize_filename = require("sanitize-filename");
8
+ sanitize_filename = require_runtime.__toESM(sanitize_filename);
7
9
  //#region src/file-utils.ts
8
10
  var file_utils_exports = /* @__PURE__ */ require_runtime.__exportAll({
9
11
  Files: () => Files,
10
12
  createTempFolder: () => createTempFolder,
11
- createTempStorageFolder: () => createTempStorageFolder
13
+ createTempStorageFolder: () => createTempStorageFolder,
14
+ resolveSafePath: () => resolveSafePath,
15
+ sanitizeFilename: () => sanitizeFilename
12
16
  });
13
17
  var Files = { DatabaseName: ".verdaccio-db.json" };
14
18
  /**
@@ -31,6 +35,61 @@ async function createTempStorageFolder(prefix, folder = "storage") {
31
35
  await (0, node_fs_promises.mkdir)(storageFolder);
32
36
  return storageFolder;
33
37
  }
38
+ /**
39
+ * Resolve a safe path within a base directory, preventing directory traversal attacks.
40
+ *
41
+ * This function provides security against path traversal by:
42
+ * - URL decoding the input path
43
+ * - Resolving the full absolute path
44
+ * - Checking that the resolved path stays within the base directory
45
+ * - Rejecting paths containing '..' that would escape the base directory
46
+ * - Rejecting absolute paths that bypass the base directory
47
+ *
48
+ * @param basePath The base directory that constrains file access
49
+ * @param requestPath The requested path from user input (may be URL-encoded)
50
+ * @returns The resolved safe absolute path or null if the path is unsafe/invalid
51
+ * @security Prevents directory traversal attacks by validating resolved paths
52
+ */
53
+ function resolveSafePath(basePath, requestPath) {
54
+ try {
55
+ if (!requestPath || requestPath === "") return null;
56
+ const decoded = decodeURIComponent(requestPath);
57
+ if (node_path.default.isAbsolute(decoded)) return null;
58
+ const baseResolved = node_path.default.resolve(basePath);
59
+ const reqResolved = node_path.default.resolve(baseResolved, decoded);
60
+ const baseComparable = process.platform === "win32" ? baseResolved.toLowerCase() : baseResolved;
61
+ const reqComparable = process.platform === "win32" ? reqResolved.toLowerCase() : reqResolved;
62
+ if (reqComparable !== baseComparable && !reqComparable.startsWith(baseComparable + node_path.default.sep)) return null;
63
+ return reqResolved;
64
+ } catch {
65
+ return null;
66
+ }
67
+ }
68
+ /**
69
+ * Sanitize a user-provided path while preserving directory separators.
70
+ *
71
+ * The web middleware uses this for `/-/assets/{*all}` which may include
72
+ * subfolders (e.g. `logos/verdaccio.svg`). We sanitize each path segment
73
+ * independently so `/` remains a real directory boundary.
74
+ *
75
+ * TODO: `sanitize-filename` silently rewrites segments instead of rejecting
76
+ * them (`file\0.txt` -> `file.txt`, `CON.svg` -> `.svg`, oversized segments
77
+ * truncated). Not exploitable today, but surprising; prefer 404 on destructive
78
+ * rewrite.
79
+ * TODO: `=== '..'` check is whitespace-strict — ` ..` / `.. ` slips past it.
80
+ * Use `path.normalize` before splitting, or `segment.trim() === '..'`.
81
+ * TODO: largely redundant with `resolveSafePath` on POSIX; the dep mainly earns
82
+ * its keep on Windows. Consider an inline `[<>:"|?*\0]` regex to drop the dep.
83
+ *
84
+ * @param filename The user-provided filename/path to sanitize.
85
+ * @returns The sanitized filename/path.
86
+ */
87
+ function sanitizeFilename(filename) {
88
+ return filename.replace(/\\/g, "/").split("/").map((segment) => {
89
+ if (segment === "." || segment === "..") return segment;
90
+ return (0, sanitize_filename.default)(segment);
91
+ }).join("/");
92
+ }
34
93
  //#endregion
35
94
  Object.defineProperty(exports, "file_utils_exports", {
36
95
  enumerable: true,
@@ -1 +1 @@
1
- {"version":3,"file":"file-utils.js","names":[],"sources":["../src/file-utils.ts"],"sourcesContent":["import { mkdir, mkdtemp } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\nexport const Files = {\n DatabaseName: '.verdaccio-db.json',\n};\n\n/**\n * Create a temporary folder.\n * @param prefix The prefix of the folder name.\n * @returns string\n */\nexport async function createTempFolder(prefix: string): Promise<string> {\n return await mkdtemp(path.join(os.tmpdir(), 'verdaccio-' + prefix + '-'));\n}\n\n/**\n * Create temporary folder for an asset.\n * @param prefix\n * @param folder name\n * @returns\n */\nexport async function createTempStorageFolder(prefix: string, folder = 'storage'): Promise<string> {\n const tempFolder = await createTempFolder(prefix);\n const storageFolder = path.join(tempFolder, folder);\n await mkdir(storageFolder);\n return storageFolder;\n}\n"],"mappings":";;;;;;;;;;;;AAIA,IAAa,QAAQ,EACnB,cAAc,sBACf;;;;;;AAOD,eAAsB,iBAAiB,QAAiC;AACtE,QAAO,OAAA,GAAA,iBAAA,SAAc,UAAA,QAAK,KAAK,QAAA,QAAG,QAAQ,EAAE,eAAe,SAAS,IAAI,CAAC;;;;;;;;AAS3E,eAAsB,wBAAwB,QAAgB,SAAS,WAA4B;CACjG,MAAM,aAAa,MAAM,iBAAiB,OAAO;CACjD,MAAM,gBAAgB,UAAA,QAAK,KAAK,YAAY,OAAO;AACnD,QAAA,GAAA,iBAAA,OAAY,cAAc;AAC1B,QAAO"}
1
+ {"version":3,"file":"file-utils.js","names":[],"sources":["../src/file-utils.ts"],"sourcesContent":["import { mkdir, mkdtemp } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\nimport sanitize from 'sanitize-filename';\n\nexport const Files = {\n DatabaseName: '.verdaccio-db.json',\n};\n\n/**\n * Create a temporary folder.\n * @param prefix The prefix of the folder name.\n * @returns string\n */\nexport async function createTempFolder(prefix: string): Promise<string> {\n return await mkdtemp(path.join(os.tmpdir(), 'verdaccio-' + prefix + '-'));\n}\n\n/**\n * Create temporary folder for an asset.\n * @param prefix\n * @param folder name\n * @returns\n */\nexport async function createTempStorageFolder(prefix: string, folder = 'storage'): Promise<string> {\n const tempFolder = await createTempFolder(prefix);\n const storageFolder = path.join(tempFolder, folder);\n await mkdir(storageFolder);\n return storageFolder;\n}\n\n/**\n * Resolve a safe path within a base directory, preventing directory traversal attacks.\n *\n * This function provides security against path traversal by:\n * - URL decoding the input path\n * - Resolving the full absolute path\n * - Checking that the resolved path stays within the base directory\n * - Rejecting paths containing '..' that would escape the base directory\n * - Rejecting absolute paths that bypass the base directory\n *\n * @param basePath The base directory that constrains file access\n * @param requestPath The requested path from user input (may be URL-encoded)\n * @returns The resolved safe absolute path or null if the path is unsafe/invalid\n * @security Prevents directory traversal attacks by validating resolved paths\n */\nexport function resolveSafePath(basePath: string, requestPath?: string): string | null {\n try {\n if (!requestPath || requestPath === '') {\n return null;\n }\n\n const decoded = decodeURIComponent(requestPath);\n // Prevent absolute paths (should not start from '/')\n if (path.isAbsolute(decoded)) {\n return null;\n }\n\n // Resolve against the base directory without requiring the target to exist.\n const baseResolved = path.resolve(basePath);\n const reqResolved = path.resolve(baseResolved, decoded);\n\n // Normalize for Windows case-insensitive filesystem comparisons.\n const baseComparable = process.platform === 'win32' ? baseResolved.toLowerCase() : baseResolved;\n const reqComparable = process.platform === 'win32' ? reqResolved.toLowerCase() : reqResolved;\n\n // Ensure the resolved path is within basePath (subdirectory or exactly the base).\n if (reqComparable !== baseComparable && !reqComparable.startsWith(baseComparable + path.sep)) {\n return null;\n }\n\n return reqResolved;\n } catch {\n // error resolving path (e.g., path does not exist or permission denied)\n return null;\n }\n}\n\n/**\n * Sanitize a user-provided path while preserving directory separators.\n *\n * The web middleware uses this for `/-/assets/{*all}` which may include\n * subfolders (e.g. `logos/verdaccio.svg`). We sanitize each path segment\n * independently so `/` remains a real directory boundary.\n *\n * TODO: `sanitize-filename` silently rewrites segments instead of rejecting\n * them (`file\\0.txt` -> `file.txt`, `CON.svg` -> `.svg`, oversized segments\n * truncated). Not exploitable today, but surprising; prefer 404 on destructive\n * rewrite.\n * TODO: `=== '..'` check is whitespace-strict — ` ..` / `.. ` slips past it.\n * Use `path.normalize` before splitting, or `segment.trim() === '..'`.\n * TODO: largely redundant with `resolveSafePath` on POSIX; the dep mainly earns\n * its keep on Windows. Consider an inline `[<>:\"|?*\\0]` regex to drop the dep.\n *\n * @param filename The user-provided filename/path to sanitize.\n * @returns The sanitized filename/path.\n */\nexport function sanitizeFilename(filename: string): string {\n // normalize windows path separator so the result is stable across platforms\n const normalized = filename.replace(/\\\\/g, '/');\n const segments = normalized.split('/').map((segment) => {\n // Keep traversal markers intact so `resolveSafePath()` can correctly\n // reject paths escaping the base directory.\n if (segment === '.' || segment === '..') {\n return segment;\n }\n return sanitize(segment);\n });\n return segments.join('/');\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAKA,IAAa,QAAQ,EACnB,cAAc,sBACf;;;;;;AAOD,eAAsB,iBAAiB,QAAiC;AACtE,QAAO,OAAA,GAAA,iBAAA,SAAc,UAAA,QAAK,KAAK,QAAA,QAAG,QAAQ,EAAE,eAAe,SAAS,IAAI,CAAC;;;;;;;;AAS3E,eAAsB,wBAAwB,QAAgB,SAAS,WAA4B;CACjG,MAAM,aAAa,MAAM,iBAAiB,OAAO;CACjD,MAAM,gBAAgB,UAAA,QAAK,KAAK,YAAY,OAAO;AACnD,QAAA,GAAA,iBAAA,OAAY,cAAc;AAC1B,QAAO;;;;;;;;;;;;;;;;;AAkBT,SAAgB,gBAAgB,UAAkB,aAAqC;AACrF,KAAI;AACF,MAAI,CAAC,eAAe,gBAAgB,GAClC,QAAO;EAGT,MAAM,UAAU,mBAAmB,YAAY;AAE/C,MAAI,UAAA,QAAK,WAAW,QAAQ,CAC1B,QAAO;EAIT,MAAM,eAAe,UAAA,QAAK,QAAQ,SAAS;EAC3C,MAAM,cAAc,UAAA,QAAK,QAAQ,cAAc,QAAQ;EAGvD,MAAM,iBAAiB,QAAQ,aAAa,UAAU,aAAa,aAAa,GAAG;EACnF,MAAM,gBAAgB,QAAQ,aAAa,UAAU,YAAY,aAAa,GAAG;AAGjF,MAAI,kBAAkB,kBAAkB,CAAC,cAAc,WAAW,iBAAiB,UAAA,QAAK,IAAI,CAC1F,QAAO;AAGT,SAAO;SACD;AAEN,SAAO;;;;;;;;;;;;;;;;;;;;;;AAuBX,SAAgB,iBAAiB,UAA0B;AAWzD,QATmB,SAAS,QAAQ,OAAO,IAAI,CACnB,MAAM,IAAI,CAAC,KAAK,YAAY;AAGtD,MAAI,YAAY,OAAO,YAAY,KACjC,QAAO;AAET,UAAA,GAAA,kBAAA,SAAgB,QAAQ;GACxB,CACc,KAAK,IAAI"}
@@ -2,11 +2,14 @@ import { __exportAll } from "./_virtual/_rolldown/runtime.mjs";
2
2
  import { mkdir, mkdtemp } from "node:fs/promises";
3
3
  import os from "node:os";
4
4
  import path from "node:path";
5
+ import sanitize from "sanitize-filename";
5
6
  //#region src/file-utils.ts
6
7
  var file_utils_exports = /* @__PURE__ */ __exportAll({
7
8
  Files: () => Files,
8
9
  createTempFolder: () => createTempFolder,
9
- createTempStorageFolder: () => createTempStorageFolder
10
+ createTempStorageFolder: () => createTempStorageFolder,
11
+ resolveSafePath: () => resolveSafePath,
12
+ sanitizeFilename: () => sanitizeFilename
10
13
  });
11
14
  var Files = { DatabaseName: ".verdaccio-db.json" };
12
15
  /**
@@ -29,6 +32,61 @@ async function createTempStorageFolder(prefix, folder = "storage") {
29
32
  await mkdir(storageFolder);
30
33
  return storageFolder;
31
34
  }
35
+ /**
36
+ * Resolve a safe path within a base directory, preventing directory traversal attacks.
37
+ *
38
+ * This function provides security against path traversal by:
39
+ * - URL decoding the input path
40
+ * - Resolving the full absolute path
41
+ * - Checking that the resolved path stays within the base directory
42
+ * - Rejecting paths containing '..' that would escape the base directory
43
+ * - Rejecting absolute paths that bypass the base directory
44
+ *
45
+ * @param basePath The base directory that constrains file access
46
+ * @param requestPath The requested path from user input (may be URL-encoded)
47
+ * @returns The resolved safe absolute path or null if the path is unsafe/invalid
48
+ * @security Prevents directory traversal attacks by validating resolved paths
49
+ */
50
+ function resolveSafePath(basePath, requestPath) {
51
+ try {
52
+ if (!requestPath || requestPath === "") return null;
53
+ const decoded = decodeURIComponent(requestPath);
54
+ if (path.isAbsolute(decoded)) return null;
55
+ const baseResolved = path.resolve(basePath);
56
+ const reqResolved = path.resolve(baseResolved, decoded);
57
+ const baseComparable = process.platform === "win32" ? baseResolved.toLowerCase() : baseResolved;
58
+ const reqComparable = process.platform === "win32" ? reqResolved.toLowerCase() : reqResolved;
59
+ if (reqComparable !== baseComparable && !reqComparable.startsWith(baseComparable + path.sep)) return null;
60
+ return reqResolved;
61
+ } catch {
62
+ return null;
63
+ }
64
+ }
65
+ /**
66
+ * Sanitize a user-provided path while preserving directory separators.
67
+ *
68
+ * The web middleware uses this for `/-/assets/{*all}` which may include
69
+ * subfolders (e.g. `logos/verdaccio.svg`). We sanitize each path segment
70
+ * independently so `/` remains a real directory boundary.
71
+ *
72
+ * TODO: `sanitize-filename` silently rewrites segments instead of rejecting
73
+ * them (`file\0.txt` -> `file.txt`, `CON.svg` -> `.svg`, oversized segments
74
+ * truncated). Not exploitable today, but surprising; prefer 404 on destructive
75
+ * rewrite.
76
+ * TODO: `=== '..'` check is whitespace-strict — ` ..` / `.. ` slips past it.
77
+ * Use `path.normalize` before splitting, or `segment.trim() === '..'`.
78
+ * TODO: largely redundant with `resolveSafePath` on POSIX; the dep mainly earns
79
+ * its keep on Windows. Consider an inline `[<>:"|?*\0]` regex to drop the dep.
80
+ *
81
+ * @param filename The user-provided filename/path to sanitize.
82
+ * @returns The sanitized filename/path.
83
+ */
84
+ function sanitizeFilename(filename) {
85
+ return filename.replace(/\\/g, "/").split("/").map((segment) => {
86
+ if (segment === "." || segment === "..") return segment;
87
+ return sanitize(segment);
88
+ }).join("/");
89
+ }
32
90
  //#endregion
33
91
  export { file_utils_exports };
34
92
 
@@ -1 +1 @@
1
- {"version":3,"file":"file-utils.mjs","names":[],"sources":["../src/file-utils.ts"],"sourcesContent":["import { mkdir, mkdtemp } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\nexport const Files = {\n DatabaseName: '.verdaccio-db.json',\n};\n\n/**\n * Create a temporary folder.\n * @param prefix The prefix of the folder name.\n * @returns string\n */\nexport async function createTempFolder(prefix: string): Promise<string> {\n return await mkdtemp(path.join(os.tmpdir(), 'verdaccio-' + prefix + '-'));\n}\n\n/**\n * Create temporary folder for an asset.\n * @param prefix\n * @param folder name\n * @returns\n */\nexport async function createTempStorageFolder(prefix: string, folder = 'storage'): Promise<string> {\n const tempFolder = await createTempFolder(prefix);\n const storageFolder = path.join(tempFolder, folder);\n await mkdir(storageFolder);\n return storageFolder;\n}\n"],"mappings":";;;;;;;;;;AAIA,IAAa,QAAQ,EACnB,cAAc,sBACf;;;;;;AAOD,eAAsB,iBAAiB,QAAiC;AACtE,QAAO,MAAM,QAAQ,KAAK,KAAK,GAAG,QAAQ,EAAE,eAAe,SAAS,IAAI,CAAC;;;;;;;;AAS3E,eAAsB,wBAAwB,QAAgB,SAAS,WAA4B;CACjG,MAAM,aAAa,MAAM,iBAAiB,OAAO;CACjD,MAAM,gBAAgB,KAAK,KAAK,YAAY,OAAO;AACnD,OAAM,MAAM,cAAc;AAC1B,QAAO"}
1
+ {"version":3,"file":"file-utils.mjs","names":[],"sources":["../src/file-utils.ts"],"sourcesContent":["import { mkdir, mkdtemp } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\nimport sanitize from 'sanitize-filename';\n\nexport const Files = {\n DatabaseName: '.verdaccio-db.json',\n};\n\n/**\n * Create a temporary folder.\n * @param prefix The prefix of the folder name.\n * @returns string\n */\nexport async function createTempFolder(prefix: string): Promise<string> {\n return await mkdtemp(path.join(os.tmpdir(), 'verdaccio-' + prefix + '-'));\n}\n\n/**\n * Create temporary folder for an asset.\n * @param prefix\n * @param folder name\n * @returns\n */\nexport async function createTempStorageFolder(prefix: string, folder = 'storage'): Promise<string> {\n const tempFolder = await createTempFolder(prefix);\n const storageFolder = path.join(tempFolder, folder);\n await mkdir(storageFolder);\n return storageFolder;\n}\n\n/**\n * Resolve a safe path within a base directory, preventing directory traversal attacks.\n *\n * This function provides security against path traversal by:\n * - URL decoding the input path\n * - Resolving the full absolute path\n * - Checking that the resolved path stays within the base directory\n * - Rejecting paths containing '..' that would escape the base directory\n * - Rejecting absolute paths that bypass the base directory\n *\n * @param basePath The base directory that constrains file access\n * @param requestPath The requested path from user input (may be URL-encoded)\n * @returns The resolved safe absolute path or null if the path is unsafe/invalid\n * @security Prevents directory traversal attacks by validating resolved paths\n */\nexport function resolveSafePath(basePath: string, requestPath?: string): string | null {\n try {\n if (!requestPath || requestPath === '') {\n return null;\n }\n\n const decoded = decodeURIComponent(requestPath);\n // Prevent absolute paths (should not start from '/')\n if (path.isAbsolute(decoded)) {\n return null;\n }\n\n // Resolve against the base directory without requiring the target to exist.\n const baseResolved = path.resolve(basePath);\n const reqResolved = path.resolve(baseResolved, decoded);\n\n // Normalize for Windows case-insensitive filesystem comparisons.\n const baseComparable = process.platform === 'win32' ? baseResolved.toLowerCase() : baseResolved;\n const reqComparable = process.platform === 'win32' ? reqResolved.toLowerCase() : reqResolved;\n\n // Ensure the resolved path is within basePath (subdirectory or exactly the base).\n if (reqComparable !== baseComparable && !reqComparable.startsWith(baseComparable + path.sep)) {\n return null;\n }\n\n return reqResolved;\n } catch {\n // error resolving path (e.g., path does not exist or permission denied)\n return null;\n }\n}\n\n/**\n * Sanitize a user-provided path while preserving directory separators.\n *\n * The web middleware uses this for `/-/assets/{*all}` which may include\n * subfolders (e.g. `logos/verdaccio.svg`). We sanitize each path segment\n * independently so `/` remains a real directory boundary.\n *\n * TODO: `sanitize-filename` silently rewrites segments instead of rejecting\n * them (`file\\0.txt` -> `file.txt`, `CON.svg` -> `.svg`, oversized segments\n * truncated). Not exploitable today, but surprising; prefer 404 on destructive\n * rewrite.\n * TODO: `=== '..'` check is whitespace-strict — ` ..` / `.. ` slips past it.\n * Use `path.normalize` before splitting, or `segment.trim() === '..'`.\n * TODO: largely redundant with `resolveSafePath` on POSIX; the dep mainly earns\n * its keep on Windows. Consider an inline `[<>:\"|?*\\0]` regex to drop the dep.\n *\n * @param filename The user-provided filename/path to sanitize.\n * @returns The sanitized filename/path.\n */\nexport function sanitizeFilename(filename: string): string {\n // normalize windows path separator so the result is stable across platforms\n const normalized = filename.replace(/\\\\/g, '/');\n const segments = normalized.split('/').map((segment) => {\n // Keep traversal markers intact so `resolveSafePath()` can correctly\n // reject paths escaping the base directory.\n if (segment === '.' || segment === '..') {\n return segment;\n }\n return sanitize(segment);\n });\n return segments.join('/');\n}\n"],"mappings":";;;;;;;;;;;;;AAKA,IAAa,QAAQ,EACnB,cAAc,sBACf;;;;;;AAOD,eAAsB,iBAAiB,QAAiC;AACtE,QAAO,MAAM,QAAQ,KAAK,KAAK,GAAG,QAAQ,EAAE,eAAe,SAAS,IAAI,CAAC;;;;;;;;AAS3E,eAAsB,wBAAwB,QAAgB,SAAS,WAA4B;CACjG,MAAM,aAAa,MAAM,iBAAiB,OAAO;CACjD,MAAM,gBAAgB,KAAK,KAAK,YAAY,OAAO;AACnD,OAAM,MAAM,cAAc;AAC1B,QAAO;;;;;;;;;;;;;;;;;AAkBT,SAAgB,gBAAgB,UAAkB,aAAqC;AACrF,KAAI;AACF,MAAI,CAAC,eAAe,gBAAgB,GAClC,QAAO;EAGT,MAAM,UAAU,mBAAmB,YAAY;AAE/C,MAAI,KAAK,WAAW,QAAQ,CAC1B,QAAO;EAIT,MAAM,eAAe,KAAK,QAAQ,SAAS;EAC3C,MAAM,cAAc,KAAK,QAAQ,cAAc,QAAQ;EAGvD,MAAM,iBAAiB,QAAQ,aAAa,UAAU,aAAa,aAAa,GAAG;EACnF,MAAM,gBAAgB,QAAQ,aAAa,UAAU,YAAY,aAAa,GAAG;AAGjF,MAAI,kBAAkB,kBAAkB,CAAC,cAAc,WAAW,iBAAiB,KAAK,IAAI,CAC1F,QAAO;AAGT,SAAO;SACD;AAEN,SAAO;;;;;;;;;;;;;;;;;;;;;;AAuBX,SAAgB,iBAAiB,UAA0B;AAWzD,QATmB,SAAS,QAAQ,OAAO,IAAI,CACnB,MAAM,IAAI,CAAC,KAAK,YAAY;AAGtD,MAAI,YAAY,OAAO,YAAY,KACjC,QAAO;AAET,SAAO,SAAS,QAAQ;GACxB,CACc,KAAK,IAAI"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdaccio/core",
3
- "version": "9.0.0-next-9.15",
3
+ "version": "9.0.0-next-9.16",
4
4
  "description": "Verdaccio Core Components",
5
5
  "keywords": [
6
6
  "private",
@@ -38,10 +38,11 @@
38
38
  "http-status-codes": "2.3.0",
39
39
  "minimatch": "9.0.7",
40
40
  "process-warning": "5.0.0",
41
+ "sanitize-filename": "1.6.3",
41
42
  "semver": "7.7.4"
42
43
  },
43
44
  "devDependencies": {
44
- "@verdaccio/types": "14.0.0-next-9.6",
45
+ "@verdaccio/types": "14.0.0-next-9.7",
45
46
  "express": "5.2.1",
46
47
  "typedoc": "0.28.14",
47
48
  "vitest": "4.1.0"