forked from baron/baron-sso
89 lines
2.1 KiB
TypeScript
89 lines
2.1 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { useAuth } from "react-oidc-context";
|
|
import { Navigate, Outlet } from "react-router-dom";
|
|
import { userManager } from "../../lib/auth";
|
|
import {
|
|
findPersistedOidcUser,
|
|
isValidOidcSessionUser,
|
|
} from "../../lib/oidcStorage";
|
|
|
|
export default function AuthGuard() {
|
|
const auth = useAuth();
|
|
const hasActiveAuthUser =
|
|
auth.isAuthenticated && isValidOidcSessionUser(auth.user);
|
|
const [hasStoredUser, setHasStoredUser] = useState<boolean | null>(() =>
|
|
findPersistedOidcUser() ? true : null,
|
|
);
|
|
const isTestMode =
|
|
(window as Window & typeof globalThis & { _IS_TEST_MODE?: boolean })
|
|
._IS_TEST_MODE === true;
|
|
|
|
useEffect(() => {
|
|
let cancelled = false;
|
|
|
|
if (isTestMode) {
|
|
setHasStoredUser(true);
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}
|
|
|
|
const persistedUser = findPersistedOidcUser();
|
|
if (persistedUser) {
|
|
setHasStoredUser(true);
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}
|
|
|
|
void userManager
|
|
.getUser()
|
|
.then((user) => {
|
|
if (!cancelled) {
|
|
setHasStoredUser(isValidOidcSessionUser(user));
|
|
}
|
|
})
|
|
.catch(() => {
|
|
if (!cancelled) {
|
|
setHasStoredUser(false);
|
|
}
|
|
});
|
|
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, [isTestMode]);
|
|
|
|
if (isTestMode) {
|
|
return <Outlet />;
|
|
}
|
|
|
|
if (auth.isLoading || auth.activeNavigator || hasStoredUser === null) {
|
|
return <div>Loading...</div>;
|
|
}
|
|
|
|
if (auth.error) {
|
|
return (
|
|
<div className="flex min-h-screen flex-col items-center justify-center p-4 text-center">
|
|
<div className="mb-4 text-red-500">
|
|
<h2 className="text-xl font-bold">Authentication Error</h2>
|
|
<p>{auth.error.message}</p>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
onClick={() => void auth.signinRedirect()}
|
|
className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600"
|
|
>
|
|
Start Login Again
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (!hasActiveAuthUser && !hasStoredUser) {
|
|
return <Navigate to="/login" replace />;
|
|
}
|
|
|
|
return <Outlet />;
|
|
}
|