WIP 5
This commit is contained in:
parent
b8c6e893ff
commit
b09cc82544
167 changed files with 2196 additions and 1302 deletions
|
|
@ -1,11 +1,9 @@
|
|||
"use client";
|
||||
|
||||
import { FC } from "react";
|
||||
import { OpenSearchWrapper } from "leafcutter-common";
|
||||
import { OpenSearchWrapper } from "leafcutter-ui";
|
||||
|
||||
export const Home: FC = () => (
|
||||
<OpenSearchWrapper
|
||||
url="/app/dashboards#/view/c39012d0-eb7a-11ed-8e00-17d7d50cd7b2?embed=true&tenant=global"
|
||||
marginTop="0"
|
||||
<OpenSearchWrapper url="/app/visualize#/edit/237b8f00-e6a0-11ee-94b3-d7b7409294e7?embed=true" marginTop="0"
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import LinkLogo from "public/link-logo-small.png";
|
|||
import { useSession, signOut } from "next-auth/react";
|
||||
import { getTicketOverviewCountsQuery } from "app/_graphql/getTicketOverviewCountsQuery";
|
||||
import { SearchBox } from "./SearchBox";
|
||||
import { fonts } from "app/_styles/theme";
|
||||
|
||||
const openWidth = 270;
|
||||
const closedWidth = 100;
|
||||
|
|
@ -49,8 +50,10 @@ const MenuItem = ({
|
|||
open = true,
|
||||
badge,
|
||||
target = "_self",
|
||||
}: any) => (
|
||||
<Link href={href} target={target}>
|
||||
}: any) => {
|
||||
const { roboto } = fonts;
|
||||
|
||||
return (<Link href={href} target={target}>
|
||||
<ListItemButton
|
||||
sx={{
|
||||
p: 0,
|
||||
|
|
@ -123,7 +126,7 @@ const MenuItem = ({
|
|||
variant="body1"
|
||||
sx={{
|
||||
fontSize: 16,
|
||||
fontFamily: "Roboto",
|
||||
fontFamily: roboto.style.fontFamily,
|
||||
fontWeight: "bold",
|
||||
border: 0,
|
||||
textAlign: "left",
|
||||
|
|
@ -157,6 +160,7 @@ const MenuItem = ({
|
|||
</ListItemButton>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
interface SidebarProps {
|
||||
open: boolean;
|
||||
|
|
@ -166,6 +170,7 @@ interface SidebarProps {
|
|||
export const Sidebar: FC<SidebarProps> = ({ open, setOpen }) => {
|
||||
const pathname = usePathname();
|
||||
const { data: session } = useSession();
|
||||
const { poppins } = fonts;
|
||||
const username = session?.user?.name || "User";
|
||||
// @ts-ignore
|
||||
const roles = session?.user?.roles || [];
|
||||
|
|
@ -272,7 +277,7 @@ export const Sidebar: FC<SidebarProps> = ({ open, setOpen }) => {
|
|||
fontWeight: 700,
|
||||
mt: 1,
|
||||
ml: 0.5,
|
||||
fontFamily: "Poppins",
|
||||
fontFamily: poppins.style.fontFamily,
|
||||
}}
|
||||
>
|
||||
CDR Link
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
"use client";
|
||||
|
||||
import { FC, /* useEffect,*/ useState } from "react";
|
||||
import { Home as HomeInternal } from "leafcutter-common";
|
||||
// import { fetchLeafcutter } from "@/app/_lib/utils";
|
||||
import ClientOnly from "@/app/(main)/_components/ClientOnly";
|
||||
|
||||
export const Home: FC = () => {
|
||||
const [visualizations, setVisualizations] = useState([]);
|
||||
/*
|
||||
useEffect(() => {
|
||||
const getVisualizations = async () => {
|
||||
const visualizations = await fetchLeafcutter(
|
||||
"/api/visualizations/list",
|
||||
{},
|
||||
);
|
||||
if (visualizations) {
|
||||
setVisualizations(visualizations);
|
||||
}
|
||||
};
|
||||
|
||||
getVisualizations();
|
||||
}, []);
|
||||
*/
|
||||
return (
|
||||
<ClientOnly>
|
||||
<HomeInternal visualizations={visualizations} />
|
||||
</ClientOnly>
|
||||
);
|
||||
};
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
import { FC, PropsWithChildren } from "react";
|
||||
import { Box } from "@mui/material";
|
||||
|
||||
export const LeafcutterWrapper: FC<PropsWithChildren> = ({ children }) => {
|
||||
return <Box sx={{ p: 3 }}>{children}</Box>;
|
||||
};
|
||||
|
|
@ -1,10 +1,5 @@
|
|||
import { Box } from "@mui/material";
|
||||
import { About } from "leafcutter-common";
|
||||
import { About } from "leafcutter-ui";
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<Box sx={{ p: 3 }}>
|
||||
<About />
|
||||
</Box>
|
||||
);
|
||||
return <About />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,8 @@
|
|||
// import { getTemplates } from "app/_lib/opensearch";
|
||||
import { Create } from "leafcutter-common";
|
||||
import { Box } from "@mui/material";
|
||||
import { getTemplates } from "opensearch-common";
|
||||
import { Create } from "leafcutter-ui";
|
||||
|
||||
export default async function Page() {
|
||||
const templates = []; // await getTemplates(100);
|
||||
const templates = await getTemplates(100);
|
||||
|
||||
return (
|
||||
<Box sx={{ p: 3 }}>
|
||||
<Create templates={templates} />
|
||||
</Box>
|
||||
);
|
||||
return <Create templates={templates} />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,5 @@
|
|||
import { Box } from "@mui/material";
|
||||
import { FAQ } from "leafcutter-common";
|
||||
import { FAQ } from "leafcutter-ui";
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<Box sx={{ p: 3 }}>
|
||||
<FAQ />
|
||||
</Box>
|
||||
);
|
||||
return <FAQ />;
|
||||
}
|
||||
|
|
|
|||
10
apps/link/app/(main)/leafcutter/layout.tsx
Normal file
10
apps/link/app/(main)/leafcutter/layout.tsx
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { ReactNode } from "react";
|
||||
import { LeafcutterWrapper } from "leafcutter-ui";
|
||||
|
||||
type LayoutProps = {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
export default function Layout({ children }: LayoutProps) {
|
||||
return <LeafcutterWrapper>{children}</LeafcutterWrapper>;
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
import { Box } from "@mui/material";
|
||||
import { FAQ } from "leafcutter-common";
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<Box sx={{ p: 3 }}>
|
||||
<FAQ />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import { Home } from "./_components/Home";
|
||||
import { LeafcutterWrapper } from "./_components/LeafcutterWrapper";
|
||||
import { Home, LeafcutterWrapper } from "leafcutter-ui";
|
||||
|
||||
export default async function Page() {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,12 +1,7 @@
|
|||
import { Box } from "@mui/material";
|
||||
import { Trends } from "leafcutter-common";
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<Box sx={{ p: 3 }}>
|
||||
<Trends visualizations={[]} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
import { Trends } from "leafcutter-ui";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export default function Page() {
|
||||
return <Trends visualizations={[]} />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,23 @@
|
|||
import { Metadata } from "next";
|
||||
import { Home } from "./_components/Home";
|
||||
import { getServerSession } from "app/_lib/authentication";
|
||||
import { Home } from "leafcutter-ui";
|
||||
import { getUserVisualizations } from "opensearch-common";
|
||||
import { LeafcutterWrapper } from "leafcutter-ui";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Link",
|
||||
};
|
||||
|
||||
export default function Page() {
|
||||
return <Home />;
|
||||
export default async function Page() {
|
||||
const session = await getServerSession();
|
||||
const {
|
||||
user: { email },
|
||||
}: any = session;
|
||||
const visualizations = await getUserVisualizations(email ?? "none", 20);
|
||||
|
||||
return (
|
||||
<LeafcutterWrapper>
|
||||
<Home visualizations={visualizations} showWelcome={false} />
|
||||
</LeafcutterWrapper>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
"use client";
|
||||
|
||||
import { FC, PropsWithChildren, useState } from "react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { CssBaseline } from "@mui/material";
|
||||
import { CookiesProvider } from "react-cookie";
|
||||
import { SessionProvider } from "next-auth/react";
|
||||
|
|
@ -12,7 +11,7 @@ import { I18n } from "react-polyglot";
|
|||
import { AdapterDateFns } from "@mui/x-date-pickers-pro/AdapterDateFnsV3";
|
||||
import { LocalizationProvider } from "@mui/x-date-pickers-pro";
|
||||
import { LicenseInfo } from "@mui/x-date-pickers-pro";
|
||||
import { locales } from "leafcutter-common";
|
||||
import { locales, LeafcutterProvider } from "leafcutter-ui";
|
||||
|
||||
LicenseInfo.setLicenseKey(
|
||||
"7c9bf25d9e240f76e77cbf7d2ba58a23Tz02NjU4OCxFPTE3MTU4NjIzMzQ2ODgsUz1wcm8sTE09c3Vic2NyaXB0aW9uLEtWPTI=",
|
||||
|
|
@ -113,7 +112,9 @@ export const MultiProvider: FC<PropsWithChildren> = ({ children }) => {
|
|||
<CookiesProvider>
|
||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||
<I18n locale={locale} messages={messages[locale]}>
|
||||
{children}
|
||||
<LeafcutterProvider>
|
||||
{children}
|
||||
</LeafcutterProvider>
|
||||
</I18n>
|
||||
</LocalizationProvider>
|
||||
</CookiesProvider>
|
||||
|
|
|
|||
140
apps/link/app/_lib/authentication.ts
Normal file
140
apps/link/app/_lib/authentication.ts
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
import type {
|
||||
GetServerSidePropsContext,
|
||||
NextApiRequest,
|
||||
NextApiResponse,
|
||||
} from "next";
|
||||
import {
|
||||
NextAuthOptions,
|
||||
getServerSession as internalGetServerSession,
|
||||
} from "next-auth";
|
||||
import Google from "next-auth/providers/google";
|
||||
import Credentials from "next-auth/providers/credentials";
|
||||
import Apple from "next-auth/providers/apple";
|
||||
|
||||
const headers = { Authorization: `Token ${process.env.ZAMMAD_API_TOKEN}` };
|
||||
|
||||
const fetchRoles = async () => {
|
||||
const url = `${process.env.ZAMMAD_URL}/api/v1/roles`;
|
||||
const res = await fetch(url, { headers });
|
||||
const roles = await res.json();
|
||||
console.log({ roles });
|
||||
const formattedRoles = roles.reduce((acc: any, role: any) => {
|
||||
acc[role.id] = role.name;
|
||||
return acc;
|
||||
}, {});
|
||||
return formattedRoles;
|
||||
};
|
||||
|
||||
const fetchUser = async (email: string) => {
|
||||
console.log({ email });
|
||||
const url = `${process.env.ZAMMAD_URL}/api/v1/users/search?query=login:${email}&limit=1`;
|
||||
console.log({ url });
|
||||
const res = await fetch(url, { headers });
|
||||
console.log({ res });
|
||||
const users = await res.json();
|
||||
console.log({ users });
|
||||
const user = users?.[0];
|
||||
|
||||
return user;
|
||||
};
|
||||
|
||||
const getUserRoles = async (email: string) => {
|
||||
try {
|
||||
const user = await fetchUser(email);
|
||||
console.log({ user });
|
||||
const allRoles = await fetchRoles();
|
||||
console.log({ allRoles });
|
||||
const roles = user.role_ids.map((roleID: number) => {
|
||||
const role = allRoles[roleID];
|
||||
return role ? role.toLowerCase().replace(" ", "_") : null;
|
||||
});
|
||||
return roles.filter((role: string) => role !== null);
|
||||
} catch (e) {
|
||||
console.log({ e });
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
const login = async (email: string, password: string) => {
|
||||
const url = `${process.env.ZAMMAD_URL}/api/v1/users/me`;
|
||||
console.log({ url });
|
||||
const authorization =
|
||||
"Basic " + Buffer.from(email + ":" + password).toString("base64");
|
||||
const res = await fetch(url, {
|
||||
headers: {
|
||||
authorization,
|
||||
},
|
||||
});
|
||||
const user = await res.json();
|
||||
console.log({ user });
|
||||
|
||||
if (user && !user.error && user.id) {
|
||||
return user;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const authOptions: NextAuthOptions = {
|
||||
pages: {
|
||||
signIn: "/login",
|
||||
error: "/login",
|
||||
signOut: "/logout",
|
||||
},
|
||||
providers: [
|
||||
Google({
|
||||
clientId: process.env.GOOGLE_CLIENT_ID,
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
||||
}),
|
||||
Apple({
|
||||
clientId: process.env.APPLE_CLIENT_ID,
|
||||
clientSecret: process.env.APPLE_CLIENT_SECRET,
|
||||
}),
|
||||
Credentials({
|
||||
name: "Zammad",
|
||||
credentials: {
|
||||
email: { label: "Email", type: "text" },
|
||||
password: { label: "Password", type: "password" },
|
||||
},
|
||||
async authorize(credentials, req) {
|
||||
const user = await login(credentials.email, credentials.password);
|
||||
if (user) {
|
||||
return user;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
}),
|
||||
],
|
||||
secret: process.env.NEXTAUTH_SECRET,
|
||||
callbacks: {
|
||||
signIn: async ({ user, account, profile }) => {
|
||||
const roles = (await getUserRoles(user.email)) ?? [];
|
||||
return (
|
||||
roles.includes("admin") ||
|
||||
roles.includes("agent") ||
|
||||
process.env.SETUP_MODE === "true"
|
||||
);
|
||||
},
|
||||
session: async ({ session, user, token }) => {
|
||||
// @ts-ignore
|
||||
session.user.roles = token.roles ?? [];
|
||||
// @ts-ignore
|
||||
session.user.leafcutter = token.leafcutter; // remove
|
||||
return session;
|
||||
},
|
||||
jwt: async ({ token, user, account, profile, trigger }) => {
|
||||
if (user) {
|
||||
token.roles = (await getUserRoles(user.email)) ?? [];
|
||||
}
|
||||
return token;
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export const getServerSession = (
|
||||
...args:
|
||||
| [GetServerSidePropsContext["req"], GetServerSidePropsContext["res"]]
|
||||
| [NextApiRequest, NextApiResponse]
|
||||
| []
|
||||
) => internalGetServerSession(...args, authOptions);
|
||||
|
|
@ -1,128 +1,6 @@
|
|||
import NextAuth from "next-auth";
|
||||
import Google from "next-auth/providers/google";
|
||||
import Credentials from "next-auth/providers/credentials";
|
||||
import Apple from "next-auth/providers/apple";
|
||||
import { authOptions } from "app/_lib/authentication";
|
||||
|
||||
const headers = { Authorization: `Token ${process.env.ZAMMAD_API_TOKEN}` };
|
||||
|
||||
const fetchRoles = async () => {
|
||||
const url = `${process.env.ZAMMAD_URL}/api/v1/roles`;
|
||||
const res = await fetch(url, { headers });
|
||||
const roles = await res.json();
|
||||
console.log({ roles });
|
||||
const formattedRoles = roles.reduce((acc: any, role: any) => {
|
||||
acc[role.id] = role.name;
|
||||
return acc;
|
||||
}, {});
|
||||
return formattedRoles;
|
||||
};
|
||||
|
||||
const fetchUser = async (email: string) => {
|
||||
console.log({ email });
|
||||
const url = `${process.env.ZAMMAD_URL}/api/v1/users/search?query=login:${email}&limit=1`;
|
||||
console.log({ url });
|
||||
const res = await fetch(url, { headers });
|
||||
console.log({ res });
|
||||
const users = await res.json();
|
||||
console.log({ users });
|
||||
const user = users?.[0];
|
||||
|
||||
return user;
|
||||
};
|
||||
|
||||
const getUserRoles = async (email: string) => {
|
||||
try {
|
||||
const user = await fetchUser(email);
|
||||
console.log({ user });
|
||||
const allRoles = await fetchRoles();
|
||||
console.log({ allRoles });
|
||||
const roles = user.role_ids.map((roleID: number) => {
|
||||
const role = allRoles[roleID];
|
||||
return role ? role.toLowerCase().replace(" ", "_") : null;
|
||||
});
|
||||
return roles.filter((role: string) => role !== null);
|
||||
} catch (e) {
|
||||
console.log({ e });
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
const login = async (email: string, password: string) => {
|
||||
const url = `${process.env.ZAMMAD_URL}/api/v1/users/me`;
|
||||
console.log({ url });
|
||||
const authorization =
|
||||
"Basic " + Buffer.from(email + ":" + password).toString("base64");
|
||||
const res = await fetch(url, {
|
||||
headers: {
|
||||
authorization,
|
||||
},
|
||||
});
|
||||
const user = await res.json();
|
||||
console.log({ user });
|
||||
|
||||
if (user && !user.error && user.id) {
|
||||
return user;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const handler = NextAuth({
|
||||
pages: {
|
||||
signIn: "/login",
|
||||
error: "/login",
|
||||
signOut: "/logout",
|
||||
},
|
||||
providers: [
|
||||
Google({
|
||||
clientId: process.env.GOOGLE_CLIENT_ID,
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
||||
}),
|
||||
Apple({
|
||||
clientId: process.env.APPLE_CLIENT_ID,
|
||||
clientSecret: process.env.APPLE_CLIENT_SECRET,
|
||||
}),
|
||||
Credentials({
|
||||
name: "Zammad",
|
||||
credentials: {
|
||||
email: { label: "Email", type: "text" },
|
||||
password: { label: "Password", type: "password" },
|
||||
},
|
||||
async authorize(credentials, req) {
|
||||
const user = await login(credentials.email, credentials.password);
|
||||
if (user) {
|
||||
return user;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
}),
|
||||
],
|
||||
secret: process.env.NEXTAUTH_SECRET,
|
||||
|
||||
callbacks: {
|
||||
signIn: async ({ user, account, profile }) => {
|
||||
const roles = (await getUserRoles(user.email)) ?? [];
|
||||
return (
|
||||
roles.includes("admin") ||
|
||||
roles.includes("agent") ||
|
||||
process.env.SETUP_MODE === "true"
|
||||
);
|
||||
},
|
||||
session: async ({ session, user, token }) => {
|
||||
// @ts-ignore
|
||||
session.user.roles = token.roles ?? [];
|
||||
// @ts-ignore
|
||||
session.user.leafcutter = token.leafcutter; // remove
|
||||
return session;
|
||||
},
|
||||
jwt: async ({ token, user, account, profile, trigger }) => {
|
||||
if (user) {
|
||||
token.roles = (await getUserRoles(user.email)) ?? [];
|
||||
}
|
||||
return token;
|
||||
},
|
||||
},
|
||||
});
|
||||
const handler = NextAuth(authOptions);
|
||||
|
||||
export { handler as GET, handler as POST };
|
||||
|
|
|
|||
|
|
@ -1,94 +1,83 @@
|
|||
import { NextResponse } from 'next/server';
|
||||
import { NextResponse } from "next/server";
|
||||
import { withAuth, NextRequestWithAuth } from "next-auth/middleware";
|
||||
|
||||
const rewriteURL = (request: NextRequestWithAuth, originBaseURL: string, destinationBaseURL: string, headers: any = {}) => {
|
||||
if (request.nextUrl.pathname.startsWith('/api/v1/reports/sets')) {
|
||||
console.log(request.nextUrl.searchParams.get("sheet"));
|
||||
NextResponse.next();
|
||||
}
|
||||
|
||||
const rewriteURL = (
|
||||
request: NextRequestWithAuth,
|
||||
originBaseURL: string,
|
||||
destinationBaseURL: string,
|
||||
headers: any = {},
|
||||
) => {
|
||||
const destinationURL = request.url.replace(originBaseURL, destinationBaseURL);
|
||||
|
||||
console.log(`Rewriting ${request.url} to ${destinationURL}`);
|
||||
|
||||
const requestHeaders = new Headers(request.headers);
|
||||
for (const [key, value] of Object.entries(headers)) {
|
||||
requestHeaders.set(key, value as string);
|
||||
}
|
||||
requestHeaders.delete("connection");
|
||||
|
||||
requestHeaders.delete('connection');
|
||||
|
||||
return NextResponse.rewrite(new URL(destinationURL), { request: { headers: requestHeaders } });
|
||||
return NextResponse.rewrite(new URL(destinationURL), {
|
||||
request: { headers: requestHeaders },
|
||||
});
|
||||
};
|
||||
|
||||
const checkRewrites = async (request: NextRequestWithAuth) => {
|
||||
const linkBaseURL = process.env.LINK_URL ?? "http://localhost:3000";
|
||||
const zammadURL = process.env.ZAMMAD_URL ?? "http://zammad-nginx:8080";
|
||||
const opensearchURL = process.env.OPENSEARCH_URL ?? "http://macmini:5601";
|
||||
const metamigoURL = process.env.METAMIGO_URL ?? "http://metamigo-api:3000";
|
||||
const labelStudioURL = process.env.LABEL_STUDIO_URL ?? "http://label-studio:8080";
|
||||
const opensearchDashboardsURL =
|
||||
process.env.OPENSEARCH_DASHBOARDS_URL ?? "http://macmini:5601";
|
||||
const zammadPaths = ["/zammad", "/api/v1", "/auth/sso", "/assets", "/mobile"];
|
||||
const { token } = request.nextauth;
|
||||
const headers = { 'X-Forwarded-User': token?.email?.toLowerCase() };
|
||||
console.log({ pathname: request.nextUrl.pathname });
|
||||
const email = token?.email?.toLowerCase() ?? "unknown";
|
||||
let headers = { "x-forwarded-user": email };
|
||||
|
||||
if (request.nextUrl.pathname.startsWith('/opensearch')) {
|
||||
const headers = {
|
||||
'x-proxy-user': "admin",
|
||||
'x-proxy-roles': "all_access",
|
||||
// 'X-Forwarded-For': "link"
|
||||
};
|
||||
return rewriteURL(request, `${linkBaseURL}/opensearch`, opensearchURL, headers);
|
||||
} else if (request.nextUrl.pathname.startsWith('/metamigo')) {
|
||||
return rewriteURL(request, `${linkBaseURL}/metamigo`, metamigoURL);
|
||||
} else if (request.nextUrl.pathname.startsWith('/label-studio')) {
|
||||
return rewriteURL(request, `${linkBaseURL}/label-studio`, labelStudioURL);
|
||||
} else if (request.nextUrl.pathname.startsWith('/zammad')) {
|
||||
if (request.nextUrl.pathname.startsWith("/dashboards")) {
|
||||
const roles: string[] = (token?.roles as string[]) ?? [];
|
||||
const leafcutterRole = roles.includes("admin")
|
||||
? "leafcutter_admin"
|
||||
: "leafcutter_user";
|
||||
headers["x-forwarded-roles"] = "admin"; // leafcutterRole;
|
||||
// headers["secruitytenant"] = "global";
|
||||
// headers["x-forwarded-for"] = 'link';
|
||||
|
||||
return rewriteURL(
|
||||
request,
|
||||
`${linkBaseURL}/dashboards`,
|
||||
opensearchDashboardsURL,
|
||||
headers,
|
||||
);
|
||||
} else if (request.nextUrl.pathname.startsWith("/zammad")) {
|
||||
return rewriteURL(request, `${linkBaseURL}/zammad`, zammadURL, headers);
|
||||
} else if (request.nextUrl.pathname.startsWith('/auth/sso') || request.nextUrl.pathname.startsWith('/assets')) {
|
||||
return rewriteURL(request, linkBaseURL, zammadURL, headers);
|
||||
} else if (request.nextUrl.pathname.startsWith('/proxy/api') || request.nextUrl.pathname.startsWith('/proxy/assets')) {
|
||||
return rewriteURL(request, `${linkBaseURL}/proxy`, zammadURL);
|
||||
} else if (request.nextUrl.pathname.startsWith('/api/v1') || request.nextUrl.pathname.startsWith('/auth/sso') || request.nextUrl.pathname.startsWith('/mobile')) {
|
||||
} else if (zammadPaths.some((p) => request.nextUrl.pathname.startsWith(p))) {
|
||||
return rewriteURL(request, linkBaseURL, zammadURL, headers);
|
||||
}
|
||||
|
||||
return NextResponse.next();
|
||||
};
|
||||
|
||||
export default withAuth(
|
||||
checkRewrites,
|
||||
{
|
||||
pages: {
|
||||
signIn: `/login`,
|
||||
export default withAuth(checkRewrites, {
|
||||
pages: {
|
||||
signIn: `/login`,
|
||||
},
|
||||
callbacks: {
|
||||
authorized: ({ token, req }) => {
|
||||
if (req.nextUrl.pathname === "/api/v1") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (process.env.SETUP_MODE === "true") {
|
||||
return true;
|
||||
}
|
||||
|
||||
const roles: any = token?.roles ?? [];
|
||||
if (roles.includes("admin") || roles.includes("agent")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
callbacks: {
|
||||
authorized: ({ token, req }) => {
|
||||
const {
|
||||
url,
|
||||
} = req;
|
||||
|
||||
const noAuthPaths = ["/login", "/api/v1"];
|
||||
const parsedURL = new URL(url);
|
||||
const path = parsedURL.pathname;
|
||||
|
||||
if (noAuthPaths.some((p: string) => path.startsWith(p))) {
|
||||
console.log({ p: parsedURL.pathname, auth: "no" });
|
||||
return true;
|
||||
}
|
||||
|
||||
const roles: any = token?.roles ?? [];
|
||||
if (roles.includes("admin") || roles.includes("agent") || process.env.SETUP_MODE === "true") {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export const config = {
|
||||
matcher: [
|
||||
'/((?!ws|wss|_next/static|_next/image|favicon.ico).*)',
|
||||
],
|
||||
matcher: ["/((?!ws|wss|_next/static|_next/image|favicon.ico).*)"],
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,33 +4,13 @@ const nextConfig = {
|
|||
experimental: {
|
||||
missingSuspenseWithCSRBailout: false,
|
||||
},
|
||||
modularizeImports: {
|
||||
"@mui/material": {
|
||||
transform: "@mui/material/{{member}}",
|
||||
},
|
||||
"@mui/icons-material": {
|
||||
transform: "@mui/icons-material/{{member}}",
|
||||
},
|
||||
},
|
||||
transpilePackages: ["leafcutter-common"],
|
||||
transpilePackages: ["leafcutter-ui", "metamigo-ui", "opensearch-common", "ui"],
|
||||
publicRuntimeConfig: {
|
||||
linkURL: process.env.LINK_URL ?? "http://localhost:3000",
|
||||
leafcutterURL:
|
||||
process.env.LEAFCUTTER_URL ?? "https://lc.digiresilience.org",
|
||||
metamigoURL: process.env.METAMIGO_URL ?? "http://localhost:8002",
|
||||
labelStudioURL: process.env.LABEL_STUDIO_URL ?? "http://localhost:8006",
|
||||
muiLicenseKey: process.env.MUI_LICENSE_KEY ?? "",
|
||||
},
|
||||
async rewrites() {
|
||||
return {
|
||||
fallback: [
|
||||
{
|
||||
source: "/:path*",
|
||||
destination: `/proxy/leafcutter/:path*`,
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = nextConfig;
|
||||
|
|
|
|||
|
|
@ -16,26 +16,24 @@
|
|||
"@emotion/server": "^11.11.0",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@mui/icons-material": "^5",
|
||||
"@mui/lab": "^5.0.0-alpha.168",
|
||||
"@mui/lab": "^5.0.0-alpha.169",
|
||||
"@mui/material": "^5",
|
||||
"@mui/x-data-grid-pro": "^6.19.6",
|
||||
"@mui/x-date-pickers-pro": "^6.19.7",
|
||||
"cryptr": "^6.3.0",
|
||||
"date-fns": "^3.5.0",
|
||||
"date-fns": "^3.6.0",
|
||||
"graphql-request": "^6.1.0",
|
||||
"leafcutter-common": "*",
|
||||
"material-ui-popup-state": "^5.0.10",
|
||||
"metamigo-common": "*",
|
||||
"leafcutter-ui": "*",
|
||||
"material-ui-popup-state": "^5.1.0",
|
||||
"metamigo-ui": "*",
|
||||
"mui-chips-input": "^2.1.4",
|
||||
"next": "14.1.3",
|
||||
"next": "14.1.4",
|
||||
"next-auth": "^4.24.7",
|
||||
"opensearch-common": "*",
|
||||
"react": "18.2.0",
|
||||
"react-cookie": "^7.1.0",
|
||||
"react-digit-input": "^2.1.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-iframe": "^1.8.5",
|
||||
"react-polyglot": "^0.7.2",
|
||||
"react-timer-hook": "^3.0.7",
|
||||
"sharp": "^0.33.2",
|
||||
"swr": "^2.2.5",
|
||||
"tss-react": "^4.9.4",
|
||||
|
|
@ -43,14 +41,14 @@
|
|||
"ui": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.24.0",
|
||||
"@types/node": "^20.11.28",
|
||||
"@types/react": "18.2.66",
|
||||
"@babel/core": "^7.24.1",
|
||||
"@types/node": "^20.11.30",
|
||||
"@types/react": "18.2.67",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"babel-loader": "^9.1.3",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-next": "^14.1.3",
|
||||
"eslint-config-next": "^14.1.4",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-jsx-a11y": "^6.8.0",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue