Opensearch wrapper WIP
This commit is contained in:
parent
5ff5eb4213
commit
6e8d3e171e
11 changed files with 58 additions and 71 deletions
|
|
@ -23,13 +23,11 @@ import { useSearchParams } from "next/navigation";
|
||||||
|
|
||||||
type LoginProps = {
|
type LoginProps = {
|
||||||
session: any;
|
session: any;
|
||||||
|
baseURL: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Login: FC<LoginProps> = ({ session }) => {
|
export const Login: FC<LoginProps> = ({ session, baseURL }) => {
|
||||||
const origin =
|
const origin = baseURL;
|
||||||
typeof window !== "undefined" && window.location.origin
|
|
||||||
? window.location.origin
|
|
||||||
: "";
|
|
||||||
const callbackUrl = `${origin}/setup`;
|
const callbackUrl = `${origin}/setup`;
|
||||||
const [provider, setProvider] = useState(undefined);
|
const [provider, setProvider] = useState(undefined);
|
||||||
const [email, setEmail] = useState("");
|
const [email, setEmail] = useState("");
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,11 @@ export const metadata: Metadata = {
|
||||||
|
|
||||||
export default async function Page() {
|
export default async function Page() {
|
||||||
const session = await getSession();
|
const session = await getSession();
|
||||||
|
const baseURL = process.env.LINK_URL;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Suspense fallback={<div>Loading...</div>}>
|
<Suspense fallback={<div>Loading...</div>}>
|
||||||
<Login session={session} />
|
<Login session={session} baseURL={baseURL} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -136,11 +136,11 @@ export const authOptions: NextAuthOptions = {
|
||||||
return roles.includes("admin") || roles.includes("agent");
|
return roles.includes("admin") || roles.includes("agent");
|
||||||
},
|
},
|
||||||
session: async ({ session, token }) => {
|
session: async ({ session, token }) => {
|
||||||
const redis = new Redis(process.env.REDIS_URL);
|
// const redis = new Redis(process.env.REDIS_URL);
|
||||||
const isInvalidated = await redis.get(`invalidated:${token.sub}`);
|
// const isInvalidated = await redis.get(`invalidated:${token.sub}`);
|
||||||
if (isInvalidated) {
|
// if (isInvalidated) {
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
session.user.roles = token.roles ?? [];
|
session.user.roles = token.roles ?? [];
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ const rewriteURL = (
|
||||||
destinationBaseURL: string,
|
destinationBaseURL: string,
|
||||||
headers: any = {},
|
headers: any = {},
|
||||||
) => {
|
) => {
|
||||||
|
console.log("Rewriting URL");
|
||||||
|
console.log({ request, originBaseURL, destinationBaseURL, headers });
|
||||||
let path = request.url.replace(originBaseURL, "");
|
let path = request.url.replace(originBaseURL, "");
|
||||||
if (path.startsWith("/")) {
|
if (path.startsWith("/")) {
|
||||||
path = path.slice(1);
|
path = path.slice(1);
|
||||||
|
|
@ -30,20 +32,11 @@ const rewriteURL = (
|
||||||
|
|
||||||
const checkRewrites = async (request: NextRequestWithAuth) => {
|
const checkRewrites = async (request: NextRequestWithAuth) => {
|
||||||
const linkBaseURL = process.env.LINK_URL ?? "http://localhost:3000";
|
const linkBaseURL = process.env.LINK_URL ?? "http://localhost:3000";
|
||||||
const zammadURL = process.env.ZAMMAD_URL ?? "http://zammad-nginx:8080";
|
console.log({ linkBaseURL });
|
||||||
const opensearchBaseURL =
|
const opensearchBaseURL =
|
||||||
process.env.OPENSEARCH_DASHBOARDS_URL ??
|
process.env.OPENSEARCH_DASHBOARDS_URL ??
|
||||||
"http://opensearch-dashboards:5601";
|
"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 { token } = request.nextauth;
|
||||||
const email = token?.email?.toLowerCase() ?? "unknown";
|
const email = token?.email?.toLowerCase() ?? "unknown";
|
||||||
const roles = (token?.roles as string[]) ?? [];
|
const roles = (token?.roles as string[]) ?? [];
|
||||||
|
|
@ -59,16 +52,6 @@ const checkRewrites = async (request: NextRequestWithAuth) => {
|
||||||
opensearchBaseURL,
|
opensearchBaseURL,
|
||||||
headers,
|
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 {
|
} else {
|
||||||
const isDev = process.env.NODE_ENV === "development";
|
const isDev = process.env.NODE_ENV === "development";
|
||||||
const nonce = Buffer.from(crypto.randomUUID()).toString("base64");
|
const nonce = Buffer.from(crypto.randomUUID()).toString("base64");
|
||||||
|
|
@ -86,30 +69,30 @@ const checkRewrites = async (request: NextRequestWithAuth) => {
|
||||||
frame-ancestors 'self';
|
frame-ancestors 'self';
|
||||||
upgrade-insecure-requests;
|
upgrade-insecure-requests;
|
||||||
`;
|
`;
|
||||||
const contentSecurityPolicyHeaderValue = cspHeader
|
const contentSecurityPolicyHeaderValue = cspHeader
|
||||||
.replace(/\s{2,}/g, " ")
|
.replace(/\s{2,}/g, " ")
|
||||||
.trim();
|
.trim();
|
||||||
|
|
||||||
const requestHeaders = new Headers(request.headers);
|
const requestHeaders = new Headers(request.headers);
|
||||||
requestHeaders.set("x-nonce", nonce);
|
requestHeaders.set("x-nonce", nonce);
|
||||||
requestHeaders.set(
|
requestHeaders.set(
|
||||||
"Content-Security-Policy",
|
"Content-Security-Policy",
|
||||||
contentSecurityPolicyHeaderValue,
|
contentSecurityPolicyHeaderValue,
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = NextResponse.next({
|
const response = NextResponse.next({
|
||||||
request: {
|
request: {
|
||||||
headers: requestHeaders,
|
headers: requestHeaders,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
response.headers.set(
|
response.headers.set(
|
||||||
"Content-Security-Policy",
|
"Content-Security-Policy",
|
||||||
contentSecurityPolicyHeaderValue,
|
contentSecurityPolicyHeaderValue,
|
||||||
);
|
);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withAuth(checkRewrites, {
|
export default withAuth(checkRewrites, {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
"version": "2.4.0b1",
|
"version": "2.4.0b1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev -H 0.0.0.0",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"export": "next export",
|
"export": "next export",
|
||||||
|
|
|
||||||
|
|
@ -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_SSL_VERIFY: "false" # this doesn't set es_ssl_verify as expected, but ideally it would
|
||||||
ELASTICSEARCH_SCHEMA: "https"
|
ELASTICSEARCH_SCHEMA: "https"
|
||||||
|
|
||||||
|
x-zammad-args: &common-zammad-args
|
||||||
|
EMBEDDED: "true"
|
||||||
|
LINK_HOST: ${LINK_HOST}
|
||||||
|
|
||||||
services:
|
services:
|
||||||
zammad-init:
|
zammad-init:
|
||||||
container_name: zammad-init
|
container_name: zammad-init
|
||||||
|
|
@ -28,7 +32,7 @@ services:
|
||||||
build:
|
build:
|
||||||
context: ../zammad
|
context: ../zammad
|
||||||
args:
|
args:
|
||||||
EMBEDDED: "true"
|
<<: *common-zammad-args
|
||||||
image: registry.gitlab.com/digiresilience/link/link-stack/zammad:${LINK_STACK_VERSION}
|
image: registry.gitlab.com/digiresilience/link/link-stack/zammad:${LINK_STACK_VERSION}
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
user: 0:0
|
user: 0:0
|
||||||
|
|
@ -57,7 +61,7 @@ services:
|
||||||
build:
|
build:
|
||||||
context: ../zammad
|
context: ../zammad
|
||||||
args:
|
args:
|
||||||
EMBEDDED: "true"
|
<<: *common-zammad-args
|
||||||
image: registry.gitlab.com/digiresilience/link/link-stack/zammad:${LINK_STACK_VERSION}
|
image: registry.gitlab.com/digiresilience/link/link-stack/zammad:${LINK_STACK_VERSION}
|
||||||
restart: ${RESTART}
|
restart: ${RESTART}
|
||||||
environment:
|
environment:
|
||||||
|
|
@ -81,7 +85,7 @@ services:
|
||||||
build:
|
build:
|
||||||
context: ../zammad
|
context: ../zammad
|
||||||
args:
|
args:
|
||||||
EMBEDDED: "true"
|
<<: *common-zammad-args
|
||||||
image: registry.gitlab.com/digiresilience/link/link-stack/zammad:${LINK_STACK_VERSION}
|
image: registry.gitlab.com/digiresilience/link/link-stack/zammad:${LINK_STACK_VERSION}
|
||||||
restart: ${RESTART}
|
restart: ${RESTART}
|
||||||
volumes:
|
volumes:
|
||||||
|
|
@ -110,7 +114,7 @@ services:
|
||||||
build:
|
build:
|
||||||
context: ../zammad
|
context: ../zammad
|
||||||
args:
|
args:
|
||||||
EMBEDDED: "true"
|
<<: *common-zammad-args
|
||||||
image: registry.gitlab.com/digiresilience/link/link-stack/zammad:${LINK_STACK_VERSION}
|
image: registry.gitlab.com/digiresilience/link/link-stack/zammad:${LINK_STACK_VERSION}
|
||||||
restart: ${RESTART}
|
restart: ${RESTART}
|
||||||
volumes:
|
volumes:
|
||||||
|
|
@ -129,7 +133,7 @@ services:
|
||||||
build:
|
build:
|
||||||
context: ../zammad
|
context: ../zammad
|
||||||
args:
|
args:
|
||||||
EMBEDDED: "true"
|
<<: *common-zammad-args
|
||||||
image: registry.gitlab.com/digiresilience/link/link-stack/zammad:${LINK_STACK_VERSION}
|
image: registry.gitlab.com/digiresilience/link/link-stack/zammad:${LINK_STACK_VERSION}
|
||||||
restart: ${RESTART}
|
restart: ${RESTART}
|
||||||
volumes:
|
volumes:
|
||||||
|
|
|
||||||
|
|
@ -20,5 +20,5 @@ opensearch_security.multitenancy.tenants.preferred: [Private, Global]
|
||||||
# opensearch_security.readonly_mode.roles: [kibana_read_only]
|
# opensearch_security.readonly_mode.roles: [kibana_read_only]
|
||||||
opensearch_security.cookie.secure: false
|
opensearch_security.cookie.secure: false
|
||||||
server.host: "0.0.0.0"
|
server.host: "0.0.0.0"
|
||||||
server.basePath: "/dashboards"
|
server.basePath: "/link/dashboards"
|
||||||
server.rewriteBasePath: false
|
server.rewriteBasePath: false
|
||||||
|
|
|
||||||
|
|
@ -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 cat contrib/docker/setup.sh
|
||||||
RUN contrib/docker/setup.sh builder
|
RUN contrib/docker/setup.sh builder
|
||||||
ARG EMBEDDED=false
|
ARG EMBEDDED=false
|
||||||
RUN if [ "$EMBEDDED" = "true" ] ; then sed -i '/location \/ {/i \
|
ARG LINK_HOST=http://link:3000
|
||||||
\ \n\
|
RUN if [ "$EMBEDDED" = "true" ] ; then sed -i "/location \/ {/i\
|
||||||
\ location /link {\n\
|
location /link {\n\
|
||||||
\ proxy_pass http://link:3000;\n\
|
proxy_pass ${LINK_HOST};\n\
|
||||||
\ proxy_set_header Host $host;\n\
|
proxy_set_header Host \$host;\n\
|
||||||
\ proxy_set_header X-Real-IP $remote_addr;\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-For \$proxy_add_x_forwarded_for;\n\
|
||||||
\ proxy_set_header X-Forwarded-Proto https;\n\
|
proxy_set_header X-Forwarded-Proto https;\n\
|
||||||
\ }\n' ${ZAMMAD_DIR}/contrib/nginx/zammad.conf; fi
|
}\n\
|
||||||
|
" ${ZAMMAD_DIR}/contrib/nginx/zammad.conf; fi
|
||||||
RUN sed -i '/^[[:space:]]*# es config/a\
|
RUN sed -i '/^[[:space:]]*# es config/a\
|
||||||
echo "about to reinstall..."\n\
|
echo "about to reinstall..."\n\
|
||||||
bundle exec rails runner /opt/zammad/contrib/link/setup.rb\n\
|
bundle exec rails runner /opt/zammad/contrib/link/setup.rb\n\
|
||||||
|
|
|
||||||
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "@link-stack",
|
"name": "@link-stack",
|
||||||
"version": "2.4.0b1",
|
"version": "2.5.0b1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@link-stack",
|
"name": "@link-stack",
|
||||||
"version": "2.4.0b1",
|
"version": "2.5.0b1",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"apps/*",
|
"apps/*",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@link-stack",
|
"name": "@link-stack",
|
||||||
"version": "2.4.0b1",
|
"version": "2.5.0b1",
|
||||||
"description": "Link from the Center for Digital Resilience",
|
"description": "Link from the Center for Digital Resilience",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "dotenv -- turbo dev",
|
"dev": "dotenv -- turbo dev",
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ export const OpenSearchWrapper: FC<OpenSearchWrapperProps> = ({
|
||||||
>
|
>
|
||||||
<Iframe
|
<Iframe
|
||||||
id="opensearch"
|
id="opensearch"
|
||||||
url={`/dashboards/${url}`}
|
url={`/link/dashboards/${url}`}
|
||||||
// url={`/dashboards/${url}&_g=(filters%3A!()%2CrefreshInterval%3A(pause%3A!t%2Cvalue%3A0)%2Ctime%3A(from%3Anow-3y%2Cto%3Anow))`}
|
// url={`/dashboards/${url}&_g=(filters%3A!()%2CrefreshInterval%3A(pause%3A!t%2Cvalue%3A0)%2Ctime%3A(from%3Anow-3y%2Cto%3Anow))`}
|
||||||
width="100%"
|
width="100%"
|
||||||
height="100%"
|
height="100%"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue