🐛 fix(App.tsx): add autoLogin function to handle automatic login on page refresh
🐛 fix(authLoginGuard/index.tsx): change condition to check autoLogin flag instead of LOCALHOST_JWT flag 🐛 fix(headerComponent/index.tsx): change condition to check autoLogin flag instead of LOCALHOST_JWT flag 🐛 fix(constants.ts): remove unused LOCALHOST_JWT variable ✨ feat(authContext.tsx): add autoLogin and setAutoLogin functions to AuthContext 🐛 fix(API/api.tsx): add auto_login endpoint to the list of excluded endpoints from Authorization header ✨ feat(API/index.ts): add autoLogin function to handle automatic login 🐛 fix(AdminPage/index.tsx): change handleDisableUser function parameter from user.is_superuser to user.is_active 🐛 fix(types/contexts/auth.ts): add autoLogin and setAutoLogin to AuthContextType
This commit is contained in:
parent
95f7a42569
commit
d320ddd30a
10 changed files with 56 additions and 70 deletions
|
|
@ -14,10 +14,8 @@ import { alertContext } from "./contexts/alertContext";
|
||||||
import { AuthContext } from "./contexts/authContext";
|
import { AuthContext } from "./contexts/authContext";
|
||||||
import { locationContext } from "./contexts/locationContext";
|
import { locationContext } from "./contexts/locationContext";
|
||||||
import { TabsContext } from "./contexts/tabsContext";
|
import { TabsContext } from "./contexts/tabsContext";
|
||||||
import { getLoggedUser, onLogin } from "./controllers/API";
|
import { autoLogin, getLoggedUser, onLogin } from "./controllers/API";
|
||||||
import Router from "./routes";
|
import Router from "./routes";
|
||||||
import { LOCALHOST_JWT } from "./constants/constants";
|
|
||||||
import { LoginType } from "./types/api";
|
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
let { setCurrent, setShowSideBar, setIsStackedOpen } =
|
let { setCurrent, setShowSideBar, setIsStackedOpen } =
|
||||||
|
|
@ -133,52 +131,32 @@ export default function App() {
|
||||||
};
|
};
|
||||||
|
|
||||||
//this function is to get the user logged in when the page is refreshed
|
//this function is to get the user logged in when the page is refreshed
|
||||||
const { setUserData, getAuthentication, login } = useContext(AuthContext);
|
const { setUserData, getAuthentication, login, setAutoLogin } = useContext(AuthContext);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (getAuthentication && !isLoginPage) {
|
autoLogin().then((user) => {
|
||||||
getLoggedUser()
|
if(user && user['access_token']){
|
||||||
.then((user) => {
|
user['refresh_token'] = "auto";
|
||||||
setUserData(user);
|
login(user['access_token'], user['refresh_token']);
|
||||||
})
|
setAutoLogin(true);
|
||||||
.catch((error) => {});
|
}
|
||||||
}
|
}).catch((error) => {
|
||||||
}, 1000);
|
setAutoLogin(false);
|
||||||
|
if (getAuthentication && !isLoginPage) {
|
||||||
|
getLoggedUser()
|
||||||
|
.then((user) => {
|
||||||
|
setUserData(user);
|
||||||
|
})
|
||||||
|
.catch((error) => {});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
navigate("/login");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 500);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
|
|
||||||
if(LOCALHOST_JWT === true && isLocalHost === true){
|
|
||||||
const user: LoginType = {
|
|
||||||
username: "superuser",
|
|
||||||
password: "12345",
|
|
||||||
};
|
|
||||||
onLogin(user)
|
|
||||||
.then((user) => {
|
|
||||||
login(user.access_token, user.refresh_token);
|
|
||||||
getUser();
|
|
||||||
navigate("/");
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
setErrorData({
|
|
||||||
title: "Error signing in",
|
|
||||||
list: [error["response"]["data"]["detail"]],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
function getUser() {
|
|
||||||
if (getAuthentication) {
|
|
||||||
setTimeout(() => {
|
|
||||||
getLoggedUser()
|
|
||||||
.then((user) => {
|
|
||||||
setUserData(user);
|
|
||||||
})
|
|
||||||
.catch((error) => {});
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
//need parent component with width and height
|
//need parent component with width and height
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,6 @@ export default function PaginatorComponent({
|
||||||
<span className="sr-only">Go to first page</span>
|
<span className="sr-only">Go to first page</span>
|
||||||
<IconComponent name="ChevronsLeft" className="h-4 w-4" />
|
<IconComponent name="ChevronsLeft" className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
disabled={index <= 0}
|
disabled={index <= 0}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|
@ -85,10 +81,6 @@ export default function PaginatorComponent({
|
||||||
<span className="sr-only">Go to previous page</span>
|
<span className="sr-only">Go to previous page</span>
|
||||||
<IconComponent name="ChevronLeft" className="h-4 w-4" />
|
<IconComponent name="ChevronLeft" className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
disabled={currentPage === maxIndex}
|
disabled={currentPage === maxIndex}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|
@ -103,10 +95,6 @@ export default function PaginatorComponent({
|
||||||
<span className="sr-only">Go to next page</span>
|
<span className="sr-only">Go to next page</span>
|
||||||
<IconComponent name="ChevronRight" className="h-4 w-4" />
|
<IconComponent name="ChevronRight" className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
disabled={currentPage === maxIndex}
|
disabled={currentPage === maxIndex}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,11 @@
|
||||||
import { useContext } from "react";
|
import { useContext } from "react";
|
||||||
import { Navigate } from "react-router-dom";
|
import { Navigate } from "react-router-dom";
|
||||||
import { AuthContext } from "../../contexts/authContext";
|
import { AuthContext } from "../../contexts/authContext";
|
||||||
import { LOCALHOST_JWT } from "../../constants/constants";
|
|
||||||
|
|
||||||
export const ProtectedLoginRoute = ({ children }) => {
|
export const ProtectedLoginRoute = ({ children }) => {
|
||||||
const { getAuthentication } = useContext(AuthContext);
|
const { getAuthentication, autoLogin } = useContext(AuthContext);
|
||||||
|
|
||||||
const isLocalHost = window.location.href.includes("localhost");
|
if(autoLogin === true){
|
||||||
|
|
||||||
if(isLocalHost && LOCALHOST_JWT){
|
|
||||||
window.location.replace("/");
|
window.location.replace("/");
|
||||||
return <Navigate to="/" replace />;
|
return <Navigate to="/" replace />;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { useContext, useEffect, useState } from "react";
|
||||||
import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa";
|
import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa";
|
||||||
import { Link, useLocation, useNavigate } from "react-router-dom";
|
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||||||
import AlertDropdown from "../../alerts/alertDropDown";
|
import AlertDropdown from "../../alerts/alertDropDown";
|
||||||
import { LOCALHOST_JWT, USER_PROJECTS_HEADER } from "../../constants/constants";
|
import { USER_PROJECTS_HEADER } from "../../constants/constants";
|
||||||
import { alertContext } from "../../contexts/alertContext";
|
import { alertContext } from "../../contexts/alertContext";
|
||||||
import { AuthContext } from "../../contexts/authContext";
|
import { AuthContext } from "../../contexts/authContext";
|
||||||
import { darkContext } from "../../contexts/darkContext";
|
import { darkContext } from "../../contexts/darkContext";
|
||||||
|
|
@ -18,11 +18,10 @@ export default function Header() {
|
||||||
const { dark, setDark } = useContext(darkContext);
|
const { dark, setDark } = useContext(darkContext);
|
||||||
const { notificationCenter } = useContext(alertContext);
|
const { notificationCenter } = useContext(alertContext);
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const { logout } = useContext(AuthContext);
|
const { logout, autoLogin } = useContext(AuthContext);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [stars, setStars] = useState(null);
|
const [stars, setStars] = useState(null);
|
||||||
const isLocalHost = window.location.href.includes("localhost");
|
|
||||||
|
|
||||||
// Get and set numbers of stars on header
|
// Get and set numbers of stars on header
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -38,7 +37,7 @@ export default function Header() {
|
||||||
<Link to="/">
|
<Link to="/">
|
||||||
<span className="ml-4 text-2xl">⛓️</span>
|
<span className="ml-4 text-2xl">⛓️</span>
|
||||||
</Link>
|
</Link>
|
||||||
{!isLocalHost || !LOCALHOST_JWT && (
|
{autoLogin === false && (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
logout();
|
logout();
|
||||||
|
|
|
||||||
|
|
@ -610,5 +610,3 @@ export function tabsArray(codes: string[], method: number) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BASE_URL_API = "http://localhost:7860/";
|
export const BASE_URL_API = "http://localhost:7860/";
|
||||||
|
|
||||||
export let LOCALHOST_JWT = false;
|
|
||||||
|
|
@ -14,6 +14,8 @@ const initialValue: AuthContextType = {
|
||||||
setUserData: () => {},
|
setUserData: () => {},
|
||||||
getAuthentication: () => false,
|
getAuthentication: () => false,
|
||||||
authenticationErrorCount: 0,
|
authenticationErrorCount: 0,
|
||||||
|
autoLogin: false,
|
||||||
|
setAutoLogin: () => {},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AuthContext = createContext<AuthContextType>(initialValue);
|
export const AuthContext = createContext<AuthContextType>(initialValue);
|
||||||
|
|
@ -23,6 +25,7 @@ export function AuthProvider({ children }): React.ReactElement {
|
||||||
const [refreshToken, setRefreshToken] = useState<string | null>(null);
|
const [refreshToken, setRefreshToken] = useState<string | null>(null);
|
||||||
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
|
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
|
||||||
const [userData, setUserData] = useState<Users>(null);
|
const [userData, setUserData] = useState<Users>(null);
|
||||||
|
const [autoLogin, setAutoLogin] = useState<boolean>(false);
|
||||||
const cookies = new Cookies();
|
const cookies = new Cookies();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -91,6 +94,8 @@ export function AuthProvider({ children }): React.ReactElement {
|
||||||
userData,
|
userData,
|
||||||
getAuthentication,
|
getAuthentication,
|
||||||
authenticationErrorCount: 0,
|
authenticationErrorCount: 0,
|
||||||
|
setAutoLogin,
|
||||||
|
autoLogin
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,10 @@ function ApiInterceptor() {
|
||||||
config?.url?.includes(
|
config?.url?.includes(
|
||||||
"https://api.github.com/repos/logspace-ai/langflow"
|
"https://api.github.com/repos/logspace-ai/langflow"
|
||||||
)
|
)
|
||||||
|
||
|
||||||
|
config?.url?.includes(
|
||||||
|
"auto_login"
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
delete config.headers["Authorization"];
|
delete config.headers["Authorization"];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -378,6 +378,21 @@ export async function onLogin(user: LoginType) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function autoLogin() {
|
||||||
|
try {
|
||||||
|
const response = await api.get(
|
||||||
|
`${BASE_URL_API}auto_login`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.status === 200) {
|
||||||
|
const data = response.data;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function renewAccessToken(token: string) {
|
export async function renewAccessToken(token: string) {
|
||||||
try {
|
try {
|
||||||
return await api.post(`${BASE_URL_API}refresh?token=${token}`);
|
return await api.post(`${BASE_URL_API}refresh?token=${token}`);
|
||||||
|
|
|
||||||
|
|
@ -266,7 +266,7 @@ export default function AdminPage() {
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHead className="h-10">Id</TableHead>
|
<TableHead className="h-10">Id</TableHead>
|
||||||
<TableHead className="h-10">Username</TableHead>
|
<TableHead className="h-10">Username</TableHead>
|
||||||
<TableHead className="h-10">Disabled</TableHead>
|
<TableHead className="h-10">Active</TableHead>
|
||||||
<TableHead className="h-10">Superuser</TableHead>
|
<TableHead className="h-10">Superuser</TableHead>
|
||||||
<TableHead className="h-10">Created At</TableHead>
|
<TableHead className="h-10">Created At</TableHead>
|
||||||
<TableHead className="h-10">Updated At</TableHead>
|
<TableHead className="h-10">Updated At</TableHead>
|
||||||
|
|
@ -304,7 +304,7 @@ export default function AdminPage() {
|
||||||
index={index}
|
index={index}
|
||||||
onConfirm={(index, user) => {
|
onConfirm={(index, user) => {
|
||||||
handleDisableUser(
|
handleDisableUser(
|
||||||
user.is_superuser,
|
user.is_active,
|
||||||
user.id,
|
user.id,
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -11,4 +11,6 @@ export type AuthContextType = {
|
||||||
setUserData: (userData: Users | null) => void;
|
setUserData: (userData: Users | null) => void;
|
||||||
getAuthentication: () => boolean;
|
getAuthentication: () => boolean;
|
||||||
authenticationErrorCount: number;
|
authenticationErrorCount: number;
|
||||||
|
autoLogin: boolean;
|
||||||
|
setAutoLogin: (autoLogin: boolean) => void
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue