@verdaccio/core 9.0.0-next-9.25 → 9.0.0-next-9.27
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/build/_virtual/_rolldown/runtime.js +1 -1
- package/build/auth-utils.js +1 -1
- package/build/auth-utils.js.map +1 -1
- package/build/auth-utils.mjs +1 -1
- package/build/auth-utils.mjs.map +1 -1
- package/build/crypto-utils.js.map +1 -1
- package/build/error-utils.js.map +1 -1
- package/build/file-utils.js.map +1 -1
- package/package.json +2 -2
|
@@ -24,7 +24,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
24
24
|
}
|
|
25
25
|
return to;
|
|
26
26
|
};
|
|
27
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
27
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
28
28
|
value: mod,
|
|
29
29
|
enumerable: true
|
|
30
30
|
}) : target, mod));
|
package/build/auth-utils.js
CHANGED
|
@@ -9,7 +9,7 @@ var auth_utils_exports = /* @__PURE__ */ require_runtime.__exportAll({
|
|
|
9
9
|
getMatchedPackagesSpec: () => getMatchedPackagesSpec
|
|
10
10
|
});
|
|
11
11
|
function createSessionToken() {
|
|
12
|
-
return { expires: new Date(Date.now() +
|
|
12
|
+
return { expires: new Date(Date.now() + 36e6) };
|
|
13
13
|
}
|
|
14
14
|
function getAuthenticatedMessage(user) {
|
|
15
15
|
return `you are authenticated as '${user}'`;
|
package/build/auth-utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-utils.js","names":[],"sources":["../src/auth-utils.ts"],"sourcesContent":["import type { MMRegExp } from 'minimatch';\nimport { minimatch } from 'minimatch';\n\nimport type { PackageAccess, PackageList } from '@verdaccio/types';\n\nexport interface CookieSessionToken {\n expires: Date;\n}\n\nexport function createSessionToken(): CookieSessionToken {\n const tenHoursTime = 10 * 60 * 60 * 1000;\n\n return {\n // npmjs.org sets 10h expire\n expires: new Date(Date.now() + tenHoursTime),\n };\n}\n\nexport function getAuthenticatedMessage(user: string): string {\n return `you are authenticated as '${user}'`;\n}\n\nexport function buildUserBuffer(name: string, password: string): Buffer {\n return Buffer.from(`${name}:${password}`, 'utf8');\n}\n\nexport function buildToken(type: string, token: string): string {\n return `${capitalize(type)} ${token}`;\n}\n\nexport function getMatchedPackagesSpec(\n pkgName: string,\n packages: PackageList\n): PackageAccess | void {\n for (const i in packages) {\n // match case-insensitively, npm package names are case-insensitive\n if ((minimatch.makeRe(i, { nocase: true }) as MMRegExp).exec(pkgName)) {\n return packages[i];\n }\n }\n return;\n}\n\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();\n}\n"],"mappings":";;;;;;;;;;AASA,SAAgB,qBAAyC;CAGvD,OAAO,EAEL,SAAS,IAAI,KAAK,KAAK,IAAI,
|
|
1
|
+
{"version":3,"file":"auth-utils.js","names":[],"sources":["../src/auth-utils.ts"],"sourcesContent":["import type { MMRegExp } from 'minimatch';\nimport { minimatch } from 'minimatch';\n\nimport type { PackageAccess, PackageList } from '@verdaccio/types';\n\nexport interface CookieSessionToken {\n expires: Date;\n}\n\nexport function createSessionToken(): CookieSessionToken {\n const tenHoursTime = 10 * 60 * 60 * 1000;\n\n return {\n // npmjs.org sets 10h expire\n expires: new Date(Date.now() + tenHoursTime),\n };\n}\n\nexport function getAuthenticatedMessage(user: string): string {\n return `you are authenticated as '${user}'`;\n}\n\nexport function buildUserBuffer(name: string, password: string): Buffer {\n return Buffer.from(`${name}:${password}`, 'utf8');\n}\n\nexport function buildToken(type: string, token: string): string {\n return `${capitalize(type)} ${token}`;\n}\n\nexport function getMatchedPackagesSpec(\n pkgName: string,\n packages: PackageList\n): PackageAccess | void {\n for (const i in packages) {\n // match case-insensitively, npm package names are case-insensitive\n if ((minimatch.makeRe(i, { nocase: true }) as MMRegExp).exec(pkgName)) {\n return packages[i];\n }\n }\n return;\n}\n\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();\n}\n"],"mappings":";;;;;;;;;;AASA,SAAgB,qBAAyC;CAGvD,OAAO,EAEL,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,IAAY,EAC7C;AACF;AAEA,SAAgB,wBAAwB,MAAsB;CAC5D,OAAO,6BAA6B,KAAK;AAC3C;AAEA,SAAgB,gBAAgB,MAAc,UAA0B;CACtE,OAAO,OAAO,KAAK,GAAG,KAAK,GAAG,YAAY,MAAM;AAClD;AAEA,SAAgB,WAAW,MAAc,OAAuB;CAC9D,OAAO,GAAG,WAAW,IAAI,EAAE,GAAG;AAChC;AAEA,SAAgB,uBACd,SACA,UACsB;CACtB,KAAK,MAAM,KAAK,UAEd,IAAK,UAAA,UAAU,OAAO,GAAG,EAAE,QAAQ,KAAK,CAAC,CAAC,CAAc,KAAK,OAAO,GAClE,OAAO,SAAS;AAItB;AAEA,SAAS,WAAW,KAAqB;CACvC,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,YAAY;AAChE"}
|
package/build/auth-utils.mjs
CHANGED
|
@@ -9,7 +9,7 @@ var auth_utils_exports = /* @__PURE__ */ __exportAll({
|
|
|
9
9
|
getMatchedPackagesSpec: () => getMatchedPackagesSpec
|
|
10
10
|
});
|
|
11
11
|
function createSessionToken() {
|
|
12
|
-
return { expires: new Date(Date.now() +
|
|
12
|
+
return { expires: new Date(Date.now() + 36e6) };
|
|
13
13
|
}
|
|
14
14
|
function getAuthenticatedMessage(user) {
|
|
15
15
|
return `you are authenticated as '${user}'`;
|
package/build/auth-utils.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-utils.mjs","names":[],"sources":["../src/auth-utils.ts"],"sourcesContent":["import type { MMRegExp } from 'minimatch';\nimport { minimatch } from 'minimatch';\n\nimport type { PackageAccess, PackageList } from '@verdaccio/types';\n\nexport interface CookieSessionToken {\n expires: Date;\n}\n\nexport function createSessionToken(): CookieSessionToken {\n const tenHoursTime = 10 * 60 * 60 * 1000;\n\n return {\n // npmjs.org sets 10h expire\n expires: new Date(Date.now() + tenHoursTime),\n };\n}\n\nexport function getAuthenticatedMessage(user: string): string {\n return `you are authenticated as '${user}'`;\n}\n\nexport function buildUserBuffer(name: string, password: string): Buffer {\n return Buffer.from(`${name}:${password}`, 'utf8');\n}\n\nexport function buildToken(type: string, token: string): string {\n return `${capitalize(type)} ${token}`;\n}\n\nexport function getMatchedPackagesSpec(\n pkgName: string,\n packages: PackageList\n): PackageAccess | void {\n for (const i in packages) {\n // match case-insensitively, npm package names are case-insensitive\n if ((minimatch.makeRe(i, { nocase: true }) as MMRegExp).exec(pkgName)) {\n return packages[i];\n }\n }\n return;\n}\n\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();\n}\n"],"mappings":";;;;;;;;;;AASA,SAAgB,qBAAyC;CAGvD,OAAO,EAEL,SAAS,IAAI,KAAK,KAAK,IAAI,
|
|
1
|
+
{"version":3,"file":"auth-utils.mjs","names":[],"sources":["../src/auth-utils.ts"],"sourcesContent":["import type { MMRegExp } from 'minimatch';\nimport { minimatch } from 'minimatch';\n\nimport type { PackageAccess, PackageList } from '@verdaccio/types';\n\nexport interface CookieSessionToken {\n expires: Date;\n}\n\nexport function createSessionToken(): CookieSessionToken {\n const tenHoursTime = 10 * 60 * 60 * 1000;\n\n return {\n // npmjs.org sets 10h expire\n expires: new Date(Date.now() + tenHoursTime),\n };\n}\n\nexport function getAuthenticatedMessage(user: string): string {\n return `you are authenticated as '${user}'`;\n}\n\nexport function buildUserBuffer(name: string, password: string): Buffer {\n return Buffer.from(`${name}:${password}`, 'utf8');\n}\n\nexport function buildToken(type: string, token: string): string {\n return `${capitalize(type)} ${token}`;\n}\n\nexport function getMatchedPackagesSpec(\n pkgName: string,\n packages: PackageList\n): PackageAccess | void {\n for (const i in packages) {\n // match case-insensitively, npm package names are case-insensitive\n if ((minimatch.makeRe(i, { nocase: true }) as MMRegExp).exec(pkgName)) {\n return packages[i];\n }\n }\n return;\n}\n\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();\n}\n"],"mappings":";;;;;;;;;;AASA,SAAgB,qBAAyC;CAGvD,OAAO,EAEL,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,IAAY,EAC7C;AACF;AAEA,SAAgB,wBAAwB,MAAsB;CAC5D,OAAO,6BAA6B,KAAK;AAC3C;AAEA,SAAgB,gBAAgB,MAAc,UAA0B;CACtE,OAAO,OAAO,KAAK,GAAG,KAAK,GAAG,YAAY,MAAM;AAClD;AAEA,SAAgB,WAAW,MAAc,OAAuB;CAC9D,OAAO,GAAG,WAAW,IAAI,EAAE,GAAG;AAChC;AAEA,SAAgB,uBACd,SACA,UACsB;CACtB,KAAK,MAAM,KAAK,UAEd,IAAK,UAAU,OAAO,GAAG,EAAE,QAAQ,KAAK,CAAC,CAAC,CAAc,KAAK,OAAO,GAClE,OAAO,SAAS;AAItB;AAEA,SAAS,WAAW,KAAqB;CACvC,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,YAAY;AAChE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto-utils.js","names":[],"sources":["../src/crypto-utils.ts"],"sourcesContent":["import type { Hash } from 'node:crypto';\nimport { createHash, randomBytes } from 'node:crypto';\n\nexport const defaultTarballHashAlgorithm = 'sha1';\n\nexport function createTarballHash(): Hash {\n return createHash(defaultTarballHashAlgorithm);\n}\n\n/**\n * Express doesn't do ETAGS with requests <= 1024b\n * we use md5 here, it works well on 1k+ bytes, but sucks with fewer data\n * could improve performance using crc32 after benchmarks.\n * @param {Object} data\n * @return {String}\n */\nexport function stringToMD5(data: Buffer | string): string {\n // @ts-ignore update method accepts Buffer or string\n return createHash('md5').update(data).digest('hex');\n}\n\nexport function generateRandomHexString(length = 8): string {\n return randomBytes(length).toString('hex');\n}\n\n/**\n * return a masquerade string with its first and last {charNum} and three dots in between.\n * @param {String} str\n * @param {Number} charNum\n * @returns {String}\n */\nexport function mask(str: string, charNum = 3): string {\n return `${str.slice(0, charNum)}...${str.slice(-charNum)}`;\n}\n"],"mappings":";;;;;;;;;;AAGA,IAAa,8BAA8B;AAE3C,SAAgB,oBAA0B;CACxC,QAAA,
|
|
1
|
+
{"version":3,"file":"crypto-utils.js","names":[],"sources":["../src/crypto-utils.ts"],"sourcesContent":["import type { Hash } from 'node:crypto';\nimport { createHash, randomBytes } from 'node:crypto';\n\nexport const defaultTarballHashAlgorithm = 'sha1';\n\nexport function createTarballHash(): Hash {\n return createHash(defaultTarballHashAlgorithm);\n}\n\n/**\n * Express doesn't do ETAGS with requests <= 1024b\n * we use md5 here, it works well on 1k+ bytes, but sucks with fewer data\n * could improve performance using crc32 after benchmarks.\n * @param {Object} data\n * @return {String}\n */\nexport function stringToMD5(data: Buffer | string): string {\n // @ts-ignore update method accepts Buffer or string\n return createHash('md5').update(data).digest('hex');\n}\n\nexport function generateRandomHexString(length = 8): string {\n return randomBytes(length).toString('hex');\n}\n\n/**\n * return a masquerade string with its first and last {charNum} and three dots in between.\n * @param {String} str\n * @param {Number} charNum\n * @returns {String}\n */\nexport function mask(str: string, charNum = 3): string {\n return `${str.slice(0, charNum)}...${str.slice(-charNum)}`;\n}\n"],"mappings":";;;;;;;;;;AAGA,IAAa,8BAA8B;AAE3C,SAAgB,oBAA0B;CACxC,QAAA,GAAO,YAAA,WAAA,CAAW,2BAA2B;AAC/C;;;;;;;;AASA,SAAgB,YAAY,MAA+B;CAEzD,QAAA,GAAO,YAAA,WAAA,CAAW,KAAK,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK;AACpD;AAEA,SAAgB,wBAAwB,SAAS,GAAW;CAC1D,QAAA,GAAO,YAAA,YAAA,CAAY,MAAM,CAAC,CAAC,SAAS,KAAK;AAC3C;;;;;;;AAQA,SAAgB,KAAK,KAAa,UAAU,GAAW;CACrD,OAAO,GAAG,IAAI,MAAM,GAAG,OAAO,EAAE,KAAK,IAAI,MAAM,CAAC,OAAO;AACzD"}
|
package/build/error-utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-utils.js","names":[],"sources":["../src/error-utils.ts"],"sourcesContent":["import type { HttpError } from 'http-errors';\nimport createError from 'http-errors';\n\nimport { HTTP_STATUS } from './constants';\n\nexport const API_ERROR = {\n PASSWORD_SHORT: 'The provided password does not pass the validation',\n MUST_BE_LOGGED: 'You must be logged in to publish packages.',\n PLUGIN_ERROR: 'bug in the auth plugin system',\n CONFIG_BAD_FORMAT: 'config file must be an object',\n BAD_USERNAME_PASSWORD: 'bad username/password, access denied',\n NO_PACKAGE: 'no such package available',\n PACKAGE_CANNOT_BE_ADDED: 'this package cannot be added',\n BAD_DATA: 'bad data',\n NOT_ALLOWED: 'not allowed to access package',\n NOT_ALLOWED_PUBLISH: 'not allowed to publish package',\n INTERNAL_SERVER_ERROR: 'internal server error',\n UNKNOWN_ERROR: 'unknown error',\n NOT_PACKAGE_UPLINK: 'package does not exist on uplink',\n UPLINK_OFFLINE_PUBLISH: 'one of the uplinks is down, refuse to publish',\n UPLINK_OFFLINE: 'uplink is offline',\n NOT_MODIFIED_NO_DATA: 'no data',\n CONTENT_MISMATCH: 'content length mismatch',\n NOT_FILE_UPLINK: \"file doesn't exist on uplink\",\n MAX_USERS_REACHED: 'maximum amount of users reached',\n VERSION_NOT_EXIST: \"this version doesn't exist\",\n NO_SUCH_FILE: 'no such file available',\n UNSUPORTED_REGISTRY_CALL: 'unsupported registry call',\n FILE_NOT_FOUND: 'File not found',\n REGISTRATION_DISABLED: 'user registration disabled',\n UNAUTHORIZED_ACCESS: 'unauthorized access',\n BAD_STATUS_CODE: 'bad status code',\n SERVER_TIME_OUT: 'looks like the server is taking to long to respond',\n PACKAGE_EXIST: 'this package is already present',\n BAD_AUTH_HEADER: 'bad authorization header',\n WEB_DISABLED: 'Web interface is disabled in the config file',\n DEPRECATED_BASIC_HEADER: 'basic authentication is deprecated, please use JWT instead',\n BAD_FORMAT_USER_GROUP: 'user groups is different than an array',\n RESOURCE_UNAVAILABLE: 'resource unavailable',\n BAD_PACKAGE_DATA: 'bad incoming package data',\n USERNAME_PASSWORD_REQUIRED: 'username and password is required',\n USERNAME_ALREADY_REGISTERED: 'username is already registered',\n USERNAME_MISMATCH: 'username does not match logged in user',\n SESSION_ID_REQUIRED: 'session id is required',\n SESSION_ID_INVALID: 'session id is invalid',\n SESSION_TOKEN_EXPIRED: 'session token expired',\n};\n\nexport const SUPPORT_ERRORS = {\n PLUGIN_MISSING_INTERFACE: 'the plugin does not provide implementation of the requested feature',\n TFA_DISABLED: 'the two-factor authentication is not yet supported',\n STORAGE_NOT_IMPLEMENT: 'the storage does not support token saving',\n PARAMETERS_NOT_VALID: 'the parameters are not valid',\n};\n\nexport const APP_ERROR = {\n CONFIG_NOT_VALID: 'CONFIG: it does not look like a valid config file',\n PROFILE_ERROR: 'profile unexpected error',\n PASSWORD_VALIDATION: 'not valid password',\n};\n\nexport type VerdaccioError = HttpError & { code: number };\n\nfunction getError(code: number, message: string): VerdaccioError {\n const httpError = createError(code, message);\n\n httpError.code = code;\n\n return httpError as VerdaccioError;\n}\n\nexport function getConflict(message: string = API_ERROR.PACKAGE_EXIST): VerdaccioError {\n return getError(HTTP_STATUS.CONFLICT, message);\n}\n\nexport function getBadData(customMessage?: string): VerdaccioError {\n return getError(HTTP_STATUS.BAD_DATA, customMessage || API_ERROR.BAD_DATA);\n}\n\nexport function getBadRequest(customMessage: string): VerdaccioError {\n return getError(HTTP_STATUS.BAD_REQUEST, customMessage);\n}\n\nexport function getInternalError(customMessage?: string): VerdaccioError {\n return customMessage\n ? getError(HTTP_STATUS.INTERNAL_ERROR, customMessage)\n : getError(HTTP_STATUS.INTERNAL_ERROR, API_ERROR.UNKNOWN_ERROR);\n}\n\nexport function getUnauthorized(message = 'no credentials provided'): VerdaccioError {\n return getError(HTTP_STATUS.UNAUTHORIZED, message);\n}\n\nexport function getForbidden(message = \"can't use this filename\"): VerdaccioError {\n return getError(HTTP_STATUS.FORBIDDEN, message);\n}\n\nexport function getServiceUnavailable(\n message: string = API_ERROR.RESOURCE_UNAVAILABLE\n): VerdaccioError {\n return getError(HTTP_STATUS.SERVICE_UNAVAILABLE, message);\n}\n\nexport function getNotFound(customMessage?: string): VerdaccioError {\n return getError(HTTP_STATUS.NOT_FOUND, customMessage || API_ERROR.NO_PACKAGE);\n}\n\nexport function getCode(statusCode: number, customMessage: string): VerdaccioError {\n return getError(statusCode, customMessage);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAKA,IAAa,YAAY;CACvB,gBAAgB;CAChB,gBAAgB;CAChB,cAAc;CACd,mBAAmB;CACnB,uBAAuB;CACvB,YAAY;CACZ,yBAAyB;CACzB,UAAU;CACV,aAAa;CACb,qBAAqB;CACrB,uBAAuB;CACvB,eAAe;CACf,oBAAoB;CACpB,wBAAwB;CACxB,gBAAgB;CAChB,sBAAsB;CACtB,kBAAkB;CAClB,iBAAiB;CACjB,mBAAmB;CACnB,mBAAmB;CACnB,cAAc;CACd,0BAA0B;CAC1B,gBAAgB;CAChB,uBAAuB;CACvB,qBAAqB;CACrB,iBAAiB;CACjB,iBAAiB;CACjB,eAAe;CACf,iBAAiB;CACjB,cAAc;CACd,yBAAyB;CACzB,uBAAuB;CACvB,sBAAsB;CACtB,kBAAkB;CAClB,4BAA4B;CAC5B,6BAA6B;CAC7B,mBAAmB;CACnB,qBAAqB;CACrB,oBAAoB;CACpB,uBAAuB;AACzB;AAEA,IAAa,iBAAiB;CAC5B,0BAA0B;CAC1B,cAAc;CACd,uBAAuB;CACvB,sBAAsB;AACxB;AAEA,IAAa,YAAY;CACvB,kBAAkB;CAClB,eAAe;CACf,qBAAqB;AACvB;AAIA,SAAS,SAAS,MAAc,SAAiC;CAC/D,MAAM,aAAA,
|
|
1
|
+
{"version":3,"file":"error-utils.js","names":[],"sources":["../src/error-utils.ts"],"sourcesContent":["import type { HttpError } from 'http-errors';\nimport createError from 'http-errors';\n\nimport { HTTP_STATUS } from './constants';\n\nexport const API_ERROR = {\n PASSWORD_SHORT: 'The provided password does not pass the validation',\n MUST_BE_LOGGED: 'You must be logged in to publish packages.',\n PLUGIN_ERROR: 'bug in the auth plugin system',\n CONFIG_BAD_FORMAT: 'config file must be an object',\n BAD_USERNAME_PASSWORD: 'bad username/password, access denied',\n NO_PACKAGE: 'no such package available',\n PACKAGE_CANNOT_BE_ADDED: 'this package cannot be added',\n BAD_DATA: 'bad data',\n NOT_ALLOWED: 'not allowed to access package',\n NOT_ALLOWED_PUBLISH: 'not allowed to publish package',\n INTERNAL_SERVER_ERROR: 'internal server error',\n UNKNOWN_ERROR: 'unknown error',\n NOT_PACKAGE_UPLINK: 'package does not exist on uplink',\n UPLINK_OFFLINE_PUBLISH: 'one of the uplinks is down, refuse to publish',\n UPLINK_OFFLINE: 'uplink is offline',\n NOT_MODIFIED_NO_DATA: 'no data',\n CONTENT_MISMATCH: 'content length mismatch',\n NOT_FILE_UPLINK: \"file doesn't exist on uplink\",\n MAX_USERS_REACHED: 'maximum amount of users reached',\n VERSION_NOT_EXIST: \"this version doesn't exist\",\n NO_SUCH_FILE: 'no such file available',\n UNSUPORTED_REGISTRY_CALL: 'unsupported registry call',\n FILE_NOT_FOUND: 'File not found',\n REGISTRATION_DISABLED: 'user registration disabled',\n UNAUTHORIZED_ACCESS: 'unauthorized access',\n BAD_STATUS_CODE: 'bad status code',\n SERVER_TIME_OUT: 'looks like the server is taking to long to respond',\n PACKAGE_EXIST: 'this package is already present',\n BAD_AUTH_HEADER: 'bad authorization header',\n WEB_DISABLED: 'Web interface is disabled in the config file',\n DEPRECATED_BASIC_HEADER: 'basic authentication is deprecated, please use JWT instead',\n BAD_FORMAT_USER_GROUP: 'user groups is different than an array',\n RESOURCE_UNAVAILABLE: 'resource unavailable',\n BAD_PACKAGE_DATA: 'bad incoming package data',\n USERNAME_PASSWORD_REQUIRED: 'username and password is required',\n USERNAME_ALREADY_REGISTERED: 'username is already registered',\n USERNAME_MISMATCH: 'username does not match logged in user',\n SESSION_ID_REQUIRED: 'session id is required',\n SESSION_ID_INVALID: 'session id is invalid',\n SESSION_TOKEN_EXPIRED: 'session token expired',\n};\n\nexport const SUPPORT_ERRORS = {\n PLUGIN_MISSING_INTERFACE: 'the plugin does not provide implementation of the requested feature',\n TFA_DISABLED: 'the two-factor authentication is not yet supported',\n STORAGE_NOT_IMPLEMENT: 'the storage does not support token saving',\n PARAMETERS_NOT_VALID: 'the parameters are not valid',\n};\n\nexport const APP_ERROR = {\n CONFIG_NOT_VALID: 'CONFIG: it does not look like a valid config file',\n PROFILE_ERROR: 'profile unexpected error',\n PASSWORD_VALIDATION: 'not valid password',\n};\n\nexport type VerdaccioError = HttpError & { code: number };\n\nfunction getError(code: number, message: string): VerdaccioError {\n const httpError = createError(code, message);\n\n httpError.code = code;\n\n return httpError as VerdaccioError;\n}\n\nexport function getConflict(message: string = API_ERROR.PACKAGE_EXIST): VerdaccioError {\n return getError(HTTP_STATUS.CONFLICT, message);\n}\n\nexport function getBadData(customMessage?: string): VerdaccioError {\n return getError(HTTP_STATUS.BAD_DATA, customMessage || API_ERROR.BAD_DATA);\n}\n\nexport function getBadRequest(customMessage: string): VerdaccioError {\n return getError(HTTP_STATUS.BAD_REQUEST, customMessage);\n}\n\nexport function getInternalError(customMessage?: string): VerdaccioError {\n return customMessage\n ? getError(HTTP_STATUS.INTERNAL_ERROR, customMessage)\n : getError(HTTP_STATUS.INTERNAL_ERROR, API_ERROR.UNKNOWN_ERROR);\n}\n\nexport function getUnauthorized(message = 'no credentials provided'): VerdaccioError {\n return getError(HTTP_STATUS.UNAUTHORIZED, message);\n}\n\nexport function getForbidden(message = \"can't use this filename\"): VerdaccioError {\n return getError(HTTP_STATUS.FORBIDDEN, message);\n}\n\nexport function getServiceUnavailable(\n message: string = API_ERROR.RESOURCE_UNAVAILABLE\n): VerdaccioError {\n return getError(HTTP_STATUS.SERVICE_UNAVAILABLE, message);\n}\n\nexport function getNotFound(customMessage?: string): VerdaccioError {\n return getError(HTTP_STATUS.NOT_FOUND, customMessage || API_ERROR.NO_PACKAGE);\n}\n\nexport function getCode(statusCode: number, customMessage: string): VerdaccioError {\n return getError(statusCode, customMessage);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAKA,IAAa,YAAY;CACvB,gBAAgB;CAChB,gBAAgB;CAChB,cAAc;CACd,mBAAmB;CACnB,uBAAuB;CACvB,YAAY;CACZ,yBAAyB;CACzB,UAAU;CACV,aAAa;CACb,qBAAqB;CACrB,uBAAuB;CACvB,eAAe;CACf,oBAAoB;CACpB,wBAAwB;CACxB,gBAAgB;CAChB,sBAAsB;CACtB,kBAAkB;CAClB,iBAAiB;CACjB,mBAAmB;CACnB,mBAAmB;CACnB,cAAc;CACd,0BAA0B;CAC1B,gBAAgB;CAChB,uBAAuB;CACvB,qBAAqB;CACrB,iBAAiB;CACjB,iBAAiB;CACjB,eAAe;CACf,iBAAiB;CACjB,cAAc;CACd,yBAAyB;CACzB,uBAAuB;CACvB,sBAAsB;CACtB,kBAAkB;CAClB,4BAA4B;CAC5B,6BAA6B;CAC7B,mBAAmB;CACnB,qBAAqB;CACrB,oBAAoB;CACpB,uBAAuB;AACzB;AAEA,IAAa,iBAAiB;CAC5B,0BAA0B;CAC1B,cAAc;CACd,uBAAuB;CACvB,sBAAsB;AACxB;AAEA,IAAa,YAAY;CACvB,kBAAkB;CAClB,eAAe;CACf,qBAAqB;AACvB;AAIA,SAAS,SAAS,MAAc,SAAiC;CAC/D,MAAM,aAAA,GAAY,YAAA,QAAA,CAAY,MAAM,OAAO;CAE3C,UAAU,OAAO;CAEjB,OAAO;AACT;AAEA,SAAgB,YAAY,UAAkB,UAAU,eAA+B;CACrF,OAAO,SAAS,kBAAA,YAAY,UAAU,OAAO;AAC/C;AAEA,SAAgB,WAAW,eAAwC;CACjE,OAAO,SAAS,kBAAA,YAAY,UAAU,iBAAiB,UAAU,QAAQ;AAC3E;AAEA,SAAgB,cAAc,eAAuC;CACnE,OAAO,SAAS,kBAAA,YAAY,aAAa,aAAa;AACxD;AAEA,SAAgB,iBAAiB,eAAwC;CACvE,OAAO,gBACH,SAAS,kBAAA,YAAY,gBAAgB,aAAa,IAClD,SAAS,kBAAA,YAAY,gBAAgB,UAAU,aAAa;AAClE;AAEA,SAAgB,gBAAgB,UAAU,2BAA2C;CACnF,OAAO,SAAS,kBAAA,YAAY,cAAc,OAAO;AACnD;AAEA,SAAgB,aAAa,UAAU,2BAA2C;CAChF,OAAO,SAAS,kBAAA,YAAY,WAAW,OAAO;AAChD;AAEA,SAAgB,sBACd,UAAkB,UAAU,sBACZ;CAChB,OAAO,SAAS,kBAAA,YAAY,qBAAqB,OAAO;AAC1D;AAEA,SAAgB,YAAY,eAAwC;CAClE,OAAO,SAAS,kBAAA,YAAY,WAAW,iBAAiB,UAAU,UAAU;AAC9E;AAEA,SAAgB,QAAQ,YAAoB,eAAuC;CACjF,OAAO,SAAS,YAAY,aAAa;AAC3C"}
|
package/build/file-utils.js.map
CHANGED
|
@@ -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';\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,qBAChB;;;;;;AAOA,eAAsB,iBAAiB,QAAiC;CACtE,OAAO,OAAA,
|
|
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,qBAChB;;;;;;AAOA,eAAsB,iBAAiB,QAAiC;CACtE,OAAO,OAAA,GAAM,iBAAA,QAAA,CAAQ,UAAA,QAAK,KAAK,QAAA,QAAG,OAAO,GAAG,eAAe,SAAS,GAAG,CAAC;AAC1E;;;;;;;AAQA,eAAsB,wBAAwB,QAAgB,SAAS,WAA4B;CACjG,MAAM,aAAa,MAAM,iBAAiB,MAAM;CAChD,MAAM,gBAAgB,UAAA,QAAK,KAAK,YAAY,MAAM;CAClD,OAAA,GAAM,iBAAA,MAAA,CAAM,aAAa;CACzB,OAAO;AACT;;;;;;;;;;;;;;;;AAiBA,SAAgB,gBAAgB,UAAkB,aAAqC;CACrF,IAAI;EACF,IAAI,CAAC,eAAe,gBAAgB,IAClC,OAAO;EAGT,MAAM,UAAU,mBAAmB,WAAW;EAE9C,IAAI,UAAA,QAAK,WAAW,OAAO,GACzB,OAAO;EAIT,MAAM,eAAe,UAAA,QAAK,QAAQ,QAAQ;EAC1C,MAAM,cAAc,UAAA,QAAK,QAAQ,cAAc,OAAO;EAGtD,MAAM,iBAAiB,QAAQ,aAAa,UAAU,aAAa,YAAY,IAAI;EACnF,MAAM,gBAAgB,QAAQ,aAAa,UAAU,YAAY,YAAY,IAAI;EAGjF,IAAI,kBAAkB,kBAAkB,CAAC,cAAc,WAAW,iBAAiB,UAAA,QAAK,GAAG,GACzF,OAAO;EAGT,OAAO;CACT,QAAQ;EAEN,OAAO;CACT;AACF;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,iBAAiB,UAA0B;CAWzD,OATmB,SAAS,QAAQ,OAAO,GAC1B,CAAA,CAAW,MAAM,GAAG,CAAC,CAAC,KAAK,YAAY;EAGtD,IAAI,YAAY,OAAO,YAAY,MACjC,OAAO;EAET,QAAA,GAAO,kBAAA,QAAA,CAAS,OAAO;CACzB,CACO,CAAA,CAAS,KAAK,GAAG;AAC1B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/core",
|
|
3
|
-
"version": "9.0.0-next-9.
|
|
3
|
+
"version": "9.0.0-next-9.27",
|
|
4
4
|
"description": "Verdaccio Core Components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"private",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"express": "5.2.1",
|
|
47
47
|
"rimraf": "6.1.3",
|
|
48
48
|
"typedoc": "0.28.14",
|
|
49
|
-
"vite": "8.1
|
|
49
|
+
"vite": "8.2.1",
|
|
50
50
|
"vitest": "4.1.10"
|
|
51
51
|
},
|
|
52
52
|
"funding": {
|