Files
HKSingleParty/03_source/frontend/src/auth/context/auth0/auth-provider.tsx
louiscklaw b7cd25b614 build ok,
2025-06-15 11:28:24 +08:00

92 lines
2.6 KiB
TypeScript

import type { AppState } from '@auth0/auth0-react';
import { Auth0Provider, useAuth0 } from '@auth0/auth0-react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { CONFIG } from 'src/global-config';
import axios from 'src/lib/axios';
import { AuthContext } from '../auth-context';
// ----------------------------------------------------------------------
type Props = {
children: React.ReactNode;
};
export function AuthProvider({ children }: Props) {
const { domain, clientId, callbackUrl } = CONFIG.auth0;
const onRedirectCallback = useCallback((appState?: AppState) => {
window.location.replace(appState?.returnTo || window.location.pathname);
}, []);
if (!(domain && clientId && callbackUrl)) {
return null;
}
return (
<Auth0Provider
domain={domain}
clientId={clientId}
authorizationParams={{ redirect_uri: callbackUrl }}
onRedirectCallback={onRedirectCallback}
cacheLocation="localstorage"
>
<AuthProviderContainer>{children}</AuthProviderContainer>
</Auth0Provider>
);
}
// ----------------------------------------------------------------------
function AuthProviderContainer({ children }: Props) {
const { user, isLoading, isAuthenticated, getAccessTokenSilently } = useAuth0();
const [accessToken, setAccessToken] = useState<string | null>(null);
const getAccessToken = useCallback(async () => {
try {
if (isAuthenticated) {
const token = await getAccessTokenSilently();
setAccessToken(token);
axios.defaults.headers.common.Authorization = `Bearer ${token}`;
} else {
setAccessToken(null);
delete axios.defaults.headers.common.Authorization;
}
} catch (error) {
console.error(error);
}
}, [getAccessTokenSilently, isAuthenticated]);
useEffect(() => {
getAccessToken();
}, [getAccessToken]);
// ----------------------------------------------------------------------
const checkAuthenticated = isAuthenticated ? 'authenticated' : 'unauthenticated';
const status = isLoading ? 'loading' : checkAuthenticated;
const memoizedValue = useMemo(
() => ({
user: user
? {
...user,
id: user?.sub,
accessToken,
displayName: user?.name,
photoURL: user?.picture,
role: user?.role ?? 'admin',
}
: null,
loading: status === 'loading',
authenticated: status === 'authenticated',
unauthenticated: status === 'unauthenticated',
}),
[accessToken, status, user]
);
return <AuthContext value={memoizedValue}>{children}</AuthContext>;
}