Compare commits
12 Commits
@verdaccio
...
@verdaccio
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d220e5b54b | ||
|
|
f8a321f03e | ||
|
|
ac0fed3fa0 | ||
|
|
f6c06fc982 | ||
|
|
d92ba65866 | ||
|
|
6a4d6dddf7 | ||
|
|
73c0194091 | ||
|
|
8a2bb51ba3 | ||
|
|
a1a73e9172 | ||
|
|
6304965009 | ||
|
|
5fef0b629a | ||
|
|
08e1b2137e |
21
.changeset/bright-mugs-buy.md
Normal file
21
.changeset/bright-mugs-buy.md
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
'docusaurus-plugin-contributors': patch
|
||||
'generator-verdaccio-plugin': patch
|
||||
'@verdaccio/logger-prettify': patch
|
||||
'@verdaccio/local-scripts': patch
|
||||
'@verdaccio/file-locking': patch
|
||||
'@verdaccio/ui-theme': patch
|
||||
'@verdaccio/server-fastify': patch
|
||||
'@verdaccio/test-helper': patch
|
||||
'@verdaccio/middleware': patch
|
||||
'verdaccio': patch
|
||||
'@verdaccio/node-api': patch
|
||||
'@verdaccio/config': patch
|
||||
'@verdaccio/hooks': patch
|
||||
'@verdaccio/proxy': patch
|
||||
'@verdaccio/store': patch
|
||||
'@verdaccio/auth': patch
|
||||
'@verdaccio/api': patch
|
||||
---
|
||||
|
||||
chore(deps): built-in node imports
|
||||
7
.changeset/cuddly-paws-laugh.md
Normal file
7
.changeset/cuddly-paws-laugh.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@verdaccio/config': patch
|
||||
'@verdaccio/logger-commons': patch
|
||||
'@verdaccio/types': patch
|
||||
---
|
||||
|
||||
feat(logger): support redacting sensitive data
|
||||
7
.changeset/gold-parents-shave.md
Normal file
7
.changeset/gold-parents-shave.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@verdaccio/core': minor
|
||||
'@verdaccio/node-api': minor
|
||||
'@verdaccio/config': minor
|
||||
---
|
||||
|
||||
feat: getListenAddress getConfigParsed methods
|
||||
@@ -74,6 +74,7 @@
|
||||
"breezy-geckos-search",
|
||||
"breezy-toys-judge",
|
||||
"bright-bobcats-ring",
|
||||
"bright-mugs-buy",
|
||||
"brown-lions-talk",
|
||||
"brown-planets-approve",
|
||||
"calm-mangos-compare",
|
||||
@@ -84,6 +85,7 @@
|
||||
"clever-bees-happen",
|
||||
"cool-balloons-search",
|
||||
"cool-seals-watch",
|
||||
"cuddly-paws-laugh",
|
||||
"curly-mirrors-smile",
|
||||
"curvy-rockets-camp",
|
||||
"cyan-snakes-kiss",
|
||||
@@ -106,6 +108,7 @@
|
||||
"fuzzy-ears-yawn",
|
||||
"gentle-stingrays-repeat",
|
||||
"gold-files-speak",
|
||||
"gold-parents-shave",
|
||||
"gold-squids-watch",
|
||||
"great-candles-hang",
|
||||
"green-eagles-boil",
|
||||
@@ -138,19 +141,23 @@
|
||||
"poor-hats-smile",
|
||||
"poor-queens-shop",
|
||||
"popular-trees-grin",
|
||||
"pretty-beds-destroy",
|
||||
"proud-houses-switch",
|
||||
"purple-planes-do",
|
||||
"quick-avocados-type",
|
||||
"quick-seas-deny",
|
||||
"rare-mirrors-notice",
|
||||
"real-balloons-travel",
|
||||
"real-seahorses-change",
|
||||
"red-dolls-repair",
|
||||
"rotten-bananas-attend",
|
||||
"rotten-melons-notice",
|
||||
"rotton-readers-shave",
|
||||
"rude-birds-design",
|
||||
"rude-socks-walk",
|
||||
"serious-apes-rule",
|
||||
"seven-peas-obey",
|
||||
"seven-suits-kneel",
|
||||
"sharp-queens-rhyme",
|
||||
"shiny-buttons-laugh",
|
||||
"short-mails-smoke",
|
||||
|
||||
5
.changeset/pretty-beds-destroy.md
Normal file
5
.changeset/pretty-beds-destroy.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@verdaccio/core': patch
|
||||
---
|
||||
|
||||
fix: restore minimatch major version
|
||||
5
.changeset/rare-mirrors-notice.md
Normal file
5
.changeset/rare-mirrors-notice.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@verdaccio/auth': patch
|
||||
---
|
||||
|
||||
chore(auth): typings
|
||||
5
.changeset/rotten-bananas-attend.md
Normal file
5
.changeset/rotten-bananas-attend.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@verdaccio/auth': patch
|
||||
---
|
||||
|
||||
chore(auth): multiple plugins test
|
||||
5
.changeset/seven-suits-kneel.md
Normal file
5
.changeset/seven-suits-kneel.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@verdaccio/proxy': patch
|
||||
---
|
||||
|
||||
chore(proxy): update tests
|
||||
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -68,7 +68,7 @@ jobs:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
node_version: [18, 20, 21, 22, 23, 24]
|
||||
node_version: [18, 20, 22, 24]
|
||||
name: ${{ matrix.os }} / Node ${{ matrix.node_version }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
"version": "2.0.0-next-8.1",
|
||||
"main": "src/index.ts",
|
||||
"devDependencies": {
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7",
|
||||
"debug": "4.4.1",
|
||||
"fs-extra": "11.2.0",
|
||||
"get-port": "5.1.1",
|
||||
"got": "11.8.6",
|
||||
"js-yaml": "4.1.0",
|
||||
"lodash": "4.17.21",
|
||||
"verdaccio": "workspace:8.0.0-next-8.19"
|
||||
"verdaccio": "workspace:8.0.0-next-8.21"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo no test",
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
"name": "@verdaccio/e2e-ui",
|
||||
"version": "2.0.0",
|
||||
"devDependencies": {
|
||||
"verdaccio": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/test-helper": "workspace:4.0.0-next-8.5",
|
||||
"verdaccio": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/test-helper": "workspace:4.0.0-next-8.6",
|
||||
"debug": "4.4.1",
|
||||
"cypress": "^13.6.0",
|
||||
"get-port": "5.1.1"
|
||||
|
||||
@@ -1,5 +1,34 @@
|
||||
# @verdaccio/api
|
||||
|
||||
## 8.1.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
- @verdaccio/auth@8.0.0-next-8.21
|
||||
- @verdaccio/config@8.0.0-next-8.21
|
||||
- @verdaccio/middleware@8.0.0-next-8.21
|
||||
- @verdaccio/store@8.0.0-next-8.21
|
||||
- @verdaccio/logger@8.0.0-next-8.21
|
||||
|
||||
## 8.1.0-next-8.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 08e1b21: chore(deps): built-in node imports
|
||||
- Updated dependencies [08e1b21]
|
||||
- Updated dependencies [a1a73e9]
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- Updated dependencies [73c0194]
|
||||
- Updated dependencies [5fef0b6]
|
||||
- @verdaccio/middleware@8.0.0-next-8.20
|
||||
- @verdaccio/config@8.0.0-next-8.20
|
||||
- @verdaccio/store@8.0.0-next-8.20
|
||||
- @verdaccio/auth@8.0.0-next-8.20
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
- @verdaccio/logger@8.0.0-next-8.20
|
||||
|
||||
## 8.1.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/api",
|
||||
"version": "8.1.0-next-8.19",
|
||||
"version": "8.1.0-next-8.21",
|
||||
"description": "Verdaccio Registry API",
|
||||
"main": "./build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -42,12 +42,12 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@verdaccio/auth": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/middleware": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/store": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/auth": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/middleware": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/store": "workspace:8.0.0-next-8.21",
|
||||
"abortcontroller-polyfill": "1.7.8",
|
||||
"body-parser": "1.20.3",
|
||||
"cookies": "0.9.1",
|
||||
@@ -58,8 +58,8 @@
|
||||
"semver": "7.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/test-helper": "workspace:4.0.0-next-8.5",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6",
|
||||
"@verdaccio/test-helper": "workspace:4.0.0-next-8.6",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7",
|
||||
"mockdate": "3.0.5",
|
||||
"supertest": "7.0.0"
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Application } from 'express';
|
||||
import _ from 'lodash';
|
||||
import path from 'path';
|
||||
import path from 'node:path';
|
||||
import supertest from 'supertest';
|
||||
import { expect } from 'vitest';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import nock from 'nock';
|
||||
import { basename } from 'path';
|
||||
import { basename } from 'node:path';
|
||||
import supertest from 'supertest';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable curly */
|
||||
// ensure that all arguments are validated
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# @verdaccio/auth
|
||||
|
||||
## 8.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
- @verdaccio/config@8.0.0-next-8.21
|
||||
- @verdaccio/loaders@8.0.0-next-8.11
|
||||
- verdaccio-htpasswd@13.0.0-next-8.21
|
||||
- @verdaccio/signature@8.0.0-next-8.13
|
||||
|
||||
## 8.0.0-next-8.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 08e1b21: chore(deps): built-in node imports
|
||||
- 73c0194: chore(auth): typings
|
||||
- 5fef0b6: chore(auth): multiple plugins test
|
||||
- Updated dependencies [08e1b21]
|
||||
- Updated dependencies [a1a73e9]
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- @verdaccio/config@8.0.0-next-8.20
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
- verdaccio-htpasswd@13.0.0-next-8.20
|
||||
- @verdaccio/loaders@8.0.0-next-8.10
|
||||
- @verdaccio/signature@8.0.0-next-8.12
|
||||
|
||||
## 8.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/auth",
|
||||
"version": "8.0.0-next-8.19",
|
||||
"version": "8.0.0-next-8.21",
|
||||
"description": "Verdaccio Authentication",
|
||||
"main": "./build/index.js",
|
||||
"types": "./build/index.d.ts",
|
||||
@@ -42,18 +42,18 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/loaders": "workspace:8.0.0-next-8.9",
|
||||
"@verdaccio/signature": "workspace:8.0.0-next-8.11",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/loaders": "workspace:8.0.0-next-8.11",
|
||||
"@verdaccio/signature": "workspace:8.0.0-next-8.13",
|
||||
"debug": "4.4.1",
|
||||
"lodash": "4.17.21",
|
||||
"verdaccio-htpasswd": "workspace:13.0.0-next-8.19"
|
||||
"verdaccio-htpasswd": "workspace:13.0.0-next-8.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/middleware": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/middleware": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.21",
|
||||
"express": "4.21.2",
|
||||
"supertest": "7.0.0"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import buildDebug from 'debug';
|
||||
import _, { isFunction } from 'lodash';
|
||||
import _ from 'lodash';
|
||||
import { HTPasswd } from 'verdaccio-htpasswd';
|
||||
|
||||
import { TOKEN_VALID_LENGTH, createAnonymousRemoteUser, createRemoteUser } from '@verdaccio/config';
|
||||
@@ -73,7 +73,7 @@ class Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {
|
||||
}
|
||||
|
||||
public async init() {
|
||||
let plugins = (await this.loadPlugin()) as pluginUtils.Auth<unknown>[];
|
||||
let plugins = await this.loadPlugin();
|
||||
|
||||
debug('auth plugins found %s', plugins.length);
|
||||
if (!plugins || plugins.length === 0) {
|
||||
@@ -86,15 +86,14 @@ class Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {
|
||||
|
||||
private loadDefaultPlugin() {
|
||||
debug('load default auth plugin');
|
||||
const pluginOptions: pluginUtils.PluginOptions = {
|
||||
config: this.config,
|
||||
logger: this.logger,
|
||||
};
|
||||
let authPlugin;
|
||||
try {
|
||||
authPlugin = new HTPasswd(
|
||||
{ file: './htpasswd' },
|
||||
pluginOptions as any as pluginUtils.PluginOptions
|
||||
{
|
||||
config: this.config,
|
||||
logger: this.logger,
|
||||
}
|
||||
);
|
||||
this.logger.info(
|
||||
{ name: 'verdaccio-htpasswd', pluginCategory: PLUGIN_CATEGORY.AUTHENTICATION },
|
||||
@@ -110,7 +109,7 @@ class Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {
|
||||
}
|
||||
|
||||
private async loadPlugin() {
|
||||
return asyncLoadPlugin<pluginUtils.Auth<unknown>>(
|
||||
return asyncLoadPlugin<pluginUtils.Auth<Config>>(
|
||||
this.config.auth,
|
||||
{
|
||||
config: this.config,
|
||||
@@ -184,9 +183,9 @@ class Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {
|
||||
): void {
|
||||
const plugins = this.plugins.slice(0);
|
||||
(function next(): void {
|
||||
const plugin = plugins.shift() as pluginUtils.Auth<Config>;
|
||||
const plugin = plugins.shift();
|
||||
|
||||
if (isFunction(plugin.authenticate) === false) {
|
||||
if (typeof plugin?.authenticate !== 'function') {
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -233,7 +232,7 @@ class Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {
|
||||
|
||||
(function next(): void {
|
||||
let method = 'adduser';
|
||||
const plugin = plugins.shift() as pluginUtils.Auth<Config>;
|
||||
const plugin = plugins.shift();
|
||||
// @ts-expect-error future major (7.x) should remove this section
|
||||
if (typeof plugin.adduser === 'undefined' && typeof plugin.add_user === 'function') {
|
||||
method = 'add_user';
|
||||
@@ -283,9 +282,9 @@ class Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {
|
||||
debug('allow access for %o', packageName);
|
||||
|
||||
(function next(): void {
|
||||
const plugin: pluginUtils.Auth<unknown> = plugins.shift() as pluginUtils.Auth<unknown>;
|
||||
const plugin = plugins.shift();
|
||||
|
||||
if (_.isNil(plugin) || isFunction(plugin.allow_access) === false) {
|
||||
if (typeof plugin?.allow_access !== 'function') {
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -321,7 +320,7 @@ class Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {
|
||||
debug('allow unpublish for %o plugin does not implement allow_unpublish', packageName);
|
||||
continue;
|
||||
} else {
|
||||
plugin.allow_unpublish(user, pkg, (err, ok): void => {
|
||||
plugin.allow_unpublish(user, pkg, (err: VerdaccioError | null, ok?: boolean): void => {
|
||||
if (err) {
|
||||
debug(
|
||||
'forbidden publish for %o, it will fallback on unpublish permissions',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import path from 'path';
|
||||
import path from 'node:path';
|
||||
import { describe, expect, test, vi } from 'vitest';
|
||||
|
||||
import {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import path from 'path';
|
||||
import path from 'node:path';
|
||||
import { describe, expect, test, vi } from 'vitest';
|
||||
|
||||
import {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import express from 'express';
|
||||
import path from 'path';
|
||||
import path from 'node:path';
|
||||
import supertest from 'supertest';
|
||||
import { describe, expect, test, vi } from 'vitest';
|
||||
|
||||
@@ -198,29 +198,52 @@ describe('AuthTest', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('test multiple authenticate methods', () => {
|
||||
test('should skip falsy values', async () => {
|
||||
const config: Config = new AppConfig({
|
||||
...getDefaultConfig(),
|
||||
plugins: path.join(__dirname, './partials/plugin'),
|
||||
auth: {
|
||||
success: {},
|
||||
'fail-invalid-method': {},
|
||||
},
|
||||
});
|
||||
config.checkSecretKey('12345');
|
||||
const auth: Auth = new Auth(config, logger);
|
||||
await auth.init();
|
||||
test('should success first plugin, ignore subsequent plugins', async () => {
|
||||
const config: Config = new AppConfig({
|
||||
...getDefaultConfig(),
|
||||
plugins: path.join(__dirname, './partials/plugin'),
|
||||
auth: {
|
||||
success: {},
|
||||
'no-access': {},
|
||||
},
|
||||
});
|
||||
config.checkSecretKey('12345');
|
||||
const auth: Auth = new Auth(config, logger);
|
||||
await auth.init();
|
||||
|
||||
return new Promise((resolve) => {
|
||||
auth.authenticate('foo', 'bar', (err, value) => {
|
||||
expect(value).toEqual({
|
||||
name: 'foo',
|
||||
groups: ['test', ROLES.$ALL, '$authenticated', '@all', '@authenticated', 'all'],
|
||||
real_groups: ['test'],
|
||||
});
|
||||
resolve(value);
|
||||
return new Promise((resolve) => {
|
||||
auth.authenticate('foo', 'bar', (err, value) => {
|
||||
expect(value).toEqual({
|
||||
name: 'foo',
|
||||
groups: ['test', ROLES.$ALL, '$authenticated', '@all', '@authenticated', 'all'],
|
||||
real_groups: ['test'],
|
||||
});
|
||||
resolve(value);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('should fail first plugin, success second plugin', async () => {
|
||||
const config: Config = new AppConfig({
|
||||
...getDefaultConfig(),
|
||||
plugins: path.join(__dirname, './partials/plugin'),
|
||||
auth: {
|
||||
'no-access': {},
|
||||
success: {},
|
||||
},
|
||||
});
|
||||
config.checkSecretKey('12345');
|
||||
const auth: Auth = new Auth(config, logger);
|
||||
await auth.init();
|
||||
|
||||
return new Promise((resolve) => {
|
||||
auth.authenticate('foo', 'bar', (err, value) => {
|
||||
expect(value).toEqual({
|
||||
name: 'foo',
|
||||
groups: ['test', ROLES.$ALL, '$authenticated', '@all', '@authenticated', 'all'],
|
||||
real_groups: ['test'],
|
||||
});
|
||||
resolve(value);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import path from 'path';
|
||||
import path from 'node:path';
|
||||
|
||||
import { getDefaultConfig } from '@verdaccio/config';
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
module.exports = function () {
|
||||
return {
|
||||
authenticate(user, pass, callback) {
|
||||
// no access but also no error
|
||||
callback(null, false);
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "verdaccio-no-access",
|
||||
"main": "no-access.js",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
@@ -1,5 +1,27 @@
|
||||
# @verdaccio/cli
|
||||
|
||||
## 8.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
- @verdaccio/config@8.0.0-next-8.21
|
||||
- @verdaccio/node-api@8.0.0-next-8.21
|
||||
- @verdaccio/logger@8.0.0-next-8.21
|
||||
|
||||
## 8.0.0-next-8.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [08e1b21]
|
||||
- Updated dependencies [a1a73e9]
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- @verdaccio/node-api@8.0.0-next-8.20
|
||||
- @verdaccio/config@8.0.0-next-8.20
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
- @verdaccio/logger@8.0.0-next-8.20
|
||||
|
||||
## 8.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/cli",
|
||||
"version": "8.0.0-next-8.19",
|
||||
"version": "8.0.0-next-8.21",
|
||||
"author": {
|
||||
"name": "Juan Picado",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
@@ -47,10 +47,10 @@
|
||||
"start": "ts-node src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/node-api": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/node-api": "workspace:8.0.0-next-8.21",
|
||||
"clipanion": "4.0.0-rc.4",
|
||||
"envinfo": "7.14.0",
|
||||
"kleur": "4.1.5",
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
# @verdaccio/config
|
||||
|
||||
## 8.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
|
||||
## 8.0.0-next-8.20
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 6a4d6dd: feat: getListenAddress getConfigParsed methods
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 08e1b21: chore(deps): built-in node imports
|
||||
- a1a73e9: feat(logger): support redacting sensitive data
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
|
||||
## 8.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/config",
|
||||
"version": "8.0.0-next-8.19",
|
||||
"version": "8.0.0-next-8.21",
|
||||
"description": "Verdaccio Configuration",
|
||||
"main": "./build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -42,7 +42,7 @@
|
||||
"build": "pnpm run build:js && pnpm run build:types"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"debug": "4.4.1",
|
||||
"js-yaml": "4.1.0",
|
||||
"lodash": "4.17.21",
|
||||
|
||||
136
packages/config/src/address.ts
Normal file
136
packages/config/src/address.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
import createDebug from 'debug';
|
||||
|
||||
import { DEFAULT_DOMAIN, DEFAULT_PORT, DEFAULT_PROTOCOL } from '@verdaccio/core';
|
||||
import { Logger } from '@verdaccio/types';
|
||||
|
||||
const debug = createDebug('verdaccio:config:address');
|
||||
|
||||
export interface ListenAddress {
|
||||
proto: string;
|
||||
host?: string;
|
||||
port?: string;
|
||||
path?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an internet address
|
||||
* Allow:
|
||||
- https:localhost:1234 - protocol + host + port
|
||||
- localhost:1234 - host + port
|
||||
- 1234 - port
|
||||
- http::1234 - protocol + port
|
||||
- https://localhost:443/ - full url + https
|
||||
- http://[::1]:443/ - ipv6
|
||||
- unix:/tmp/http.sock - unix sockets
|
||||
- https://unix:/tmp/http.sock - unix sockets (https)
|
||||
* @param {*} urlAddress the internet address definition
|
||||
* @return {Object|Null} literal object that represent the address parsed
|
||||
*/
|
||||
export function parseAddress(urlAddress: string): ListenAddress | null {
|
||||
//
|
||||
// TODO: refactor it to something more reasonable?
|
||||
//
|
||||
// protocol : // ( host )|( ipv6 ): port /
|
||||
const urlPattern = /^((https?):(\/\/)?)?((([^\/:]*)|\[([^\[\]]+)\]):)?(\d+)\/?$/.exec(urlAddress);
|
||||
|
||||
if (urlPattern) {
|
||||
return {
|
||||
proto: urlPattern[2] || DEFAULT_PROTOCOL,
|
||||
host: urlPattern[6] || urlPattern[7] || DEFAULT_DOMAIN,
|
||||
port: urlPattern[8] || DEFAULT_PORT,
|
||||
};
|
||||
}
|
||||
|
||||
const unixPattern = /^(?:(https?):\/\/)?unix:(\/.*)$/.exec(urlAddress);
|
||||
if (!unixPattern) {
|
||||
// if we cannot match the unix pattern, we return null
|
||||
// this is to avoid returning a wrong object
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
host: unixPattern[2],
|
||||
proto: unixPattern[1] || 'unix',
|
||||
path: unixPattern[2],
|
||||
};
|
||||
}
|
||||
|
||||
function addrToString(a: ListenAddress): string {
|
||||
return a.proto === 'unix' ? `unix:${a.host}` : `${a.proto}://${a.host}:${a.port}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all addresses defined in the config file.
|
||||
* Verdaccio is able to listen multiple ports
|
||||
* @param {String} argListen
|
||||
* @param {String} configListen
|
||||
* eg:
|
||||
* listen:
|
||||
- localhost:5555
|
||||
- localhost:5557
|
||||
@return {Array}
|
||||
*/
|
||||
export function getListenAddress(listen: (string | void)[], logger: Logger): ListenAddress {
|
||||
debug('getListenAddress called with %o', listen);
|
||||
|
||||
if (!listen) {
|
||||
debug('No listen address provided, using default');
|
||||
return { proto: DEFAULT_PROTOCOL, host: DEFAULT_DOMAIN, port: DEFAULT_PORT };
|
||||
}
|
||||
|
||||
if (Array.isArray(listen)) {
|
||||
const filteredListen = listen.filter((item) => typeof item === 'string');
|
||||
|
||||
if (filteredListen.length === 0) {
|
||||
throw new Error('Listen addresses array cannot be empty');
|
||||
}
|
||||
|
||||
const invalid: string[] = [];
|
||||
|
||||
for (const raw of filteredListen) {
|
||||
const candidate = parseAddress(raw as string);
|
||||
if (candidate) {
|
||||
debug('valid listen address found: %o', candidate);
|
||||
|
||||
invalid.forEach((bad) =>
|
||||
logger.warn(
|
||||
{ addr: bad },
|
||||
'invalid address - @{addr}, we expect a port (e.g. "4873"), ' +
|
||||
'host:port (e.g. "localhost:4873"), full url ' +
|
||||
'(e.g. "http://localhost:4873/") or unix:/path/socket'
|
||||
)
|
||||
);
|
||||
|
||||
if (listen.length > 1) {
|
||||
logger.warn(
|
||||
`Multiple listen addresses are not supported, using the first valid one ${addrToString(
|
||||
candidate
|
||||
)}`
|
||||
);
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
invalid.push(raw as string);
|
||||
}
|
||||
|
||||
invalid.forEach((bad) =>
|
||||
logger.warn(
|
||||
{ addr: bad },
|
||||
'invalid address - @{addr}, we expect a port (e.g. "4873"), ' +
|
||||
'host:port (e.g. "localhost:4873"), full url ' +
|
||||
'(e.g. "http://localhost:4873/") or unix:/path/socket'
|
||||
)
|
||||
);
|
||||
throw new Error('No valid listen addresses found in configuration array');
|
||||
}
|
||||
|
||||
const single = parseAddress(listen);
|
||||
if (!single) {
|
||||
throw new Error(
|
||||
`Invalid address - ${listen}, we expect a port (e.g. "4873"), ` +
|
||||
`host:port (e.g. "localhost:4873"), full url ` +
|
||||
`(e.g. "http://localhost:4873/") or unix:/path/socket`
|
||||
);
|
||||
}
|
||||
return single;
|
||||
}
|
||||
@@ -210,7 +210,16 @@ middlewares:
|
||||
|
||||
# Log settings
|
||||
# https://verdaccio.org/docs/logger
|
||||
log: { type: stdout, format: pretty, level: http }
|
||||
# Redaction: https://getpino.io/#/docs/redaction
|
||||
# Synchronous logging: https://getpino.io/#/docs/asynchronous
|
||||
log:
|
||||
type: stdout
|
||||
format: pretty
|
||||
level: http
|
||||
# redact:
|
||||
# paths: ['req.header.authorization','req.header.cookie','req.remoteAddress','req.remotePort','ip','remoteIP','user','msg']
|
||||
# censor: '<redacted>'
|
||||
# sync: true
|
||||
|
||||
# Feature flags (experimental settings that can be changed or removed in the future)
|
||||
# https://verdaccio.org/docs/configuration#experiments
|
||||
|
||||
@@ -210,7 +210,16 @@ middlewares:
|
||||
|
||||
# Log settings
|
||||
# https://verdaccio.org/docs/logger
|
||||
log: { type: stdout, format: pretty, level: http }
|
||||
# Redaction: https://getpino.io/#/docs/redaction
|
||||
# Synchronous logging: https://getpino.io/#/docs/asynchronous
|
||||
log:
|
||||
type: stdout
|
||||
format: pretty
|
||||
level: http
|
||||
# redact:
|
||||
# paths: ['req.header.authorization','req.header.cookie','req.remoteAddress','req.remotePort','ip','remoteIP','user','msg']
|
||||
# censor: '<redacted>'
|
||||
# sync: true
|
||||
|
||||
# Feature flags (experimental settings that can be changed or removed in the future)
|
||||
# https://verdaccio.org/docs/configuration#experiments
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { join } from 'path';
|
||||
import { join } from 'node:path';
|
||||
|
||||
import { parseConfigFile } from '../parse';
|
||||
|
||||
export function getDefaultConfig(fileName = 'default.yaml') {
|
||||
export function getDefaultConfig(fileName: string = 'default.yaml') {
|
||||
const file = join(__dirname, `./${fileName}`);
|
||||
return parseConfigFile(file);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import buildDebug from 'debug';
|
||||
import fs from 'fs';
|
||||
import _ from 'lodash';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
|
||||
import { fileExists, folderExists } from './config-utils';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import buildDebug from 'debug';
|
||||
import fs from 'fs';
|
||||
import fs from 'node:fs';
|
||||
|
||||
const debug = buildDebug('verdaccio:config:config-utils');
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import assert from 'assert';
|
||||
import buildDebug from 'debug';
|
||||
import _ from 'lodash';
|
||||
import assert from 'node:assert';
|
||||
|
||||
import { APP_ERROR, authUtils, cryptoUtils, validationUtils, warningUtils } from '@verdaccio/core';
|
||||
import { Codes } from '@verdaccio/core/build/warning-utils';
|
||||
|
||||
@@ -3,10 +3,11 @@ export * from './config-path';
|
||||
export * from './token';
|
||||
export * from './config-utils';
|
||||
export * from './package-access';
|
||||
export { fromJStoYAML, parseConfigFile } from './parse';
|
||||
export { fromJStoYAML, parseConfigFile, getConfigParsed } from './parse';
|
||||
export * from './uplinks';
|
||||
export * from './security';
|
||||
export * from './agent';
|
||||
export * from './user';
|
||||
export { default as ConfigBuilder } from './builder';
|
||||
export { getDefaultConfig } from './conf';
|
||||
export * from './address';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import assert from 'assert';
|
||||
import buildDebug from 'debug';
|
||||
import _ from 'lodash';
|
||||
import assert from 'node:assert';
|
||||
|
||||
import { errorUtils } from '@verdaccio/core';
|
||||
import { PackageAccess } from '@verdaccio/types';
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import buildDebug from 'debug';
|
||||
import fs from 'fs';
|
||||
import YAML from 'js-yaml';
|
||||
import { isObject } from 'lodash';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import { APP_ERROR } from '@verdaccio/core';
|
||||
import { API_ERROR, APP_ERROR } from '@verdaccio/core';
|
||||
import { ConfigYaml } from '@verdaccio/types';
|
||||
|
||||
import { findConfigFile } from './config-path';
|
||||
import { fileExists } from './config-utils';
|
||||
|
||||
const debug = buildDebug('verdaccio:config:parse');
|
||||
@@ -61,3 +63,48 @@ export function fromJStoYAML(config: Partial<ConfigYaml>): string | null {
|
||||
throw new Error(`config is not a valid object`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and returns a configuration object of type `ConfigYaml`.
|
||||
*
|
||||
* If a string or `undefined` is provided, it is interpreted as a path to a config file
|
||||
* (or uses a default location). The config file is then loaded and parsed.
|
||||
* If an object is provided, it is assumed to be a pre-parsed configuration.
|
||||
* Backward compability: ensures the returned configuration object has a `self_path` property set,
|
||||
* either to the config file path or to a property within the object.
|
||||
*
|
||||
* @param {string | ConfigYaml} [config] - Optional. A path to the configuration file (string),
|
||||
* a pre-parsed config object, or `undefined`.
|
||||
* @returns {ConfigYaml} The parsed configuration object with a guaranteed `self_path` property.
|
||||
* @throws {Error} If the provided config is neither a string, undefined, nor an object.
|
||||
*/
|
||||
export function getConfigParsed(config?: string | ConfigYaml): ConfigYaml {
|
||||
debug('getConfigParsed called with config: %o', typeof config);
|
||||
let configurationParsed: ConfigYaml;
|
||||
if (config === undefined || typeof config === 'string') {
|
||||
debug('using default configuration');
|
||||
const configPathLocation = findConfigFile(config);
|
||||
configurationParsed = parseConfigFile(configPathLocation);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
if (!configurationParsed.self_path) {
|
||||
debug('self_path not defined, using config path location');
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
configurationParsed.self_path = path.resolve(configPathLocation);
|
||||
}
|
||||
} else if (typeof config === 'object' && config !== null) {
|
||||
configurationParsed = config;
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
if (!configurationParsed.self_path) {
|
||||
debug('self_path not defined, using config path location');
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
configurationParsed.self_path = configurationParsed.configPath;
|
||||
}
|
||||
} else {
|
||||
throw new Error(API_ERROR.CONFIG_BAD_FORMAT);
|
||||
}
|
||||
return configurationParsed;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { randomBytes } from 'crypto';
|
||||
import { randomBytes } from 'node:crypto';
|
||||
|
||||
export const TOKEN_VALID_LENGTH = 32;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import assert from 'assert';
|
||||
import _ from 'lodash';
|
||||
import assert from 'node:assert';
|
||||
|
||||
import { authUtils } from '@verdaccio/core';
|
||||
import { PackageList, UpLinksConfList } from '@verdaccio/types';
|
||||
|
||||
209
packages/config/test/address.spec.ts
Normal file
209
packages/config/test/address.spec.ts
Normal file
@@ -0,0 +1,209 @@
|
||||
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
||||
|
||||
import { Logger } from '@verdaccio/types';
|
||||
|
||||
import { getListenAddress, parseAddress } from '../src';
|
||||
|
||||
const logger: Logger = {
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
} as any;
|
||||
|
||||
describe('address parsing', () => {
|
||||
describe('getListenAddress', () => {
|
||||
const warn = logger.warn as unknown as ReturnType<typeof vi.fn>;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
test('returns a parsed object for a simple port', () => {
|
||||
const addr = getListenAddress('4873', logger);
|
||||
|
||||
expect(addr).toEqual({
|
||||
proto: 'http',
|
||||
host: 'localhost',
|
||||
port: '4873',
|
||||
});
|
||||
expect(warn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('throws when the single string is invalid', () => {
|
||||
expect(() => getListenAddress('not_valid', logger)).toThrow(/Invalid address/i);
|
||||
expect(warn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('uses the first valid element and warns about the rest', () => {
|
||||
const addr = getListenAddress(['bad', 'http://localhost:4873', 'unix:/tmp/x.sock'], logger);
|
||||
|
||||
expect(addr).toEqual({
|
||||
proto: 'http',
|
||||
host: 'localhost',
|
||||
port: '4873',
|
||||
});
|
||||
|
||||
expect(warn).toHaveBeenCalledTimes(2);
|
||||
// expect(warn.mock.calls[0][0]).toMatchObject({ addr: 'bad' });
|
||||
expect(warn.mock.calls[1][0]).toMatch(/Multiple listen addresses/i);
|
||||
});
|
||||
|
||||
test('throws if every element in the array is invalid', () => {
|
||||
expect(() => getListenAddress(['bad1', 'also_bad'], logger)).toThrow(
|
||||
/No valid listen addresses/i
|
||||
);
|
||||
// two warnings, one per invalid element
|
||||
expect(warn).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
test('throws when given an empty array', () => {
|
||||
expect(() => getListenAddress([])).toThrow(/array cannot be empty/i);
|
||||
expect(warn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('localhost:4873 (default value)', () => {
|
||||
const addr = getListenAddress('localhost:4873');
|
||||
|
||||
expect(addr).toEqual({ proto: 'http', host: 'localhost', port: '4873' });
|
||||
expect(warn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('http://localhost:4873 (explicit protocol)', () => {
|
||||
const addr = getListenAddress('http://localhost:4873', logger);
|
||||
|
||||
expect(addr).toEqual({ proto: 'http', host: 'localhost', port: '4873' });
|
||||
expect(warn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('0.0.0.0:4873 (INADDR_ANY)', () => {
|
||||
const addr = getListenAddress('0.0.0.0:4873', logger);
|
||||
|
||||
expect(addr).toEqual({ proto: 'http', host: '0.0.0.0', port: '4873' });
|
||||
expect(warn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('https://example.org:4873 (TLS)', () => {
|
||||
const addr = getListenAddress('https://example.org:4873', logger);
|
||||
|
||||
expect(addr).toEqual({ proto: 'https', host: 'example.org', port: '4873' });
|
||||
expect(warn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('"[::1]:4873" (IPv6)', () => {
|
||||
const addr = getListenAddress('[::1]:4873', logger);
|
||||
|
||||
/* parseAddress collapses brackets & assigns proto http */
|
||||
expect(addr).toEqual({ proto: 'http', host: '::1', port: '4873' });
|
||||
expect(warn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('"https:[::1]:4873" (IPv6)', () => {
|
||||
const addr = getListenAddress('https:[::1]:4873', logger);
|
||||
|
||||
/* parseAddress collapses brackets & assigns proto http */
|
||||
expect(addr).toEqual({ proto: 'https', host: '::1', port: '4873' });
|
||||
expect(warn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('unix:/tmp/verdaccio.sock (Unix socket)', () => {
|
||||
const addr = getListenAddress('unix:/tmp/verdaccio.sock', logger);
|
||||
|
||||
expect(addr).toEqual({
|
||||
proto: 'unix',
|
||||
path: '/tmp/verdaccio.sock',
|
||||
host: '/tmp/verdaccio.sock',
|
||||
});
|
||||
expect(warn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('http://foo.sock:34 (Unix socket)', () => {
|
||||
const addr = getListenAddress('http://foo.sock:34', logger);
|
||||
|
||||
expect(addr).toEqual({
|
||||
host: 'foo.sock',
|
||||
port: '34',
|
||||
proto: 'http',
|
||||
});
|
||||
expect(warn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('http://unix:/tmp/verdaccio.sock (HTTP Unix socket)', () => {
|
||||
const addr = getListenAddress('http://unix:/tmp/verdaccio.sock', logger);
|
||||
|
||||
expect(addr).toEqual({
|
||||
path: '/tmp/verdaccio.sock',
|
||||
proto: 'http',
|
||||
host: '/tmp/verdaccio.sock',
|
||||
});
|
||||
expect(warn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('https://unix:/tmp/verdaccio.sock (HTTPS Unix socket)', () => {
|
||||
const addr = getListenAddress('https://unix:/tmp/verdaccio.sock', logger);
|
||||
|
||||
expect(addr).toEqual({
|
||||
path: '/tmp/verdaccio.sock',
|
||||
proto: 'https',
|
||||
host: '/tmp/verdaccio.sock',
|
||||
});
|
||||
expect(warn).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseAddress – documented listen values', () => {
|
||||
test('localhost:4873 (default style)', () => {
|
||||
expect(parseAddress('localhost:4873')).toEqual({
|
||||
proto: 'http',
|
||||
host: 'localhost',
|
||||
port: '4873',
|
||||
});
|
||||
});
|
||||
|
||||
test('http://localhost:4873 (explicit protocol)', () => {
|
||||
expect(parseAddress('http://localhost:4873')).toEqual({
|
||||
proto: 'http',
|
||||
host: 'localhost',
|
||||
port: '4873',
|
||||
});
|
||||
});
|
||||
|
||||
test('0.0.0.0:4873 (INADDR_ANY)', () => {
|
||||
expect(parseAddress('0.0.0.0:4873')).toEqual({
|
||||
proto: 'http',
|
||||
host: '0.0.0.0',
|
||||
port: '4873',
|
||||
});
|
||||
});
|
||||
|
||||
test('https://example.org:4873 (HTTPS)', () => {
|
||||
expect(parseAddress('https://example.org:4873')).toEqual({
|
||||
proto: 'https',
|
||||
host: 'example.org',
|
||||
port: '4873',
|
||||
});
|
||||
});
|
||||
|
||||
test('"[::1]:4873" (IPv6)', () => {
|
||||
expect(parseAddress('[::1]:4873')).toEqual({
|
||||
proto: 'http',
|
||||
host: '::1',
|
||||
port: '4873',
|
||||
});
|
||||
});
|
||||
|
||||
test('unix:/tmp/verdaccio.sock (Unix socket)', () => {
|
||||
expect(parseAddress('unix:/tmp/verdaccio.sock')).toEqual({
|
||||
host: '/tmp/verdaccio.sock',
|
||||
proto: 'unix',
|
||||
path: '/tmp/verdaccio.sock',
|
||||
});
|
||||
});
|
||||
|
||||
test('https://unix:/tmp/verdaccio.sock (HTTPS Unix socket)', () => {
|
||||
expect(parseAddress('https://unix:/tmp/verdaccio.sock')).toEqual({
|
||||
host: '/tmp/verdaccio.sock',
|
||||
proto: 'https',
|
||||
path: '/tmp/verdaccio.sock',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import { fileUtils } from '@verdaccio/core';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import path from 'path';
|
||||
import path from 'node:path';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import { fileExists, folderExists } from '../src/config-utils';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
|
||||
|
||||
import { findConfigFile } from '../src/config-path';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import path from 'path';
|
||||
import path from 'node:path';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import {
|
||||
|
||||
27
packages/config/test/parse.spec.ts
Normal file
27
packages/config/test/parse.spec.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import path from 'node:path';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import { getConfigParsed, parseConfigFile } from '../src';
|
||||
|
||||
describe('getConfigParsed', () => {
|
||||
const partialsDir = path.join(__dirname, './partials/config/yaml');
|
||||
|
||||
test('parses config from a YAML file path', () => {
|
||||
const yamlFile = path.join(partialsDir, 'config-getMatchedPackagesSpec.yaml');
|
||||
const config = getConfigParsed(yamlFile);
|
||||
expect(config).toBeDefined();
|
||||
});
|
||||
|
||||
test('parses config from a YAML file path', () => {
|
||||
const yamlFile = path.join(partialsDir, 'config-getMatchedPackagesSpec.yaml');
|
||||
const config = getConfigParsed(parseConfigFile(yamlFile));
|
||||
expect(config).toBeDefined();
|
||||
});
|
||||
|
||||
test('throws error for invalid config type', () => {
|
||||
// @ts-expect-error
|
||||
expect(() => getConfigParsed(123)).toThrow();
|
||||
// @ts-expect-error
|
||||
expect(() => getConfigParsed(true)).toThrow();
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import path from 'path';
|
||||
import path from 'node:path';
|
||||
|
||||
export const parseConfigurationFile = (conf: string) => {
|
||||
const { name, ext } = path.parse(conf);
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# @verdaccio/core
|
||||
|
||||
## 8.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f8a321f: fix: restore minimatch major version
|
||||
|
||||
## 8.0.0-next-8.20
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 6a4d6dd: feat: getListenAddress getConfigParsed methods
|
||||
|
||||
## 8.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/core",
|
||||
"version": "8.0.0-next-8.19",
|
||||
"version": "8.0.0-next-8.21",
|
||||
"description": "Verdaccio Core Components",
|
||||
"keywords": [
|
||||
"private",
|
||||
@@ -36,12 +36,12 @@
|
||||
"ajv": "8.17.1",
|
||||
"http-errors": "2.0.0",
|
||||
"http-status-codes": "2.3.0",
|
||||
"minimatch": "10.0.1",
|
||||
"minimatch": "7.4.6",
|
||||
"process-warning": "1.0.0",
|
||||
"semver": "7.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7",
|
||||
"express": "4.21.2",
|
||||
"typedoc": "0.23.25",
|
||||
"vitest": "3.0.4"
|
||||
|
||||
@@ -163,3 +163,7 @@ export const PLUGIN_CATEGORY = {
|
||||
FILTER: 'filter',
|
||||
THEME: 'theme',
|
||||
};
|
||||
|
||||
export const DEFAULT_PORT = '4873';
|
||||
export const DEFAULT_PROTOCOL = 'http';
|
||||
export const DEFAULT_DOMAIN = 'localhost';
|
||||
|
||||
@@ -31,6 +31,9 @@ export {
|
||||
PLUGIN_PREFIX,
|
||||
PLUGIN_UI_PREFIX,
|
||||
HtpasswdHashAlgorithm,
|
||||
DEFAULT_DOMAIN,
|
||||
DEFAULT_PORT,
|
||||
DEFAULT_PROTOCOL,
|
||||
} from './constants';
|
||||
export {
|
||||
authUtils,
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Change Log
|
||||
|
||||
## 13.0.0-next-8.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 08e1b21: chore(deps): built-in node imports
|
||||
|
||||
## 13.0.0-next-8.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/file-locking",
|
||||
"version": "13.0.0-next-8.4",
|
||||
"version": "13.0.0-next-8.5",
|
||||
"description": "Verdaccio File Locking Library",
|
||||
"keywords": [
|
||||
"private",
|
||||
@@ -39,7 +39,7 @@
|
||||
"lockfile": "1.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7",
|
||||
"vitest": "3.0.4"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import locker from 'lockfile';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { promisify } from 'util';
|
||||
import { promisify } from 'node:util';
|
||||
|
||||
const fsP = fs.promises ? fs.promises : require('fs/promises');
|
||||
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# Change Log
|
||||
|
||||
## 13.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
- @verdaccio/url@13.0.0-next-8.21
|
||||
|
||||
## 13.0.0-next-8.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
- @verdaccio/url@13.0.0-next-8.20
|
||||
|
||||
## 13.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/tarball",
|
||||
"version": "13.0.0-next-8.19",
|
||||
"version": "13.0.0-next-8.21",
|
||||
"description": "Verdaccio Tarball Utilities",
|
||||
"keywords": [
|
||||
"private",
|
||||
@@ -33,14 +33,14 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/url": "workspace:13.0.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/url": "workspace:13.0.0-next-8.21",
|
||||
"debug": "4.4.1",
|
||||
"gunzip-maybe": "^1.4.2",
|
||||
"tar-stream": "^3.1.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7",
|
||||
"node-mocks-http": "1.14.1",
|
||||
"vitest": "3.0.4"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Change Log
|
||||
|
||||
## 13.0.0-next-8.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- a1a73e9: feat(logger): support redacting sensitive data
|
||||
|
||||
## 13.0.0-next-8.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/types",
|
||||
"version": "13.0.0-next-8.6",
|
||||
"version": "13.0.0-next-8.7",
|
||||
"description": "Verdaccio Type Definitions",
|
||||
"keywords": [
|
||||
"private",
|
||||
|
||||
@@ -20,13 +20,20 @@ export type LoggerType = 'stdout' | 'file';
|
||||
export type LoggerFormat = 'pretty' | 'pretty-timestamped' | 'json';
|
||||
export type LoggerLevel = 'fatal' | 'error' | 'warn' | 'info' | 'http' | 'debug' | 'trace';
|
||||
|
||||
export type LoggerRedact = {
|
||||
paths: string[];
|
||||
censor?: string;
|
||||
remove?: boolean;
|
||||
};
|
||||
|
||||
export type LoggerConfigItem = {
|
||||
type?: LoggerType;
|
||||
format?: LoggerFormat;
|
||||
path?: string;
|
||||
level?: LoggerLevel;
|
||||
colors?: boolean;
|
||||
async?: boolean;
|
||||
sync?: boolean;
|
||||
redact?: LoggerRedact;
|
||||
};
|
||||
|
||||
export interface ConfigWithHttps extends Config {
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# Change Log
|
||||
|
||||
## 13.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
|
||||
## 13.0.0-next-8.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
|
||||
## 13.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/url",
|
||||
"version": "13.0.0-next-8.19",
|
||||
"version": "13.0.0-next-8.21",
|
||||
"description": "Verdaccio URL Utilities",
|
||||
"keywords": [
|
||||
"private",
|
||||
@@ -33,13 +33,13 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"debug": "4.4.1",
|
||||
"lodash": "4.17.21",
|
||||
"validator": "13.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7",
|
||||
"node-mocks-http": "1.14.1",
|
||||
"vitest": "3.0.4"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @verdaccio/hooks
|
||||
|
||||
## 8.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
- @verdaccio/logger@8.0.0-next-8.21
|
||||
|
||||
## 8.0.0-next-8.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 08e1b21: chore(deps): built-in node imports
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
- @verdaccio/logger@8.0.0-next-8.20
|
||||
|
||||
## 8.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/hooks",
|
||||
"version": "8.0.0-next-8.19",
|
||||
"version": "8.0.0-next-8.21",
|
||||
"description": "Verdaccio Hooks",
|
||||
"main": "./build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -33,15 +33,15 @@
|
||||
"node": ">=18"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.21",
|
||||
"debug": "4.4.1",
|
||||
"got-cjs": "12.5.4",
|
||||
"handlebars": "4.7.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7",
|
||||
"nock": "13.5.6",
|
||||
"vitest": "3.0.4"
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import path from 'path';
|
||||
import path from 'node:path';
|
||||
|
||||
export const parseConfigurationFile = (name) => {
|
||||
return path.join(__dirname, `../partials/config/yaml/${name}.yaml`);
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @verdaccio/loaders
|
||||
|
||||
## 8.0.0-next-8.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
|
||||
## 8.0.0-next-8.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
|
||||
## 8.0.0-next-8.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/loaders",
|
||||
"version": "8.0.0-next-8.9",
|
||||
"version": "8.0.0-next-8.11",
|
||||
"description": "Verdaccio Loader Logic",
|
||||
"main": "./build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -17,14 +17,14 @@
|
||||
"url": "https://github.com/verdaccio/verdaccio/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"debug": "4.4.1",
|
||||
"lodash": "4.17.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio-scope/verdaccio-auth-foo": "0.0.2",
|
||||
"customprefix-auth": "workspace:2.0.0",
|
||||
"verdaccio-auth-memory": "workspace:*",
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @verdaccio/logger-commons
|
||||
|
||||
## 8.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
|
||||
## 8.0.0-next-8.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- a1a73e9: feat(logger): support redacting sensitive data
|
||||
- Updated dependencies [08e1b21]
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- @verdaccio/logger-prettify@8.0.0-next-8.4
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
|
||||
## 8.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/logger-commons",
|
||||
"version": "8.0.0-next-8.19",
|
||||
"version": "8.0.0-next-8.21",
|
||||
"description": "Verdaccio Logger Commons",
|
||||
"main": "./build/index.js",
|
||||
"types": "./build/index.d.ts",
|
||||
@@ -42,13 +42,13 @@
|
||||
"build": "pnpm run build:js && pnpm run build:types"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/logger-prettify": "workspace:8.0.0-next-8.3",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/logger-prettify": "workspace:8.0.0-next-8.4",
|
||||
"debug": "4.4.1",
|
||||
"colorette": "2.0.20"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7",
|
||||
"pino": "9.7.0",
|
||||
"vitest": "3.0.4"
|
||||
},
|
||||
|
||||
@@ -25,10 +25,8 @@ export type LogPlugin = {
|
||||
options?: any[];
|
||||
};
|
||||
|
||||
type LoggerOptions = { level?: string; path?: string; colors?: boolean; sync?: boolean };
|
||||
|
||||
export function createLogger(
|
||||
options: LoggerOptions = { level: 'http' },
|
||||
options: LoggerConfigItem = { level: 'http' },
|
||||
// eslint-disable-next-line no-undef
|
||||
// @ts-ignore
|
||||
destination: NodeJS.WritableStream = pino.destination(1),
|
||||
@@ -46,6 +44,8 @@ export function createLogger(
|
||||
req: pino.stdSerializers.req,
|
||||
res: pino.stdSerializers.res,
|
||||
},
|
||||
sync: options.sync,
|
||||
redact: options.redact,
|
||||
};
|
||||
|
||||
debug('has prettifier? %o', !isProd());
|
||||
@@ -124,32 +124,17 @@ export function prepareSetup(options: LoggerConfigItem = DEFAULT_LOGGER_CONF, pi
|
||||
loggerConfig
|
||||
);
|
||||
}
|
||||
const pinoConfig = { level: loggerConfig.level };
|
||||
if (loggerConfig.type === 'file') {
|
||||
debug('logging file enabled');
|
||||
const destination = pino.destination(loggerConfig.path);
|
||||
/* eslint-disable */
|
||||
/* istanbul ignore next */
|
||||
process.on('SIGUSR2', () => destination.reopen());
|
||||
// @ts-ignore
|
||||
logger = createLogger(
|
||||
{ level: loggerConfig.level, path: loggerConfig.path, colors: loggerConfig.colors },
|
||||
// @ts-ignore
|
||||
destination,
|
||||
loggerConfig.format,
|
||||
pino
|
||||
);
|
||||
logger = createLogger(loggerConfig, destination, loggerConfig.format, pino);
|
||||
return logger;
|
||||
} else {
|
||||
debug('logging stdout enabled');
|
||||
// @ts-ignore
|
||||
logger = createLogger(
|
||||
{ level: loggerConfig.level, colors: loggerConfig.colors },
|
||||
// @ts-ignore
|
||||
pino.destination(1),
|
||||
loggerConfig.format,
|
||||
pino
|
||||
);
|
||||
logger = createLogger(loggerConfig, pino.destination(1), loggerConfig.format, pino);
|
||||
return logger;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,4 +126,168 @@ describe('logger test', () => {
|
||||
expect(content).toMatch('info --- publishing or updating a new version for test\n');
|
||||
});
|
||||
});
|
||||
|
||||
describe('redacting sensitive data', () => {
|
||||
test('should redact sensitive data with default censor', async () => {
|
||||
const file = await createLogFile();
|
||||
const logger = prepareSetup(
|
||||
{
|
||||
...defaultOptions,
|
||||
format: 'json',
|
||||
type: 'file',
|
||||
path: file,
|
||||
level: 'info',
|
||||
redact: {
|
||||
paths: ['password', 'token'],
|
||||
},
|
||||
},
|
||||
pino
|
||||
);
|
||||
logger.info(
|
||||
{
|
||||
user: 'testuser',
|
||||
password: 'secretpassword123',
|
||||
token: 'bearer-token-xyz',
|
||||
publicInfo: 'this should be visible',
|
||||
},
|
||||
'User authentication attempt'
|
||||
);
|
||||
|
||||
const content = await readLogFile(file);
|
||||
const logEntry = JSON.parse(content);
|
||||
|
||||
expect(logEntry.user).toBe('testuser');
|
||||
expect(logEntry.password).toBe('[Redacted]');
|
||||
expect(logEntry.token).toBe('[Redacted]');
|
||||
expect(logEntry.publicInfo).toBe('this should be visible');
|
||||
expect(logEntry.msg).toBe('User authentication attempt');
|
||||
});
|
||||
|
||||
test('should redact sensitive data with custom censor string', async () => {
|
||||
const file = await createLogFile();
|
||||
const logger = prepareSetup(
|
||||
{
|
||||
...defaultOptions,
|
||||
format: 'json',
|
||||
type: 'file',
|
||||
path: file,
|
||||
level: 'info',
|
||||
redact: {
|
||||
paths: ['apiKey', 'credentials.secret'],
|
||||
censor: '***HIDDEN***',
|
||||
},
|
||||
},
|
||||
pino
|
||||
);
|
||||
logger.info(
|
||||
{
|
||||
apiKey: 'api-key-12345',
|
||||
credentials: {
|
||||
secret: 'very-secret-data',
|
||||
publicKey: 'public-data-ok-to-show',
|
||||
},
|
||||
requestId: 'req-123',
|
||||
},
|
||||
'API request processed'
|
||||
);
|
||||
|
||||
const content = await readLogFile(file);
|
||||
const logEntry = JSON.parse(content);
|
||||
|
||||
expect(logEntry.apiKey).toBe('***HIDDEN***');
|
||||
expect(logEntry.credentials.secret).toBe('***HIDDEN***');
|
||||
expect(logEntry.credentials.publicKey).toBe('public-data-ok-to-show');
|
||||
expect(logEntry.requestId).toBe('req-123');
|
||||
});
|
||||
|
||||
test('should remove sensitive fields when remove option is true', async () => {
|
||||
const file = await createLogFile();
|
||||
const logger = prepareSetup(
|
||||
{
|
||||
...defaultOptions,
|
||||
format: 'json',
|
||||
type: 'file',
|
||||
path: file,
|
||||
level: 'info',
|
||||
redact: {
|
||||
paths: ['sensitiveData', 'auth.token'],
|
||||
remove: true,
|
||||
},
|
||||
},
|
||||
pino
|
||||
);
|
||||
logger.info(
|
||||
{
|
||||
sensitiveData: 'this should be completely removed',
|
||||
auth: {
|
||||
token: 'auth-token-456',
|
||||
userId: 'user123',
|
||||
},
|
||||
normalData: 'this should remain',
|
||||
},
|
||||
'Processing request with sensitive data'
|
||||
);
|
||||
|
||||
const content = await readLogFile(file);
|
||||
const logEntry = JSON.parse(content);
|
||||
|
||||
expect(logEntry).not.toHaveProperty('sensitiveData');
|
||||
expect(logEntry.auth).not.toHaveProperty('token');
|
||||
expect(logEntry.auth.userId).toBe('user123');
|
||||
expect(logEntry.normalData).toBe('this should remain');
|
||||
});
|
||||
|
||||
test('should redact nested paths correctly', async () => {
|
||||
const file = await createLogFile();
|
||||
const logger = prepareSetup(
|
||||
{
|
||||
...defaultOptions,
|
||||
format: 'json',
|
||||
type: 'file',
|
||||
path: file,
|
||||
level: 'info',
|
||||
redact: {
|
||||
paths: ['user.password', 'request.headers.authorization', 'data[*].secret'],
|
||||
censor: '<REDACTED>',
|
||||
},
|
||||
},
|
||||
pino
|
||||
);
|
||||
logger.info(
|
||||
{
|
||||
user: {
|
||||
name: 'john',
|
||||
password: 'userpassword',
|
||||
email: 'john@example.com',
|
||||
},
|
||||
request: {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
authorization: 'Bearer token123',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
},
|
||||
data: [
|
||||
{ id: 1, secret: 'secret1', value: 'public1' },
|
||||
{ id: 2, secret: 'secret2', value: 'public2' },
|
||||
],
|
||||
},
|
||||
'Complex nested data processing'
|
||||
);
|
||||
|
||||
const content = await readLogFile(file);
|
||||
const logEntry = JSON.parse(content);
|
||||
|
||||
expect(logEntry.user.name).toBe('john');
|
||||
expect(logEntry.user.password).toBe('<REDACTED>');
|
||||
expect(logEntry.user.email).toBe('john@example.com');
|
||||
expect(logEntry.request.method).toBe('POST');
|
||||
expect(logEntry.request.headers.authorization).toBe('<REDACTED>');
|
||||
expect(logEntry.request.headers['content-type']).toBe('application/json');
|
||||
expect(logEntry.data[0].secret).toBe('<REDACTED>');
|
||||
expect(logEntry.data[0].value).toBe('public1');
|
||||
expect(logEntry.data[1].secret).toBe('<REDACTED>');
|
||||
expect(logEntry.data[1].value).toBe('public2');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @verdaccio/logger-prettify
|
||||
|
||||
## 8.0.0-next-8.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 08e1b21: chore(deps): built-in node imports
|
||||
|
||||
## 8.0.0-next-8.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/logger-prettify",
|
||||
"version": "8.0.0-next-8.3",
|
||||
"version": "8.0.0-next-8.4",
|
||||
"description": "Verdaccio Logger Prettify",
|
||||
"main": "./build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { green, red, white } from 'colorette';
|
||||
import { inspect } from 'util';
|
||||
import { inspect } from 'node:util';
|
||||
|
||||
import { LevelCode, calculateLevel, levelsColors, subSystemLevels } from './levels';
|
||||
import { PrettyOptionsExtended } from './types';
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# @verdaccio/logger
|
||||
|
||||
## 8.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @verdaccio/logger-commons@8.0.0-next-8.21
|
||||
|
||||
## 8.0.0-next-8.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a1a73e9]
|
||||
- @verdaccio/logger-commons@8.0.0-next-8.20
|
||||
|
||||
## 8.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/logger",
|
||||
"version": "8.0.0-next-8.19",
|
||||
"version": "8.0.0-next-8.21",
|
||||
"description": "Verdaccio Logger",
|
||||
"main": "./build/index.js",
|
||||
"types": "./build/index.d.ts",
|
||||
@@ -42,11 +42,11 @@
|
||||
"build": "pnpm run build:js && pnpm run build:types"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/logger-commons": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/logger-commons": "workspace:8.0.0-next-8.21",
|
||||
"pino": "9.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6"
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
# @verdaccio/middleware
|
||||
|
||||
## 8.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
- @verdaccio/config@8.0.0-next-8.21
|
||||
- @verdaccio/url@13.0.0-next-8.21
|
||||
|
||||
## 8.0.0-next-8.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 08e1b21: chore(deps): built-in node imports
|
||||
- Updated dependencies [08e1b21]
|
||||
- Updated dependencies [a1a73e9]
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- @verdaccio/config@8.0.0-next-8.20
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
- @verdaccio/url@13.0.0-next-8.20
|
||||
|
||||
## 8.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/middleware",
|
||||
"version": "8.0.0-next-8.19",
|
||||
"version": "8.0.0-next-8.21",
|
||||
"description": "Verdaccio Express Middleware",
|
||||
"main": "./build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -42,9 +42,9 @@
|
||||
"build": "pnpm run build:js && pnpm run build:types"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/url": "workspace:13.0.0-next-8.19",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/url": "workspace:13.0.0-next-8.21",
|
||||
"debug": "4.4.1",
|
||||
"express": "4.21.2",
|
||||
"express-rate-limit": "5.5.1",
|
||||
@@ -57,8 +57,8 @@
|
||||
"url": "https://opencollective.com/verdaccio"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7",
|
||||
"http-errors": "2.0.0",
|
||||
"supertest": "7.0.0",
|
||||
"jsdom": "26.1.0",
|
||||
|
||||
2
packages/middleware/types/custom.d.ts
vendored
2
packages/middleware/types/custom.d.ts
vendored
@@ -1,5 +1,5 @@
|
||||
// <reference types="node" />
|
||||
import * as http from 'http';
|
||||
import * as http from 'node:http';
|
||||
|
||||
import { Logger, RemoteUser } from '@verdaccio/types';
|
||||
|
||||
|
||||
@@ -1,5 +1,34 @@
|
||||
# @verdaccio/node-api
|
||||
|
||||
## 8.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
- @verdaccio/config@8.0.0-next-8.21
|
||||
- @verdaccio/server@8.0.0-next-8.21
|
||||
- @verdaccio/server-fastify@8.0.0-next-8.21
|
||||
- @verdaccio/logger@8.0.0-next-8.21
|
||||
|
||||
## 8.0.0-next-8.20
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 6a4d6dd: feat: getListenAddress getConfigParsed methods
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 08e1b21: chore(deps): built-in node imports
|
||||
- Updated dependencies [08e1b21]
|
||||
- Updated dependencies [a1a73e9]
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- @verdaccio/server-fastify@8.0.0-next-8.20
|
||||
- @verdaccio/config@8.0.0-next-8.20
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
- @verdaccio/server@8.0.0-next-8.20
|
||||
- @verdaccio/logger@8.0.0-next-8.20
|
||||
|
||||
## 8.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/node-api",
|
||||
"version": "8.0.0-next-8.19",
|
||||
"version": "8.0.0-next-8.21",
|
||||
"description": "Verdaccio Node API",
|
||||
"main": "build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -42,16 +42,16 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/server": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/server-fastify": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/server": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/server-fastify": "workspace:8.0.0-next-8.21",
|
||||
"debug": "4.4.1",
|
||||
"lodash": "4.17.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7",
|
||||
"selfsigned": "2.4.1",
|
||||
"supertest": "7.0.0",
|
||||
"vitest": "3.0.4"
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
import { warningUtils } from '@verdaccio/core';
|
||||
|
||||
export const DEFAULT_PORT = '4873';
|
||||
export const DEFAULT_PROTOCOL = 'http';
|
||||
export const DEFAULT_DOMAIN = 'localhost';
|
||||
/**
|
||||
* Parse an internet address
|
||||
* Allow:
|
||||
- https:localhost:1234 - protocol + host + port
|
||||
- localhost:1234 - host + port
|
||||
- 1234 - port
|
||||
- http::1234 - protocol + port
|
||||
- https://localhost:443/ - full url + https
|
||||
- http://[::1]:443/ - ipv6
|
||||
- unix:/tmp/http.sock - unix sockets
|
||||
- https://unix:/tmp/http.sock - unix sockets (https)
|
||||
* @param {*} urlAddress the internet address definition
|
||||
* @return {Object|Null} literal object that represent the address parsed
|
||||
*/
|
||||
export function parseAddress(urlAddress: any): any {
|
||||
//
|
||||
// TODO: refactor it to something more reasonable?
|
||||
//
|
||||
// protocol : // ( host )|( ipv6 ): port /
|
||||
let urlPattern = /^((https?):(\/\/)?)?((([^\/:]*)|\[([^\[\]]+)\]):)?(\d+)\/?$/.exec(urlAddress);
|
||||
|
||||
if (urlPattern) {
|
||||
return {
|
||||
proto: urlPattern[2] || DEFAULT_PROTOCOL,
|
||||
host: urlPattern[6] || urlPattern[7] || DEFAULT_DOMAIN,
|
||||
port: urlPattern[8] || DEFAULT_PORT,
|
||||
};
|
||||
}
|
||||
|
||||
urlPattern = /^((https?):(\/\/)?)?unix:(.*)$/.exec(urlAddress);
|
||||
|
||||
if (urlPattern) {
|
||||
return {
|
||||
proto: urlPattern[2] || DEFAULT_PROTOCOL,
|
||||
path: urlPattern[4],
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all addresses defined in the config file.
|
||||
* Verdaccio is able to listen multiple ports
|
||||
* @param {String} argListen
|
||||
* @param {String} configListen
|
||||
* eg:
|
||||
* listen:
|
||||
- localhost:5555
|
||||
- localhost:5557
|
||||
@return {Array}
|
||||
*/
|
||||
export function getListListenAddresses(argListen: string | void, configListen: any): any {
|
||||
// command line || config file || default
|
||||
let addresses;
|
||||
if (argListen) {
|
||||
addresses = [argListen];
|
||||
} else if (Array.isArray(configListen)) {
|
||||
addresses = configListen;
|
||||
process.emitWarning('multiple addresses will be deprecated in the next major, only use one');
|
||||
} else if (configListen) {
|
||||
addresses = [configListen];
|
||||
} else {
|
||||
addresses = [DEFAULT_PORT];
|
||||
}
|
||||
addresses = addresses
|
||||
.map(function (addr): string {
|
||||
const parsedAddr = parseAddress(addr);
|
||||
|
||||
if (!parsedAddr) {
|
||||
warningUtils.emit(warningUtils.Codes.VERWAR004, addr);
|
||||
}
|
||||
|
||||
return parsedAddr;
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
return addresses;
|
||||
}
|
||||
@@ -1,20 +1,19 @@
|
||||
/* eslint-disable */
|
||||
import constants from 'constants';
|
||||
import buildDebug from 'debug';
|
||||
import _, { assign, isFunction } from 'lodash';
|
||||
import constants from 'node:constants';
|
||||
import fs from 'node:fs';
|
||||
import http from 'node:http';
|
||||
import https from 'node:https';
|
||||
import url from 'node:url';
|
||||
|
||||
import { findConfigFile, parseConfigFile } from '@verdaccio/config';
|
||||
import { API_ERROR } from '@verdaccio/core';
|
||||
import { setup } from '@verdaccio/logger';
|
||||
import { getConfigParsed, getListenAddress } from '@verdaccio/config';
|
||||
import { DEFAULT_PORT } from '@verdaccio/core';
|
||||
import { logger, setup } from '@verdaccio/logger';
|
||||
import expressServer from '@verdaccio/server';
|
||||
import fastifyServer from '@verdaccio/server-fastify';
|
||||
import { ConfigYaml, HttpsConfKeyCert, HttpsConfPfx } from '@verdaccio/types';
|
||||
|
||||
import { getListListenAddresses } from './cli-utils';
|
||||
import { displayExperimentsInfoBox } from './experiments';
|
||||
|
||||
const debug = buildDebug('verdaccio:node-api');
|
||||
@@ -121,9 +120,9 @@ export async function initServer(
|
||||
pkgName: string
|
||||
): Promise<void> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
// FIXME: get only the first match, the multiple address will be removed
|
||||
const [addr] = getListListenAddresses(port, config.listen);
|
||||
const logger = setup(config?.log as any);
|
||||
const combined: string | undefined | any[] = [port, config?.listen, DEFAULT_PORT];
|
||||
const addr = getListenAddress(combined, logger);
|
||||
displayExperimentsInfoBox(config.flags);
|
||||
|
||||
let app;
|
||||
@@ -198,20 +197,12 @@ export async function initServer(
|
||||
* @param config
|
||||
*/
|
||||
export async function runServer(config?: string | ConfigYaml): Promise<any> {
|
||||
let configurationParsed: ConfigYaml;
|
||||
if (config === undefined || typeof config === 'string') {
|
||||
const configPathLocation = findConfigFile(config);
|
||||
configurationParsed = parseConfigFile(configPathLocation);
|
||||
} else if (_.isObject(config)) {
|
||||
configurationParsed = config;
|
||||
} else {
|
||||
throw new Error(API_ERROR.CONFIG_BAD_FORMAT);
|
||||
}
|
||||
|
||||
const configurationParsed = getConfigParsed(config);
|
||||
setup(configurationParsed.log as any);
|
||||
displayExperimentsInfoBox(configurationParsed.flags);
|
||||
// FIXME: get only the first match, the multiple address will be removed
|
||||
const [addr] = getListListenAddresses(undefined, configurationParsed.listen);
|
||||
const combined: string | undefined | any[] = [configurationParsed?.listen, DEFAULT_PORT];
|
||||
const addr = getListenAddress(combined, logger);
|
||||
const app = await expressServer(configurationParsed);
|
||||
return createServerFactory(configurationParsed, addr, app);
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
import _ from 'lodash';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import {
|
||||
DEFAULT_DOMAIN,
|
||||
DEFAULT_PORT,
|
||||
DEFAULT_PROTOCOL,
|
||||
getListListenAddresses,
|
||||
} from '../src/cli-utils';
|
||||
|
||||
describe('getListListenAddresses test', () => {
|
||||
test('should return no address if a single address is wrong', () => {
|
||||
// @ts-ignore
|
||||
const addrs = getListListenAddresses('wrong');
|
||||
|
||||
expect(_.isArray(addrs)).toBeTruthy();
|
||||
expect(addrs).toHaveLength(0);
|
||||
});
|
||||
|
||||
test('should return no address if a two address are wrong', () => {
|
||||
// @ts-ignore
|
||||
const addrs = getListListenAddresses(['wrong', 'same-wrong']);
|
||||
|
||||
expect(_.isArray(addrs)).toBeTruthy();
|
||||
expect(addrs).toHaveLength(0);
|
||||
});
|
||||
|
||||
test('should return a list of 1 address provided', () => {
|
||||
// @ts-ignore
|
||||
const addrs = getListListenAddresses(null, '1000');
|
||||
|
||||
expect(_.isArray(addrs)).toBeTruthy();
|
||||
expect(addrs).toHaveLength(1);
|
||||
});
|
||||
|
||||
test('should return a list of 2 address provided', () => {
|
||||
// @ts-ignore
|
||||
const addrs = getListListenAddresses(null, ['1000', '2000']);
|
||||
|
||||
expect(_.isArray(addrs)).toBeTruthy();
|
||||
expect(addrs).toHaveLength(2);
|
||||
});
|
||||
|
||||
test(`should return by default ${DEFAULT_PORT}`, () => {
|
||||
// @ts-ignore
|
||||
const [addrs] = getListListenAddresses();
|
||||
|
||||
// @ts-ignore
|
||||
expect(addrs.proto).toBe(DEFAULT_PROTOCOL);
|
||||
// @ts-ignore
|
||||
expect(addrs.host).toBe(DEFAULT_DOMAIN);
|
||||
// @ts-ignore
|
||||
expect(addrs.port).toBe(DEFAULT_PORT);
|
||||
});
|
||||
|
||||
test('should return default proto, host and custom port', () => {
|
||||
const initPort = '1000';
|
||||
// @ts-ignore
|
||||
const [addrs] = getListListenAddresses(null, initPort);
|
||||
|
||||
// @ts-ignore
|
||||
expect(addrs.proto).toEqual(DEFAULT_PROTOCOL);
|
||||
// @ts-ignore
|
||||
expect(addrs.host).toEqual(DEFAULT_DOMAIN);
|
||||
// @ts-ignore
|
||||
expect(addrs.port).toEqual(initPort);
|
||||
});
|
||||
});
|
||||
@@ -1,52 +0,0 @@
|
||||
import _ from 'lodash';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import { DEFAULT_DOMAIN, DEFAULT_PORT, parseAddress } from '../src/cli-utils';
|
||||
|
||||
describe('Parse listen address', () => {
|
||||
const useCases: any[] = [];
|
||||
|
||||
function addTest(uri: string, proto: string | null, host?: string, port?: string) {
|
||||
useCases.push([uri, proto, host, port]);
|
||||
}
|
||||
|
||||
addTest(DEFAULT_PORT, 'http', DEFAULT_DOMAIN, DEFAULT_PORT);
|
||||
addTest(':4873', 'http', DEFAULT_DOMAIN, DEFAULT_PORT);
|
||||
addTest('blah:4873', 'http', 'blah', DEFAULT_PORT);
|
||||
addTest('http://:4873', 'http', DEFAULT_DOMAIN, DEFAULT_PORT);
|
||||
addTest('https::4873', 'https', DEFAULT_DOMAIN, DEFAULT_PORT);
|
||||
addTest('https:blah:4873', 'https', 'blah', DEFAULT_PORT);
|
||||
addTest('https://blah:4873/', 'https', 'blah', DEFAULT_PORT);
|
||||
addTest('[::1]:4873', 'http', '::1', DEFAULT_PORT);
|
||||
addTest('https:[::1]:4873', 'https', '::1', DEFAULT_PORT);
|
||||
|
||||
addTest('unix:/tmp/foo.sock', 'http', '/tmp/foo.sock');
|
||||
addTest('http:unix:foo.sock', 'http', 'foo.sock');
|
||||
addTest('https://unix:foo.sock', 'https', 'foo.sock');
|
||||
addTest('https://unix:foo.sock:34', 'https', 'foo.sock:34');
|
||||
addTest('http://foo.sock:34', 'http', 'foo.sock', '34');
|
||||
|
||||
addTest('blah', null);
|
||||
addTest('blah://4873', null);
|
||||
addTest('https://blah:4873///', null);
|
||||
addTest('unix:1234', 'http', 'unix', '1234'); // not unix socket
|
||||
|
||||
test.each(useCases)(`should parse (%s - %s - %s - %s)`, (uri, proto, host, port) => {
|
||||
const parsed = parseAddress(uri);
|
||||
|
||||
if (_.isNull(proto)) {
|
||||
expect(parsed).toBeNull();
|
||||
} else if (port) {
|
||||
expect(parsed).toEqual({
|
||||
proto,
|
||||
host,
|
||||
port,
|
||||
});
|
||||
} else {
|
||||
expect(parsed).toEqual({
|
||||
proto,
|
||||
path: host,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,23 @@
|
||||
# Change Log
|
||||
|
||||
## 13.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
- @verdaccio/config@8.0.0-next-8.21
|
||||
|
||||
## 13.0.0-next-8.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [08e1b21]
|
||||
- Updated dependencies [a1a73e9]
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- @verdaccio/config@8.0.0-next-8.20
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
|
||||
## 13.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "verdaccio-audit",
|
||||
"version": "13.0.0-next-8.19",
|
||||
"version": "13.0.0-next-8.21",
|
||||
"description": "Verdaccio Middleware plugin to bypass npmjs audit",
|
||||
"keywords": [
|
||||
"private",
|
||||
@@ -30,16 +30,16 @@
|
||||
"node": ">=18"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"express": "4.21.2",
|
||||
"https-proxy-agent": "5.0.1",
|
||||
"node-fetch": "cjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/auth": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6",
|
||||
"@verdaccio/auth": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7",
|
||||
"nock": "13.5.6",
|
||||
"supertest": "7.0.0",
|
||||
"vitest": "3.0.4"
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# Change Log
|
||||
|
||||
## 13.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
|
||||
## 13.0.0-next-8.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
|
||||
## 13.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "verdaccio-auth-memory",
|
||||
"version": "13.0.0-next-8.19",
|
||||
"version": "13.0.0-next-8.21",
|
||||
"description": "Auth plugin for Verdaccio that keeps users in memory",
|
||||
"keywords": [
|
||||
"private",
|
||||
@@ -30,13 +30,13 @@
|
||||
"node": ">=18"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"debug": "4.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/debug": "^4.1.12",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6"
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf ./build",
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# Change Log
|
||||
|
||||
## 13.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
|
||||
## 13.0.0-next-8.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [08e1b21]
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- @verdaccio/file-locking@13.0.0-next-8.5
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
|
||||
## 13.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "verdaccio-htpasswd",
|
||||
"version": "13.0.0-next-8.19",
|
||||
"version": "13.0.0-next-8.21",
|
||||
"description": "Htpasswd Authentication Plugin for Verdaccio",
|
||||
"keywords": [
|
||||
"private",
|
||||
@@ -33,8 +33,8 @@
|
||||
"node": ">=18"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/file-locking": "workspace:13.0.0-next-8.4",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/file-locking": "workspace:13.0.0-next-8.5",
|
||||
"apache-md5": "1.1.8",
|
||||
"bcryptjs": "2.4.3",
|
||||
"http-errors": "2.0.0",
|
||||
@@ -43,8 +43,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bcryptjs": "2.4.6",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.21",
|
||||
"mockdate": "3.0.5",
|
||||
"vitest": "3.0.4"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# Change Log
|
||||
|
||||
## 13.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
- @verdaccio/utils@8.1.0-next-8.21
|
||||
|
||||
## 13.0.0-next-8.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [08e1b21]
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- @verdaccio/file-locking@13.0.0-next-8.5
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
- @verdaccio/utils@8.1.0-next-8.20
|
||||
|
||||
## 13.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/local-storage",
|
||||
"version": "13.0.0-next-8.19",
|
||||
"version": "13.0.0-next-8.21",
|
||||
"description": "Verdaccio Local Storage Plugin",
|
||||
"keywords": [
|
||||
"private",
|
||||
@@ -36,9 +36,9 @@
|
||||
"node": ">=18"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/file-locking": "workspace:13.0.0-next-8.4",
|
||||
"@verdaccio/utils": "workspace:8.1.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/file-locking": "workspace:13.0.0-next-8.5",
|
||||
"@verdaccio/utils": "workspace:8.1.0-next-8.21",
|
||||
"debug": "4.4.1",
|
||||
"globby": "11.1.0",
|
||||
"lodash": "4.17.21",
|
||||
@@ -46,8 +46,8 @@
|
||||
"sanitize-filename": "1.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7",
|
||||
"vitest": "3.0.4"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# Change Log
|
||||
|
||||
## 13.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
|
||||
## 13.0.0-next-8.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
|
||||
## 13.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "verdaccio-memory",
|
||||
"version": "13.0.0-next-8.19",
|
||||
"version": "13.0.0-next-8.21",
|
||||
"description": "Verdaccio Memory Storage Plugin",
|
||||
"keywords": [
|
||||
"private",
|
||||
@@ -30,14 +30,14 @@
|
||||
"node": ">=18"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.21",
|
||||
"debug": "4.4.1",
|
||||
"memfs": "3.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.6",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.19",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.7",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.21",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.21",
|
||||
"vitest": "3.0.4"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @verdaccio/ui-theme
|
||||
|
||||
## 8.0.0-next-8.21
|
||||
|
||||
## 8.0.0-next-8.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 08e1b21: chore(deps): built-in node imports
|
||||
|
||||
## 8.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/ui-theme",
|
||||
"version": "8.0.0-next-8.19",
|
||||
"version": "8.0.0-next-8.21",
|
||||
"description": "Verdaccio User Interface (Theme)",
|
||||
"author": {
|
||||
"name": "Verdaccio Contributors",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
/**
|
||||
* A module to get package informations from package.json
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import FriendlyErrorsPlugin from 'friendly-errors-webpack-plugin';
|
||||
import fs from 'fs';
|
||||
import HTMLWebpackPlugin from 'html-webpack-plugin';
|
||||
import yaml from 'js-yaml';
|
||||
import fs from 'node:fs';
|
||||
import StyleLintPlugin from 'stylelint-webpack-plugin';
|
||||
import webpack from 'webpack';
|
||||
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
# @verdaccio/proxy
|
||||
|
||||
## 8.0.0-next-8.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f8a321f]
|
||||
- @verdaccio/core@8.0.0-next-8.21
|
||||
- @verdaccio/config@8.0.0-next-8.21
|
||||
|
||||
## 8.0.0-next-8.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 08e1b21: chore(deps): built-in node imports
|
||||
- d92ba65: chore(proxy): update tests
|
||||
- Updated dependencies [08e1b21]
|
||||
- Updated dependencies [a1a73e9]
|
||||
- Updated dependencies [6a4d6dd]
|
||||
- @verdaccio/config@8.0.0-next-8.20
|
||||
- @verdaccio/core@8.0.0-next-8.20
|
||||
|
||||
## 8.0.0-next-8.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user