diff --git a/package.json b/package.json index 5ecc38b260..40ac3714db 100644 --- a/package.json +++ b/package.json @@ -246,6 +246,7 @@ "grapheme-splitter": "^1.0.4", "handlebars": "^4.7.7", "history": "^4.10.1", + "hpagent": "^1.2.0", "http-proxy": "^1.18.1", "immer": "^9.0.16", "joi": "^17.7.0", diff --git a/src/common/fetch/fetch.injectable.ts b/src/common/fetch/fetch.injectable.ts index e320c0128a..bd1ba89db7 100644 --- a/src/common/fetch/fetch.injectable.ts +++ b/src/common/fetch/fetch.injectable.ts @@ -3,7 +3,9 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; +import { HttpsProxyAgent } from "hpagent"; import type * as FetchModule from "node-fetch"; +import userStoreInjectable from "../user-store/user-store.injectable"; const { NodeFetch: { default: fetch }} = require("../../../build/webpack/node-fetch.bundle") as { NodeFetch: typeof FetchModule }; @@ -14,7 +16,20 @@ export type Fetch = (url: string, init?: RequestInit) => Promise; const fetchInjectable = getInjectable({ id: "fetch", - instantiate: (): Fetch => fetch, + instantiate: (di): Fetch => { + const { httpsProxy, allowUntrustedCAs } = di.inject(userStoreInjectable); + const agent = httpsProxy + ? new HttpsProxyAgent({ + proxy: httpsProxy, + rejectUnauthorized: !allowUntrustedCAs, + }) + : undefined; + + return (url, init = {}) => fetch(url, { + agent, + ...init, + }); + }, causesSideEffects: true, }); diff --git a/src/common/request.ts b/src/common/request.ts deleted file mode 100644 index 331b257f4d..0000000000 --- a/src/common/request.ts +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ - -import request from "request"; -import requestPromise from "request-promise-native"; -import { UserStore } from "./user-store"; - -// todo: get rid of "request" (deprecated) -// https://github.com/lensapp/lens/issues/459 - -function getDefaultRequestOpts(): Partial { - const { httpsProxy, allowUntrustedCAs } = UserStore.getInstance(); - - return { - proxy: httpsProxy || undefined, - rejectUnauthorized: !allowUntrustedCAs, - }; -} - -/** - * @deprecated - */ -export function customRequest(opts: request.Options) { - return request.defaults(getDefaultRequestOpts())(opts); -} - -/** - * @deprecated - */ -export function customRequestPromise(opts: requestPromise.Options) { - return requestPromise.defaults(getDefaultRequestOpts())(opts); -} diff --git a/src/features/helm-charts/add-custom-helm-repository-in-preferences.test.ts b/src/features/helm-charts/add-custom-helm-repository-in-preferences.test.ts index a1b215c40c..f24f0a5391 100644 --- a/src/features/helm-charts/add-custom-helm-repository-in-preferences.test.ts +++ b/src/features/helm-charts/add-custom-helm-repository-in-preferences.test.ts @@ -13,7 +13,7 @@ import execFileInjectable from "../../common/fs/exec-file.injectable"; import helmBinaryPathInjectable from "../../main/helm/helm-binary-path.injectable"; import getActiveHelmRepositoriesInjectable from "../../main/helm/repositories/get-active-helm-repositories/get-active-helm-repositories.injectable"; import type { HelmRepo } from "../../common/helm/helm-repo"; -import callForPublicHelmRepositoriesInjectable from "./child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable"; +import requestPublicHelmRepositoriesInjectable from "./child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/request-public-helm-repositories.injectable"; import isPathInjectable from "../../renderer/components/input/validators/is-path.injectable"; import showSuccessNotificationInjectable from "../../renderer/components/notifications/show-success-notification.injectable"; import showErrorNotificationInjectable from "../../renderer/components/notifications/show-error-notification.injectable"; @@ -47,7 +47,7 @@ describe("add custom helm repository in preferences", () => { }); builder.beforeWindowStart((windowDi) => { - windowDi.override(callForPublicHelmRepositoriesInjectable, () => async () => []); + windowDi.override(requestPublicHelmRepositoriesInjectable, () => async () => []); windowDi.override(showSuccessNotificationInjectable, () => showSuccessNotificationMock); windowDi.override(showErrorNotificationInjectable, () => showErrorNotificationMock); diff --git a/src/features/helm-charts/add-helm-repository-from-list-in-preferences.test.ts b/src/features/helm-charts/add-helm-repository-from-list-in-preferences.test.ts index 29e6ea890d..21ddaba1aa 100644 --- a/src/features/helm-charts/add-helm-repository-from-list-in-preferences.test.ts +++ b/src/features/helm-charts/add-helm-repository-from-list-in-preferences.test.ts @@ -12,7 +12,7 @@ import execFileInjectable from "../../common/fs/exec-file.injectable"; import helmBinaryPathInjectable from "../../main/helm/helm-binary-path.injectable"; import getActiveHelmRepositoriesInjectable from "../../main/helm/repositories/get-active-helm-repositories/get-active-helm-repositories.injectable"; import type { HelmRepo } from "../../common/helm/helm-repo"; -import callForPublicHelmRepositoriesInjectable from "./child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable"; +import requestPublicHelmRepositoriesInjectable from "./child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/request-public-helm-repositories.injectable"; import showSuccessNotificationInjectable from "../../renderer/components/notifications/show-success-notification.injectable"; import showErrorNotificationInjectable from "../../renderer/components/notifications/show-error-notification.injectable"; import type { AsyncResult } from "../../common/utils/async-result"; @@ -44,7 +44,7 @@ describe("add helm repository from list in preferences", () => { builder.beforeWindowStart((windowDi) => { windowDi.override(showSuccessNotificationInjectable, () => showSuccessNotificationMock); windowDi.override(showErrorNotificationInjectable, () => showErrorNotificationMock); - windowDi.override(callForPublicHelmRepositoriesInjectable, () => callForPublicHelmRepositoriesMock); + windowDi.override(requestPublicHelmRepositoriesInjectable, () => callForPublicHelmRepositoriesMock); }); rendered = await builder.render(); diff --git a/src/features/helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable.ts b/src/features/helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable.ts deleted file mode 100644 index 6858b854fd..0000000000 --- a/src/features/helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getInjectable } from "@ogre-tools/injectable"; -import { sortBy } from "lodash/fp"; -import type { HelmRepo } from "../../../../../../../common/helm/helm-repo"; -import { customRequestPromise } from "../../../../../../../common/request"; - -const callForPublicHelmRepositoriesInjectable = getInjectable({ - id: "call-for-public-helm-repositories", - - instantiate: () => async (): Promise => { - const res = await customRequestPromise({ - uri: "https://github.com/lensapp/artifact-hub-repositories/releases/download/latest/repositories.json", - json: true, - resolveWithFullResponse: true, - timeout: 10000, - }); - - const repositories = res.body as HelmRepo[]; - - return sortBy(repo => repo.name, repositories); - }, - - causesSideEffects: true, -}); - -export default callForPublicHelmRepositoriesInjectable; diff --git a/src/features/helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/public-helm-repositories.injectable.ts b/src/features/helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/public-helm-repositories.injectable.ts index 4c32ff7154..16a0fe98cd 100644 --- a/src/features/helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/public-helm-repositories.injectable.ts +++ b/src/features/helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/public-helm-repositories.injectable.ts @@ -4,19 +4,15 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { asyncComputed } from "@ogre-tools/injectable-react"; -import callForPublicHelmRepositoriesInjectable from "./call-for-public-helm-repositories.injectable"; +import requestPublicHelmRepositoriesInjectable from "./request-public-helm-repositories.injectable"; const publicHelmRepositoriesInjectable = getInjectable({ id: "public-helm-repositories", - instantiate: (di) => { - const callForPublicHelmRepositories = di.inject(callForPublicHelmRepositoriesInjectable); - - return asyncComputed({ - getValueFromObservedPromise: callForPublicHelmRepositories, - valueWhenPending: [], - }); - }, + instantiate: (di) => asyncComputed({ + getValueFromObservedPromise: di.inject(requestPublicHelmRepositoriesInjectable), + valueWhenPending: [], + }), }); export default publicHelmRepositoriesInjectable; diff --git a/src/features/helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/request-public-helm-repositories.injectable.ts b/src/features/helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/request-public-helm-repositories.injectable.ts new file mode 100644 index 0000000000..64e130aa09 --- /dev/null +++ b/src/features/helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/request-public-helm-repositories.injectable.ts @@ -0,0 +1,40 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { sortBy } from "lodash/fp"; +import downloadJsonInjectable from "../../../../../../../common/fetch/download-json.injectable"; +import { withTimeout } from "../../../../../../../common/fetch/timeout-controller"; +import type { HelmRepo } from "../../../../../../../common/helm/helm-repo"; +import loggerInjectable from "../../../../../../../common/logger.injectable"; + +const publicHelmReposUrl = "https://github.com/lensapp/artifact-hub-repositories/releases/download/latest/repositories.json"; + +const requestPublicHelmRepositoriesInjectable = getInjectable({ + id: "request-public-helm-repositories", + + instantiate: (di) => { + const downloadJson = di.inject(downloadJsonInjectable); + const logger = di.inject(loggerInjectable); + + return async (): Promise => { + const controller = withTimeout(10_000); + const result = await downloadJson(publicHelmReposUrl, { + signal: controller.signal, + }); + + if (!result.callWasSuccessful) { + logger.warn(`Failed to download public helm repos: ${result.error}`); + + return []; + } + + return sortBy(repo => repo.name, result.response as HelmRepo[]); + }; + }, + + causesSideEffects: true, +}); + +export default requestPublicHelmRepositoriesInjectable; diff --git a/src/features/helm-charts/listing-active-helm-repositories-in-preferences.test.ts b/src/features/helm-charts/listing-active-helm-repositories-in-preferences.test.ts index df92796e76..f95387fded 100644 --- a/src/features/helm-charts/listing-active-helm-repositories-in-preferences.test.ts +++ b/src/features/helm-charts/listing-active-helm-repositories-in-preferences.test.ts @@ -14,7 +14,7 @@ import execFileInjectable, { type ExecFile } from "../../common/fs/exec-file.inj import helmBinaryPathInjectable from "../../main/helm/helm-binary-path.injectable"; import loggerInjectable from "../../common/logger.injectable"; import type { Logger } from "../../common/logger"; -import callForPublicHelmRepositoriesInjectable from "./child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable"; +import requestPublicHelmRepositoriesInjectable from "./child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/request-public-helm-repositories.injectable"; import showErrorNotificationInjectable from "../../renderer/components/notifications/show-error-notification.injectable"; describe("listing active helm repositories in preferences", () => { @@ -43,7 +43,7 @@ describe("listing active helm repositories in preferences", () => { builder.beforeWindowStart((windowDi) => { windowDi.override(showErrorNotificationInjectable, () => showErrorNotificationMock); - windowDi.override(callForPublicHelmRepositoriesInjectable, () => async () => []); + windowDi.override(requestPublicHelmRepositoriesInjectable, () => async () => []); }); rendered = await builder.render(); diff --git a/src/features/helm-charts/remove-helm-repository-from-list-of-active-repository-in-preferences.test.ts b/src/features/helm-charts/remove-helm-repository-from-list-of-active-repository-in-preferences.test.ts index f2a23f0409..303d749061 100644 --- a/src/features/helm-charts/remove-helm-repository-from-list-of-active-repository-in-preferences.test.ts +++ b/src/features/helm-charts/remove-helm-repository-from-list-of-active-repository-in-preferences.test.ts @@ -13,7 +13,7 @@ import execFileInjectable from "../../common/fs/exec-file.injectable"; import helmBinaryPathInjectable from "../../main/helm/helm-binary-path.injectable"; import getActiveHelmRepositoriesInjectable from "../../main/helm/repositories/get-active-helm-repositories/get-active-helm-repositories.injectable"; import type { HelmRepo } from "../../common/helm/helm-repo"; -import callForPublicHelmRepositoriesInjectable from "./child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable"; +import requestPublicHelmRepositoriesInjectable from "./child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/request-public-helm-repositories.injectable"; import type { AsyncResult } from "../../common/utils/async-result"; describe("remove helm repository from list of active repositories in preferences", () => { @@ -35,7 +35,7 @@ describe("remove helm repository from list of active repositories in preferences }); builder.beforeWindowStart((windowDi) => { - windowDi.override(callForPublicHelmRepositoriesInjectable, () => async () => []); + windowDi.override(requestPublicHelmRepositoriesInjectable, () => async () => []); }); rendered = await builder.render(); diff --git a/src/features/preferences/navigation-to-kubernetes-preferences.test.ts b/src/features/preferences/navigation-to-kubernetes-preferences.test.ts index 925d600545..1f4bd9b490 100644 --- a/src/features/preferences/navigation-to-kubernetes-preferences.test.ts +++ b/src/features/preferences/navigation-to-kubernetes-preferences.test.ts @@ -5,7 +5,7 @@ import type { RenderResult } from "@testing-library/react"; import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; -import callForPublicHelmRepositoriesInjectable from "../helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable"; +import requestPublicHelmRepositoriesInjectable from "../helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/request-public-helm-repositories.injectable"; import getActiveHelmRepositoriesInjectable from "../../main/helm/repositories/get-active-helm-repositories/get-active-helm-repositories.injectable"; import type { Discover } from "../../renderer/components/test-utils/discovery-of-html-elements"; import { discoverFor } from "../../renderer/components/test-utils/discovery-of-html-elements"; @@ -30,7 +30,7 @@ describe("preferences - navigation to kubernetes preferences", () => { }); builder.beforeWindowStart((windowDi) => { - windowDi.override(callForPublicHelmRepositoriesInjectable, () => async () => []); + windowDi.override(requestPublicHelmRepositoriesInjectable, () => async () => []); }); builder.beforeWindowStart(() => { diff --git a/src/renderer/getDiForUnitTesting.tsx b/src/renderer/getDiForUnitTesting.tsx index 6dc7fa010e..230b8ceb1d 100644 --- a/src/renderer/getDiForUnitTesting.tsx +++ b/src/renderer/getDiForUnitTesting.tsx @@ -30,7 +30,7 @@ import { observable, computed, runInAction } from "mobx"; import requestAnimationFrameInjectable from "./components/animate/request-animation-frame.injectable"; import getRandomIdInjectable from "../common/utils/get-random-id.injectable"; import getFilePathsInjectable from "../features/helm-charts/child-features/preferences/renderer/adding-of-custom-helm-repository/helm-file-input/get-file-paths.injectable"; -import callForPublicHelmRepositoriesInjectable from "../features/helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable"; +import requestPublicHelmRepositoriesInjectable from "../features/helm-charts/child-features/preferences/renderer/adding-of-public-helm-repository/public-helm-repositories/request-public-helm-repositories.injectable"; import platformInjectable from "../common/vars/platform.injectable"; import startTopbarStateSyncInjectable from "./components/layout/top-bar/start-state-sync.injectable"; import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx"; @@ -142,7 +142,7 @@ export const getDiForUnitTesting = ( overrideFunctionalInjectables(di, [ broadcastMessageInjectable, getFilePathsInjectable, - callForPublicHelmRepositoriesInjectable, + requestPublicHelmRepositoriesInjectable, ]); di.override(extensionsStoreInjectable, () => ({ diff --git a/yarn.lock b/yarn.lock index f9f35148da..6c16fc47bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6708,6 +6708,11 @@ hpack.js@^2.1.6: readable-stream "^2.0.1" wbuf "^1.1.0" +hpagent@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/hpagent/-/hpagent-1.2.0.tgz#0ae417895430eb3770c03443456b8d90ca464903" + integrity sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA== + html-encoding-sniffer@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3"