From 6e8d3e171e067b10d0d13922719e85b531ee538e Mon Sep 17 00:00:00 2001 From: Darren Clarke Date: Mon, 17 Feb 2025 10:53:08 +0100 Subject: [PATCH] Opensearch wrapper WIP --- .../app/(login)/login/_components/Login.tsx | 8 +-- apps/link/app/(login)/login/page.tsx | 3 +- apps/link/app/_lib/authentication.ts | 10 +-- apps/link/middleware.ts | 63 +++++++------------ apps/link/package.json | 2 +- docker/compose/zammad.yml | 14 +++-- .../opensearch_dashboards.yml | 2 +- docker/zammad/Dockerfile | 19 +++--- package-lock.json | 4 +- package.json | 2 +- .../components/OpenSearchWrapper.tsx | 2 +- 11 files changed, 58 insertions(+), 71 deletions(-) diff --git a/apps/link/app/(login)/login/_components/Login.tsx b/apps/link/app/(login)/login/_components/Login.tsx index 01ad0d2..5faf515 100644 --- a/apps/link/app/(login)/login/_components/Login.tsx +++ b/apps/link/app/(login)/login/_components/Login.tsx @@ -23,13 +23,11 @@ import { useSearchParams } from "next/navigation"; type LoginProps = { session: any; + baseURL: string; }; -export const Login: FC = ({ session }) => { - const origin = - typeof window !== "undefined" && window.location.origin - ? window.location.origin - : ""; +export const Login: FC = ({ session, baseURL }) => { + const origin = baseURL; const callbackUrl = `${origin}/setup`; const [provider, setProvider] = useState(undefined); const [email, setEmail] = useState(""); diff --git a/apps/link/app/(login)/login/page.tsx b/apps/link/app/(login)/login/page.tsx index 7bafdbb..ea944ba 100644 --- a/apps/link/app/(login)/login/page.tsx +++ b/apps/link/app/(login)/login/page.tsx @@ -9,10 +9,11 @@ export const metadata: Metadata = { export default async function Page() { const session = await getSession(); + const baseURL = process.env.LINK_URL; return ( Loading...}> - + ); } diff --git a/apps/link/app/_lib/authentication.ts b/apps/link/app/_lib/authentication.ts index ed59889..008b4a8 100644 --- a/apps/link/app/_lib/authentication.ts +++ b/apps/link/app/_lib/authentication.ts @@ -136,11 +136,11 @@ export const authOptions: NextAuthOptions = { return roles.includes("admin") || roles.includes("agent"); }, session: async ({ session, token }) => { - const redis = new Redis(process.env.REDIS_URL); - const isInvalidated = await redis.get(`invalidated:${token.sub}`); - if (isInvalidated) { - return null; - } + // const redis = new Redis(process.env.REDIS_URL); + // const isInvalidated = await redis.get(`invalidated:${token.sub}`); + // if (isInvalidated) { + // return null; + // } // @ts-ignore session.user.roles = token.roles ?? []; // @ts-ignore diff --git a/apps/link/middleware.ts b/apps/link/middleware.ts index db88b60..4607122 100644 --- a/apps/link/middleware.ts +++ b/apps/link/middleware.ts @@ -7,6 +7,8 @@ const rewriteURL = ( destinationBaseURL: string, headers: any = {}, ) => { + console.log("Rewriting URL"); + console.log({ request, originBaseURL, destinationBaseURL, headers }); let path = request.url.replace(originBaseURL, ""); if (path.startsWith("/")) { path = path.slice(1); @@ -30,20 +32,11 @@ const rewriteURL = ( const checkRewrites = async (request: NextRequestWithAuth) => { const linkBaseURL = process.env.LINK_URL ?? "http://localhost:3000"; - const zammadURL = process.env.ZAMMAD_URL ?? "http://zammad-nginx:8080"; + console.log({ linkBaseURL }); const opensearchBaseURL = process.env.OPENSEARCH_DASHBOARDS_URL ?? "http://opensearch-dashboards:5601"; - const zammadPaths = [ - "/zammad", - "/auth/sso", - "/assets", - "/mobile", - "/graphql", - "/cable", - ]; - const isSetupMode = process.env.SETUP_MODE === "true"; const { token } = request.nextauth; const email = token?.email?.toLowerCase() ?? "unknown"; const roles = (token?.roles as string[]) ?? []; @@ -59,16 +52,6 @@ const checkRewrites = async (request: NextRequestWithAuth) => { opensearchBaseURL, headers, ); - } else if (request.nextUrl.pathname.startsWith("/zammad")) { - return rewriteURL(request, `${linkBaseURL}/zammad`, zammadURL, headers); - } else if (zammadPaths.some((p) => request.nextUrl.pathname.startsWith(p))) { - return rewriteURL(request, linkBaseURL, zammadURL, headers); - } else if (request.nextUrl.pathname.startsWith("/api/v1")) { - if ((email && email !== "unknown") || isSetupMode) { - return NextResponse.next(); - } else { - return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); - } } else { const isDev = process.env.NODE_ENV === "development"; const nonce = Buffer.from(crypto.randomUUID()).toString("base64"); @@ -86,30 +69,30 @@ const checkRewrites = async (request: NextRequestWithAuth) => { frame-ancestors 'self'; upgrade-insecure-requests; `; - const contentSecurityPolicyHeaderValue = cspHeader - .replace(/\s{2,}/g, " ") - .trim(); + const contentSecurityPolicyHeaderValue = cspHeader + .replace(/\s{2,}/g, " ") + .trim(); - const requestHeaders = new Headers(request.headers); - requestHeaders.set("x-nonce", nonce); - requestHeaders.set( - "Content-Security-Policy", - contentSecurityPolicyHeaderValue, - ); + const requestHeaders = new Headers(request.headers); + requestHeaders.set("x-nonce", nonce); + requestHeaders.set( + "Content-Security-Policy", + contentSecurityPolicyHeaderValue, + ); - const response = NextResponse.next({ - request: { - headers: requestHeaders, - }, - }); + const response = NextResponse.next({ + request: { + headers: requestHeaders, + }, + }); - response.headers.set( - "Content-Security-Policy", - contentSecurityPolicyHeaderValue, - ); + response.headers.set( + "Content-Security-Policy", + contentSecurityPolicyHeaderValue, + ); - return response; -}; + return response; + }; } export default withAuth(checkRewrites, { diff --git a/apps/link/package.json b/apps/link/package.json index dd6b5a9..c5d8bd8 100644 --- a/apps/link/package.json +++ b/apps/link/package.json @@ -3,7 +3,7 @@ "version": "2.4.0b1", "type": "module", "scripts": { - "dev": "next dev", + "dev": "next dev -H 0.0.0.0", "build": "next build", "start": "next start", "export": "next export", diff --git a/docker/compose/zammad.yml b/docker/compose/zammad.yml index 7f358cb..73bae17 100644 --- a/docker/compose/zammad.yml +++ b/docker/compose/zammad.yml @@ -15,6 +15,10 @@ x-zammad-vars: &common-zammad-variables ELASTICSEARCH_SSL_VERIFY: "false" # this doesn't set es_ssl_verify as expected, but ideally it would ELASTICSEARCH_SCHEMA: "https" +x-zammad-args: &common-zammad-args + EMBEDDED: "true" + LINK_HOST: ${LINK_HOST} + services: zammad-init: container_name: zammad-init @@ -28,7 +32,7 @@ services: build: context: ../zammad args: - EMBEDDED: "true" + <<: *common-zammad-args image: registry.gitlab.com/digiresilience/link/link-stack/zammad:${LINK_STACK_VERSION} restart: on-failure user: 0:0 @@ -57,7 +61,7 @@ services: build: context: ../zammad args: - EMBEDDED: "true" + <<: *common-zammad-args image: registry.gitlab.com/digiresilience/link/link-stack/zammad:${LINK_STACK_VERSION} restart: ${RESTART} environment: @@ -81,7 +85,7 @@ services: build: context: ../zammad args: - EMBEDDED: "true" + <<: *common-zammad-args image: registry.gitlab.com/digiresilience/link/link-stack/zammad:${LINK_STACK_VERSION} restart: ${RESTART} volumes: @@ -110,7 +114,7 @@ services: build: context: ../zammad args: - EMBEDDED: "true" + <<: *common-zammad-args image: registry.gitlab.com/digiresilience/link/link-stack/zammad:${LINK_STACK_VERSION} restart: ${RESTART} volumes: @@ -129,7 +133,7 @@ services: build: context: ../zammad args: - EMBEDDED: "true" + <<: *common-zammad-args image: registry.gitlab.com/digiresilience/link/link-stack/zammad:${LINK_STACK_VERSION} restart: ${RESTART} volumes: diff --git a/docker/opensearch-dashboards/opensearch_dashboards.yml b/docker/opensearch-dashboards/opensearch_dashboards.yml index 6d93741..1520a20 100644 --- a/docker/opensearch-dashboards/opensearch_dashboards.yml +++ b/docker/opensearch-dashboards/opensearch_dashboards.yml @@ -20,5 +20,5 @@ opensearch_security.multitenancy.tenants.preferred: [Private, Global] # opensearch_security.readonly_mode.roles: [kibana_read_only] opensearch_security.cookie.secure: false server.host: "0.0.0.0" -server.basePath: "/dashboards" +server.basePath: "/link/dashboards" server.rewriteBasePath: false diff --git a/docker/zammad/Dockerfile b/docker/zammad/Dockerfile index 18f9cc3..44ded97 100644 --- a/docker/zammad/Dockerfile +++ b/docker/zammad/Dockerfile @@ -22,15 +22,16 @@ RUN sed -i '/touch db\/schema.rb/a ZAMMAD_SAFE_MODE=1 DATABASE_URL=postgresql:\/ RUN cat contrib/docker/setup.sh RUN contrib/docker/setup.sh builder ARG EMBEDDED=false -RUN if [ "$EMBEDDED" = "true" ] ; then sed -i '/location \/ {/i \ -\ \n\ -\ location /link {\n\ -\ proxy_pass http://link:3000;\n\ -\ proxy_set_header Host $host;\n\ -\ proxy_set_header X-Real-IP $remote_addr;\n\ -\ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n\ -\ proxy_set_header X-Forwarded-Proto https;\n\ -\ }\n' ${ZAMMAD_DIR}/contrib/nginx/zammad.conf; fi +ARG LINK_HOST=http://link:3000 +RUN if [ "$EMBEDDED" = "true" ] ; then sed -i "/location \/ {/i\ + location /link {\n\ + proxy_pass ${LINK_HOST};\n\ + proxy_set_header Host \$host;\n\ + proxy_set_header X-Real-IP \$remote_addr;\n\ + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;\n\ + proxy_set_header X-Forwarded-Proto https;\n\ + }\n\ +" ${ZAMMAD_DIR}/contrib/nginx/zammad.conf; fi RUN sed -i '/^[[:space:]]*# es config/a\ echo "about to reinstall..."\n\ bundle exec rails runner /opt/zammad/contrib/link/setup.rb\n\ diff --git a/package-lock.json b/package-lock.json index 0583cd0..2f32a07 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@link-stack", - "version": "2.4.0b1", + "version": "2.5.0b1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@link-stack", - "version": "2.4.0b1", + "version": "2.5.0b1", "license": "AGPL-3.0-or-later", "workspaces": [ "apps/*", diff --git a/package.json b/package.json index 3c8b677..f6b6a6e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@link-stack", - "version": "2.4.0b1", + "version": "2.5.0b1", "description": "Link from the Center for Digital Resilience", "scripts": { "dev": "dotenv -- turbo dev", diff --git a/packages/leafcutter-ui/components/OpenSearchWrapper.tsx b/packages/leafcutter-ui/components/OpenSearchWrapper.tsx index f3de21a..949743c 100644 --- a/packages/leafcutter-ui/components/OpenSearchWrapper.tsx +++ b/packages/leafcutter-ui/components/OpenSearchWrapper.tsx @@ -34,7 +34,7 @@ export const OpenSearchWrapper: FC = ({ >