This commit is contained in:
@@ -1,59 +0,0 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { getSiteInfo } from "../api/site";
|
||||
import { getIpList } from "../api/ip";
|
||||
import { ENDPOINT } from "../config";
|
||||
import { getCookie } from "../lib";
|
||||
|
||||
const siteId = getCookie("site-id-key") ?? "";
|
||||
|
||||
const ClientIpGuard = ({
|
||||
currentPath,
|
||||
children,
|
||||
}: {
|
||||
currentPath?: string;
|
||||
children: React.ReactNode;
|
||||
}) => {
|
||||
const queryClient = useQueryClient();
|
||||
const [clientIp, setClientIp] = useState("");
|
||||
const [isAllowed, setIsAllowed] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const response = await fetch("https://api.ipify.org?format=json");
|
||||
const data = await response.json();
|
||||
if (!data?.ip) return;
|
||||
setClientIp(data.ip);
|
||||
})();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
if (!siteId || !clientIp) return;
|
||||
|
||||
const siteInfo = await queryClient.ensureQueryData({
|
||||
queryKey: [ENDPOINT.CMS_SERVICE.SITES, siteId],
|
||||
queryFn: () => getSiteInfo(siteId),
|
||||
});
|
||||
|
||||
if (siteInfo.siteKndCd === "O") return;
|
||||
|
||||
const { content: ipList } = await getIpList({
|
||||
siteId,
|
||||
prmYn: "Y",
|
||||
});
|
||||
|
||||
const allowedClientIp = ipList.some((ip) => ip.ipAddr === clientIp);
|
||||
setIsAllowed(allowedClientIp);
|
||||
})();
|
||||
}, [queryClient, clientIp, currentPath]);
|
||||
|
||||
if (!isAllowed) {
|
||||
alert("허용되지 않은 IP로 접근하였습니다.");
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return <>{children}</>;
|
||||
};
|
||||
|
||||
export { ClientIpGuard };
|
||||
@@ -3,7 +3,6 @@ import type { QueryClient } from "@tanstack/react-query";
|
||||
import { QueryProvider } from "../../provider/query-provider";
|
||||
import { PopupProvider } from "../../provider/popup-provider";
|
||||
import { HelpDialogProvider } from "../../provider/help-dialog-context";
|
||||
import { ClientIpGuard } from "../../lib/client-ip-guard";
|
||||
import type { MenuItem } from "../../api";
|
||||
import { SidebarProvider } from "../sidebar";
|
||||
import { LNB } from "../lnb";
|
||||
@@ -29,30 +28,28 @@ export function BaseLayout({
|
||||
}) {
|
||||
return (
|
||||
<QueryProvider queryClient={queryClient}>
|
||||
<ClientIpGuard currentPath={currentPath}>
|
||||
<PopupProvider>
|
||||
<HelpDialogProvider>
|
||||
<SidebarProvider>
|
||||
<div className="flex-1">
|
||||
<Header
|
||||
authService={authService}
|
||||
tokenManager={authService ? undefined : tokenManager}
|
||||
<PopupProvider>
|
||||
<HelpDialogProvider>
|
||||
<SidebarProvider>
|
||||
<div className="flex-1">
|
||||
<Header
|
||||
authService={authService}
|
||||
tokenManager={authService ? undefined : tokenManager}
|
||||
/>
|
||||
<div className="flex">
|
||||
<LNB
|
||||
currentPath={currentPath}
|
||||
handleMenuClick={handleMenuClick}
|
||||
/>
|
||||
<div className="flex">
|
||||
<LNB
|
||||
currentPath={currentPath}
|
||||
handleMenuClick={handleMenuClick}
|
||||
/>
|
||||
<div className="flex min-h-[calc(100vh-50px)] flex-1 flex-col">
|
||||
<div className="flex-1">{children}</div>
|
||||
<Footer />
|
||||
</div>
|
||||
<div className="flex min-h-[calc(100vh-50px)] flex-1 flex-col">
|
||||
<div className="flex-1">{children}</div>
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</SidebarProvider>
|
||||
</HelpDialogProvider>
|
||||
</PopupProvider>
|
||||
</ClientIpGuard>
|
||||
</div>
|
||||
</SidebarProvider>
|
||||
</HelpDialogProvider>
|
||||
</PopupProvider>
|
||||
</QueryProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { QueryClient } from "@tanstack/react-query";
|
||||
import { QueryProvider } from "../../provider/query-provider";
|
||||
import { PopupProvider } from "../../provider/popup-provider";
|
||||
import { HelpDialogProvider } from "../../provider/help-dialog-context";
|
||||
import { ClientIpGuard } from "../../lib/client-ip-guard";
|
||||
import type { MenuItem } from "../../api";
|
||||
import { SidebarProvider } from "../sidebar";
|
||||
import { LNB } from "../lnb";
|
||||
@@ -25,26 +24,24 @@ export function NoFooterLayout({
|
||||
}) {
|
||||
return (
|
||||
<QueryProvider queryClient={queryClient}>
|
||||
<ClientIpGuard currentPath={currentPath}>
|
||||
<PopupProvider>
|
||||
<HelpDialogProvider>
|
||||
<SidebarProvider>
|
||||
<div className="flex-1">
|
||||
<Header authService={authService} />
|
||||
<div className="flex">
|
||||
<LNB
|
||||
currentPath={currentPath}
|
||||
handleMenuClick={handleMenuClick}
|
||||
/>
|
||||
<div className="flex min-h-[calc(100vh-50px)] flex-1 flex-col overflow-auto">
|
||||
<div className="flex-1">{children}</div>
|
||||
</div>
|
||||
<PopupProvider>
|
||||
<HelpDialogProvider>
|
||||
<SidebarProvider>
|
||||
<div className="flex-1">
|
||||
<Header authService={authService} />
|
||||
<div className="flex">
|
||||
<LNB
|
||||
currentPath={currentPath}
|
||||
handleMenuClick={handleMenuClick}
|
||||
/>
|
||||
<div className="flex min-h-[calc(100vh-50px)] flex-1 flex-col overflow-auto">
|
||||
<div className="flex-1">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
</SidebarProvider>
|
||||
</HelpDialogProvider>
|
||||
</PopupProvider>
|
||||
</ClientIpGuard>
|
||||
</div>
|
||||
</SidebarProvider>
|
||||
</HelpDialogProvider>
|
||||
</PopupProvider>
|
||||
</QueryProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import type { QueryClient } from "@tanstack/react-query";
|
||||
import { QueryProvider } from "../../provider/query-provider";
|
||||
import { PopupProvider } from "../../provider/popup-provider";
|
||||
import { HelpDialogProvider } from "../../provider/help-dialog-context";
|
||||
import { ClientIpGuard } from "../../lib/client-ip-guard";
|
||||
import type { MenuItem } from "../../api";
|
||||
import { SidebarProvider } from "../sidebar";
|
||||
import { Header } from "../header";
|
||||
@@ -14,7 +13,6 @@ export function NoLNBLayout({
|
||||
children,
|
||||
queryClient,
|
||||
authService,
|
||||
currentPath,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
queryClient?: QueryClient;
|
||||
@@ -24,23 +22,21 @@ export function NoLNBLayout({
|
||||
}) {
|
||||
return (
|
||||
<QueryProvider queryClient={queryClient}>
|
||||
<ClientIpGuard currentPath={currentPath}>
|
||||
<PopupProvider>
|
||||
<HelpDialogProvider>
|
||||
<SidebarProvider>
|
||||
<div className="flex-1">
|
||||
<Header authService={authService} />
|
||||
<div className="flex">
|
||||
<div className="flex min-h-[calc(100vh-50px)] flex-1 flex-col overflow-auto">
|
||||
<div className="flex-1">{children}</div>
|
||||
<Footer />
|
||||
</div>
|
||||
<PopupProvider>
|
||||
<HelpDialogProvider>
|
||||
<SidebarProvider>
|
||||
<div className="flex-1">
|
||||
<Header authService={authService} />
|
||||
<div className="flex">
|
||||
<div className="flex min-h-[calc(100vh-50px)] flex-1 flex-col overflow-auto">
|
||||
<div className="flex-1">{children}</div>
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</SidebarProvider>
|
||||
</HelpDialogProvider>
|
||||
</PopupProvider>
|
||||
</ClientIpGuard>
|
||||
</div>
|
||||
</SidebarProvider>
|
||||
</HelpDialogProvider>
|
||||
</PopupProvider>
|
||||
</QueryProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,13 +3,9 @@
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["."],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist",
|
||||
"coverage",
|
||||
"storybook-static"
|
||||
]
|
||||
"exclude": ["node_modules", "dist", "coverage", "storybook-static"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user