From 7bc9bb175e77e9e727e2754dea464c75645ae649 Mon Sep 17 00:00:00 2001 From: Tim Haasdyk Date: Thu, 13 Jun 2024 15:57:24 +0200 Subject: [PATCH] Adds https-proxy as oauth authority for local or k8s --- Taskfile.yml | 5 ++- backend/Taskfile.yml | 6 +-- frontend/Taskfile.yml | 17 ++++++++ frontend/eslint.config.js | 3 +- frontend/https-proxy/.gitignore | 24 ++++++++++ frontend/https-proxy/package.json | 17 ++++++++ frontend/https-proxy/vite.config.ts | 68 +++++++++++++++++++++++++++++ frontend/pnpm-lock.yaml | 13 +++++- frontend/pnpm-workspace.yaml | 2 +- frontend/vite.config.ts | 11 +---- 10 files changed, 149 insertions(+), 17 deletions(-) create mode 100644 frontend/https-proxy/.gitignore create mode 100644 frontend/https-proxy/package.json create mode 100644 frontend/https-proxy/vite.config.ts diff --git a/Taskfile.yml b/Taskfile.yml index d3e1c51a0..5e5b69ef9 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -78,5 +78,8 @@ tasks: deps: [ infra-up, api:only, k8s:infra-forward ] interactive: true + local-web-app-for-develop: + deps: [ ui:viewer-dev, api:local-web-app-for-develop, ui:https-oauth-authority ] + local-web-app: - deps: [ ui:viewer-dev, api:local-web-app ] + deps: [ ui:viewer-dev, api:local-web-app, ui:https-oauth-authority ] diff --git a/backend/Taskfile.yml b/backend/Taskfile.yml index 21ac8a733..c0e4637ae 100644 --- a/backend/Taskfile.yml +++ b/backend/Taskfile.yml @@ -91,14 +91,14 @@ tasks: cmds: - kubectl port-forward service/db 27018:27017 -n languageforge --context dallas-rke - local-web-app: + local-web-app-for-develop: label: dotnet dir: ./LocalWebApp cmd: dotnet watch --no-hot-reload - local-web-app-with-local-lexbox: + local-web-app: label: Run LocalWebApp with Local LexBox env: - Auth__DefaultAuthority: "https://localhost:3000" + Auth__DefaultAuthority: "https://localhost:3050" dir: ./LocalWebApp cmd: dotnet watch --no-hot-reload diff --git a/frontend/Taskfile.yml b/frontend/Taskfile.yml index b5bee46f7..e72e0c6a6 100644 --- a/frontend/Taskfile.yml +++ b/frontend/Taskfile.yml @@ -56,3 +56,20 @@ tasks: dir: ./viewer deps: [ install-viewer ] cmd: pnpm run dev-app + + + install-https-proxy: + dir: ./https-proxy + method: checksum + sources: + - package.json + cmds: + - corepack enable || true + - pnpm install + https-proxy: + dir: ./https-proxy + desc: "MSAL requires the oauth authority to be available over https. That's why this is here. As a bonus it dynamically looks for the UI either locally or in k8s." + aliases: [ https-oauth-authority ] + deps: [ install-https-proxy ] + cmd: pnpm run dev + diff --git a/frontend/eslint.config.js b/frontend/eslint.config.js index 739761c65..2e376186d 100644 --- a/frontend/eslint.config.js +++ b/frontend/eslint.config.js @@ -20,7 +20,8 @@ export default [ 'playwright.config.ts', '.svelte-kit/**', '**/generated/**', - 'viewer/' + 'viewer/', + 'https-proxy/', ], }, js.configs.recommended, diff --git a/frontend/https-proxy/.gitignore b/frontend/https-proxy/.gitignore new file mode 100644 index 000000000..a547bf36d --- /dev/null +++ b/frontend/https-proxy/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/frontend/https-proxy/package.json b/frontend/https-proxy/package.json new file mode 100644 index 000000000..b0d615111 --- /dev/null +++ b/frontend/https-proxy/package.json @@ -0,0 +1,17 @@ +{ + "name": "https-proxy", + "version": "0.0.1", + "private": true, + "packageManager": "pnpm@8.15.1", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "devDependencies": { + "typescript": "^5.2.2", + "vite": "^5.2.0", + "@vitejs/plugin-basic-ssl": "^1.1.0" + } +} diff --git a/frontend/https-proxy/vite.config.ts b/frontend/https-proxy/vite.config.ts new file mode 100644 index 000000000..03da48eb5 --- /dev/null +++ b/frontend/https-proxy/vite.config.ts @@ -0,0 +1,68 @@ +import basicSsl from '@vitejs/plugin-basic-ssl'; +import {defineConfig, type ProxyOptions} from 'vite'; +import http from 'http'; + +async function checkTargetAvailability(url: string): Promise { + return new Promise((resolve) => { + const req = http.get(url, (res) => { + resolve(!!res.statusCode && res.statusCode < 400); + }); + + req.on('error', () => { + resolve(false); + }); + + req.end(); + }); +} + +const targets = ['http://localhost:3000', 'http://localhost']; + +const lexboxServer: ProxyOptions = { + target: targets[0], + secure: false, + changeOrigin: false, + autoRewrite: true, + protocolRewrite: 'https', + headers: { + 'x-forwarded-proto': 'https', + }, + configure: async (proxy, options) => { + let availableTarget: string | undefined = undefined; + + proxy.on('proxyReq', function () { + if (!availableTarget) console.warn(`Request before target (${lexboxServer.target}) was confirmed to be available.`); + }); + + while (!availableTarget) { + for (const target of targets) { + const isAvailable = await checkTargetAvailability(target); + if (isAvailable) { + options.target = availableTarget = target; + console.log('Will proxy to available target:', target); + return; + } + } + console.warn('No target available, retrying in 5s'); + await new Promise((resolve) => setTimeout(resolve, 5000)); + } + }, +}; + +export default defineConfig({ + build: { + target: 'esnext', + sourcemap: true + }, + plugins: [ + basicSsl(), + ], + server: { + port: 3050, + host: true, + strictPort: true, + proxy: { + '/': lexboxServer, + } + }, +}); diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index e84c17b69..049bb4f80 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -223,6 +223,18 @@ importers: specifier: ^4.4.2 version: 4.4.2 + https-proxy: + devDependencies: + '@vitejs/plugin-basic-ssl': + specifier: ^1.1.0 + version: 1.1.0(vite@5.2.11) + typescript: + specifier: ^5.2.2 + version: 5.3.3 + vite: + specifier: ^5.2.0 + version: 5.2.11(@types/node@20.12.12) + viewer: dependencies: '@microsoft/dotnet-js-interop': @@ -4097,7 +4109,6 @@ packages: vite: ^3.0.0 || ^4.0.0 || ^5.0.0 dependencies: vite: 5.2.11(@types/node@20.12.12) - dev: false /@vitest/expect@1.6.0: resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==} diff --git a/frontend/pnpm-workspace.yaml b/frontend/pnpm-workspace.yaml index 79ed274d5..9616a464a 100644 --- a/frontend/pnpm-workspace.yaml +++ b/frontend/pnpm-workspace.yaml @@ -1,3 +1,3 @@ packages: - - 'frontend' + - 'https-proxy' - 'viewer' diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 4c09d7df4..8705018c9 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -7,20 +7,11 @@ import precompileIntl from 'svelte-intl-precompile/sveltekit-plugin'; import {type ProxyOptions, searchForWorkspaceRoot} from 'vite'; import { sveltekit } from '@sveltejs/kit/vite'; - - - const inDocker = process.env['DockerDev'] === 'true'; -const exposeServer = !inDocker; +const exposeServer = false; const lexboxServer: ProxyOptions = { target: 'http://localhost:5158', secure: false, - changeOrigin: false, - autoRewrite: true, - protocolRewrite: 'https', - headers: { - 'x-forwarded-proto': 'https', - } }; export default defineConfig({