@verdaccio/core 8.0.0-next-8.11 → 8.0.0-next-8.13
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/LICENSE +1 -1
- package/README.md +73 -12
- package/build/constants.d.ts +3 -0
- package/build/constants.js +6 -1
- package/build/constants.js.map +1 -1
- package/build/plugin-utils.d.ts +2 -2
- package/build/plugin-utils.js.map +1 -1
- package/package.json +3 -3
- package/.babelrc +0 -14
- package/.eslintignore +0 -6
- package/.eslintrc.json +0 -5
- package/CHANGELOG.md +0 -565
- package/src/constants.ts +0 -134
- package/src/error-utils.ts +0 -106
- package/src/file-utils.ts +0 -31
- package/src/index.ts +0 -46
- package/src/path-utils.ts +0 -0
- package/src/pkg-utils.ts +0 -68
- package/src/plugin-utils.ts +0 -205
- package/src/schemes/publish-manifest.ts +0 -38
- package/src/schemes/unpublish-manifest.ts +0 -69
- package/src/search-utils.ts +0 -81
- package/src/stream-utils.ts +0 -28
- package/src/string-utils.ts +0 -36
- package/src/tarball-utils.ts +0 -43
- package/src/validation-utils.ts +0 -128
- package/src/warning-utils.ts +0 -69
- package/test/errors.spec.ts +0 -109
- package/test/merge.dist.tags.spec.ts +0 -64
- package/test/mystreams.spec.ts +0 -18
- package/test/pkg-utils.spec.ts +0 -28
- package/test/publish-manifest.spec.ts +0 -61
- package/test/string-utils.spec.ts +0 -42
- package/test/tarball-utils.spec.ts +0 -81
- package/test/unpublish-manifest.spec.ts +0 -71
- package/test/validation-utilts.spec.ts +0 -182
- package/tsconfig.build.json +0 -10
- package/tsconfig.json +0 -12
- package/typedoc.json +0 -5
package/src/error-utils.ts
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import createError, { HttpError } from 'http-errors';
|
|
2
|
-
|
|
3
|
-
import { HTTP_STATUS } from './constants';
|
|
4
|
-
|
|
5
|
-
export const API_ERROR = {
|
|
6
|
-
PASSWORD_SHORT: 'The provided password does not pass the validation',
|
|
7
|
-
MUST_BE_LOGGED: 'You must be logged in to publish packages.',
|
|
8
|
-
PLUGIN_ERROR: 'bug in the auth plugin system',
|
|
9
|
-
CONFIG_BAD_FORMAT: 'config file must be an object',
|
|
10
|
-
BAD_USERNAME_PASSWORD: 'bad username/password, access denied',
|
|
11
|
-
NO_PACKAGE: 'no such package available',
|
|
12
|
-
PACKAGE_CANNOT_BE_ADDED: 'this package cannot be added',
|
|
13
|
-
BAD_DATA: 'bad data',
|
|
14
|
-
NOT_ALLOWED: 'not allowed to access package',
|
|
15
|
-
NOT_ALLOWED_PUBLISH: 'not allowed to publish package',
|
|
16
|
-
INTERNAL_SERVER_ERROR: 'internal server error',
|
|
17
|
-
UNKNOWN_ERROR: 'unknown error',
|
|
18
|
-
NOT_PACKAGE_UPLINK: 'package does not exist on uplink',
|
|
19
|
-
UPLINK_OFFLINE_PUBLISH: 'one of the uplinks is down, refuse to publish',
|
|
20
|
-
UPLINK_OFFLINE: 'uplink is offline',
|
|
21
|
-
NOT_MODIFIED_NO_DATA: 'no data',
|
|
22
|
-
CONTENT_MISMATCH: 'content length mismatch',
|
|
23
|
-
NOT_FILE_UPLINK: "file doesn't exist on uplink",
|
|
24
|
-
MAX_USERS_REACHED: 'maximum amount of users reached',
|
|
25
|
-
VERSION_NOT_EXIST: "this version doesn't exist",
|
|
26
|
-
NO_SUCH_FILE: 'no such file available',
|
|
27
|
-
UNSUPORTED_REGISTRY_CALL: 'unsupported registry call',
|
|
28
|
-
FILE_NOT_FOUND: 'File not found',
|
|
29
|
-
REGISTRATION_DISABLED: 'user registration disabled',
|
|
30
|
-
UNAUTHORIZED_ACCESS: 'unauthorized access',
|
|
31
|
-
BAD_STATUS_CODE: 'bad status code',
|
|
32
|
-
SERVER_TIME_OUT: 'looks like the server is taking to long to respond',
|
|
33
|
-
PACKAGE_EXIST: 'this package is already present',
|
|
34
|
-
BAD_AUTH_HEADER: 'bad authorization header',
|
|
35
|
-
WEB_DISABLED: 'Web interface is disabled in the config file',
|
|
36
|
-
DEPRECATED_BASIC_HEADER: 'basic authentication is deprecated, please use JWT instead',
|
|
37
|
-
BAD_FORMAT_USER_GROUP: 'user groups is different than an array',
|
|
38
|
-
RESOURCE_UNAVAILABLE: 'resource unavailable',
|
|
39
|
-
BAD_PACKAGE_DATA: 'bad incoming package data',
|
|
40
|
-
USERNAME_PASSWORD_REQUIRED: 'username and password is required',
|
|
41
|
-
USERNAME_ALREADY_REGISTERED: 'username is already registered',
|
|
42
|
-
USERNAME_MISMATCH: 'username does not match logged in user',
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export const SUPPORT_ERRORS = {
|
|
46
|
-
PLUGIN_MISSING_INTERFACE: 'the plugin does not provide implementation of the requested feature',
|
|
47
|
-
TFA_DISABLED: 'the two-factor authentication is not yet supported',
|
|
48
|
-
STORAGE_NOT_IMPLEMENT: 'the storage does not support token saving',
|
|
49
|
-
PARAMETERS_NOT_VALID: 'the parameters are not valid',
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export const APP_ERROR = {
|
|
53
|
-
CONFIG_NOT_VALID: 'CONFIG: it does not look like a valid config file',
|
|
54
|
-
PROFILE_ERROR: 'profile unexpected error',
|
|
55
|
-
PASSWORD_VALIDATION: 'not valid password',
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
export type VerdaccioError = HttpError & { code: number };
|
|
59
|
-
|
|
60
|
-
function getError(code: number, message: string): VerdaccioError {
|
|
61
|
-
const httpError = createError(code, message);
|
|
62
|
-
|
|
63
|
-
httpError.code = code;
|
|
64
|
-
|
|
65
|
-
return httpError as VerdaccioError;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export function getConflict(message: string = API_ERROR.PACKAGE_EXIST): VerdaccioError {
|
|
69
|
-
return getError(HTTP_STATUS.CONFLICT, message);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export function getBadData(customMessage?: string): VerdaccioError {
|
|
73
|
-
return getError(HTTP_STATUS.BAD_DATA, customMessage || API_ERROR.BAD_DATA);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export function getBadRequest(customMessage: string): VerdaccioError {
|
|
77
|
-
return getError(HTTP_STATUS.BAD_REQUEST, customMessage);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export function getInternalError(customMessage?: string): VerdaccioError {
|
|
81
|
-
return customMessage
|
|
82
|
-
? getError(HTTP_STATUS.INTERNAL_ERROR, customMessage)
|
|
83
|
-
: getError(HTTP_STATUS.INTERNAL_ERROR, API_ERROR.UNKNOWN_ERROR);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function getUnauthorized(message = 'no credentials provided'): VerdaccioError {
|
|
87
|
-
return getError(HTTP_STATUS.UNAUTHORIZED, message);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function getForbidden(message = "can't use this filename"): VerdaccioError {
|
|
91
|
-
return getError(HTTP_STATUS.FORBIDDEN, message);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export function getServiceUnavailable(
|
|
95
|
-
message: string = API_ERROR.RESOURCE_UNAVAILABLE
|
|
96
|
-
): VerdaccioError {
|
|
97
|
-
return getError(HTTP_STATUS.SERVICE_UNAVAILABLE, message);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function getNotFound(customMessage?: string): VerdaccioError {
|
|
101
|
-
return getError(HTTP_STATUS.NOT_FOUND, customMessage || API_ERROR.NO_PACKAGE);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export function getCode(statusCode: number, customMessage: string): VerdaccioError {
|
|
105
|
-
return getError(statusCode, customMessage);
|
|
106
|
-
}
|
package/src/file-utils.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import os from 'os';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
|
|
5
|
-
export const Files = {
|
|
6
|
-
DatabaseName: '.verdaccio-db.json',
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
const { mkdir, mkdtemp } = fs.promises ? fs.promises : require('fs/promises');
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Create a temporary folder.
|
|
13
|
-
* @param prefix The prefix of the folder name.
|
|
14
|
-
* @returns string
|
|
15
|
-
*/
|
|
16
|
-
export async function createTempFolder(prefix: string): Promise<string> {
|
|
17
|
-
return await mkdtemp(path.join(os.tmpdir(), 'verdaccio-' + prefix + '-'));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Create temporary folder for an asset.
|
|
22
|
-
* @param prefix
|
|
23
|
-
* @param folder name
|
|
24
|
-
* @returns
|
|
25
|
-
*/
|
|
26
|
-
export async function createTempStorageFolder(prefix: string, folder = 'storage'): Promise<string> {
|
|
27
|
-
const tempFolder = await createTempFolder(prefix);
|
|
28
|
-
const storageFolder = path.join(tempFolder, folder);
|
|
29
|
-
await mkdir(storageFolder);
|
|
30
|
-
return storageFolder;
|
|
31
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import * as constants from './constants';
|
|
2
|
-
import * as errorUtils from './error-utils';
|
|
3
|
-
import * as fileUtils from './file-utils';
|
|
4
|
-
import * as pkgUtils from './pkg-utils';
|
|
5
|
-
import * as pluginUtils from './plugin-utils';
|
|
6
|
-
import * as searchUtils from './search-utils';
|
|
7
|
-
import * as streamUtils from './stream-utils';
|
|
8
|
-
import * as stringUtils from './string-utils';
|
|
9
|
-
import * as tarballUtils from './tarball-utils';
|
|
10
|
-
import * as validatioUtils from './validation-utils';
|
|
11
|
-
import * as warningUtils from './warning-utils';
|
|
12
|
-
|
|
13
|
-
export { VerdaccioError, API_ERROR, SUPPORT_ERRORS, APP_ERROR } from './error-utils';
|
|
14
|
-
export {
|
|
15
|
-
TOKEN_BASIC,
|
|
16
|
-
TOKEN_BEARER,
|
|
17
|
-
HTTP_STATUS,
|
|
18
|
-
API_MESSAGE,
|
|
19
|
-
HEADERS,
|
|
20
|
-
DIST_TAGS,
|
|
21
|
-
CHARACTER_ENCODING,
|
|
22
|
-
HEADER_TYPE,
|
|
23
|
-
LATEST,
|
|
24
|
-
DEFAULT_PASSWORD_VALIDATION,
|
|
25
|
-
DEFAULT_USER,
|
|
26
|
-
USERS,
|
|
27
|
-
MAINTAINERS,
|
|
28
|
-
PLUGIN_CATEGORY,
|
|
29
|
-
HtpasswdHashAlgorithm,
|
|
30
|
-
} from './constants';
|
|
31
|
-
const validationUtils = validatioUtils;
|
|
32
|
-
export {
|
|
33
|
-
fileUtils,
|
|
34
|
-
pkgUtils,
|
|
35
|
-
searchUtils,
|
|
36
|
-
streamUtils,
|
|
37
|
-
errorUtils,
|
|
38
|
-
// TODO: remove this typo
|
|
39
|
-
validatioUtils,
|
|
40
|
-
validationUtils,
|
|
41
|
-
stringUtils,
|
|
42
|
-
constants,
|
|
43
|
-
pluginUtils,
|
|
44
|
-
warningUtils,
|
|
45
|
-
tarballUtils,
|
|
46
|
-
};
|
package/src/path-utils.ts
DELETED
|
File without changes
|
package/src/pkg-utils.ts
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import semver from 'semver';
|
|
2
|
-
|
|
3
|
-
import { Manifest } from '@verdaccio/types';
|
|
4
|
-
|
|
5
|
-
import { DIST_TAGS } from './constants';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Function filters out bad semver versions and sorts the array.
|
|
9
|
-
* @return {Array} sorted Array
|
|
10
|
-
*/
|
|
11
|
-
export function semverSort(listVersions: string[]): string[] {
|
|
12
|
-
return listVersions
|
|
13
|
-
.filter(function (x): boolean {
|
|
14
|
-
if (!semver.parse(x, true)) {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
return true;
|
|
18
|
-
})
|
|
19
|
-
.sort(semver.compareLoose)
|
|
20
|
-
.map(String);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Get the latest publihsed version of a package.
|
|
25
|
-
* @param package metadata
|
|
26
|
-
**/
|
|
27
|
-
export function getLatest(pkg: Manifest): string {
|
|
28
|
-
const listVersions: string[] = Object.keys(pkg.versions);
|
|
29
|
-
if (listVersions.length < 1) {
|
|
30
|
-
throw Error('cannot get lastest version of none');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const versions: string[] = semverSort(listVersions);
|
|
34
|
-
const latest: string | undefined = pkg[DIST_TAGS]?.latest ? pkg[DIST_TAGS].latest : versions[0];
|
|
35
|
-
|
|
36
|
-
return latest;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Function gets a local info and an info from uplinks and tries to merge it
|
|
41
|
-
exported for unit tests only.
|
|
42
|
-
* @param {*} local
|
|
43
|
-
* @param {*} upstream
|
|
44
|
-
* @param {*} config sds
|
|
45
|
-
* @deprecated use @verdaccio/storage mergeVersions method
|
|
46
|
-
*/
|
|
47
|
-
// @deprecated
|
|
48
|
-
export function mergeVersions(local: Manifest, upstream: Manifest) {
|
|
49
|
-
// copy new versions to a cache
|
|
50
|
-
// NOTE: if a certain version was updated, we can't refresh it reliably
|
|
51
|
-
for (const i in upstream.versions) {
|
|
52
|
-
if (typeof local.versions[i] === 'undefined') {
|
|
53
|
-
local.versions[i] = upstream.versions[i];
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
for (const i in upstream[DIST_TAGS]) {
|
|
58
|
-
if (local[DIST_TAGS][i] !== upstream[DIST_TAGS][i]) {
|
|
59
|
-
if (!local[DIST_TAGS][i] || semver.lte(local[DIST_TAGS][i], upstream[DIST_TAGS][i])) {
|
|
60
|
-
local[DIST_TAGS][i] = upstream[DIST_TAGS][i];
|
|
61
|
-
}
|
|
62
|
-
if (i === 'latest' && local[DIST_TAGS][i] === upstream[DIST_TAGS][i]) {
|
|
63
|
-
// if remote has more fresh package, we should borrow its readme
|
|
64
|
-
local.readme = upstream.readme;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
package/src/plugin-utils.ts
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import { Express, RequestHandler } from 'express';
|
|
2
|
-
import { Readable, Writable } from 'stream';
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
AllowAccess,
|
|
6
|
-
Callback,
|
|
7
|
-
Config,
|
|
8
|
-
Logger,
|
|
9
|
-
Manifest,
|
|
10
|
-
PackageAccess,
|
|
11
|
-
RemoteUser,
|
|
12
|
-
Token,
|
|
13
|
-
TokenFilter,
|
|
14
|
-
} from '@verdaccio/types';
|
|
15
|
-
|
|
16
|
-
import { VerdaccioError, searchUtils } from '.';
|
|
17
|
-
|
|
18
|
-
export interface PluginOptions {
|
|
19
|
-
config: Config;
|
|
20
|
-
logger: Logger;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Base Plugin Class
|
|
25
|
-
*
|
|
26
|
-
* Set of utilities for developing plugins.
|
|
27
|
-
*/
|
|
28
|
-
export class Plugin<PluginConfig> {
|
|
29
|
-
static version = 1;
|
|
30
|
-
public readonly version: number;
|
|
31
|
-
public readonly config: PluginConfig | unknown;
|
|
32
|
-
public readonly options: PluginOptions;
|
|
33
|
-
public constructor(config: PluginConfig, options: PluginOptions) {
|
|
34
|
-
this.version = Plugin.version;
|
|
35
|
-
this.config = config;
|
|
36
|
-
this.options = options;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
public getVersion() {
|
|
40
|
-
return this.version;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// --- STORAGE PLUGIN ---
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Storage Handler
|
|
48
|
-
*
|
|
49
|
-
* Used in storage plugin for managing packages and tarballs.
|
|
50
|
-
*/
|
|
51
|
-
export interface StorageHandler {
|
|
52
|
-
logger: Logger;
|
|
53
|
-
deletePackage(fileName: string): Promise<void>;
|
|
54
|
-
removePackage(): Promise<void>;
|
|
55
|
-
// next packages migration (this list is meant to replace the callback parent functions)
|
|
56
|
-
updatePackage(
|
|
57
|
-
packageName: string,
|
|
58
|
-
handleUpdate: (manifest: Manifest) => Promise<Manifest>
|
|
59
|
-
): Promise<Manifest>;
|
|
60
|
-
readPackage(packageName: string): Promise<Manifest>;
|
|
61
|
-
savePackage(packageName: string, manifest: Manifest): Promise<void>;
|
|
62
|
-
readTarball(fileName: string, { signal }: { signal: AbortSignal }): Promise<Readable>;
|
|
63
|
-
createPackage(packageName: string, manifest: Manifest): Promise<void>;
|
|
64
|
-
writeTarball(fileName: string, { signal }: { signal: AbortSignal }): Promise<Writable>;
|
|
65
|
-
// verify if tarball exist in the storage
|
|
66
|
-
hasTarball(fileName: string): Promise<boolean>;
|
|
67
|
-
// verify if package exist in the storage
|
|
68
|
-
hasPackage(): Promise<boolean>;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Storage Plugin interface
|
|
73
|
-
*
|
|
74
|
-
* https://verdaccio.org/docs/next/plugin-storage
|
|
75
|
-
*/
|
|
76
|
-
export interface Storage<PluginConfig> extends Plugin<PluginConfig> {
|
|
77
|
-
add(packageName: string): Promise<void>;
|
|
78
|
-
remove(packageName: string): Promise<void>;
|
|
79
|
-
get(): Promise<string[]>;
|
|
80
|
-
init(): Promise<void>;
|
|
81
|
-
getSecret(): Promise<string>;
|
|
82
|
-
setSecret(secret: string): Promise<any>;
|
|
83
|
-
getPackageStorage(packageName: string): StorageHandler;
|
|
84
|
-
search(query: searchUtils.SearchQuery): Promise<searchUtils.SearchItem[]>;
|
|
85
|
-
saveToken(token: Token): Promise<any>;
|
|
86
|
-
deleteToken(user: string, tokenKey: string): Promise<any>;
|
|
87
|
-
readTokens(filter: TokenFilter): Promise<Token[]>;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// --- MIDDLEWARE PLUGIN ---
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Middleware Plugin Interface
|
|
94
|
-
*
|
|
95
|
-
* https://verdaccio.org/docs/next/plugin-middleware
|
|
96
|
-
*
|
|
97
|
-
* This function allow add middleware to the application.
|
|
98
|
-
*
|
|
99
|
-
* ```ts
|
|
100
|
-
* import express, { Request, Response } from 'express';
|
|
101
|
-
*
|
|
102
|
-
* class Middleware extends Plugin {
|
|
103
|
-
* // instances of auth and storage are injected
|
|
104
|
-
* register_middlewares(app, auth, storage) {
|
|
105
|
-
* const router = express.Router();
|
|
106
|
-
* router.post('/my-endpoint', (req: Request, res: Response): void => {
|
|
107
|
-
res.status(200).end();
|
|
108
|
-
});
|
|
109
|
-
* }
|
|
110
|
-
* }
|
|
111
|
-
*
|
|
112
|
-
* const [plugin] = await asyncLoadPlugin(...);
|
|
113
|
-
* plugin.register_middlewares(app, auth, storage);
|
|
114
|
-
* ```
|
|
115
|
-
*/
|
|
116
|
-
export interface ExpressMiddleware<PluginConfig, Storage, Auth> extends Plugin<PluginConfig> {
|
|
117
|
-
register_middlewares(app: Express, auth: Auth, storage: Storage): void;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// --- AUTH PLUGIN ---
|
|
121
|
-
|
|
122
|
-
export type AuthCallback = (error: VerdaccioError | null, groups?: string[] | false) => void;
|
|
123
|
-
|
|
124
|
-
export type AuthAccessCallback = (error: VerdaccioError | null, access?: boolean) => void;
|
|
125
|
-
export type AuthUserCallback = (error: VerdaccioError | null, access?: boolean | string) => void;
|
|
126
|
-
export type AuthChangePasswordCallback = (error: VerdaccioError | null, access?: boolean) => void;
|
|
127
|
-
export type AccessCallback = (error: VerdaccioError | null, ok?: boolean) => void;
|
|
128
|
-
|
|
129
|
-
export interface AuthPluginPackage {
|
|
130
|
-
packageName: string;
|
|
131
|
-
packageVersion?: string;
|
|
132
|
-
tag?: string;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Authentication Plugin Interface
|
|
137
|
-
*
|
|
138
|
-
* https://verdaccio.org/docs/next/plugin-auth
|
|
139
|
-
*/
|
|
140
|
-
export interface Auth<T> extends Plugin<T> {
|
|
141
|
-
/**
|
|
142
|
-
* Handles the authenticated method.
|
|
143
|
-
* ```ts
|
|
144
|
-
* class Auth {
|
|
145
|
-
public authenticate(user: string, password: string, done: AuthCallback): void {
|
|
146
|
-
if (!password) {
|
|
147
|
-
return done(errorUtils.getUnauthorized(API_ERROR.BAD_USERNAME_PASSWORD));
|
|
148
|
-
}
|
|
149
|
-
// always return an array of users
|
|
150
|
-
return done(null, [user]);
|
|
151
|
-
* }
|
|
152
|
-
* ```
|
|
153
|
-
*/
|
|
154
|
-
authenticate(user: string, password: string, cb: AuthCallback): void;
|
|
155
|
-
/**
|
|
156
|
-
* Handles the authenticated method.
|
|
157
|
-
* ```ts
|
|
158
|
-
* class Auth {
|
|
159
|
-
public adduser(user: string, password: string, done: AuthCallback): void {
|
|
160
|
-
if (!password) {
|
|
161
|
-
return done(errorUtils.getUnauthorized(API_ERROR.BAD_USERNAME_PASSWORD));
|
|
162
|
-
}
|
|
163
|
-
// return boolean
|
|
164
|
-
return done(null, true);
|
|
165
|
-
* }
|
|
166
|
-
* ```
|
|
167
|
-
*/
|
|
168
|
-
adduser?(user: string, password: string, cb: AuthUserCallback): void;
|
|
169
|
-
changePassword?(
|
|
170
|
-
user: string,
|
|
171
|
-
password: string,
|
|
172
|
-
newPassword: string,
|
|
173
|
-
cb: AuthChangePasswordCallback
|
|
174
|
-
): void;
|
|
175
|
-
allow_publish?(user: RemoteUser, pkg: T & PackageAccess, cb: AuthAccessCallback): void;
|
|
176
|
-
allow_publish?(user: RemoteUser, pkg: AllowAccess & PackageAccess, cb: AuthAccessCallback): void;
|
|
177
|
-
allow_access?(user: RemoteUser, pkg: T & PackageAccess, cb: AccessCallback): void;
|
|
178
|
-
allow_access?(user: RemoteUser, pkg: AllowAccess & PackageAccess, cb: AccessCallback): void;
|
|
179
|
-
allow_unpublish?(user: RemoteUser, pkg: T & PackageAccess, cb: AuthAccessCallback): void;
|
|
180
|
-
allow_unpublish?(
|
|
181
|
-
user: RemoteUser,
|
|
182
|
-
pkg: AllowAccess & PackageAccess,
|
|
183
|
-
cb: AuthAccessCallback
|
|
184
|
-
): void;
|
|
185
|
-
apiJWTmiddleware?(helpers: any): RequestHandler;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
export interface IBasicAuth {
|
|
189
|
-
authenticate(user: string, password: string, cb: Callback): void;
|
|
190
|
-
invalidateToken?(token: string): Promise<void>;
|
|
191
|
-
changePassword(user: string, password: string, newPassword: string, cb: Callback): void;
|
|
192
|
-
allow_access(pkg: AuthPluginPackage, user: RemoteUser, callback: Callback): void;
|
|
193
|
-
add_user(user: string, password: string, cb: Callback): any;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// --- FILTER PLUGIN ---
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Filter Plugin Interface
|
|
200
|
-
*
|
|
201
|
-
* https://verdaccio.org/docs/next/plugin-filter
|
|
202
|
-
*/
|
|
203
|
-
export interface ManifestFilter<T> extends Plugin<T> {
|
|
204
|
-
filter_metadata(manifest: Manifest): Promise<Manifest>;
|
|
205
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import Ajv, { JSONSchemaType } from 'ajv';
|
|
2
|
-
|
|
3
|
-
const ajv = new Ajv();
|
|
4
|
-
|
|
5
|
-
// FIXME: this could extend from @verdaccio/types but we need
|
|
6
|
-
// schemas from @verdaccio/types to be able to validate them
|
|
7
|
-
interface Manifest {
|
|
8
|
-
name: string;
|
|
9
|
-
versions: object;
|
|
10
|
-
_attachments: object;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const schema: JSONSchemaType<Manifest> = {
|
|
14
|
-
type: 'object',
|
|
15
|
-
properties: {
|
|
16
|
-
name: { type: 'string' },
|
|
17
|
-
versions: { type: 'object', maxProperties: 1 },
|
|
18
|
-
_attachments: { type: 'object', maxProperties: 1 },
|
|
19
|
-
},
|
|
20
|
-
required: ['name', 'versions', '_attachments'],
|
|
21
|
-
additionalProperties: true,
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
// validate is a type guard for MyData - type is inferred from schema type
|
|
25
|
-
const validate = ajv.compile(schema);
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Validate if a manifest has the correct structure when a new package
|
|
29
|
-
* is being created. The properties name, versions and _attachments must contain 1 element.
|
|
30
|
-
* @param data a manifest object
|
|
31
|
-
* @returns boolean
|
|
32
|
-
*/
|
|
33
|
-
export function validatePublishSingleVersion(manifest: any) {
|
|
34
|
-
if (!manifest) {
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
return validate(manifest);
|
|
38
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import Ajv, { JSONSchemaType } from 'ajv';
|
|
2
|
-
|
|
3
|
-
const ajv = new Ajv();
|
|
4
|
-
|
|
5
|
-
interface Manifest {
|
|
6
|
-
name: string;
|
|
7
|
-
versions: Record<string, unknown>;
|
|
8
|
-
_rev: string;
|
|
9
|
-
_id: string;
|
|
10
|
-
time: {
|
|
11
|
-
created: string;
|
|
12
|
-
modified: string;
|
|
13
|
-
[key: string]: string; // Allows pattern properties such as version numbers
|
|
14
|
-
};
|
|
15
|
-
readme: string;
|
|
16
|
-
'dist-tags': {
|
|
17
|
-
latest: string;
|
|
18
|
-
[key: string]: unknown; // Allows additional properties
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// @ts-ignore
|
|
23
|
-
const schema: JSONSchemaType<Manifest> = {
|
|
24
|
-
type: 'object',
|
|
25
|
-
properties: {
|
|
26
|
-
name: { type: 'string' },
|
|
27
|
-
versions: { type: 'object', minProperties: 1 },
|
|
28
|
-
_rev: { type: 'string' },
|
|
29
|
-
_id: { type: 'string' },
|
|
30
|
-
time: {
|
|
31
|
-
type: 'object',
|
|
32
|
-
properties: {
|
|
33
|
-
created: { type: 'string' },
|
|
34
|
-
modified: { type: 'string' },
|
|
35
|
-
},
|
|
36
|
-
patternProperties: {
|
|
37
|
-
'^[0-9]+\\.[0-9]+\\.[0-9]+-\\d+$': { type: 'string' },
|
|
38
|
-
},
|
|
39
|
-
additionalProperties: true,
|
|
40
|
-
},
|
|
41
|
-
readme: { type: 'string' },
|
|
42
|
-
'dist-tags': {
|
|
43
|
-
type: 'object',
|
|
44
|
-
properties: {
|
|
45
|
-
latest: { type: 'string' },
|
|
46
|
-
},
|
|
47
|
-
required: ['latest'],
|
|
48
|
-
additionalProperties: true,
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
required: ['name', 'versions', 'dist-tags', '_rev', '_id', 'readme', 'time'],
|
|
52
|
-
additionalProperties: true,
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
// validate is a type guard for MyData - type is inferred from schema type
|
|
56
|
-
const validate = ajv.compile(schema);
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Validate if a manifest has the correct structure when a new package
|
|
60
|
-
* is being created. The properties name, versions and _attachments must contain 1 element.
|
|
61
|
-
* @param data a manifest object
|
|
62
|
-
* @returns boolean
|
|
63
|
-
*/
|
|
64
|
-
export function validateUnPublishSingleVersion(manifest: any) {
|
|
65
|
-
if (!manifest) {
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
return validate(manifest);
|
|
69
|
-
}
|
package/src/search-utils.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
export type SearchMetrics = {
|
|
2
|
-
quality: number;
|
|
3
|
-
popularity: number;
|
|
4
|
-
maintenance: number;
|
|
5
|
-
};
|
|
6
|
-
export type UnStable = {
|
|
7
|
-
flags?: {
|
|
8
|
-
// if is false is not be included in search results (majority are stable)
|
|
9
|
-
unstable?: boolean;
|
|
10
|
-
};
|
|
11
|
-
};
|
|
12
|
-
export type SearchItemPkg = {
|
|
13
|
-
name: string;
|
|
14
|
-
scoped?: string;
|
|
15
|
-
path?: string;
|
|
16
|
-
time?: number | Date;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
type PrivatePackage = {
|
|
20
|
-
// note: prefixed to avoid external conflicts
|
|
21
|
-
|
|
22
|
-
// the package is published as private
|
|
23
|
-
verdaccioPrivate?: boolean;
|
|
24
|
-
// if the package is not private but is cached
|
|
25
|
-
verdaccioPkgCached?: boolean;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export interface SearchItem extends UnStable, PrivatePackage {
|
|
29
|
-
package: SearchItemPkg;
|
|
30
|
-
score: Score;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export type Score = {
|
|
34
|
-
final: number;
|
|
35
|
-
detail: SearchMetrics;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export type SearchResults = {
|
|
39
|
-
objects: SearchItemPkg[];
|
|
40
|
-
total: number;
|
|
41
|
-
time: string;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
// @deprecated use @verdaccio/types
|
|
45
|
-
type PublisherMaintainer = {
|
|
46
|
-
username: string;
|
|
47
|
-
email: string;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// @deprecated use @verdaccio/types
|
|
51
|
-
export type SearchPackageBody = {
|
|
52
|
-
name: string;
|
|
53
|
-
scope: string;
|
|
54
|
-
description: string;
|
|
55
|
-
author: string | PublisherMaintainer;
|
|
56
|
-
version: string;
|
|
57
|
-
keywords: string | string[] | undefined;
|
|
58
|
-
date: string;
|
|
59
|
-
links?: {
|
|
60
|
-
npm: string; // only include placeholder for URL eg: {url}/{packageName}
|
|
61
|
-
homepage?: string;
|
|
62
|
-
repository?: string;
|
|
63
|
-
bugs?: string;
|
|
64
|
-
};
|
|
65
|
-
publisher?: any;
|
|
66
|
-
maintainers?: PublisherMaintainer[];
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
export interface SearchPackageItem extends UnStable, PrivatePackage {
|
|
70
|
-
package: SearchPackageBody;
|
|
71
|
-
score: Score;
|
|
72
|
-
searchScore?: number;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export const UNSCOPED = 'unscoped';
|
|
76
|
-
|
|
77
|
-
export type SearchQuery = {
|
|
78
|
-
text: string;
|
|
79
|
-
size?: number;
|
|
80
|
-
from?: number;
|
|
81
|
-
} & SearchMetrics;
|
package/src/stream-utils.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { Readable, Transform } from 'stream';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Converts a buffer stream to a string.
|
|
5
|
-
*/
|
|
6
|
-
const readableToString = async (stream: Readable) => {
|
|
7
|
-
const chunks: Buffer[] = [];
|
|
8
|
-
for await (let chunk of stream) {
|
|
9
|
-
chunks.push(Buffer.from(chunk));
|
|
10
|
-
}
|
|
11
|
-
const buffer = Buffer.concat(chunks);
|
|
12
|
-
const str = buffer.toString('utf-8');
|
|
13
|
-
return str;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Transform stream object mode to string
|
|
18
|
-
**/
|
|
19
|
-
const transformObjectToString = () => {
|
|
20
|
-
return new Transform({
|
|
21
|
-
objectMode: true,
|
|
22
|
-
transform: (chunk, encoding, callback) => {
|
|
23
|
-
callback(null, JSON.stringify(chunk));
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export { readableToString, transformObjectToString };
|