active sso feature
All checks were successful
Build and Deploy Next.js + Nginx Docker Image / build-and-deploy (push) Successful in 2m56s
Build and Deploy Next.js + Nginx Docker Image / deploy (push) Successful in 6s

This commit is contained in:
Hossein Salari 2026-02-26 13:22:23 +03:30
parent cb6052820e
commit 37188ff30a
4 changed files with 91 additions and 45 deletions

View File

@ -9,10 +9,10 @@ const axiosInstance = axios.create({
axiosInstance.interceptors.request.use(
async (config) => {
// if (keycloak?.authenticated) {
// config.headers.Authorization = `Bearer ${keycloak.token}`;
// await keycloak.updateToken(30);
// }
if (keycloak?.authenticated) {
config.headers.Authorization = `Bearer ${keycloak.token}`;
await keycloak.updateToken(30);
}
return config;
},
(error) => Promise.reject(error),
@ -23,22 +23,21 @@ axiosInstance.interceptors.response.use(
async (error) => {
const originalRequest = error.config;
// if (error?.response?.status === 401 && !originalRequest._retry) {
// originalRequest._retry = true;
// keycloak.login();
// try {
// await keycloak.updateToken(30);
// const newToken = keycloak.token;
if (error?.response?.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
keycloak.login();
try {
await keycloak.updateToken(30);
const newToken = keycloak.token;
// if (newToken) {
// originalRequest.headers["Authorization"] = `Bearer ${newToken}`;
// return axiosInstance(originalRequest);
// }
// } catch (refreshError) {
// localStorage.removeItem("access_account");
// keycloak.logout({ redirectUri: window.location.origin });
// }
// }
if (newToken) {
originalRequest.headers["Authorization"] = `Bearer ${newToken}`;
return axiosInstance(originalRequest);
}
} catch (refreshError) {
keycloak.logout({ redirectUri: window.location.origin });
}
}
return Promise.reject(error);
},

View File

@ -3,7 +3,7 @@ import Keycloak from "keycloak-js";
const keycloak = new Keycloak({
url: "https://auth.ibagher.ir",
realm: "bi",
clientId: "rasad",
clientId: "generative",
});
export const initKeycloak = () =>

View File

@ -1,32 +1,44 @@
import "@/styles/globals.css";
import { ChakraProvider } from "@chakra-ui/react";
import { ChakraProvider, Spinner } from "@chakra-ui/react";
import { QueryParamProvider } from "use-query-params";
import { NextAdapter } from "next-query-params";
import { theme } from "@/components/theme";
import { useKeycloak } from "@/contexts/KeycloakContext";
import { KeycloakProvider, useKeycloak } from "@/contexts/KeycloakContext";
import { SWRConfig } from "swr";
import { fetcher } from "@/lib/api";
import { Fonts } from "@/components/base/global";
const Adapter = (props) => <NextAdapter {...props} shallow={true} />;
export default function App({ Component, pageProps }) {
// const { initialized, authenticated } = useKeycloak();
function AppWrapper({ Component, pageProps }) {
const { initialized, authenticated } = useKeycloak();
// if (!initialized) return <Spinner />;
// if (!authenticated) return <div>Redirecting to login...</div>;
if (!initialized) return <Spinner />;
if (!authenticated) return <div>Redirecting to login...</div>;
return (
<ChakraProvider theme={theme}>
<SWRConfig value={{ fetcher }}>
<QueryParamProvider
adapter={Adapter}
options={{ enableBatching: true }}
>
<Fonts />
<Component {...pageProps} />
</QueryParamProvider>
</SWRConfig>
</ChakraProvider>
<KeycloakProvider>
<ChakraProvider theme={theme}>
<SWRConfig value={{ fetcher }}>
<QueryParamProvider
adapter={Adapter}
options={{ enableBatching: true }}
>
<Fonts />
<Component {...pageProps} />
</QueryParamProvider>
</SWRConfig>
</ChakraProvider>
</KeycloakProvider>
);
}
function App(props) {
return (
<KeycloakProvider>
<AppWrapper {...props} />
</KeycloakProvider>
);
}
export default App;

View File

@ -30,6 +30,8 @@ import {
withDefault,
} from "use-query-params";
import { BsChatText } from "react-icons/bs";
import { AiOutlinePoweroff } from "react-icons/ai";
import keycloak from "@/lib/keycloak";
export default function Home() {
const [filters, setFilters] = useQueryParams({
@ -52,15 +54,19 @@ export default function Home() {
borderLeft="1px solid"
borderColor="gray.200"
py={8}
overflowY={"auto"}
maxH={"calc(100vh - 92px)"}
sx={{
"::-webkit-scrollbar": { display: "none" },
"scrollbar-width": "none",
"-ms-overflow-style": "none",
}}
position={"relative"}
>
<VStack align="stretch" spacing={6}>
<VStack
align="stretch"
spacing={6}
overflowY={"auto"}
maxH={"calc(100vh - 150px)"}
sx={{
"::-webkit-scrollbar": { display: "none" },
"scrollbar-width": "none",
"-ms-overflow-style": "none",
}}
>
{/* Menu */}
<Tabs
isFitted
@ -189,6 +195,35 @@ export default function Home() {
{/* Footer */}
</VStack>
<Box
w={"full"}
position={"absolute"}
bottom={0}
left={0}
right={0}
zIndex={10}
borderTop={"1px"}
borderColor={"gray.300"}
bg={"gray.50"}
>
<HStack
w={"full"}
py={2}
gap={2}
justifyContent={"center"}
alignItems={"center"}
color={"gray.700"}
cursor={"pointer"}
transition={"all"}
transitionDuration={"200"}
_hover={{ color: "red.600" }}
onClick={() => keycloak.logout()}
>
<AiOutlinePoweroff size={20} />
<Text>خروج از حساب</Text>
</HStack>
</Box>
</Box>
{/* Content */}