0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2025-01-27 22:59:51 -05:00

feat: add cache-control header to endpoints (#2791)

Add no cache to endpoints that returns tokens in the body
This commit is contained in:
Juan Picado 2021-12-20 23:11:17 +01:00 committed by GitHub
parent 1c17d0986e
commit fd3ad1e546
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 36 additions and 51 deletions

View file

@ -4,7 +4,7 @@ import Cookies from 'cookies';
import { Config, RemoteUser } from '@verdaccio/types';
import { Response, Router } from 'express';
import { ErrorCode } from '../../../lib/utils';
import { API_ERROR, API_MESSAGE, HTTP_STATUS } from '../../../lib/constants';
import { API_ERROR, API_MESSAGE, HEADERS, HTTP_STATUS } from '../../../lib/constants';
import { createRemoteUser, createSessionToken, getApiToken, getAuthenticatedMessage, validatePassword } from '../../../lib/auth-utils';
import { logger } from '../../../lib/logger';
@ -33,7 +33,7 @@ export default function (route: Router, auth: IAuth, config: Config): void {
const token = await getApiToken(auth, config, restoredRemoteUser, password);
res.status(HTTP_STATUS.CREATED);
res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');
return next({
ok: getAuthenticatedMessage(req.remote_user.name),
token,
@ -60,6 +60,7 @@ export default function (route: Router, auth: IAuth, config: Config): void {
req.remote_user = user;
res.status(HTTP_STATUS.CREATED);
res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');
return next({
ok: `user '${req.body.name}' created`,
token,

View file

@ -2,7 +2,7 @@ import _ from 'lodash';
import buildDebug from 'debug';
import { Response, Router } from 'express';
import { Config, RemoteUser, Token } from '@verdaccio/types';
import { HTTP_STATUS, SUPPORT_ERRORS } from '../../../../lib/constants';
import { HEADERS, HTTP_STATUS, SUPPORT_ERRORS } from '../../../../lib/constants';
import { ErrorCode, mask } from '../../../../lib/utils';
import { getApiToken } from '../../../../lib/auth-utils';
import { stringToMD5 } from '../../../../lib/crypto-utils';
@ -89,6 +89,7 @@ export default function (route: Router, auth: IAuth, storage: IStorageHandler, c
await storage.saveToken(saveToken);
debug('token %o was created for user %o', key, name);
res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');
return next(
normalizeToken({
token,

View file

@ -7,7 +7,7 @@ import _ from 'lodash';
import { Router, Response, Request } from 'express';
import { Config, RemoteUser, JWTSignOptions } from '@verdaccio/types';
import { API_ERROR, APP_ERROR, HTTP_STATUS } from '../../../lib/constants';
import { API_ERROR, APP_ERROR, HEADERS, HTTP_STATUS } from '../../../lib/constants';
import { IAuth, $NextFunctionVer } from '../../../../types';
import { ErrorCode } from '../../../lib/utils';
import { getSecurity, validatePassword } from '../../../lib/auth-utils';
@ -23,7 +23,7 @@ function addUserAuthApi(route: Router, auth: IAuth, config: Config): void {
} else {
req.remote_user = user;
const jWTSignOptions: JWTSignOptions = getSecurity(config).web.sign;
res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');
next({
token: await auth.jwtEncrypt(user, jWTSignOptions),
username: req.remote_user.name,

View file

@ -26,6 +26,7 @@ export const HEADERS = {
JSON: 'application/json',
CONTENT_TYPE: 'Content-type',
CONTENT_LENGTH: 'content-length',
CACHE_CONTROL: 'Cache-Control',
TEXT_PLAIN: 'text/plain',
TEXT_HTML: 'text/html',
AUTHORIZATION: 'authorization',

View file

@ -200,7 +200,7 @@ describe('endpoint unit test', () => {
const token = res.body.token;
expect(typeof token).toBe('string');
expect(res.body.ok).toMatch(`user '${credentials.name}' created`);
expect(res.get(HEADERS.CACHE_CONTROL)).toEqual('no-cache, no-store');
// testing JWT auth headers with token
// we need it here, because token is required
request(app)
@ -272,6 +272,7 @@ describe('endpoint unit test', () => {
if (err) {
return done(err);
}
expect(res.get(HEADERS.CACHE_CONTROL)).toEqual('no-cache, no-store');
expect(res.body).toBeTruthy();
done();
});
@ -1078,7 +1079,7 @@ describe('endpoint unit test', () => {
await Promise.all([
putPackage(request(app), `/${pkgName}`, generatePackageMetadata(pkgName, '2.0.0'), token),
putPackage(request(app), `/${pkgName}`, generatePackageMetadata(pkgName, '2.0.1'), token),
putPackage(request(app), `/${pkgName}`, generatePackageMetadata(pkgName, '2.0.2'), token)
putPackage(request(app), `/${pkgName}`, generatePackageMetadata(pkgName, '2.0.2'), token),
]);
const pkg = generatePackageMetadata(pkgName, '2.0.3');

View file

@ -6,18 +6,12 @@ import _ from 'lodash';
import configDefault from '../../partials/config';
import endPointAPI from '../../../../src/api';
import {
HEADERS,
HTTP_STATUS,
HEADER_TYPE,
TOKEN_BEARER,
API_ERROR,
SUPPORT_ERRORS
} from '../../../../src/lib/constants';
import { HEADERS, HTTP_STATUS, HEADER_TYPE, TOKEN_BEARER, API_ERROR, SUPPORT_ERRORS } from '../../../../src/lib/constants';
import { mockServer } from '../../__helper/mock';
import { DOMAIN_SERVERS } from '../../../functional/config.functional';
import { getNewToken } from '../../__helper/api';
import { buildToken } from '../../../../src/lib/utils';
import { expectJson } from '../../../../src/api/middleware';
require('../../../../src/lib/logger').setup([{ type: 'stdout', format: 'pretty', level: 'trace' }]);
@ -69,17 +63,17 @@ describe('endpoint unit test', () => {
{
auth: {
htpasswd: {
file: './test-storage-token-spec/.htpasswd-token'
}
file: './test-storage-token-spec/.htpasswd-token',
},
},
storage: store,
self_path: store,
uplinks: {
npmjs: {
url: `http://${DOMAIN_SERVERS}:${mockServerPort}`
}
url: `http://${DOMAIN_SERVERS}:${mockServerPort}`,
},
},
logs: [{ type: 'stdout', format: 'pretty', level: 'trace' }]
logs: [{ type: 'stdout', format: 'pretty', level: 'trace' }],
},
'token.spec.yaml'
);
@ -117,11 +111,12 @@ describe('endpoint unit test', () => {
});
test('should generate one token', async (done) => {
await generateTokenCLI(app, token, {
const [, resp] = await generateTokenCLI(app, token, {
password: credentials.password,
readonly: false,
cidr_whitelist: []
cidr_whitelist: [],
});
expect(resp.get(HEADERS.CACHE_CONTROL)).toEqual('no-cache, no-store');
request(app)
.get('/-/npm/v1/tokens')
@ -134,7 +129,6 @@ describe('endpoint unit test', () => {
}
const { objects, urls } = resp.body;
expect(objects).toHaveLength(1);
const [tokenGenerated] = objects;
expect(tokenGenerated.user).toEqual(credentials.name);
@ -152,7 +146,7 @@ describe('endpoint unit test', () => {
const res = await generateTokenCLI(app, token, {
password: credentials.password,
readonly: false,
cidr_whitelist: []
cidr_whitelist: [],
});
const t = res[1].body.token;
@ -182,7 +176,7 @@ describe('endpoint unit test', () => {
await generateTokenCLI(app, token, {
password: 'wrongPassword',
readonly: false,
cidr_whitelist: []
cidr_whitelist: [],
});
done();
} catch (e) {
@ -198,7 +192,7 @@ describe('endpoint unit test', () => {
try {
const res = await generateTokenCLI(app, token, {
password: credentials.password,
cidr_whitelist: []
cidr_whitelist: [],
});
expect(res[0]).toBeNull();
@ -213,7 +207,7 @@ describe('endpoint unit test', () => {
try {
const res = await generateTokenCLI(app, token, {
password: credentials.password,
readonly: false
readonly: false,
});
expect(res[0]).toBeNull();

View file

@ -7,13 +7,7 @@ import publishMetadata from '../../partials/publish-api';
import forbiddenPlace from '../../partials/forbidden-place';
import endPointAPI from '../../../../src/api';
import {
HEADERS,
API_ERROR,
HTTP_STATUS,
HEADER_TYPE,
DIST_TAGS
} from '../../../../src/lib/constants';
import { HEADERS, API_ERROR, HTTP_STATUS, HEADER_TYPE, DIST_TAGS } from '../../../../src/lib/constants';
import { DOMAIN_SERVERS } from '../../../functional/config.functional';
import { mockServer } from '../../__helper/mock';
import { addUser } from '../../__helper/api';
@ -34,16 +28,16 @@ describe('endpoint web unit test', () => {
{
auth: {
htpasswd: {
file: './web-api-storage/.htpasswd-web-api'
}
file: './web-api-storage/.htpasswd-web-api',
},
},
storage: store,
uplinks: {
npmjs: {
url: `http://${DOMAIN_SERVERS}:${mockServerPort}`
}
url: `http://${DOMAIN_SERVERS}:${mockServerPort}`,
},
},
self_path: store
self_path: store,
},
'api.web.spec.yaml'
);
@ -60,17 +54,9 @@ describe('endpoint web unit test', () => {
describe('Registry WebUI endpoints', () => {
beforeAll(async () => {
await request(app)
.put('/@scope%2fpk1-test')
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
.send(JSON.stringify(publishMetadata))
.expect(HTTP_STATUS.CREATED);
await request(app).put('/@scope%2fpk1-test').set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON).send(JSON.stringify(publishMetadata)).expect(HTTP_STATUS.CREATED);
await request(app)
.put('/forbidden-place')
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
.send(JSON.stringify(forbiddenPlace))
.expect(HTTP_STATUS.CREATED);
await request(app).put('/forbidden-place').set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON).send(JSON.stringify(forbiddenPlace)).expect(HTTP_STATUS.CREATED);
});
describe('Packages', () => {
@ -209,7 +195,7 @@ describe('endpoint web unit test', () => {
.post('/-/verdaccio/login')
.send({
username: credentials.name,
password: credentials.password
password: credentials.password,
})
.expect(HTTP_STATUS.OK)
.end(function (err, res) {
@ -217,6 +203,7 @@ describe('endpoint web unit test', () => {
expect(res.body.token).toBeDefined();
expect(res.body.token).toBeTruthy();
expect(res.body.username).toMatch(credentials.name);
expect(res.get(HEADERS.CACHE_CONTROL)).toEqual('no-cache, no-store');
done();
});
});
@ -227,7 +214,7 @@ describe('endpoint web unit test', () => {
.send(
JSON.stringify({
username: 'fake',
password: 'fake'
password: 'fake',
})
)
// FIXME: there should be 401