Authorization working

This commit is contained in:
2025-02-24 21:53:20 -05:00
parent 2186889b11
commit 5bb6e0a37f
37 changed files with 5723 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
import { api } from "@/util/AxiosUtil";
import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useState } from "react";
import { Navigate, Outlet } from "react-router";
type AuthProviderProps = {
children: React.ReactNode;
jwtStorageKey?: string;
refreshTokenStorageKey?: string;
}
type AuthProviderState = {
jwt: string | null;
setJwt: (token: string | null) => void;
expiration: Date | null;
setExpiration: (expiration: Date | null) => void;
}
const initialState: AuthProviderState = {
jwt: null,
setJwt: () => null,
expiration: null,
setExpiration: () => null
}
const AuthContext = createContext<AuthProviderState>(initialState);
export function AuthProvider({
children
}: AuthProviderProps){
const [ jwt, setJwt ] = useState<string | null>(null);
const [ expiration, setExpiration ] = useState<Date | null>(null)
const fetchToken = useCallback(async () => {
try{
const response = await api.get("/auth/refresh");
//If the token is retrieved
if((response.status === 200) && (!response.data.errors)){
setJwt(response.data.token);
setExpiration(new Date(atob(response.data.token.split(".")[1])));
}
//If the token cannot be retrieved
else{
setJwt(null);
setExpiration(null);
}
}
//If the token cannot be retrieved
catch{
setJwt(null);
setExpiration(null);
}
}, [ setJwt, setExpiration ]);
//Add the token to all queries
useLayoutEffect(() => {
if((expiration) && (expiration < new Date())){
fetchToken();
}
const authInterceptor = api.interceptors.request.use(config => {
config.headers.Authorization = jwt ? `Bearer ${jwt}` : config.headers.Authorization;
return config;
});
return () => { api.interceptors.request.eject(authInterceptor); };
}, [ jwt, expiration, fetchToken ]);
//Try to get the token on page load
useEffect(() => {
fetchToken();
}, [ fetchToken ]);
const currentTokens = useMemo(() => ({
jwt,
setJwt,
expiration,
setExpiration
}), [ jwt, setJwt, expiration, setExpiration ]);
return (
<AuthContext.Provider value={currentTokens}>
{children}
</AuthContext.Provider>
);
}
export function ProtectedRoute(){
const { jwt } = useAuth();
if(!jwt){
return <Navigate to="/login"/>;
}
return <Outlet/>;
}
export const useAuth = () => {
const context = useContext(AuthContext);
if(context === undefined){
throw new Error("useAuth must be used within an AuthProvider");
}
return context;
}