Skip to content

Commit

Permalink
Upgrades hapi from v17 to v20 (#1146)
Browse files Browse the repository at this point in the history
* Bumping 3 major versions ahead introduces many breaking changes. Hapi
provides a detailed changelog: https://hapi.dev/resources/changelog
* v18 notes: hapijs/hapi#3871
* v19 notes: hapijs/hapi#4017
* Bumps `raw-loader` from v3.1.0 to v4.0.2 to address a bootstrap
warning. No breaking changes other than bumping Node.js to v10.
* Removes the `--no-deprecation` flag for the integration tests since
the newest version of hapi doesn't use the deprecated library.

Resolves #1070
Resolves #1073
Resolves #1076
Resolves #1088
Resolves #1090

Signed-off-by: Tommy Markley <markleyt@amazon.com>
  • Loading branch information
Tommy Markley committed Jan 15, 2022
1 parent a765199 commit 167b993
Show file tree
Hide file tree
Showing 71 changed files with 644 additions and 704 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr_check_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ jobs:
- name: Run integration tests
if: steps.integration_tests_results.outputs.integration_tests_results != 'success'
id: integration-tests
run: node --no-deprecation scripts/jest_integration --ci --colors --max-old-space-size=5120
run: node scripts/jest_integration --ci --colors --max-old-space-size=5120

# Set cache if linter, unit tests, and integration tests were successful then the job will be marked successful
# Sets individual results to empower re-runs of the same build without re-running successful steps.
Expand Down
47 changes: 22 additions & 25 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"test": "grunt test",
"test:bwc": "./scripts/bwctest-osd.sh",
"test:jest": "node scripts/jest",
"test:jest_integration": "node --no-deprecation scripts/jest_integration",
"test:jest_integration": "node scripts/jest_integration",
"test:mocha": "node scripts/mocha",
"test:mocha:coverage": "grunt test:mochaCoverage",
"test:ftr": "node scripts/functional_tests",
Expand Down Expand Up @@ -123,29 +123,36 @@
"@elastic/numeral": "^2.5.0",
"@elastic/request-crypto": "1.1.4",
"@elastic/safer-lodash-set": "0.0.0",
"@hapi/good-squeeze": "5.2.1",
"@hapi/wreck": "^15.0.2",
"@hapi/accept": "^5.0.2",
"@hapi/boom": "^9.1.4",
"@hapi/cookie": "^11.0.2",
"@hapi/good-squeeze": "^6.0.0",
"@hapi/h2o2": "^9.1.0",
"@hapi/hapi": "^20.2.1",
"@hapi/hoek": "^9.2.1",
"@hapi/inert": "^6.0.4",
"@hapi/podium": "^4.1.3",
"@hapi/vision": "^6.1.0",
"@hapi/wreck": "^17.1.0",
"@osd/ace": "1.0.0",
"@osd/analytics": "1.0.0",
"@osd/apm-config-loader": "1.0.0",
"@osd/config": "1.0.0",
"@osd/config-schema": "1.0.0",
"@osd/i18n": "1.0.0",
"@osd/interpreter": "1.0.0",
"@osd/logging": "1.0.0",
"@osd/monaco": "1.0.0",
"@osd/std": "1.0.0",
"@osd/ui-framework": "1.0.0",
"@osd/ace": "1.0.0",
"@osd/monaco": "1.0.0",
"@osd/ui-shared-deps": "1.0.0",
"@types/yauzl": "^2.9.1",
"JSONStream": "1.3.5",
"abortcontroller-polyfill": "^1.4.0",
"accept": "3.0.2",
"angular": "^1.8.0",
"angular-elastic": "^2.5.1",
"angular-sanitize": "^1.8.0",
"bluebird": "3.5.5",
"boom": "^7.2.0",
"chalk": "^4.1.0",
"chokidar": "^3.4.2",
"color": "1.0.3",
Expand All @@ -164,15 +171,10 @@
"glob": "^7.1.7",
"glob-all": "^3.2.1",
"globby": "^8.0.1",
"h2o2": "^8.1.2",
"handlebars": "4.7.7",
"hapi": "^17.5.3",
"hapi-auth-cookie": "^9.0.0",
"hjson": "3.2.1",
"hoek": "^5.0.4",
"http-proxy-agent": "^2.1.0",
"https-proxy-agent": "^5.0.0",
"inert": "^5.1.0",
"inline-style": "^2.0.0",
"ip-cidr": "^2.1.0",
"joi": "^13.5.2",
Expand Down Expand Up @@ -213,7 +215,6 @@
"tslib": "^2.0.0",
"type-detect": "^4.0.8",
"uuid": "3.3.2",
"vision": "^5.3.3",
"whatwg-fetch": "^3.0.0",
"yauzl": "^2.10.0"
},
Expand All @@ -230,13 +231,15 @@
"@elastic/filesaver": "1.1.2",
"@elastic/github-checks-reporter": "0.0.20b3",
"@elastic/makelogs": "^6.0.0",
"@microsoft/api-documenter": "^7.13.78",
"@microsoft/api-extractor": "^7.19.3",
"@osd/babel-preset": "1.0.0",
"@osd/dev-utils": "1.0.0",
"@osd/opensearch": "1.0.0",
"@osd/opensearch-archiver": "1.0.0",
"@osd/eslint-import-resolver-opensearch-dashboards": "2.0.0",
"@osd/eslint-plugin-eslint": "1.0.0",
"@osd/expect": "1.0.0",
"@osd/opensearch": "1.0.0",
"@osd/opensearch-archiver": "1.0.0",
"@osd/optimizer": "1.0.0",
"@osd/plugin-generator": "1.0.0",
"@osd/pm": "1.0.0",
Expand All @@ -245,20 +248,16 @@
"@osd/test": "1.0.0",
"@osd/test-subj-selector": "0.2.1",
"@osd/utility-types": "1.0.0",
"@microsoft/api-documenter": "^7.13.78",
"@microsoft/api-extractor": "^7.19.3",
"@percy/agent": "^0.28.6",
"@testing-library/dom": "^7.24.2",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.0.4",
"@testing-library/react-hooks": "^3.4.1",
"@types/accept": "3.1.1",
"@types/angular": "^1.6.56",
"@types/angular-mocks": "^1.7.0",
"@types/archiver": "^3.1.0",
"@types/babel__core": "^7.1.17",
"@types/bluebird": "^3.1.1",
"@types/boom": "^7.2.0",
"@types/chance": "^1.0.0",
"@types/cheerio": "^0.22.10",
"@types/chromedriver": "^81.0.0",
Expand All @@ -278,14 +277,13 @@
"@types/glob": "^7.1.3",
"@types/globby": "^8.0.0",
"@types/graphql": "^0.13.2",
"@types/h2o2": "^8.1.1",
"@types/hapi": "^17.0.18",
"@types/hapi-auth-cookie": "^9.1.0",
"@types/hapi__cookie": "^10.1.4",
"@types/hapi__h2o2": "^8.3.3",
"@types/hapi__hapi": "^20.0.10",
"@types/hapi__inert": "^5.2.3",
"@types/has-ansi": "^3.0.0",
"@types/history": "^4.7.3",
"@types/hjson": "^2.4.2",
"@types/hoek": "^4.1.3",
"@types/inert": "^5.1.2",
"@types/jest": "^26.0.14",
"@types/joi": "^13.4.2",
"@types/jquery": "^3.3.31",
Expand All @@ -307,7 +305,6 @@
"@types/normalize-path": "^3.0.0",
"@types/pegjs": "^0.10.1",
"@types/pngjs": "^3.4.0",
"@types/podium": "^1.0.0",
"@types/prop-types": "^15.7.3",
"@types/reach__router": "^1.2.6",
"@types/react": "^16.9.36",
Expand Down
5 changes: 3 additions & 2 deletions packages/osd-ace/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"devDependencies": {
"@osd/dev-utils": "1.0.0",
"@osd/babel-preset": "1.0.0",
"raw-loader": "^3.1.0",
"typescript": "4.0.2"
"raw-loader": "^4.0.2",
"typescript": "4.0.2",
"webpack": "^4.41.5"
}
}
2 changes: 1 addition & 1 deletion packages/osd-monaco/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"babel-loader": "^8.2.3",
"css-loader": "^5.2.7",
"del": "^5.1.0",
"raw-loader": "^3.1.0",
"raw-loader": "^4.0.2",
"supports-color": "^7.0.0",
"typescript": "4.0.2",
"webpack": "^4.41.5",
Expand Down
2 changes: 1 addition & 1 deletion packages/osd-optimizer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"pirates": "^4.0.1",
"postcss": "^8.4.5",
"postcss-loader": "^4.2.0",
"raw-loader": "^3.1.0",
"raw-loader": "^4.0.2",
"rxjs": "^6.5.5",
"sass-loader": "^10.2.0",
"source-map-support": "^0.5.19",
Expand Down
2 changes: 1 addition & 1 deletion packages/osd-ui-framework/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"node-sass": "^6.0.1",
"postcss": "^8.4.5",
"postcss-loader": "^4.2.0",
"raw-loader": "^3.1.0",
"raw-loader": "^4.0.2",
"react-dom": "^16.12.0",
"react-redux": "^7.2.0",
"react-router": "^5.2.1",
Expand Down
2 changes: 1 addition & 1 deletion src/core/public/public.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { Action } from 'history';
import { ApiResponse } from '@elastic/elasticsearch/lib/Transport';
import Boom from 'boom';
import Boom from '@hapi/boom';
import { ConfigPath } from '@osd/config';
import { EnvironmentMode } from '@osd/config';
import { EuiBreadcrumb } from '@elastic/eui';
Expand Down
4 changes: 2 additions & 2 deletions src/core/server/http/base_path_proxy_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ import { Agent as HttpsAgent, ServerOptions as TlsOptions } from 'https';

import apm from 'elastic-apm-node';
import { ByteSizeValue } from '@osd/config-schema';
import { Server, Request } from 'hapi';
import HapiProxy from 'h2o2';
import { Server, Request } from '@hapi/hapi';
import HapiProxy from '@hapi/h2o2';
import { sampleSize } from 'lodash';
import * as Rx from 'rxjs';
import { take } from 'rxjs/operators';
Expand Down
43 changes: 13 additions & 30 deletions src/core/server/http/cookie_session_storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@
* GitHub history for details.
*/

import { Request, Server } from 'hapi';
import hapiAuthCookie from 'hapi-auth-cookie';
// @ts-expect-error no TS definitions
import Statehood from 'statehood';
import { Request, Server } from '@hapi/hapi';
import hapiAuthCookie from '@hapi/cookie';

import { OpenSearchDashboardsRequest, ensureRawRequest } from './router';
import { SessionStorageFactory, SessionStorage } from './session_storage';
Expand Down Expand Up @@ -93,7 +91,7 @@ class ScopedCookieSessionStorage<T extends Record<string, any>> implements Sessi
const session = await this.server.auth.test('security-cookie', this.request);
// A browser can send several cookies, if it's not an array, just return the session value
if (!Array.isArray(session)) {
return session as T;
return session.credentials as T;
}

// If we have an array with one value, we're good also
Expand Down Expand Up @@ -154,39 +152,24 @@ export async function createCookieSessionStorageFactory<T>(
await server.register({ plugin: hapiAuthCookie });

server.auth.strategy('security-cookie', 'cookie', {
cookie: cookieOptions.name,
password: cookieOptions.encryptionKey,
validateFunc: async (req, session: T | T[]) => {
cookie: {
name: cookieOptions.name,
password: cookieOptions.encryptionKey,
isSecure: cookieOptions.isSecure,
path: basePath === undefined ? '/' : basePath,
clearInvalid: false,
isHttpOnly: true,
isSameSite: cookieOptions.sameSite ?? false,
},
validateFunc: async (req: Request, session: T | T[]) => {
const result = cookieOptions.validate(session);
if (!result.isValid) {
clearInvalidCookie(req, result.path);
}
return { valid: result.isValid };
},
isSecure: cookieOptions.isSecure,
path: basePath,
clearInvalid: false,
isHttpOnly: true,
isSameSite: cookieOptions.sameSite === 'None' ? false : cookieOptions.sameSite ?? false,
});

// A hack to support SameSite: 'None'.
// Remove it after update Hapi to v19 that supports SameSite: 'None' out of the box.
if (cookieOptions.sameSite === 'None') {
log.debug('Patching Statehood.prepareValue');
const originalPrepareValue = Statehood.prepareValue;
Statehood.prepareValue = function opensearchDashboardsStatehoodPrepareValueWrapper(
name: string,
value: unknown,
options: any
) {
if (name === cookieOptions.name) {
options.isSameSite = cookieOptions.sameSite;
}
return originalPrepareValue(name, value, options);
};
}

return {
asScoped(request: OpenSearchDashboardsRequest) {
return new ScopedCookieSessionStorage<T>(log, server, ensureRawRequest(request));
Expand Down
28 changes: 16 additions & 12 deletions src/core/server/http/http_server.mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/
import { Request } from 'hapi';

import { URL, format as formatUrl } from 'url';
import { Request } from '@hapi/hapi';
import { merge } from 'lodash';
import { Socket } from 'net';
import { stringify } from 'query-string';
Expand Down Expand Up @@ -88,6 +90,7 @@ function createOpenSearchDashboardsRequestMock<P = any, Q = any, B = any>({
auth = { isAuthenticated: true },
}: RequestFixtureOptions<P, Q, B> = {}) {
const queryString = stringify(query, { sort: false });
const url = new URL(`${path}${queryString ? `?${queryString}` : ''}`, 'http://localhost');

return OpenSearchDashboardsRequest.from<P, Q, B>(
createRawRequestMock({
Expand All @@ -99,15 +102,11 @@ function createOpenSearchDashboardsRequestMock<P = any, Q = any, B = any>({
payload: body,
path,
method,
url: {
path,
pathname: path,
query: queryString,
search: queryString ? `?${queryString}` : queryString,
},
url,
route: {
settings: {
tags: routeTags,
// @ts-expect-error According to types/hapi__hapi `auth` can't be a boolean, but it can according to the @hapi/hapi source (https://github.com/hapijs/hapi/blob/v20.2.1/lib/route.js#L134)
auth: routeAuthRequired,
app: opensearchDashboardsRouteOptions,
},
Expand Down Expand Up @@ -141,6 +140,13 @@ interface DeepPartialArray<T> extends Array<DeepPartial<T>> {}
type DeepPartialObject<T> = { [P in keyof T]+?: DeepPartial<T[P]> };

function createRawRequestMock(customization: DeepPartial<Request> = {}) {
const pathname = customization.url?.pathname || '/';
const path = `${pathname}${customization.url?.search || ''}`;
const url = new URL(
formatUrl(Object.assign({ pathname, path, href: path }, customization.url)),
'http://localhost'
);

return merge(
{},
{
Expand All @@ -149,14 +155,12 @@ function createRawRequestMock(customization: DeepPartial<Request> = {}) {
isAuthenticated: true,
},
headers: {},
path: '/',
path,
route: { settings: {} },
url: {
href: '/',
},
url,
raw: {
req: {
url: '/',
url: path,
socket: {},
},
},
Expand Down
6 changes: 3 additions & 3 deletions src/core/server/http/http_server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -695,8 +695,8 @@ describe('with `basepath: /bar` and `rewriteBasePath: false`', () => {
});

describe('with `basepath: /bar` and `rewriteBasePath: true`', () => {
let innerServerListener: Server;
let configWithBasePath: HttpConfig;
let innerServerListener: Server;

beforeEach(async () => {
configWithBasePath = {
Expand Down Expand Up @@ -1224,7 +1224,7 @@ describe('timeout options', () => {
router.get(
{
path: '/',
validate: { body: schema.any() },
validate: { body: schema.maybe(schema.any()) },
},
(context, req, res) => {
return res.ok({
Expand Down Expand Up @@ -1257,7 +1257,7 @@ describe('timeout options', () => {
router.get(
{
path: '/',
validate: { body: schema.any() },
validate: { body: schema.maybe(schema.any()) },
options: { timeout: { idleSocket: 12000 } },
},
(context, req, res) => {
Expand Down
Loading

0 comments on commit 167b993

Please sign in to comment.