2018-03-02 23:19:08 +01:00
|
|
|
import _ from 'lodash';
|
2021-03-14 08:42:46 +01:00
|
|
|
import { Response, Router } from 'express';
|
2018-08-21 08:05:34 +02:00
|
|
|
|
2020-09-17 06:48:16 +02:00
|
|
|
import {
|
|
|
|
createRemoteUser,
|
|
|
|
getAuthenticatedMessage,
|
|
|
|
validatePassword,
|
|
|
|
ErrorCode,
|
|
|
|
} from '@verdaccio/utils';
|
2020-03-08 10:13:56 +01:00
|
|
|
import { getApiToken } from '@verdaccio/auth';
|
2020-03-03 23:59:19 +01:00
|
|
|
import { logger } from '@verdaccio/logger';
|
|
|
|
|
|
|
|
import { Config, RemoteUser } from '@verdaccio/types';
|
2020-09-17 06:48:16 +02:00
|
|
|
import { IAuth } from '@verdaccio/auth';
|
2020-03-03 23:59:19 +01:00
|
|
|
import { API_ERROR, API_MESSAGE, HTTP_STATUS } from '@verdaccio/dev-commons';
|
2020-09-17 06:48:16 +02:00
|
|
|
import { $RequestExtend, $NextFunctionVer } from '../types/custom';
|
2018-08-21 08:05:34 +02:00
|
|
|
|
2020-08-13 23:27:00 +02:00
|
|
|
export default function (route: Router, auth: IAuth, config: Config): void {
|
2020-09-17 06:48:16 +02:00
|
|
|
route.get('/-/user/:org_couchdb_user', function (
|
|
|
|
req: $RequestExtend,
|
|
|
|
res: Response,
|
|
|
|
next: $NextFunctionVer
|
|
|
|
): void {
|
2021-03-31 23:22:32 +02:00
|
|
|
res.status(HTTP_STATUS.OK);
|
|
|
|
next({
|
|
|
|
ok: getAuthenticatedMessage(req.remote_user.name),
|
|
|
|
});
|
|
|
|
});
|
2017-06-15 15:53:55 +02:00
|
|
|
|
2020-09-17 06:48:16 +02:00
|
|
|
route.put('/-/user/:org_couchdb_user/:_rev?/:revision?', function (
|
|
|
|
req: $RequestExtend,
|
|
|
|
res: Response,
|
|
|
|
next: $NextFunctionVer
|
|
|
|
): void {
|
2021-03-31 23:22:32 +02:00
|
|
|
const { name, password } = req.body;
|
|
|
|
const remoteName = req.remote_user.name;
|
2018-08-21 08:05:34 +02:00
|
|
|
|
2021-03-31 23:22:32 +02:00
|
|
|
if (_.isNil(remoteName) === false && _.isNil(name) === false && remoteName === name) {
|
2020-09-17 06:48:16 +02:00
|
|
|
auth.authenticate(name, password, async function callbackAuthenticate(
|
|
|
|
err,
|
|
|
|
user
|
|
|
|
): Promise<void> {
|
2021-03-31 23:22:32 +02:00
|
|
|
if (err) {
|
2020-09-17 06:48:16 +02:00
|
|
|
logger.trace(
|
|
|
|
{ name, err },
|
|
|
|
'authenticating for user @{username} failed. Error: @{err.message}'
|
|
|
|
);
|
2021-03-31 23:22:32 +02:00
|
|
|
return next(ErrorCode.getCode(HTTP_STATUS.UNAUTHORIZED, API_ERROR.BAD_USERNAME_PASSWORD));
|
|
|
|
}
|
2019-06-13 06:58:43 +02:00
|
|
|
|
2021-03-31 23:22:32 +02:00
|
|
|
const restoredRemoteUser: RemoteUser = createRemoteUser(name, user.groups || []);
|
|
|
|
const token = await getApiToken(auth, config, restoredRemoteUser, password);
|
2018-08-21 08:05:34 +02:00
|
|
|
|
2021-03-31 23:22:32 +02:00
|
|
|
res.status(HTTP_STATUS.CREATED);
|
2018-08-21 08:05:34 +02:00
|
|
|
|
2021-03-31 23:22:32 +02:00
|
|
|
return next({
|
|
|
|
ok: getAuthenticatedMessage(req.remote_user.name),
|
|
|
|
token,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
if (validatePassword(password) === false) {
|
|
|
|
// eslint-disable-next-line new-cap
|
|
|
|
return next(ErrorCode.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.PASSWORD_SHORT()));
|
|
|
|
}
|
2017-06-15 15:53:55 +02:00
|
|
|
|
2020-08-13 23:27:00 +02:00
|
|
|
auth.add_user(name, password, async function (err, user): Promise<void> {
|
2021-03-31 23:22:32 +02:00
|
|
|
if (err) {
|
|
|
|
if (err.status >= HTTP_STATUS.BAD_REQUEST && err.status < HTTP_STATUS.INTERNAL_ERROR) {
|
|
|
|
// With npm registering is the same as logging in,
|
|
|
|
// and npm accepts only an 409 error.
|
|
|
|
// So, changing status code here.
|
2020-09-17 06:48:16 +02:00
|
|
|
return next(
|
|
|
|
ErrorCode.getCode(err.status, err.message) || ErrorCode.getConflict(err.message)
|
|
|
|
);
|
2021-03-14 08:42:46 +01:00
|
|
|
}
|
2021-03-31 23:22:32 +02:00
|
|
|
return next(err);
|
|
|
|
}
|
2021-03-14 08:42:46 +01:00
|
|
|
|
2020-09-17 06:48:16 +02:00
|
|
|
const token =
|
|
|
|
name && password ? await getApiToken(auth, config, user, password) : undefined;
|
2018-08-21 08:05:34 +02:00
|
|
|
|
2021-03-31 23:22:32 +02:00
|
|
|
req.remote_user = user;
|
|
|
|
res.status(HTTP_STATUS.CREATED);
|
|
|
|
return next({
|
|
|
|
ok: `user '${req.body.name}' created`,
|
|
|
|
token,
|
2017-06-15 15:53:55 +02:00
|
|
|
});
|
2021-03-14 08:42:46 +01:00
|
|
|
});
|
|
|
|
}
|
2021-03-31 23:22:32 +02:00
|
|
|
});
|
|
|
|
|
2020-09-17 06:48:16 +02:00
|
|
|
route.delete('/-/user/token/*', function (
|
|
|
|
req: $RequestExtend,
|
|
|
|
res: Response,
|
|
|
|
next: $NextFunctionVer
|
|
|
|
): void {
|
2021-03-31 23:22:32 +02:00
|
|
|
res.status(HTTP_STATUS.OK);
|
|
|
|
next({
|
|
|
|
ok: API_MESSAGE.LOGGED_OUT,
|
|
|
|
});
|
|
|
|
});
|
2018-03-10 21:09:04 +01:00
|
|
|
}
|