Added `oidc-client-ts` and `jwt-decode` dependencies to support OIDC authentication. Implemented `authFetch` for secure API calls and integrated user session management with `AuthBootstrap`. Updated `App` to utilize token-based authentication flows with protected endpoints.
83 lines
2.1 KiB
JavaScript
83 lines
2.1 KiB
JavaScript
import React, { useEffect, useState } from "react";
|
|
import { userManager } from "./auth/userManager";
|
|
|
|
/**
|
|
* Responsável por:
|
|
* - tratar /callback (retorno do Authentik)
|
|
* - garantir que o usuário esteja logado antes de renderizar o app
|
|
*/
|
|
export default function AuthBootstrap({ children }) {
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState(null);
|
|
|
|
useEffect(() => {
|
|
(async () => {
|
|
try {
|
|
const { pathname, search } = window.location;
|
|
|
|
if (pathname === "/callback") {
|
|
// Finaliza o fluxo OIDC
|
|
await userManager.signinRedirectCallback();
|
|
|
|
// Volta para home (mantém a URL limpa)
|
|
window.history.replaceState({}, document.title, "/");
|
|
setLoading(false);
|
|
return;
|
|
}
|
|
|
|
const user = await userManager.getUser();
|
|
|
|
if (!user || user.expired) {
|
|
await userManager.signinRedirect();
|
|
return;
|
|
}
|
|
|
|
setLoading(false);
|
|
} catch (e) {
|
|
setError(e?.message ?? String(e));
|
|
setLoading(false);
|
|
}
|
|
})();
|
|
}, []);
|
|
|
|
if (loading) {
|
|
return (
|
|
<div style={{
|
|
minHeight: "100vh",
|
|
display: "flex",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
fontFamily: "system-ui, -apple-system, Segoe UI, Roboto, sans-serif"
|
|
}}>
|
|
Carregando autenticação...
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (error) {
|
|
return (
|
|
<div style={{
|
|
minHeight: "100vh",
|
|
display: "flex",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
padding: 24,
|
|
fontFamily: "system-ui, -apple-system, Segoe UI, Roboto, sans-serif"
|
|
}}>
|
|
<div>
|
|
<h2 style={{ marginBottom: 12 }}>Erro na autenticação</h2>
|
|
<pre style={{ whiteSpace: "pre-wrap" }}>{error}</pre>
|
|
<button
|
|
onClick={() => userManager.signinRedirect()}
|
|
style={{ marginTop: 12, padding: "8px 12px" }}
|
|
>
|
|
Tentar novamente
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return children;
|
|
}
|