From 2b3c275b4b98b28bab82d7a9d6c2e63547afdba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Skr=C3=B8vseth?= Date: Tue, 27 Aug 2024 10:21:58 +0200 Subject: [PATCH] =?UTF-8?q?Happy-DOM=20version=20of=20NAV=20Dekorat=C3=B8r?= =?UTF-8?q?en?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy-to-dev.yaml | 6 ++ Dockerfile | 3 - frontend/index.html | 6 +- server/bun.lockb | Bin 86010 -> 56661 bytes server/package.json | 5 +- server/src/config/version.ts | 4 +- server/src/index-file.ts | 31 ++++--- server/src/nav-dekoratoren/csr-elements.ts | 22 +++++ server/src/nav-dekoratoren/nav-dekoratoren.ts | 81 ++++++++++++++++++ server/src/nav-dekoratoren/types.ts | 58 +++++++++++++ server/src/nav-dekoratoren/urls.ts | 64 ++++++++++++++ server/tsconfig.json | 4 +- 12 files changed, 262 insertions(+), 22 deletions(-) create mode 100644 server/src/nav-dekoratoren/csr-elements.ts create mode 100644 server/src/nav-dekoratoren/nav-dekoratoren.ts create mode 100644 server/src/nav-dekoratoren/types.ts create mode 100644 server/src/nav-dekoratoren/urls.ts diff --git a/.github/workflows/deploy-to-dev.yaml b/.github/workflows/deploy-to-dev.yaml index b745eab4..8de08061 100644 --- a/.github/workflows/deploy-to-dev.yaml +++ b/.github/workflows/deploy-to-dev.yaml @@ -80,6 +80,12 @@ jobs: cd server bun test + - name: Build server + shell: bash + run: | + cd server + bun run build + - name: Generate version number id: version run: echo "version=$(TZ="Europe/Oslo" git show -s --format=%cd --date='format-local:%Y-%m-%dT%H:%M:%S')" >> "$GITHUB_OUTPUT" diff --git a/Dockerfile b/Dockerfile index d6f32043..02c3c313 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,9 +9,6 @@ COPY frontend frontend WORKDIR /usr/src/app/server -# This command will create an absolute path reference to JSDOM (used by nav-dekoratoren-moduler), which will not work if built outside Docker -RUN npm run build - ARG VERSION ENV VERSION=$VERSION diff --git a/frontend/index.html b/frontend/index.html index 060d8c97..a12e14d0 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -12,12 +12,16 @@ + {{DECORATOR_STYLES}} + {{DECORATOR_SCRIPTS}} Klage eller anke på vedtak + {{DECORATOR_HEADER}}
+ {{DECORATOR_FOOTER}} - + \ No newline at end of file diff --git a/server/bun.lockb b/server/bun.lockb index ef7b0b95a61a94be110181c3fd9c24862ca01ec2..04323a65c1815496316d4ebcd99dafe2225df0d4 100755 GIT binary patch delta 8419 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 MB%!=HQrv9yFNaB!;s5{u delta 26198 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 diff --git a/server/package.json b/server/package.json index 2df91b85..8e35ccc0 100644 --- a/server/package.json +++ b/server/package.json @@ -6,7 +6,8 @@ "license": "MIT", "type": "module", "scripts": { - "build": "tsc && tsc-alias", + "start": "bun run build --watch & node --watch --trace-warnings dist/server.js", + "build": "bun build ./src/server.ts --target node --format esm --sourcemap --outdir dist", "typecheck": "tsc --noEmit", "lint": "biome check" }, @@ -14,9 +15,9 @@ "@fastify/cors": "9.0.1", "@fastify/http-proxy": "9.5.0", "@fastify/type-provider-typebox": "4.1.0", - "@navikt/nav-dekoratoren-moduler": "1.6.9", "fastify": "4.28.1", "fastify-metrics": "11.0.0", + "happy-dom": "^15.0.0", "jose": "5.8.0", "openid-client": "5.6.5", "prom-client": "15.1.3", diff --git a/server/src/config/version.ts b/server/src/config/version.ts index a99f2e6d..cc01c2dc 100644 --- a/server/src/config/version.ts +++ b/server/src/config/version.ts @@ -1,5 +1,5 @@ -import { isDeployed } from './env'; -import { requiredEnvString } from './env-var'; +import { isDeployed } from '@app/config/env'; +import { requiredEnvString } from '@app/config/env-var'; const getDefaultVersion = () => { if (isDeployed) { diff --git a/server/src/index-file.ts b/server/src/index-file.ts index 4e319c17..d7bca896 100644 --- a/server/src/index-file.ts +++ b/server/src/index-file.ts @@ -1,16 +1,17 @@ +import { readFileSync } from 'node:fs'; import path from 'node:path'; import { performance } from 'node:perf_hooks'; import { frontendDistDirectoryPath } from '@app/config/config'; import { ENVIRONMENT, isDeployedToProd } from '@app/config/env'; import { VERSION } from '@app/config/version'; import { getLogger } from '@app/logger'; +import { fetchDecoratorHtml } from '@app/nav-dekoratoren/nav-dekoratoren'; import { EmojiIcons, sendToSlack } from '@app/slack'; -import { injectDecoratorServerSide } from '@navikt/nav-dekoratoren-moduler/ssr'; const log = getLogger('index-file'); class IndexFile { - private readonly INDEX_HTML_PATH = path.join(frontendDistDirectoryPath, 'index.html'); + private readonly INDEX_HTML = readFileSync(path.join(frontendDistDirectoryPath, 'index.html'), 'utf-8'); private _isReady = false; public get isReady() { @@ -40,21 +41,27 @@ class IndexFile { try { const start = performance.now(); - const indexHtml = await injectDecoratorServerSide({ + const { DECORATOR_SCRIPTS, DECORATOR_STYLES, DECORATOR_HEADER, DECORATOR_FOOTER } = await fetchDecoratorHtml({ env: isDeployedToProd ? 'prod' : 'dev', - filePath: this.INDEX_HTML_PATH, - simple: true, - chatbot: true, - redirectToApp: true, - logoutUrl: '/oauth2/logout', - context: 'privatperson', - level: 'Level4', - utloggingsvarsel: true, + params: { + simple: true, + chatbot: true, + redirectToApp: true, + logoutUrl: '/oauth2/logout', + context: 'privatperson', + level: 'Level4', + logoutWarning: true, + }, }); const end = performance.now(); - this._indexFile = indexHtml.replace('{{ENVIRONMENT}}', ENVIRONMENT).replace('{{VERSION}}', VERSION); + this._indexFile = this.INDEX_HTML.replace('{{DECORATOR_SCRIPTS}}', DECORATOR_SCRIPTS) + .replace('{{DECORATOR_STYLES}}', DECORATOR_STYLES) + .replace('{{DECORATOR_HEADER}}', DECORATOR_HEADER) + .replace('{{DECORATOR_FOOTER}}', DECORATOR_FOOTER) + .replace('{{ENVIRONMENT}}', ENVIRONMENT) + .replace('{{VERSION}}', VERSION); log.debug({ msg: 'Successfully updated index.html with Dekoratøren and variables.', diff --git a/server/src/nav-dekoratoren/csr-elements.ts b/server/src/nav-dekoratoren/csr-elements.ts new file mode 100644 index 00000000..01b688c6 --- /dev/null +++ b/server/src/nav-dekoratoren/csr-elements.ts @@ -0,0 +1,22 @@ +import type { DecoratorFetchProps, DecoratorUrlProps } from '@app/nav-dekoratoren/types'; +import { getDecoratorUrl } from '@app/nav-dekoratoren/urls'; + +export const getCsrElements = (csrProps: DecoratorFetchProps) => { + const props: DecoratorUrlProps = { + ...csrProps, + csr: true, + }; + + const envUrl = getDecoratorUrl(props); + const assetsUrl = getDecoratorUrl({ ...props, params: undefined }); + const scriptSrc = `${assetsUrl}/client.js`; + + return { + header: '
', + footer: '', + env: `
`, + styles: ``, + scripts: ``, + scriptSrc, + }; +}; diff --git a/server/src/nav-dekoratoren/nav-dekoratoren.ts b/server/src/nav-dekoratoren/nav-dekoratoren.ts new file mode 100644 index 00000000..a571c610 --- /dev/null +++ b/server/src/nav-dekoratoren/nav-dekoratoren.ts @@ -0,0 +1,81 @@ +import { getCsrElements } from '@app/nav-dekoratoren/csr-elements'; +import type { DecoratorFetchProps } from '@app/nav-dekoratoren/types'; +import { getDecoratorUrl } from '@app/nav-dekoratoren/urls'; +import { Window } from 'happy-dom'; + +export type DecoratorElements = { + DECORATOR_STYLES: string; + DECORATOR_SCRIPTS: string; + DECORATOR_HEADER: string; + DECORATOR_FOOTER: string; +}; + +const fetchDecorator = async (url: string, props: DecoratorFetchProps, retries = 3): Promise => + fetch(url) + .then((res) => { + if (res.ok) { + return res.text(); + } + throw new Error(`${res.status} - ${res.statusText}`); + }) + .then((html) => { + const window = new Window(); + window.document.write(html); + const { document } = window; + + const styles = document.getElementById('styles')?.innerHTML; + if (!styles) { + throw new Error('Decorator styles element not found!'); + } + + const scripts = document.getElementById('scripts')?.innerHTML; + if (!scripts) { + throw new Error('Decorator scripts element not found!'); + } + + const header = document.getElementById('header-withmenu')?.innerHTML; + if (!header) { + throw new Error('Decorator header element not found!'); + } + + const footer = document.getElementById('footer-withmenu')?.innerHTML; + if (!footer) { + throw new Error('Decorator footer element not found!'); + } + + const elements = { + DECORATOR_STYLES: styles.trim(), + DECORATOR_SCRIPTS: scripts.trim(), + DECORATOR_HEADER: header.trim(), + DECORATOR_FOOTER: footer.trim(), + }; + + return elements; + }) + .catch((e) => { + if (retries > 0) { + console.warn(`Failed to fetch decorator, retrying ${retries} more times - Url: ${url} - Error: ${e}`); + return fetchDecorator(url, props, retries - 1); + } + + throw e; + }); + +export const fetchDecoratorHtml = async (props: DecoratorFetchProps): Promise => { + const url = getDecoratorUrl(props); + + return fetchDecorator(url, props).catch((e) => { + console.error( + `Failed to fetch decorator, falling back to elements for client-side rendering - Url: ${url} - Error: ${e}`, + ); + + const csrElements = getCsrElements(props); + + return { + DECORATOR_STYLES: csrElements.styles, + DECORATOR_SCRIPTS: `${csrElements.env}${csrElements.scripts}`, + DECORATOR_HEADER: csrElements.header, + DECORATOR_FOOTER: csrElements.footer, + }; + }); +}; diff --git a/server/src/nav-dekoratoren/types.ts b/server/src/nav-dekoratoren/types.ts new file mode 100644 index 00000000..615477d7 --- /dev/null +++ b/server/src/nav-dekoratoren/types.ts @@ -0,0 +1,58 @@ +export type DecoratorLocale = 'nb' | 'nn' | 'en' | 'se' | 'pl' | 'uk' | 'ru'; + +export type DecoratorLanguageOption = + | { + url?: string; + locale: DecoratorLocale; + handleInApp: true; + } + | { + url: string; + locale: DecoratorLocale; + handleInApp?: false; + }; + +export type DecoratorBreadcrumb = { + url: string; + title: string; + analyticsTitle?: string; + handleInApp?: boolean; +}; + +export type DecoratorNaisEnv = 'prod' | 'dev' | 'beta' | 'betaTms' | 'devNext' | 'prodNext'; + +export type DecoratorEnvProps = + | { env: 'localhost'; localUrl: string } + | { env: DecoratorNaisEnv; serviceDiscovery?: boolean }; + +export type DecoratorFetchProps = { + params?: DecoratorParams; + noCache?: boolean; +} & DecoratorEnvProps; + +export type DecoratorUrlProps = { + csr?: boolean; +} & DecoratorFetchProps; + +export type DecoratorParams = Partial<{ + context: 'privatperson' | 'arbeidsgiver' | 'samarbeidspartner'; + simple: boolean; + simpleHeader: boolean; + simpleFooter: boolean; + enforceLogin: boolean; + redirectToApp: boolean; + redirectToUrl: string; + redirectToUrlLogout: string; + level: string; + language: DecoratorLocale; + availableLanguages: DecoratorLanguageOption[]; + breadcrumbs: DecoratorBreadcrumb[]; + utilsBackground: 'white' | 'gray' | 'transparent'; + feedback: boolean; + chatbot: boolean; + chatbotVisible: boolean; + urlLookupTable: boolean; + shareScreen: boolean; + logoutUrl: string; + logoutWarning: boolean; +}>; diff --git a/server/src/nav-dekoratoren/urls.ts b/server/src/nav-dekoratoren/urls.ts new file mode 100644 index 00000000..c6843b53 --- /dev/null +++ b/server/src/nav-dekoratoren/urls.ts @@ -0,0 +1,64 @@ +import { NAIS_CLUSTER_NAME } from '@app/config/config'; +import type { + DecoratorBreadcrumb, + DecoratorLanguageOption, + DecoratorNaisEnv, + DecoratorUrlProps, +} from '@app/nav-dekoratoren/types'; + +type NaisUrls = Record; + +const externalUrls: NaisUrls = { + prod: 'https://www.nav.no/dekoratoren', + dev: 'https://dekoratoren.ekstern.dev.nav.no', + beta: 'https://dekoratoren-beta.intern.dev.nav.no', + betaTms: 'https://dekoratoren-beta-tms.intern.dev.nav.no', + devNext: 'https://decorator-next.ekstern.dev.nav.no', + prodNext: 'https://www.nav.no/decorator-next', +}; + +const serviceUrls: NaisUrls = { + prod: 'http://nav-dekoratoren.personbruker', + dev: 'http://nav-dekoratoren.personbruker', + beta: 'http://nav-dekoratoren-beta.personbruker', + betaTms: 'http://nav-dekoratoren-beta-tms.personbruker', + devNext: 'http://decorator-next.personbruker', + prodNext: 'http://decorator-next.personbruker', +}; + +const naisGcpClusters: Record = { + 'dev-gcp': true, + 'prod-gcp': true, +}; + +const objectToQueryString = ( + params: Record, +) => + params + ? Object.entries(params).reduce( + (acc, [k, v], i) => + v !== undefined + ? `${acc}${i ? '&' : '?'}${k}=${encodeURIComponent(typeof v === 'object' ? JSON.stringify(v) : v)}` + : acc, + '', + ) + : ''; + +const isNaisApp = () => typeof process !== 'undefined' && NAIS_CLUSTER_NAME && naisGcpClusters[NAIS_CLUSTER_NAME]; + +const getNaisUrl = (env: DecoratorNaisEnv, csr = false, serviceDiscovery = true) => { + const shouldUseServiceDiscovery = serviceDiscovery && !csr && isNaisApp(); + + return (shouldUseServiceDiscovery ? serviceUrls[env] : externalUrls[env]) || externalUrls.prod; +}; + +export const getDecoratorUrl = (props: DecoratorUrlProps) => { + const { env, params, csr } = props; + const baseUrl = env === 'localhost' ? props.localUrl : getNaisUrl(env, csr, props.serviceDiscovery); + + if (!params) { + return baseUrl; + } + + return `${baseUrl}/${csr ? 'env' : ''}${objectToQueryString(params)}`; +}; diff --git a/server/tsconfig.json b/server/tsconfig.json index 8a57e130..979ca195 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -3,10 +3,10 @@ // Enable latest features "lib": ["ESNext"], "target": "ESNext", - "module": "NodeNext", + "module": "ESNext", "moduleDetection": "force", // Bundler mode - "moduleResolution": "NodeNext", + "moduleResolution": "Bundler", // Best practices "strict": true, "skipLibCheck": true,