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:
parent
1c17d0986e
commit
fd3ad1e546
7 changed files with 36 additions and 51 deletions
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue